1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-07-15 20:35:13 +00:00

git subrepo pull --force tools/ZAPD

subrepo:
  subdir:   "tools/ZAPD"
  merged:   "b3bfa14cf"
upstream:
  origin:   "https://github.com/zeldaret/ZAPD.git"
  branch:   "master"
  commit:   "b3bfa14cf"
git-subrepo:
  version:  "0.4.6"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "110b9eb"
This commit is contained in:
Dragorn421 2024-02-19 16:45:07 +01:00
parent 59017f201e
commit 1330ae8d0c
No known key found for this signature in database
GPG key ID: 381AEBAF3D429335
19 changed files with 1141 additions and 51 deletions

83
tools/ZAPD/.github/workflows/main.yml vendored Normal file
View file

@ -0,0 +1,83 @@
name: Build ZAPD
on:
push:
pull_request:
branches:
- master
jobs:
build:
runs-on: self-hosted-runner
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Build ZAPD
run: make -j WERROR=1
- name: Checkout Repos
run: echo "Checkout Repos"
- name: Checkout oot
run: |
git clone https://github.com/zeldaret/oot.git
cd oot
git submodule update --init --recursive
- name: Checkout mm
run: |
git clone https://github.com/zeldaret/mm.git
cd mm
- name: Set up repos
run: echo "Set up repos"
- name: Setup OOT
run: |
cd oot
mkdir -p baseroms/gc-eu-mq-dbg/segments
cp ~/baserom_original.z64 ./baseroms/gc-eu-mq-dbg/baserom.z64
make venv
make -C tools -j
cp ../ZAPD.out tools/ZAPD/
.venv/bin/python3 tools/decompress_baserom.py gc-eu-mq-dbg
.venv/bin/python3 tools/extract_baserom.py baseroms/gc-eu-mq-dbg/baserom-decompressed.z64 -o baseroms/gc-eu-mq-dbg/segments --dmadata-start 0x12f70 --dmadata-names baseroms/gc-eu-mq-dbg/dmadata_names.txt
.venv/bin/python3 extract_assets.py -j 4
.venv/bin/python3 tools/msgdis.py --text-out assets/text/message_data.h --staff-text-out assets/text/message_data_staff.h
- name: Setup MM
run: |
cd mm
python3 -m venv .mm-env
source .mm-env/bin/activate
python3 -m pip install -r requirements.txt
cp ~/baserom.mm.us.rev1.z64 ./baserom.mm.us.rev1.z64
make -C tools -j
cp ../ZAPD.out tools/ZAPD/
python3 tools/fixbaserom.py
python3 tools/extract_baserom.py
python3 tools/decompress_yars.py
python3 extract_assets.py -j $(nproc)
- name: Build Repos
run: echo "Build Repos"
- name: Build oot
run: |
cd oot
make venv
make -j
- name: Build mm
run: |
cd mm
python3 -m venv .mm-env
source .mm-env/bin/activate
python3 -m pip install -r requirements.txt
make -j disasm
make -j
- name: Clean workspace
run: git clean -fdX

View file

@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/zeldaret/ZAPD.git
branch = master
commit = 2b6f459b9523603168b6869cf03057a0d68d5f89
parent = 2ab90bc51788c6baac0a94c3acb256be5f39ca12
commit = b3bfa14cf432115a0a675d243f3a1b3197f17cbd
parent = 59017f201eae4a1bc9212ea2c7dc51d4a036108b
method = merge
cmdver = 0.4.6

View file

@ -117,6 +117,11 @@ ZAPD also accepts the following list of extra parameters:
- `-us` / `--unaccounted-static` : Mark unaccounted data as `static`
- `-s` / `--static` : Mark every asset as `static`.
- This behaviour can be overridden per asset using `Static=` in the respective XML node.
- `--cs-float` : How cutscene floats should be extracted.
- Valid values:
- `hex`
- `float`
- `both`
- `-W...`: warning flags, see below
Additionally, you can pass the flag `--version` to see the current ZAPD version. If that flag is passed, ZAPD will ignore any other parameter passed.

View file

@ -167,7 +167,7 @@ void GameConfig::ConfigFunc_ExternalFile(const tinyxml2::XMLElement& element)
void GameConfig::ConfigFunc_EnumData(const tinyxml2::XMLElement& element)
{
std::string path = Path::GetDirectoryName(configFilePath);
std::string path = Path::GetDirectoryName(configFilePath).string();
path = path.append("/").append(element.Attribute("File"));
tinyxml2::XMLDocument doc;
tinyxml2::XMLError eResult = doc.LoadFile(path.c_str());
@ -247,6 +247,12 @@ void GameConfig::ConfigFunc_EnumData(const tinyxml2::XMLElement& element)
else if (enumKey == "endSfx")
enumData.endSfx[itemIndex] = itemID;
else if (enumKey == "csSplineInterpType")
enumData.interpType[itemIndex] = itemID;
else if (enumKey == "csSplineRelTo")
enumData.relTo[itemIndex] = itemID;
}
}
}

View file

@ -48,6 +48,8 @@ public:
std::map<uint16_t, std::string> rumbleType;
std::map<uint8_t, std::string> spawnFlag;
std::map<uint8_t, std::string> endSfx;
std::map<uint8_t, std::string> interpType;
std::map<uint16_t, std::string> relTo;
};
class ZFile;

View file

