Hex and Binary

From Final Fantasy Hacktics Wiki
Jump to navigation Jump to search


Binary

Binary has two possible values:

  • TRUE (1)
  • FALSE (0)

Hex

Hex is base 8. Decimal, the format we use in everyday life is base 10. Base 8 is simply far more efficient for computer operations.

Binary, Hexadecimal and Decimal (unsigned) equivalents

0x Represents an hexadecimal value
00000000 : 0x00 : 0
00000001 : 0x01 : 1
00000010 : 0x02 : 2
00000011 : 0x03 : 3
00000100 : 0x04 : 4
00000101 : 0x05 : 5
00000110 : 0x06 : 6
00000111 : 0x07 : 7
00001000 : 0x08 : 8
00001001 : 0x09 : 9
00001010 : 0x0A : 10
00001011 : 0x0B : 11
00001100 : 0x0C : 12
00001101 : 0x0D : 13
00001110 : 0x0E : 14
00001111 : 0x0F : 15
00010000 : 0x10 : 16
00011000 : 0x18 : 24
00100000 : 0x20 : 32
00110000 : 0x30 : 48
01000000 : 0x40 : 64
01100000 : 0x60 : 96
10000000 : 0x80 : 128
10100000 : 0xA0 : 160
10110000 : 0xB0 : 176
11000000 : 0xC0 : 192
11010000 : 0xD0 : 208
11100000 : 0xE0 : 224
11110000 : 0xF0 : 240
11111111 : 0xFF : 255

Each bit is worth twice more than the previous one. You simply add them all up to have your value in hex/decimal.

1st bit: 1
2nd bit: 2
3rd bit: 4
4th bit: 8
5th bit: 16
6th bit: 32
7th bit: 64
8th bit: 128
and so on

Bytes and Beyond

Bytes, Half-Words, Words are composed of so many bits (a bit is a boolean value, TRUE or FALSE):

  • Boolean: 0 or 1 (1 bit)
  • Nibble: 0x0 to 0xF (4 bits)
    unsigned: 0 to +15
    signed: -8 to +7
  • Byte: 0x00 to 0xFF (8 bits)
    unsigned: 0 to +255
    signed: -128 to +127
  • Half-Word: 0x0000 to 0xFFFF (16 bits)
    unsigned: 0 to +65535
    signed: -32768 to +65535
  • Word: 0x00000000 to 0xFFFFFFFF (32 bits)
    unsigned: 0 to +4294967295
    signed: -2147483648 to +2147483647

Flags

Flags are values that are usually one bit long, part of a byte, that it meant to literally be interpreted as TRUE or FALSE by the game.

For example, this byte is only composed of flags. They're technically Boolean values, but we call them flags to understand each other better:

0x??

   0x80 Male
   0x40 Female
   0x20 Monster
   0x10 Join After Event
   0x08 Load Formation
   0x04 ??? Stats
   0x02
   0x01 Save Formation

Now let's say this Byte has a value of 0x59, which in binary is 010011001 or 0x40 + 0x10 + 0x08 + 0x01. Meaning that "Female", "Join After Event", "Load Formation" and "Save Formation" are set.

Byte Order

Now you have to understand that MIPS r3000 will swap the bytes when handling Half-Words and Words.

What does this mean?

If the game wants to fetch a Half-Word, in the game's memory that value might be written as:

78 5A

But because the game is trying to read a Half-Word through opcode instructions (see ASM Hacking), it will be stored in the registers as 0x00005A78. Registers are 32bit and are used to hold values that will be computed by the game. They are loaded, altered, compared, and saved back as necessary.

Similarly, if the game wanted to load a Word:

9C B5 06 80

The value loaded would be 0x8006B59C.

Now if you see these values in the game's memory through a Hex Editor or an emulator's Memory Viewer:

59 00 C8 00 74 01 66 01 12 00 B7 01 32 00

You can simply guess the format and say those all look like Half-Words, you'd likely be right. But be careful, it depends on the way the game loads and saves values that determines if they are Bytes/Half-Words/Words, and not what you, yourself see in just Hex.

Unsigned VS signed

Again, this is determined by the game's code. Unless you can figure it out through the game's code or through logic, you cannot tell if a value is signed or unsigned. 0xC0 can be +192 (unsigned) or -64 (signed) 0xFFF8 can be +65528 (unsigned) or -8 (signed)

  • Bytes:
    Lowest unsigned value: 0x00 (0)
    Highest unsigned value: 0xFF (+255)
    Lowest signed value: 0x80 (-128)
    Highest signed value: 0x7F (+127)
  • Half-Words:
    Lowest unsigned value: 0x0000 (0)
    Highest unsigned value: 0xFFFF (+65535)
    Lowest signed value: 0x8000 (-32768)
    Highest signed value: 0x7FFF (+32767)
  • Half-Words:
    Lowest unsigned value: 0x00000000 (0)
    Highest unsigned value: 0xFFFFFFFF (+4294967295)
    Lowest signed value: 0x80000000 (-2147483648)
    Highest signed value: 0x7FFFFFFF (+2147483647)

Half the values are negative and the other half are positive when dealing with signed values (0 being positive).

Signed Values:

0x80000000 = -2147483648
0xFF000000 = -16777216
0xFFFF0000 = -65536
0xFFFFFF00 = -256
0xFFFFFFF8 = -8
0xFFFFFFFF = -1
0x00000000 = 0
0x00000008 = +8
0x000000FF = +255
0x0000FFFF = +65535
0x00FFFFFF = +16777215
0x7FFFFFFF = +2147483647