diff --git a/assets/xml/objects/gameplay_keep.xml b/assets/xml/objects/gameplay_keep.xml
index 5881fcb37e..d7c6a93753 100644
--- a/assets/xml/objects/gameplay_keep.xml
+++ b/assets/xml/objects/gameplay_keep.xml
@@ -970,15 +970,12 @@
-
-
-
+
-
-
+
@@ -1333,10 +1330,7 @@
-
-
-
-
+
@@ -1345,8 +1339,7 @@
-
-
+
@@ -1450,8 +1443,7 @@
-
-
+
@@ -1482,8 +1474,7 @@
-
-
+
diff --git a/assets/xml/objects/object_fall2.xml b/assets/xml/objects/object_fall2.xml
index 70c8ca2d4c..1ad99a8a33 100644
--- a/assets/xml/objects/object_fall2.xml
+++ b/assets/xml/objects/object_fall2.xml
@@ -12,8 +12,7 @@
-
-
+
@@ -30,6 +29,6 @@
-
+
diff --git a/assets/xml/objects/object_moonend.xml b/assets/xml/objects/object_moonend.xml
index c23659dce4..9b9e078a27 100644
--- a/assets/xml/objects/object_moonend.xml
+++ b/assets/xml/objects/object_moonend.xml
@@ -1,8 +1,6 @@
-
-
-
+
@@ -21,10 +19,8 @@
-
-
-
-
+
+
@@ -34,7 +30,7 @@
-
+
diff --git a/assets/xml/objects/object_syoten.xml b/assets/xml/objects/object_syoten.xml
index 63a0619719..2516167574 100644
--- a/assets/xml/objects/object_syoten.xml
+++ b/assets/xml/objects/object_syoten.xml
@@ -1,8 +1,6 @@
-
-
-
+
@@ -14,10 +12,7 @@
-
-
-
-
+
diff --git a/include/z64keyframe.h b/include/z64keyframe.h
index 10d7f85096..ac350c125c 100644
--- a/include/z64keyframe.h
+++ b/include/z64keyframe.h
@@ -70,6 +70,8 @@ typedef struct {
// Array of bitflags for each limb indicating whether to do keyframe interpolation
// or pull from fixed values that do not change throughout the animation.
union {
+ // Used to initialize bitflags without warnings
+ /* 0x00 */ void* data;
// For standard the bit layout in each array element is:
// [5] X Translation (root limb only)
// [4] Y Translation (root limb only)
diff --git a/src/overlays/actors/ovl_Demo_Moonend/z_demo_moonend.c b/src/overlays/actors/ovl_Demo_Moonend/z_demo_moonend.c
index 91d6c2377a..798de67563 100644
--- a/src/overlays/actors/ovl_Demo_Moonend/z_demo_moonend.c
+++ b/src/overlays/actors/ovl_Demo_Moonend/z_demo_moonend.c
@@ -46,9 +46,9 @@ void DemoMoonend_Init(Actor* thisx, PlayState* play) {
this->actionFunc = func_80C17B60;
} else {
Actor_SetScale(&this->actor, 0.095f);
- Keyframe_InitFlex(&this->kfSkelAnime, (KeyFrameFlexSkeleton*)&object_moonend_Blob_00B5A0,
- (KeyFrameAnimation*)&object_moonend_Blob_001214, this->jointTable, this->morphTable, NULL);
- Keyframe_FlexPlayOnce(&this->kfSkelAnime, (KeyFrameAnimation*)&object_moonend_Blob_001214);
+ Keyframe_InitFlex(&this->kfSkelAnime, &object_moonend_KFSkel_00B5A0, &object_moonened_KFAnim_001214,
+ this->jointTable, this->morphTable, NULL);
+ Keyframe_FlexPlayOnce(&this->kfSkelAnime, &object_moonened_KFAnim_001214);
this->cueType = CS_CMD_ACTOR_CUE_560;
this->actionFunc = func_80C17C48;
this->actor.home.rot.z = 0;
@@ -110,13 +110,13 @@ void func_80C17C48(DemoMoonend* this, PlayState* play) {
switch (this->cueId) {
case 1:
this->actor.draw = DemoMoonend_Draw;
- Keyframe_FlexPlayOnce(&this->kfSkelAnime, (KeyFrameAnimation*)&object_moonend_Blob_001214);
+ Keyframe_FlexPlayOnce(&this->kfSkelAnime, &object_moonened_KFAnim_001214);
this->kfSkelAnime.frameCtrl.speed = 0.0f;
break;
case 2:
this->actor.draw = DemoMoonend_Draw;
- Keyframe_FlexPlayOnce(&this->kfSkelAnime, (KeyFrameAnimation*)&object_moonend_Blob_001214);
+ Keyframe_FlexPlayOnce(&this->kfSkelAnime, &object_moonened_KFAnim_001214);
this->kfSkelAnime.frameCtrl.speed = 2.0f / 3.0f;
Actor_PlaySfx(&this->actor, NA_SE_EV_MOON_EXPLOSION);
this->actor.home.rot.z = 1;
diff --git a/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.c b/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.c
index 3780c075c5..5f25137f5d 100644
--- a/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.c
+++ b/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.c
@@ -73,9 +73,9 @@ void DemoSyoten_Init(Actor* thisx, PlayState* play) {
switch (DEMOSYOTEN_GET_F(&this->actor)) {
case DEMOSYOTEN_F_0:
- Keyframe_InitFlex(&this->kfSkelAnime, (KeyFrameFlexSkeleton*)&object_syoten_Blob_001328,
- (KeyFrameAnimation*)&object_syoten_Blob_00023C, this->jointTable, this->morphTable, NULL);
- Keyframe_FlexPlayLoop(&this->kfSkelAnime, (KeyFrameAnimation*)&object_syoten_Blob_00023C);
+ Keyframe_InitFlex(&this->kfSkelAnime, &object_syoten_KFSkel_001328, &object_syoten_KFAnim_00023C,
+ this->jointTable, this->morphTable, NULL);
+ Keyframe_FlexPlayLoop(&this->kfSkelAnime, &object_syoten_KFAnim_00023C);
this->actor.draw = NULL;
this->actionFunc = func_80C16A74;
this->actor.child =
diff --git a/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c b/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c
index 81bdd2d376..18e019b281 100644
--- a/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c
+++ b/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c
@@ -4,7 +4,6 @@
* Description: Blue warp portal and crystal, and the Majora's Mask-shaped boss warp platform
*/
-#include "prevent_bss_reordering.h"
#include "z_door_warp1.h"
#include "objects/object_warp1/object_warp1.h"
diff --git a/src/overlays/actors/ovl_Eff_Change/z_eff_change.c b/src/overlays/actors/ovl_Eff_Change/z_eff_change.c
index 24a079632f..0a1b46e84b 100644
--- a/src/overlays/actors/ovl_Eff_Change/z_eff_change.c
+++ b/src/overlays/actors/ovl_Eff_Change/z_eff_change.c
@@ -50,9 +50,9 @@ void EffChange_Init(Actor* thisx, PlayState* play) {
EffChange_SetColors(this, EFFCHANGE_GET_COLORS(thisx));
Actor_SetScale(&this->actor, 0.075f);
this->primColors[3] = 0;
- Keyframe_InitFlex(&this->kfSkelAnime, (KeyFrameFlexSkeleton*)&gameplay_keep_Blob_02900C,
- (KeyFrameAnimation*)&gameplay_keep_Blob_0281DC, this->jointTable, this->morphTable, NULL);
- Keyframe_FlexPlayOnce(&this->kfSkelAnime, (KeyFrameAnimation*)&gameplay_keep_Blob_0281DC);
+ Keyframe_InitFlex(&this->kfSkelAnime, &gameplay_keep_KFSkel_02900C, &gameplay_keep_KFAnim_0281DC, this->jointTable,
+ this->morphTable, NULL);
+ Keyframe_FlexPlayOnce(&this->kfSkelAnime, &gameplay_keep_KFAnim_0281DC);
this->step = 0;
this->actor.shape.rot.y = 0;
this->kfSkelAnime.frameCtrl.speed = 2.0f / 3.0f;
diff --git a/src/overlays/actors/ovl_En_Fall2/z_en_fall2.c b/src/overlays/actors/ovl_En_Fall2/z_en_fall2.c
index b1a67d9e0d..6d282e2d12 100644
--- a/src/overlays/actors/ovl_En_Fall2/z_en_fall2.c
+++ b/src/overlays/actors/ovl_En_Fall2/z_en_fall2.c
@@ -35,9 +35,9 @@ void EnFall2_Init(Actor* thisx, PlayState* play) {
Actor_SetScale(&this->actor, 1.0f);
this->actionFunc = EnFall2_DoNothing;
- Keyframe_InitFlex(&this->kfSkelAnime, (KeyFrameFlexSkeleton*)&object_fall2_Blob_008898,
- (KeyFrameAnimation*)&object_fall2_Blob_005EF4, this->jointTable, this->morphTable, NULL);
- Keyframe_FlexPlayLoop(&this->kfSkelAnime, (KeyFrameAnimation*)&object_fall2_Blob_005EF4);
+ Keyframe_InitFlex(&this->kfSkelAnime, &object_fall2_KFSkel_008898, &object_fall2_KFAnim_005EF4, this->jointTable,
+ this->morphTable, NULL);
+ Keyframe_FlexPlayLoop(&this->kfSkelAnime, &object_fall2_KFAnim_005EF4);
this->unk2DC = Lib_SegmentedToVirtual(object_fall2_Matanimheader_008840);
Actor_SetScale(&this->actor, 0.02f);
this->actionFunc = EnFall2_HandleCutscene;
diff --git a/src/overlays/actors/ovl_En_Ot/z_en_ot.c b/src/overlays/actors/ovl_En_Ot/z_en_ot.c
index 89d32e6e23..ed200e1976 100644
--- a/src/overlays/actors/ovl_En_Ot/z_en_ot.c
+++ b/src/overlays/actors/ovl_En_Ot/z_en_ot.c
@@ -4,7 +4,6 @@
* Description: Seahorse
*/
-#include "prevent_bss_reordering.h"
#include "z_en_ot.h"
#include "objects/gameplay_keep/gameplay_keep.h"
diff --git a/src/overlays/actors/ovl_En_Test/z_en_test.c b/src/overlays/actors/ovl_En_Test/z_en_test.c
index 6cff068b32..4bef57063b 100644
--- a/src/overlays/actors/ovl_En_Test/z_en_test.c
+++ b/src/overlays/actors/ovl_En_Test/z_en_test.c
@@ -186,9 +186,9 @@ void EnTest_Init(Actor* thisx, PlayState* play2) {
this->surfaceMaterial = SurfaceType_GetMaterial(&play->colCtx, thisx->floorPoly, bgId);
}
- Keyframe_InitFlex(&this->kfSkelAnime, (KeyFrameFlexSkeleton*)&gameplay_keep_Blob_06EB70,
- (KeyFrameAnimation*)&gameplay_keep_Blob_06BB0C, this->jointTable, this->morphTable, NULL);
- Keyframe_FlexPlayOnce(&this->kfSkelAnime, (KeyFrameAnimation*)&gameplay_keep_Blob_06BB0C);
+ Keyframe_InitFlex(&this->kfSkelAnime, &gameplay_keep_KFSkel_06EB70, &gameplay_keep_KFAnim_06BB0C, this->jointTable,
+ this->morphTable, NULL);
+ Keyframe_FlexPlayOnce(&this->kfSkelAnime, &gameplay_keep_KFAnim_06BB0C);
this->kfSkelAnime.frameCtrl.curTime = 9.0f;
func_80862B70(this->unk_20C);
}
diff --git a/src/overlays/actors/ovl_En_Test7/z_en_test7.c b/src/overlays/actors/ovl_En_Test7/z_en_test7.c
index da2aab1d5f..b96b8d8b70 100644
--- a/src/overlays/actors/ovl_En_Test7/z_en_test7.c
+++ b/src/overlays/actors/ovl_En_Test7/z_en_test7.c
@@ -383,9 +383,9 @@ void EnTest7_Init(Actor* thisx, PlayState* play2) {
this->playerScaleZ = player->actor.scale.z;
// Keyframe animations
- Keyframe_InitFlex(&this->kfSkelAnime, (KeyFrameFlexSkeleton*)&gameplay_keep_Blob_085640,
- (KeyFrameAnimation*)&gameplay_keep_Blob_083534, this->jointTable, this->morphTable, NULL);
- Keyframe_FlexPlayOnce(&this->kfSkelAnime, (KeyFrameAnimation*)&gameplay_keep_Blob_083534);
+ Keyframe_InitFlex(&this->kfSkelAnime, &gameplay_keep_KFSkel_085640, &gameplay_keep_KFAnim_083534, this->jointTable,
+ this->morphTable, NULL);
+ Keyframe_FlexPlayOnce(&this->kfSkelAnime, &gameplay_keep_KFAnim_083534);
EnTest7_InitFeathers(this->feathers);
EnTest7_InitWindCapsule(&this->windCapsule);
diff --git a/tools/ZAPD/.github/workflows/main.yml b/tools/ZAPD/.github/workflows/main.yml
new file mode 100644
index 0000000000..604c18c961
--- /dev/null
+++ b/tools/ZAPD/.github/workflows/main.yml
@@ -0,0 +1,98 @@
+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: |
+ cd ../
+ rm -rf oot/
+ git clone https://github.com/zeldaret/oot.git
+ cd oot
+ echo $(pwd)
+ git submodule update --init --recursive
+
+ - name: Checkout mm
+ run: |
+ cd ../
+ rm -rf mm/
+ git clone https://github.com/zeldaret/mm.git
+ cd mm
+ echo $(pwd)
+
+ - name: Set up repos
+ run: echo "Set up repos"
+
+ - name: Setup OOT
+ run: |
+ cd ../
+ cd oot
+ echo $(pwd)
+ mkdir -p baseroms/gc-eu-mq-dbg/segments
+ cp ~/baserom_original.z64 ./baseroms/gc-eu-mq-dbg/baserom.z64
+ cd tools
+ rm -rf ZAPD/
+ ln -s ../../ZAPD
+ cd ../
+ make -j $(nproc) setup
+
+ - name: Setup MM
+ run: |
+ cd ../
+ cd mm
+ echo $(pwd)
+ 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
+ cd tools
+ rm -rf ZAPD/
+ ln -s ../../ZAPD
+ cd ../
+ make -C tools -j
+ 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 ../
+ cd oot
+ echo $(pwd)
+ make venv
+ make -j
+
+ - name: Build mm
+ run: |
+ cd ../
+ cd mm
+ echo $(pwd)
+ 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
diff --git a/tools/ZAPD/.gitrepo b/tools/ZAPD/.gitrepo
index 7eb187efc7..d5596db31b 100644
--- a/tools/ZAPD/.gitrepo
+++ b/tools/ZAPD/.gitrepo
@@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/zeldaret/ZAPD.git
branch = master
- commit = 9601f2699c142bb8273d33763ef4d84e8a7d650f
- parent = 3e1207d5e7818ab6676422cda10f206b180126db
+ commit = c31c5e9fec72863e38cdfef8c0b1915140234253
+ parent = 1685597d9aded6ee06f4e191954940331e34f346
method = merge
cmdver = 0.4.6
diff --git a/tools/ZAPD/README.md b/tools/ZAPD/README.md
index 76dfbd1e95..5006f8d4b5 100644
--- a/tools/ZAPD/README.md
+++ b/tools/ZAPD/README.md
@@ -117,6 +117,16 @@ 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`: `0x42280000`
+ - `float`: `42.0f`
+ - `both`: `CS_FLOAT(0x42280000, 42.0f)`
+ - `hex-commented-left`: `/* 42.0f */ 0x42280000`
+ - `hex-commented-right`: `0x42280000 /* 42.0f */`
+- `--base-address ADDRESS`: Override base virtual address for input files.
+- `--start-offset OFFSET`: Override start offset for input files.
+- `--end-offset OFFSET`: Override end offset for input files.
- `-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.
diff --git a/tools/ZAPD/ZAPD/Globals.h b/tools/ZAPD/ZAPD/Globals.h
index 0bfcaeec72..2cc9c2d4db 100644
--- a/tools/ZAPD/ZAPD/Globals.h
+++ b/tools/ZAPD/ZAPD/Globals.h
@@ -16,6 +16,15 @@ enum class VerbosityLevel
VERBOSITY_DEBUG
};
+enum class CsFloatType
+{
+ HexOnly,
+ FloatOnly,
+ HexAndFloat,
+ HexAndCommentedFloatLeft,
+ HexAndCommentedFloatRight,
+};
+
class Globals
{
public:
@@ -31,6 +40,10 @@ public:
ZFileMode fileMode;
fs::path baseRomPath, inputPath, outputPath, sourceOutputPath, cfgPath;
TextureType texType;
+ CsFloatType floatType = CsFloatType::FloatOnly;
+ int64_t baseAddress = -1;
+ int64_t startOffset = -1;
+ int64_t endOffset = -1;
ZGame game;
GameConfig cfg;
bool verboseUnaccounted = false;
diff --git a/tools/ZAPD/ZAPD/Main.cpp b/tools/ZAPD/ZAPD/Main.cpp
index 40a38bc601..19d10d7d96 100644
--- a/tools/ZAPD/ZAPD/Main.cpp
+++ b/tools/ZAPD/ZAPD/Main.cpp
@@ -36,11 +36,15 @@ 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[]);
+void Arg_BaseAddress(int& i, char* argv[]);
+void Arg_StartOffset(int& i, char* argv[]);
+void Arg_EndOffset(int& i, char* argv[]);
int main(int argc, char* argv[]);
bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath,
- ZFileMode fileMode);
+ ZFileMode fileMode);
void ParseArgs(int& argc, char* argv[]);
@@ -114,7 +118,7 @@ int main(int argc, char* argv[])
returnCode = HandleExtract(fileMode, exporterSet);
else if (fileMode == ZFileMode::BuildTexture)
BuildAssetTexture(Globals::Instance->inputPath, Globals::Instance->texType,
- Globals::Instance->outputPath);
+ Globals::Instance->outputPath);
else if (fileMode == ZFileMode::BuildBackground)
BuildAssetBackground(Globals::Instance->inputPath, Globals::Instance->outputPath);
else if (fileMode == ZFileMode::BuildBlob)
@@ -125,7 +129,7 @@ int main(int argc, char* argv[])
}
bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath,
- ZFileMode fileMode)
+ ZFileMode fileMode)
{
tinyxml2::XMLDocument doc;
tinyxml2::XMLError eResult = doc.LoadFile(xmlFilePath.string().c_str());
@@ -134,7 +138,7 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path
{
// TODO: use XMLDocument::ErrorIDToName to get more specific error messages here
HANDLE_ERROR(WarningType::InvalidXML,
- StringHelper::Sprintf("invalid XML file: '%s'", xmlFilePath.c_str()), "");
+ StringHelper::Sprintf("invalid XML file: '%s'", xmlFilePath.c_str()), "");
return false;
}
@@ -149,7 +153,7 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path
}
for (tinyxml2::XMLElement* child = root->FirstChildElement(); child != NULL;
- child = child->NextSiblingElement())
+ child = child->NextSiblingElement())
{
if (std::string_view(child->Name()) == "File")
{
@@ -252,6 +256,10 @@ void ParseArgs(int& argc, char* argv[])
{"--static", &Arg_ForceStatic},
{"-us", &Arg_ForceUnaccountedStatic},
{"--unaccounted-static", &Arg_ForceUnaccountedStatic},
+ {"--cs-float", &Arg_CsFloatMode},
+ {"--base-address", &Arg_BaseAddress},
+ {"--start-offset", &Arg_StartOffset},
+ {"--end-offset", &Arg_EndOffset},
};
for (int32_t i = 2; i < argc; i++)
@@ -392,6 +400,62 @@ 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 if (std::strcmp(argv[i], "hex-commented-left") == 0)
+ {
+ Globals::Instance->floatType = CsFloatType::HexAndCommentedFloatLeft;
+ }
+ else if (std::strcmp(argv[i], "hex-commented-right") == 0)
+ {
+ Globals::Instance->floatType = CsFloatType::HexAndCommentedFloatRight;
+ }
+ else
+ {
+ Globals::Instance->floatType = CsFloatType::FloatOnly;
+ HANDLE_WARNING(
+ WarningType::Always, "Invalid CS Float Type",
+ StringHelper::Sprintf("Invalid CS float type entered. Expected \"hex\", \"float\", "
+ "\"both\", \"hex-commented-left\" or \"hex-commented-right\". "
+ "Got %s.\n Defaulting to \"float\".",
+ argv[i]));
+ }
+}
+
+uint32_t ParseU32Hex(char* str)
+{
+ static_assert(sizeof(uint32_t) <= sizeof(unsigned long));
+ return (uint32_t)std::stoul(str, nullptr, 16);
+}
+
+void Arg_BaseAddress(int& i, char* argv[])
+{
+ Globals::Instance->baseAddress = ParseU32Hex(argv[++i]);
+}
+
+void Arg_StartOffset(int& i, char* argv[])
+{
+ Globals::Instance->startOffset = ParseU32Hex(argv[++i]);
+}
+
+void Arg_EndOffset(int& i, char* argv[])
+{
+ Globals::Instance->endOffset = ParseU32Hex(argv[++i]);
+}
+
int HandleExtract(ZFileMode fileMode, ExporterSet* exporterSet)
{
bool procFileModeSuccess = false;
@@ -412,14 +476,14 @@ int HandleExtract(ZFileMode fileMode, ExporterSet* exporterSet)
printf("Parsing external file from config: '%s'\n", externalXmlFilePath.c_str());
parseSuccessful = Parse(externalXmlFilePath, Globals::Instance->baseRomPath,
- extFile.outPath, ZFileMode::ExternalFile);
+ extFile.outPath, ZFileMode::ExternalFile);
if (!parseSuccessful)
return 1;
}
parseSuccessful = Parse(Globals::Instance->inputPath, Globals::Instance->baseRomPath,
- Globals::Instance->outputPath, fileMode);
+ Globals::Instance->outputPath, fileMode);
if (!parseSuccessful)
return 1;
}
diff --git a/tools/ZAPD/ZAPD/OtherStructs/CutsceneMM_Commands.cpp b/tools/ZAPD/ZAPD/OtherStructs/CutsceneMM_Commands.cpp
index b47bc40e16..960404e598 100644
--- a/tools/ZAPD/ZAPD/OtherStructs/CutsceneMM_Commands.cpp
+++ b/tools/ZAPD/ZAPD/OtherStructs/CutsceneMM_Commands.cpp
@@ -6,6 +6,8 @@
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
+#include "ZCutscene.h"
+
/**** GENERIC ****/
// Specific for command lists where each entry has size 8 bytes
@@ -127,8 +129,9 @@ std::string CutsceneMMCommand_GenericCmd::GetCommandMacro() const
/**** CAMERA ****/
-CutsceneSubCommandEntry_SplineCamPoint::CutsceneSubCommandEntry_SplineCamPoint(const std::vector& rawData,
- offset_t rawDataIndex): CutsceneSubCommandEntry(rawData, rawDataIndex)
+CutsceneSubCommandEntry_SplineCamPoint::CutsceneSubCommandEntry_SplineCamPoint(
+ const std::vector& rawData, offset_t rawDataIndex)
+ : CutsceneSubCommandEntry(rawData, rawDataIndex)
{
interpType = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0);
weight = BitConverter::ToUInt8BE(rawData, rawDataIndex + 1);
@@ -144,7 +147,9 @@ std::string CutsceneSubCommandEntry_SplineCamPoint::GetBodySourceCode() const
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());
+ 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_SplineCamPoint::GetRawSize() const
@@ -152,9 +157,9 @@ size_t CutsceneSubCommandEntry_SplineCamPoint::GetRawSize() const
return 0x0C;
}
-
-CutsceneSubCommandEntry_SplineMiscPoint::CutsceneSubCommandEntry_SplineMiscPoint(const std::vector& rawData,
- offset_t rawDataIndex): CutsceneSubCommandEntry(rawData, rawDataIndex)
+CutsceneSubCommandEntry_SplineMiscPoint::CutsceneSubCommandEntry_SplineMiscPoint(
+ const std::vector& rawData, offset_t rawDataIndex)
+ : CutsceneSubCommandEntry(rawData, rawDataIndex)
{
unused0 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0);
roll = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2);
@@ -164,7 +169,8 @@ CutsceneSubCommandEntry_SplineMiscPoint::CutsceneSubCommandEntry_SplineMiscPoint
std::string CutsceneSubCommandEntry_SplineMiscPoint::GetBodySourceCode() const
{
- return StringHelper::Sprintf("CS_CAM_MISC(0x%04X, 0x%04X, 0x%04X, 0x%04X)", unused0, roll, fov, unused1);
+ return StringHelper::Sprintf("CS_CAM_MISC(0x%04X, 0x%04X, 0x%04X, 0x%04X)", unused0, roll, fov,
+ unused1);
}
size_t CutsceneSubCommandEntry_SplineMiscPoint::GetRawSize() const
@@ -172,8 +178,9 @@ size_t CutsceneSubCommandEntry_SplineMiscPoint::GetRawSize() const
return 0x08;
}
-CutsceneSubCommandEntry_SplineHeader::CutsceneSubCommandEntry_SplineHeader(const std::vector& rawData,
- offset_t rawDataIndex): CutsceneSubCommandEntry(rawData, rawDataIndex)
+CutsceneSubCommandEntry_SplineHeader::CutsceneSubCommandEntry_SplineHeader(
+ const std::vector& rawData, offset_t rawDataIndex)
+ : CutsceneSubCommandEntry(rawData, rawDataIndex)
{
numEntries = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0);
unused0 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2);
@@ -183,8 +190,8 @@ CutsceneSubCommandEntry_SplineHeader::CutsceneSubCommandEntry_SplineHeader(const
std::string CutsceneSubCommandEntry_SplineHeader::GetBodySourceCode() const
{
- return StringHelper::Sprintf("CS_CAM_SPLINE(0x%04X, 0x%04X, 0x%04X, 0x%04X)", numEntries, unused0, unused1, duration);
-
+ return StringHelper::Sprintf("CS_CAM_SPLINE(0x%04X, 0x%04X, 0x%04X, 0x%04X)", numEntries,
+ unused0, unused1, duration);
}
size_t CutsceneSubCommandEntry_SplineHeader::GetRawSize() const
@@ -192,16 +199,19 @@ size_t CutsceneSubCommandEntry_SplineHeader::GetRawSize() const
return 0x08;
}
-CutsceneSubCommandEntry_SplineFooter::CutsceneSubCommandEntry_SplineFooter(const std::vector& rawData,
- offset_t rawDataIndex): CutsceneSubCommandEntry(rawData, rawDataIndex)
+CutsceneSubCommandEntry_SplineFooter::CutsceneSubCommandEntry_SplineFooter(
+ const std::vector& 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) {
+ 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));
+ StringHelper::Sprintf(
+ "Invalid Spline footer. Was expecting 0xFFFF, 0x0004. Got 0x%04X, 0x%04X",
+ firstHalfWord, secondHalfWord));
}
}
@@ -223,8 +233,10 @@ CutsceneMMCommand_Spline::CutsceneMMCommand_Spline(const std::vector& r
totalCommands = 0;
rawDataIndex += 4;
- while(1) {
- if (BitConverter::ToUInt16BE(rawData, rawDataIndex) == 0xFFFF) {
+ while (1)
+ {
+ if (BitConverter::ToUInt16BE(rawData, rawDataIndex) == 0xFFFF)
+ {
break;
}
numHeaders++;
@@ -232,7 +244,7 @@ CutsceneMMCommand_Spline::CutsceneMMCommand_Spline(const std::vector& r
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++)
@@ -269,7 +281,8 @@ std::string CutsceneMMCommand_Spline::GetCommandMacro() const
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.
+ // 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;
}
@@ -545,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(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());
}
}
diff --git a/tools/ZAPD/ZAPD/OtherStructs/CutsceneMM_Commands.h b/tools/ZAPD/ZAPD/OtherStructs/CutsceneMM_Commands.h
index 9891a24ac4..597f6788bc 100644
--- a/tools/ZAPD/ZAPD/OtherStructs/CutsceneMM_Commands.h
+++ b/tools/ZAPD/ZAPD/OtherStructs/CutsceneMM_Commands.h
@@ -282,7 +282,8 @@ public:
uint16_t posZ;
uint16_t relTo;
- CutsceneSubCommandEntry_SplineCamPoint(const std::vector& rawData, offset_t rawDataIndex);
+ CutsceneSubCommandEntry_SplineCamPoint(const std::vector& rawData,
+ offset_t rawDataIndex);
std::string GetBodySourceCode() const override;
@@ -296,8 +297,9 @@ public:
uint16_t roll;
uint16_t fov;
uint16_t unused1;
-
- CutsceneSubCommandEntry_SplineMiscPoint(const std::vector& rawData, offset_t rawDataIndex);
+
+ CutsceneSubCommandEntry_SplineMiscPoint(const std::vector& rawData,
+ offset_t rawDataIndex);
std::string GetBodySourceCode() const override;
@@ -306,8 +308,9 @@ public:
class CutsceneSubCommandEntry_SplineFooter : public CutsceneSubCommandEntry
{
-public:
- CutsceneSubCommandEntry_SplineFooter(const std::vector& rawData, offset_t rawDataIndex);
+public:
+ CutsceneSubCommandEntry_SplineFooter(const std::vector& rawData,
+ offset_t rawDataIndex);
std::string GetBodySourceCode() const override;
@@ -321,7 +324,8 @@ public:
uint16_t unused0;
uint16_t unused1;
uint16_t duration;
- CutsceneSubCommandEntry_SplineHeader(const std::vector& rawData, offset_t rawDataIndex);
+ CutsceneSubCommandEntry_SplineHeader(const std::vector& rawData,
+ offset_t rawDataIndex);
std::string GetBodySourceCode() const override;
diff --git a/tools/ZAPD/ZAPD/OtherStructs/CutsceneOoT_Commands.cpp b/tools/ZAPD/ZAPD/OtherStructs/CutsceneOoT_Commands.cpp
index 8c530f796e..668657e7aa 100644
--- a/tools/ZAPD/ZAPD/OtherStructs/CutsceneOoT_Commands.cpp
+++ b/tools/ZAPD/ZAPD/OtherStructs/CutsceneOoT_Commands.cpp
@@ -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
@@ -13,7 +15,7 @@ const std::unordered_map csCom
{CutsceneOoT_CommandType::CS_CMD_MISC,
{"CS_MISC", "(%s, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}},
{CutsceneOoT_CommandType::CS_CMD_LIGHT_SETTING,
- {"CS_LIGHT_SETTING", "(0x%02X, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}},
+ {"CS_LIGHT_SETTING", "(0x%02X, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}},
{CutsceneOoT_CommandType::CS_CMD_START_SEQ,
{"CS_START_SEQ", "(%s, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}},
{CutsceneOoT_CommandType::CS_CMD_STOP_SEQ,
@@ -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(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());
}
}
diff --git a/tools/ZAPD/ZAPD/ZAPD.vcxproj b/tools/ZAPD/ZAPD/ZAPD.vcxproj
index 22bc720e9d..26a0b70363 100644
--- a/tools/ZAPD/ZAPD/ZAPD.vcxproj
+++ b/tools/ZAPD/ZAPD/ZAPD.vcxproj
@@ -45,6 +45,7 @@
true
v142
MultiByte
+ false
Application
@@ -52,6 +53,7 @@
v142
true
MultiByte
+ false
@@ -194,6 +196,8 @@ mkdir build\ZAPD
+
+
@@ -289,6 +293,8 @@ mkdir build\ZAPD
+
+
diff --git a/tools/ZAPD/ZAPD/ZAPD.vcxproj.filters b/tools/ZAPD/ZAPD/ZAPD.vcxproj.filters
index f693a749d2..51723306b4 100644
--- a/tools/ZAPD/ZAPD/ZAPD.vcxproj.filters
+++ b/tools/ZAPD/ZAPD/ZAPD.vcxproj.filters
@@ -300,6 +300,12 @@
Source Files\Z64\ZRoom\Commands
+
+ Source Files\Z64
+
+
+ Source Files\Z64
+
@@ -575,6 +581,12 @@
Header Files\Z64\ZRoom\Commands
+
+ Header Files\Z64
+
+
+ Header Files\Z64
+
diff --git a/tools/ZAPD/ZAPD/ZCKeyFrame.cpp b/tools/ZAPD/ZAPD/ZCKeyFrame.cpp
new file mode 100644
index 0000000000..3893394f5c
--- /dev/null
+++ b/tools/ZAPD/ZAPD/ZCKeyFrame.cpp
@@ -0,0 +1,312 @@
+#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(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
+{
+ switch (limbType)
+ {
+ case ZKeyframeSkelType::Normal:
+ return "KeyFrameSkeleton";
+
+ case ZKeyframeSkelType::Flex:
+ return "KeyFrameFlexSkeleton";
+
+ default:
+ 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;
+ }
+}
diff --git a/tools/ZAPD/ZAPD/ZCKeyFrame.h b/tools/ZAPD/ZAPD/ZCKeyFrame.h
new file mode 100644
index 0000000000..417d7cc686
--- /dev/null
+++ b/tools/ZAPD/ZAPD/ZCKeyFrame.h
@@ -0,0 +1,121 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+#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 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 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;
+};
diff --git a/tools/ZAPD/ZAPD/ZCKeyFrameAnim.cpp b/tools/ZAPD/ZAPD/ZCKeyFrameAnim.cpp
new file mode 100644
index 0000000000..0b07471333
--- /dev/null
+++ b/tools/ZAPD/ZAPD/ZCKeyFrameAnim.cpp
@@ -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(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
+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;
+}
\ No newline at end of file
diff --git a/tools/ZAPD/ZAPD/ZCkeyFrameAnim.h b/tools/ZAPD/ZAPD/ZCkeyFrameAnim.h
new file mode 100644
index 0000000000..64f95b13ae
--- /dev/null
+++ b/tools/ZAPD/ZAPD/ZCkeyFrameAnim.h
@@ -0,0 +1,52 @@
+#pragma once
+#include
+#include
+#include
+#include
+
+#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 bitFlags; // Standard only
+ std::vector bitFlagsFlex; // Flex only
+
+ std::vector keyFrames;
+ std::vector kfNums;
+ std::vector 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
+ uint32_t GetSetBits(T data) const;
+};
diff --git a/tools/ZAPD/ZAPD/ZCutscene.cpp b/tools/ZAPD/ZAPD/ZCutscene.cpp
index b90fb872d6..7ae431ebab 100644
--- a/tools/ZAPD/ZAPD/ZCutscene.cpp
+++ b/tools/ZAPD/ZAPD/ZCutscene.cpp
@@ -24,7 +24,7 @@ std::string ZCutscene::GetBodySourceCode() const
{
std::string output = "";
- output += StringHelper::Sprintf(" CS_BEGIN_CUTSCENE(%i, %i),\n", commands.size(), endFrame);
+ output += StringHelper::Sprintf(" CS_BEGIN_CUTSCENE(%i, %i),\n", numCommands, endFrame);
for (size_t i = 0; i < commands.size(); i++)
{
@@ -32,7 +32,7 @@ std::string ZCutscene::GetBodySourceCode() const
output += " " + cmd->GenerateSourceCode();
}
- output += StringHelper::Sprintf(" CS_END(),", commands.size(), endFrame);
+ output += StringHelper::Sprintf(" CS_END(),");
return output;
}
@@ -372,3 +372,25 @@ ZResourceType ZCutscene::GetResourceType() const
{
return ZResourceType::Cutscene;
}
+
+std::string ZCutscene::GetCsEncodedFloat(float f, CsFloatType type, bool useSciNotation)
+{
+ uint32_t i;
+ std::memcpy(&i, &f, sizeof(i));
+
+ switch (type)
+ {
+ default:
+ // This default case will NEVER be reached, but GCC still gives a warning.
+ case CsFloatType::HexOnly:
+ return StringHelper::Sprintf("0x%08X", i);
+ case CsFloatType::FloatOnly:
+ return StringHelper::Sprintf(useSciNotation ? "%.8ef" : "%ff", f);
+ case CsFloatType::HexAndFloat:
+ return StringHelper::Sprintf(useSciNotation ? "CS_FLOAT(0x%08X, %.8ef)" : "CS_FLOAT(0x%08X, %ff)", i, f);
+ case CsFloatType::HexAndCommentedFloatLeft:
+ return StringHelper::Sprintf(useSciNotation ? "/* %.8ef */ 0x%08X" : "/* %ff */ 0x%08X", f, i);
+ case CsFloatType::HexAndCommentedFloatRight:
+ return StringHelper::Sprintf(useSciNotation ? "0x%08X /* %.8ef */" : "0x%08X /* %ff */", i, f);
+ }
+}
diff --git a/tools/ZAPD/ZAPD/ZCutscene.h b/tools/ZAPD/ZAPD/ZCutscene.h
index 5b54426cea..5dbf475c33 100644
--- a/tools/ZAPD/ZAPD/ZCutscene.h
+++ b/tools/ZAPD/ZAPD/ZCutscene.h
@@ -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 commands;
diff --git a/tools/ZAPD/ZAPD/ZFile.cpp b/tools/ZAPD/ZAPD/ZFile.cpp
index 0b2a4d631c..db2d251a5c 100644
--- a/tools/ZAPD/ZAPD/ZFile.cpp
+++ b/tools/ZAPD/ZAPD/ZFile.cpp
@@ -120,6 +120,9 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
if (reader->Attribute("BaseAddress") != nullptr)
baseAddress = StringHelper::StrToL(reader->Attribute("BaseAddress"), 16);
+ if (mode == ZFileMode::Extract && Globals::Instance->baseAddress != -1)
+ baseAddress = Globals::Instance->baseAddress;
+
if (reader->Attribute("RangeStart") != nullptr)
rangeStart = StringHelper::StrToL(reader->Attribute("RangeStart"), 16);
@@ -197,6 +200,9 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
}
rawData = File::ReadAllBytes((basePath / name).string());
+ if (mode == ZFileMode::Extract && Globals::Instance->startOffset != -1 && Globals::Instance->endOffset != -1)
+ rawData = std::vector(rawData.begin() + Globals::Instance->startOffset,
+ rawData.begin() + Globals::Instance->endOffset);
if (reader->Attribute("RangeEnd") == nullptr)
rangeEnd = rawData.size();
@@ -585,6 +591,12 @@ Declaration* ZFile::AddDeclarationIncludeArray(offset_t address, std::string& in
includePath = "assets/" + StringHelper::Split(includePath, "assets/extracted/")[1];
if (StringHelper::StartsWith(includePath, "assets/custom/"))
includePath = "assets/" + StringHelper::Split(includePath, "assets/custom/")[1];
+ // Hack for OOT: don't prefix include paths with extracted/VERSION/
+ if (StringHelper::StartsWith(includePath, "extracted/")) {
+ std::vector parts = StringHelper::Split(includePath, "/");
+ parts.erase(parts.begin(), parts.begin() + 2);
+ includePath = StringHelper::Join(parts, "/");
+ }
Declaration* decl = GetDeclaration(address);
if (decl == nullptr)
@@ -621,6 +633,12 @@ Declaration* ZFile::AddDeclarationIncludeArray(offset_t address, std::string& in
includePath = "assets/" + StringHelper::Split(includePath, "assets/extracted/")[1];
if (StringHelper::StartsWith(includePath, "assets/custom/"))
includePath = "assets/" + StringHelper::Split(includePath, "assets/custom/")[1];
+ // Hack for OOT: don't prefix include paths with extracted/VERSION/
+ if (StringHelper::StartsWith(includePath, "extracted/")) {
+ std::vector parts = StringHelper::Split(includePath, "/");
+ parts.erase(parts.begin(), parts.begin() + 2);
+ includePath = StringHelper::Join(parts, "/");
+ }
Declaration* decl = GetDeclaration(address);
if (decl == nullptr)
diff --git a/tools/ZAPD/ZAPD/ZResource.h b/tools/ZAPD/ZAPD/ZResource.h
index 9754013984..768b785441 100644
--- a/tools/ZAPD/ZAPD/ZResource.h
+++ b/tools/ZAPD/ZAPD/ZResource.h
@@ -55,6 +55,10 @@ enum class ZResourceType
Vector,
Vertex,
Waterbox,
+ KeyFrameFlexLimb,
+ KeyFrameStandardLimb,
+ KeyFrameSkel,
+ KeyFrameAnimation,
};
class ResourceAttribute
diff --git a/tools/ZAPD/ZAPDUtils/Utils/StringHelper.h b/tools/ZAPD/ZAPDUtils/Utils/StringHelper.h
index c4e012eb06..942d0bcc9e 100644
--- a/tools/ZAPD/ZAPDUtils/Utils/StringHelper.h
+++ b/tools/ZAPD/ZAPDUtils/Utils/StringHelper.h
@@ -30,6 +30,21 @@ public:
return result;
}
+ static std::string Join(const std::vector parts, const std::string& delimiter)
+ {
+ std::string result;
+
+ for (size_t i = 0; i < parts.size(); i++)
+ {
+ result += parts[i];
+
+ if (i != parts.size() - 1)
+ result += delimiter;
+ }
+
+ return result;
+ }
+
static std::string Strip(std::string s, const std::string& delimiter)
{
size_t pos = 0;