@ -16,6 +16,13 @@ enum class VerbosityLevel
VERBOSITY_DEBUG
};
enum class CsFloatType
{
HexOnly,
FloatOnly,
HexAndFloat,
};
class Globals
{
public:
@ -31,6 +38,7 @@ public:
ZFileMode fileMode;
fs::path baseRomPath, inputPath, outputPath, sourceOutputPath, cfgPath;
TextureType texType;
CsFloatType floatType = CsFloatType::FloatOnly;
ZGame game;
GameConfig cfg;
bool verboseUnaccounted = false;

View file

@ -36,6 +36,7 @@ void Arg_SetExporter(int& i, char* argv[]);
void Arg_EnableGCCCompat(int& i, char* argv[]);
void Arg_ForceStatic(int& i, char* argv[]);
void Arg_ForceUnaccountedStatic(int& i, char* argv[]);
void Arg_CsFloatMode(int& i, char* argv[]);
int main(int argc, char* argv[]);
@ -252,6 +253,7 @@ void ParseArgs(int& argc, char* argv[])
{"--static", &Arg_ForceStatic},
{"-us", &Arg_ForceUnaccountedStatic},
{"--unaccounted-static", &Arg_ForceUnaccountedStatic},
{"--cs-float", &Arg_CsFloatMode},
};
for (int32_t i = 2; i < argc; i++)
@ -392,6 +394,32 @@ void Arg_ForceUnaccountedStatic([[maybe_unused]] int& i, [[maybe_unused]] char*
Globals::Instance->forceUnaccountedStatic = true;
}
void Arg_CsFloatMode([[maybe_unused]] int& i, [[maybe_unused]] char* argv[])
{
i++;
if (std::strcmp(argv[i], "hex") == 0)
{
Globals::Instance->floatType = CsFloatType::HexOnly;
}
else if (std::strcmp(argv[i], "float") == 0)
{
Globals::Instance->floatType = CsFloatType::FloatOnly;
}
else if (std::strcmp(argv[i], "both") == 0)
{
Globals::Instance->floatType = CsFloatType::HexAndFloat;
}
else
{
Globals::Instance->floatType = CsFloatType::FloatOnly;
HANDLE_WARNING(
WarningType::Always, "Invalid CS Float Type",
StringHelper::Sprintf("Invalid CS float type entered. Expected \"hex\", \"float\", or "
"\"both\". Got %s.\n Defaulting to \"float\".",
argv[i]));
}
}
int HandleExtract(ZFileMode fileMode, ExporterSet* exporterSet)
{
bool procFileModeSuccess = false;

View file

@ -4,6 +4,9 @@
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZCutscene.h"
/**** GENERIC ****/
@ -126,42 +129,163 @@ std::string CutsceneMMCommand_GenericCmd::GetCommandMacro() const
/**** CAMERA ****/
CutsceneSubCommandEntry_Camera::CutsceneSubCommandEntry_Camera(const std::vector<uint8_t>& rawData,
offset_t rawDataIndex)
CutsceneSubCommandEntry_SplineCamPoint::CutsceneSubCommandEntry_SplineCamPoint(
const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
: CutsceneSubCommandEntry(rawData, rawDataIndex)
{
interpType = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0);
weight = BitConverter::ToUInt8BE(rawData, rawDataIndex + 1);
duration = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2);
posX = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4);
posY = BitConverter::ToUInt16BE(rawData, rawDataIndex + 6);
posZ = BitConverter::ToUInt16BE(rawData, rawDataIndex + 8);
relTo = BitConverter::ToUInt16BE(rawData, rawDataIndex + 10);
}
std::string CutsceneSubCommandEntry_Camera::GetBodySourceCode() const
std::string CutsceneSubCommandEntry_SplineCamPoint::GetBodySourceCode() const
{
return StringHelper::Sprintf("CMD_HH(0x%04X, 0x%04X)", base, startFrame);
const auto interpTypeMap = &Globals::Instance->cfg.enumData.interpType;
const auto relToMap = &Globals::Instance->cfg.enumData.relTo;
return StringHelper::Sprintf("CS_CAM_POINT(%s, 0x%02X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, %s)",
interpTypeMap->at(interpType).c_str(), weight, duration, posX,
posY, posZ, relToMap->at(relTo).c_str());
}
size_t CutsceneSubCommandEntry_Camera::GetRawSize() const
size_t CutsceneSubCommandEntry_SplineCamPoint::GetRawSize() const
{
return 0x0C;
}
CutsceneSubCommandEntry_SplineMiscPoint::CutsceneSubCommandEntry_SplineMiscPoint(
const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
: CutsceneSubCommandEntry(rawData, rawDataIndex)
{
unused0 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0);
roll = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2);
fov = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4);
unused1 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 6);
}
std::string CutsceneSubCommandEntry_SplineMiscPoint::GetBodySourceCode() const
{
return StringHelper::Sprintf("CS_CAM_MISC(0x%04X, 0x%04X, 0x%04X, 0x%04X)", unused0, roll, fov,
unused1);
}
size_t CutsceneSubCommandEntry_SplineMiscPoint::GetRawSize() const
{
return 0x08;
}
CutsceneSubCommandEntry_SplineHeader::CutsceneSubCommandEntry_SplineHeader(
const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
: CutsceneSubCommandEntry(rawData, rawDataIndex)
{
numEntries = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0);
unused0 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2);
unused1 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4);
duration = BitConverter::ToUInt16BE(rawData, rawDataIndex + 6);
}
std::string CutsceneSubCommandEntry_SplineHeader::GetBodySourceCode() const
{
return StringHelper::Sprintf("CS_CAM_SPLINE(0x%04X, 0x%04X, 0x%04X, 0x%04X)", numEntries,
unused0, unused1, duration);
}
size_t CutsceneSubCommandEntry_SplineHeader::GetRawSize() const
{
return 0x08;
}
CutsceneSubCommandEntry_SplineFooter::CutsceneSubCommandEntry_SplineFooter(
const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
: CutsceneSubCommandEntry(rawData, rawDataIndex)
{
uint16_t firstHalfWord = BitConverter::ToUInt16BE(rawData, rawDataIndex);
uint16_t secondHalfWord = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2);
if (firstHalfWord != 0xFFFF || secondHalfWord != 4)
{
HANDLE_ERROR(WarningType::InvalidExtractedData, "Invalid Spline Footer",
StringHelper::Sprintf(
"Invalid Spline footer. Was expecting 0xFFFF, 0x0004. Got 0x%04X, 0x%04X",
firstHalfWord, secondHalfWord));
}
}
std::string CutsceneSubCommandEntry_SplineFooter::GetBodySourceCode() const
{
return "CS_CAM_END()";
}
size_t CutsceneSubCommandEntry_SplineFooter::GetRawSize() const
{
return 0x04;
}
CutsceneMMCommand_Camera::CutsceneMMCommand_Camera(const std::vector<uint8_t>& rawData,
CutsceneMMCommand_Spline::CutsceneMMCommand_Spline(const std::vector<uint8_t>& rawData,
offset_t rawDataIndex)
: CutsceneCommand(rawData, rawDataIndex)
{
numHeaders = 0;
totalCommands = 0;
rawDataIndex += 4;
entries.reserve(numEntries);
for (size_t i = 0; i < numEntries / 4; i++)
while (1)
{
auto* entry = new CutsceneSubCommandEntry_Camera(rawData, rawDataIndex);
entries.push_back(entry);
rawDataIndex += entry->GetRawSize();
if (BitConverter::ToUInt16BE(rawData, rawDataIndex) == 0xFFFF)
{
break;
}
numHeaders++;
auto* header = new CutsceneSubCommandEntry_SplineHeader(rawData, rawDataIndex);
rawDataIndex += header->GetRawSize();
entries.push_back(header);
totalCommands += header->numEntries;
for (uint32_t i = 0; i < header->numEntries; i++)
{
auto* entry = new CutsceneSubCommandEntry_SplineCamPoint(rawData, rawDataIndex);
entries.push_back(entry);
rawDataIndex += entry->GetRawSize();
}
for (uint32_t i = 0; i < header->numEntries; i++)
{
auto* entry = new CutsceneSubCommandEntry_SplineCamPoint(rawData, rawDataIndex);
entries.push_back(entry);
rawDataIndex += entry->GetRawSize();
}
for (uint32_t i = 0; i < header->numEntries; i++)
{
auto* entry = new CutsceneSubCommandEntry_SplineMiscPoint(rawData, rawDataIndex);
entries.push_back(entry);
rawDataIndex += entry->GetRawSize();
}
}
auto* footer = new CutsceneSubCommandEntry_SplineFooter(rawData, rawDataIndex);
entries.push_back(footer);
rawDataIndex += footer->GetRawSize();
}
std::string CutsceneMMCommand_Camera::GetCommandMacro() const
std::string CutsceneMMCommand_Spline::GetCommandMacro() const
{
return StringHelper::Sprintf("CS_CAM_SPLINE_LIST(%i)", numEntries);
}
size_t CutsceneMMCommand_Spline::GetCommandSize() const
{
// 8 Bytes once for the spline command, 8 Bytes per spline the header, two groups of size 12, 1
// group of size 8, 4 bytes for the footer.
return 8 + (8 * numHeaders) + ((totalCommands * 2) * 0xC) + (totalCommands * 8) + 4;
}
/**** TRANSITION GENERAL ****/
CutsceneSubCommandEntry_TransitionGeneral::CutsceneSubCommandEntry_TransitionGeneral(
@ -434,22 +558,29 @@ CutsceneMMSubCommandEntry_ActorCue::CutsceneMMSubCommandEntry_ActorCue(
std::string CutsceneMMSubCommandEntry_ActorCue::GetBodySourceCode() const
{
EnumData* enumData = &Globals::Instance->cfg.enumData;
std::string normalXStr =
ZCutscene::GetCsEncodedFloat(normalX, Globals::Instance->floatType, true);
std::string normalYStr =
ZCutscene::GetCsEncodedFloat(normalY, Globals::Instance->floatType, true);
std::string normalZStr =
ZCutscene::GetCsEncodedFloat(normalZ, Globals::Instance->floatType, true);
if (static_cast<CutsceneMM_CommandType>(commandID) == CutsceneMM_CommandType::CS_CMD_PLAYER_CUE)
{
return StringHelper::Sprintf("CS_PLAYER_CUE(%s, %i, %i, 0x%04X, 0x%04X, 0x%04X, %i, %i, "
"%i, %i, %i, %i, %.8ef, %.8ef, %.8ef)",
"%i, %i, %i, %i, %s, %s, %s)",
enumData->playerCueId[base].c_str(), startFrame, endFrame,
rotX, rotY, rotZ, startPosX, startPosY, startPosZ, endPosX,
endPosY, endPosZ, normalX, normalY, normalZ);
endPosY, endPosZ, normalXStr.c_str(), normalYStr.c_str(),
normalZStr.c_str());
}
else
{
return StringHelper::Sprintf("CS_ACTOR_CUE(%i, %i, %i, 0x%04X, 0x%04X, 0x%04X, %i, %i, "
"%i, %i, %i, %i, %.8ef, %.8ef, %.8ef)",
"%i, %i, %i, %i, %s, %s, %s)",
base, startFrame, endFrame, rotX, rotY, rotZ, startPosX,
startPosY, startPosZ, endPosX, endPosY, endPosZ, normalX,
normalY, normalZ);
startPosY, startPosZ, endPosX, endPosY, endPosZ,
normalXStr.c_str(), normalYStr.c_str(), normalZStr.c_str());
}
}

View file

@ -268,24 +268,79 @@ public:
// TODO: MM cutscene camera command is implemented as a placeholder until we better understand how
// it works
class CutsceneSubCommandEntry_Camera : public CutsceneSubCommandEntry
class CutsceneSubCommandEntry_SplineCamPoint : public CutsceneSubCommandEntry
{
public:
uint32_t unk_08;
uint8_t interpType;
uint8_t weight;
uint16_t duration;
CutsceneSubCommandEntry_Camera(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
uint16_t posX;
uint16_t posY;
uint16_t posZ;
uint16_t relTo;
CutsceneSubCommandEntry_SplineCamPoint(const std::vector<uint8_t>& rawData,
offset_t rawDataIndex);
std::string GetBodySourceCode() const override;
size_t GetRawSize() const override;
};
class CutsceneMMCommand_Camera : public CutsceneCommand
class CutsceneSubCommandEntry_SplineMiscPoint : public CutsceneSubCommandEntry
{
public:
CutsceneMMCommand_Camera(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
uint16_t unused0;
uint16_t roll;
uint16_t fov;
uint16_t unused1;
CutsceneSubCommandEntry_SplineMiscPoint(const std::vector<uint8_t>& rawData,
offset_t rawDataIndex);
std::string GetBodySourceCode() const override;
size_t GetRawSize() const override;
};
class CutsceneSubCommandEntry_SplineFooter : public CutsceneSubCommandEntry
{
public:
CutsceneSubCommandEntry_SplineFooter(const std::vector<uint8_t>& rawData,
offset_t rawDataIndex);
std::string GetBodySourceCode() const override;
size_t GetRawSize() const override;
};
class CutsceneSubCommandEntry_SplineHeader : public CutsceneSubCommandEntry
{
public:
uint16_t numEntries;
uint16_t unused0;
uint16_t unused1;
uint16_t duration;
CutsceneSubCommandEntry_SplineHeader(const std::vector<uint8_t>& rawData,
offset_t rawDataIndex);
std::string GetBodySourceCode() const override;
size_t GetRawSize() const override;
};
class CutsceneMMCommand_Spline : public CutsceneCommand
{
public:
uint32_t numHeaders;
uint32_t totalCommands;
CutsceneMMCommand_Spline(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
std::string GetCommandMacro() const override;
size_t GetCommandSize() const override;
};
/**** TRANSITION GENERAL ****/

View file

@ -6,6 +6,8 @@
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "ZCutscene.h"
/**** GENERIC ****/
// Specific for command lists where each entry has size 0x30 bytes
@ -139,9 +141,11 @@ std::string CutsceneOoTCommand_CameraPoint::GetBodySourceCode() const
if (continueFlag != 0)
continueMacro = "CS_CAM_STOP";
return StringHelper::Sprintf("CS_CAM_POINT(%s, 0x%02X, %i, %ff, %i, %i, %i, 0x%04X)",
continueMacro.c_str(), cameraRoll, nextPointFrame, viewAngle, posX,
posY, posZ, unused);
return StringHelper::Sprintf(
"CS_CAM_POINT(%s, 0x%02X, %i, %s, %i, %i, %i, 0x%04X)", continueMacro.c_str(), cameraRoll,
nextPointFrame,
ZCutscene::GetCsEncodedFloat(viewAngle, Globals::Instance->floatType, false).c_str(), posX,
posY, posZ, unused);
}
size_t CutsceneOoTCommand_CameraPoint::GetRawSize() const
@ -334,27 +338,34 @@ CutsceneOoTSubCommandEntry_ActorCue::CutsceneOoTSubCommandEntry_ActorCue(
normalY = BitConverter::ToFloatBE(rawData, rawDataIndex + 0x28);
normalZ = BitConverter::ToFloatBE(rawData, rawDataIndex + 0x2C);
}
std::string CutsceneOoTSubCommandEntry_ActorCue::GetBodySourceCode() const
{
EnumData* enumData = &Globals::Instance->cfg.enumData;
std::string normalXStr =
ZCutscene::GetCsEncodedFloat(normalX, Globals::Instance->floatType, true);
std::string normalYStr =
ZCutscene::GetCsEncodedFloat(normalY, Globals::Instance->floatType, true);
std::string normalZStr =
ZCutscene::GetCsEncodedFloat(normalZ, Globals::Instance->floatType, true);
if (static_cast<CutsceneOoT_CommandType>(commandID) ==
CutsceneOoT_CommandType::CS_CMD_PLAYER_CUE)
{
return StringHelper::Sprintf("CS_PLAYER_CUE(%s, %i, %i, 0x%04X, 0x%04X, 0x%04X, %i, %i, "
"%i, %i, %i, %i, %.8ef, %.8ef, %.8ef)",
"%i, %i, %i, %i, %s, %s, %s)",
enumData->playerCueId[base].c_str(), startFrame, endFrame,
rotX, rotY, rotZ, startPosX, startPosY, startPosZ, endPosX,
endPosY, endPosZ, normalX, normalY, normalZ);
endPosY, endPosZ, normalXStr.c_str(), normalYStr.c_str(),
normalZStr.c_str());
}
else
{
return StringHelper::Sprintf("CS_ACTOR_CUE(%i, %i, %i, 0x%04X, 0x%04X, 0x%04X, %i, %i, "
"%i, %i, %i, %i, %.8ef, %.8ef, %.8ef)",
"%i, %i, %i, %i, %s, %s, %s)",
base, startFrame, endFrame, rotX, rotY, rotZ, startPosX,
startPosY, startPosZ, endPosX, endPosY, endPosZ, normalX,
normalY, normalZ);
startPosY, startPosZ, endPosX, endPosY, endPosZ,
normalXStr.c_str(), normalYStr.c_str(), normalZStr.c_str());
}
}

View file

@ -45,6 +45,7 @@
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<EnableASAN>false</EnableASAN>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
@ -52,6 +53,7 @@
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<EnableASAN>false</EnableASAN>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@ -186,21 +188,24 @@ mkdir build\ZAPD
<ClCompile Include="ImageBackend.cpp" />
<ClCompile Include="Main.cpp" />
<ClCompile Include="OtherStructs\CutsceneMM_Commands.cpp" />
<ClCompile Include="OtherStructs\Cutscene_Commands.cpp" />
<ClCompile Include="OtherStructs\CutsceneOoT_Commands.cpp" />
<ClCompile Include="OtherStructs\Cutscene_Common.cpp" />
<ClCompile Include="OtherStructs\SkinLimbStructs.cpp" />
<ClCompile Include="OutputFormatter.cpp" />
<ClCompile Include="WarningHandler.cpp" />
<ClCompile Include="ZActorList.cpp" />
<ClCompile Include="ZArray.cpp" />
<ClCompile Include="ZBackground.cpp" />
<ClCompile Include="ZCKeyFrame.cpp" />
<ClCompile Include="ZCKeyFrameAnim.cpp" />
<ClCompile Include="ZCollisionPoly.cpp" />
<ClCompile Include="ZLimb.cpp" />
<ClCompile Include="ZMtx.cpp" />
<ClCompile Include="ZPath.cpp" />
<ClCompile Include="ZPlayerAnimationData.cpp" />
<ClCompile Include="ZRoom\Commands\SetActorCutsceneList.cpp" />
<ClCompile Include="ZRoom\Commands\SetAnimatedMaterialList.cpp" />
<ClCompile Include="ZRoom\Commands\SetCsCamera.cpp" />
<ClCompile Include="ZRoom\Commands\SetCutsceneEntryList.cpp" />
<ClCompile Include="ZRoom\Commands\SetMinimapChests.cpp" />
<ClCompile Include="ZRoom\Commands\SetMinimapList.cpp" />
<ClCompile Include="ZRoom\Commands\SetWorldMapVisited.cpp" />
@ -278,7 +283,8 @@ mkdir build\ZAPD
<ClInclude Include="Globals.h" />
<ClInclude Include="ImageBackend.h" />
<ClInclude Include="OtherStructs\CutsceneMM_Commands.h" />
<ClInclude Include="OtherStructs\Cutscene_Commands.h" />
<ClInclude Include="OtherStructs\CutsceneOoT_Commands.h" />
<ClInclude Include="OtherStructs\Cutscene_Common.h" />
<ClInclude Include="OtherStructs\SkinLimbStructs.h" />
<ClInclude Include="OutputFormatter.h" />
<ClInclude Include="WarningHandler.h" />
@ -287,6 +293,8 @@ mkdir build\ZAPD
<ClInclude Include="ZArray.h" />
<ClInclude Include="ZBackground.h" />
<ClInclude Include="ZBlob.h" />
<ClInclude Include="ZCKeyFrame.h" />
<ClInclude Include="ZCkeyFrameAnim.h" />
<ClInclude Include="ZCollision.h" />
<ClInclude Include="ZCollisionPoly.h" />
<ClInclude Include="ZCutscene.h" />
@ -296,9 +304,9 @@ mkdir build\ZAPD
<ClInclude Include="ZMtx.h" />
<ClInclude Include="ZPath.h" />
<ClInclude Include="ZPlayerAnimationData.h" />
<ClInclude Include="ZRoom\Commands\SetActorCutsceneList.h" />
<ClInclude Include="ZRoom\Commands\SetAnimatedMaterialList.h" />
<ClInclude Include="ZRoom\Commands\SetCsCamera.h" />
<ClInclude Include="ZRoom\Commands\SetCutsceneEntryList.h" />
<ClInclude Include="ZRoom\Commands\SetMinimapChests.h" />
<ClInclude Include="ZRoom\Commands\SetMinimapList.h" />
<ClInclude Include="ZRoom\Commands\SetWorldMapVisited.h" />

View file

@ -228,9 +228,6 @@
<ClCompile Include="ZRoom\Commands\Unused1D.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetActorCutsceneList.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetCsCamera.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
@ -279,9 +276,6 @@
<ClCompile Include="ZCollisionPoly.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="OtherStructs\Cutscene_Commands.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="OtherStructs\CutsceneMM_Commands.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
@ -297,6 +291,21 @@
<ClCompile Include="ZWaterbox.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="OtherStructs\CutsceneOoT_Commands.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="OtherStructs\Cutscene_Common.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetCutsceneEntryList.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZCKeyFrame.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZCKeyFrameAnim.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ZRoom\ZRoom.h">
@ -497,9 +506,6 @@
<ClInclude Include="ZRoom\Commands\SetWorldMapVisited.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetActorCutsceneList.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\Unused1D.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
@ -548,9 +554,6 @@
<ClInclude Include="ZCollisionPoly.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="OtherStructs\Cutscene_Commands.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="OtherStructs\CutsceneMM_Commands.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
@ -569,6 +572,21 @@
<ClInclude Include="ZWaterbox.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="OtherStructs\Cutscene_Common.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="OtherStructs\CutsceneOoT_Commands.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetCutsceneEntryList.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZCKeyFrame.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZCkeyFrameAnim.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="..\SymbolMap_OoTMqDbg.txt">

View file

@ -0,0 +1,302 @@
#include "ZCKeyFrame.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
REGISTER_ZFILENODE(KeyFrameSkel, ZKeyFrameSkel);
REGISTER_ZFILENODE(KeyFrameLimbList, ZKeyFrameLimbList);
ZKeyFrameSkel::ZKeyFrameSkel(ZFile* nParent) : ZResource(nParent)
{
RegisterRequiredAttribute("LimbType");
}
ZKeyFrameSkel::~ZKeyFrameSkel()
{
}
ZKeyFrameLimb::ZKeyFrameLimb(ZFile* nParent) : ZResource(nParent)
{
}
ZKeyFrameStandardLimb::ZKeyFrameStandardLimb(ZFile* nParent) : ZKeyFrameLimb(nParent)
{
}
ZKeyFrameFlexLimb::ZKeyFrameFlexLimb(ZFile* nParent) : ZKeyFrameLimb(nParent)
{
}
ZKeyFrameLimbList::ZKeyFrameLimbList(ZFile* nParent) : ZResource(nParent)
{
RegisterRequiredAttribute("LimbType");
RegisterRequiredAttribute("LimbCount");
}
ZKeyFrameLimbList::ZKeyFrameLimbList(ZFile* nParent, uint32_t limbCount, ZKeyframeSkelType type)
: ZResource(nParent)
{
numLimbs = limbCount;
limbType = type;
}
ZKeyFrameLimbList::~ZKeyFrameLimbList()
{
for (const auto l : limbs)
delete l;
}
void ZKeyFrameSkel::ParseXML(tinyxml2::XMLElement* reader)
{
ZResource::ParseXML(reader);
std::string limbTypeStr = registeredAttributes.at("LimbType").value;
limbType = ZKeyFrameLimbList::ParseLimbTypeStr(limbTypeStr);
if (limbType == ZKeyframeSkelType::Error)
HANDLE_ERROR_RESOURCE(
WarningType::InvalidXML, parent, this, rawDataIndex, "Invalid limb type",
StringHelper::Sprintf("Invalid limb type. Was expecting 'Flex' or 'Normal'. Got %s.",
limbTypeStr.c_str()));
}
void ZKeyFrameLimbList::ParseXML(tinyxml2::XMLElement* reader)
{
ZResource::ParseXML(reader);
std::string limbTypeStr = registeredAttributes.at("LimbType").value;
std::string numLimbStr = registeredAttributes.at("LimbCount").value;
limbType = ParseLimbTypeStr(limbTypeStr);
if (limbType == ZKeyframeSkelType::Error)
HANDLE_ERROR_RESOURCE(
WarningType::InvalidXML, parent, this, rawDataIndex, "Invalid limb type",
StringHelper::Sprintf("Invalid limb type. Was expecting 'Flex' or 'Normal'. Got %s.",
limbTypeStr.c_str()));
numLimbs = (uint8_t)StringHelper::StrToL(numLimbStr);
}
void ZKeyFrameSkel::ParseRawData()
{
ZResource::ParseRawData();
const auto& rawData = parent->GetRawData();
limbCount = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0);
dListCount = BitConverter::ToUInt8BE(rawData, rawDataIndex + 1);
limbsPtr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 4);
limbList = std::make_unique<ZKeyFrameLimbList>(parent, limbCount, limbType);
limbList->SetRawDataIndex(GETSEGOFFSET(limbsPtr));
limbList->ParseRawData();
}
void ZKeyFrameSkel::DeclareReferences(const std::string& prefix)
{
std::string defaultPrefix = name;
std::string declaration;
if (defaultPrefix == "")
defaultPrefix = prefix;
ZResource::DeclareReferences(defaultPrefix);
declaration += limbList->GetBodySourceCode();
parent->AddDeclarationArray(
GETSEGOFFSET(limbsPtr), DeclarationAlignment::Align4, limbList->GetRawDataSize(),
limbList->GetSourceTypeName(),
StringHelper::Sprintf("%s_KeyFrameLimbs_%06X", prefix.c_str(), rawDataIndex),
limbList->limbs.size(), declaration);
}
std::string ZKeyFrameSkel::GetBodySourceCode() const
{
std::string limbStr;
if (limbType == ZKeyframeSkelType::Normal)
Globals::Instance->GetSegmentedPtrName(limbsPtr, parent, "KeyFrameStandardLimb", limbStr);
else
Globals::Instance->GetSegmentedPtrName(limbsPtr, parent, "KeyFrameFlexLimb", limbStr);
return StringHelper::Sprintf("\n\t0x%02X, 0x%02X, %s\n", limbCount, dListCount,
limbStr.c_str());
}
size_t ZKeyFrameSkel::GetRawDataSize() const
{
return 0x8;
}
std::string ZKeyFrameSkel::GetSourceTypeName() const
{
return "KeyFrameSkeleton";
}
ZResourceType ZKeyFrameSkel::GetResourceType() const
{
return ZResourceType::KeyFrameSkel;
}
size_t ZKeyFrameStandardLimb::GetRawDataSize() const
{
return 0xC;
}
size_t ZKeyFrameFlexLimb::GetRawDataSize() const
{
return 0x8;
}
size_t ZKeyFrameLimbList::GetRawDataSize() const
{
size_t limbSize;
if (limbType == ZKeyframeSkelType::Flex)
limbSize = 0x8;
else
limbSize = 0xC;
return limbSize * numLimbs;
}
ZKeyframeSkelType ZKeyFrameLimbList::ParseLimbTypeStr(const std::string& typeStr)
{
if (typeStr == "Flex")
return ZKeyframeSkelType::Flex;
else if (typeStr == "Normal")
return ZKeyframeSkelType::Normal;
else
return ZKeyframeSkelType::Error;
}
void ZKeyFrameLimb::ParseRawData()
{
const auto& rawData = parent->GetRawData();
dlist = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x0);
numChildren = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x4);
flags = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x5);
}
void ZKeyFrameStandardLimb::ParseRawData()
{
const auto& rawData = parent->GetRawData();
ZKeyFrameLimb::ParseRawData();
translation.x = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x6);
translation.y = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x8);
translation.z = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0xA);
}
void ZKeyFrameFlexLimb::ParseRawData()
{
const auto& rawData = parent->GetRawData();
ZKeyFrameLimb::ParseRawData();
callbackIndex = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x6);
}
void ZKeyFrameLimbList::ParseRawData()
{
limbs.reserve(numLimbs);
rawDataIndex = GetRawDataIndex();
for (uint32_t i = 0; i < numLimbs; i++)
{
ZKeyFrameLimb* limb;
if (limbType == ZKeyframeSkelType::Flex)
limb = new ZKeyFrameFlexLimb(parent);
else
limb = new ZKeyFrameStandardLimb(parent);
limb->SetRawDataIndex(rawDataIndex + (offset_t)(i * limb->GetRawDataSize()));
limb->ParseRawData();
limbs.push_back(limb);
}
}
std::string ZKeyFrameLimbList::GetBodySourceCode() const
{
std::string declaration;
for (const auto l : limbs)
declaration += StringHelper::Sprintf("\t{ %s },\n", l->GetBodySourceCode().c_str());
// Remove last newline
return declaration.substr(0, declaration.length() - 1);
}
std::string ZKeyFrameStandardLimb::GetBodySourceCode() const
{
std::string declaration;
std::string dlString;
Globals::Instance->GetSegmentedArrayIndexedName(dlist, 8, parent, "Gfx", dlString);
declaration +=
StringHelper::Sprintf("%s, 0x%02X, 0x%02X, { 0x%04X, 0x%04X, 0x%04X},", dlString.c_str(),
numChildren, flags, translation.x, translation.y, translation.z);
return declaration;
}
std::string ZKeyFrameFlexLimb::GetBodySourceCode() const
{
std::string declaration;
std::string dlString;
Globals::Instance->GetSegmentedArrayIndexedName(dlist, 8, parent, "Gfx", dlString);
declaration += StringHelper::Sprintf("%s, 0x%02X, 0x%02X, 0x%02X", dlString.c_str(),
numChildren, flags, callbackIndex);
return declaration;
}
std::string ZKeyFrameStandardLimb::GetSourceTypeName() const
{
return "KeyFrameStandardLimb";
}
std::string ZKeyFrameFlexLimb::GetSourceTypeName() const
{
return "KeyFrameFlexLimb";
}
std::string ZKeyFrameLimbList::GetSourceTypeName() const
{
switch (limbType)
{
case ZKeyframeSkelType::Flex:
return "KeyFrameFlexLimb";
case ZKeyframeSkelType::Normal:
return "KeyFrameStandardLimb";
default:
HANDLE_ERROR_RESOURCE(WarningType::InvalidXML, parent, this, rawDataIndex,
"Invalid limb type", "");
break;
}
}
ZResourceType ZKeyFrameStandardLimb::GetResourceType() const
{
return ZResourceType::KeyFrameStandardLimb;
}
ZResourceType ZKeyFrameFlexLimb::GetResourceType() const
{
return ZResourceType::KeyFrameFlexLimb;
}
ZResourceType ZKeyFrameLimbList::GetResourceType() const
{
switch (limbType)
{
case ZKeyframeSkelType::Flex:
return ZResourceType::KeyFrameFlexLimb;
case ZKeyframeSkelType::Normal:
return ZResourceType::KeyFrameStandardLimb;
default:
HANDLE_ERROR_RESOURCE(WarningType::InvalidXML, parent, this, rawDataIndex,
"Invalid limb type", "");
break;
}
}

