mirror of
https://github.com/zeldaret/oot.git
synced 2025-05-11 11:33:48 +00:00
implement more skeleton-related types, cleanups, fixups
This commit is contained in:
parent
f70a07f8cf
commit
66db26a999
18 changed files with 459 additions and 128 deletions
4
Makefile
4
Makefile
|
@ -790,7 +790,7 @@ setup: venv
|
||||||
$(MAKE) -C tools
|
$(MAKE) -C tools
|
||||||
$(PYTHON) tools/decompress_baserom.py $(VERSION)
|
$(PYTHON) tools/decompress_baserom.py $(VERSION)
|
||||||
$(PYTHON) tools/extract_baserom.py $(BASEROM_DIR)/baserom-decompressed.z64 $(EXTRACTED_DIR)/baserom -v $(VERSION)
|
$(PYTHON) tools/extract_baserom.py $(BASEROM_DIR)/baserom-decompressed.z64 $(EXTRACTED_DIR)/baserom -v $(VERSION)
|
||||||
$(PYTHON) -m tools.assets.extract -j
|
$(PYTHON) -m tools.assets.extract -j $(EXTRACTED_DIR)/baserom $(EXTRACTED_DIR)
|
||||||
$(PYTHON) tools/extract_incbins.py $(EXTRACTED_DIR)/baserom $(EXTRACTED_DIR)/incbin -v $(VERSION)
|
$(PYTHON) tools/extract_incbins.py $(EXTRACTED_DIR)/baserom $(EXTRACTED_DIR)/incbin -v $(VERSION)
|
||||||
$(PYTHON) tools/extract_text.py $(EXTRACTED_DIR)/baserom $(EXTRACTED_DIR)/text -v $(VERSION)
|
$(PYTHON) tools/extract_text.py $(EXTRACTED_DIR)/baserom $(EXTRACTED_DIR)/text -v $(VERSION)
|
||||||
$(PYTHON) tools/extract_audio.py -o $(EXTRACTED_DIR) -v $(VERSION) --read-xml
|
$(PYTHON) tools/extract_audio.py -o $(EXTRACTED_DIR) -v $(VERSION) --read-xml
|
||||||
|
@ -985,7 +985,7 @@ $(BUILD_DIR)/src/overlays/%_reloc.o: $(BUILD_DIR)/spec
|
||||||
$(AS) $(ASFLAGS) $(@:.o=.s) -o $@
|
$(AS) $(ASFLAGS) $(@:.o=.s) -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/assets/%.inc.c: assets/%.png
|
$(BUILD_DIR)/assets/%.inc.c: assets/%.png
|
||||||
false # TODO
|
false # TODO duplicate extracted/ build rules for git-tracked assets/ too
|
||||||
|
|
||||||
$(BUILD_DIR)/assets/%.u64.inc.c: $(EXTRACTED_DIR)/assets/%.u64.png
|
$(BUILD_DIR)/assets/%.u64.inc.c: $(EXTRACTED_DIR)/assets/%.u64.png
|
||||||
$(PYTHON) tools/assets/build_from_png.py $< $(@:.inc.c=.bin)
|
$(PYTHON) tools/assets/build_from_png.py $< $(@:.inc.c=.bin)
|
||||||
|
|
|
@ -13,7 +13,7 @@ typedef struct BowSlingshotStringData {
|
||||||
/* 0x04 */ Vec3f pos;
|
/* 0x04 */ Vec3f pos;
|
||||||
} BowSlingshotStringData; // size = 0x10
|
} BowSlingshotStringData; // size = 0x10
|
||||||
|
|
||||||
FlexSkeletonHeader* gPlayerSkelHeaders[] = { (void*)&gLinkAdultSkel, (void*)&gLinkChildSkel }; //! FIXME
|
FlexSkeletonHeader* gPlayerSkelHeaders[] = { &gLinkAdultSkel, &gLinkChildSkel };
|
||||||
|
|
||||||
s16 sBootData[PLAYER_BOOTS_MAX][17] = {
|
s16 sBootData[PLAYER_BOOTS_MAX][17] = {
|
||||||
// PLAYER_BOOTS_KOKIRI
|
// PLAYER_BOOTS_KOKIRI
|
||||||
|
|
|
@ -93,7 +93,7 @@ void EnArrow_Init(Actor* thisx, PlayState* play) {
|
||||||
if (this->actor.params <= ARROW_SEED) {
|
if (this->actor.params <= ARROW_SEED) {
|
||||||
|
|
||||||
if (this->actor.params <= ARROW_0E) {
|
if (this->actor.params <= ARROW_0E) {
|
||||||
SkelAnime_Init(play, &this->skelAnime, (void*)&gArrowSkel, &gArrow2Anim, NULL, NULL, 0);
|
SkelAnime_Init(play, &this->skelAnime, &gArrowSkel, &gArrow2Anim, NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->actor.params <= ARROW_NORMAL) {
|
if (this->actor.params <= ARROW_NORMAL) {
|
||||||
|
|
|
@ -67,7 +67,7 @@ static AnimationHeader** sAnimationHeaders[] = { sEponaAnimHeaders, sHniAnimHead
|
||||||
|
|
||||||
static f32 sPlaybackSpeeds[] = { 2.0f / 3.0f, 2.0f / 3.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f / 3.0f, 2.0f / 3.0f };
|
static f32 sPlaybackSpeeds[] = { 2.0f / 3.0f, 2.0f / 3.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f / 3.0f, 2.0f / 3.0f };
|
||||||
|
|
||||||
static SkeletonHeader* sSkeletonHeaders[] = { (void*)&gEponaSkel, (void*)&gHorseIngoSkel };
|
static SkeletonHeader* sSkeletonHeaders[] = { &gEponaSkel, &gHorseIngoSkel };
|
||||||
|
|
||||||
ActorProfile En_Horse_Profile = {
|
ActorProfile En_Horse_Profile = {
|
||||||
/**/ ACTOR_EN_HORSE,
|
/**/ ACTOR_EN_HORSE,
|
||||||
|
|
|
@ -177,7 +177,7 @@ void EnHorseGanon_Init(Actor* thisx, PlayState* play) {
|
||||||
this->actor.focus.pos = this->actor.world.pos;
|
this->actor.focus.pos = this->actor.world.pos;
|
||||||
this->action = 0;
|
this->action = 0;
|
||||||
this->actor.focus.pos.y += 70.0f;
|
this->actor.focus.pos.y += 70.0f;
|
||||||
Skin_Init(play, &this->skin, (void*)&gHorseGanonSkel, &gHorseGanonIdleAnim);
|
Skin_Init(play, &this->skin, &gHorseGanonSkel, &gHorseGanonIdleAnim);
|
||||||
this->currentAnimation = 0;
|
this->currentAnimation = 0;
|
||||||
Animation_PlayOnce(&this->skin.skelAnime, sAnimations[0]);
|
Animation_PlayOnce(&this->skin.skelAnime, sAnimations[0]);
|
||||||
|
|
||||||
|
|
|
@ -162,7 +162,7 @@ void EnHorseLinkChild_Init(Actor* thisx, PlayState* play) {
|
||||||
this->action = 1;
|
this->action = 1;
|
||||||
this->actor.focus.pos = this->actor.world.pos;
|
this->actor.focus.pos = this->actor.world.pos;
|
||||||
this->actor.focus.pos.y += 70.0f;
|
this->actor.focus.pos.y += 70.0f;
|
||||||
Skin_Init(play, &this->skin, (void*)&gChildEponaSkel, &gChildEponaGallopingAnim);
|
Skin_Init(play, &this->skin, &gChildEponaSkel, &gChildEponaGallopingAnim);
|
||||||
this->animationIdx = 0;
|
this->animationIdx = 0;
|
||||||
Animation_PlayOnce(&this->skin.skelAnime, sAnimations[0]);
|
Animation_PlayOnce(&this->skin.skelAnime, sAnimations[0]);
|
||||||
Collider_InitCylinder(play, &this->bodyCollider);
|
Collider_InitCylinder(play, &this->bodyCollider);
|
||||||
|
|
|
@ -226,7 +226,7 @@ void EnHorseNormal_Init(Actor* thisx, PlayState* play) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->actor.home.rot.z = this->actor.world.rot.z = this->actor.shape.rot.z = 0;
|
this->actor.home.rot.z = this->actor.world.rot.z = this->actor.shape.rot.z = 0;
|
||||||
Skin_Init(play, &this->skin, (void*)&gHorseNormalSkel, &gHorseNormalIdleAnim);
|
Skin_Init(play, &this->skin, &gHorseNormalSkel, &gHorseNormalIdleAnim);
|
||||||
Animation_PlayOnce(&this->skin.skelAnime, sAnimations[this->animationIdx]);
|
Animation_PlayOnce(&this->skin.skelAnime, sAnimations[this->animationIdx]);
|
||||||
if ((this->actor.world.pos.x == -730.0f && this->actor.world.pos.y == 0.0f &&
|
if ((this->actor.world.pos.x == -730.0f && this->actor.world.pos.y == 0.0f &&
|
||||||
this->actor.world.pos.z == -1100.0f) ||
|
this->actor.world.pos.z == -1100.0f) ||
|
||||||
|
@ -240,7 +240,7 @@ void EnHorseNormal_Init(Actor* thisx, PlayState* play) {
|
||||||
Actor_Kill(&this->actor);
|
Actor_Kill(&this->actor);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
Skin_Init(play, &this->skin, (void*)&gHorseNormalSkel, &gHorseNormalIdleAnim);
|
Skin_Init(play, &this->skin, &gHorseNormalSkel, &gHorseNormalIdleAnim);
|
||||||
Animation_PlayOnce(&this->skin.skelAnime, sAnimations[this->animationIdx]);
|
Animation_PlayOnce(&this->skin.skelAnime, sAnimations[this->animationIdx]);
|
||||||
func_80A6C6B0(this);
|
func_80A6C6B0(this);
|
||||||
return;
|
return;
|
||||||
|
@ -248,15 +248,15 @@ void EnHorseNormal_Init(Actor* thisx, PlayState* play) {
|
||||||
} else if (play->sceneId == SCENE_GERUDOS_FORTRESS) {
|
} else if (play->sceneId == SCENE_GERUDOS_FORTRESS) {
|
||||||
if (this->actor.world.pos.x == 3707.0f && this->actor.world.pos.y == 1413.0f &&
|
if (this->actor.world.pos.x == 3707.0f && this->actor.world.pos.y == 1413.0f &&
|
||||||
this->actor.world.pos.z == -665.0f) {
|
this->actor.world.pos.z == -665.0f) {
|
||||||
Skin_Init(play, &this->skin, (void*)&gHorseNormalSkel, &gHorseNormalIdleAnim);
|
Skin_Init(play, &this->skin, &gHorseNormalSkel, &gHorseNormalIdleAnim);
|
||||||
Animation_PlayOnce(&this->skin.skelAnime, sAnimations[this->animationIdx]);
|
Animation_PlayOnce(&this->skin.skelAnime, sAnimations[this->animationIdx]);
|
||||||
func_80A6C4CC(this);
|
func_80A6C4CC(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Skin_Init(play, &this->skin, (void*)&gHorseNormalSkel, &gHorseNormalIdleAnim);
|
Skin_Init(play, &this->skin, &gHorseNormalSkel, &gHorseNormalIdleAnim);
|
||||||
Animation_PlayOnce(&this->skin.skelAnime, sAnimations[this->animationIdx]);
|
Animation_PlayOnce(&this->skin.skelAnime, sAnimations[this->animationIdx]);
|
||||||
} else {
|
} else {
|
||||||
Skin_Init(play, &this->skin, (void*)&gHorseNormalSkel, &gHorseNormalIdleAnim);
|
Skin_Init(play, &this->skin, &gHorseNormalSkel, &gHorseNormalIdleAnim);
|
||||||
Animation_PlayOnce(&this->skin.skelAnime, sAnimations[this->animationIdx]);
|
Animation_PlayOnce(&this->skin.skelAnime, sAnimations[this->animationIdx]);
|
||||||
}
|
}
|
||||||
if (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x10 && PARAMS_GET_U(this->actor.params, 0, 4) != 0xF) {
|
if (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x10 && PARAMS_GET_U(this->actor.params, 0, 4) != 0xF) {
|
||||||
|
|
|
@ -158,7 +158,7 @@ void EnHorseZelda_Init(Actor* thisx, PlayState* play) {
|
||||||
this->actor.focus.pos = this->actor.world.pos;
|
this->actor.focus.pos = this->actor.world.pos;
|
||||||
this->action = 0;
|
this->action = 0;
|
||||||
this->actor.focus.pos.y += 70.0f;
|
this->actor.focus.pos.y += 70.0f;
|
||||||
Skin_Init(play, &this->skin, (void*)&gHorseZeldaSkel, &gHorseZeldaGallopingAnim);
|
Skin_Init(play, &this->skin, &gHorseZeldaSkel, &gHorseZeldaGallopingAnim);
|
||||||
this->animationIndex = 0;
|
this->animationIndex = 0;
|
||||||
Animation_PlayOnce(&this->skin.skelAnime, sAnimationHeaders[0]);
|
Animation_PlayOnce(&this->skin.skelAnime, sAnimationHeaders[0]);
|
||||||
Collider_InitCylinder(play, &this->colliderCylinder);
|
Collider_InitCylinder(play, &this->colliderCylinder);
|
||||||
|
|
|
@ -102,7 +102,7 @@ void EnTorch2_Init(Actor* thisx, PlayState* play2) {
|
||||||
this->currentShield = PLAYER_SHIELD_HYLIAN;
|
this->currentShield = PLAYER_SHIELD_HYLIAN;
|
||||||
this->heldItemAction = this->heldItemId = PLAYER_IA_SWORD_MASTER;
|
this->heldItemAction = this->heldItemId = PLAYER_IA_SWORD_MASTER;
|
||||||
Player_SetModelGroup(this, PLAYER_MODELGROUP_SWORD_AND_SHIELD);
|
Player_SetModelGroup(this, PLAYER_MODELGROUP_SWORD_AND_SHIELD);
|
||||||
play->playerInit(this, play, (void*)&gDarkLinkSkel); //! FIXME
|
play->playerInit(this, play, &gDarkLinkSkel);
|
||||||
this->actor.naviEnemyId = NAVI_ENEMY_DARK_LINK;
|
this->actor.naviEnemyId = NAVI_ENEMY_DARK_LINK;
|
||||||
this->cylinder.base.acFlags = AC_ON | AC_TYPE_PLAYER;
|
this->cylinder.base.acFlags = AC_ON | AC_TYPE_PLAYER;
|
||||||
this->meleeWeaponQuads[0].base.atFlags = this->meleeWeaponQuads[1].base.atFlags = AT_ON | AT_TYPE_ENEMY;
|
this->meleeWeaponQuads[0].base.atFlags = this->meleeWeaponQuads[1].base.atFlags = AT_ON | AT_TYPE_ENEMY;
|
||||||
|
|
|
@ -80,7 +80,7 @@ void EnfHG_Init(Actor* thisx, PlayState* play2) {
|
||||||
this->actor.speed = 0.0f;
|
this->actor.speed = 0.0f;
|
||||||
this->actor.focus.pos = this->actor.world.pos;
|
this->actor.focus.pos = this->actor.world.pos;
|
||||||
this->actor.focus.pos.y += 70.0f;
|
this->actor.focus.pos.y += 70.0f;
|
||||||
Skin_Init(play, &this->skin, (void*)&gPhantomHorseSkel, &gPhantomHorseRunningAnim);
|
Skin_Init(play, &this->skin, &gPhantomHorseSkel, &gPhantomHorseRunningAnim);
|
||||||
|
|
||||||
if (this->actor.params >= GND_FAKE_BOSS) {
|
if (this->actor.params >= GND_FAKE_BOSS) {
|
||||||
EnfHG_SetupApproach(this, play, this->actor.params - GND_FAKE_BOSS);
|
EnfHG_SetupApproach(this, play, this->actor.params - GND_FAKE_BOSS);
|
||||||
|
|
|
@ -687,6 +687,8 @@ class File:
|
||||||
h.writelines(headers_includes)
|
h.writelines(headers_includes)
|
||||||
h.write("\n")
|
h.write("\n")
|
||||||
|
|
||||||
|
if not self._is_resources_sorted:
|
||||||
|
self.sort_resources()
|
||||||
for resource in self._resources:
|
for resource in self._resources:
|
||||||
|
|
||||||
if resource.write_c_definition(c):
|
if resource.write_c_definition(c):
|
||||||
|
@ -720,6 +722,14 @@ class File:
|
||||||
+ f"({self.name!r}, data is None={self.data is None}, size={self.size}, {self._resources!r})"
|
+ f"({self.name!r}, data is None={self.data is None}, size={self.size}, {self._resources!r})"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def __rich_repr__(self):
|
||||||
|
yield "name", self.name
|
||||||
|
yield "data is None", self.data is None
|
||||||
|
yield "size", self.size
|
||||||
|
yield "resources", self._resources
|
||||||
|
|
||||||
|
__rich_repr__.angular = True
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# resources
|
# resources
|
||||||
|
@ -973,7 +983,7 @@ class Resource(abc.ABC):
|
||||||
else "..."
|
else "..."
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
f"file_name={self.file.name!r}",
|
f"file.name={self.file.name!r}",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
+ ")"
|
+ ")"
|
||||||
|
@ -985,7 +995,7 @@ class Resource(abc.ABC):
|
||||||
f"0x{self.range_start:08X}-"
|
f"0x{self.range_start:08X}-"
|
||||||
+ (f"0x{self.range_end:08X}" if self.range_end is not None else "...")
|
+ (f"0x{self.range_end:08X}" if self.range_end is not None else "...")
|
||||||
)
|
)
|
||||||
yield "file_name", self.file.name
|
yield "file.name", self.file.name
|
||||||
|
|
||||||
__rich_repr__.angular = True
|
__rich_repr__.angular = True
|
||||||
|
|
||||||
|
|
|
@ -303,7 +303,10 @@ class CDataArrayResource(CDataResource):
|
||||||
return super().try_parse_data(memory_context)
|
return super().try_parse_data(memory_context)
|
||||||
|
|
||||||
def get_c_reference(self, resource_offset: int):
|
def get_c_reference(self, resource_offset: int):
|
||||||
|
if resource_offset == 0:
|
||||||
return self.symbol_name
|
return self.symbol_name
|
||||||
|
else:
|
||||||
|
raise ValueError
|
||||||
|
|
||||||
def get_c_expression_length(self, resource_offset: int):
|
def get_c_expression_length(self, resource_offset: int):
|
||||||
if resource_offset == 0:
|
if resource_offset == 0:
|
||||||
|
|
|
@ -899,7 +899,7 @@ class ColorIndexedTexturesManager:
|
||||||
tluts: dict[int, "ColorIndexedTexturesManager.Tlut"]
|
tluts: dict[int, "ColorIndexedTexturesManager.Tlut"]
|
||||||
texs: list["ColorIndexedTexturesManager.Tex"]
|
texs: list["ColorIndexedTexturesManager.Tex"]
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self, *, HACK_late_SetTextureLUT=False):
|
||||||
self.cur_tlut_mode: G_TT = None
|
self.cur_tlut_mode: G_TT = None
|
||||||
|
|
||||||
self.cur_tluts_count: int = None
|
self.cur_tluts_count: int = None
|
||||||
|
@ -908,6 +908,11 @@ class ColorIndexedTexturesManager:
|
||||||
|
|
||||||
self.ci_states: list[ColorIndexedTexturesManager.CIState] = []
|
self.ci_states: list[ColorIndexedTexturesManager.CIState] = []
|
||||||
|
|
||||||
|
# Rarely,
|
||||||
|
# gsDPSetTextureLUT comes after gsDPLoadTextureBlock and gsDPLoadTLUT,
|
||||||
|
# instead of before
|
||||||
|
self.HACK_late_SetTextureLUT = HACK_late_SetTextureLUT
|
||||||
|
|
||||||
def ci_timg(self, timg, fmt: G_IM_FMT, siz: G_IM_SIZ, width, height, pal):
|
def ci_timg(self, timg, fmt: G_IM_FMT, siz: G_IM_SIZ, width, height, pal):
|
||||||
if VERBOSE_ColorIndexedTexturesManager:
|
if VERBOSE_ColorIndexedTexturesManager:
|
||||||
print(
|
print(
|
||||||
|
@ -920,6 +925,7 @@ class ColorIndexedTexturesManager:
|
||||||
pal,
|
pal,
|
||||||
)
|
)
|
||||||
assert fmt == G_IM_FMT.CI
|
assert fmt == G_IM_FMT.CI
|
||||||
|
if not self.HACK_late_SetTextureLUT:
|
||||||
assert self.cur_tlut_mode != G_TT.NONE
|
assert self.cur_tlut_mode != G_TT.NONE
|
||||||
|
|
||||||
self.cur_texs.append(
|
self.cur_texs.append(
|
||||||
|
@ -933,6 +939,7 @@ class ColorIndexedTexturesManager:
|
||||||
# HACK idx==-1 may be a libgfxd bug?
|
# HACK idx==-1 may be a libgfxd bug?
|
||||||
assert count == 256
|
assert count == 256
|
||||||
idx = 0
|
idx = 0
|
||||||
|
if not self.HACK_late_SetTextureLUT:
|
||||||
assert self.cur_tlut_mode != G_TT.NONE
|
assert self.cur_tlut_mode != G_TT.NONE
|
||||||
if self.cur_tluts_count != count:
|
if self.cur_tluts_count != count:
|
||||||
self.cur_tluts.clear() # TODO ? idk. (at worst it will cause errors)
|
self.cur_tluts.clear() # TODO ? idk. (at worst it will cause errors)
|
||||||
|
@ -943,6 +950,7 @@ class ColorIndexedTexturesManager:
|
||||||
if VERBOSE_ColorIndexedTexturesManager:
|
if VERBOSE_ColorIndexedTexturesManager:
|
||||||
print("ColorIndexedTexturesManager.tlut_mode", tt)
|
print("ColorIndexedTexturesManager.tlut_mode", tt)
|
||||||
if self.cur_tlut_mode != tt:
|
if self.cur_tlut_mode != tt:
|
||||||
|
if not self.HACK_late_SetTextureLUT:
|
||||||
self.cur_tluts.clear() # TODO ? idk. (at worst it will cause errors)
|
self.cur_tluts.clear() # TODO ? idk. (at worst it will cause errors)
|
||||||
self.cur_tlut_mode = tt
|
self.cur_tlut_mode = tt
|
||||||
|
|
||||||
|
@ -1101,7 +1109,10 @@ class DListResource(Resource, can_size_be_unknown=True):
|
||||||
)
|
)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
ci_tex_manager = ColorIndexedTexturesManager()
|
ci_tex_manager = ColorIndexedTexturesManager(
|
||||||
|
# TODO
|
||||||
|
HACK_late_SetTextureLUT=(self.name in {"gEponaHeadLimb_0600AC20_DL"})
|
||||||
|
)
|
||||||
|
|
||||||
def timg_cb(timg, fmt, siz, width, height, pal):
|
def timg_cb(timg, fmt, siz, width, height, pal):
|
||||||
g_fmt = G_IM_FMT.by_i[fmt]
|
g_fmt = G_IM_FMT.by_i[fmt]
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
from __future__ import annotations
|
|
||||||
import io
|
import io
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ..extase.memorymap import MemoryContext
|
from ..extase.memorymap import MemoryContext
|
||||||
|
|
||||||
from ..extase import (
|
|
||||||
File,
|
|
||||||
ResourceParseWaiting,
|
|
||||||
)
|
|
||||||
from ..extase.cdata_resources import (
|
from ..extase.cdata_resources import (
|
||||||
CDataResource,
|
CDataResource,
|
||||||
|
CDataArrayResource,
|
||||||
CDataExt_Value,
|
CDataExt_Value,
|
||||||
CDataExt_Struct,
|
CDataExt_Struct,
|
||||||
CDataExt_Array,
|
CDataExt_Array,
|
||||||
|
@ -40,15 +36,38 @@ class StandardLimbResource(CDataResource):
|
||||||
raise ValueError()
|
raise ValueError()
|
||||||
|
|
||||||
|
|
||||||
class LimbsArrayResource(CDataResource, can_size_be_unknown=True):
|
class LODLimbResource(CDataResource):
|
||||||
|
cdata_ext = CDataExt_Struct(
|
||||||
|
(
|
||||||
|
("jointPos", cdata_ext_Vec3s),
|
||||||
|
("child", CDataExt_Value.u8),
|
||||||
|
("sibling", CDataExt_Value.u8),
|
||||||
|
("dLists", CDataExt_Array(dlist_resources.cdata_ext_gfx_segmented, 2)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_c_declaration_base(self):
|
||||||
|
return f"LodLimb {self.symbol_name}"
|
||||||
|
|
||||||
|
def get_c_reference(self, resource_offset: int):
|
||||||
|
if resource_offset == 0:
|
||||||
|
return f"&{self.symbol_name}"
|
||||||
|
else:
|
||||||
|
raise ValueError()
|
||||||
|
|
||||||
|
|
||||||
|
class LimbsArrayResourceABC(CDataArrayResource):
|
||||||
|
limb_type: type[CDataResource]
|
||||||
|
c_limb_type: str
|
||||||
|
|
||||||
def report_limb_element(resource, memory_context: "MemoryContext", v):
|
def report_limb_element(resource, memory_context: "MemoryContext", v):
|
||||||
assert isinstance(v, int)
|
assert isinstance(v, int)
|
||||||
address = v
|
address = v
|
||||||
memory_context.report_resource_at_segmented(
|
memory_context.report_resource_at_segmented(
|
||||||
resource,
|
resource,
|
||||||
address,
|
address,
|
||||||
StandardLimbResource,
|
resource.limb_type,
|
||||||
lambda file, offset: StandardLimbResource(
|
lambda file, offset: resource.limb_type(
|
||||||
file, offset, f"{resource.name}_{address:08X}"
|
file, offset, f"{resource.name}_{address:08X}"
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -68,51 +87,39 @@ class LimbsArrayResource(CDataResource, can_size_be_unknown=True):
|
||||||
.set_write(write_limb_element)
|
.set_write(write_limb_element)
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, file: File, range_start: int, name: str):
|
|
||||||
super().__init__(file, range_start, name)
|
|
||||||
self.length = None
|
|
||||||
|
|
||||||
def try_parse_data(self, memory_context: "MemoryContext"):
|
|
||||||
if self.length is not None:
|
|
||||||
self.cdata_ext = CDataExt_Array(self.elem_cdata_ext, self.length)
|
|
||||||
self.range_end = self.range_start + self.cdata_ext.size
|
|
||||||
return super().try_parse_data(memory_context)
|
|
||||||
else:
|
|
||||||
raise ResourceParseWaiting(waiting_for=["self.length"])
|
|
||||||
|
|
||||||
def get_c_declaration_base(self):
|
def get_c_declaration_base(self):
|
||||||
return f"void* {self.symbol_name}[]"
|
return f"{self.c_limb_type}* {self.symbol_name}[]"
|
||||||
|
|
||||||
def get_c_reference(self, resource_offset: int):
|
|
||||||
if resource_offset == 0:
|
|
||||||
return f"{self.symbol_name}"
|
|
||||||
else:
|
|
||||||
raise ValueError()
|
|
||||||
|
|
||||||
def get_c_expression_length(self, resource_offset: int):
|
|
||||||
if resource_offset == 0:
|
|
||||||
return f"ARRAY_COUNT({self.symbol_name})"
|
|
||||||
else:
|
|
||||||
raise ValueError()
|
|
||||||
|
|
||||||
|
|
||||||
class SkeletonNormalResource(CDataResource):
|
class StandardLimbsArrayResource(LimbsArrayResourceABC):
|
||||||
|
limb_type = StandardLimbResource
|
||||||
|
c_limb_type = "StandardLimb"
|
||||||
|
|
||||||
|
|
||||||
|
class LODLimbsArrayResource(LimbsArrayResourceABC):
|
||||||
|
limb_type = LODLimbResource
|
||||||
|
c_limb_type = "LodLimb"
|
||||||
|
|
||||||
|
|
||||||
|
class SkeletonResourceABC(CDataResource):
|
||||||
|
limbs_array_type: type[LimbsArrayResourceABC]
|
||||||
|
|
||||||
def report_segment(resource, memory_context: "MemoryContext", v):
|
def report_segment(resource, memory_context: "MemoryContext", v):
|
||||||
assert isinstance(v, int)
|
assert isinstance(v, int)
|
||||||
address = v
|
address = v
|
||||||
resource_limbs = memory_context.report_resource_at_segmented(
|
resource_limbs = memory_context.report_resource_at_segmented(
|
||||||
resource,
|
resource,
|
||||||
address,
|
address,
|
||||||
LimbsArrayResource,
|
resource.limbs_array_type,
|
||||||
lambda file, offset: LimbsArrayResource(
|
lambda file, offset: resource.limbs_array_type(
|
||||||
file,
|
file,
|
||||||
offset,
|
offset,
|
||||||
f"{resource.name}_{address:08X}_Limbs",
|
f"{resource.name}_{address:08X}_Limbs",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
resource_limbs.length = resource.get_skeleton_header_cdata_unpacked()[
|
resource_limbs.set_length(
|
||||||
"limbCount"
|
resource.get_skeleton_header_cdata_unpacked()["limbCount"]
|
||||||
]
|
)
|
||||||
|
|
||||||
def write_segment(
|
def write_segment(
|
||||||
resource, memory_context: "MemoryContext", v, f: io.TextIOBase, line_prefix
|
resource, memory_context: "MemoryContext", v, f: io.TextIOBase, line_prefix
|
||||||
|
@ -162,18 +169,32 @@ class SkeletonNormalResource(CDataResource):
|
||||||
return f"SkeletonHeader {self.symbol_name}"
|
return f"SkeletonHeader {self.symbol_name}"
|
||||||
|
|
||||||
|
|
||||||
class SkeletonFlexResource(CDataResource):
|
class SkeletonNormalResource(SkeletonResourceABC):
|
||||||
cdata_ext = CDataExt_Struct(
|
limbs_array_type = StandardLimbsArrayResource
|
||||||
|
|
||||||
|
|
||||||
|
class SkeletonNormalLODResource(SkeletonResourceABC):
|
||||||
|
limbs_array_type = LODLimbsArrayResource
|
||||||
|
|
||||||
|
|
||||||
|
class SkeletonFlexResourceABC(CDataResource):
|
||||||
|
skeleton_type: type[SkeletonResourceABC]
|
||||||
|
|
||||||
|
# For SkeletonResourceABC.report_segment
|
||||||
|
@property
|
||||||
|
def limbs_array_type(self):
|
||||||
|
return self.skeleton_type.limbs_array_type
|
||||||
|
|
||||||
|
def __init__(self, file, range_start, name):
|
||||||
|
self.cdata_ext = CDataExt_Struct(
|
||||||
(
|
(
|
||||||
(
|
("sh", self.skeleton_type.cdata_ext),
|
||||||
"sh",
|
|
||||||
SkeletonNormalResource.cdata_ext,
|
|
||||||
), # TODO FIXME this is bad, it ends up using StandardLimb s (or is it fine?)
|
|
||||||
("dListCount", CDataExt_Value.u8),
|
("dListCount", CDataExt_Value.u8),
|
||||||
("pad9", CDataExt_Value.pad8),
|
("pad9", CDataExt_Value.pad8),
|
||||||
("pad10", CDataExt_Value.pad16),
|
("pad10", CDataExt_Value.pad16),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
super().__init__(file, range_start, name)
|
||||||
|
|
||||||
def get_skeleton_header_cdata_unpacked(self):
|
def get_skeleton_header_cdata_unpacked(self):
|
||||||
return self.cdata_unpacked["sh"]
|
return self.cdata_unpacked["sh"]
|
||||||
|
@ -186,3 +207,11 @@ class SkeletonFlexResource(CDataResource):
|
||||||
|
|
||||||
def get_c_declaration_base(self):
|
def get_c_declaration_base(self):
|
||||||
return f"FlexSkeletonHeader {self.symbol_name}"
|
return f"FlexSkeletonHeader {self.symbol_name}"
|
||||||
|
|
||||||
|
|
||||||
|
class SkeletonFlexResource(SkeletonFlexResourceABC):
|
||||||
|
skeleton_type = SkeletonNormalResource
|
||||||
|
|
||||||
|
|
||||||
|
class SkeletonFlexLODResource(SkeletonFlexResourceABC):
|
||||||
|
skeleton_type = SkeletonNormalLODResource
|
||||||
|
|
244
tools/assets/extract/extase_oot64/skeleton_skin_resources.py
Normal file
244
tools/assets/extract/extase_oot64/skeleton_skin_resources.py
Normal file
|
@ -0,0 +1,244 @@
|
||||||
|
import io
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from ..oot64_data.misc_ids import SKIN_LIMB_TYPES
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from ..extase.memorymap import MemoryContext
|
||||||
|
|
||||||
|
from ..extase.cdata_resources import (
|
||||||
|
CDataResource,
|
||||||
|
CDataArrayResource,
|
||||||
|
CDataExt_Value,
|
||||||
|
CDataExt_Struct,
|
||||||
|
cdata_ext_Vec3s,
|
||||||
|
)
|
||||||
|
|
||||||
|
from . import dlist_resources
|
||||||
|
from . import skeleton_resources
|
||||||
|
|
||||||
|
|
||||||
|
class SkinVertexArrayResource(CDataArrayResource):
|
||||||
|
elem_cdata_ext = CDataExt_Struct(
|
||||||
|
(
|
||||||
|
("index", CDataExt_Value.u16),
|
||||||
|
("s", CDataExt_Value.s16),
|
||||||
|
("t", CDataExt_Value.s16),
|
||||||
|
("normX", CDataExt_Value.s8),
|
||||||
|
("normY", CDataExt_Value.s8),
|
||||||
|
("normZ", CDataExt_Value.s8),
|
||||||
|
("alpha", CDataExt_Value.u8),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_c_declaration_base(self):
|
||||||
|
return f"SkinVertex {self.symbol_name}[]"
|
||||||
|
|
||||||
|
|
||||||
|
class SkinTransformationArrayResource(CDataArrayResource):
|
||||||
|
elem_cdata_ext = CDataExt_Struct(
|
||||||
|
(
|
||||||
|
("limbIndex", CDataExt_Value.u8),
|
||||||
|
("pad1", CDataExt_Value.pad8),
|
||||||
|
("x", CDataExt_Value.s16),
|
||||||
|
("y", CDataExt_Value.s16),
|
||||||
|
("z", CDataExt_Value.s16),
|
||||||
|
("scale", CDataExt_Value.u8),
|
||||||
|
("pad9", CDataExt_Value.pad8),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_c_declaration_base(self):
|
||||||
|
return f"SkinTransformation {self.symbol_name}[]"
|
||||||
|
|
||||||
|
|
||||||
|
class SkinLimbModifArrayResource(CDataArrayResource):
|
||||||
|
def report_elem(resource, memory_context: "MemoryContext", v):
|
||||||
|
assert isinstance(v, dict)
|
||||||
|
|
||||||
|
address = v["skinVertices"]
|
||||||
|
assert isinstance(address, int)
|
||||||
|
skin_vertices_res = memory_context.report_resource_at_segmented(
|
||||||
|
resource,
|
||||||
|
address,
|
||||||
|
SkinVertexArrayResource,
|
||||||
|
lambda file, offset: SkinVertexArrayResource(
|
||||||
|
file,
|
||||||
|
offset,
|
||||||
|
f"{resource.name}_{offset:08X}_SkinVertices",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
skin_vertices_res.set_length(v["vtxCount"])
|
||||||
|
|
||||||
|
address = v["limbTransformations"]
|
||||||
|
assert isinstance(address, int)
|
||||||
|
skin_vertices_res = memory_context.report_resource_at_segmented(
|
||||||
|
resource,
|
||||||
|
address,
|
||||||
|
SkinTransformationArrayResource,
|
||||||
|
lambda file, offset: SkinTransformationArrayResource(
|
||||||
|
file,
|
||||||
|
offset,
|
||||||
|
f"{resource.name}_{offset:08X}_SkinTransforms",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
skin_vertices_res.set_length(v["transformCount"])
|
||||||
|
|
||||||
|
def write_skinVertices(
|
||||||
|
resource, memory_context: "MemoryContext", v, f: io.TextIOBase, line_prefix
|
||||||
|
):
|
||||||
|
assert isinstance(v, int)
|
||||||
|
address = v
|
||||||
|
f.write(line_prefix)
|
||||||
|
f.write(memory_context.get_c_reference_at_segmented(address))
|
||||||
|
return True
|
||||||
|
|
||||||
|
def write_limbTransformations(
|
||||||
|
resource, memory_context: "MemoryContext", v, f: io.TextIOBase, line_prefix
|
||||||
|
):
|
||||||
|
assert isinstance(v, int)
|
||||||
|
address = v
|
||||||
|
f.write(line_prefix)
|
||||||
|
f.write(memory_context.get_c_reference_at_segmented(address))
|
||||||
|
return True
|
||||||
|
|
||||||
|
elem_cdata_ext = CDataExt_Struct(
|
||||||
|
(
|
||||||
|
("vtxCount", CDataExt_Value.u16),
|
||||||
|
("transformCount", CDataExt_Value.u16),
|
||||||
|
("unk_4", CDataExt_Value.u16),
|
||||||
|
("pad6", CDataExt_Value.pad16),
|
||||||
|
(
|
||||||
|
"skinVertices",
|
||||||
|
(CDataExt_Value("I").set_write(write_skinVertices)),
|
||||||
|
), # SkinVertex*
|
||||||
|
(
|
||||||
|
"limbTransformations",
|
||||||
|
(CDataExt_Value("I").set_write(write_limbTransformations)),
|
||||||
|
), # SkinTransformation*
|
||||||
|
)
|
||||||
|
).set_report(report_elem)
|
||||||
|
|
||||||
|
def get_c_declaration_base(self):
|
||||||
|
return f"SkinLimbModif {self.symbol_name}[]"
|
||||||
|
|
||||||
|
|
||||||
|
class SkinAnimatedLimbDataResource(CDataResource):
|
||||||
|
def report_limbModifications(resource, memory_context: "MemoryContext", v):
|
||||||
|
assert isinstance(v, int)
|
||||||
|
address = v
|
||||||
|
skin_vertices_res = memory_context.report_resource_at_segmented(
|
||||||
|
resource,
|
||||||
|
address,
|
||||||
|
SkinLimbModifArrayResource,
|
||||||
|
lambda file, offset: SkinLimbModifArrayResource(
|
||||||
|
file,
|
||||||
|
offset,
|
||||||
|
f"{resource.name}_{offset:08X}_SkinLimbModifs",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
skin_vertices_res.set_length(resource.cdata_unpacked["limbModifCount"])
|
||||||
|
|
||||||
|
def write_limbModifications(
|
||||||
|
resource, memory_context: "MemoryContext", v, f: io.TextIOBase, line_prefix
|
||||||
|
):
|
||||||
|
assert isinstance(v, int)
|
||||||
|
address = v
|
||||||
|
f.write(line_prefix)
|
||||||
|
f.write(memory_context.get_c_reference_at_segmented(address))
|
||||||
|
return True
|
||||||
|
|
||||||
|
cdata_ext = CDataExt_Struct(
|
||||||
|
(
|
||||||
|
("totalVtxCount", CDataExt_Value.u16),
|
||||||
|
("limbModifCount", CDataExt_Value.u16),
|
||||||
|
(
|
||||||
|
"limbModifications",
|
||||||
|
(
|
||||||
|
CDataExt_Value("I")
|
||||||
|
.set_report(report_limbModifications)
|
||||||
|
.set_write(write_limbModifications)
|
||||||
|
),
|
||||||
|
), # SkinLimbModif*
|
||||||
|
("dlist", dlist_resources.cdata_ext_gfx_segmented),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_c_declaration_base(self):
|
||||||
|
return f"SkinAnimatedLimbData {self.symbol_name}"
|
||||||
|
|
||||||
|
def get_c_reference(self, resource_offset: int):
|
||||||
|
if resource_offset == 0:
|
||||||
|
return f"&{self.symbol_name}"
|
||||||
|
else:
|
||||||
|
raise ValueError()
|
||||||
|
|
||||||
|
|
||||||
|
class SkinLimbResource(CDataResource):
|
||||||
|
def report_segment(resource, memory_context: "MemoryContext", v):
|
||||||
|
assert isinstance(v, int)
|
||||||
|
address = v
|
||||||
|
segmentType = resource.cdata_unpacked["segmentType"]
|
||||||
|
if segmentType == 4: # SKIN_LIMB_TYPE_ANIMATED
|
||||||
|
# segment is SkinAnimatedLimbData*
|
||||||
|
assert address != 0
|
||||||
|
memory_context.report_resource_at_segmented(
|
||||||
|
resource,
|
||||||
|
address,
|
||||||
|
SkinAnimatedLimbDataResource, # TODO
|
||||||
|
lambda file, offset: SkinAnimatedLimbDataResource(
|
||||||
|
file, offset, f"{resource.name}_{address:08X}_SkinAnimatedLimbData"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
elif segmentType == 11: # SKIN_LIMB_TYPE_NORMAL
|
||||||
|
# segment is Gfx*
|
||||||
|
assert address != 0
|
||||||
|
dlist_resources.report_gfx_segmented(resource, memory_context, address)
|
||||||
|
|
||||||
|
def write_segment(
|
||||||
|
resource, memory_context: "MemoryContext", v, f: io.TextIOBase, line_prefix
|
||||||
|
):
|
||||||
|
assert isinstance(v, int)
|
||||||
|
address = v
|
||||||
|
f.write(line_prefix)
|
||||||
|
if address == 0:
|
||||||
|
f.write("NULL")
|
||||||
|
else:
|
||||||
|
f.write(memory_context.get_c_reference_at_segmented(address))
|
||||||
|
return True
|
||||||
|
|
||||||
|
cdata_ext = CDataExt_Struct(
|
||||||
|
(
|
||||||
|
("jointPos", cdata_ext_Vec3s),
|
||||||
|
("child", CDataExt_Value.u8),
|
||||||
|
("sibling", CDataExt_Value.u8),
|
||||||
|
(
|
||||||
|
"segmentType",
|
||||||
|
CDataExt_Value("i").set_write_str_v(
|
||||||
|
lambda v: SKIN_LIMB_TYPES.get(v, f"{v}")
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"segment",
|
||||||
|
CDataExt_Value("I").set_report(report_segment).set_write(write_segment),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_c_declaration_base(self):
|
||||||
|
return f"SkinLimb {self.symbol_name}"
|
||||||
|
|
||||||
|
def get_c_reference(self, resource_offset: int):
|
||||||
|
if resource_offset == 0:
|
||||||
|
return f"&{self.symbol_name}"
|
||||||
|
else:
|
||||||
|
raise ValueError()
|
||||||
|
|
||||||
|
|
||||||
|
class SkinLimbsArrayResource(skeleton_resources.LimbsArrayResourceABC):
|
||||||
|
limb_type = SkinLimbResource
|
||||||
|
c_limb_type = "SkinLimb"
|
||||||
|
|
||||||
|
|
||||||
|
class SkeletonSkinResource(skeleton_resources.SkeletonResourceABC):
|
||||||
|
limbs_array_type = SkinLimbsArrayResource
|
|
@ -1,5 +1,4 @@
|
||||||
import dataclasses
|
import dataclasses
|
||||||
import functools
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
|
|
||||||
|
@ -33,15 +32,16 @@ WRITE_EXTRACT = True
|
||||||
from ..conf import WRITE_HINTS, I_D_OMEGALUL
|
from ..conf import WRITE_HINTS, I_D_OMEGALUL
|
||||||
|
|
||||||
|
|
||||||
OOT_VERSION = "gc-eu-mq-dbg"
|
@dataclasses.dataclass
|
||||||
BASEROM_PATH = Path("extracted") / OOT_VERSION / "baserom"
|
class ExtractionContext:
|
||||||
BUILD_PATH = Path("build") / OOT_VERSION
|
oot_version: str
|
||||||
EXTRACTED_PATH = Path("extracted") / OOT_VERSION
|
version_memctx_base: MemoryContext
|
||||||
|
baserom_path: Path
|
||||||
|
build_path: Path
|
||||||
|
extracted_path: Path
|
||||||
|
|
||||||
|
def get_baserom_file_data(self, baserom_file_name: str):
|
||||||
@functools.lru_cache(maxsize=200)
|
return memoryview((self.baserom_path / baserom_file_name).read_bytes())
|
||||||
def get_baserom_file_data(baserom_file_name: str):
|
|
||||||
return memoryview((BASEROM_PATH / baserom_file_name).read_bytes())
|
|
||||||
|
|
||||||
|
|
||||||
def create_file_resources(rescoll: ResourcesDescCollection, file: File):
|
def create_file_resources(rescoll: ResourcesDescCollection, file: File):
|
||||||
|
@ -92,7 +92,7 @@ def create_file_resources(rescoll: ResourcesDescCollection, file: File):
|
||||||
|
|
||||||
|
|
||||||
def process_pool(
|
def process_pool(
|
||||||
version_memctx_base: MemoryContext, pool_desc: ResourcesDescCollectionsPool
|
extraction_ctx: ExtractionContext, pool_desc: ResourcesDescCollectionsPool
|
||||||
):
|
):
|
||||||
if VERBOSE2:
|
if VERBOSE2:
|
||||||
print("> process_pool")
|
print("> process_pool")
|
||||||
|
@ -112,7 +112,7 @@ def process_pool(
|
||||||
for rescoll in pool_desc.collections:
|
for rescoll in pool_desc.collections:
|
||||||
if not isinstance(rescoll.backing_memory, BaseromFileBackingMemory):
|
if not isinstance(rescoll.backing_memory, BaseromFileBackingMemory):
|
||||||
raise NotImplementedError(rescoll.backing_memory)
|
raise NotImplementedError(rescoll.backing_memory)
|
||||||
data = get_baserom_file_data(rescoll.backing_memory.name)
|
data = extraction_ctx.get_baserom_file_data(rescoll.backing_memory.name)
|
||||||
if rescoll.backing_memory.range is not None:
|
if rescoll.backing_memory.range is not None:
|
||||||
range_start, range_end = rescoll.backing_memory.range
|
range_start, range_end = rescoll.backing_memory.range
|
||||||
data = data[range_start:range_end]
|
data = data[range_start:range_end]
|
||||||
|
@ -135,7 +135,7 @@ def process_pool(
|
||||||
|
|
||||||
# 2) Build a MemoryContext for each File
|
# 2) Build a MemoryContext for each File
|
||||||
|
|
||||||
memctx_base = version_memctx_base.copy()
|
memctx_base = extraction_ctx.version_memctx_base.copy()
|
||||||
files_by_segment: dict[int, list[File]] = dict()
|
files_by_segment: dict[int, list[File]] = dict()
|
||||||
|
|
||||||
for rescoll, file in file_by_rescoll.items():
|
for rescoll, file in file_by_rescoll.items():
|
||||||
|
@ -228,31 +228,30 @@ def process_pool(
|
||||||
|
|
||||||
# 5)
|
# 5)
|
||||||
|
|
||||||
# TODO this looks jank
|
|
||||||
for rescoll, file in file_by_rescoll.items():
|
for rescoll, file in file_by_rescoll.items():
|
||||||
file.set_source_path(Path("assets") / rescoll.out_path)
|
file.set_source_path(Path("assets") / rescoll.out_path)
|
||||||
|
|
||||||
file.set_resources_paths(
|
file.set_resources_paths(
|
||||||
EXTRACTED_PATH,
|
extraction_ctx.extracted_path,
|
||||||
BUILD_PATH,
|
extraction_ctx.build_path,
|
||||||
Path("assets") / rescoll.out_path,
|
Path("assets") / rescoll.out_path,
|
||||||
)
|
)
|
||||||
|
|
||||||
for file, file_memctx in memctx_by_file.items():
|
for file, file_memctx in memctx_by_file.items():
|
||||||
# write to EXTRACTED_PATH
|
# write to extracted/
|
||||||
if WRITE_EXTRACT:
|
if WRITE_EXTRACT:
|
||||||
file.write_resources_extracted(file_memctx)
|
file.write_resources_extracted(file_memctx)
|
||||||
|
|
||||||
# "source" refers to the main .c and .h `#include`ing all the extracted resources
|
# "source" refers to the main .c and .h `#include`ing all the extracted resources
|
||||||
if WRITE_SOURCE:
|
if WRITE_SOURCE:
|
||||||
# TODO fill referenced_files properly or something
|
# TODO fill referenced_files properly or something
|
||||||
file.referenced_files = set(memctx_by_file.keys())
|
file.referenced_files = set(memctx_by_file.keys()) - {file}
|
||||||
file.write_source()
|
file.write_source()
|
||||||
|
|
||||||
|
|
||||||
def process_pool_wrapped(version_memctx_base, pd):
|
def process_pool_wrapped(extraction_ctx, pd):
|
||||||
try:
|
try:
|
||||||
process_pool(version_memctx_base, pd)
|
process_pool(extraction_ctx, pd)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
import traceback
|
import traceback
|
||||||
import sys
|
import sys
|
||||||
|
@ -273,6 +272,16 @@ def main():
|
||||||
from tools import version_config
|
from tools import version_config
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument(
|
||||||
|
"baserom_segments_dir",
|
||||||
|
type=Path,
|
||||||
|
help="Directory of uncompressed ROM segments",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"output_dir",
|
||||||
|
type=Path,
|
||||||
|
help="Output directory to place files in",
|
||||||
|
)
|
||||||
parser.add_argument("-v", dest="oot_version", default="gc-eu-mq-dbg")
|
parser.add_argument("-v", dest="oot_version", default="gc-eu-mq-dbg")
|
||||||
parser.add_argument("-j", dest="use_multiprocessing", action="store_true")
|
parser.add_argument("-j", dest="use_multiprocessing", action="store_true")
|
||||||
parser.add_argument("-s", dest="single", default=None)
|
parser.add_argument("-s", dest="single", default=None)
|
||||||
|
@ -299,6 +308,14 @@ def main():
|
||||||
)
|
)
|
||||||
version_memctx_base.set_direct_file(vc.variables["sShadowTex"], file_sShadowTex)
|
version_memctx_base.set_direct_file(vc.variables["sShadowTex"], file_sShadowTex)
|
||||||
|
|
||||||
|
extraction_ctx = ExtractionContext(
|
||||||
|
args.oot_version,
|
||||||
|
version_memctx_base,
|
||||||
|
args.baserom_segments_dir,
|
||||||
|
Path("build") / args.oot_version,
|
||||||
|
args.output_dir,
|
||||||
|
)
|
||||||
|
|
||||||
z64_resource_handlers.register_resource_handlers()
|
z64_resource_handlers.register_resource_handlers()
|
||||||
|
|
||||||
# TODO extract only when a pool xml was modified since last extract
|
# TODO extract only when a pool xml was modified since last extract
|
||||||
|
@ -312,7 +329,7 @@ def main():
|
||||||
if coll.backing_memory.name == args.single:
|
if coll.backing_memory.name == args.single:
|
||||||
do_process_pool = True
|
do_process_pool = True
|
||||||
if do_process_pool:
|
if do_process_pool:
|
||||||
process_pool(version_memctx_base, pool_desc)
|
process_pool(extraction_ctx, pool_desc)
|
||||||
any_do_process_pool = True
|
any_do_process_pool = True
|
||||||
if any_do_process_pool:
|
if any_do_process_pool:
|
||||||
print("OK")
|
print("OK")
|
||||||
|
@ -320,7 +337,7 @@ def main():
|
||||||
print("Not found:", args.single)
|
print("Not found:", args.single)
|
||||||
elif not args.use_multiprocessing: # everything on one process
|
elif not args.use_multiprocessing: # everything on one process
|
||||||
for pool_desc in pools_desc:
|
for pool_desc in pools_desc:
|
||||||
process_pool(version_memctx_base, pool_desc)
|
process_pool(extraction_ctx, pool_desc)
|
||||||
print("all OK!!!")
|
print("all OK!!!")
|
||||||
else: # multiprocessing
|
else: # multiprocessing
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
|
@ -328,7 +345,7 @@ def main():
|
||||||
with multiprocessing.Pool() as pool:
|
with multiprocessing.Pool() as pool:
|
||||||
pool.starmap(
|
pool.starmap(
|
||||||
process_pool_wrapped,
|
process_pool_wrapped,
|
||||||
zip([version_memctx_base] * len(pools_desc), pools_desc),
|
zip([extraction_ctx] * len(pools_desc), pools_desc),
|
||||||
)
|
)
|
||||||
print("all OK!?")
|
print("all OK!?")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -349,16 +366,3 @@ def main():
|
||||||
else:
|
else:
|
||||||
print("rich.pretty.pprint(e):")
|
print("rich.pretty.pprint(e):")
|
||||||
rich.pretty.pprint(e, indent_guides=False)
|
rich.pretty.pprint(e, indent_guides=False)
|
||||||
|
|
||||||
# extract_xml(Path("objects/object_ydan_objects"))
|
|
||||||
# extract_xml(Path("objects/object_fd2")) # TODO xml needs TLUT fixing, see VERBOSE_BEST_EFFORT_TLUT_NO_REAL_USER
|
|
||||||
# extract_xml(Path("objects/object_am"))
|
|
||||||
# extract_xml(Path("scenes/indoors/hylia_labo"))
|
|
||||||
# extract_xml(Path("objects/gameplay_keep"))
|
|
||||||
# extract_xml(Path("overlays/ovl_En_Jsjutan")) # The only xml with ~~<Symbol>~~ a <File Extract="False"
|
|
||||||
# extract_xml(Path("overlays/ovl_Magic_Wind")) # SkelCurve
|
|
||||||
# extract_xml(Path("objects/object_link_child")) # The only xml with <Mtx>
|
|
||||||
# extract_xml(Path("scenes/dungeons/ddan")) # cutscene test
|
|
||||||
# extract_xml(Path("scenes/dungeons/ganontikasonogo")) # has a spawn not in the entrance table
|
|
||||||
|
|
||||||
pprint(get_baserom_file_data.cache_info())
|
|
||||||
|
|
|
@ -101,3 +101,8 @@ CAMERA_SETTING_TYPES = {
|
||||||
0x40: "CAM_SET_PIVOT_FROM_SIDE",
|
0x40: "CAM_SET_PIVOT_FROM_SIDE",
|
||||||
0x41: "CAM_SET_NORMAL4",
|
0x41: "CAM_SET_NORMAL4",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SKIN_LIMB_TYPES = {
|
||||||
|
4: "SKIN_LIMB_TYPE_ANIMATED",
|
||||||
|
11: "SKIN_LIMB_TYPE_NORMAL",
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ from .extase.cdata_resources import Vec3sArrayResource, S16ArrayResource
|
||||||
|
|
||||||
from .extase_oot64 import (
|
from .extase_oot64 import (
|
||||||
skeleton_resources,
|
skeleton_resources,
|
||||||
|
skeleton_skin_resources,
|
||||||
animation_resources,
|
animation_resources,
|
||||||
collision_resources,
|
collision_resources,
|
||||||
dlist_resources,
|
dlist_resources,
|
||||||
|
@ -82,16 +83,13 @@ def register_resource_handlers():
|
||||||
if resource_desc.limb_type == z64resources.LimbType.STANDARD:
|
if resource_desc.limb_type == z64resources.LimbType.STANDARD:
|
||||||
pass
|
pass
|
||||||
elif resource_desc.limb_type == z64resources.LimbType.LOD:
|
elif resource_desc.limb_type == z64resources.LimbType.LOD:
|
||||||
# TODO
|
|
||||||
if resource_desc.type == z64resources.SkeletonType.NORMAL:
|
if resource_desc.type == z64resources.SkeletonType.NORMAL:
|
||||||
# } SkeletonHeader; // size = 0x8
|
return skeleton_resources.SkeletonNormalLODResource(
|
||||||
return BinaryBlobResource(
|
file, offset, resource_desc.symbol_name
|
||||||
file, offset, offset + 0x8, resource_desc.symbol_name
|
|
||||||
)
|
)
|
||||||
elif resource_desc.type == z64resources.SkeletonType.FLEX:
|
elif resource_desc.type == z64resources.SkeletonType.FLEX:
|
||||||
# } FlexSkeletonHeader; // size = 0xC
|
return skeleton_resources.SkeletonFlexLODResource(
|
||||||
return BinaryBlobResource(
|
file, offset, resource_desc.symbol_name
|
||||||
file, offset, offset + 0xC, resource_desc.symbol_name
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError(
|
raise NotImplementedError(
|
||||||
|
@ -100,11 +98,9 @@ def register_resource_handlers():
|
||||||
resource_desc.type,
|
resource_desc.type,
|
||||||
)
|
)
|
||||||
elif resource_desc.limb_type == z64resources.LimbType.SKIN:
|
elif resource_desc.limb_type == z64resources.LimbType.SKIN:
|
||||||
# TODO
|
|
||||||
assert resource_desc.type == z64resources.SkeletonType.NORMAL
|
assert resource_desc.type == z64resources.SkeletonType.NORMAL
|
||||||
# } SkeletonHeader; // size = 0x8
|
return skeleton_skin_resources.SkeletonSkinResource(
|
||||||
return BinaryBlobResource(
|
file, offset, resource_desc.symbol_name
|
||||||
file, offset, offset + 0x8, resource_desc.symbol_name
|
|
||||||
)
|
)
|
||||||
elif resource_desc.limb_type == z64resources.LimbType.CURVE:
|
elif resource_desc.limb_type == z64resources.LimbType.CURVE:
|
||||||
assert resource_desc.type == z64resources.SkeletonType.CURVE
|
assert resource_desc.type == z64resources.SkeletonType.CURVE
|
||||||
|
@ -147,16 +143,15 @@ def register_resource_handlers():
|
||||||
resource_desc.symbol_name,
|
resource_desc.symbol_name,
|
||||||
)
|
)
|
||||||
if resource_desc.limb_type == z64resources.LimbType.SKIN:
|
if resource_desc.limb_type == z64resources.LimbType.SKIN:
|
||||||
# } SkinLimb; // size = 0x10
|
return skeleton_skin_resources.SkinLimbResource(
|
||||||
return BinaryBlobResource(
|
file, offset, resource_desc.symbol_name
|
||||||
file, offset, offset + 0x10, resource_desc.symbol_name
|
|
||||||
)
|
)
|
||||||
if resource_desc.limb_type == z64resources.LimbType.LOD:
|
if resource_desc.limb_type == z64resources.LimbType.LOD:
|
||||||
# } LodLimb; // size = 0x10
|
return skeleton_resources.LODLimbResource(
|
||||||
return BinaryBlobResource(
|
file, offset, resource_desc.symbol_name
|
||||||
file, offset, offset + 0x10, resource_desc.symbol_name
|
|
||||||
)
|
)
|
||||||
if resource_desc.limb_type == z64resources.LimbType.LEGACY:
|
if resource_desc.limb_type == z64resources.LimbType.LEGACY:
|
||||||
|
# TODO LegacyLimbResource
|
||||||
# } LegacyLimb; // size = 0x20
|
# } LegacyLimb; // size = 0x20
|
||||||
return BinaryBlobResource(
|
return BinaryBlobResource(
|
||||||
file, offset, offset + 0x20, resource_desc.symbol_name
|
file, offset, offset + 0x20, resource_desc.symbol_name
|
||||||
|
@ -171,6 +166,39 @@ def register_resource_handlers():
|
||||||
resource_desc.limb_type,
|
resource_desc.limb_type,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def limb_table_handler(
|
||||||
|
file: File,
|
||||||
|
resource_desc: z64resources.LimbTableResourceDesc,
|
||||||
|
):
|
||||||
|
if resource_desc.limb_type == z64resources.LimbType.STANDARD:
|
||||||
|
resource = skeleton_resources.StandardLimbsArrayResource(
|
||||||
|
file, resource_desc.offset, resource_desc.symbol_name
|
||||||
|
)
|
||||||
|
resource.set_length(resource_desc.count)
|
||||||
|
return resource
|
||||||
|
elif resource_desc.limb_type == z64resources.LimbType.SKIN:
|
||||||
|
resource = skeleton_skin_resources.SkinLimbsArrayResource(
|
||||||
|
file, resource_desc.offset, resource_desc.symbol_name
|
||||||
|
)
|
||||||
|
resource.set_length(resource_desc.count)
|
||||||
|
return resource
|
||||||
|
elif resource_desc.limb_type == z64resources.LimbType.LOD:
|
||||||
|
resource = skeleton_resources.LODLimbsArrayResource(
|
||||||
|
file, resource_desc.offset, resource_desc.symbol_name
|
||||||
|
)
|
||||||
|
resource.set_length(resource_desc.count)
|
||||||
|
return resource
|
||||||
|
elif resource_desc.limb_type == z64resources.LimbType.LEGACY:
|
||||||
|
# TODO LegacyLimbsArrayResource
|
||||||
|
return BinaryBlobResource(
|
||||||
|
file,
|
||||||
|
resource_desc.offset,
|
||||||
|
resource_desc.offset + 4,
|
||||||
|
resource_desc.symbol_name,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise NotImplementedError("LimbTable of limb type", resource_desc.limb_type)
|
||||||
|
|
||||||
def animation_resource_handler(
|
def animation_resource_handler(
|
||||||
file: File,
|
file: File,
|
||||||
resource_desc: z64resources.AnimationResourceDesc,
|
resource_desc: z64resources.AnimationResourceDesc,
|
||||||
|
@ -412,10 +440,7 @@ def register_resource_handlers():
|
||||||
z64resources.LegacyAnimationResourceDesc: get_fixed_size_resource_handler(
|
z64resources.LegacyAnimationResourceDesc: get_fixed_size_resource_handler(
|
||||||
0xC
|
0xC
|
||||||
), # TODO
|
), # TODO
|
||||||
z64resources.LimbTableResourceDesc: get_fixed_size_resource_handler(
|
z64resources.LimbTableResourceDesc: limb_table_handler,
|
||||||
# idk, probably an array
|
|
||||||
4
|
|
||||||
), # TODO
|
|
||||||
z64resources.CurveAnimationResourceDesc: CurveAnimation_handler,
|
z64resources.CurveAnimationResourceDesc: CurveAnimation_handler,
|
||||||
z64resources.SceneResourceDesc: scene_resource_handler,
|
z64resources.SceneResourceDesc: scene_resource_handler,
|
||||||
z64resources.RoomResourceDesc: room_resource_handler,
|
z64resources.RoomResourceDesc: room_resource_handler,
|
||||||
|
|
Loading…
Add table
Reference in a new issue