Extract Keyframe Assets data (#1664)

* git subrepo pull --force tools/ZAPD

subrepo:
  subdir:   "tools/ZAPD"
  merged:   "c31c5e9fe"
upstream:
  origin:   "https://github.com/zeldaret/ZAPD.git"
  branch:   "master"
  commit:   "c31c5e9fe"
git-subrepo:
  version:  "0.4.6"
  origin:   "git@github.com:ingydotnet/git-subrepo.git"
  commit:   "110b9eb"

* extract keyframe data

* initialize typo
This commit is contained in:
Derek Hensley 2024-07-28 09:31:28 -07:00 committed by GitHub
parent 6f5352e6c2
commit bd776e6bf5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
32 changed files with 1093 additions and 107 deletions

View File

@ -970,15 +970,12 @@
<Texture Name="gSwordBeam2Tex" OutName="sword_beam_2" Format="i8" Width="32" Height="64" Offset="0x271E0" />
<DList Name="gSwordBeamDL" Offset="0x27CA0" />
<Blob Name="gameplay_keep_Blob_027DD0" Size="0x32C" Offset="0x27DD0" />
<Blob Name="gameplay_keep_Blob_0281DC" Size="0x14" Offset="0x281DC" />
<KeyFrameAnimation Name="gameplay_keep_KFAnim_0281DC" Skel="0x2900C" Offset="0x281DC"/>
<DList Name="gameplay_keep_DL_0282D0" Offset="0x282D0" />
<Texture Name="gameplay_keep_Tex_0283B8" OutName="tex_0283B8" Format="i4" Width="64" Height="64" Offset="0x283B8" />
<Texture Name="gameplay_keep_Tex_028BB8" OutName="tex_028BB8" Format="i8" Width="32" Height="32" Offset="0x28BB8" />
<TextureAnimation Name="gameplay_keep_Matanimheader_028FEC" Offset="0x28FEC" />
<Blob Name="gameplay_keep_Blob_028FFC" Size="0x10" Offset="0x28FFC" />
<Blob Name="gameplay_keep_Blob_02900C" Size="0x14" Offset="0x2900C" />
<KeyFrameSkel Name="gameplay_keep_KFSkel_02900C" LimbType="Flex" Offset="0x2900C"/>
<Animation Name="gameplay_keep_Anim_029140" Offset="0x29140" />
<Texture Name="gameplay_keep_Tex_029150" OutName="tex_029150" Format="i8" Width="32" Height="64" Offset="0x29150" />
<DList Name="gameplay_keep_DL_029990" Offset="0x29990" />
@ -1333,10 +1330,7 @@
<Texture Name="gameplay_keep_Tex_06ABF8" OutName="tex_06ABF8" Format="rgba16" Width="36" Height="36" Offset="0x6ABF8" />
<TextureAnimation Name="gameplay_keep_Matanimheader_06B6A0" Offset="0x6B6A0" />
<TextureAnimation Name="gameplay_keep_Matanimheader_06B730" Offset="0x6B730" />
<Blob Name="gameplay_keep_Blob_06B750" Size="0x3BC" Offset="0x6B750" />
<Blob Name="gameplay_keep_Blob_06BB0C" Size="0x14" Offset="0x6BB0C" />
<KeyFrameAnimation Name="gameplay_keep_KFAnim_06BB0C" Skel="0x6EB70" Offset="0x6BB0C"/>
<DList Name="gameplay_keep_DL_06BFE0" Offset="0x6BFE0" />
<DList Name="gameplay_keep_DL_06C098" Offset="0x6C098" />
<DList Name="gameplay_keep_DL_06C1E8" Offset="0x6C1E8" />
@ -1345,8 +1339,7 @@
<Texture Name="gameplay_keep_Tex_06D350" OutName="tex_06D350" Format="i4" Width="64" Height="64" Offset="0x6D350" />
<Texture Name="gameplay_keep_Tex_06DB50" OutName="tex_06DB50" Format="i4" Width="64" Height="64" Offset="0x6DB50" />
<Texture Name="gameplay_keep_Tex_06E350" OutName="tex_06E350" Format="i4" Width="64" Height="64" Offset="0x6E350" />
<Blob Name="gameplay_keep_Blob_06EB50" Size="0x20" Offset="0x6EB50" />
<Blob Name="gameplay_keep_Blob_06EB70" Size="0x10" Offset="0x6EB70" />
<KeyFrameSkel Name="gameplay_keep_KFSkel_06EB70" LimbType="Flex" Offset="0x6EB70"/>
<Texture Name="gameplay_keep_Tex_06EB80" OutName="tex_06EB80" Format="i4" Width="64" Height="64" Offset="0x6EB80" />
<DList Name="gameplay_keep_DL_06F380" Offset="0x6F380" />
<DList Name="gameplay_keep_DL_06F9F0" Offset="0x6F9F0" />
@ -1450,8 +1443,7 @@
<DList Name="gSoaringWarpCsEmptyDL" Offset="0x81620" />
<DList Name="gSoaringWarpCsFeatherDL" Offset="0x81628" />
<Texture Name="gSoaringWarpCsFeatherTex" OutName="soaring_warp_cs_feather" Format="rgba16" Width="16" Height="32" Offset="0x816C0" />
<Blob Name="gameplay_keep_Blob_081AC0" Size="0x1A74" Offset="0x81AC0" />
<Blob Name="gameplay_keep_Blob_083534" Size="0x1C" Offset="0x83534" /> <!-- Is a `KeyFrameAnimation` struct -->
<KeyFrameAnimation Name="gameplay_keep_KFAnim_083534" Skel="0x85640" Offset="0x83534"/>
<DList Name="gameplay_keep_DL_084790" Offset="0x84790" />
<DList Name="gameplay_keep_DL_0847E0" Offset="0x847E0" />
<DList Name="gameplay_keep_DL_084850" Offset="0x84850" />
@ -1482,8 +1474,7 @@
<DList Name="gameplay_keep_DL_0853B0" Offset="0x853B0" />
<DList Name="gameplay_keep_DL_085418" Offset="0x85418" />
<DList Name="gameplay_keep_DL_085490" Offset="0x85490" />
<Blob Name="gameplay_keep_Blob_085510" Size="0x130" Offset="0x85510" />
<Blob Name="gameplay_keep_Blob_085640" Size="0x10" Offset="0x85640" /> <!-- Is a `KeyFrameSkeleton` struct -->
<KeyFrameSkel Name="gameplay_keep_KFSkel_085640" LimbType="Flex" Offset="0x85640"/>
<!-- Zora Elegy of Emptiness Shell -->
<DList Name="gElegyShellZoraDL" Offset="0x89070" /> <!-- Original name is "pzs_zo_model" -->

View File

@ -12,8 +12,7 @@
<Texture Name="gOpenMouthMoonFaceTex" OutName="open_mouth_moon_face" Format="ci4" Width="64" Height="64" Offset="0x44E8" />
<Texture Name="gOpenMouthMoonTeethTex" OutName="open_mouth_moon_teeth" Format="rgba16" Width="64" Height="32" Offset="0x4CE8" />
<TextureAnimation Name="object_fall2_Matanimheader_005CF0" Offset="0x5CF0" /> <!-- Empty TexAnim -->
<!-- <Blob Name="object_fall2_Blob_005CF8" Size="0x11C" Offset="0x5CF8" /> -->
<Blob Name="object_fall2_Blob_005EF4" Size="0x1C" Offset="0x5EF4" /> <!-- Original name might be "moon_start_anm"; needs c_keyframe docs to know if it's this one or the one below. -->
<KeyFrameAnimation Name="object_fall2_KFAnim_005EF4" Skel="0x8898" Offset="0x5EF4"/> <!-- Original name is "moon_start_anm" -->
<Array Name="object_fall2_Vtx_005F10" Count="239" Offset="0x5F10">
<Vtx />
</Array>
@ -30,6 +29,6 @@
<Texture Name="object_fall2_Tex_007838" OutName="tex_007838" Format="i4" Width="64" Height="64" Offset="0x7838" />
<Texture Name="object_fall2_Tex_008038" OutName="tex_008038" Format="i4" Width="64" Height="64" Offset="0x8038" />
<TextureAnimation Name="object_fall2_Matanimheader_008840" Offset="0x8840" />
<Blob Name="object_fall2_Blob_008898" Size="0x8" Offset="0x8898" /> <!-- Original name might be "moon_start_anm"; needs c_keyframe docs to know if it's this one or the one above. -->
<KeyFrameSkel Name="object_fall2_KFSkel_008898" LimbType="Flex" Offset="0x8898"/>
</File>
</Root>

View File

@ -1,8 +1,6 @@
<Root>
<File Name="object_moonend" Segment="6">
<Blob Name="object_moonend_Blob_000000" Size="0x1214" Offset="0x0" />
<Blob Name="object_moonend_Blob_001214" Size="0x1C" Offset="0x1214" />
<KeyFrameAnimation Name="object_moonened_KFAnim_001214" Skel="0xB5A0" Offset="0x1214"/>
<DList Name="object_moonend_DL_0055F0" Offset="0x55F0" />
<DList Name="object_moonend_DL_0061F8" Offset="0x61F8" />
<DList Name="object_moonend_DL_006460" Offset="0x6460" />
@ -21,10 +19,8 @@
<Texture Name="object_moonend_Tex_009530" OutName="tex_009530" Format="i8" Width="64" Height="64" Offset="0x9530" />
<Texture Name="object_moonend_Tex_00A530" OutName="tex_00A530" Format="i8" Width="64" Height="64" Offset="0xA530" />
<TextureAnimation Name="object_moonend_Matanimheader_00B540" Offset="0xB540" />
<Blob Name="object_moonend_Blob_00B550" Size="0x50" Offset="0xB550" />
<Blob Name="object_moonend_Blob_00B5A0" Size="0x170" Offset="0xB5A0" />
<KeyFrameSkel Name="object_moonend_KFSkel_00B5A0" LimbType="Flex" Offset="0xB5A0"/>
<KeyFrameAnimation Name="object_moonened_KFAnim_00B6F4" Skel="0xE690" Offset="0xB6F4"/>
<DList Name="object_moonend_DL_00CCF0" Offset="0xCCF0" />
<DList Name="object_moonend_DL_00CF58" Offset="0xCF58" />
<DList Name="object_moonend_DL_00D080" Offset="0xD080" />
@ -34,7 +30,7 @@
<DList Name="object_moonend_DL_00D520" Offset="0xD520" />
<Texture Name="object_moonend_Tex_00D648" OutName="tex_00D648" Format="i8" Width="64" Height="64" Offset="0xD648" />
<TextureAnimation Name="object_moonend_Matanimheader_00E650" Offset="0xE650" />
<!-- <Blob Name="object_moonend_Blob_00E658" Size="0x48" Offset="0xE658" /> -->
<KeyFrameSkel Name="object_moonend_KFSkel_00E690" LimbType="Flex" Offset="0xE690"/>
<DList Name="object_moonend_DL_00EB00" Offset="0xEB00" />
<Texture Name="object_moonend_Tex_00EC58" OutName="tex_00EC58" Format="i8" Width="64" Height="64" Offset="0xEC58" />
<DList Name="object_moonend_DL_010C40" Offset="0x10C40" /> <!-- Original name is "rainbow_model" -->

View File

@ -1,8 +1,6 @@
<Root>
<File Name="object_syoten" Segment="6">
<Blob Name="object_syoten_Blob_000000" Size="0x23C" Offset="0x0" />
<Blob Name="object_syoten_Blob_00023C" Size="0x14" Offset="0x23C" />
<KeyFrameAnimation Name="object_syoten_KFAnim_00023C" Skel="0x1328" Offset="0x23C"/>
<DList Name="object_syoten_DL_000450" Offset="0x450" />
<DList Name="object_syoten_DL_000518" Offset="0x518" />
<DList Name="object_syoten_DL_0005E0" Offset="0x5E0" />
@ -14,10 +12,7 @@
<Texture Name="object_syoten_Tex_000A90" OutName="tex_000A90" Format="i8" Width="32" Height="32" Offset="0xA90" />
<Texture Name="object_syoten_Tex_000E90" OutName="tex_000E90" Format="i8" Width="32" Height="32" Offset="0xE90" />
<TextureAnimation Name="object_syoten_Matanimheader_001298" Offset="0x1298" />
<!-- <Blob Name="object_syoten_Blob_0012A0" Size="0x88" Offset="0x12A0" /> -->
<Blob Name="object_syoten_Blob_001328" Size="0x8" Offset="0x1328" />
<KeyFrameSkel Name="object_syoten_KFSkel_001328" LimbType="Flex" Offset="0x1328"/>
<DList Name="object_syoten_DL_001370" Offset="0x1370" />
<TextureAnimation Name="object_syoten_Matanimheader_001448" Offset="0x1448" />
<DList Name="object_syoten_DL_001730" Offset="0x1730" />

View File

@ -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)