View file

@ -0,0 +1,121 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include <memory>
#include "ZFile.h"
class ZKeyFrameLimb;
struct Vec3s
{
int16_t x;
int16_t y;
int16_t z;
};
enum class ZKeyframeSkelType
{
Normal,
Flex,
Error,
};
class ZKeyFrameLimbList : public ZResource
{
public:
ZKeyFrameLimbList();
ZKeyFrameLimbList(ZFile* nParent);
ZKeyFrameLimbList(ZFile* nParent, uint32_t limbCount, ZKeyframeSkelType type);
~ZKeyFrameLimbList();
void ParseRawData() override;
std::string GetBodySourceCode() const override;
void ParseXML(tinyxml2::XMLElement* reader) override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
static ZKeyframeSkelType ParseLimbTypeStr(const std::string& typeStr);
std::vector<ZKeyFrameLimb*> limbs;
ZKeyframeSkelType limbType;
uint8_t numLimbs;
};
class ZKeyFrameLimb : public ZResource
{
public:
segptr_t dlist;
uint8_t numChildren;
uint8_t flags;
ZKeyFrameLimb(ZFile* nParent);
void ParseRawData() override;
};
class ZKeyFrameStandardLimb : public ZKeyFrameLimb
{
public:
Vec3s translation;
ZKeyFrameStandardLimb(ZFile* nParent);
void ParseRawData() override;
std::string GetBodySourceCode() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
};
class ZKeyFrameFlexLimb : public ZKeyFrameLimb
{
public:
uint8_t callbackIndex;
ZKeyFrameFlexLimb(ZFile* nParent);
// void ParseXML(tinyxml2::XMLElement* reader) override;
void ParseRawData() override;
std::string GetBodySourceCode() const override;
// std::string GetSourceOutputHeader(const std::string& prefix) override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
};
class ZKeyFrameSkel : public ZResource
{
public:
std::unique_ptr<ZKeyFrameLimbList> limbList;
segptr_t limbsPtr;
ZKeyframeSkelType limbType;
uint8_t limbCount;
uint8_t dListCount;
ZKeyFrameSkel(ZFile* nParent);
~ZKeyFrameSkel();
void ParseXML(tinyxml2::XMLElement* reader) override;
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
};

