Shipwright/libultraship/libultraship/Cutscene.cpp

522 lines
13 KiB
C++

#include "Cutscene.h"
enum class CutsceneCommands
{
Cmd00 = 0x0000,
SetCameraPos = 0x0001,
SetCameraFocus = 0x0002,
SpecialAction = 0x0003,
SetLighting = 0x0004,
SetCameraPosLink = 0x0005,
SetCameraFocusLink = 0x0006,
Cmd07 = 0x0007,
Cmd08 = 0x0008,
Cmd09 = 0x0009,
Unknown = 0x001A,
Textbox = 0x0013,
SetActorAction0 = 0x000A,
SetActorAction1 = 0x000F,
SetActorAction2 = 0x000E,
SetActorAction3 = 0x0019,
SetActorAction4 = 0x001D,
SetActorAction5 = 0x001E,
SetActorAction6 = 0x002C,
SetActorAction7 = 0x001F,
SetActorAction8 = 0x0031,
SetActorAction9 = 0x003E,
SetActorAction10 = 0x008F,
SetSceneTransFX = 0x002D,
Nop = 0x000B,
PlayBGM = 0x0056,
StopBGM = 0x0057,
FadeBGM = 0x007C,
SetTime = 0x008C,
Terminator = 0x03E8,
End = 0xFFFF,
Error = 0xFEAF,
};
static inline uint32_t read_CMD_BBBB(BinaryReader* reader)
{
uint32_t v;
reader->Read((char*)&v, sizeof(uint32_t));
return v;
}
static inline uint32_t read_CMD_BBH(BinaryReader* reader)
{
uint32_t v;
reader->Read((char*)&v, sizeof(uint32_t));
// swap the half word to match endianness
if (reader->GetEndianness() != Endianness::Native)
{
uint8_t* b = (uint8_t*)&v;
uint8_t tmp = b[2];
b[2] = b[3];
b[3] = tmp;
}
return v;
}
static inline uint32_t read_CMD_HBB(BinaryReader* reader)
{
uint32_t v;
reader->Read((char*)&v, sizeof(uint32_t));
// swap the half word to match endianness
if (reader->GetEndianness() != Endianness::Native)
{
uint8_t* b = (uint8_t*)&v;
uint8_t tmp = b[0];
b[0] = b[1];
b[1] = tmp;
}
return v;
}
static inline uint32_t read_CMD_HH(BinaryReader* reader)
{
uint32_t v;
reader->Read((char*)&v, sizeof(uint32_t));
// swap the half words to match endianness
if (reader->GetEndianness() != Endianness::Native)
{
uint8_t* b = (uint8_t*)&v;
uint8_t tmp = b[0];
b[0] = b[1];
b[1] = tmp;
tmp = b[2];
b[2] = b[3];
b[3] = tmp;
}
return v;
}
void Ship::CutsceneV0::ParseFileBinary(BinaryReader* reader, Resource* res)
{
Cutscene* cs = (Cutscene*)res;
ResourceFile::ParseFileBinary(reader, res);
uint32_t numEntries = reader->ReadUInt32();
cs->commands.reserve(numEntries);
uint32_t numCommands = reader->ReadUInt32();
cs->commands.push_back(numCommands);
// endFrame
cs->commands.push_back(reader->ReadUInt32());
while (true)
{
uint32_t commandId = reader->ReadUInt32();
cs->commands.push_back(commandId);
switch (commandId)
{
case (uint32_t)CutsceneCommands::SetCameraPos:
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
while (true)
{
uint32_t val = read_CMD_BBH(reader);
int8_t continueFlag = ((int8_t*)&val)[0];
cs->commands.push_back(val);
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
if (continueFlag == -1)
break;
}
}
break;
case (uint32_t)CutsceneCommands::SetCameraFocus:
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
while (true)
{
uint32_t val = read_CMD_BBH(reader);
int8_t continueFlag = ((int8_t*)&val)[0];
cs->commands.push_back(val);
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
if (continueFlag == -1)
break;
}
break;
}
case (uint32_t)CutsceneCommands::SpecialAction:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
}
break;
}
case (uint32_t)CutsceneCommands::SetLighting:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
}
break;
}
case (uint32_t)CutsceneCommands::SetCameraPosLink:
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
while (true)
{
uint32_t val = read_CMD_BBH(reader);
int8_t continueFlag = ((int8_t*)&val)[0];
cs->commands.push_back(val);
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
if (continueFlag == -1)
break;
}
break;
}
case (uint32_t)CutsceneCommands::SetCameraFocusLink:
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
while (true)
{
uint32_t val = read_CMD_BBH(reader);
int8_t continueFlag = ((int8_t*)&val)[0];
cs->commands.push_back(val);
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
if (continueFlag == -1)
break;
}
break;
}
case (uint32_t)CutsceneCommands::Cmd09:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HBB(reader));
cs->commands.push_back(read_CMD_BBH(reader));
}
break;
}
case 0x15:
case (uint32_t)CutsceneCommands::Unknown:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
}
}
break;
case (uint32_t)CutsceneCommands::Textbox:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
}
break;
}
case (uint32_t)CutsceneCommands::SetActorAction0:
case (uint32_t)CutsceneCommands::SetActorAction1:
case 17:
case 18:
case 23:
case 34:
case 39:
case 46:
case 76:
case 85:
case 93:
case 105:
case 107:
case 110:
case 119:
case 123:
case 138:
case 139:
case 144:
case (uint32_t)CutsceneCommands::SetActorAction2:
case 16:
case 24:
case 35:
case 40:
case 48:
case 64:
case 68:
case 70:
case 78:
case 80:
case 94:
case 116:
case 118:
case 120:
case 125:
case 131:
case 141:
case (uint32_t)CutsceneCommands::SetActorAction3:
case 36:
case 41:
case 50:
case 67:
case 69:
case 72:
case 74:
case 81:
case 106:
case 117:
case 121:
case 126:
case 132:
case (uint32_t)CutsceneCommands::SetActorAction4:
case 37:
case 42:
case 51:
case 53:
case 63:
case 65:
case 66:
case 75:
case 82:
case 108:
case 127:
case 133:
case (uint32_t)CutsceneCommands::SetActorAction5:
case 38:
case 43:
case 47:
case 54:
case 79:
case 83:
case 128:
case 135:
case (uint32_t)CutsceneCommands::SetActorAction6:
case 55:
case 77:
case 84:
case 90:
case 129:
case 136:
case (uint32_t)CutsceneCommands::SetActorAction7:
case 52:
case 57:
case 58:
case 88:
case 115:
case 130:
case 137:
case (uint32_t)CutsceneCommands::SetActorAction8:
case 60:
case 89:
case 111:
case 114:
case 134:
case 142:
case (uint32_t)CutsceneCommands::SetActorAction9:
case (uint32_t)CutsceneCommands::SetActorAction10:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
}
break;
}
case (uint32_t)CutsceneCommands::SetSceneTransFX:
{
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
break;
}
case (uint32_t)CutsceneCommands::PlayBGM:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
}
break;
}
case (uint32_t)CutsceneCommands::StopBGM:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
}
break;
}
case (uint32_t)CutsceneCommands::FadeBGM:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
}
break;
}
case (uint32_t)CutsceneCommands::SetTime:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HBB(reader));
cs->commands.push_back(reader->ReadUInt32());
}
break;
}
case (uint32_t)CutsceneCommands::Terminator:
{
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
break;
}
case 0xFFFFFFFF: // CS_END
{
cs->commands.push_back(reader->ReadUInt32());
return;
}
default:
#ifdef _DEBUG
printf("CutsceneV0: Unknown command %x\n", commandId);
#endif
// error?
break;
}
}
}