Field File Section 9: Background - niemasd/PyFF7 GitHub Wiki

The Background section stores the actual background. This wiki is a useful reference for the Background section. All offsets referenced in this section do not include the Section Length.

Final Fantasy VII stores its backgrounds in a rather complex format. Basically, there are three sections:

  1. The palette, which is basically just a list of colors
  2. The background sprites (or tiles), which are just references to other bits of data
  3. The raw image data, which is palettized grayscale data

Each background sprite represents a 16x16 pixel block on the finished background. The sprite essentially contains the following information:

  • The target block, i.e., where on the background to draw this 16x16 square
  • The source block, i.e., where on the raw image data to take the pixels from
  • The palette page, i.e., which 256-color palette block to apply to the raw image data

This is a very efficient way to store the image. On one hand, it's in 16-bit colour, far better than just palettizing the whole image (i.e., 256 colors over the whole background). On the other hand, each 16x16 pixel block takes much less space than if you'd stored it directly in 16-bit color format. It isn't, however, easy to decode or (especially) encode.

The image source data is split up into 256x256 pixel pages; that's why, as well as a source X and Y, you also have a source page (which 256x256 block to take data from). On the other hand, the destination background is stored as one big bitmap with no limits on size, so there, you just have a target X/Y position which can be used directly.

4 bytes: Section Length

  • This is a 4-byte unsigned integer denoting the total length (in bytes) of this section

Header

2 bytes: Unknown 1

  • The first 2 bytes are an unsigned integer with unknown value
  • It seems to always be 0

2 bytes: Depth

  • The next 2 bytes are an unsigned integer denoting the depth
  • It seems to almost always be 1
    • I did see a file (blin67_4) that had 2 for this value

1 byte: Unknown 2

  • The next byte is an unsigned integer with unknown value
  • It seems to always be 1

Subsection 1: Palette

This Makou Ractor code might help decode the palette subsection.

7 bytes: "PALETTE"

  • The first 7 bytes of this subsection are the string PALETTE

4 bytes: Palette Size

  • The next 4 bytes are an unsigned integer representing the palette size

2 bytes: PalX

  • The next 2 bytes are an unsigned integer representing PalX

2 bytes: PalY

  • The next 2 bytes are an unsigned integer representing PalY

2 bytes: Width

  • The next 2 bytes are an unsigned integer representing the palette width

2 bytes: Height

  • The next 2 bytes are an unsigned integer representing the palette height

12 bytes: Colors

  • Next are 6 colors, each composed of 2 bytes
  • From leftmost bit to rightmost bit:
    • The first bit denotes alpha (1: alpha = 255; 0: alpha = 0)
    • The next 5 bits are an unsigned integer for Blue
    • The next 5 bits are an unsigned integer for Green
    • The next 5 bits are an unsigned integer for Red
    • In other words: ABBBBBGG GGGRRRRR (A = Mask, B = Blue, G = Green, R = Red)

Subsection 2: Background Tiles

4 bytes: "BACK"

  • The first 4 bytes of this subsection are the string BACK

Layer 1

2 bytes: Width

  • The next 2 bytes are an unsigned integer representing the width

2 bytes: Height

  • The next 2 bytes are an unsigned integer representing the height

2 bytes: Number of Tiles

  • The next 2 bytes are an unsigned integer representing the total number of tiles

4 bytes: Depth

  • The next 4 bytes are an unsigned integer denoting the depth

2 bytes: Blank

  • This seems to just be <NULL><NULL> (i.e., 0x0 0x0)