View File

@ -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;

View File

@ -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 =

View File

@ -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"

View File

@ -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;

View File

@ -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;

View File

@ -4,7 +4,6 @@
* Description: Seahorse
*/
#include "prevent_bss_reordering.h"
#include "z_en_ot.h"
#include "objects/gameplay_keep/gameplay_keep.h"

View File

@ -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);
}

View File

@ -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);

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

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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;
}

View File

@ -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<uint8_t>& rawData,
offset_t rawDataIndex): CutsceneSubCommandEntry(rawData, 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);
@ -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<uint8_t>& rawData,
offset_t rawDataIndex): CutsceneSubCommandEntry(rawData, rawDataIndex)
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);
@ -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<uint8_t>& rawData,
offset_t rawDataIndex): CutsceneSubCommandEntry(rawData, rawDataIndex)
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);
@ -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<uint8_t>& rawData,
offset_t rawDataIndex): CutsceneSubCommandEntry(rawData, rawDataIndex)
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) {
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<uint8_t>& 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<uint8_t>& 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<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

@ -282,7 +282,8 @@ public:
uint16_t posZ;
uint16_t relTo;
CutsceneSubCommandEntry_SplineCamPoint(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
CutsceneSubCommandEntry_SplineCamPoint(const std::vector<uint8_t>& 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<uint8_t>& rawData, offset_t rawDataIndex);
CutsceneSubCommandEntry_SplineMiscPoint(const std::vector<uint8_t>& 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<uint8_t>& rawData, offset_t rawDataIndex);
public:
CutsceneSubCommandEntry_SplineFooter(const std::vector<uint8_t>& 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<uint8_t>& rawData, offset_t rawDataIndex);
CutsceneSubCommandEntry_SplineHeader(const std::vector<uint8_t>& rawData,
offset_t rawDataIndex);
std::string GetBodySourceCode() const override;

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
@ -13,7 +15,7 @@ const std::unordered_map<CutsceneOoT_CommandType, CsCommandListDescriptor> 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<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">
@ -194,6 +196,8 @@ mkdir build\ZAPD
<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" />
@ -289,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" />

View File

@ -300,6 +300,12 @@
<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">
@ -575,6 +581,12 @@
<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,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<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
{
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;
}
}

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

@ -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);
}
}

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

@ -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<uint8_t>(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<std::string> 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<std::string> parts = StringHelper::Split(includePath, "/");
parts.erase(parts.begin(), parts.begin() + 2);
includePath = StringHelper::Join(parts, "/");
}
Declaration* decl = GetDeclaration(address);
if (decl == nullptr)

View File

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

View File

@ -30,6 +30,21 @@ public:
return result;
}
static std::string Join(const std::vector<std::string> 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;