mirror of
https://github.com/pmret/papermario.git
synced 2024-11-08 12:02:30 +01:00
tex archives (#1072)
* extraction * hmm * eth cleanup * tex skeleton * building * OK * pal OK * cleaned texture names * moved tex code to separate file * additional error checking * proposed splits * split a5dd0 * additional cleanup * myoop * wahoo * lru * fixules * fixin agin --------- Co-authored-by: HailSanta <Hail2Santa@gmail.com> Co-authored-by: Ethan Roseman <ethteck@gmail.com>
This commit is contained in:
parent
8f0f0bd941
commit
6bb14ff8be
@ -994,14 +994,13 @@ typedef struct BattleStatus {
|
|||||||
/* 0x45C */ char unk_45C[4];
|
/* 0x45C */ char unk_45C[4];
|
||||||
} BattleStatus; // size = 0x460
|
} BattleStatus; // size = 0x460
|
||||||
|
|
||||||
// alternative name: TileDescriptor
|
|
||||||
typedef struct TextureHeader {
|
typedef struct TextureHeader {
|
||||||
/* 0x00 */ s8 name[32];
|
/* 0x00 */ s8 name[32];
|
||||||
/* 0x20 */ u16 auxW;
|
/* 0x20 */ u16 auxW;
|
||||||
/* 0x22 */ u16 mainW;
|
/* 0x22 */ u16 mainW;
|
||||||
/* 0x24 */ u16 auxH;
|
/* 0x24 */ u16 auxH;
|
||||||
/* 0x26 */ u16 mainH;
|
/* 0x26 */ u16 mainH;
|
||||||
/* 0x28 */ u8 unk_28;
|
/* 0x28 */ u8 isVariant;
|
||||||
/* 0x29 */ u8 extraTiles; // 0 - none, 1 - mipmap, 2 - ?, 3 - use aux tile
|
/* 0x29 */ u8 extraTiles; // 0 - none, 1 - mipmap, 2 - ?, 3 - use aux tile
|
||||||
/* 0x2A */ u8 colorCombineType : 6;
|
/* 0x2A */ u8 colorCombineType : 6;
|
||||||
/* 0x2A */ u8 colorCombineSubType : 2;
|
/* 0x2A */ u8 colorCombineSubType : 2;
|
||||||
|
@ -113,7 +113,7 @@ void filemenu_choose_name_update(MenuPanel*);
|
|||||||
void filemenu_choose_name_cleanup(MenuPanel*);
|
void filemenu_choose_name_cleanup(MenuPanel*);
|
||||||
|
|
||||||
void filemenu_draw_message(u8*, s32, s32, s32, s32, u32);
|
void filemenu_draw_message(u8*, s32, s32, s32, s32, u32);
|
||||||
void filemenu_draw_rect(s32 ulx, s32 uly, s32 lrx, s32 lry, s32 tileDescriptor, s32 uls, s32 ult, s32 dsdx, s32 dtdy);
|
void filemenu_draw_rect(s32 ulx, s32 uly, s32 lrx, s32 lry, s32 tileIdx, s32 uls, s32 ult, s32 dsdx, s32 dtdy);
|
||||||
|
|
||||||
extern WindowStyleCustom filemenu_windowStyles[];
|
extern WindowStyleCustom filemenu_windowStyles[];
|
||||||
extern u8 filemenu_createfile_gridData[];
|
extern u8 filemenu_createfile_gridData[];
|
||||||
|
@ -1097,7 +1097,7 @@ void btl_update(void);
|
|||||||
void update_item_entities(void);
|
void update_item_entities(void);
|
||||||
void iterate_models(void);
|
void iterate_models(void);
|
||||||
void restore_map_collision_data(void);
|
void restore_map_collision_data(void);
|
||||||
void load_model_textures(struct ModelNode* model, s32 romOffset, s32 size);
|
void mdl_load_all_textures(struct ModelNode* model, s32 romOffset, s32 size);
|
||||||
void calculate_model_sizes(void);
|
void calculate_model_sizes(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -179,7 +179,7 @@ void update_model_animator(s32);
|
|||||||
void update_model_animator_with_transform(s32 animatorID, Mtx* mtx);
|
void update_model_animator_with_transform(s32 animatorID, Mtx* mtx);
|
||||||
void set_mdl_custom_gfx_set(Model*, s32, u32);
|
void set_mdl_custom_gfx_set(Model*, s32, u32);
|
||||||
ModelNodeProperty* get_model_property(ModelNode* node, ModelPropertyKeys key);
|
ModelNodeProperty* get_model_property(ModelNode* node, ModelPropertyKeys key);
|
||||||
void func_80115498(u32 romOffset, s32 textureID, s32 baseOffset, s32 size);
|
void load_texture_variants(u32 romOffset, s32 textureID, s32 baseOffset, s32 size);
|
||||||
s32 step_model_animator(ModelAnimator* animator);
|
s32 step_model_animator(ModelAnimator* animator);
|
||||||
AnimatorNode* get_animator_node_for_tree_index(ModelAnimator* animator, s32 treeIndex);
|
AnimatorNode* get_animator_node_for_tree_index(ModelAnimator* animator, s32 treeIndex);
|
||||||
AnimatorNode* get_animator_node_with_id(ModelAnimator* animator, s32 id);
|
AnimatorNode* get_animator_node_with_id(ModelAnimator* animator, s32 id);
|
||||||
|
@ -146,7 +146,7 @@ extern u16 gCurrentDoorSounds;
|
|||||||
|
|
||||||
extern UNK_TYPE D_800E92D8;
|
extern UNK_TYPE D_800E92D8;
|
||||||
extern UNK_TYPE D_80147574;
|
extern UNK_TYPE D_80147574;
|
||||||
extern s8 D_8014C248[];
|
extern b8 D_8014C248;
|
||||||
|
|
||||||
extern UNK_FUN_PTR(TalkNotificationCallback);
|
extern UNK_FUN_PTR(TalkNotificationCallback);
|
||||||
extern UNK_FUN_PTR(InteractNotificationCallback);
|
extern UNK_FUN_PTR(InteractNotificationCallback);
|
||||||
|
12
src/16F740.c
12
src/16F740.c
@ -193,8 +193,8 @@ void btl_state_update_normal_start(void) {
|
|||||||
s32 size;
|
s32 size;
|
||||||
UiStatus* uiStatus;
|
UiStatus* uiStatus;
|
||||||
void* compressedAsset;
|
void* compressedAsset;
|
||||||
ModelNode* model;
|
ModelNode* rootModel;
|
||||||
s32 textureRom;
|
s32 texturesOffset;
|
||||||
Actor* actor;
|
Actor* actor;
|
||||||
Evt* script;
|
Evt* script;
|
||||||
s32 enemyNotDone;
|
s32 enemyNotDone;
|
||||||
@ -226,10 +226,10 @@ void btl_state_update_normal_start(void) {
|
|||||||
|
|
||||||
ASSERT(size <= 0x8000);
|
ASSERT(size <= 0x8000);
|
||||||
|
|
||||||
model = gMapShapeData.header.root;
|
rootModel = gMapShapeData.header.root;
|
||||||
textureRom = get_asset_offset(stage->texture, &size);
|
texturesOffset = get_asset_offset(stage->texture, &size);
|
||||||
if (model != NULL) {
|
if (rootModel != NULL) {
|
||||||
load_data_for_models(model, textureRom, size);
|
load_data_for_models(rootModel, texturesOffset, size);
|
||||||
}
|
}
|
||||||
load_battle_hit_asset(stage->hit);
|
load_battle_hit_asset(stage->hit);
|
||||||
|
|
||||||
|
1759
src/entity.c
Normal file
1759
src/entity.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -181,14 +181,14 @@ BSS u16 D_802517E0[2][0x400] ALIGNED(16);
|
|||||||
BSS u8 filemenu_glyphBuffer[20][0x80];
|
BSS u8 filemenu_glyphBuffer[20][0x80];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void filemenu_draw_rect(s32 ulx, s32 uly, s32 lrx, s32 lry, s32 tileDescriptor, s32 uls, s32 ult, s32 dsdx, s32 dtdy) {
|
void filemenu_draw_rect(s32 ulx, s32 uly, s32 lrx, s32 lry, s32 tileIdx, s32 uls, s32 ult, s32 dsdx, s32 dtdy) {
|
||||||
if (ulx <= -2688 || uly <= -2688 || lrx <= 0 || lry <= 0) {
|
if (ulx <= -2688 || uly <= -2688 || lrx <= 0 || lry <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ulx >= 1280 || uly >= 960 || lrx >= 2688 || lry >= 2688) {
|
if (ulx >= 1280 || uly >= 960 || lrx >= 2688 || lry >= 2688) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gSPScisTextureRectangle(gMainGfxPos++, ulx, uly, lrx, lry, tileDescriptor, uls, ult, dsdx, dtdy);
|
gSPScisTextureRectangle(gMainGfxPos++, ulx, uly, lrx, lry, tileIdx, uls, ult, dsdx, dtdy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void filemenu_set_selected(MenuPanel* menu, s32 col, s32 row) {
|
void filemenu_set_selected(MenuPanel* menu, s32 col, s32 row) {
|
||||||
|
180
src/game_states.c
Normal file
180
src/game_states.c
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
extern GameMode gMainGameState[2]; // TODO rename
|
||||||
|
|
||||||
|
void state_delegate_NOP(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_game_modes(void) {
|
||||||
|
GameMode* gameMode;
|
||||||
|
s32 i;
|
||||||
|
|
||||||
|
for (gameMode = gMainGameState, i = 0; i < ARRAY_COUNT(gMainGameState); i++, gameMode++) {
|
||||||
|
gameMode->flags = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GameMode* set_next_game_mode(GameMode* arg0) {
|
||||||
|
GameMode* gameMode;
|
||||||
|
s32 i;
|
||||||
|
|
||||||
|
for (gameMode = gMainGameState, i = 0; i < ARRAY_COUNT(gMainGameState); i++, gameMode++) {
|
||||||
|
if (gameMode->flags == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(i < ARRAY_COUNT(gMainGameState));
|
||||||
|
|
||||||
|
gameMode->flags = 1 | 2;
|
||||||
|
gameMode->init = arg0->init;
|
||||||
|
gameMode->step = arg0->step;
|
||||||
|
gameMode->render = arg0->render;
|
||||||
|
gameMode->unk_0C = NULL;
|
||||||
|
|
||||||
|
if (gameMode->init == NULL) {
|
||||||
|
gameMode->init = state_delegate_NOP;
|
||||||
|
}
|
||||||
|
if (gameMode->step == NULL) {
|
||||||
|
gameMode->step = state_delegate_NOP;
|
||||||
|
}
|
||||||
|
if (gameMode->unk_0C == NULL) {
|
||||||
|
gameMode->unk_0C = state_delegate_NOP;
|
||||||
|
}
|
||||||
|
if (gameMode->render == NULL) {
|
||||||
|
gameMode->render = state_delegate_NOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
gameMode->renderAux = state_delegate_NOP;
|
||||||
|
gameMode->init();
|
||||||
|
|
||||||
|
return gameMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameMode* set_game_mode_slot(s32 i, GameMode* mode) {
|
||||||
|
GameMode* gameMode = &gMainGameState[i];
|
||||||
|
|
||||||
|
ASSERT(i < ARRAY_COUNT(gMainGameState));
|
||||||
|
|
||||||
|
gameMode->flags = 2 | 1;
|
||||||
|
gameMode->init = mode->init;
|
||||||
|
gameMode->step = mode->step;
|
||||||
|
gameMode->render = mode->render;
|
||||||
|
gameMode->unk_0C = NULL;
|
||||||
|
if (gameMode->init == NULL) gameMode->init = state_delegate_NOP;
|
||||||
|
if (gameMode->step == NULL) gameMode->step = state_delegate_NOP;
|
||||||
|
if (gameMode->unk_0C == NULL) gameMode->unk_0C = state_delegate_NOP;
|
||||||
|
if (gameMode->render == NULL) gameMode->render = state_delegate_NOP;
|
||||||
|
|
||||||
|
gameMode->renderAux = state_delegate_NOP;
|
||||||
|
gameMode->init();
|
||||||
|
|
||||||
|
return gameMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void game_mode_set_fpDrawAuxUI(s32 i, void (*fn)(void)) {
|
||||||
|
GameMode* gameMode = &gMainGameState[i];
|
||||||
|
|
||||||
|
ASSERT(i < ARRAY_COUNT(gMainGameState));
|
||||||
|
|
||||||
|
gameMode->renderAux = fn;
|
||||||
|
gameMode->flags |= 0x20;
|
||||||
|
|
||||||
|
if (fn == NULL) {
|
||||||
|
gameMode->renderAux = state_delegate_NOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void func_80112DD4(s32 i) {
|
||||||
|
gMainGameState[i].flags |= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void func_80112DFC(s32 i) {
|
||||||
|
gMainGameState[i].flags |= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void func_80112E24(s32 i) {
|
||||||
|
gMainGameState[i].flags &= ~0x1C;
|
||||||
|
}
|
||||||
|
|
||||||
|
void func_80112E4C(s32 i) {
|
||||||
|
gMainGameState[i].flags &= ~0x0C;
|
||||||
|
gMainGameState[i].flags |= 0x10;
|
||||||
|
}
|
||||||
|
|
||||||
|
void step_current_game_mode(void) {
|
||||||
|
GameMode* gameMode = gMainGameState;
|
||||||
|
s32 i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_COUNT(gMainGameState); i++, gameMode++) {
|
||||||
|
if (gameMode->flags != 0) {
|
||||||
|
if (!(gameMode->flags & 4)) {
|
||||||
|
if (!(gameMode->flags & 8)) {
|
||||||
|
gameMode->flags &= ~2;
|
||||||
|
gameMode->step();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void state_do_unk(void) {
|
||||||
|
GameMode* gameMode = gMainGameState;
|
||||||
|
s32 i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_COUNT(gMainGameState); i++, gameMode++) {
|
||||||
|
if (gameMode->flags != 0) {
|
||||||
|
if (!(gameMode->flags & 4)) {
|
||||||
|
if (!(gameMode->flags & 0x10)) {
|
||||||
|
gameMode->unk_0C();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void state_render_backUI(void) {
|
||||||
|
GameMode* gameMode = gMainGameState;
|
||||||
|
s32 i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_COUNT(gMainGameState); i++, gameMode++) {
|
||||||
|
if (gameMode->flags != 0) {
|
||||||
|
if (!(gameMode->flags & 4)) {
|
||||||
|
if (!(gameMode->flags & 0x10)) {
|
||||||
|
gameMode->render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void state_render_frontUI(void) {
|
||||||
|
GameMode* gameMode = gMainGameState;
|
||||||
|
s32 i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_COUNT(gMainGameState); i++, gameMode++) {
|
||||||
|
if (gameMode->flags != 0) {
|
||||||
|
if (!(gameMode->flags & 4)) {
|
||||||
|
if (!(gameMode->flags & 2)) {
|
||||||
|
if (gameMode->flags & 0x20) {
|
||||||
|
gameMode->renderAux();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// re-initialization needed - evidence of inlining? or just copy/pasting?
|
||||||
|
gameMode = &gMainGameState[0];
|
||||||
|
for (i = 0; i < ARRAY_COUNT(gMainGameState); i++, gameMode++) {
|
||||||
|
if (gameMode->flags != 0) {
|
||||||
|
if (!(gameMode->flags & 4)) {
|
||||||
|
if (!(gameMode->flags & 2)) {
|
||||||
|
if (gameMode->flags & 0x10) {
|
||||||
|
gameMode->render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -126,7 +126,7 @@ void pause_set_cursor_pos_immediate(s32 windowID, s32 posX, s32 posY);
|
|||||||
void pause_set_cursor_opacity(s32 val);
|
void pause_set_cursor_opacity(s32 val);
|
||||||
void pause_draw_menu_label(s32 index, s32 x, s32 y);
|
void pause_draw_menu_label(s32 index, s32 x, s32 y);
|
||||||
s32 pause_get_total_equipped_bp_cost(void);
|
s32 pause_get_total_equipped_bp_cost(void);
|
||||||
void pause_draw_rect(s32 ulx, s32 uly, s32 lrx, s32 lry, s32 tileDescriptor, s32 uls, s32 ult, s32 dsdx, s32 dtdy);
|
void pause_draw_rect(s32 ulx, s32 uly, s32 lrx, s32 lry, s32 tileIdx, s32 uls, s32 ult, s32 dsdx, s32 dtdy);
|
||||||
s32 pause_get_menu_msg(s32 index);
|
s32 pause_get_menu_msg(s32 index);
|
||||||
s32 pause_interp_vertical_scroll(s32 deltaBefore);
|
s32 pause_interp_vertical_scroll(s32 deltaBefore);
|
||||||
void pause_sort_item_list(s16* arr, s32 len, s32 (*compare)(s16*, s16 *));
|
void pause_sort_item_list(s16* arr, s32 len, s32 (*compare)(s16*, s16 *));
|
||||||
|
@ -845,14 +845,14 @@ s32 pause_get_total_equipped_bp_cost(void) {
|
|||||||
return totalCost;
|
return totalCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pause_draw_rect(s32 ulx, s32 uly, s32 lrx, s32 lry, s32 tileDescriptor, s32 uls, s32 ult, s32 dsdx, s32 dtdy) {
|
void pause_draw_rect(s32 ulx, s32 uly, s32 lrx, s32 lry, s32 tileIdx, s32 uls, s32 ult, s32 dsdx, s32 dtdy) {
|
||||||
if (ulx <= -2688 || uly <= -2688 || lrx <= 0 || lry <= 0) {
|
if (ulx <= -2688 || uly <= -2688 || lrx <= 0 || lry <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ulx >= 1280 || uly >= 960 || lrx >= 2688 || lry >= 2688) {
|
if (ulx >= 1280 || uly >= 960 || lrx >= 2688 || lry >= 2688) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gSPScisTextureRectangle(gMainGfxPos++, ulx, uly, lrx, lry, tileDescriptor, uls, ult, dsdx, dtdy);
|
gSPScisTextureRectangle(gMainGfxPos++, ulx, uly, lrx, lry, tileIdx, uls, ult, dsdx, dtdy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pause_sort_item_list(s16* arr, s32 len, s32 (*compare)(s16*, s16 *)) {
|
void pause_sort_item_list(s16* arr, s32 len, s32 (*compare)(s16*, s16 *)) {
|
||||||
|
@ -195,7 +195,7 @@ void state_step_end_battle(void) {
|
|||||||
set_background_size(296, 200, 12, 20);
|
set_background_size(296, 200, 12, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
load_model_textures(mapSettings->modelTreeRoot, get_asset_offset(wMapTexName, &sizeTemp), sizeTemp);
|
mdl_load_all_textures(mapSettings->modelTreeRoot, get_asset_offset(wMapTexName, &sizeTemp), sizeTemp);
|
||||||
calculate_model_sizes();
|
calculate_model_sizes();
|
||||||
npc_reload_all();
|
npc_reload_all();
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ void state_init_file_select(void) {
|
|||||||
general_heap_create();
|
general_heap_create();
|
||||||
hud_element_set_aux_cache(0, 0);
|
hud_element_set_aux_cache(0, 0);
|
||||||
hud_element_clear_cache();
|
hud_element_clear_cache();
|
||||||
load_model_textures(0, 0, 0);
|
mdl_load_all_textures(NULL, 0, 0);
|
||||||
gCameras[CAM_DEFAULT].updateMode = CAM_UPDATE_MODE_6;
|
gCameras[CAM_DEFAULT].updateMode = CAM_UPDATE_MODE_6;
|
||||||
gCameras[CAM_DEFAULT].needsInit = TRUE;
|
gCameras[CAM_DEFAULT].needsInit = TRUE;
|
||||||
gCameras[CAM_DEFAULT].nearClip = 16;
|
gCameras[CAM_DEFAULT].nearClip = 16;
|
||||||
|
@ -100,7 +100,7 @@ void state_init_title_screen(void) {
|
|||||||
|
|
||||||
gOverrideFlags = 0;
|
gOverrideFlags = 0;
|
||||||
timeFreezeMode = 0;
|
timeFreezeMode = 0;
|
||||||
D_8014C248[0] = 1;
|
D_8014C248 = TRUE;
|
||||||
general_heap_create();
|
general_heap_create();
|
||||||
clear_printers();
|
clear_printers();
|
||||||
sfx_set_reverb_mode(0);
|
sfx_set_reverb_mode(0);
|
||||||
|
@ -1910,11 +1910,6 @@ EvtScript N(EVS_Intro_Main) = {
|
|||||||
|
|
||||||
f32 N(AnimBowser_FlyOff_Time) = 0.0;
|
f32 N(AnimBowser_FlyOff_Time) = 0.0;
|
||||||
|
|
||||||
#if VERSION_PAL
|
|
||||||
API_CALLABLE(N(AnimBowser_FlyOff));
|
|
||||||
INCLUDE_ASM(ApiResult, "world/area_hos/hos_05/hos_05_5_intro", AnimBowser_FlyOff);
|
|
||||||
asm(".section .data");
|
|
||||||
#else
|
|
||||||
API_CALLABLE(N(AnimBowser_FlyOff)) {
|
API_CALLABLE(N(AnimBowser_FlyOff)) {
|
||||||
Npc* bowserMain = resolve_npc(script, NPC_Bowser_Body);
|
Npc* bowserMain = resolve_npc(script, NPC_Bowser_Body);
|
||||||
Npc* bowserProp = resolve_npc(script, NPC_Bowser_Prop);
|
Npc* bowserProp = resolve_npc(script, NPC_Bowser_Prop);
|
||||||
@ -1931,20 +1926,15 @@ API_CALLABLE(N(AnimBowser_FlyOff)) {
|
|||||||
bowserMain->colliderPos.y = bowserMain->pos.y;
|
bowserMain->colliderPos.y = bowserMain->pos.y;
|
||||||
bowserProp->colliderPos.y = bowserProp->pos.y;
|
bowserProp->colliderPos.y = bowserProp->pos.y;
|
||||||
N(AnimBowser_FlyOff_Time)++;
|
N(AnimBowser_FlyOff_Time)++;
|
||||||
if (N(AnimBowser_FlyOff_Time) > 40.0f) {
|
if (N(AnimBowser_FlyOff_Time) > (int)(40 * DT)) {
|
||||||
return ApiStatus_DONE1;
|
return ApiStatus_DONE1;
|
||||||
} else {
|
} else {
|
||||||
return ApiStatus_BLOCK;
|
return ApiStatus_BLOCK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
f32 N(AnimKammy_FlyOff_Time) = 0.0;
|
f32 N(AnimKammy_FlyOff_Time) = 0.0;
|
||||||
|
|
||||||
#if VERSION_PAL
|
|
||||||
API_CALLABLE(N(AnimKammy_FlyOff));
|
|
||||||
INCLUDE_ASM(ApiResult, "world/area_hos/hos_05/hos_05_5_intro", AnimKammy_FlyOff);
|
|
||||||
#else
|
|
||||||
API_CALLABLE(N(AnimKammy_FlyOff)) {
|
API_CALLABLE(N(AnimKammy_FlyOff)) {
|
||||||
Npc* kammy = resolve_npc(script, NPC_Kammy);
|
Npc* kammy = resolve_npc(script, NPC_Kammy);
|
||||||
|
|
||||||
@ -1958,13 +1948,12 @@ API_CALLABLE(N(AnimKammy_FlyOff)) {
|
|||||||
40.0f, &kammy->pos.y);
|
40.0f, &kammy->pos.y);
|
||||||
kammy->colliderPos.y = kammy->pos.y;
|
kammy->colliderPos.y = kammy->pos.y;
|
||||||
N(AnimKammy_FlyOff_Time)++;
|
N(AnimKammy_FlyOff_Time)++;
|
||||||
if (N(AnimKammy_FlyOff_Time) > 40.0f) {
|
if (N(AnimKammy_FlyOff_Time) > (int)(40 * DT)) {
|
||||||
return ApiStatus_DONE1;
|
return ApiStatus_DONE1;
|
||||||
} else {
|
} else {
|
||||||
return ApiStatus_BLOCK;
|
return ApiStatus_BLOCK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
API_CALLABLE(N(func_80244934_A2EB74)) {
|
API_CALLABLE(N(func_80244934_A2EB74)) {
|
||||||
if (isInitialCall) {
|
if (isInitialCall) {
|
||||||
|
@ -44,3 +44,7 @@ extern EvtScript N(EVS_Main);
|
|||||||
extern EvtScript N(EVS_Dummy);
|
extern EvtScript N(EVS_Dummy);
|
||||||
extern EvtScript N(EVS_InitializeMinigame);
|
extern EvtScript N(EVS_InitializeMinigame);
|
||||||
extern NpcGroupList N(DefaultNPCs);
|
extern NpcGroupList N(DefaultNPCs);
|
||||||
|
|
||||||
|
#if VERSION_PAL
|
||||||
|
extern s32 N(pal_variable);
|
||||||
|
#endif
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include "mgm_02.h"
|
#include "mgm_02.h"
|
||||||
|
|
||||||
#if VERSION_PAL
|
#if VERSION_PAL
|
||||||
extern s32 N(pal_variable);
|
|
||||||
s32 N(get_tattle)(void) {
|
s32 N(get_tattle)(void) {
|
||||||
s32 msgID = MSG_MapTattle_mgm_02;
|
s32 msgID = MSG_MapTattle_mgm_02;
|
||||||
if (N(pal_variable) != 0) {
|
if (N(pal_variable) != 0) {
|
||||||
|
@ -438,7 +438,7 @@ API_CALLABLE(N(RunMinigame)) {
|
|||||||
|
|
||||||
gameFinished = FALSE;
|
gameFinished = FALSE;
|
||||||
hittingPeachBlock = FALSE;
|
hittingPeachBlock = FALSE;
|
||||||
data = get_enemy(0)->varTablePtr[0];
|
data = get_enemy(SCOREKEEPER_ENEMY_IDX)->varTablePtr[SMASH_DATA_VAR_IDX];
|
||||||
|
|
||||||
for (i = 0; i < NUM_BOXES; i++) {
|
for (i = 0; i < NUM_BOXES; i++) {
|
||||||
if (data->box[i].npcID != -1) {
|
if (data->box[i].npcID != -1) {
|
||||||
|
@ -199,10 +199,10 @@ void load_map_by_IDs(s16 areaID, s16 mapID, s16 loadType) {
|
|||||||
sfx_reset_door_sounds();
|
sfx_reset_door_sounds();
|
||||||
|
|
||||||
if (!skipLoadingAssets) {
|
if (!skipLoadingAssets) {
|
||||||
s32 thing = get_asset_offset(wMapTexName, &decompressedSize);
|
s32 texturesOffset = get_asset_offset(wMapTexName, &decompressedSize);
|
||||||
|
|
||||||
if (mapSettings->modelTreeRoot != NULL) {
|
if (mapSettings->modelTreeRoot != NULL) {
|
||||||
load_data_for_models(mapSettings->modelTreeRoot, thing, decompressedSize);
|
load_data_for_models(mapSettings->modelTreeRoot, texturesOffset, decompressedSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
from functools import cache
|
from functools import lru_cache
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
from typing import List, Dict, Optional, Set, Union
|
from typing import List, Dict, Optional, Set, Union
|
||||||
@ -21,6 +21,7 @@ YAY0_COMPRESS_TOOL = f"{BUILD_TOOLS}/yay0/Yay0compress"
|
|||||||
CRC_TOOL = f"{BUILD_TOOLS}/rom/n64crc"
|
CRC_TOOL = f"{BUILD_TOOLS}/rom/n64crc"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def exec_shell(command: List[str]) -> str:
|
def exec_shell(command: List[str]) -> str:
|
||||||
ret = subprocess.run(command, stdout=subprocess.PIPE, text=True)
|
ret = subprocess.run(command, stdout=subprocess.PIPE, text=True)
|
||||||
return ret.stdout
|
return ret.stdout
|
||||||
@ -238,6 +239,12 @@ def write_ninja_rules(
|
|||||||
command=f"$python {BUILD_TOOLS}/mapfs/combine.py $version $out $in",
|
command=f"$python {BUILD_TOOLS}/mapfs/combine.py $version $out $in",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ninja.rule(
|
||||||
|
"tex",
|
||||||
|
description="tex $out",
|
||||||
|
command=f"$python {BUILD_TOOLS}/mapfs/tex.py $out $tex_dir",
|
||||||
|
)
|
||||||
|
|
||||||
ninja.rule(
|
ninja.rule(
|
||||||
"pack_title_data",
|
"pack_title_data",
|
||||||
description="pack_title_data $out",
|
description="pack_title_data $out",
|
||||||
@ -400,7 +407,7 @@ class Configure:
|
|||||||
|
|
||||||
return [str(v) for v in ret.values()]
|
return [str(v) for v in ret.values()]
|
||||||
|
|
||||||
@cache
|
@lru_cache(maxsize=None)
|
||||||
def resolve_asset_path(self, path: Path) -> Path:
|
def resolve_asset_path(self, path: Path) -> Path:
|
||||||
parts = list(path.parts)
|
parts = list(path.parts)
|
||||||
|
|
||||||
@ -887,7 +894,15 @@ class Configure:
|
|||||||
)
|
)
|
||||||
elif name.endswith("_tex"):
|
elif name.endswith("_tex"):
|
||||||
compress = False
|
compress = False
|
||||||
bin_path = path
|
tex_dir = path.parent / name
|
||||||
|
build(
|
||||||
|
bin_path,
|
||||||
|
[tex_dir],
|
||||||
|
"tex",
|
||||||
|
variables={
|
||||||
|
"tex_dir": str(tex_dir)
|
||||||
|
}
|
||||||
|
)
|
||||||
elif name.endswith("_shape"):
|
elif name.endswith("_shape"):
|
||||||
map_name = "_".join(name.split("_")[:-1])
|
map_name = "_".join(name.split("_")[:-1])
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ from glob import glob
|
|||||||
import png # type: ignore
|
import png # type: ignore
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def unpack_color(s):
|
def unpack_color(s):
|
||||||
r = (s >> 11) & 0x1F
|
r = (s >> 11) & 0x1F
|
||||||
g = (s >> 6) & 0x1F
|
g = (s >> 6) & 0x1F
|
||||||
@ -47,12 +48,11 @@ def reversed_if(iterator, cond):
|
|||||||
|
|
||||||
|
|
||||||
class Converter:
|
class Converter:
|
||||||
def __init__(self, mode, infile, outfile, *argv):
|
def __init__(self, mode, infile, flip_x: bool = False, flip_y: bool = False):
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
self.infile = infile
|
self.infile = infile
|
||||||
self.outfile = outfile
|
self.flip_x = flip_x
|
||||||
self.flip_x = "--flip-x" in argv
|
self.flip_y = flip_y
|
||||||
self.flip_y = "--flip-y" in argv
|
|
||||||
|
|
||||||
assert self.flip_x == False, "flip_x is not supported"
|
assert self.flip_x == False, "flip_x is not supported"
|
||||||
|
|
||||||
@ -64,46 +64,48 @@ class Converter:
|
|||||||
print(self.infile + ": warning: " + msg, file=stderr)
|
print(self.infile + ": warning: " + msg, file=stderr)
|
||||||
|
|
||||||
def convert(self):
|
def convert(self):
|
||||||
|
out_bytes = bytearray()
|
||||||
|
out_width = 0
|
||||||
|
out_height = 0
|
||||||
img = png.Reader(self.infile)
|
img = png.Reader(self.infile)
|
||||||
|
|
||||||
if self.mode == "rgba32":
|
if self.mode == "rgba32":
|
||||||
with open(self.outfile, "wb") as f:
|
(out_width, out_height, data, info) = img.asRGBA()
|
||||||
for row in reversed_if(img.asRGBA()[2], self.flip_y):
|
for row in reversed_if(data, self.flip_y):
|
||||||
f.write(row)
|
out_bytes += row
|
||||||
elif self.mode == "rgba16":
|
elif self.mode == "rgba16":
|
||||||
with open(self.outfile, "wb") as f:
|
(out_width, out_height, data, info) = img.asRGBA()
|
||||||
for row in reversed_if(img.asRGBA()[2], self.flip_y):
|
for row in reversed_if(data, self.flip_y):
|
||||||
for rgba in iter_in_groups(row, 4):
|
for rgba in iter_in_groups(row, 4):
|
||||||
if rgba[3] not in (0, 0xFF):
|
if rgba[3] not in (0, 0xFF):
|
||||||
self.warn("alpha mask mode but translucent pixels used")
|
self.warn("alpha mask mode but translucent pixels used")
|
||||||
|
|
||||||
color = pack_color(*rgba)
|
color = pack_color(*rgba)
|
||||||
f.write(color.to_bytes(2, byteorder="big"))
|
out_bytes += color.to_bytes(2, byteorder="big")
|
||||||
elif self.mode == "ci8":
|
elif self.mode == "ci8":
|
||||||
with open(self.outfile, "wb") as f:
|
(out_width, out_height, data, info) = img.read()
|
||||||
for row in reversed_if(img.read()[2], self.flip_y):
|
for row in reversed_if(data, self.flip_y):
|
||||||
f.write(row)
|
out_bytes += row
|
||||||
elif self.mode == "ci4":
|
elif self.mode == "ci4":
|
||||||
with open(self.outfile, "wb") as f:
|
(out_width, out_height, data, info) = img.read()
|
||||||
for row in reversed_if(img.read()[2], self.flip_y):
|
for row in reversed_if(data, self.flip_y):
|
||||||
for a, b in iter_in_groups(row, 2):
|
for a, b in iter_in_groups(row, 2):
|
||||||
byte = (a << 4) | b
|
byte = (a << 4) | b
|
||||||
byte = byte & 0xFF
|
byte = byte & 0xFF
|
||||||
f.write(byte.to_bytes(1, byteorder="big"))
|
out_bytes += byte.to_bytes(1, byteorder="big")
|
||||||
elif self.mode == "palette":
|
elif self.mode == "palette":
|
||||||
img.preamble(True)
|
img.preamble(True)
|
||||||
palette = img.palette(alpha="force")
|
palette = img.palette(alpha="force")
|
||||||
|
|
||||||
with open(self.outfile, "wb") as f:
|
|
||||||
for rgba in palette:
|
for rgba in palette:
|
||||||
if rgba[3] not in (0, 0xFF):
|
if rgba[3] not in (0, 0xFF):
|
||||||
self.warn("alpha mask mode but translucent pixels used")
|
self.warn("alpha mask mode but translucent pixels used")
|
||||||
|
|
||||||
color = pack_color(*rgba)
|
color = pack_color(*rgba)
|
||||||
f.write(color.to_bytes(2, byteorder="big"))
|
out_bytes += color.to_bytes(2, byteorder="big")
|
||||||
elif self.mode == "ia4":
|
elif self.mode == "ia4":
|
||||||
with open(self.outfile, "wb") as f:
|
(out_width, out_height, data, info) = img.asRGBA()
|
||||||
for row in reversed_if(img.asRGBA()[2], self.flip_y):
|
for row in reversed_if(data, self.flip_y):
|
||||||
for c1, c2 in iter_in_groups(iter_in_groups(row, 4), 2):
|
for c1, c2 in iter_in_groups(iter_in_groups(row, 4), 2):
|
||||||
i1 = rgb_to_intensity(*c1[:3])
|
i1 = rgb_to_intensity(*c1[:3])
|
||||||
a1 = c1[3]
|
a1 = c1[3]
|
||||||
@ -128,10 +130,10 @@ class Converter:
|
|||||||
l = (i2 << 1) | a2
|
l = (i2 << 1) | a2
|
||||||
|
|
||||||
byte = (h << 4) | l
|
byte = (h << 4) | l
|
||||||
f.write(byte.to_bytes(1, byteorder="big"))
|
out_bytes += byte.to_bytes(1, byteorder="big")
|
||||||
elif self.mode == "ia8":
|
elif self.mode == "ia8":
|
||||||
with open(self.outfile, "wb") as f:
|
(out_width, out_height, data, info) = img.asRGBA()
|
||||||
for row in reversed_if(img.asRGBA()[2], self.flip_y):
|
for row in reversed_if(data, self.flip_y):
|
||||||
for rgba in iter_in_groups(row, 4):
|
for rgba in iter_in_groups(row, 4):
|
||||||
i = rgb_to_intensity(*rgba[:3])
|
i = rgb_to_intensity(*rgba[:3])
|
||||||
a = rgba[3]
|
a = rgba[3]
|
||||||
@ -143,10 +145,10 @@ class Converter:
|
|||||||
self.warn("grayscale mode but image is not")
|
self.warn("grayscale mode but image is not")
|
||||||
|
|
||||||
byte = (i << 4) | a
|
byte = (i << 4) | a
|
||||||
f.write(byte.to_bytes(1, byteorder="big"))
|
out_bytes += byte.to_bytes(1, byteorder="big")
|
||||||
elif self.mode == "ia16":
|
elif self.mode == "ia16":
|
||||||
with open(self.outfile, "wb") as f:
|
(out_width, out_height, data, info) = img.asRGBA()
|
||||||
for row in reversed_if(img.asRGBA()[2], self.flip_y):
|
for row in reversed_if(data, self.flip_y):
|
||||||
for rgba in iter_in_groups(row, 4):
|
for rgba in iter_in_groups(row, 4):
|
||||||
i = rgb_to_intensity(*rgba[:3])
|
i = rgb_to_intensity(*rgba[:3])
|
||||||
a = rgba[3]
|
a = rgba[3]
|
||||||
@ -154,10 +156,10 @@ class Converter:
|
|||||||
if rgba[0] != rgba[1] != rgba[2]:
|
if rgba[0] != rgba[1] != rgba[2]:
|
||||||
self.warn("grayscale mode but image is not")
|
self.warn("grayscale mode but image is not")
|
||||||
|
|
||||||
f.write(bytes((i, a)))
|
out_bytes += bytes((i, a))
|
||||||
elif self.mode == "i4":
|
elif self.mode == "i4":
|
||||||
with open(self.outfile, "wb") as f:
|
(out_width, out_height, data, info) = img.asRGBA()
|
||||||
for row in reversed_if(img.asRGBA()[2], self.flip_y):
|
for row in reversed_if(data, self.flip_y):
|
||||||
for c1, c2 in iter_in_groups(iter_in_groups(row, 4), 2):
|
for c1, c2 in iter_in_groups(iter_in_groups(row, 4), 2):
|
||||||
if c1[3] != 0xFF or c2[3] != 0xFF:
|
if c1[3] != 0xFF or c2[3] != 0xFF:
|
||||||
self.warn("discarding alpha channel")
|
self.warn("discarding alpha channel")
|
||||||
@ -174,10 +176,10 @@ class Converter:
|
|||||||
self.warn("grayscale mode but image is not")
|
self.warn("grayscale mode but image is not")
|
||||||
|
|
||||||
byte = (i1 << 4) | i2
|
byte = (i1 << 4) | i2
|
||||||
f.write(byte.to_bytes(1, byteorder="big"))
|
out_bytes += byte.to_bytes(1, byteorder="big")
|
||||||
elif self.mode == "i8":
|
elif self.mode == "i8":
|
||||||
with open(self.outfile, "wb") as f:
|
(out_width, out_height, data, info) = img.asRGBA()
|
||||||
for row in reversed_if(img.asRGBA()[2], self.flip_y):
|
for row in reversed_if(data, self.flip_y):
|
||||||
for rgba in iter_in_groups(row, 4):
|
for rgba in iter_in_groups(row, 4):
|
||||||
if rgba[3] != 0xFF or rgba[3] != 0xFF:
|
if rgba[3] != 0xFF or rgba[3] != 0xFF:
|
||||||
self.warn("discarding alpha channel")
|
self.warn("discarding alpha channel")
|
||||||
@ -185,30 +187,27 @@ class Converter:
|
|||||||
self.warn("grayscale mode but image is not")
|
self.warn("grayscale mode but image is not")
|
||||||
|
|
||||||
i = rgb_to_intensity(*rgba[:3])
|
i = rgb_to_intensity(*rgba[:3])
|
||||||
f.write(i.to_bytes(1, byteorder="big"))
|
out_bytes += i.to_bytes(1, byteorder="big")
|
||||||
elif self.mode == "party":
|
elif self.mode == "party":
|
||||||
data = img.read()[2]
|
(out_width, out_height, data, info) = img.read()
|
||||||
img.preamble(True)
|
img.preamble(True)
|
||||||
palette = img.palette(alpha="force")
|
palette = img.palette(alpha="force")
|
||||||
|
|
||||||
with open(self.outfile, "wb") as f:
|
|
||||||
# palette
|
# palette
|
||||||
for rgba in palette:
|
for rgba in palette:
|
||||||
if rgba[3] not in (0, 0xFF):
|
if rgba[3] not in (0, 0xFF):
|
||||||
self.warn("alpha mask mode but translucent pixels used")
|
self.warn("alpha mask mode but translucent pixels used")
|
||||||
|
|
||||||
color = pack_color(*rgba)
|
color = pack_color(*rgba)
|
||||||
f.write(color.to_bytes(2, byteorder="big"))
|
out_bytes += color.to_bytes(2, byteorder="big")
|
||||||
|
|
||||||
assert f.tell() == 0x200, "palette has wrong size"
|
|
||||||
|
|
||||||
# ci 8
|
# ci 8
|
||||||
for row in reversed_if(data, self.flip_y):
|
for row in reversed_if(data, self.flip_y):
|
||||||
f.write(row)
|
out_bytes += row
|
||||||
|
|
||||||
f.write(b"\0\0\0\0\0\0\0\0\0\0") # padding
|
out_bytes += b"\0\0\0\0\0\0\0\0\0\0" # padding
|
||||||
elif self.mode == "bg":
|
elif self.mode == "bg":
|
||||||
width, height, data, info = img.read()
|
(out_width, out_height, data, info) = img.read()
|
||||||
img.preamble(True)
|
img.preamble(True)
|
||||||
palettes = [img.palette(alpha="force")]
|
palettes = [img.palette(alpha="force")]
|
||||||
|
|
||||||
@ -217,29 +216,22 @@ class Converter:
|
|||||||
pal.preamble(True)
|
pal.preamble(True)
|
||||||
palettes.append(pal.palette(alpha="force"))
|
palettes.append(pal.palette(alpha="force"))
|
||||||
|
|
||||||
with open(self.outfile, "wb") as f:
|
|
||||||
baseaddr = 0x80200000 # gBackgroundImage
|
baseaddr = 0x80200000 # gBackgroundImage
|
||||||
headers_len = 0x10 * len(palettes)
|
headers_len = 0x10 * len(palettes)
|
||||||
palettes_len = 0x200 * len(palettes)
|
palettes_len = 0x200 * len(palettes)
|
||||||
|
|
||||||
# header (struct BackgroundHeader)
|
# header (struct BackgroundHeader)
|
||||||
for i, palette in enumerate(palettes):
|
for i, palette in enumerate(palettes):
|
||||||
f.write(
|
out_bytes += (baseaddr + palettes_len + headers_len).to_bytes(
|
||||||
(baseaddr + palettes_len + headers_len).to_bytes(
|
|
||||||
4, byteorder="big"
|
4, byteorder="big"
|
||||||
)
|
|
||||||
) # raster offset
|
) # raster offset
|
||||||
f.write(
|
out_bytes += (baseaddr + headers_len + 0x200 * i).to_bytes(
|
||||||
(baseaddr + headers_len + 0x200 * i).to_bytes(
|
|
||||||
4, byteorder="big"
|
4, byteorder="big"
|
||||||
)
|
|
||||||
) # palette offset
|
) # palette offset
|
||||||
f.write((12).to_bytes(2, byteorder="big")) # startX
|
out_bytes += (12).to_bytes(2, byteorder="big") # startX
|
||||||
f.write((20).to_bytes(2, byteorder="big")) # startY
|
out_bytes += (20).to_bytes(2, byteorder="big") # startY
|
||||||
f.write((width).to_bytes(2, byteorder="big")) # width
|
out_bytes += (out_width).to_bytes(2, byteorder="big") # width
|
||||||
f.write((height).to_bytes(2, byteorder="big")) # height
|
out_bytes += (out_height).to_bytes(2, byteorder="big") # height
|
||||||
|
|
||||||
assert f.tell() == headers_len
|
|
||||||
|
|
||||||
for palette in palettes:
|
for palette in palettes:
|
||||||
# palette
|
# palette
|
||||||
@ -248,21 +240,32 @@ class Converter:
|
|||||||
self.warn("alpha mask mode but translucent pixels used")
|
self.warn("alpha mask mode but translucent pixels used")
|
||||||
|
|
||||||
color = pack_color(*rgba)
|
color = pack_color(*rgba)
|
||||||
f.write(color.to_bytes(2, byteorder="big"))
|
out_bytes += color.to_bytes(2, byteorder="big")
|
||||||
|
|
||||||
assert f.tell() == palettes_len + headers_len
|
|
||||||
|
|
||||||
# ci 8
|
# ci 8
|
||||||
for row in reversed_if(data, self.flip_y):
|
for row in reversed_if(data, self.flip_y):
|
||||||
f.write(row)
|
out_bytes += row
|
||||||
else:
|
else:
|
||||||
print("unsupported mode", file=stderr)
|
print("unsupported mode", file=stderr)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
return (out_bytes, out_width, out_height)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if len(argv) < 4:
|
if len(argv) < 4:
|
||||||
print("usage: build.py MODE INFILE OUTFILE [--flip-x] [--flip-y]")
|
print("usage: build.py MODE INFILE OUTFILE [--flip-x] [--flip-y]")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
Converter(*argv[1:]).convert()
|
mode = argv[1]
|
||||||
|
infile = argv[2]
|
||||||
|
outfile = argv[3]
|
||||||
|
|
||||||
|
flip_x = "--flip-x" in argv
|
||||||
|
flip_y = "--flip-y" in argv
|
||||||
|
|
||||||
|
(out_bytes, out_width, out_height) = Converter(
|
||||||
|
mode, infile, flip_x, flip_y
|
||||||
|
).convert()
|
||||||
|
with open(argv[3], "wb") as f:
|
||||||
|
f.write(out_bytes)
|
||||||
|
19
tools/build/mapfs/tex.py
Normal file
19
tools/build/mapfs/tex.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
from pathlib import Path
|
||||||
|
from sys import argv, path
|
||||||
|
path.append(str(Path(__file__).parent.parent.parent / "splat"))
|
||||||
|
path.append(str(Path(__file__).parent.parent.parent / "splat_ext"))
|
||||||
|
from tex_archives import TexArchive
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(description="Texture archives")
|
||||||
|
parser.add_argument("bin_out", type=Path, help="Output binary file path")
|
||||||
|
parser.add_argument("tex_dir", type=Path, help="File path to input tex subdirectory")
|
||||||
|
parser.add_argument(
|
||||||
|
"--endian", choices=["big", "little"], default="big", help="Output endianness"
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
TexArchive.build(args.bin_out, args.tex_dir, args.endian)
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from functools import cache
|
from functools import lru_cache
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import sys
|
import sys
|
||||||
from typing import List
|
from typing import List
|
||||||
@ -95,7 +95,7 @@ SPECIAL_RASTER_BYTES = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@cache
|
@lru_cache(maxsize=None)
|
||||||
def get_asset_path(asset: str) -> Path:
|
def get_asset_path(asset: str) -> Path:
|
||||||
for sdir in ASSET_STACK:
|
for sdir in ASSET_STACK:
|
||||||
potential_path = ASSET_DIR / sdir / "sprite" / asset
|
potential_path = ASSET_DIR / sdir / "sprite" / asset
|
||||||
|
@ -17,3 +17,11 @@ def unpack_color(data):
|
|||||||
b = ceil(0xFF * (b / 31))
|
b = ceil(0xFF * (b / 31))
|
||||||
|
|
||||||
return r, g, b, a
|
return r, g, b, a
|
||||||
|
|
||||||
|
def pack_color(r, g, b, a):
|
||||||
|
r = r >> 3
|
||||||
|
g = g >> 3
|
||||||
|
b = b >> 3
|
||||||
|
a = a >> 7
|
||||||
|
|
||||||
|
return (r << 11) | (g << 6) | (b << 1) | a
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import os
|
import os, sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import List
|
||||||
from segtypes.n64.segment import N64Segment
|
from segtypes.n64.segment import N64Segment
|
||||||
from util.n64.Yay0decompress import Yay0Decompressor
|
from util.n64.Yay0decompress import Yay0Decompressor
|
||||||
from util.color import unpack_color
|
from util.color import unpack_color
|
||||||
@ -9,6 +10,10 @@ import png # type: ignore
|
|||||||
import yaml as yaml_loader
|
import yaml as yaml_loader
|
||||||
import n64img.image
|
import n64img.image
|
||||||
|
|
||||||
|
SPLAT_EXT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
sys.path.append(str(Path(SPLAT_EXT_DIR)))
|
||||||
|
from tex_archives import TexArchive
|
||||||
|
|
||||||
script_dir = Path(os.path.dirname(os.path.realpath(__file__)))
|
script_dir = Path(os.path.dirname(os.path.realpath(__file__)))
|
||||||
|
|
||||||
|
|
||||||
@ -69,6 +74,8 @@ class N64SegPm_map_data(N64Segment):
|
|||||||
self.files = yaml_loader.load(f.read(), Loader=yaml_loader.SafeLoader)
|
self.files = yaml_loader.load(f.read(), Loader=yaml_loader.SafeLoader)
|
||||||
|
|
||||||
def split(self, rom_bytes):
|
def split(self, rom_bytes):
|
||||||
|
assert isinstance(self.rom_start, int)
|
||||||
|
|
||||||
fs_dir = options.opts.asset_path / self.dir / self.name
|
fs_dir = options.opts.asset_path / self.dir / self.name
|
||||||
(fs_dir / "title").mkdir(parents=True, exist_ok=True)
|
(fs_dir / "title").mkdir(parents=True, exist_ok=True)
|
||||||
(fs_dir / "party").mkdir(parents=True, exist_ok=True)
|
(fs_dir / "party").mkdir(parents=True, exist_ok=True)
|
||||||
@ -104,6 +111,7 @@ class N64SegPm_map_data(N64Segment):
|
|||||||
bytes = Yay0Decompressor.decompress_python(bytes)
|
bytes = Yay0Decompressor.decompress_python(bytes)
|
||||||
|
|
||||||
if name.startswith("party_"):
|
if name.startswith("party_"):
|
||||||
|
assert path is not None
|
||||||
with open(path, "wb") as f:
|
with open(path, "wb") as f:
|
||||||
# CI-8
|
# CI-8
|
||||||
w = png.Writer(150, 105, palette=parse_palette(bytes[:0x200]))
|
w = png.Writer(150, 105, palette=parse_palette(bytes[:0x200]))
|
||||||
@ -143,7 +151,7 @@ class N64SegPm_map_data(N64Segment):
|
|||||||
w = 128
|
w = 128
|
||||||
h = 32
|
h = 32
|
||||||
img = n64img.image.CI4(
|
img = n64img.image.CI4(
|
||||||
data=bytes[0x10 : 0x10 + w * h], width=w, height=h
|
data=bytes[0x10 : 0x10 + (w * h // 2)], width=w, height=h
|
||||||
)
|
)
|
||||||
img.palette = parse_palette(bytes[0x810:0x830])
|
img.palette = parse_palette(bytes[0x810:0x830])
|
||||||
img.write(fs_dir / "title/copyright.png")
|
img.write(fs_dir / "title/copyright.png")
|
||||||
@ -189,7 +197,10 @@ class N64SegPm_map_data(N64Segment):
|
|||||||
write_bg_png(
|
write_bg_png(
|
||||||
bytes, fs_dir / "bg" / f"{name}.alt.png", header_offset=0x10
|
bytes, fs_dir / "bg" / f"{name}.alt.png", header_offset=0x10
|
||||||
)
|
)
|
||||||
|
elif name.endswith("_tex"):
|
||||||
|
TexArchive.extract(bytes, fs_dir / "tex" / name)
|
||||||
else:
|
else:
|
||||||
|
assert path is not None
|
||||||
with open(path, "wb") as f:
|
with open(path, "wb") as f:
|
||||||
f.write(bytes)
|
f.write(bytes)
|
||||||
|
|
||||||
|
642
tools/splat_ext/tex_archives.py
Normal file
642
tools/splat_ext/tex_archives.py
Normal file
@ -0,0 +1,642 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
import os
|
||||||
|
import struct
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import png
|
||||||
|
import n64img.image
|
||||||
|
from util.color import unpack_color, pack_color
|
||||||
|
from segtypes.n64.palette import iter_in_groups
|
||||||
|
|
||||||
|
from sys import path
|
||||||
|
|
||||||
|
path.append(str(Path(__file__).parent.parent / "build"))
|
||||||
|
from img.build import Converter
|
||||||
|
|
||||||
|
|
||||||
|
def decode_null_terminated_ascii(data):
|
||||||
|
length = 0
|
||||||
|
for byte in data:
|
||||||
|
if byte == 0:
|
||||||
|
break
|
||||||
|
length += 1
|
||||||
|
|
||||||
|
return data[:length].decode("ascii")
|
||||||
|
|
||||||
|
|
||||||
|
def parse_palette(data):
|
||||||
|
palette = []
|
||||||
|
|
||||||
|
for a, b in iter_in_groups(data, 2):
|
||||||
|
palette.append(unpack_color([a, b]))
|
||||||
|
|
||||||
|
return palette
|
||||||
|
|
||||||
|
|
||||||
|
FMT_RGBA = 0
|
||||||
|
FMT_CI = 2
|
||||||
|
FMT_IA = 3
|
||||||
|
FMT_I = 4
|
||||||
|
|
||||||
|
DEPTH_4_BIT = 0
|
||||||
|
DEPTH_8_BIT = 1
|
||||||
|
DEPTH_16_BIT = 2
|
||||||
|
DEPTH_32_BIT = 3
|
||||||
|
|
||||||
|
# extra tile modes
|
||||||
|
TILES_BASIC = 0
|
||||||
|
TILES_MIPMAPS = 1
|
||||||
|
TILES_SHARED_AUX = 2
|
||||||
|
TILES_INDEPENDENT_AUX = 3
|
||||||
|
|
||||||
|
aux_combine_modes = {
|
||||||
|
0x00: "None", # multiply main * prim, ignore aux
|
||||||
|
0x08: "Multiply", # multiply main * aux * prim
|
||||||
|
0x0D: "ModulateAlpha", # use prim color, but multiply alpha by the difference between main and aux red channels
|
||||||
|
0x10: "LerpMainAux", # use prim alpha to lerp between main and aux color, use main alpha
|
||||||
|
}
|
||||||
|
aux_combine_modes_inv = {v: k for k, v in aux_combine_modes.items()}
|
||||||
|
|
||||||
|
wrap_modes = {
|
||||||
|
0: "Repeat",
|
||||||
|
1: "Mirror",
|
||||||
|
2: "Clamp",
|
||||||
|
}
|
||||||
|
wrap_modes_inv = {v: k for k, v in wrap_modes.items()}
|
||||||
|
|
||||||
|
# correspond to modes provided to gSetTextureFilter, only 0 and 2 are ever used
|
||||||
|
filter_modes = {
|
||||||
|
0: "Nearest",
|
||||||
|
2: "Bilerp",
|
||||||
|
3: "Average",
|
||||||
|
}
|
||||||
|
filter_modes_inv = {v: k for k, v in filter_modes.items()}
|
||||||
|
|
||||||
|
|
||||||
|
def get_format_name(fmt, depth):
|
||||||
|
# get image from bytes for valid combinations of fmt and bit depth
|
||||||
|
if fmt == FMT_RGBA:
|
||||||
|
if depth == DEPTH_16_BIT:
|
||||||
|
return "RGBA16"
|
||||||
|
if depth == DEPTH_32_BIT:
|
||||||
|
return "RGBA32"
|
||||||
|
elif fmt == FMT_CI:
|
||||||
|
if depth == DEPTH_4_BIT:
|
||||||
|
return "CI4"
|
||||||
|
elif depth == DEPTH_8_BIT:
|
||||||
|
return "CI8"
|
||||||
|
elif fmt == FMT_IA:
|
||||||
|
if depth == DEPTH_4_BIT:
|
||||||
|
return "IA4"
|
||||||
|
elif depth == DEPTH_8_BIT:
|
||||||
|
return "IA8"
|
||||||
|
elif depth == DEPTH_16_BIT:
|
||||||
|
return "IA16"
|
||||||
|
elif fmt == FMT_I:
|
||||||
|
if depth == DEPTH_4_BIT:
|
||||||
|
return "I4"
|
||||||
|
elif depth == DEPTH_8_BIT:
|
||||||
|
return "I8"
|
||||||
|
else:
|
||||||
|
raise Exception(f"Invalid format/depth pair: {fmt} and {depth}")
|
||||||
|
|
||||||
|
|
||||||
|
def get_format_code(name):
|
||||||
|
# get image from bytes for valid combinations of fmt and bit depth
|
||||||
|
if name == "RGBA16":
|
||||||
|
return (FMT_RGBA, DEPTH_16_BIT)
|
||||||
|
elif name == "RGBA32":
|
||||||
|
return (FMT_RGBA, DEPTH_32_BIT)
|
||||||
|
elif name == "CI4":
|
||||||
|
return (FMT_CI, DEPTH_4_BIT)
|
||||||
|
elif name == "CI8":
|
||||||
|
return (FMT_CI, DEPTH_8_BIT)
|
||||||
|
elif name == "IA4":
|
||||||
|
return (FMT_IA, DEPTH_4_BIT)
|
||||||
|
elif name == "IA8":
|
||||||
|
return (FMT_IA, DEPTH_8_BIT)
|
||||||
|
elif name == "IA16":
|
||||||
|
return (FMT_IA, DEPTH_16_BIT)
|
||||||
|
elif name == "I4":
|
||||||
|
return (FMT_I, DEPTH_4_BIT)
|
||||||
|
elif name == "I8":
|
||||||
|
return (FMT_I, DEPTH_8_BIT)
|
||||||
|
else:
|
||||||
|
raise Exception(f"Invalid format: {name}")
|
||||||
|
|
||||||
|
|
||||||
|
# class for reading a tex file buffer one chunk at a time
|
||||||
|
@dataclass
|
||||||
|
class TexBuffer:
|
||||||
|
data: bytes
|
||||||
|
pos: int = 0
|
||||||
|
|
||||||
|
@property
|
||||||
|
def capacity(self):
|
||||||
|
return len(self.data)
|
||||||
|
|
||||||
|
def get(self, count):
|
||||||
|
amt = int(min(count, self.capacity - self.pos))
|
||||||
|
ret = self.data[self.pos : self.pos + amt]
|
||||||
|
self.pos += amt
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def remaining(self):
|
||||||
|
return self.capacity - self.pos
|
||||||
|
|
||||||
|
|
||||||
|
class TexImage:
|
||||||
|
# utility function for unpacking aux/main property pairs from a single byte
|
||||||
|
def split_byte(self, byte):
|
||||||
|
return (byte >> 4 & 0xF), (byte & 0xF)
|
||||||
|
|
||||||
|
# utility function for unpacking aux/main property pairs from a single byte
|
||||||
|
def pack_byte(self, aux, main):
|
||||||
|
return ((aux & 0xF) << 4) | (main & 0xF)
|
||||||
|
|
||||||
|
# get n64img object from the buffer
|
||||||
|
def get_n64_img(self, texbuf: TexBuffer, fmt, depth, w, h):
|
||||||
|
# calculate size for bit depth
|
||||||
|
if depth == DEPTH_4_BIT:
|
||||||
|
size = w * h // 2
|
||||||
|
elif depth == DEPTH_8_BIT:
|
||||||
|
size = w * h
|
||||||
|
elif depth == DEPTH_16_BIT:
|
||||||
|
size = w * h * 2
|
||||||
|
elif depth == DEPTH_32_BIT:
|
||||||
|
size = w * h * 4
|
||||||
|
else:
|
||||||
|
raise Exception(f"Invalid bit depth: {depth}")
|
||||||
|
|
||||||
|
bytes = texbuf.get(size)
|
||||||
|
|
||||||
|
# get image from bytes for valid combinations of fmt and bit depth
|
||||||
|
fmt_name = get_format_name(fmt, depth)
|
||||||
|
if fmt_name == "RGBA16":
|
||||||
|
img = n64img.image.RGBA16(data=bytes, width=w, height=h)
|
||||||
|
elif fmt_name == "RGBA32":
|
||||||
|
img = n64img.image.RGBA32(data=bytes, width=w, height=h)
|
||||||
|
elif fmt_name == "CI4":
|
||||||
|
img = n64img.image.CI4(data=bytes, width=w, height=h)
|
||||||
|
elif fmt_name == "CI8":
|
||||||
|
img = n64img.image.CI8(data=bytes, width=w, height=h)
|
||||||
|
elif fmt_name == "IA4":
|
||||||
|
img = n64img.image.IA4(data=bytes, width=w, height=h)
|
||||||
|
elif fmt_name == "IA8":
|
||||||
|
img = n64img.image.IA8(data=bytes, width=w, height=h)
|
||||||
|
elif fmt_name == "IA16":
|
||||||
|
img = n64img.image.IA16(data=bytes, width=w, height=h)
|
||||||
|
elif fmt_name == "I4":
|
||||||
|
img = n64img.image.I4(data=bytes, width=w, height=h)
|
||||||
|
elif fmt_name == "I8":
|
||||||
|
img = n64img.image.I8(data=bytes, width=w, height=h)
|
||||||
|
else:
|
||||||
|
raise Exception(f"Invalid format: {fmt_name}")
|
||||||
|
|
||||||
|
img.flip_v = True
|
||||||
|
return img
|
||||||
|
|
||||||
|
# get palette from the buffer
|
||||||
|
def get_n64_pal(self, texbuf, fmt, depth):
|
||||||
|
if fmt == FMT_CI:
|
||||||
|
if depth == DEPTH_4_BIT:
|
||||||
|
return parse_palette(texbuf.get(0x20))
|
||||||
|
elif depth == DEPTH_8_BIT:
|
||||||
|
return parse_palette(texbuf.get(0x200))
|
||||||
|
|
||||||
|
# extract texture properties and rasters from buffer
|
||||||
|
def from_bytes(self, texbuf: TexBuffer):
|
||||||
|
# strip area prefix and original extension suffix
|
||||||
|
raw_name = decode_null_terminated_ascii(texbuf.get(32))
|
||||||
|
self.img_name = raw_name[4:-3]
|
||||||
|
self.raw_ext = raw_name[-3:]
|
||||||
|
|
||||||
|
(
|
||||||
|
self.aux_width,
|
||||||
|
self.main_width,
|
||||||
|
self.aux_height,
|
||||||
|
self.main_height,
|
||||||
|
self.is_variant,
|
||||||
|
self.extra_tiles,
|
||||||
|
self.combine_mode,
|
||||||
|
fmts,
|
||||||
|
depths,
|
||||||
|
hwraps,
|
||||||
|
vwraps,
|
||||||
|
self.filter_mode,
|
||||||
|
) = struct.unpack(">HHHHBBBBBBBB", texbuf.get(16))
|
||||||
|
|
||||||
|
# unpack upper/lower nibbles for aux/main
|
||||||
|
(self.aux_fmt, self.main_fmt) = self.split_byte(fmts)
|
||||||
|
(self.aux_depth, self.main_depth) = self.split_byte(depths)
|
||||||
|
(self.aux_hwrap, self.main_hwrap) = self.split_byte(hwraps)
|
||||||
|
(self.aux_vwrap, self.main_vwrap) = self.split_byte(vwraps)
|
||||||
|
|
||||||
|
self.has_mipmaps = False
|
||||||
|
self.has_aux = False
|
||||||
|
|
||||||
|
# main img only
|
||||||
|
if self.extra_tiles == TILES_BASIC:
|
||||||
|
self.main_img = self.get_n64_img(
|
||||||
|
texbuf,
|
||||||
|
self.main_fmt,
|
||||||
|
self.main_depth,
|
||||||
|
self.main_width,
|
||||||
|
self.main_height,
|
||||||
|
)
|
||||||
|
if self.main_fmt == FMT_CI:
|
||||||
|
self.main_img.palette = self.get_n64_pal(
|
||||||
|
texbuf, self.main_fmt, self.main_depth
|
||||||
|
)
|
||||||
|
# main img + mipmaps
|
||||||
|
elif self.extra_tiles == TILES_MIPMAPS:
|
||||||
|
self.has_mipmaps = True
|
||||||
|
self.main_img = self.get_n64_img(
|
||||||
|
texbuf,
|
||||||
|
self.main_fmt,
|
||||||
|
self.main_depth,
|
||||||
|
self.main_width,
|
||||||
|
self.main_height,
|
||||||
|
)
|
||||||
|
# read mipmaps
|
||||||
|
self.mipmaps = []
|
||||||
|
divisor = 2
|
||||||
|
if self.main_width >= (32 >> self.main_depth):
|
||||||
|
while True:
|
||||||
|
if (self.main_width // divisor) <= 0:
|
||||||
|
break
|
||||||
|
mmw = self.main_width // divisor
|
||||||
|
mmh = self.main_height // divisor
|
||||||
|
mipmap = self.get_n64_img(
|
||||||
|
texbuf, self.main_fmt, self.main_depth, mmw, mmh
|
||||||
|
)
|
||||||
|
self.mipmaps.append(mipmap)
|
||||||
|
|
||||||
|
divisor = divisor * 2
|
||||||
|
if (self.main_width // divisor) < (16 >> self.main_depth):
|
||||||
|
break
|
||||||
|
# read palette and assign to all images
|
||||||
|
if self.main_fmt == FMT_CI:
|
||||||
|
shared_pal = self.get_n64_pal(texbuf, self.main_fmt, self.main_depth)
|
||||||
|
self.main_img.palette = shared_pal
|
||||||
|
for mipmap in self.mipmaps:
|
||||||
|
mipmap.palette = shared_pal
|
||||||
|
|
||||||
|
# main + aux (shared attributes)
|
||||||
|
elif self.extra_tiles == TILES_SHARED_AUX:
|
||||||
|
self.has_aux = True
|
||||||
|
self.main_img = self.get_n64_img(
|
||||||
|
texbuf,
|
||||||
|
self.main_fmt,
|
||||||
|
self.main_depth,
|
||||||
|
self.main_width,
|
||||||
|
self.main_height // 2,
|
||||||
|
)
|
||||||
|
self.aux_img = self.get_n64_img(
|
||||||
|
texbuf,
|
||||||
|
self.main_fmt,
|
||||||
|
self.main_depth,
|
||||||
|
self.main_width,
|
||||||
|
self.main_height // 2,
|
||||||
|
)
|
||||||
|
if self.main_fmt == FMT_CI:
|
||||||
|
shared_pal = self.get_n64_pal(texbuf, self.main_fmt, self.main_depth)
|
||||||
|
self.main_img.palette = shared_pal
|
||||||
|
self.aux_img.palette = shared_pal
|
||||||
|
|
||||||
|
# main + aux (independent attributes)
|
||||||
|
elif self.extra_tiles == TILES_INDEPENDENT_AUX:
|
||||||
|
self.has_aux = True
|
||||||
|
# read main
|
||||||
|
self.main_img = self.get_n64_img(
|
||||||
|
texbuf,
|
||||||
|
self.main_fmt,
|
||||||
|
self.main_depth,
|
||||||
|
self.main_width,
|
||||||
|
self.main_height,
|
||||||
|
)
|
||||||
|
if self.main_fmt == FMT_CI:
|
||||||
|
pal = self.get_n64_pal(texbuf, self.main_fmt, self.main_depth)
|
||||||
|
self.main_img.palette = pal
|
||||||
|
# read aux
|
||||||
|
self.aux_img = self.get_n64_img(
|
||||||
|
texbuf, self.aux_fmt, self.aux_depth, self.aux_width, self.aux_height
|
||||||
|
)
|
||||||
|
if self.aux_fmt == FMT_CI:
|
||||||
|
self.aux_img.palette = self.get_n64_pal(
|
||||||
|
texbuf, self.aux_fmt, self.aux_depth
|
||||||
|
)
|
||||||
|
|
||||||
|
# constructs a dictionary entry for the tex archive for this texture
|
||||||
|
def get_json_entry(self):
|
||||||
|
out = {}
|
||||||
|
out["name"] = self.img_name
|
||||||
|
|
||||||
|
# only a single texture in 'tst_tex' has 'rgb', otherwise this is always 'tif'
|
||||||
|
if self.raw_ext != "tif":
|
||||||
|
out["ext"] = self.raw_ext
|
||||||
|
|
||||||
|
out["main"] = {
|
||||||
|
"format": get_format_name(self.main_fmt, self.main_depth),
|
||||||
|
"hwrap": wrap_modes.get(self.main_hwrap),
|
||||||
|
"vwrap": wrap_modes.get(self.main_vwrap),
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.has_aux:
|
||||||
|
if self.extra_tiles == TILES_SHARED_AUX:
|
||||||
|
out["aux"] = {
|
||||||
|
"format": "Shared",
|
||||||
|
"hwrap": wrap_modes.get(self.aux_hwrap),
|
||||||
|
"vwrap": wrap_modes.get(self.aux_vwrap),
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
out["aux"] = {
|
||||||
|
"format": get_format_name(self.aux_fmt, self.aux_depth),
|
||||||
|
"hwrap": wrap_modes.get(self.aux_hwrap),
|
||||||
|
"vwrap": wrap_modes.get(self.aux_vwrap),
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.has_mipmaps:
|
||||||
|
out["hasMipmaps"] = True
|
||||||
|
|
||||||
|
if self.filter_mode == 2:
|
||||||
|
out["filter"] = True
|
||||||
|
|
||||||
|
out["combine"] = aux_combine_modes.get(self.combine_mode)
|
||||||
|
|
||||||
|
if self.is_variant:
|
||||||
|
out["variant"] = True
|
||||||
|
|
||||||
|
return out
|
||||||
|
|
||||||
|
def save_images(self, tex_path):
|
||||||
|
self.main_img.write(tex_path / f"{self.img_name}.png")
|
||||||
|
if self.has_aux:
|
||||||
|
self.aux_img.write(tex_path / f"{self.img_name}_AUX.png")
|
||||||
|
if self.has_mipmaps:
|
||||||
|
for idx, mipmap in enumerate(self.mipmaps):
|
||||||
|
mipmap.write(tex_path / f"{self.img_name}_MM{idx + 1}.png")
|
||||||
|
|
||||||
|
def read_json_img(self, img_data, tile_name, img_name):
|
||||||
|
fmt_str = img_data.get("format")
|
||||||
|
if fmt_str == None:
|
||||||
|
raise Exception(f"Texture {img_name} is missing 'format' for '{tile_name}'")
|
||||||
|
|
||||||
|
hwrap_str = img_data.get("hwrap", "Missing")
|
||||||
|
hwrap = wrap_modes_inv.get(hwrap_str)
|
||||||
|
if hwrap == None:
|
||||||
|
raise Exception(f"Texture {img_name} has invalid 'hwrap' for '{tile_name}'")
|
||||||
|
|
||||||
|
vwrap_str = img_data.get("vwrap", "Missing")
|
||||||
|
vwrap = wrap_modes_inv.get(vwrap_str)
|
||||||
|
if vwrap == None:
|
||||||
|
raise Exception(f"Texture {img_name} has invalid 'vwrap' for '{tile_name}'")
|
||||||
|
|
||||||
|
return fmt_str, hwrap, vwrap
|
||||||
|
|
||||||
|
def get_img_file(self, fmt_str, img_file):
|
||||||
|
(out_img, out_w, out_h) = Converter(
|
||||||
|
mode=fmt_str.lower(), infile=img_file, flip_y=True
|
||||||
|
).convert()
|
||||||
|
|
||||||
|
out_pal = bytearray()
|
||||||
|
if fmt_str == "CI4" or fmt_str == "CI8":
|
||||||
|
img = png.Reader(img_file)
|
||||||
|
img.preamble(True)
|
||||||
|
palette = img.palette(alpha="force")
|
||||||
|
for rgba in palette:
|
||||||
|
if rgba[3] not in (0, 0xFF):
|
||||||
|
self.warn("alpha mask mode but translucent pixels used")
|
||||||
|
|
||||||
|
color = pack_color(*rgba)
|
||||||
|
out_pal += color.to_bytes(2, byteorder="big")
|
||||||
|
|
||||||
|
return (out_img, out_pal, out_w, out_h)
|
||||||
|
|
||||||
|
# read texture properties from dictionary and load images
|
||||||
|
def from_json(self, tex_path: Path, json_data):
|
||||||
|
self.img_name = json_data["name"]
|
||||||
|
|
||||||
|
if "ext" in json_data:
|
||||||
|
self.raw_ext = json_data["ext"]
|
||||||
|
else:
|
||||||
|
self.raw_ext = "tif"
|
||||||
|
|
||||||
|
# read data for main tile
|
||||||
|
main_data = json_data.get("main")
|
||||||
|
if main_data == None:
|
||||||
|
raise Exception(f"Texture {self.img_name} has no definition for 'main'")
|
||||||
|
|
||||||
|
(main_fmt_name, self.main_hwrap, self.main_vwrap) = self.read_json_img(
|
||||||
|
main_data, "main", self.img_name
|
||||||
|
)
|
||||||
|
(self.main_fmt, self.main_depth) = get_format_code(main_fmt_name)
|
||||||
|
|
||||||
|
# read main image
|
||||||
|
img_path = str(tex_path / f"{self.img_name}.png")
|
||||||
|
if not os.path.isfile(img_path):
|
||||||
|
raise Exception(f"Could not find main image for texture: {self.img_name}")
|
||||||
|
(
|
||||||
|
self.main_img,
|
||||||
|
self.main_pal,
|
||||||
|
self.main_width,
|
||||||
|
self.main_height,
|
||||||
|
) = self.get_img_file(main_fmt_name, img_path)
|
||||||
|
|
||||||
|
# read data for aux tile
|
||||||
|
self.has_aux = "aux" in json_data
|
||||||
|
if self.has_aux:
|
||||||
|
aux_data = json_data.get("aux")
|
||||||
|
(aux_fmt_name, self.aux_hwrap, self.aux_vwrap) = self.read_json_img(
|
||||||
|
aux_data, "aux", self.img_name
|
||||||
|
)
|
||||||
|
|
||||||
|
if aux_fmt_name == "Shared":
|
||||||
|
# aux tiles have blank attributes in SHARED mode
|
||||||
|
aux_fmt_name = main_fmt_name
|
||||||
|
self.aux_fmt = 0
|
||||||
|
self.aux_depth = 0
|
||||||
|
self.aux_hwrap = 0
|
||||||
|
self.aux_vwrap = 0
|
||||||
|
self.extra_tiles = TILES_SHARED_AUX
|
||||||
|
else:
|
||||||
|
(self.aux_fmt, self.aux_depth) = get_format_code(aux_fmt_name)
|
||||||
|
self.extra_tiles = TILES_INDEPENDENT_AUX
|
||||||
|
|
||||||
|
# read aux image
|
||||||
|
img_path = str(tex_path / f"{self.img_name}_AUX.png")
|
||||||
|
if not os.path.isfile(img_path):
|
||||||
|
raise Exception(
|
||||||
|
f"Could not find AUX image for texture: {self.img_name}"
|
||||||
|
)
|
||||||
|
(
|
||||||
|
self.aux_img,
|
||||||
|
self.aux_pal,
|
||||||
|
self.aux_width,
|
||||||
|
self.aux_height,
|
||||||
|
) = self.get_img_file(aux_fmt_name, img_path)
|
||||||
|
if self.extra_tiles == TILES_SHARED_AUX:
|
||||||
|
# aux tiles have blank sizes in SHARED mode
|
||||||
|
self.main_height *= 2
|
||||||
|
self.aux_width = 0
|
||||||
|
self.aux_height = 0
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.aux_fmt = 0
|
||||||
|
self.aux_depth = 0
|
||||||
|
self.aux_hwrap = 0
|
||||||
|
self.aux_vwrap = 0
|
||||||
|
self.aux_width = 0
|
||||||
|
self.aux_height = 0
|
||||||
|
self.extra_tiles = TILES_BASIC
|
||||||
|
|
||||||
|
# read mipmaps
|
||||||
|
self.has_mipmaps = json_data.get("hasMipmaps", False)
|
||||||
|
if self.has_mipmaps:
|
||||||
|
self.mipmaps = []
|
||||||
|
mipmap_idx = 1
|
||||||
|
divisor = 2
|
||||||
|
if self.main_width >= (32 >> self.main_depth):
|
||||||
|
while True:
|
||||||
|
if (self.main_width // divisor) <= 0:
|
||||||
|
break
|
||||||
|
mmw = self.main_width // divisor
|
||||||
|
mmh = self.main_height // divisor
|
||||||
|
|
||||||
|
img_path = str(tex_path / f"{self.img_name}_MM{mipmap_idx}.png")
|
||||||
|
if not os.path.isfile(img_path):
|
||||||
|
raise Exception(
|
||||||
|
f"Texture {self.img_name} is missing mipmap level {mipmap_idx} (size = {mmw} x {mmh})"
|
||||||
|
)
|
||||||
|
|
||||||
|
(raster, pal, width, height) = self.get_img_file(
|
||||||
|
main_fmt_name, img_path
|
||||||
|
)
|
||||||
|
self.mipmaps.append(raster)
|
||||||
|
if width != mmw or height != mmh:
|
||||||
|
raise Exception(
|
||||||
|
f"Texture {self.img_name} has wrong size for mipmap level {mipmap_idx} \n"
|
||||||
|
+ f"MM{mipmap_idx} size = {width} x {height}, but should be = {mmw} x {mmh}"
|
||||||
|
)
|
||||||
|
|
||||||
|
divisor = divisor * 2
|
||||||
|
mipmap_idx += 1
|
||||||
|
if (self.main_width // divisor) < (16 >> self.main_depth):
|
||||||
|
break
|
||||||
|
self.extra_tiles = TILES_MIPMAPS
|
||||||
|
|
||||||
|
# read filter mode
|
||||||
|
if json_data.get("filter", False):
|
||||||
|
self.filter_mode = 2
|
||||||
|
else:
|
||||||
|
self.filter_mode = 0
|
||||||
|
|
||||||
|
# read tile combine mode
|
||||||
|
combine_str = json_data.get("combine", "Missing")
|
||||||
|
self.combine = aux_combine_modes_inv.get(combine_str)
|
||||||
|
if self.combine == None:
|
||||||
|
raise Exception(f"Texture {self.img_name} has invalid 'combine'")
|
||||||
|
|
||||||
|
self.is_variant = json_data.get("variant", False)
|
||||||
|
|
||||||
|
# write texture header and image raster/palettes to byte array
|
||||||
|
def add_bytes(self, tex_name: str, bytes: bytearray):
|
||||||
|
# form raw name and write to header
|
||||||
|
raw_name = tex_name[:4] + self.img_name + self.raw_ext
|
||||||
|
name_bytes = raw_name.encode("ascii")
|
||||||
|
bytes += name_bytes
|
||||||
|
|
||||||
|
# pad name out to 32 bytes
|
||||||
|
pad_len = 32 - len(name_bytes)
|
||||||
|
assert pad_len > 0
|
||||||
|
bytes += b"\0" * pad_len
|
||||||
|
|
||||||
|
# write header fields
|
||||||
|
bytes += struct.pack(
|
||||||
|
">HHHHBBBBBBBB",
|
||||||
|
self.aux_width,
|
||||||
|
self.main_width,
|
||||||
|
self.aux_height,
|
||||||
|
self.main_height,
|
||||||
|
self.is_variant,
|
||||||
|
self.extra_tiles,
|
||||||
|
self.combine,
|
||||||
|
self.pack_byte(self.aux_fmt, self.main_fmt),
|
||||||
|
self.pack_byte(self.aux_depth, self.main_depth),
|
||||||
|
self.pack_byte(self.aux_hwrap, self.main_hwrap),
|
||||||
|
self.pack_byte(self.aux_vwrap, self.main_vwrap),
|
||||||
|
self.filter_mode,
|
||||||
|
)
|
||||||
|
|
||||||
|
# write rasters and palettes
|
||||||
|
if self.extra_tiles == TILES_BASIC:
|
||||||
|
bytes += self.main_img
|
||||||
|
if self.main_fmt == FMT_CI:
|
||||||
|
bytes += self.main_pal
|
||||||
|
elif self.extra_tiles == TILES_MIPMAPS:
|
||||||
|
bytes += self.main_img
|
||||||
|
for mipmap in self.mipmaps:
|
||||||
|
bytes += mipmap
|
||||||
|
if self.main_fmt == FMT_CI:
|
||||||
|
bytes += self.main_pal
|
||||||
|
elif self.extra_tiles == TILES_SHARED_AUX:
|
||||||
|
bytes += self.main_img
|
||||||
|
bytes += self.aux_img
|
||||||
|
if self.main_fmt == FMT_CI:
|
||||||
|
bytes += self.main_pal
|
||||||
|
elif self.extra_tiles == TILES_INDEPENDENT_AUX:
|
||||||
|
bytes += self.main_img
|
||||||
|
if self.main_fmt == FMT_CI:
|
||||||
|
bytes += self.main_pal
|
||||||
|
bytes += self.aux_img
|
||||||
|
if self.aux_fmt == FMT_CI:
|
||||||
|
bytes += self.aux_pal
|
||||||
|
|
||||||
|
|
||||||
|
class TexArchive:
|
||||||
|
@staticmethod
|
||||||
|
def extract(bytes, tex_path: Path):
|
||||||
|
textures = []
|
||||||
|
texbuf = TexBuffer(bytes)
|
||||||
|
|
||||||
|
while texbuf.remaining() > 0:
|
||||||
|
img = TexImage()
|
||||||
|
img.from_bytes(texbuf)
|
||||||
|
textures.append(img)
|
||||||
|
|
||||||
|
tex_path.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
out = []
|
||||||
|
for texture in textures:
|
||||||
|
texture.save_images(tex_path)
|
||||||
|
out.append(texture.get_json_entry())
|
||||||
|
|
||||||
|
json_out = json.dumps(out, sort_keys=False, indent=4)
|
||||||
|
|
||||||
|
json_fn = str(tex_path) + ".json"
|
||||||
|
with open(json_fn, "w") as f:
|
||||||
|
f.write(json_out)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def build(out_path: Path, tex_path: Path, endian: str = "big"):
|
||||||
|
out_bytes = bytearray()
|
||||||
|
tex_name = os.path.basename(tex_path)
|
||||||
|
|
||||||
|
json_fn = str(tex_path) + ".json"
|
||||||
|
with open(json_fn, "r") as json_file:
|
||||||
|
json_str = json_file.read()
|
||||||
|
json_data = json.loads(json_str)
|
||||||
|
|
||||||
|
if len(json_data) > 128:
|
||||||
|
raise Exception(
|
||||||
|
f"Maximum number of textures (128) exceeded by {tex_name} ({len(json_data)})`"
|
||||||
|
)
|
||||||
|
|
||||||
|
for img_data in json_data:
|
||||||
|
img = TexImage()
|
||||||
|
img.from_json(tex_path, img_data)
|
||||||
|
img.add_bytes(tex_name, out_bytes)
|
||||||
|
|
||||||
|
with open(out_path, "wb") as out_bin:
|
||||||
|
out_bin.write(out_bytes)
|
@ -106,7 +106,7 @@ dlabel entity_numShadows
|
|||||||
dlabel gSpriteShadingProfile
|
dlabel gSpriteShadingProfile
|
||||||
.space 4
|
.space 4
|
||||||
|
|
||||||
dlabel entity_area_specific_data_is_loaded
|
dlabel isAreaSpecificEntityDataLoaded
|
||||||
.space 4
|
.space 4
|
||||||
|
|
||||||
dlabel entity_updateCounter
|
dlabel entity_updateCounter
|
||||||
@ -178,7 +178,7 @@ dlabel D_801516FC
|
|||||||
dlabel gMainGameState
|
dlabel gMainGameState
|
||||||
.space 0x00000040
|
.space 0x00000040
|
||||||
|
|
||||||
dlabel gCurrentTileDescriptor
|
dlabel gCurrentTextureHeader
|
||||||
.space 0x00000030
|
.space 0x00000030
|
||||||
|
|
||||||
dlabel wModelList
|
dlabel wModelList
|
||||||
@ -268,7 +268,7 @@ dlabel texPannerAuxU
|
|||||||
dlabel texPannerAuxV
|
dlabel texPannerAuxV
|
||||||
.space 0x00000040
|
.space 0x00000040
|
||||||
|
|
||||||
dlabel mdl_nextTextureAddress
|
dlabel TextureHeapPos
|
||||||
.space 4
|
.space 4
|
||||||
|
|
||||||
dlabel mdl_currentTransformGroupChildIndex
|
dlabel mdl_currentTransformGroupChildIndex
|
||||||
|
@ -401,7 +401,9 @@ segments:
|
|||||||
vram: 0x8010dab0
|
vram: 0x8010dab0
|
||||||
subsegments:
|
subsegments:
|
||||||
- [0xA4990, hasm, bss3]
|
- [0xA4990, hasm, bss3]
|
||||||
- [0xA4990, c, a5dd0_len_114e0]
|
- [0xA4990, c, entity]
|
||||||
|
- [auto, c, game_states]
|
||||||
|
- [auto, c, model]
|
||||||
- [0xB3140, c, B4580]
|
- [0xB3140, c, B4580]
|
||||||
- [0xB5E70, c, entity_model]
|
- [0xB5E70, c, entity_model]
|
||||||
- [0xB8370, c, worker]
|
- [0xB8370, c, worker]
|
||||||
@ -419,7 +421,9 @@ segments:
|
|||||||
- [0xDD6B0, c, sprite_shading]
|
- [0xDD6B0, c, sprite_shading]
|
||||||
- [0xDE8C0, c, audio/sfx]
|
- [0xDE8C0, c, audio/sfx]
|
||||||
- [0xDFAA0, c, audio/e0b30_len_b80]
|
- [0xDFAA0, c, audio/e0b30_len_b80]
|
||||||
- [0xE0620, .data, a5dd0_len_114e0]
|
- [0xE0620, .data, entity]
|
||||||
|
- [auto, .data, game_states]
|
||||||
|
- [auto, .data, model]
|
||||||
- [0xE18C0, .data, B4580]
|
- [0xE18C0, .data, B4580]
|
||||||
- [0xE18D0, .data, entity_model]
|
- [0xE18D0, .data, entity_model]
|
||||||
- [0xE18F0, .data, msg]
|
- [0xE18F0, .data, msg]
|
||||||
|
@ -176,7 +176,7 @@ game_mode_set_fpDrawAuxUI = 0x80117F94;
|
|||||||
step_current_game_mode = 0x80118088;
|
step_current_game_mode = 0x80118088;
|
||||||
state_render_backUI = 0x80118168;
|
state_render_backUI = 0x80118168;
|
||||||
state_render_frontUI = 0x801181D4;
|
state_render_frontUI = 0x801181D4;
|
||||||
load_model_textures = 0x8011AE34;
|
mdl_load_all_textures = 0x8011AE34;
|
||||||
clear_model_data = 0x8011AF54;
|
clear_model_data = 0x8011AF54;
|
||||||
init_model_data = 0x8011B1F8;
|
init_model_data = 0x8011B1F8;
|
||||||
calculate_model_sizes = 0x8011B33C;
|
calculate_model_sizes = 0x8011B33C;
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
.set noat /* allow manual use of $at */
|
|
||||||
.set noreorder /* don't insert nops after branches */
|
|
||||||
|
|
||||||
/* Generated by spimdisasm 1.11.1 */
|
|
||||||
|
|
||||||
glabel hos_05_AnimBowser_FlyOff
|
|
||||||
/* A9A8B4 80244774 27BDFFD0 */ addiu $sp, $sp, -0x30
|
|
||||||
/* A9A8B8 80244778 AFB00018 */ sw $s0, 0x18($sp)
|
|
||||||
/* A9A8BC 8024477C 0080802D */ daddu $s0, $a0, $zero
|
|
||||||
/* A9A8C0 80244780 AFB1001C */ sw $s1, 0x1C($sp)
|
|
||||||
/* A9A8C4 80244784 00A0882D */ daddu $s1, $a1, $zero
|
|
||||||
/* A9A8C8 80244788 24050007 */ addiu $a1, $zero, 0x7
|
|
||||||
/* A9A8CC 8024478C AFBF0028 */ sw $ra, 0x28($sp)
|
|
||||||
/* A9A8D0 80244790 AFB30024 */ sw $s3, 0x24($sp)
|
|
||||||
/* A9A8D4 80244794 0C0B42B0 */ jal resolve_npc
|
|
||||||
/* A9A8D8 80244798 AFB20020 */ sw $s2, 0x20($sp)
|
|
||||||
/* A9A8DC 8024479C 0200202D */ daddu $a0, $s0, $zero
|
|
||||||
/* A9A8E0 802447A0 24050008 */ addiu $a1, $zero, 0x8
|
|
||||||
/* A9A8E4 802447A4 0C0B42B0 */ jal resolve_npc
|
|
||||||
/* A9A8E8 802447A8 0040902D */ daddu $s2, $v0, $zero
|
|
||||||
/* A9A8EC 802447AC 12200004 */ beqz $s1, .LPAL_802447C0
|
|
||||||
/* A9A8F0 802447B0 0040982D */ daddu $s3, $v0, $zero
|
|
||||||
/* A9A8F4 802447B4 C640003C */ lwc1 $f0, 0x3C($s2)
|
|
||||||
/* A9A8F8 802447B8 3C018025 */ lui $at, %hi(hos_05_AnimBowser_FlyOff_InitialY)
|
|
||||||
/* A9A8FC 802447BC E420F314 */ swc1 $f0, %lo(hos_05_AnimBowser_FlyOff_InitialY)($at)
|
|
||||||
.LPAL_802447C0:
|
|
||||||
/* A9A900 802447C0 3C018025 */ lui $at, %hi(hos_05_AnimBowser_FlyOff_InitialY)
|
|
||||||
/* A9A904 802447C4 C420F314 */ lwc1 $f0, %lo(hos_05_AnimBowser_FlyOff_InitialY)($at)
|
|
||||||
/* A9A908 802447C8 24040003 */ addiu $a0, $zero, 0x3
|
|
||||||
/* A9A90C 802447CC 44050000 */ mfc1 $a1, $f0
|
|
||||||
/* A9A910 802447D0 3C0143FA */ lui $at, (0x43FA0000 >> 16)
|
|
||||||
/* A9A914 802447D4 44810000 */ mtc1 $at, $f0
|
|
||||||
/* A9A918 802447D8 44853000 */ mtc1 $a1, $f6
|
|
||||||
/* A9A91C 802447DC 3C108025 */ lui $s0, %hi(hos_05_AnimBowser_FlyOff_Time)
|
|
||||||
/* A9A920 802447E0 2610AE70 */ addiu $s0, $s0, %lo(hos_05_AnimBowser_FlyOff_Time)
|
|
||||||
/* A9A924 802447E4 46003180 */ add.s $f6, $f6, $f0
|
|
||||||
/* A9A928 802447E8 3C014220 */ lui $at, (0x42200000 >> 16)
|
|
||||||
/* A9A92C 802447EC 44811000 */ mtc1 $at, $f2
|
|
||||||
/* A9A930 802447F0 8E070000 */ lw $a3, 0x0($s0)
|
|
||||||
/* A9A934 802447F4 44063000 */ mfc1 $a2, $f6
|
|
||||||
/* A9A938 802447F8 2642003C */ addiu $v0, $s2, 0x3C
|
|
||||||
/* A9A93C 802447FC AFA20014 */ sw $v0, 0x14($sp)
|
|
||||||
/* A9A940 80244800 0C090439 */ jal interp_value_with_easing
|
|
||||||
/* A9A944 80244804 E7A20010 */ swc1 $f2, 0x10($sp)
|
|
||||||
/* A9A948 80244808 C640003C */ lwc1 $f0, 0x3C($s2)
|
|
||||||
/* A9A94C 8024480C 3C013F80 */ lui $at, (0x3F800000 >> 16)
|
|
||||||
/* A9A950 80244810 44811000 */ mtc1 $at, $f2
|
|
||||||
/* A9A954 80244814 E660003C */ swc1 $f0, 0x3C($s3)
|
|
||||||
/* A9A958 80244818 C6000000 */ lwc1 $f0, 0x0($s0)
|
|
||||||
/* A9A95C 8024481C C644003C */ lwc1 $f4, 0x3C($s2)
|
|
||||||
/* A9A960 80244820 46020000 */ add.s $f0, $f0, $f2
|
|
||||||
/* A9A964 80244824 E6440070 */ swc1 $f4, 0x70($s2)
|
|
||||||
/* A9A968 80244828 C662003C */ lwc1 $f2, 0x3C($s3)
|
|
||||||
/* A9A96C 8024482C 3C014204 */ lui $at, (0x42040000 >> 16)
|
|
||||||
/* A9A970 80244830 44812000 */ mtc1 $at, $f4
|
|
||||||
/* A9A974 80244834 24020001 */ addiu $v0, $zero, 0x1
|
|
||||||
/* A9A978 80244838 E6620070 */ swc1 $f2, 0x70($s3)
|
|
||||||
/* A9A97C 8024483C 4600203C */ c.lt.s $f4, $f0
|
|
||||||
/* A9A980 80244840 00000000 */ nop
|
|
||||||
/* A9A984 80244844 45010002 */ bc1t .LPAL_80244850
|
|
||||||
/* A9A988 80244848 E6000000 */ swc1 $f0, 0x0($s0)
|
|
||||||
/* A9A98C 8024484C 0000102D */ daddu $v0, $zero, $zero
|
|
||||||
.LPAL_80244850:
|
|
||||||
/* A9A990 80244850 8FBF0028 */ lw $ra, 0x28($sp)
|
|
||||||
/* A9A994 80244854 8FB30024 */ lw $s3, 0x24($sp)
|
|
||||||
/* A9A998 80244858 8FB20020 */ lw $s2, 0x20($sp)
|
|
||||||
/* A9A99C 8024485C 8FB1001C */ lw $s1, 0x1C($sp)
|
|
||||||
/* A9A9A0 80244860 8FB00018 */ lw $s0, 0x18($sp)
|
|
||||||
/* A9A9A4 80244864 03E00008 */ jr $ra
|
|
||||||
/* A9A9A8 80244868 27BD0030 */ addiu $sp, $sp, 0x30
|
|
@ -1,57 +0,0 @@
|
|||||||
.set noat /* allow manual use of $at */
|
|
||||||
.set noreorder /* don't insert nops after branches */
|
|
||||||
|
|
||||||
/* Generated by spimdisasm 1.11.1 */
|
|
||||||
|
|
||||||
glabel hos_05_AnimKammy_FlyOff
|
|
||||||
/* A9A9AC 8024486C 27BDFFD8 */ addiu $sp, $sp, -0x28
|
|
||||||
/* A9A9B0 80244870 AFB00018 */ sw $s0, 0x18($sp)
|
|
||||||
/* A9A9B4 80244874 00A0802D */ daddu $s0, $a1, $zero
|
|
||||||
/* A9A9B8 80244878 24050009 */ addiu $a1, $zero, 0x9
|
|
||||||
/* A9A9BC 8024487C AFBF0020 */ sw $ra, 0x20($sp)
|
|
||||||
/* A9A9C0 80244880 0C0B42B0 */ jal resolve_npc
|
|
||||||
/* A9A9C4 80244884 AFB1001C */ sw $s1, 0x1C($sp)
|
|
||||||
/* A9A9C8 80244888 12000004 */ beqz $s0, .LPAL_8024489C
|
|
||||||
/* A9A9CC 8024488C 0040882D */ daddu $s1, $v0, $zero
|
|
||||||
/* A9A9D0 80244890 C620003C */ lwc1 $f0, 0x3C($s1)
|
|
||||||
/* A9A9D4 80244894 3C018025 */ lui $at, %hi(hos_05_AnimKammy_FlyOff_InitialY)
|
|
||||||
/* A9A9D8 80244898 E420F318 */ swc1 $f0, %lo(hos_05_AnimKammy_FlyOff_InitialY)($at)
|
|
||||||
.LPAL_8024489C:
|
|
||||||
/* A9A9DC 8024489C 3C018025 */ lui $at, %hi(hos_05_AnimKammy_FlyOff_InitialY)
|
|
||||||
/* A9A9E0 802448A0 C420F318 */ lwc1 $f0, %lo(hos_05_AnimKammy_FlyOff_InitialY)($at)
|
|
||||||
/* A9A9E4 802448A4 24040003 */ addiu $a0, $zero, 0x3
|
|
||||||
/* A9A9E8 802448A8 44050000 */ mfc1 $a1, $f0
|
|
||||||
/* A9A9EC 802448AC 3C0143FA */ lui $at, (0x43FA0000 >> 16)
|
|
||||||
/* A9A9F0 802448B0 44810000 */ mtc1 $at, $f0
|
|
||||||
/* A9A9F4 802448B4 44853000 */ mtc1 $a1, $f6
|
|
||||||
/* A9A9F8 802448B8 3C108025 */ lui $s0, %hi(hos_05_AnimKammy_FlyOff_Time)
|
|
||||||
/* A9A9FC 802448BC 2610AE74 */ addiu $s0, $s0, %lo(hos_05_AnimKammy_FlyOff_Time)
|
|
||||||
/* A9AA00 802448C0 46003180 */ add.s $f6, $f6, $f0
|
|
||||||
/* A9AA04 802448C4 3C014220 */ lui $at, (0x42200000 >> 16)
|
|
||||||
/* A9AA08 802448C8 44811000 */ mtc1 $at, $f2
|
|
||||||
/* A9AA0C 802448CC 8E070000 */ lw $a3, 0x0($s0)
|
|
||||||
/* A9AA10 802448D0 44063000 */ mfc1 $a2, $f6
|
|
||||||
/* A9AA14 802448D4 2622003C */ addiu $v0, $s1, 0x3C
|
|
||||||
/* A9AA18 802448D8 AFA20014 */ sw $v0, 0x14($sp)
|
|
||||||
/* A9AA1C 802448DC 0C090439 */ jal interp_value_with_easing
|
|
||||||
/* A9AA20 802448E0 E7A20010 */ swc1 $f2, 0x10($sp)
|
|
||||||
/* A9AA24 802448E4 C6020000 */ lwc1 $f2, 0x0($s0)
|
|
||||||
/* A9AA28 802448E8 3C013F80 */ lui $at, (0x3F800000 >> 16)
|
|
||||||
/* A9AA2C 802448EC 44810000 */ mtc1 $at, $f0
|
|
||||||
/* A9AA30 802448F0 3C014204 */ lui $at, (0x42040000 >> 16)
|
|
||||||
/* A9AA34 802448F4 44812000 */ mtc1 $at, $f4
|
|
||||||
/* A9AA38 802448F8 46001080 */ add.s $f2, $f2, $f0
|
|
||||||
/* A9AA3C 802448FC C620003C */ lwc1 $f0, 0x3C($s1)
|
|
||||||
/* A9AA40 80244900 24020001 */ addiu $v0, $zero, 0x1
|
|
||||||
/* A9AA44 80244904 E6200070 */ swc1 $f0, 0x70($s1)
|
|
||||||
/* A9AA48 80244908 4602203C */ c.lt.s $f4, $f2
|
|
||||||
/* A9AA4C 8024490C 00000000 */ nop
|
|
||||||
/* A9AA50 80244910 45010002 */ bc1t .LPAL_8024491C
|
|
||||||
/* A9AA54 80244914 E6020000 */ swc1 $f2, 0x0($s0)
|
|
||||||
/* A9AA58 80244918 0000102D */ daddu $v0, $zero, $zero
|
|
||||||
.LPAL_8024491C:
|
|
||||||
/* A9AA5C 8024491C 8FBF0020 */ lw $ra, 0x20($sp)
|
|
||||||
/* A9AA60 80244920 8FB1001C */ lw $s1, 0x1C($sp)
|
|
||||||
/* A9AA64 80244924 8FB00018 */ lw $s0, 0x18($sp)
|
|
||||||
/* A9AA68 80244928 03E00008 */ jr $ra
|
|
||||||
/* A9AA6C 8024492C 27BD0028 */ addiu $sp, $sp, 0x28
|
|
@ -106,7 +106,7 @@ dlabel entity_numShadows
|
|||||||
dlabel gSpriteShadingProfile
|
dlabel gSpriteShadingProfile
|
||||||
.space 4
|
.space 4
|
||||||
|
|
||||||
dlabel entity_area_specific_data_is_loaded
|
dlabel isAreaSpecificEntityDataLoaded
|
||||||
.space 4
|
.space 4
|
||||||
|
|
||||||
dlabel entity_updateCounter
|
dlabel entity_updateCounter
|
||||||
@ -178,7 +178,7 @@ dlabel D_801516FC
|
|||||||
dlabel gMainGameState
|
dlabel gMainGameState
|
||||||
.space 0x00000040
|
.space 0x00000040
|
||||||
|
|
||||||
dlabel gCurrentTileDescriptor
|
dlabel gCurrentTextureHeader
|
||||||
.space 0x00000030
|
.space 0x00000030
|
||||||
|
|
||||||
dlabel wModelList
|
dlabel wModelList
|
||||||
@ -268,7 +268,7 @@ dlabel texPannerAuxU
|
|||||||
dlabel texPannerAuxV
|
dlabel texPannerAuxV
|
||||||
.space 0x00000040
|
.space 0x00000040
|
||||||
|
|
||||||
dlabel mdl_nextTextureAddress
|
dlabel TextureHeapPos
|
||||||
.space 4
|
.space 4
|
||||||
|
|
||||||
dlabel mdl_currentTransformGroupChildIndex
|
dlabel mdl_currentTransformGroupChildIndex
|
||||||
|
@ -824,7 +824,9 @@ segments:
|
|||||||
follows_vram: engine1
|
follows_vram: engine1
|
||||||
subsegments:
|
subsegments:
|
||||||
- [0xA5DD0, hasm, bss3]
|
- [0xA5DD0, hasm, bss3]
|
||||||
- [0xA5DD0, c, a5dd0_len_114e0]
|
- [0xA5DD0, c, entity]
|
||||||
|
- [0xA9290, c, game_states]
|
||||||
|
- [0xA9790, c, model]
|
||||||
- [0xB4580, c, B4580]
|
- [0xB4580, c, B4580]
|
||||||
- [0xB72B0, c, entity_model]
|
- [0xB72B0, c, entity_model]
|
||||||
- [0xB97B0, c, worker]
|
- [0xB97B0, c, worker]
|
||||||
@ -842,7 +844,9 @@ segments:
|
|||||||
- [0xDE740, c, sprite_shading]
|
- [0xDE740, c, sprite_shading]
|
||||||
- [0xDF950, c, audio/sfx]
|
- [0xDF950, c, audio/sfx]
|
||||||
- [0xE0B30, c, audio/e0b30_len_b80]
|
- [0xE0B30, c, audio/e0b30_len_b80]
|
||||||
- [0xE16B0, .data, a5dd0_len_114e0]
|
- [0xE16B0, .data, entity]
|
||||||
|
- [0xE16C0, .data, game_states]
|
||||||
|
- [0xE16C0, .data, model]
|
||||||
- [0xE2950, .data, B4580]
|
- [0xE2950, .data, B4580]
|
||||||
- [0xE2960, .data, entity_model]
|
- [0xE2960, .data, entity_model]
|
||||||
- [0xE2980, .data, msg]
|
- [0xE2980, .data, msg]
|
||||||
|
@ -3998,12 +3998,12 @@ state_do_unk = 0x80112EEC; // type:func rom:0xA95EC
|
|||||||
state_render_backUI = 0x80112F58; // type:func rom:0xA9658
|
state_render_backUI = 0x80112F58; // type:func rom:0xA9658
|
||||||
state_render_frontUI = 0x80112FC4; // type:func rom:0xA96C4
|
state_render_frontUI = 0x80112FC4; // type:func rom:0xA96C4
|
||||||
appendGfx_model = 0x80113090; // type:func rom:0xA9790
|
appendGfx_model = 0x80113090; // type:func rom:0xA9790
|
||||||
func_80114B58 = 0x80114B58; // type:func rom:0xAB258
|
load_texture_impl = 0x80114B58; // type:func rom:0xAB258
|
||||||
load_tile_header = 0x80114D6C; // type:func rom:0xAB46C
|
load_texture_by_name = 0x80114D6C; // type:func rom:0xAB46C
|
||||||
func_80115498 = 0x80115498; // type:func rom:0xABB98
|
load_texture_variants = 0x80115498; // type:func rom:0xABB98
|
||||||
get_model_property = 0x80115B0C; // type:func rom:0xAC20C
|
get_model_property = 0x80115B0C; // type:func rom:0xAC20C
|
||||||
_load_model_textures = 0x80115B44; // type:func rom:0xAC244
|
load_next_model_textures = 0x80115B44; // type:func rom:0xAC244
|
||||||
load_model_textures = 0x80115C24; // type:func rom:0xAC324
|
mdl_load_all_textures = 0x80115C24; // type:func rom:0xAC324
|
||||||
mdl_get_child_count = 0x80115CA8; // type:func rom:0xAC3A8
|
mdl_get_child_count = 0x80115CA8; // type:func rom:0xAC3A8
|
||||||
clear_model_data = 0x80115D44; // type:func rom:0xAC444
|
clear_model_data = 0x80115D44; // type:func rom:0xAC444
|
||||||
init_model_data = 0x80115FE8; // type:func rom:0xAC6E8
|
init_model_data = 0x80115FE8; // type:func rom:0xAC6E8
|
||||||
@ -4016,7 +4016,7 @@ appendGfx_model_group = 0x80117C94; // type:func rom:0xAE394
|
|||||||
func_80117D00 = 0x80117D00; // type:func rom:0xAE400
|
func_80117D00 = 0x80117D00; // type:func rom:0xAE400
|
||||||
render_transform_group_node = 0x80117E74; // type:func rom:0xAE574
|
render_transform_group_node = 0x80117E74; // type:func rom:0xAE574
|
||||||
render_transform_group = 0x8011800C; // type:func rom:0xAE70C
|
render_transform_group = 0x8011800C; // type:func rom:0xAE70C
|
||||||
func_801180E8 = 0x801180E8; // type:func rom:0xAE7E8
|
make_texture_gfx = 0x801180E8; // type:func rom:0xAE7E8
|
||||||
get_model_from_list_index = 0x8011AD30; // type:func rom:0xB1430
|
get_model_from_list_index = 0x8011AD30; // type:func rom:0xB1430
|
||||||
load_data_for_models = 0x8011AD48; // type:func rom:0xB1448
|
load_data_for_models = 0x8011AD48; // type:func rom:0xB1448
|
||||||
load_model_transforms = 0x8011ADC8; // type:func rom:0xB14C8
|
load_model_transforms = 0x8011ADC8; // type:func rom:0xB14C8
|
||||||
@ -4493,7 +4493,7 @@ D_8014B0B8 = 0x8014B0B8; // rom:0xE17B8
|
|||||||
D_8014B0BC = 0x8014B0BC; // rom:0xE17BC
|
D_8014B0BC = 0x8014B0BC; // rom:0xE17BC
|
||||||
D_8014B400 = 0x8014B400; // rom:0xE1B00
|
D_8014B400 = 0x8014B400; // rom:0xE1B00
|
||||||
D_8014B404 = 0x8014B404; // rom:0xE1B04
|
D_8014B404 = 0x8014B404; // rom:0xE1B04
|
||||||
mdl_textureBaseAddress = 0x8014B748; // rom:0xE1E48
|
TextureHeapBase = 0x8014B748; // rom:0xE1E48
|
||||||
mdl_bgMultiplyColorA = 0x8014B74C; // rom:0xE1E4C
|
mdl_bgMultiplyColorA = 0x8014B74C; // rom:0xE1E4C
|
||||||
mdl_bgMultiplyColorR = 0x8014B74D; // rom:0xE1E4D
|
mdl_bgMultiplyColorR = 0x8014B74D; // rom:0xE1E4D
|
||||||
mdl_bgMultiplyColorG = 0x8014B74E; // rom:0xE1E4E
|
mdl_bgMultiplyColorG = 0x8014B74E; // rom:0xE1E4E
|
||||||
|
Loading…
Reference in New Issue
Block a user