View file

@ -0,0 +1,219 @@
#include "ZCkeyFrameAnim.h"
#include "ZCKeyFrame.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
REGISTER_ZFILENODE(KeyFrameAnimation, ZKeyFrameAnim);
ZKeyFrameAnim::ZKeyFrameAnim(ZFile* nParent) : ZResource(nParent)
{
RegisterRequiredAttribute("Skel");
}
ZKeyFrameAnim::~ZKeyFrameAnim()
{
}
void ZKeyFrameAnim::ParseXML(tinyxml2::XMLElement* reader)
{
ZResource::ParseXML(reader);
std::string skelAddrStr = registeredAttributes.at("Skel").value;
skelOffset = (offset_t)StringHelper::StrToL(skelAddrStr, 16);
}
void ZKeyFrameAnim::DeclareReferencesLate(const std::string& prefix)
{
std::string defaultPrefix = name;
std::string declaration;
if (defaultPrefix == "")
defaultPrefix = prefix;
ZResource::DeclareReferences(defaultPrefix);
declaration += "\t";
if (skel->limbType == ZKeyframeSkelType::Normal)
{
for (const auto b : bitFlags)
{
declaration += StringHelper::Sprintf("0x%02X, ", b);
parent->AddDeclarationArray(
GETSEGOFFSET(bitFlagsAddr), DeclarationAlignment::Align4, bitFlags.size(), "u8",
StringHelper::Sprintf("%s_bitFlags_%06X", prefix.c_str(), rawDataIndex),
bitFlags.size(), declaration);
}
}
else
{
for (const auto b : bitFlagsFlex)
{
declaration += StringHelper::Sprintf("0x%04X, ", b);
parent->AddDeclarationArray(
GETSEGOFFSET(bitFlagsAddr), DeclarationAlignment::Align4, bitFlagsFlex.size() * 2,
"u16", StringHelper::Sprintf("%s_flexBitFlags_%06X", prefix.c_str(), rawDataIndex),
bitFlagsFlex.size(), declaration);
}
}
declaration.clear();
for (const auto kf : keyFrames)
{
declaration +=
StringHelper::Sprintf(" \t { %i, %i, %i, },\n", kf.frame, kf.value, kf.velocity);
}
// Remove last new line to prevent an extra line after the last element
declaration = declaration.substr(0, declaration.length() - 1);
parent->AddDeclarationArray(
GETSEGOFFSET(keyFramesAddr), DeclarationAlignment::Align4, keyFrames.size() * 6, "KeyFrame",
StringHelper::Sprintf("%s_KeyFrame_%06X", prefix.c_str(), rawDataIndex), keyFrames.size(),
declaration);
declaration.clear();
declaration += "\t";
for (const auto kfNum : kfNums)
{
declaration += StringHelper::Sprintf("0x%04X, ", kfNum);
}
parent->AddDeclarationArray(
GETSEGOFFSET(kfNumsAddr), DeclarationAlignment::Align4, kfNums.size() * 2, "s16",
StringHelper::Sprintf("%s_kfNums_%06X", prefix.c_str(), rawDataIndex), kfNums.size(),
declaration);
declaration += "\n";
declaration.clear();
declaration += "\t";
for (const auto pv : presetValues)
{
declaration += StringHelper::Sprintf("0x%04X, ", pv);
}
declaration += "\n";
parent->AddDeclarationArray(
GETSEGOFFSET(presentValuesAddr), DeclarationAlignment::Align4, presetValues.size() * 2,
"s16", StringHelper::Sprintf("%s_presetValues_%06X", prefix.c_str(), rawDataIndex),
presetValues.size(), declaration);
}
// ParseRawDataLate is used because we need to make sure the flex skel has been processed first.
void ZKeyFrameAnim::ParseRawDataLate()
{
const auto& rawData = parent->GetRawData();
skel = static_cast<ZKeyFrameSkel*>(parent->FindResource(skelOffset));
size_t numLimbs = skel->limbCount;
bitFlagsAddr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x0);
keyFramesAddr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x4);
kfNumsAddr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x8);
presentValuesAddr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0xC);
uint32_t kfNumsSize = 0;
uint32_t presetValuesSize = 0;
uint32_t keyFramesCount = 0;
if (skel->limbType == ZKeyframeSkelType::Normal)
{
bitFlags.reserve(numLimbs);
for (size_t i = 0; i < numLimbs; i++)
{
uint8_t e = BitConverter::ToUInt8BE(rawData, GETSEGOFFSET(bitFlagsAddr) + i);
bitFlags.push_back(e);
kfNumsSize += GetSetBits((uint8_t)(e & 0b111111));
presetValuesSize += GetSetBits((uint8_t)((e ^ 0xFF) & 0b111111));
}
}
else
{
bitFlagsFlex.reserve(numLimbs);
for (size_t i = 0; i < numLimbs; i++)
{
uint16_t e = BitConverter::ToUInt16BE(rawData, GETSEGOFFSET(bitFlagsAddr) + (i * 2));
bitFlagsFlex.push_back(e);
kfNumsSize += GetSetBits((uint16_t)(e & 0b111111111));
presetValuesSize += GetSetBits((uint16_t)((e ^ 0xFFFF) & 0b111111111));
}
}
kfNums.reserve(kfNumsSize);
for (uint32_t i = 0; i < kfNumsSize; i++)
{
int16_t kfNum = BitConverter::ToUInt16BE(rawData, GETSEGOFFSET(kfNumsAddr) + (i * 2));
keyFramesCount += kfNum;
kfNums.push_back(kfNum);
}
keyFrames.reserve(keyFramesCount);
for (uint32_t i = 0; i < keyFramesCount; i++)
{
KeyFrame kf;
kf.frame = BitConverter::ToInt16BE(rawData, (GETSEGOFFSET(keyFramesAddr) + 0) + (i * 6));
kf.value = BitConverter::ToInt16BE(rawData, (GETSEGOFFSET(keyFramesAddr) + 2) + (i * 6));
kf.velocity = BitConverter::ToInt16BE(rawData, (GETSEGOFFSET(keyFramesAddr) + 4) + (i * 6));
keyFrames.push_back(kf);
}
presetValues.reserve(presetValuesSize);
for (uint32_t i = 0; i < presetValuesSize; i++)
{
presetValues.push_back(
BitConverter::ToInt16BE(rawData, GETSEGOFFSET(presentValuesAddr) + (i * 2)));
}
unk_10 = BitConverter::ToInt16BE(rawData, GETSEGOFFSET(rawDataIndex) + 0x10);
duration = BitConverter::ToInt16BE(rawData, GETSEGOFFSET(rawDataIndex) + 0x12);
}
std::string ZKeyFrameAnim::GetBodySourceCode() const
{
std::string declaration;
std::string bitFlagsStr;
std::string keyFrameStr;
std::string kfNumsStr;
std::string presetValuesStr;
Globals::Instance->GetSegmentedPtrName(bitFlagsAddr, parent, "", bitFlagsStr);
Globals::Instance->GetSegmentedPtrName(keyFramesAddr, parent, "", keyFrameStr);
Globals::Instance->GetSegmentedPtrName(kfNumsAddr, parent, "", kfNumsStr);
Globals::Instance->GetSegmentedPtrName(presentValuesAddr, parent, "", presetValuesStr);
return StringHelper::Sprintf("\n\t%s, %s, %s, %s, 0x%04X, 0x%04X\n", bitFlagsStr.c_str(),
keyFrameStr.c_str(), kfNumsStr.c_str(), presetValuesStr.c_str(),
unk_10, duration);
}
std::string ZKeyFrameAnim::GetSourceTypeName() const
{
return "KeyFrameAnimation";
}
ZResourceType ZKeyFrameAnim::GetResourceType() const
{
return ZResourceType::KeyFrameAnimation;
}
size_t ZKeyFrameAnim::GetRawDataSize() const
{
return 0x14;
}
template <typename T>
uint32_t ZKeyFrameAnim::GetSetBits(T data) const
{
uint32_t num = 0;
for (size_t i = 0; i < sizeof(T) * 8; i++)
{
if ((data >> i) & 1)
num++;
}
return num;
}