Tiles

  • Each background tile has the following components:
    • 2 bytes: Blank (seems to just be <NULL><NULL>)
    • 2 bytes: Destination X (signed int)
    • 2 bytes: Destination Y (signed int)
    • 4 bytes: Unknown 1
    • 1 byte: Source X (unsigned integer)
    • 1 byte: Unknown 2
    • 1 byte: Source Y (unsigned integer)
    • 1 byte: Unknown 3
    • 1 byte: Source X2 (unsigned integer)
    • 1 byte: Unknown 4
    • 1 byte: Source Y2 (unsigned integer)
    • 1 byte: Unknown 5
    • 2 bytes: Width (unsigned integer) (normally unused)
      • Can probably always just assume 16 (even if the value in the tile doesn't match)
    • 2 bytes: Height (unsigned integer) (normally unused)
      • Can probably always just assume 16 (even if the value in the tile doesn't match)
    • 1 byte: Palette ID (unsigned integer)
    • 1 byte: Unknown 6
    • 2 bytes: ID (unsigned integer)
    • 1 byte: Param (unsigned integer)
    • 1 byte: State (unsigned integer)
    • 1 byte: Blending (unsigned integer)
    • 1 byte: Unknown 7
    • 1 byte: Type Trans (unsigned integer)
    • 1 byte: Unknown 8
    • 1 byte: Texture ID (unsigned integer)
    • 1 byte: Unknown 9
    • 1 byte: Texture ID 2 (unsigned integer)
    • 1 byte: Unknown 10
    • 1 byte: Depth (unsigned integer) (normally unused)
    • 1 byte: Unknown 11
    • 4 bytes: ID Big (unsigned integer)
    • 4 bytes: Source X Big (unsigned integer)
    • 4 bytes: Source Y Big (unsigned integer)
    • 2 bytes: Blank (seems to just be <NULL><NULL>)
  • Note that, for Destination X and Destination Y, (0,0) is the center of the image, not the top-left corner

2 bytes: Blank

  • This seems to just be <NULL><NULL> (i.e., 0x0 0x0)

Layer 2

1 byte: Layer 2 Flag

  • This is an unsigned integer
  • 1 denotes the presence of Layer 2, otherwise 0
    • If 0, there is nothing else in Layer 2 after this

2 bytes: Width

  • The next 2 bytes are an unsigned integer representing the width

2 bytes: Height

  • The next 2 bytes are an unsigned integer representing the height

2 bytes: Number of Tiles

  • The next 2 bytes are an unsigned integer representing the total number of tiles

16 bytes: Unknown

  • The next 16 bytes have unknown function and are unused

2 bytes: Blank

  • This seems to just be <NULL><NULL> (i.e., 0x0 0x0)

Tiles

  • Each background tile has the same components as in Layer 1

2 bytes: Blank

  • This seems to just be <NULL><NULL> (i.e., 0x0 0x0)

Layer 3

1 byte: Layer 2 Flag

  • This is an unsigned integer
  • 1 denotes the presence of Layer 2, otherwise 0
    • If 0, there is nothing else in Layer 2 after this

2 bytes: Width

  • The next 2 bytes are an unsigned integer representing the width

2 bytes: Height

  • The next 2 bytes are an unsigned integer representing the height

2 bytes: Number of Tiles

  • The next 2 bytes are an unsigned integer representing the total number of tiles

10 bytes: Unknown

  • The next 16 bytes have unknown function and are unused

2 bytes: Blank

  • This seems to just be <NULL><NULL> (i.e., 0x0 0x0)

Tiles

  • Each background tile has the same components as in Layer 1

2 bytes: Blank

  • This seems to just be <NULL><NULL> (i.e., 0x0 0x0)

Layer 4

1 byte: Layer 2 Flag

  • This is an unsigned integer
  • 1 denotes the presence of Layer 2, otherwise 0
    • If 0, there is nothing else in Layer 2 after this

2 bytes: Width

  • The next 2 bytes are an unsigned integer representing the width

2 bytes: Height

  • The next 2 bytes are an unsigned integer representing the height

2 bytes: Number of Tiles

  • The next 2 bytes are an unsigned integer representing the total number of tiles

10 bytes: Unknown

  • The next 16 bytes have unknown function and are unused

2 bytes: Blank

  • This seems to just be <NULL><NULL> (i.e., 0x0 0x0)

Tiles

  • Each background tile has the same components as in Layer 1

2 bytes: Blank

  • This seems to just be <NULL><NULL> (i.e., 0x0 0x0)

Subsection 3: Textures

7 bytes: "TEXTURE"

  • The first 7 bytes of this subsection are the string TEXTURE

Textures

  • The remaining bytes in this subsection are the actual textures
  • For each of the possible 42 textures:
    • 2 bytes: "Exists" flag
    • If the "Exists" flag is 1 (i.e., True):
      • 2 bytes: Size
      • 2 bytes: Depth
      • Depth * 65,536 Bytes: Data

End of File

3 bytes: "END"

  • The first 3 bytes are the string END

14 bytes: "FINAL FANTASY7"

  • The next (and last) 14 bytes are the string FINAL FANTASY7
⚠️ **GitHub.com Fallback** ⚠️