Preliminary details, will update as I continue.
Code:
DK64 Model Header:
This data is for the final version, though the kiosk versions header is the same; just subtract 8 bytes from each offset.
Layout is "offset (datatype) = description and details"
s16 = signed 16 bit int (-32768 - 32767)
u8 = unsigned 8 bit int (byte, 0-255)
0x38-0x3B (32-bit UInt) = pointer to start of master vertex lookup table (16 bytes per entry - [xxxx - s16][yyyy - s16][zzzz - s16][0000][uuuu - s16][vvvv - s16][rr - u8][gg - u8][bb - u8][aa - u8]
0x40-0x43 (32-bit UInt) = pointer to end of master vertex lookup table
((endptr-startptr) / 16) = vertex count)
0xE6-0xE7 (16-bit UInt) = number of display list commands (*8 = dlist buffer size in bytes)
0x148 (64-bit UInt per command) = start of master display list (first 8b = commandcode, next 24b = loword, next 32b = hiword)
struct DK64Header
{
int VertStart;
int VertEnd;
int VertCount;
int DLStart;
int DLCommandCount;
}
struct Vertex
{
short x;
short y;
short z;
short flags;
short u;
short v;
byte r;
byte g;
byte b;
byte a;
}
struct DisplayList
{
unsigned long Command;
byte CommandCode;
unsigned int loWord;
unsigned int hiWord;
}
long[4] ShiftTable = {0xFFFFFFFF, 0xFFFF, 0xFF, 1}; // macro for appending bytes
void ReadHeader(byte[] FileByteBuffer, struct DK64Header Header, bool kioskMode)
{
int inc = 0; // for kiosk/final compatibility
if(kioskMode) {inc=8;} // could be more elegant
for(int i=0;i<4;i++)
{
Header.VertStart += FileByteBuffer[(0x38-inc)+i] * ShiftTable[i];
Header.VertEnd += FileByteBuffer[(0x40-inc)+i] * ShiftTable[i];
}
Header.VertCount = ((Header.VertEnd - Header.VertStart) / 16);
Header.DLStart = 0x148-inc; //constant
for(int i=0;i<2;i++)
{
Header.DLCommandCount += FileByteBuffer[(0xE6-inc)+i] * ShiftTable[i+3];
}
}