View file

@ -0,0 +1,52 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include <memory>
#include "ZFile.h"
class ZKeyFrameSkel;
typedef struct
{
int16_t frame;
int16_t value;
int16_t velocity;
} KeyFrame;
class ZKeyFrameAnim : public ZResource
{
public:
ZKeyFrameSkel* skel;
std::vector<uint8_t> bitFlags; // Standard only
std::vector<uint16_t> bitFlagsFlex; // Flex only
std::vector<KeyFrame> keyFrames;
std::vector<int16_t> kfNums;
std::vector<int16_t> presetValues;
uint16_t unk_10;
int16_t duration;
ZKeyFrameAnim(ZFile* nParent);
~ZKeyFrameAnim();
void ParseXML(tinyxml2::XMLElement* reader) override;
void DeclareReferencesLate(const std::string& prefix) override;
void ParseRawDataLate() override;
std::string GetBodySourceCode() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
private:
offset_t skelOffset;
segptr_t bitFlagsAddr;
segptr_t keyFramesAddr;
segptr_t kfNumsAddr;
segptr_t presentValuesAddr;
template <typename T>
uint32_t GetSetBits(T data) const;
};

View file

@ -323,7 +323,7 @@ CutsceneCommand* ZCutscene::GetCommandMM(uint32_t id, offset_t currentPtr) const
return new CutsceneMMCommand_Text(rawData, currentPtr);
case CutsceneMM_CommandType::CS_CMD_CAMERA_SPLINE:
return new CutsceneMMCommand_Camera(rawData, currentPtr);
return new CutsceneMMCommand_Spline(rawData, currentPtr);
case CutsceneMM_CommandType::CS_CMD_TRANSITION_GENERAL:
return new CutsceneMMCommand_TransitionGeneral(rawData, currentPtr);
@ -372,3 +372,36 @@ ZResourceType ZCutscene::GetResourceType() const
{
return ZResourceType::Cutscene;
}
std::string ZCutscene::GetCsEncodedFloat(float f, CsFloatType type, bool useSciNotation)
{
switch (type)
{
default:
// This default case will NEVER be reached, but GCC still gives a warning.
case CsFloatType::HexOnly:
{
uint32_t i;
std::memcpy(&i, &f, sizeof(i));
return StringHelper::Sprintf("0x%08X", i);
}
case CsFloatType::FloatOnly:
{
if (useSciNotation)
{
return StringHelper::Sprintf("%.8ef", f);
}
return StringHelper::Sprintf("%ff", f);
}
case CsFloatType::HexAndFloat:
{
uint32_t i;
std::memcpy(&i, &f, sizeof(i));
if (useSciNotation)
{
return StringHelper::Sprintf("CS_FLOAT(0x%08X, %.8ef)", i, f);
}
return StringHelper::Sprintf("CS_FLOAT(0x%08X, %ff)", i, f);
}
}
}

View file

@ -10,6 +10,8 @@
#include "ZFile.h"
#include "ZResource.h"
enum class CsFloatType;
class ZCutscene : public ZResource
{
public:
@ -27,6 +29,8 @@ public:
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
static std::string GetCsEncodedFloat(float f, CsFloatType type, bool useSciNotation);
int32_t numCommands;
int32_t endFrame;
std::vector<CutsceneCommand*> commands;

View file

@ -55,6 +55,10 @@ enum class ZResourceType
Vector,
Vertex,
Waterbox,
KeyFrameFlexLimb,
KeyFrameStandardLimb,
KeyFrameSkel,
KeyFrameAnimation,
};
class ResourceAttribute