mirror of
https://github.com/pmret/papermario.git
synced 2024-11-08 12:02:30 +01:00
Upgrade to splat 0.9.0 (#730)
* changes for splat 0.9.0 * wip * git subrepo pull --branch=develop --force tools/splat subrepo: subdir: "tools/splat" merged: "2ff7357501" upstream: origin: "https://github.com/ethteck/splat.git" branch: "develop" commit: "2ff7357501" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" * OK * big_snowflakes gfx data * Jenkins? * cleanup * debuff effect gfx data * fix * more effect gfx data * dlabel * git subrepo pull --branch=experiment --force tools/splat subrepo: subdir: "tools/splat" merged: "1365775e09" upstream: origin: "https://github.com/ethteck/splat.git" branch: "experiment" commit: "1365775e09" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" * . * git subrepo pull --branch=experiment --force tools/splat subrepo: subdir: "tools/splat" merged: "6bd9fe1c4e" upstream: origin: "https://github.com/ethteck/splat.git" branch: "experiment" commit: "6bd9fe1c4e" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" * flower splash/trail gfx * throw_spiny gfx * disable_x and butterflies gfx data * draw_coin_sparkles * Warnings, cleanup * cleanin * attempt at test_item_player_collision * more gfx + cleanup * more effect gfx * func_8002D160 * update update_symbol_addrs and symbol_addrs * git subrepo pull --branch=develop --force tools/splat subrepo: subdir: "tools/splat" merged: "4914dc9029" upstream: origin: "https://github.com/ethteck/splat.git" branch: "develop" commit: "4914dc9029" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" * git subrepo pull --branch=master --force tools/splat subrepo: subdir: "tools/splat" merged: "aa71299594" upstream: origin: "https://github.com/ethteck/splat.git" branch: "master" commit: "aa71299594" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" * fix * fix regression * Add rabbitizer to requirements * warnings * symbol_addrs fixes
This commit is contained in:
parent
763b320bfb
commit
bae34c46ed
1
Jenkinsfile
vendored
1
Jenkinsfile
vendored
@ -13,6 +13,7 @@ pipeline {
|
||||
sh 'curl -L "https://github.com/ethteck/ido-static-recomp/releases/download/per-function/ido-5.3-recomp-ubuntu-latest.tar.gz" | tar zx -C tools/build/cc/ido5.3'
|
||||
sh 'curl -L "https://github.com/decompals/mips-gcc-2.7.2/releases/download/main/gcc-2.7.2-linux.tar.gz" | tar zx -C tools/build/cc/gcc2.7.2'
|
||||
sh 'curl -L "https://github.com/decompals/mips-binutils-2.6/releases/download/main/binutils-2.6-linux.tar.gz" | tar zx -C tools/build/cc/gcc2.7.2'
|
||||
sh 'pip install -r requirements.txt'
|
||||
sh './configure'
|
||||
}
|
||||
}
|
||||
|
@ -2439,4 +2439,20 @@ typedef struct FoldImageRecPart {
|
||||
/* 0x11 */ char unk_11[0x7];
|
||||
} FoldImageRecPart; // size = 0x18
|
||||
|
||||
typedef struct FoldImageRec {
|
||||
/* 0x00 */ s8* raster;
|
||||
/* 0x04 */ s8* palette;
|
||||
/* 0x08 */ u16 width;
|
||||
/* 0x0A */ u16 height;
|
||||
/* 0x0C */ s16 xOffset;
|
||||
/* 0x0E */ s16 yOffset;
|
||||
/* 0x10 */ u8 unk_10;
|
||||
/* 0x11 */ char unk_11[0x7];
|
||||
/* 0x18 */ s16 unk_18;
|
||||
/* 0x1A */ char unk_1A[0x4];
|
||||
/* 0x1E */ s16 unk_1E;
|
||||
/* 0x20 */ char unk_20[0x4];
|
||||
/* 0x24 */ u8 alphaMultiplier;
|
||||
} FoldImageRec; // size = 0x25
|
||||
|
||||
#endif
|
||||
|
@ -434,6 +434,11 @@ typedef struct AttackResultTextFXData {
|
||||
/* 0x34 */ f32 unk_34;
|
||||
} AttackResultTextFXData; // size = 0x38
|
||||
|
||||
typedef struct GotItemOutlineFXData {
|
||||
/* 0x00 */ char unk_00[0x14];
|
||||
/* 0x14 */ s32 unk_14;
|
||||
} GotItemOutlineFXData; // size = ???
|
||||
|
||||
typedef struct SmallGoldSparkleFXData {
|
||||
/* 0x00 */ s32 unk_00;
|
||||
/* 0x04 */ s32 unk_04;
|
||||
|
@ -786,6 +786,7 @@ void entity_base_block_init(Entity* entity);
|
||||
s32 entity_start_script(Entity* entity);
|
||||
void remove_item_entity_by_index(s32 index);
|
||||
void set_entity_commandlist(Entity* entity, s32* entityScript);
|
||||
s32 func_800DFCF4(void);
|
||||
void func_800EF3E4(void);
|
||||
void func_80268858(void);
|
||||
void func_80269118(void);
|
||||
|
@ -7,3 +7,7 @@ ninja_syntax
|
||||
msgpack
|
||||
pylibyaml
|
||||
tqdm
|
||||
spimdisasm
|
||||
pygfxd
|
||||
intervaltree
|
||||
rabbitizer
|
||||
|
@ -1,15 +1,15 @@
|
||||
#include "common.h"
|
||||
|
||||
extern void(*D_8004AA85)(void);
|
||||
extern void(*obfuscated_create_audio_system)(void);
|
||||
|
||||
void func_80200000(void) {
|
||||
u32 t0 = 0xAC29007B;
|
||||
u32 t1 = 0xB00006A8;
|
||||
void(*create_audio_subsystem)(void) = &D_8004AA85;
|
||||
void(*create_audio_system)(void) = &obfuscated_create_audio_system;
|
||||
|
||||
while (IO_READ(PI_STATUS_REG) & 3);
|
||||
|
||||
t0 -= IO_READ(t1 - 0x1C8);
|
||||
create_audio_subsystem += t0;
|
||||
create_audio_subsystem();
|
||||
create_audio_system += t0;
|
||||
create_audio_system();
|
||||
}
|
||||
|
@ -3,12 +3,12 @@
|
||||
#include "ld_addrs.h"
|
||||
#include "mips.h"
|
||||
|
||||
extern s32 D_7012BC11[];
|
||||
extern s32 obfuscated_general_heap_create[];
|
||||
|
||||
void func_802AE000_316C00(void) {
|
||||
s32(*readFunc)(OSPiHandle*, u32, u32*) = osEPiReadIo;
|
||||
s32 seed = 0x3C016C07 + 0xFEFEFEF;
|
||||
HeapNode*(*generalHeapCreate)(void) = D_7012BC11; // general_heap_create - 0xFEFEFEF
|
||||
HeapNode*(*generalHeapCreate)(void) = obfuscated_general_heap_create; // general_heap_create - 0xFEFEFEF
|
||||
u32 hash = 0;
|
||||
u32 thisInsn;
|
||||
u32* it;
|
||||
|
@ -2,12 +2,12 @@
|
||||
#include "ld_addrs.h"
|
||||
#include "mips.h"
|
||||
|
||||
extern s32 D_80026AC7[];
|
||||
extern s32 obfuscated_load_engine_data[];
|
||||
|
||||
void func_80200080(void) {
|
||||
s32 seed = 0x3C01A775;
|
||||
u32 thisInsn = 0xB0018FFC;
|
||||
HeapNode*(*load_engine_data)(s32) = D_80026AC7; // load_engine_data - ????????
|
||||
HeapNode*(*load_engine_data)(s32) = obfuscated_load_engine_data; // load_engine_data - ????????
|
||||
s32 hash = 0;
|
||||
u32 prevInsn;
|
||||
u32* it;
|
||||
|
@ -3,12 +3,12 @@
|
||||
#include "ld_addrs.h"
|
||||
#include "mips.h"
|
||||
|
||||
extern s32 D_7012ACA1[];
|
||||
extern s32 obfuscated_battle_heap_create[];
|
||||
|
||||
void func_802AE000(void) {
|
||||
s32(*readFunc)(OSPiHandle*, u32, u32*) = osEPiReadIo;
|
||||
s32 seed = 0x33F50000;
|
||||
UNK_FUN_PTR(battle_heap_create) = D_7012ACA1;
|
||||
UNK_FUN_PTR(battle_heap_create) = obfuscated_battle_heap_create;
|
||||
u32 hash = 0;
|
||||
u32 thisInsn;
|
||||
u32* it;
|
||||
|
74
src/8560.c
74
src/8560.c
@ -1,3 +1,75 @@
|
||||
#include "common.h"
|
||||
#include "nu/nusys.h"
|
||||
#include "ld_addrs.h"
|
||||
#include "mips.h"
|
||||
|
||||
INCLUDE_ASM(s32, "8560", func_8002D160);
|
||||
extern s8 D_F79DDD0F[];
|
||||
extern s8 D_7599F6D8[];
|
||||
|
||||
void func_8002D160(void) {
|
||||
s32 (*readFunc)(OSPiHandle*, u32, u32*);
|
||||
s32 (*readFunc2)(OSPiHandle*, u32, u32*);
|
||||
s8* vramDest = D_7599F6D8;
|
||||
s8* romStart = D_F79DDD0F;
|
||||
s32 seed;
|
||||
u32 hash;
|
||||
u32 thisInsn;
|
||||
u32 thisInsn2;
|
||||
u32 prevInsn;
|
||||
u8* it;
|
||||
|
||||
// vramDest
|
||||
readFunc = osEPiReadIo;
|
||||
seed = 0x0B112D28;
|
||||
hash = 0;
|
||||
readFunc(nuPiCartHandle, 0xB0000D10, &thisInsn);
|
||||
seed -= thisInsn;
|
||||
prevInsn = 0;
|
||||
|
||||
for (it = _316D90_ROM_START; it < _316D90_ROM_END; it += 4) {
|
||||
readFunc(nuPiCartHandle, (u32)it, &thisInsn);
|
||||
hash += LOWER(thisInsn) + UPPER(thisInsn);
|
||||
|
||||
if (OPCODE(prevInsn) == LUI && (OPCODE(thisInsn) == ADDIU || OPCODE(thisInsn) == LW)) {
|
||||
if (GET_RS(thisInsn) == GET_RT(prevInsn) && GET_RS(thisInsn) == GET_RT(thisInsn)) {
|
||||
hash -= LOWER(thisInsn);
|
||||
hash -= LOWER(prevInsn);
|
||||
}
|
||||
}
|
||||
|
||||
if (OPCODE(thisInsn) == JAL) {
|
||||
hash -= LOWER(thisInsn) + (UPPER(thisInsn) & 0xFC00);
|
||||
}
|
||||
|
||||
prevInsn = thisInsn;
|
||||
}
|
||||
vramDest += seed + 0x2A4EB6 - hash;
|
||||
|
||||
// romStart
|
||||
readFunc2 = osEPiReadIo;
|
||||
seed = 0x18F414AB;
|
||||
hash = 0;
|
||||
readFunc2(nuPiCartHandle, 0xB0000E38, &thisInsn2);
|
||||
seed -= thisInsn2;
|
||||
prevInsn = 0;
|
||||
|
||||
for (it = _316F30_ROM_START; it < _316F30_ROM_END; it += 4) {
|
||||
readFunc2(nuPiCartHandle, (u32)it, &thisInsn2);
|
||||
hash += LOWER(thisInsn2) + UPPER(thisInsn2);
|
||||
|
||||
if (OPCODE(prevInsn) == LUI && (OPCODE(thisInsn2) == ADDIU || OPCODE(thisInsn2) == LW)) {
|
||||
if (GET_RS(thisInsn2) == GET_RT(prevInsn) && GET_RS(thisInsn2) == GET_RT(thisInsn2)) {
|
||||
hash -= LOWER(thisInsn2);
|
||||
hash -= LOWER(prevInsn);
|
||||
}
|
||||
}
|
||||
|
||||
if (OPCODE(thisInsn2) == JAL) {
|
||||
hash -= LOWER(thisInsn2) + (UPPER(thisInsn2) & 0xFC00);
|
||||
}
|
||||
prevInsn = thisInsn2;
|
||||
}
|
||||
romStart += seed + 0xED41C - hash;
|
||||
|
||||
dma_copy(romStart, _316F30_ROM_END, vramDest);
|
||||
}
|
||||
|
167
src/C50A0.c
167
src/C50A0.c
@ -1,27 +1,37 @@
|
||||
#include "common.h"
|
||||
#include "effects.h"
|
||||
#include "hud_element.h"
|
||||
#include "pause/pause_common.h"
|
||||
#include "world/partners.h"
|
||||
#include "sparkle_script.h"
|
||||
|
||||
#define MAX_ITEM_ENTITIES 256
|
||||
|
||||
extern SparkleScript SparkleScript_Coin;
|
||||
|
||||
extern Lights1 D_8014C6C8;
|
||||
|
||||
extern s32 ItemEntitiesCreated;
|
||||
extern s32 D_80155D80;
|
||||
extern s32 ItemEntityAlternatingSpawn;
|
||||
extern s32 ItemEntityRenderGroup;
|
||||
extern s16 D_80155D8C;
|
||||
extern s16 D_80155D8E;
|
||||
extern s16 D_80155D90;
|
||||
extern ItemEntity* WorldItemEntities[MAX_ITEM_ENTITIES];
|
||||
extern ItemEntity* BattleItemEntities[MAX_ITEM_ENTITIES];
|
||||
extern ItemEntity** gCurrentItemEntities;
|
||||
extern s16 isPickingUpItem;
|
||||
extern s32 D_80155D80;
|
||||
extern s16 D_80155D8C;
|
||||
extern s16 D_80155D8E;
|
||||
extern s16 D_80155D90;
|
||||
extern s16 D_801565A6;
|
||||
extern s16 D_801565A8;
|
||||
extern PopupMenu D_801565B0;
|
||||
extern s32 D_801568E0;
|
||||
extern s32 D_801568E4;
|
||||
extern s32 D_801568E8;
|
||||
extern s32 D_801568EC;
|
||||
|
||||
extern SparkleScript SparkleScript_Coin;
|
||||
extern EffectInstance* D_801568F0;
|
||||
extern MessagePrintState* D_801568F4;
|
||||
extern s32 D_801568F8;
|
||||
|
||||
void item_entity_load(ItemEntity*);
|
||||
void item_entity_update(ItemEntity*);
|
||||
@ -239,7 +249,6 @@ void draw_coin_sparkles(ItemEntity* itemEntity) {
|
||||
|
||||
gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW);
|
||||
gDPPipeSync(gMasterGfxPos++);
|
||||
|
||||
}
|
||||
|
||||
ItemEntity* get_item_entity(s32 itemEntityIndex) {
|
||||
@ -884,7 +893,151 @@ void func_80133A94(s32 idx, s32 itemID) {
|
||||
item_entity_load(item);
|
||||
}
|
||||
|
||||
// float/stack crap
|
||||
#ifdef NON_EQUIVALENT
|
||||
s32 test_item_player_collision(ItemEntity* item) {
|
||||
PlayerStatus* playerStatus = &gPlayerStatus;
|
||||
PartnerActionStatus* partnerActionStatus = &gPartnerActionStatus;
|
||||
EncounterStatus* encounterStatus = &gCurrentEncounter;
|
||||
Camera* camera = &gCameras[gCurrentCameraID];
|
||||
s32 actionState;
|
||||
f32 t;
|
||||
f32 itemX;
|
||||
f32 itemY;
|
||||
f32 itemZ;
|
||||
f32 playerX;
|
||||
f32 playerY;
|
||||
f32 playerZ;
|
||||
|
||||
f32 sp10;
|
||||
f32 sp14;
|
||||
f32 sp1C;
|
||||
f32 sp20;
|
||||
f32 sp24;
|
||||
f32 zDiff;
|
||||
f32 temp_f14;
|
||||
f32 xDiff;
|
||||
f32 angle;
|
||||
s32 cond;
|
||||
f32 f1;
|
||||
|
||||
|
||||
actionState = playerStatus->actionState;
|
||||
|
||||
if (item->flags & 0x100) {
|
||||
item->flags &= ~0x100;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (gGameState != 2 && gGameState != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (encounterStatus->hitType == 5) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (item->flags & 0x200000) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (isPickingUpItem) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (item->flags & 0x40) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (get_time_freeze_mode() != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (partnerActionStatus->partnerActionState != 0 && partnerActionStatus->actingPartner == 9) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((actionState == 0x1D || actionState == 0x1E || actionState == 0x1F) && item->itemID != ITEM_COIN) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gOverrideFlags & 0x200000) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cond = FALSE;
|
||||
sp1C = playerStatus->colliderHeight / 2;
|
||||
playerX = playerStatus->position.x;
|
||||
playerY = playerStatus->position.y;
|
||||
playerZ = playerStatus->position.z;
|
||||
|
||||
sp20 = playerStatus->colliderDiameter / 4;
|
||||
if (playerStatus->spriteFacingAngle < 180.0f) {
|
||||
temp_f14 = clamp_angle(camera->currentYaw - 90.0f);
|
||||
} else {
|
||||
temp_f14 = clamp_angle(camera->currentYaw + 90.0f);
|
||||
}
|
||||
sp10 = playerX;
|
||||
sp24 = playerY;
|
||||
sp14 = playerZ;
|
||||
if (get_clamped_angle_diff(camera->currentYaw, temp_f14) < 0.0f) {
|
||||
angle = clamp_angle(camera->currentYaw - 90.0f);
|
||||
if (playerStatus->trueAnimation & 0x01000000) {
|
||||
angle = clamp_angle(angle + 30.0f);
|
||||
}
|
||||
} else {
|
||||
angle = clamp_angle(camera->currentYaw + 90.0f);
|
||||
if (playerStatus->trueAnimation & 0x01000000) {
|
||||
angle = clamp_angle(angle - 30.0f);
|
||||
}
|
||||
}
|
||||
add_vec2D_polar(&sp10, &sp14, 24.0f, angle);
|
||||
itemX = item->position.x;
|
||||
itemY = item->position.y;
|
||||
itemZ = item->position.z;
|
||||
t = 13.5f;
|
||||
xDiff = itemX - playerX;
|
||||
zDiff = itemZ - playerZ;
|
||||
f1 = sqrtf(SQ(xDiff) + SQ(zDiff));
|
||||
if (!(sp20 + t <= f1) &&
|
||||
!(itemY + 27.0f < playerY) &&
|
||||
!(playerY + sp1C < itemY))
|
||||
{
|
||||
cond = TRUE;
|
||||
}
|
||||
|
||||
if (playerStatus->actionState == 0x12 && (playerStatus->flags & 0x01000000)) {
|
||||
xDiff = itemX - sp10;
|
||||
zDiff = itemZ - sp14;
|
||||
f1 = sqrtf(SQ(xDiff) + SQ(zDiff));
|
||||
if (!(14.0f + t <= f1) &&
|
||||
!(itemY + 27.0f < sp24) &&
|
||||
!(sp24 + 18.0f < itemY))
|
||||
{
|
||||
cond = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (cond) {
|
||||
if (item->flags & 0x80) {
|
||||
if (D_801565A6 != 0) {
|
||||
D_801565A6--;
|
||||
return FALSE;
|
||||
} else {
|
||||
item->flags &= ~0x80;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (item->flags & 0x80) {
|
||||
item->flags &= ~0x80;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
INCLUDE_ASM(s32, "C50A0", test_item_player_collision);
|
||||
#endif
|
||||
|
||||
s32 test_item_entity_position(f32 x, f32 y, f32 z, f32 dist) {
|
||||
ItemEntity* item;
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#include "common/GetSelectedMoveID.inc.c"
|
||||
|
||||
ApiStatus SetActorLevelToZero(Evt* script, s32 isInitialCall) {
|
||||
ApiStatus N(SetActorLevelToZero)(Evt* script, s32 isInitialCall) {
|
||||
get_actor(script->owner1.actorID)->actorBlueprint->level = 0;
|
||||
return ApiStatus_DONE2;
|
||||
}
|
||||
@ -798,7 +798,7 @@ EvtScript N(fallOff) = {
|
||||
EVT_CALL(ResetAllActorSounds, ACTOR_SELF)
|
||||
EVT_CALL(GetActorSize, ACTOR_SELF, LW(0), LW(1))
|
||||
EVT_CALL(SetActorSize, ACTOR_SELF, 24, LW(1))
|
||||
EVT_CALL(SetActorLevelToZero)
|
||||
EVT_CALL(N(SetActorLevelToZero))
|
||||
EVT_RETURN
|
||||
EVT_END
|
||||
};
|
||||
|
@ -36,22 +36,6 @@ typedef struct FoldDataCache {
|
||||
/* 0x06 */ char unk_06[0x2];
|
||||
} FoldDataCache; // size = 0x8
|
||||
|
||||
typedef struct FoldImageRec {
|
||||
/* 0x00 */ s8* raster;
|
||||
/* 0x04 */ s8* palette;
|
||||
/* 0x08 */ u16 width;
|
||||
/* 0x0A */ u16 height;
|
||||
/* 0x0C */ s16 xOffset;
|
||||
/* 0x0E */ s16 yOffset;
|
||||
/* 0x10 */ u8 unk_10;
|
||||
/* 0x11 */ char unk_11[0x7];
|
||||
/* 0x18 */ s16 unk_18;
|
||||
/* 0x1A */ char unk_1A[0x4];
|
||||
/* 0x1E */ s16 unk_1E;
|
||||
/* 0x20 */ char unk_20[0x4];
|
||||
/* 0x24 */ u8 alphaMultiplier;
|
||||
} FoldImageRec; // size = 0x25
|
||||
|
||||
typedef struct FoldGfxDescriptor {
|
||||
/* 0x00 */ Vtx* vtx;
|
||||
/* 0x04 */ Gfx* gfx;
|
||||
|
@ -28,20 +28,20 @@ extern s32 D_801A6000;
|
||||
|
||||
EffectTableEntry gEffectTable[] = {
|
||||
/* 0x00 */ {},
|
||||
/* 0x01 */ FX_ENTRY(big_smoke_puff, _326410),
|
||||
/* 0x01 */ FX_ENTRY(big_smoke_puff, effect_gfx_big_smoke_puff),
|
||||
/* 0x02 */ {},
|
||||
/* 0x03 */ {},
|
||||
/* 0x04 */ {},
|
||||
/* 0x05 */ {},
|
||||
/* 0x06 */ FX_ENTRY(landing_dust, _328EA0),
|
||||
/* 0x07 */ FX_ENTRY(walking_dust, _328EA0),
|
||||
/* 0x08 */ FX_ENTRY(flower_splash, _32CEC0),
|
||||
/* 0x09 */ FX_ENTRY(flower_trail, _32CEC0),
|
||||
/* 0x0A */ FX_ENTRY(cloud_puff, _32EC50),
|
||||
/* 0x0B */ FX_ENTRY(cloud_trail, _32EC50),
|
||||
/* 0x0C */ FX_ENTRY(footprint, _32FB50),
|
||||
/* 0x0D */ FX_ENTRY(floating_flower, _330460),
|
||||
/* 0x0E */ FX_ENTRY(snowflake, _330F00),
|
||||
/* 0x08 */ FX_ENTRY(flower_splash, effect_gfx_flower_splash_trail),
|
||||
/* 0x09 */ FX_ENTRY(flower_trail, effect_gfx_flower_splash_trail),
|
||||
/* 0x0A */ FX_ENTRY(cloud_puff, effect_gfx_cloud_puff_trail),
|
||||
/* 0x0B */ FX_ENTRY(cloud_trail, effect_gfx_cloud_puff_trail),
|
||||
/* 0x0C */ FX_ENTRY(footprint, effect_gfx_footprint),
|
||||
/* 0x0D */ FX_ENTRY(floating_flower, effect_gfx_floating_flower),
|
||||
/* 0x0E */ FX_ENTRY(snowflake, effect_gfx_snowflake),
|
||||
/* 0x0F */ FX_ENTRY(star, _3326A0),
|
||||
/* 0x10 */ FX_ENTRY(emote, _334C70),
|
||||
/* 0x11 */ FX_ENTRY(sparkles, _337FC0),
|
||||
@ -57,7 +57,7 @@ EffectTableEntry gEffectTable[] = {
|
||||
/* 0x1B */ FX_ENTRY(got_item_outline, _345B40),
|
||||
/* 0x1C */ FX_ENTRY(spiky_white_aura, _34E770),
|
||||
/* 0x1D */ FX_ENTRY(smoke_impact, _328EA0),
|
||||
/* 0x1E */ FX_ENTRY(damage_indicator, _350220),
|
||||
/* 0x1E */ FX_ENTRY(damage_indicator, effect_gfx_damage_indicator),
|
||||
/* 0x1F */ FX_ENTRY(purple_ring, _352CE0),
|
||||
/* 0x20 */ FX_ENTRY(flame, _353BB0),
|
||||
/* 0x21 */ FX_ENTRY(stars_burst, _343040),
|
||||
@ -75,8 +75,8 @@ EffectTableEntry gEffectTable[] = {
|
||||
/* 0x2D */ FX_ENTRY(stars_spread, _360A30),
|
||||
/* 0x2E */ FX_ENTRY(steam_burst, _361670),
|
||||
/* 0x2F */ FX_ENTRY(stars_orbiting, _362C50),
|
||||
/* 0x30 */ FX_ENTRY(big_snowflakes, _3638C0),
|
||||
/* 0x31 */ FX_ENTRY(debuff, _364C00),
|
||||
/* 0x30 */ FX_ENTRY(big_snowflakes, effect_gfx_big_snowflakes),
|
||||
/* 0x31 */ FX_ENTRY(debuff, effect_gfx_debuff),
|
||||
/* 0x32 */ FX_ENTRY(green_impact, _3659B0),
|
||||
/* 0x33 */ FX_ENTRY(radial_shimmer, _366D60),
|
||||
/* 0x34 */ FX_ENTRY(ending_decals, _36AEE0),
|
||||
@ -92,7 +92,7 @@ EffectTableEntry gEffectTable[] = {
|
||||
/* 0x3E */ FX_ENTRY(blast, _37D9D0),
|
||||
/* 0x3F */ FX_ENTRY(fire_flower, _3803A0),
|
||||
/* 0x40 */ FX_ENTRY(recover, _381E00),
|
||||
/* 0x41 */ FX_ENTRY(disable_x, _3863B0),
|
||||
/* 0x41 */ FX_ENTRY(disable_x, effect_gfx_disable_x),
|
||||
/* 0x42 */ FX_ENTRY(bombette_breaking, _37D9D0),
|
||||
/* 0x43 */ FX_ENTRY(firework, _38A350),
|
||||
/* 0x44 */ FX_ENTRY(confetti, _38BBA0),
|
||||
@ -100,7 +100,7 @@ EffectTableEntry gEffectTable[] = {
|
||||
/* 0x46 */ FX_ENTRY_NUMBERED(46, _38E990),
|
||||
/* 0x47 */ FX_ENTRY(gather_magic, _38F710),
|
||||
/* 0x48 */ FX_ENTRY(attack_result_text, _3903D0),
|
||||
/* 0x49 */ FX_ENTRY(small_gold_sparkle, _392440),
|
||||
/* 0x49 */ FX_ENTRY(small_gold_sparkle, effect_gfx_small_gold_sparkle),
|
||||
/* 0x4A */ FX_ENTRY(flashing_box_shockwave, _3930A0),
|
||||
/* 0x4B */ FX_ENTRY(balloon, _394670),
|
||||
/* 0x4C */ FX_ENTRY(floating_rock, _3960F0),
|
||||
@ -112,7 +112,7 @@ EffectTableEntry gEffectTable[] = {
|
||||
/* 0x52 */ FX_ENTRY(energy_orb_wave, _3A4320),
|
||||
/* 0x53 */ FX_ENTRY(merlin_house_stars, _3A5BE0),
|
||||
/* 0x54 */ FX_ENTRY(quizmo_audience, _3A77A0),
|
||||
/* 0x55 */ FX_ENTRY(butterflies, _3AB030),
|
||||
/* 0x55 */ FX_ENTRY(butterflies, effect_gfx_butterflies),
|
||||
/* 0x56 */ FX_ENTRY(stat_change, _3AF700),
|
||||
/* 0x57 */ FX_ENTRY(snaking_static, _3B2D90),
|
||||
/* 0x58 */ FX_ENTRY(thunderbolt_ring, _3B46A0),
|
||||
@ -127,7 +127,7 @@ EffectTableEntry gEffectTable[] = {
|
||||
/* 0x61 */ FX_ENTRY(fright_jar, _3C1BA0),
|
||||
/* 0x62 */ FX_ENTRY(stop_watch, _3CB890),
|
||||
/* 0x63 */ FX_ENTRY_NUMBERED(63, _3CD6E0),
|
||||
/* 0x64 */ FX_ENTRY(throw_spiny, _3CFAF0),
|
||||
/* 0x64 */ FX_ENTRY(throw_spiny, effect_gfx_throw_spiny),
|
||||
/* 0x65 */ FX_ENTRY_NUMBERED(65, _3D11E0),
|
||||
/* 0x66 */ FX_ENTRY(tubba_heart_attack, _3D2580),
|
||||
/* 0x67 */ FX_ENTRY(whirlwind, _3D3930),
|
||||
|
@ -6,16 +6,17 @@ static f32 D_E0002788[10] = { 2.2f, 2.7f, 3.0f, 2.2f, 2.7f, 3.0f, 1.9f, 1.9f, 1.
|
||||
static f32 sPartScales[10] = { 1.4f, 1.3f, 1.2f, 1.3f, 1.4f, 1.3f, 1.6f, 1.6f, 1.6f, 1.6f };
|
||||
static f32 sPartYaws[10] = { 0.0f, 234.0f, 468.0f, 702.0f, 936.0f, 1260.0f, 1404.0f, 1638.0f, 1902.0f, 1976.0f };
|
||||
|
||||
extern Gfx D_09000FA0[];
|
||||
extern Gfx D_09001060[];
|
||||
extern Gfx D_09001120[];
|
||||
extern Gfx D_090011E0[];
|
||||
extern Gfx D_090012A0[];
|
||||
extern Gfx D_09001360[];
|
||||
extern Gfx D_09001420[];
|
||||
extern Gfx D_09000FA0_3273B0[];
|
||||
extern Gfx D_09001060_327470[];
|
||||
extern Gfx D_09001120_327530[];
|
||||
extern Gfx D_090011E0_3275F0[];
|
||||
extern Gfx D_090012A0_3276B0[];
|
||||
extern Gfx D_09001360_327770[];
|
||||
extern Gfx D_09001420_327830[];
|
||||
|
||||
static Gfx* sDlists[7] = {
|
||||
D_09000FA0, D_09001060, D_09001120, D_090011E0, D_090012A0, D_09001360, D_09001420
|
||||
D_09000FA0_3273B0, D_09001060_327470, D_09001120_327530, D_090011E0_3275F0, D_090012A0_3276B0, D_09001360_327770,
|
||||
D_09001420_327830
|
||||
};
|
||||
|
||||
void big_smoke_puff_init(EffectInstance* effect);
|
||||
|
@ -1,12 +1,12 @@
|
||||
#include "common.h"
|
||||
#include "effects_internal.h"
|
||||
|
||||
extern Gfx D_09000900[];
|
||||
extern Gfx D_090009E8[];
|
||||
extern Gfx D_09000A10[];
|
||||
extern Gfx D_09000900_3641C0[];
|
||||
extern Gfx D_090009E8_3642A8[];
|
||||
extern Gfx D_09000A10_3642D0[];
|
||||
|
||||
Gfx* D_E0060730[] = { D_090009E8, D_09000A10 };
|
||||
Gfx* D_E0060738[] = { D_09000900, D_09000900 };
|
||||
Gfx* D_E0060730[] = { D_090009E8_3642A8, D_09000A10_3642D0 };
|
||||
Gfx* D_E0060738[] = { D_09000900_3641C0, D_09000900_3641C0 };
|
||||
|
||||
void big_snowflakes_init(EffectInstance* effect);
|
||||
void big_snowflakes_update(EffectInstance* effect);
|
||||
|
@ -1,27 +1,28 @@
|
||||
#include "common.h"
|
||||
#include "effects_internal.h"
|
||||
|
||||
extern Vtx D_09002D40[][6]; // TODO confirm this type is correct
|
||||
extern Gfx D_09003880[];
|
||||
extern Gfx D_090038F8[];
|
||||
extern Gfx D_09003968[];
|
||||
extern Gfx D_090039D8[];
|
||||
extern Gfx D_09003A48[];
|
||||
extern Gfx D_09003AB8[];
|
||||
extern Gfx D_09003B28[];
|
||||
extern Gfx D_09003B98[];
|
||||
extern Gfx D_09003C08[];
|
||||
extern Gfx D_09003C78[];
|
||||
extern Gfx D_09003CE8[];
|
||||
extern Gfx D_09003D58[];
|
||||
extern Gfx D_09003DC8[];
|
||||
extern Vtx D_09002D40_3ADD70[][6]; // TODO confirm this type is correct
|
||||
extern Gfx D_09003880_3AE8B0[];
|
||||
extern Gfx D_090038F8_3AE928[];
|
||||
extern Gfx D_09003968_3AE998[];
|
||||
extern Gfx D_090039D8_3AEA08[];
|
||||
extern Gfx D_09003A48_3AEA78[];
|
||||
extern Gfx D_09003AB8_3AEAE8[];
|
||||
extern Gfx D_09003B28_3AEB58[];
|
||||
extern Gfx D_09003B98_3AEBC8[];
|
||||
extern Gfx D_09003C08_3AEC38[];
|
||||
extern Gfx D_09003C78_3AECA8[];
|
||||
extern Gfx D_09003CE8_3AED18[];
|
||||
extern Gfx D_09003D58_3AED88[];
|
||||
extern Gfx D_09003DC8_3AEDF8[];
|
||||
|
||||
Gfx* D_E00AA6C0[11] = {
|
||||
D_090038F8, D_09003968, D_090039D8, D_09003A48, D_09003AB8, D_09003B28, D_09003B98, D_09003C08, D_09003C78, D_09003CE8, D_09003D58
|
||||
D_090038F8_3AE928, D_09003968_3AE998, D_090039D8_3AEA08, D_09003A48_3AEA78, D_09003AB8_3AEAE8, D_09003B28_3AEB58, D_09003B98_3AEBC8, D_09003C08_3AEC38, D_09003C78_3AECA8, D_09003CE8_3AED18, D_09003D58_3AED88
|
||||
};
|
||||
|
||||
s8 D_E00AA6EC[] = {
|
||||
-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
void butterflies_init(EffectInstance* effect);
|
||||
void butterflies_update(EffectInstance* effect);
|
||||
@ -181,10 +182,10 @@ void butterflies_appendGfx(void* effect) {
|
||||
|
||||
gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gDPSetPrimColor(gMasterGfxPos++, 0, 0, primColor, primColor, primColor, 255);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09003880);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09003880_3AE8B0);
|
||||
gSPDisplayList(gMasterGfxPos++, D_E00AA6C0[type]);
|
||||
gSPVertex(gMasterGfxPos++, &D_09002D40[data->unk_2C], 6, 0);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09003DC8);
|
||||
gSPVertex(gMasterGfxPos++, &D_09002D40_3ADD70[data->unk_2C], 6, 0);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09003DC8_3AEDF8);
|
||||
gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW);
|
||||
gDPPipeSync(gMasterGfxPos++);
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "common.h"
|
||||
#include "effects_internal.h"
|
||||
|
||||
extern Gfx D_090000E0[];
|
||||
extern Gfx D_090001B8[];
|
||||
extern Gfx D_090000E0_32ED30[];
|
||||
extern Gfx D_090001B8_32EE08[];
|
||||
|
||||
void cloud_puff_init(EffectInstance* effect);
|
||||
void cloud_puff_update(EffectInstance* effect);
|
||||
@ -121,7 +121,7 @@ void cloud_puff_appendGfx(void* effect) {
|
||||
|
||||
gDPPipeSync(gMasterGfxPos++);
|
||||
gSPSegment(gMasterGfxPos++, 0x09, VIRTUAL_TO_PHYSICAL(effectTemp->graphics->data));
|
||||
gSPDisplayList(gMasterGfxPos++, D_090000E0);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090000E0_32ED30);
|
||||
|
||||
for (i = 0; i < effectTemp->numParts; i++, part++) {
|
||||
if (part->alive) {
|
||||
@ -134,7 +134,7 @@ void cloud_puff_appendGfx(void* effect) {
|
||||
gDPSetPrimColor(gMasterGfxPos++, 0, 0, 112, 96, 24, part->alpha);
|
||||
gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++],
|
||||
G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090001B8);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090001B8_32EE08);
|
||||
gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW);
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "common.h"
|
||||
#include "effects_internal.h"
|
||||
|
||||
extern Gfx D_090000E0[];
|
||||
extern Gfx D_090001B8[];
|
||||
extern Gfx D_090000E0_32ED30[];
|
||||
extern Gfx D_090001B8_32EE08[];
|
||||
|
||||
void cloud_trail_init(EffectInstance* effect);
|
||||
void cloud_trail_update(EffectInstance* effect);
|
||||
@ -122,7 +122,7 @@ void cloud_trail_appendGfx(void* effect) {
|
||||
|
||||
gDPPipeSync(gMasterGfxPos++);
|
||||
gSPSegment(gMasterGfxPos++, 0x09, VIRTUAL_TO_PHYSICAL(effectTemp->graphics->data));
|
||||
gSPDisplayList(gMasterGfxPos++, D_090000E0);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090000E0_32ED30);
|
||||
|
||||
for (i = 0; i < effectTemp->numParts; i++, part++) {
|
||||
if (part->alive) {
|
||||
@ -137,7 +137,7 @@ void cloud_trail_appendGfx(void* effect) {
|
||||
gDPSetPrimColor(gMasterGfxPos++, 0, 0, 112, 96, 24, part->alpha);
|
||||
gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++],
|
||||
G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090001B8);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090001B8_32EE08);
|
||||
gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW);
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +1,34 @@
|
||||
#include "common.h"
|
||||
#include "effects_internal.h"
|
||||
|
||||
extern Gfx D_09001D40[];
|
||||
extern Gfx D_09001DE0[];
|
||||
extern Gfx D_09001E50[];
|
||||
extern Gfx D_09001E90[];
|
||||
extern Gfx D_09001ED0[];
|
||||
extern Gfx D_09001F10[];
|
||||
extern Gfx D_09001F50[];
|
||||
extern Gfx D_09001F90[];
|
||||
extern Gfx D_09001FD0[];
|
||||
extern Gfx D_09002010[];
|
||||
extern Gfx D_09002050[];
|
||||
extern Gfx D_09002090[];
|
||||
extern Gfx D_090020D0[];
|
||||
extern Gfx D_09002110[];
|
||||
extern Gfx D_09002150[];
|
||||
extern Gfx D_09002160[];
|
||||
extern Gfx D_09002170[];
|
||||
extern Gfx D_09002180[];
|
||||
extern Gfx D_090021A8[];
|
||||
extern Gfx D_09002190[];
|
||||
extern Gfx D_090021C0[];
|
||||
extern Gfx D_090021E0[];
|
||||
extern Gfx D_09002200[];
|
||||
extern Gfx D_09001D40_351F60[];
|
||||
extern Gfx D_09001DE0_352000[];
|
||||
extern Gfx D_09001E50_352070[];
|
||||
extern Gfx D_09001E90_3520B0[];
|
||||
extern Gfx D_09001ED0_3520F0[];
|
||||
extern Gfx D_09001F10_352130[];
|
||||
extern Gfx D_09001F50_352170[];
|
||||
extern Gfx D_09001F90_3521B0[];
|
||||
extern Gfx D_09001FD0_3521F0[];
|
||||
extern Gfx D_09002010_352230[];
|
||||
extern Gfx D_09002050_352270[];
|
||||
extern Gfx D_09002090_3522B0[];
|
||||
extern Gfx D_090020D0_3522F0[];
|
||||
extern Gfx D_09002110_352330[];
|
||||
extern Gfx D_09002150_352370[];
|
||||
extern Gfx D_09002160_352380[];
|
||||
extern Gfx D_09002170_352390[];
|
||||
extern Gfx D_09002180_3523A0[];
|
||||
extern Gfx D_09002190_3523B0[];
|
||||
extern Gfx D_090021A8_3523C8[];
|
||||
extern Gfx D_090021C0_3523E0[];
|
||||
extern Gfx D_090021E0_352400[];
|
||||
extern Gfx D_09002200_352420[];
|
||||
|
||||
Gfx* D_E003CCA0[] = {
|
||||
D_09001E50, D_09001E90, D_09001ED0, D_09001F10,
|
||||
D_09001F50, D_09001F90, D_09001FD0, D_09002010,
|
||||
D_09002050, D_09002090, D_090020D0, D_09002110
|
||||
D_09001E50_352070, D_09001E90_3520B0, D_09001ED0_3520F0, D_09001F10_352130,
|
||||
D_09001F50_352170, D_09001F90_3521B0, D_09001FD0_3521F0, D_09002010_352230,
|
||||
D_09002050_352270, D_09002090_3522B0, D_090020D0_3522F0, D_09002110_352330
|
||||
};
|
||||
|
||||
u8 D_E003CCD0[] = {
|
||||
@ -224,20 +224,20 @@ void func_E003C498(EffectInstance* effect) {
|
||||
for (i = 1; i < effect->numParts; i++, part--) {
|
||||
s32 index = (i + spA0);
|
||||
gDPSetPrimColor(gMasterGfxPos++, 0, 0, D_E003CCF8[index % 12].r, D_E003CCF8[index % 12].g, D_E003CCF8[index % 12].b, part->alpha);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09001D40);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09001D40_351F60);
|
||||
if (i == spA4) {
|
||||
shim_guPositionF(sp20, 0.0f, 0.0f, 0.0f, part->unk_38, part->unk_10.x, part->unk_10.y, part->unk_10.z);
|
||||
shim_guMtxF2L(sp20, &gDisplayContext->matrixStack[gMatrixListPos]);
|
||||
gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002150);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002150_352370);
|
||||
gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW);
|
||||
shim_guPositionF(sp20, 0.0f, 0.0f, 0.0f, part->unk_38, (part->unk_10.x + part->unk_04.x) * 0.5, (part->unk_10.y + part->unk_04.y) * 0.5, (part->unk_10.z + part->unk_04.z) * 0.5);
|
||||
shim_guMtxF2L(sp20, &gDisplayContext->matrixStack[gMatrixListPos]);
|
||||
gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002160);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002160_352380);
|
||||
gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW);
|
||||
}
|
||||
gSPDisplayList(gMasterGfxPos++, D_09001D40);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09001D40_351F60);
|
||||
shim_guTranslateF(sp20, part->unk_04.x, part->unk_04.y, part->unk_04.z);
|
||||
shim_guMtxF2L(sp20, &gDisplayContext->matrixStack[gMatrixListPos]);
|
||||
gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW);
|
||||
@ -246,27 +246,27 @@ void func_E003C498(EffectInstance* effect) {
|
||||
gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW);
|
||||
|
||||
if (i == spA4) {
|
||||
gSPDisplayList(gMasterGfxPos++, &D_09002170);
|
||||
gSPDisplayList(gMasterGfxPos++, &D_09002170_352390);
|
||||
} else {
|
||||
gSPDisplayList(gMasterGfxPos++, &D_09002180);
|
||||
gSPDisplayList(gMasterGfxPos++, &D_09002180_3523A0);
|
||||
}
|
||||
if (i == spA4) {
|
||||
gSPDisplayList(gMasterGfxPos++, D_090021A8);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090021A8_3523C8);
|
||||
gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09001DE0);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090021E0_352400);
|
||||
if (spA8 < 10) {
|
||||
gSPDisplayList(gMasterGfxPos++, D_E003CCA0[i]);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090021C0);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090021C0_3523E0);
|
||||
} else {
|
||||
s32 temp = spA8 % 10;
|
||||
s32 temp2 = spA8 / 10;
|
||||
gSPDisplayList(gMasterGfxPos++, D_E003CCA0[temp]);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002200);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002200_352420);
|
||||
gSPDisplayList(gMasterGfxPos++, D_E003CCA0[temp2]);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090021E0);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090021E0_352400);
|
||||
}
|
||||
} else {
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002190);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002190_3523B0);
|
||||
gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW);
|
||||
}
|
||||
gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW);
|
||||
|
@ -1,11 +1,11 @@
|
||||
#include "common.h"
|
||||
#include "effects_internal.h"
|
||||
|
||||
extern Gfx D_09000240[];
|
||||
extern Gfx D_090002E8[];
|
||||
extern Gfx D_09000240_364E40[];
|
||||
extern Gfx D_090002E8_364EE8[];
|
||||
|
||||
Gfx* D_E00628C0[] = { D_090002E8 };
|
||||
Gfx* D_E00628C4[] = { D_09000240 };
|
||||
Gfx* D_E00628C0[] = { D_090002E8_364EE8 };
|
||||
Gfx* D_E00628C4[] = { D_09000240_364E40 };
|
||||
|
||||
void debuff_init(EffectInstance* effect);
|
||||
void debuff_update(EffectInstance* effect);
|
||||
|
@ -1,29 +1,29 @@
|
||||
#include "common.h"
|
||||
#include "effects_internal.h"
|
||||
|
||||
extern Gfx D_09002100[];
|
||||
extern Gfx D_09002198[];
|
||||
extern Gfx D_09002230[];
|
||||
extern Gfx D_09002250[];
|
||||
extern Gfx D_09002270[];
|
||||
extern Gfx D_09002290[];
|
||||
extern Gfx D_090022B0[];
|
||||
extern Gfx D_09002320[];
|
||||
extern Gfx D_09002360[];
|
||||
extern Gfx D_090023A0[];
|
||||
extern Gfx D_090023E0[];
|
||||
extern Gfx D_09002420[];
|
||||
extern Gfx D_09002460[];
|
||||
extern Gfx D_090024A0[];
|
||||
extern Gfx D_090024E0[];
|
||||
extern Gfx D_09002520[];
|
||||
extern Gfx D_09002560[];
|
||||
extern Gfx D_090025A0[];
|
||||
extern Gfx D_090025E0[];
|
||||
extern Gfx D_09002100_3884B0[];
|
||||
extern Gfx D_09002198_388548[];
|
||||
extern Gfx D_09002230_3885E0[];
|
||||
extern Gfx D_09002250_388600[];
|
||||
extern Gfx D_09002270_388620[];
|
||||
extern Gfx D_09002290_388640[];
|
||||
extern Gfx D_090022B0_388660[];
|
||||
extern Gfx D_09002320_3886D0[];
|
||||
extern Gfx D_09002360_388710[];
|
||||
extern Gfx D_090023A0_388750[];
|
||||
extern Gfx D_090023E0_388790[];
|
||||
extern Gfx D_09002420_3887D0[];
|
||||
extern Gfx D_09002460_388810[];
|
||||
extern Gfx D_090024A0_388850[];
|
||||
extern Gfx D_090024E0_388890[];
|
||||
extern Gfx D_09002520_3888D0[];
|
||||
extern Gfx D_09002560_388910[];
|
||||
extern Gfx D_090025A0_388950[];
|
||||
extern Gfx D_090025E0_388990[];
|
||||
|
||||
Gfx* D_E0082D00[] = {
|
||||
D_09002320, D_09002360, D_090023A0, D_090023E0, D_09002420, D_09002460, D_090024A0, D_090024E0, D_09002520,
|
||||
D_09002560, D_090025A0, D_090025E0
|
||||
D_09002320_3886D0, D_09002360_388710, D_090023A0_388750, D_090023E0_388790, D_09002420_3887D0, D_09002460_388810,
|
||||
D_090024A0_388850, D_090024E0_388890, D_09002520_3888D0, D_09002560_388910, D_090025A0_388950, D_090025E0_388990
|
||||
};
|
||||
|
||||
void disable_x_init(EffectInstance* effect);
|
||||
@ -269,12 +269,12 @@ void func_E00828B4(EffectInstance* effect) {
|
||||
for (i = 1; i < effect->numParts; i++, data++) {
|
||||
if (unk_38 > 0 || type == 10) {
|
||||
if (type == 1) {
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002198);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002198_388548);
|
||||
} else {
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002100);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002100_3884B0);
|
||||
}
|
||||
func_E00826C4(data);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002230);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002230_3885E0);
|
||||
gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW);
|
||||
}
|
||||
}
|
||||
@ -296,19 +296,19 @@ void func_E0082A84(EffectInstance* effect) {
|
||||
for (i = 1; i < effect->numParts; i++, data++) {
|
||||
func_E00826C4(data);
|
||||
if (unk_38 > 0) {
|
||||
gSPDisplayList(gMasterGfxPos++, D_090022B0);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090022B0_388660);
|
||||
if (unk_38 < 10) {
|
||||
gSPDisplayList(gMasterGfxPos++, D_E0082D00[unk_38]);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002250);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002250_388600);
|
||||
} else {
|
||||
s32 ones = unk_38 % 10;
|
||||
s32 tens = unk_38 / 10;
|
||||
|
||||
gSPDisplayList(gMasterGfxPos++, D_E0082D00[ones]);
|
||||
gSPDisplayList(gMasterGfxPos++, D_E0082D00[tens]);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002290);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002290_388640);
|
||||
gSPDisplayList(gMasterGfxPos++, D_E0082D00[tens]);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002270);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09002270_388620);
|
||||
}
|
||||
}
|
||||
gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW);
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
s32 D_E001A610 = 0;
|
||||
|
||||
extern Gfx D_090002F0[];
|
||||
extern Gfx D_090002F0_330750[];
|
||||
|
||||
void floating_flower_init(EffectInstance* effect);
|
||||
void floating_flower_update(EffectInstance* effect);
|
||||
@ -164,7 +164,7 @@ void floating_flower_appendGfx(void* effect) {
|
||||
|
||||
if (alpha != 0) {
|
||||
gDPSetPrimColor(gMasterGfxPos++, 0, 0, 0, 0, 0, alpha);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090002F0);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090002F0_330750);
|
||||
gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "common.h"
|
||||
#include "effects_internal.h"
|
||||
|
||||
extern Gfx D_09000E08[];
|
||||
extern Gfx D_09000E08_32DCC8[];
|
||||
|
||||
void flower_splash_init(EffectInstance* effect);
|
||||
void flower_splash_update(EffectInstance* effect);
|
||||
@ -147,7 +147,7 @@ void flower_splash_appendGfx(void* effect) {
|
||||
|
||||
for (i = 0; i < effectTemp->numParts; i++, data++) {
|
||||
if (data->unk_00 != 0) {
|
||||
Gfx* dlist = D_09000E08;
|
||||
Gfx* dlist = D_09000E08_32DCC8;
|
||||
|
||||
gDisplayContext->matrixStack[gMatrixListPos] = data->unk_30;
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "common.h"
|
||||
#include "effects_internal.h"
|
||||
|
||||
extern Gfx D_09000E20[];
|
||||
extern Gfx D_09000E38[];
|
||||
extern Gfx D_09000E20_32DCE0[];
|
||||
extern Gfx D_09000E38_32DCF8[];
|
||||
|
||||
void flower_trail_init(EffectInstance* effect);
|
||||
void flower_trail_update(EffectInstance* effect);
|
||||
@ -167,9 +167,9 @@ void flower_trail_appendGfx(void* effect) {
|
||||
for (i = 0; i < effectTemp->numParts; i++, part++) {
|
||||
if (part->unk_00 != 0) {
|
||||
if (part->unk_09 != 0) {
|
||||
dlist = D_09000E20;
|
||||
dlist = D_09000E20_32DCE0;
|
||||
} else {
|
||||
dlist = D_09000E38;
|
||||
dlist = D_09000E38_32DCF8;
|
||||
}
|
||||
|
||||
gDisplayContext->matrixStack[gMatrixListPos] = part->unk_30;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "common.h"
|
||||
#include "effects_internal.h"
|
||||
|
||||
extern Gfx D_09000240[];
|
||||
extern Gfx D_09000240_32FD90[];
|
||||
|
||||
void func_E0018000(FootprintFXData* part);
|
||||
void footprint_init(EffectInstance* effect);
|
||||
@ -124,7 +124,7 @@ void footprint_appendGfx(void* effect) {
|
||||
|
||||
for (i = 0; i < effectTemp->numParts; i++, part++) {
|
||||
if (part->alive) {
|
||||
Gfx* dlist = D_09000240;
|
||||
Gfx* dlist = D_09000240_32FD90;
|
||||
|
||||
gDisplayContext->matrixStack[gMatrixListPos] = part->mtx;
|
||||
|
||||
|
28
src/effects/gfx/big_smoke_puff.c
Normal file
28
src/effects/gfx/big_smoke_puff.c
Normal file
@ -0,0 +1,28 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "effects/gfx/D_09000000_326410.png.inc.c"
|
||||
#include "effects/gfx/D_09000000_326410.pal.inc.c"
|
||||
#include "effects/gfx/D_09000220_326630.png.inc.c"
|
||||
#include "effects/gfx/D_09000220_326630.pal.inc.c"
|
||||
#include "effects/gfx/D_09000440_326850.png.inc.c"
|
||||
#include "effects/gfx/D_09000440_326850.pal.inc.c"
|
||||
#include "effects/gfx/D_09000660_326A70.png.inc.c"
|
||||
#include "effects/gfx/D_09000660_326A70.pal.inc.c"
|
||||
#include "effects/gfx/D_09000880_326C90.png.inc.c"
|
||||
#include "effects/gfx/D_09000880_326C90.pal.inc.c"
|
||||
#include "effects/gfx/D_09000AA0_326EB0.png.inc.c"
|
||||
#include "effects/gfx/D_09000AA0_326EB0.pal.inc.c"
|
||||
#include "effects/gfx/D_09000CC0_3270D0.png.inc.c"
|
||||
#include "effects/gfx/D_09000CC0_3270D0.pal.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09000EE0_3272F0.vtx.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09000F20_327330.gfx.inc.c"
|
||||
#include "effects/gfx/D_09000F88_327398.gfx.inc.c"
|
||||
#include "effects/gfx/D_09000FA0_3273B0.gfx.inc.c"
|
||||
#include "effects/gfx/D_09001060_327470.gfx.inc.c"
|
||||
#include "effects/gfx/D_09001120_327530.gfx.inc.c"
|
||||
#include "effects/gfx/D_090011E0_3275F0.gfx.inc.c"
|
||||
#include "effects/gfx/D_090012A0_3276B0.gfx.inc.c"
|
||||
#include "effects/gfx/D_09001360_327770.gfx.inc.c"
|
||||
#include "effects/gfx/D_09001420_327830.gfx.inc.c"
|
11
src/effects/gfx/big_snowflakes.c
Normal file
11
src/effects/gfx/big_snowflakes.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "effects/gfx/D_09000000_3638C0.png.inc.c"
|
||||
#include "effects/gfx/D_09000080_363940.png.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09000880_364140.vtx.inc.c"
|
||||
#include "effects/gfx/D_090008C0_364180.vtx.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09000900_3641C0.gfx.inc.c"
|
||||
#include "effects/gfx/D_090009E8_3642A8.gfx.inc.c"
|
||||
#include "effects/gfx/D_09000A10_3642D0.gfx.inc.c"
|
40
src/effects/gfx/butterflies.c
Normal file
40
src/effects/gfx/butterflies.c
Normal file
@ -0,0 +1,40 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "effects/gfx/D_09000000_3AB030.png.inc.c"
|
||||
#include "effects/gfx/D_09000000_3AB030.pal.inc.c"
|
||||
#include "effects/gfx/D_09000420_3AB450.png.inc.c"
|
||||
#include "effects/gfx/D_09000420_3AB450.pal.inc.c"
|
||||
#include "effects/gfx/D_09000840_3AB870.png.inc.c"
|
||||
#include "effects/gfx/D_09000840_3AB870.pal.inc.c"
|
||||
#include "effects/gfx/D_09000C50_3ABC80.png.inc.c"
|
||||
#include "effects/gfx/D_09000C50_3ABC80.pal.inc.c"
|
||||
#include "effects/gfx/D_09001070_3AC0A0.png.inc.c"
|
||||
#include "effects/gfx/D_09001070_3AC0A0.pal.inc.c"
|
||||
#include "effects/gfx/D_09001480_3AC4B0.png.inc.c"
|
||||
#include "effects/gfx/D_09001480_3AC4B0.pal.inc.c"
|
||||
#include "effects/gfx/D_090018A0_3AC8D0.png.inc.c"
|
||||
#include "effects/gfx/D_090018A0_3AC8D0.pal.inc.c"
|
||||
#include "effects/gfx/D_09001CC0_3ACCF0.png.inc.c"
|
||||
#include "effects/gfx/D_09001CC0_3ACCF0.pal.inc.c"
|
||||
#include "effects/gfx/D_090020E0_3AD110.png.inc.c"
|
||||
#include "effects/gfx/D_090020E0_3AD110.pal.inc.c"
|
||||
#include "effects/gfx/D_09002500_3AD530.png.inc.c"
|
||||
#include "effects/gfx/D_09002500_3AD530.pal.inc.c"
|
||||
#include "effects/gfx/D_09002920_3AD950.png.inc.c"
|
||||
#include "effects/gfx/D_09002920_3AD950.pal.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09002D40_3ADD70.vtx.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09003880_3AE8B0.gfx.inc.c"
|
||||
#include "effects/gfx/D_090038F8_3AE928.gfx.inc.c"
|
||||
#include "effects/gfx/D_09003968_3AE998.gfx.inc.c"
|
||||
#include "effects/gfx/D_090039D8_3AEA08.gfx.inc.c"
|
||||
#include "effects/gfx/D_09003A48_3AEA78.gfx.inc.c"
|
||||
#include "effects/gfx/D_09003AB8_3AEAE8.gfx.inc.c"
|
||||
#include "effects/gfx/D_09003B28_3AEB58.gfx.inc.c"
|
||||
#include "effects/gfx/D_09003B98_3AEBC8.gfx.inc.c"
|
||||
#include "effects/gfx/D_09003C08_3AEC38.gfx.inc.c"
|
||||
#include "effects/gfx/D_09003C78_3AECA8.gfx.inc.c"
|
||||
#include "effects/gfx/D_09003CE8_3AED18.gfx.inc.c"
|
||||
#include "effects/gfx/D_09003D58_3AED88.gfx.inc.c"
|
||||
#include "effects/gfx/D_09003DC8_3AEDF8.gfx.inc.c"
|
9
src/effects/gfx/cloud_puff_trail.c
Normal file
9
src/effects/gfx/cloud_puff_trail.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "effects/gfx/D_09000000_32EC50.png.inc.c"
|
||||
#include "effects/gfx/D_09000000_32EC50.pal.inc.c"
|
||||
|
||||
#include "effects/gfx/D_090000A0_32ECF0.vtx.inc.c"
|
||||
|
||||
#include "effects/gfx/D_090000E0_32ED30.gfx.inc.c"
|
||||
#include "effects/gfx/D_090001B8_32EE08.gfx.inc.c"
|
48
src/effects/gfx/damage_indicator.c
Normal file
48
src/effects/gfx/damage_indicator.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "effects/gfx/D_09000000_350220.png.inc.c"
|
||||
#include "effects/gfx/D_09000200_350420.png.inc.c"
|
||||
#include "effects/gfx/D_09000400_350620.png.inc.c"
|
||||
#include "effects/gfx/D_09000600_350820.png.inc.c"
|
||||
#include "effects/gfx/D_09000800_350A20.png.inc.c"
|
||||
#include "effects/gfx/D_09000A00_350C20.png.inc.c"
|
||||
#include "effects/gfx/D_09000C00_350E20.png.inc.c"
|
||||
#include "effects/gfx/D_09000E00_351020.png.inc.c"
|
||||
#include "effects/gfx/D_09001000_351220.png.inc.c"
|
||||
#include "effects/gfx/D_09001200_351420.png.inc.c"
|
||||
#include "effects/gfx/D_09001400_351620.png.inc.c"
|
||||
#include "effects/gfx/D_09001600_351820.png.inc.c"
|
||||
#include "effects/gfx/D_09001800_351A20.png.inc.c"
|
||||
#include "effects/gfx/D_09001A00_351C20.png.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09001C00_351E20.vtx.inc.c"
|
||||
#include "effects/gfx/D_09001C10_351E30.vtx.inc.c"
|
||||
#include "effects/gfx/D_09001C30_351E50.vtx.inc.c"
|
||||
#include "effects/gfx/D_09001C40_351E60.vtx.inc.c"
|
||||
#include "effects/gfx/D_09001C80_351EA0.vtx.inc.c"
|
||||
#include "effects/gfx/D_09001CC0_351EE0.vtx.inc.c"
|
||||
#include "effects/gfx/D_09001D00_351F20.vtx.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09001D40_351F60.gfx.inc.c"
|
||||
#include "effects/gfx/D_09001DE0_352000.gfx.inc.c"
|
||||
#include "effects/gfx/D_09001E50_352070.gfx.inc.c"
|
||||
#include "effects/gfx/D_09001E90_3520B0.gfx.inc.c"
|
||||
#include "effects/gfx/D_09001ED0_3520F0.gfx.inc.c"
|
||||
#include "effects/gfx/D_09001F10_352130.gfx.inc.c"
|
||||
#include "effects/gfx/D_09001F50_352170.gfx.inc.c"
|
||||
#include "effects/gfx/D_09001F90_3521B0.gfx.inc.c"
|
||||
#include "effects/gfx/D_09001FD0_3521F0.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002010_352230.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002050_352270.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002090_3522B0.gfx.inc.c"
|
||||
#include "effects/gfx/D_090020D0_3522F0.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002110_352330.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002150_352370.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002160_352380.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002170_352390.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002180_3523A0.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002190_3523B0.gfx.inc.c"
|
||||
#include "effects/gfx/D_090021A8_3523C8.gfx.inc.c"
|
||||
#include "effects/gfx/D_090021C0_3523E0.gfx.inc.c"
|
||||
#include "effects/gfx/D_090021E0_352400.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002200_352420.gfx.inc.c"
|
8
src/effects/gfx/debuff.c
Normal file
8
src/effects/gfx/debuff.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "effects/gfx/D_09000000_364C00.png.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09000200_364E00.vtx.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09000240_364E40.gfx.inc.c"
|
||||
#include "effects/gfx/D_090002E8_364EE8.gfx.inc.c"
|
40
src/effects/gfx/disable_x.c
Normal file
40
src/effects/gfx/disable_x.c
Normal file
@ -0,0 +1,40 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "effects/gfx/D_09000000_3863B0.png.inc.c"
|
||||
#include "effects/gfx/D_09000200_3865B0.png.inc.c"
|
||||
#include "effects/gfx/D_09000400_3867B0.png.inc.c"
|
||||
#include "effects/gfx/D_09000600_3869B0.png.inc.c"
|
||||
#include "effects/gfx/D_09000800_386BB0.png.inc.c"
|
||||
#include "effects/gfx/D_09000A00_386DB0.png.inc.c"
|
||||
#include "effects/gfx/D_09000C00_386FB0.png.inc.c"
|
||||
#include "effects/gfx/D_09000E00_3871B0.png.inc.c"
|
||||
#include "effects/gfx/D_09001000_3873B0.png.inc.c"
|
||||
#include "effects/gfx/D_09001200_3875B0.png.inc.c"
|
||||
#include "effects/gfx/D_09001400_3877B0.png.inc.c"
|
||||
#include "effects/gfx/D_09001600_3879B0.png.inc.c"
|
||||
#include "effects/gfx/D_09001800_387BB0.png.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09002000_3883B0.vtx.inc.c"
|
||||
#include "effects/gfx/D_09002040_3883F0.vtx.inc.c"
|
||||
#include "effects/gfx/D_09002080_388430.vtx.inc.c"
|
||||
#include "effects/gfx/D_090020C0_388470.vtx.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09002100_3884B0.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002198_388548.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002230_3885E0.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002250_388600.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002270_388620.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002290_388640.gfx.inc.c"
|
||||
#include "effects/gfx/D_090022B0_388660.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002320_3886D0.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002360_388710.gfx.inc.c"
|
||||
#include "effects/gfx/D_090023A0_388750.gfx.inc.c"
|
||||
#include "effects/gfx/D_090023E0_388790.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002420_3887D0.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002460_388810.gfx.inc.c"
|
||||
#include "effects/gfx/D_090024A0_388850.gfx.inc.c"
|
||||
#include "effects/gfx/D_090024E0_388890.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002520_3888D0.gfx.inc.c"
|
||||
#include "effects/gfx/D_09002560_388910.gfx.inc.c"
|
||||
#include "effects/gfx/D_090025A0_388950.gfx.inc.c"
|
||||
#include "effects/gfx/D_090025E0_388990.gfx.inc.c"
|
11
src/effects/gfx/floating_flower.c
Normal file
11
src/effects/gfx/floating_flower.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "effects/gfx/D_09000000_330460.png.inc.c"
|
||||
#include "effects/gfx/D_09000000_330460.pal.inc.c"
|
||||
|
||||
#include "effects/gfx/D_090000A0_330500.vtx.inc.c"
|
||||
#include "effects/gfx/D_09000170_3305D0.vtx.inc.c"
|
||||
#include "effects/gfx/D_09000230_330690.vtx.inc.c"
|
||||
|
||||
#include "effects/gfx/D_090002F0_330750.gfx.inc.c"
|
||||
#include "effects/gfx/D_09000450_3308B0.gfx.inc.c"
|
23
src/effects/gfx/flower_splash_trail.c
Normal file
23
src/effects/gfx/flower_splash_trail.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "effects/gfx/D_09000000_32CEC0.png.inc.c"
|
||||
#include "effects/gfx/D_09000000_32CEC0.pal.inc.c"
|
||||
#include "effects/gfx/D_09000000_32CEC0.yellow.pal.inc.c"
|
||||
#include "effects/gfx/D_090000C0_32CF80.png.inc.c"
|
||||
|
||||
#include "effects/gfx/D_090008C0_32D780.vtx.inc.c"
|
||||
#include "effects/gfx/D_09000A30_32D8F0.vtx.inc.c"
|
||||
#include "effects/gfx/D_09000A40_32D900.vtx.inc.c"
|
||||
#include "effects/gfx/D_09000A50_32D910.vtx.inc.c"
|
||||
#include "effects/gfx/D_09000A90_32D950.vtx.inc.c"
|
||||
#include "effects/gfx/D_09000AB0_32D970.vtx.inc.c"
|
||||
#include "effects/gfx/D_09000AF0_32D9B0.vtx.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09000B50_32DA10.gfx.inc.c"
|
||||
#include "effects/gfx/D_09000C10_32DAD0.gfx.inc.c"
|
||||
#include "effects/gfx/D_09000CD0_32DB90.gfx.inc.c"
|
||||
#include "effects/gfx/D_09000D58_32DC18.gfx.inc.c"
|
||||
#include "effects/gfx/D_09000D90_32DC50.gfx.inc.c"
|
||||
#include "effects/gfx/D_09000E08_32DCC8.gfx.inc.c"
|
||||
#include "effects/gfx/D_09000E20_32DCE0.gfx.inc.c"
|
||||
#include "effects/gfx/D_09000E38_32DCF8.gfx.inc.c"
|
7
src/effects/gfx/footprint.c
Normal file
7
src/effects/gfx/footprint.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "effects/gfx/D_09000000_32FB50.png.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09000200_32FD50.vtx.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09000240_32FD90.gfx.inc.c"
|
17
src/effects/gfx/small_gold_sparkle.c
Normal file
17
src/effects/gfx/small_gold_sparkle.c
Normal file
@ -0,0 +1,17 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "effects/gfx/D_09000000_392440.png.inc.c"
|
||||
#include "effects/gfx/D_09000080_3924C0.png.inc.c"
|
||||
#include "effects/gfx/D_09000100_392540.png.inc.c"
|
||||
#include "effects/gfx/D_09000180_3925C0.png.inc.c"
|
||||
#include "effects/gfx/D_09000200_392640.png.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09000280_3926C0.vtx.inc.c"
|
||||
|
||||
#include "effects/gfx/D_090002C0_392700.gfx.inc.c"
|
||||
#include "effects/gfx/D_09000330_392770.gfx.inc.c"
|
||||
#include "effects/gfx/D_09000370_3927B0.gfx.inc.c"
|
||||
#include "effects/gfx/D_090003B0_3927F0.gfx.inc.c"
|
||||
#include "effects/gfx/D_090003F0_392830.gfx.inc.c"
|
||||
#include "effects/gfx/D_09000430_392870.gfx.inc.c"
|
||||
#include "effects/gfx/D_09000470_3928B0.gfx.inc.c"
|
11
src/effects/gfx/snowflake.c
Normal file
11
src/effects/gfx/snowflake.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "effects/gfx/D_09000000_330F00.png.inc.c"
|
||||
#include "effects/gfx/D_09000080_330F80.png.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09000880_331780.vtx.inc.c"
|
||||
#include "effects/gfx/D_090008C0_3317C0.vtx.inc.c"
|
||||
|
||||
#include "effects/gfx/D_09000900_331800.gfx.inc.c"
|
||||
#include "effects/gfx/D_090009E8_3318E8.gfx.inc.c"
|
||||
#include "effects/gfx/D_09000A10_331910.gfx.inc.c"
|
20
src/effects/gfx/throw_spiny.c
Normal file
20
src/effects/gfx/throw_spiny.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "effects/gfx/D_09000000_3CFAF0.png.inc.c"
|
||||
#include "effects/gfx/D_09000000_3CFAF0.pal.inc.c"
|
||||
|
||||
u8 D_09000220_3CFD10[] = {
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
|
||||
};
|
||||
|
||||
#include "effects/gfx/D_09000400_3CFEF0.png.inc.c"
|
||||
#include "effects/gfx/D_09000400_3CFEF0.pal.inc.c"
|
||||
|
||||
u8 D_09000620_3D0110[] = {
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
|
||||
};
|
||||
|
||||
#include "effects/gfx/D_09000800_3D02F0.gfx.inc.c"
|
||||
#include "effects/gfx/D_090008D8_3D03C8.gfx.inc.c"
|
||||
#include "effects/gfx/D_090009B0_3D04A0.vtx.inc.c"
|
||||
#include "effects/gfx/D_090009F0_3D04E0.gfx.inc.c"
|
@ -1,15 +1,15 @@
|
||||
#include "common.h"
|
||||
#include "effects_internal.h"
|
||||
|
||||
extern Gfx D_090002C0[];
|
||||
extern Gfx D_09000330[];
|
||||
extern Gfx D_09000370[];
|
||||
extern Gfx D_090003B0[];
|
||||
extern Gfx D_090003F0[];
|
||||
extern Gfx D_09000430[];
|
||||
extern Gfx D_09000470[];
|
||||
extern Gfx D_090002C0_392700[];
|
||||
extern Gfx D_09000330_392770[];
|
||||
extern Gfx D_09000370_3927B0[];
|
||||
extern Gfx D_090003B0_3927F0[];
|
||||
extern Gfx D_090003F0_392830[];
|
||||
extern Gfx D_09000430_392870[];
|
||||
extern Gfx D_09000470_3928B0[];
|
||||
|
||||
static Gfx* sDlists[] = { D_09000430, D_090003F0, D_090003B0, D_09000370, D_09000330 };
|
||||
static Gfx* sDlists[] = { D_09000430_392870, D_090003F0_392830, D_090003B0_3927F0, D_09000370_3927B0, D_09000330_392770 };
|
||||
|
||||
static s32 sPartParams[4 * 5] = {
|
||||
1, 0, 0, 0, 100,
|
||||
@ -126,7 +126,7 @@ void small_gold_sparkle_appendGfx(void* effect) {
|
||||
shim_guMtxF2L(sp18, &gDisplayContext->matrixStack[gMatrixListPos]);
|
||||
|
||||
gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090002C0);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090002C0_392700);
|
||||
gDPSetPrimColor(gMasterGfxPos++, 0, 0, 255, 255, 15, 255);
|
||||
|
||||
part++;
|
||||
@ -144,7 +144,7 @@ void small_gold_sparkle_appendGfx(void* effect) {
|
||||
G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW);
|
||||
gSPMatrix(gMasterGfxPos++, spD8, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(gMasterGfxPos++, sDlists[part->unk_04 >> 1]);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09000470);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09000470_3928B0);
|
||||
gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW);
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,8 @@
|
||||
|
||||
s32 D_E001C5E0 = 0;
|
||||
|
||||
extern Gfx D_09000900[];
|
||||
extern Gfx D_090009E8[];
|
||||
extern Gfx D_09000900_331800[];
|
||||
extern Gfx D_090009E8_3318E8[];
|
||||
|
||||
void snowflake_init(EffectInstance* effect);
|
||||
void snowflake_update(EffectInstance* effect);
|
||||
@ -124,7 +124,7 @@ void snowflake_appendGfx(void* effect) {
|
||||
|
||||
gDPPipeSync(gMasterGfxPos++);
|
||||
gSPSegment(gMasterGfxPos++, 0x09, VIRTUAL_TO_PHYSICAL(effectTemp->graphics->data));
|
||||
gSPDisplayList(gMasterGfxPos++, D_09000900);
|
||||
gSPDisplayList(gMasterGfxPos++, D_09000900_331800);
|
||||
|
||||
shim_guTranslateF(sp18, part->xPos, part->yPos, part->zPos);
|
||||
shim_guRotateF(spD8, -gCameras[gCurrentCameraID].currentYaw, 0.0f, 1.0f, 0.0f);
|
||||
@ -140,7 +140,7 @@ void snowflake_appendGfx(void* effect) {
|
||||
shim_guMtxF2L(sp118, &gDisplayContext->matrixStack[gMatrixListPos]);
|
||||
|
||||
gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090009E8);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090009E8_3318E8);
|
||||
gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW);
|
||||
gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW);
|
||||
}
|
||||
|
@ -8,11 +8,11 @@ void throw_spiny_init(EffectInstance* effect);
|
||||
void throw_spiny_update(EffectInstance* effect);
|
||||
void throw_spiny_render(EffectInstance* effect);
|
||||
|
||||
extern Gfx D_09000800[];
|
||||
extern Gfx D_090008D8[];
|
||||
extern Gfx D_090009F0[];
|
||||
extern Gfx D_09000800_3D02F0[];
|
||||
extern Gfx D_090008D8_3D03C8[];
|
||||
extern Gfx D_090009F0_3D04E0[];
|
||||
|
||||
Gfx* D_E00C8710[2] = { D_09000800, D_090008D8 };
|
||||
Gfx* D_E00C8710[2] = { D_09000800_3D02F0, D_090008D8_3D03C8 };
|
||||
|
||||
u8 D_E00C8718[8] = { 110, 150, 130, 110, 100, 95, 100, 0 };
|
||||
u8 D_E00C8720[8] = { 80, 60, 80, 100, 120, 110, 100, 0 };
|
||||
@ -207,6 +207,6 @@ void throw_spiny_appendGfx(void* effect) {
|
||||
gSPMatrix(gMasterGfxPos++, camera->unkMatrix, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
|
||||
gDPSetPrimColor(gMasterGfxPos++, 0, 0, data->unk_30, data->unk_34, data->unk_38, temp_s5);
|
||||
gSPDisplayList(gMasterGfxPos++, D_E00C8710[temp_s6]);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090009F0);
|
||||
gSPDisplayList(gMasterGfxPos++, D_090009F0_3D04E0);
|
||||
gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW);
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ Gfx gPauseDLArrows[] = {
|
||||
gsDPSetTextureFilter(G_TF_POINT),
|
||||
gsDPSetTextureConvert(G_TC_FILT),
|
||||
gsDPSetTextureLUT(G_TT_NONE),
|
||||
gsDPLoadTextureTile_4b(pause_map_arrows_png, G_IM_FMT_IA, pause_map_arrows_png_width, pause_map_arrows_png_height, 0, 0, pause_map_arrows_png_width - 1, pause_map_arrows_png_height - 1, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, 4, 6, G_TX_NOLOD, G_TX_NOLOD),
|
||||
gsDPLoadTextureTile_4b(pause_arrows_png, G_IM_FMT_IA, pause_arrows_png_width, pause_arrows_png_height, 0, 0, pause_arrows_png_width - 1, pause_arrows_png_height - 1, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, 4, 6, G_TX_NOLOD, G_TX_NOLOD),
|
||||
gsDPSetRenderMode(AA_EN | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA | GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM), AA_EN | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA | GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)),
|
||||
gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_DECALRGBA),
|
||||
gsSPClearGeometryMode(G_LIGHTING),
|
||||
|
@ -8,15 +8,15 @@
|
||||
s32 D_80077980[] = { &D_8038F800, &D_803B5000, &heap_battleHead, };
|
||||
|
||||
NUPiOverlaySegment D_8007798C = {
|
||||
.romStart = _163400_ROM_START,
|
||||
.romEnd = _163400_ROM_END,
|
||||
.ramStart = _163400_VRAM,
|
||||
.textStart = _163400_TEXT_START,
|
||||
.textEnd = _163400_TEXT_END,
|
||||
.dataStart = _163400_DATA_START,
|
||||
.dataEnd = _163400_DATA_END,
|
||||
.bssStart = _163400_BSS_START,
|
||||
.bssEnd = _163400_BSS_END,
|
||||
.romStart = filemenu_ROM_START,
|
||||
.romEnd = filemenu_ROM_END,
|
||||
.ramStart = filemenu_VRAM,
|
||||
.textStart = filemenu_TEXT_START,
|
||||
.textEnd = filemenu_TEXT_END,
|
||||
.dataStart = filemenu_DATA_START,
|
||||
.dataEnd = filemenu_DATA_END,
|
||||
.bssStart = filemenu_BSS_START,
|
||||
.bssEnd = filemenu_BSS_END,
|
||||
};
|
||||
|
||||
u8 D_800779B0 = 0;
|
||||
|
@ -1,19 +1,11 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
from pathlib import Path
|
||||
from sys import argv
|
||||
import re
|
||||
import png
|
||||
|
||||
if __name__ == "__main__":
|
||||
infile, outfile = argv[1:]
|
||||
|
||||
cname = re.sub(r"[^0-9a-zA-Z_]", "_", outfile)
|
||||
|
||||
if cname.startswith("ver_"):
|
||||
cname = "_".join(cname.split("_")[2:])
|
||||
|
||||
cname = re.sub(r"^build_include_", "", cname)
|
||||
cname = re.sub(r"_inc_c$", "", cname)
|
||||
infile, outfile, cname = argv[1:]
|
||||
|
||||
with open(outfile, "w") as f:
|
||||
f.write(f"unsigned char {cname}[] = {{")
|
||||
|
@ -140,12 +140,12 @@ def write_ninja_rules(ninja: ninja_syntax.Writer, cpp: str, cppflags: str, extra
|
||||
|
||||
ninja.rule("img_header",
|
||||
description="img_header $in",
|
||||
command=f"$python {BUILD_TOOLS}/img/header.py $in $out",
|
||||
command=f"$python {BUILD_TOOLS}/img/header.py $in $out $c_name",
|
||||
)
|
||||
|
||||
ninja.rule("bin_inc_c",
|
||||
description="bin_inc_c $out",
|
||||
command=f"$python {BUILD_TOOLS}/bin_inc_c.py $in $out",
|
||||
command=f"$python {BUILD_TOOLS}/bin_inc_c.py $in $out $c_name",
|
||||
)
|
||||
|
||||
ninja.rule("yay0",
|
||||
@ -231,7 +231,7 @@ class Configure:
|
||||
|
||||
modes = ["ld"]
|
||||
if assets:
|
||||
modes.extend(["bin", "Yay0", "img", "vtx", "pm_map_data", "pm_msg", "pm_npc_sprites", "pm_charset",
|
||||
modes.extend(["bin", "Yay0", "img", "vtx", "gfx", "pm_map_data", "pm_msg", "pm_npc_sprites", "pm_charset",
|
||||
"pm_charset_palettes", "pm_effect_loads", "pm_effect_shims"])
|
||||
if code:
|
||||
modes.extend(["code", "c", "data", "rodata"])
|
||||
@ -409,8 +409,12 @@ class Configure:
|
||||
"img_flags": flags,
|
||||
})
|
||||
|
||||
build(inc_dir / (seg.name + ".png.h"), src_paths, "img_header")
|
||||
build(inc_dir / (seg.name + ".png.inc.c"), [bin_path], "bin_inc_c")
|
||||
c_sym = seg.create_symbol(
|
||||
addr=seg.vram_start, in_segment=True, type="data", define=True
|
||||
)
|
||||
vars = {"c_name": c_sym.name}
|
||||
build(inc_dir / (seg.name + ".png.h"), src_paths, "img_header", vars)
|
||||
build(inc_dir / (seg.name + ".png.inc.c"), [bin_path], "bin_inc_c", vars)
|
||||
elif isinstance(seg, segtypes.n64.palette.N64SegPalette):
|
||||
src_paths = [seg.out_path().relative_to(ROOT)]
|
||||
inc_dir = self.build_path() / "include" / seg.dir
|
||||
@ -420,7 +424,12 @@ class Configure:
|
||||
"img_type": seg.type,
|
||||
"img_flags": "",
|
||||
})
|
||||
build(inc_dir / (seg.name + ".pal.inc.c"), [bin_path], "bin_inc_c")
|
||||
|
||||
c_sym = seg.create_symbol(
|
||||
addr=seg.vram_start, in_segment=True, type="data", define=True
|
||||
)
|
||||
vars = {"c_name": c_sym.name}
|
||||
build(inc_dir / (seg.name + ".pal.inc.c"), [bin_path], "bin_inc_c", vars)
|
||||
elif isinstance(seg, segtypes.common.bin.CommonSegBin):
|
||||
build(entry.object_path, entry.src_paths, "bin")
|
||||
elif isinstance(seg, segtypes.n64.Yay0.N64SegYay0):
|
||||
@ -443,6 +452,10 @@ class Configure:
|
||||
})
|
||||
build(entry.object_path, [bin_path], "bin")
|
||||
|
||||
# c_sym = seg.create_symbol(
|
||||
# addr=seg.vram_start, in_segment=True, type="data", define=True
|
||||
# )
|
||||
# vars = {"c_name": c_sym.name}
|
||||
build(inc_dir / (seg.name + ".png.h"), entry.src_paths, "img_header")
|
||||
elif isinstance(seg, segtypes.n64.palette.N64SegPalette):
|
||||
bin_path = entry.object_path.with_suffix(".bin")
|
||||
|
@ -5,21 +5,24 @@ import re
|
||||
import png
|
||||
|
||||
if __name__ == "__main__":
|
||||
infile, outfile = argv[1:]
|
||||
infile, outfile = argv[1:3]
|
||||
|
||||
if len(argv) > 3:
|
||||
cname = argv[3]
|
||||
else:
|
||||
cname = re.sub(r"[^0-9a-zA-Z_]", "_", infile)
|
||||
|
||||
if cname.startswith("ver_"):
|
||||
cname = "_".join(cname.split("_")[2:])
|
||||
|
||||
if cname.startswith("src_"):
|
||||
cname = cname[4:]
|
||||
elif cname.startswith("assets_"):
|
||||
cname = "_".join(cname.split("_")[2:])
|
||||
|
||||
img = png.Reader(infile)
|
||||
width, height, rows, info = img.read()
|
||||
|
||||
cname = re.sub(r"[^0-9a-zA-Z_]", "_", infile)
|
||||
|
||||
if cname.startswith("ver_"):
|
||||
cname = "_".join(cname.split("_")[2:])
|
||||
|
||||
if cname.startswith("src_"):
|
||||
cname = cname[4:]
|
||||
elif cname.startswith("assets_"):
|
||||
cname = "_".join(cname.split("_")[2:])
|
||||
|
||||
with open(outfile, "w") as f:
|
||||
f.write("// Generated file, do not edit.\n")
|
||||
f.write(f"#ifndef _{cname.upper()}_\n")
|
||||
|
4
tools/splat/.github/workflows/mypy.yml
vendored
4
tools/splat/.github/workflows/mypy.yml
vendored
@ -10,10 +10,10 @@ jobs:
|
||||
name: mypy
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Set up Python 3.9
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: 3.9
|
||||
python-version: 3.8
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
pip install mypy
|
||||
|
@ -6,7 +6,7 @@
|
||||
[subrepo]
|
||||
remote = https://github.com/ethteck/splat.git
|
||||
branch = master
|
||||
commit = a847090eac32ef0d9cf183cd8f04e2452a0e250b
|
||||
parent = 3e71bb8cea31e9e5a87f2f251e99d55daa0f902e
|
||||
commit = aa71299594b8f864f9af9c22823c64a9c9189706
|
||||
parent = d0b02e98a6bf6773e3c4f4ca7f1e203c86aaf6df
|
||||
method = merge
|
||||
cmdver = 0.4.3
|
||||
|
@ -1,5 +1,65 @@
|
||||
# splat Release Notes
|
||||
|
||||
## 0.9.0: The Big Update
|
||||
### Introducing [spimdisasm](https://github.com/Decompollaborate/spimdisasm)!
|
||||
* Thanks to [AngheloAlf](https://github.com/AngheloAlf), we now have a much better MIPS disassembler in splat! spimdisasm has much better hi/lo matching, much lower ram usage, and plenty of other goodies.
|
||||
|
||||
We plan to roll this out in phases. Currently, it only handles actual code disassembly. Later on, we will probably migrate our current data assembly code to use spimdisasm as well.
|
||||
|
||||
**NOTICE**: This integration has been tested on a variety of games and configurations. However, with any giant change to the platform like this, there are bound to be things we didn't catch. Please be patient with us as we handle these remaining issues. Though from what we've seen already, the slight bugs one may come across are totally worth the much improved disassembly.
|
||||
|
||||
### gfx segment type
|
||||
* A new `gfx` segment type is available, which creates a c file containing a disassembled display list according to the segment's start and end offsets. Thanks to [Glank](https://github.com/glankk) and [Tharo](https://github.com/thar0/) for their work on [libgfxd](https://github.com/glankk/libgfxd) and [pygfxd](https://github.com/thar0/pygfxd/), respectively, for helping make this a possibility in splat.
|
||||
|
||||
### API breaking changes
|
||||
* Some `Segment()` arguments have changed, which may cause extensions to break. Please see the `__init__` function for `Segment` for more details.
|
||||
|
||||
### symbol_addrs.txt changes
|
||||
* symbol_addrs now supports the `segment:` attribute, which allows specifying the symbol's top-level segment. This can be helpful for symbol resolution when overlays use overlapping vram ranges. See `exclusive_ram_id` below for more information.
|
||||
|
||||
### Global options changes
|
||||
|
||||
The new `symbol_name_format` option allows specification of how symbols will be named. This can be set as a global option and also changed per-segment. `symbol_norom_name_format` is used when the symbol does not have a rom address (BSS).
|
||||
|
||||
The following substitutions are allowed:
|
||||
|
||||
`$ROM` - the rom address of the symbol, hex-formatted and padded to 6 characters (ABCF10, 000030, 123456) (note: only for `symbol_name_format`, usage in `symbol_norom_name_format` will cause an error)
|
||||
|
||||
`$VRAM` - the vram address of the symbol, hex-formatted and padded to 8 characters (00030010, 00020015, ABCDEF10)
|
||||
|
||||
`$SEG` - the name of the top-level segment in which the symbol resides
|
||||
|
||||
The default values for these options are as follows
|
||||
|
||||
`symbol_name_format` : `$VRAM_$ROM`
|
||||
|
||||
`symbol_noram_name_format` : `$VRAM_$SEG`
|
||||
|
||||
The appropriate prefix string will still automatically be applied depending on the type of the symbol: `D_` for data, `jtbl_` for jump tables, and `func_` for functions. This functionality may be customizable in the future.
|
||||
|
||||
----
|
||||
The `auto_all_section` option now should be a list of section names (`[".data", ".rodata", ".bss"]` by default) indicating the sections that should be linked from .o files built from source files (.c or asm/hasm .s files), when no subsegment explicitly indicates linking this type of section.
|
||||
|
||||
For example, if any subsegment of a code segment is of segment type `data` or `.data`, the `.data` section from all `c`/`asm`/`hasm` subsegments will not be linked unless explicitly indicated with a relevant `.data` subsegment.
|
||||
|
||||
Previously, this option was a bool, and it enabled this feature for all sections specified in `section_order`. Now, the desired sections must be specified manually. The default value for this option retains previous behavior.
|
||||
|
||||
----
|
||||
The new `mips_abi_float_regs` option allows for changing the format of float registers for MIPS disassembly. The default value does not change any prior behavior, but `o32` is heavily encouraged and may become the default option in the future. For more information, see this [great writeup](https://gist.github.com/EllipticEllipsis/27eef11205c7a59d8ea85632bc49224d).
|
||||
|
||||
----
|
||||
The new `gfx_ucode` option allows for specifying the target for the graphics macro format, which is used in the gfx segment type. The default is `f3dex2`.
|
||||
|
||||
|
||||
### Segment options changes
|
||||
|
||||
The new `exclusive_ram_id` segment option allows specifying an identifer that will prevent the segment from seeing any symbols from other segments with the same identifer. This is useful when multiple segments are mapped to the same vram address at runtime and should never be able to refer to each other's symbols. Setting all of these segments to have the same value for this option will prevent their symbols from clashing / meshing unexpectedly.
|
||||
|
||||
----
|
||||
|
||||
The `overlay` setting on segments has been removed. Please see `symbol_name_format` above for info on how to influence the names of symbols, which can be applied at the segment level as well as the global level.
|
||||
|
||||
----
|
||||
## 0.8.0: Arbitrary Section Order
|
||||
* You can now use the option `section_order` to define the binary section order for your target binary. By default, this is `[".text", ".data", ".rodata", ".bss"]`. See options.py for more details
|
||||
* Documented all options in options.py
|
||||
@ -30,7 +90,7 @@
|
||||
|
||||
* Fixed a bug involving detection of defined functions in c files for GLOBAL_ASM-using projects
|
||||
* Added options to disable the creation of undefined_funcs/syms_auto.txt files
|
||||
* Add a Vtx segment type for creating c files containg model vertex data in the n64 libultra Vtx format
|
||||
* Added a Vtx segment type for creating c files containg model vertex data in the n64 libultra Vtx format
|
||||
* Added a `cpp` segment type which is identical to `c` but looks for a file with the extension ".cpp" instead of ".c".
|
||||
|
||||
### 0.7.5: all_ types and auto_all_sections
|
||||
|
@ -3,9 +3,7 @@ A binary splitting tool to assist with decompilation and modding projects
|
||||
|
||||
Currently, only N64 and PSX binaries are supported.
|
||||
|
||||
The Makefile `setup` target calls splat with a config file that you can use for reference.
|
||||
|
||||
Please check out the [wiki](https://github.com/ethteck/splat/wiki) for more information including [examples](https://github.com/ethteck/splat/wiki/Examples) of projects that use splat.
|
||||
|
||||
### Requirements
|
||||
Python package requirements can be installed via `pip3 install -r requirements.txt`
|
||||
splat requires Python 3.8+. Package requirements can be installed via `pip3 install -r requirements.txt`
|
||||
|
@ -1,5 +1,6 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
@ -9,11 +10,17 @@ parser = argparse.ArgumentParser(description="Create a splat config from an N64
|
||||
parser.add_argument("rom", help="Path to a .z64/.n64 ROM")
|
||||
|
||||
|
||||
def main(rom_path):
|
||||
rom = rominfo.get_info(rom_path)
|
||||
def main(rom_path: Path):
|
||||
if not rom_path.exists():
|
||||
sys.exit(f"ROM file {rom_path} does not exist ({rom_path.absolute()})")
|
||||
if rom_path.is_dir():
|
||||
sys.exit(f"Path {rom_path} is a directory ({rom_path.absolute()})")
|
||||
rom_bytes = rominfo.read_rom(rom_path)
|
||||
|
||||
rom = rominfo.get_info(rom_path, rom_bytes)
|
||||
basename = rom.name.replace(" ", "").lower()
|
||||
|
||||
header = f"""
|
||||
header = f"""\
|
||||
name: {rom.name.title()} ({rom.get_country_name()})
|
||||
sha1: {rom.sha1}
|
||||
options:
|
||||
@ -24,7 +31,9 @@ options:
|
||||
find_file_boundaries: True
|
||||
header_encoding: {rom.header_encoding}
|
||||
# platform: n64
|
||||
# undefined_funcs_auto: True
|
||||
# undefined_funcs_auto_path: undefined_funcs_auto.txt
|
||||
# undefined_syms_auto: True
|
||||
# undefined_syms_auto_path: undefined_syms_auto.txt
|
||||
# symbol_addrs_path: symbol_addrs.txt
|
||||
# undefined_syms_path: undefined_syms.txt
|
||||
@ -32,15 +41,14 @@ options:
|
||||
# src_path: src
|
||||
# build_path: build
|
||||
# extensions_path: tools/splat_ext
|
||||
# auto_all_sections: True
|
||||
""".lstrip()
|
||||
# mips_abi_float_regs: o32
|
||||
# section_order: [".text", ".data", ".rodata", ".bss"]
|
||||
# auto_all_sections: [".data", ".rodata", ".bss"]
|
||||
"""
|
||||
|
||||
with open(rom_path, "rb") as f:
|
||||
fbytes = f.read()
|
||||
first_section_end = find_code_length.run(rom_bytes, 0x1000, rom.entry_point)
|
||||
|
||||
first_section_end = find_code_length.run(fbytes, 0x1000, rom.entry_point)
|
||||
|
||||
segments = f"""
|
||||
segments = f"""\
|
||||
segments:
|
||||
- name: header
|
||||
type: header
|
||||
@ -57,12 +65,13 @@ segments:
|
||||
- type: bin
|
||||
start: 0x{first_section_end:X}
|
||||
- [0x{rom.size:X}]
|
||||
""".lstrip()
|
||||
"""
|
||||
|
||||
out_file = f"{basename}.yaml"
|
||||
with open(out_file, "w", newline="\n") as f:
|
||||
print(f"Writing config to {out_file}")
|
||||
f.write(header + segments)
|
||||
f.write(header)
|
||||
f.write(segments)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -2,4 +2,8 @@ PyYAML
|
||||
pylibyaml
|
||||
pypng
|
||||
colorama
|
||||
capstone
|
||||
spimdisasm>=1.2.1
|
||||
rabbitizer
|
||||
pygfxd
|
||||
tqdm
|
||||
intervaltree
|
||||
|
@ -15,7 +15,7 @@ class CommonSegAsm(CommonSegCodeSubsegment):
|
||||
and self.rom_end != "auto"
|
||||
and self.rom_start != self.rom_end
|
||||
):
|
||||
self.funcs_text = self.scan_code(rom_bytes, is_asm=True)
|
||||
self.scan_code(rom_bytes, is_asm=True)
|
||||
|
||||
def get_file_header(self):
|
||||
return []
|
||||
@ -26,16 +26,9 @@ class CommonSegAsm(CommonSegCodeSubsegment):
|
||||
if out_path:
|
||||
out_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
out_lines = self.get_file_header()
|
||||
self.print_file_boundaries()
|
||||
|
||||
self.funcs_text = self.split_code(rom_bytes)
|
||||
|
||||
for func in self.funcs_text:
|
||||
out_lines.extend(self.funcs_text[func][0])
|
||||
out_lines.append("")
|
||||
|
||||
self.split_write(out_path, out_lines)
|
||||
|
||||
def split_write(self, out_path, out_lines):
|
||||
with open(out_path, "w", newline="\n") as f:
|
||||
f.write("\n".join(out_lines))
|
||||
with open(out_path, "w", newline="\n") as f:
|
||||
for line in self.get_file_header():
|
||||
f.write(line + "\n")
|
||||
f.write(self.text_section.disassemble())
|
||||
|
@ -1,6 +1,9 @@
|
||||
from segtypes.common.data import CommonSegData
|
||||
from segtypes.linker_entry import LinkerEntry
|
||||
from util import options, log
|
||||
|
||||
from typing import List
|
||||
|
||||
|
||||
class CommonSegBss(CommonSegData):
|
||||
def get_linker_section(self) -> str:
|
||||
@ -12,12 +15,14 @@ class CommonSegBss(CommonSegData):
|
||||
def split(self, rom_bytes: bytes):
|
||||
pass
|
||||
|
||||
def get_linker_entries(self):
|
||||
from segtypes.linker_entry import LinkerEntry
|
||||
def get_linker_entries(self) -> "List[LinkerEntry]":
|
||||
|
||||
if self.sibling:
|
||||
path = self.sibling.out_path()
|
||||
else:
|
||||
path = options.get_src_path() / self.name
|
||||
path = self.out_path()
|
||||
|
||||
return [LinkerEntry(self, [path], path, self.get_linker_section())]
|
||||
if path:
|
||||
return [LinkerEntry(self, [path], path, self.get_linker_section())]
|
||||
else:
|
||||
return []
|
||||
|
@ -4,6 +4,8 @@ from typing import Optional, Set
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
import spimdisasm
|
||||
import rabbitizer
|
||||
|
||||
from util import log, options
|
||||
from util.compiler import GCC, SN64
|
||||
@ -122,26 +124,25 @@ class CommonSegC(CommonSegCodeSubsegment):
|
||||
asm_out_dir = options.get_nonmatchings_path() / self.dir
|
||||
asm_out_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
is_new_c_file = False
|
||||
self.print_file_boundaries()
|
||||
|
||||
self.funcs_text = self.split_code(rom_bytes)
|
||||
is_new_c_file = False
|
||||
|
||||
c_path = self.out_path()
|
||||
if c_path:
|
||||
if not os.path.exists(c_path) and options.get_create_c_files():
|
||||
self.create_c_file(self.funcs_text, asm_out_dir, c_path)
|
||||
self.create_c_file(asm_out_dir, c_path)
|
||||
is_new_c_file = True
|
||||
|
||||
for func_addr in self.funcs_text:
|
||||
func_sym = self.parent.get_symbol(
|
||||
func_addr, type="func", local_only=True
|
||||
for func in self.text_section.symbolList:
|
||||
assert func.vram is not None
|
||||
func_sym = self.get_symbol(
|
||||
func.vram, in_segment=True, type="func", local_only=True
|
||||
)
|
||||
assert func_sym is not None
|
||||
|
||||
if func_sym.name in self.global_asm_funcs or is_new_c_file:
|
||||
self.create_c_asm_file(
|
||||
self.funcs_text, func_addr, asm_out_dir, func_sym
|
||||
)
|
||||
if func.getName() in self.global_asm_funcs or is_new_c_file:
|
||||
self.create_c_asm_file(func, asm_out_dir, func_sym)
|
||||
|
||||
def get_c_preamble(self):
|
||||
ret = []
|
||||
@ -155,8 +156,8 @@ class CommonSegC(CommonSegCodeSubsegment):
|
||||
def mark_c_funcs_as_defined(self, c_funcs):
|
||||
for func_name in c_funcs:
|
||||
found = False
|
||||
for func_addr in self.seg_symbols:
|
||||
for symbol in self.seg_symbols[func_addr]:
|
||||
for symbols in self.seg_symbols.values():
|
||||
for symbol in symbols:
|
||||
if symbol.name == func_name:
|
||||
symbol.defined = True
|
||||
found = True
|
||||
@ -164,8 +165,11 @@ class CommonSegC(CommonSegCodeSubsegment):
|
||||
if found:
|
||||
break
|
||||
|
||||
def create_c_asm_file(self, funcs_text, func_addr, out_dir, func_sym: Symbol):
|
||||
def create_c_asm_file(
|
||||
self, func: spimdisasm.mips.symbols.SymbolBase, out_dir, func_sym: Symbol
|
||||
):
|
||||
outpath = Path(os.path.join(out_dir, self.name, func_sym.name + ".s"))
|
||||
assert func.vram is not None
|
||||
|
||||
# Skip extraction if the file exists and the symbol is marked as extract=false
|
||||
if outpath.exists() and not func_sym.extract:
|
||||
@ -179,10 +183,10 @@ class CommonSegC(CommonSegCodeSubsegment):
|
||||
if self.parent and isinstance(self.parent, CommonSegGroup):
|
||||
if (
|
||||
options.get_migrate_rodata_to_functions()
|
||||
and func_addr in self.parent.rodata_syms
|
||||
and func.vram in self.parent.rodata_syms
|
||||
):
|
||||
func_rodata = list(
|
||||
{s for s in self.parent.rodata_syms[func_addr] if s.disasm_str}
|
||||
{s for s in self.parent.rodata_syms[func.vram] if s.disasm_str}
|
||||
)
|
||||
func_rodata.sort(key=lambda s: s.vram_start)
|
||||
|
||||
@ -205,8 +209,7 @@ class CommonSegC(CommonSegCodeSubsegment):
|
||||
out_lines.append(".section .text")
|
||||
out_lines.append("")
|
||||
|
||||
out_lines.extend(funcs_text[func_addr][0])
|
||||
out_lines.append("")
|
||||
out_lines.append(func.disassemble())
|
||||
|
||||
outpath.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
@ -215,21 +218,19 @@ class CommonSegC(CommonSegCodeSubsegment):
|
||||
f.write(newline_sep.join(out_lines))
|
||||
self.log(f"Disassembled {func_sym.name} to {outpath}")
|
||||
|
||||
def create_c_file(self, funcs_text, asm_out_dir, c_path):
|
||||
def create_c_file(self, asm_out_dir, c_path):
|
||||
c_lines = self.get_c_preamble()
|
||||
|
||||
for func in funcs_text:
|
||||
func_name = self.parent.get_symbol(func, type="func", local_only=True).name
|
||||
for func in self.text_section.symbolList:
|
||||
assert isinstance(func, spimdisasm.mips.symbols.SymbolFunction)
|
||||
|
||||
# Terrible hack to "auto-decompile" empty functions
|
||||
# TODO move disassembly into funcs_text or somewhere we can access it from here
|
||||
if (
|
||||
options.get_auto_decompile_empty_functions()
|
||||
and len(funcs_text[func][0]) == 3
|
||||
and funcs_text[func][0][1][-3:] in ["$ra", "$31"]
|
||||
and funcs_text[func][0][2][-3:] == "nop"
|
||||
and func.instructions[0].isJrRa()
|
||||
and func.instructions[1].isNop()
|
||||
):
|
||||
c_lines.append("void " + func_name + "(void) {")
|
||||
c_lines.append("void " + func.getName() + "(void) {")
|
||||
c_lines.append("}")
|
||||
else:
|
||||
if options.get_compiler() in [GCC, SN64]:
|
||||
@ -237,12 +238,16 @@ class CommonSegC(CommonSegCodeSubsegment):
|
||||
rel_asm_out_dir = asm_out_dir.relative_to(
|
||||
options.get_nonmatchings_path()
|
||||
)
|
||||
c_lines.append(f'INCLUDE_ASM(s32, "{rel_asm_out_dir / self.name}", {func_name});')
|
||||
c_lines.append(
|
||||
f'INCLUDE_ASM(s32, "{rel_asm_out_dir / self.name}", {func.getName()});'
|
||||
)
|
||||
else:
|
||||
c_lines.append(f'INCLUDE_ASM("{asm_out_dir / self.name}", {func_name});')
|
||||
c_lines.append(
|
||||
f'INCLUDE_ASM("{asm_out_dir / self.name}", {func.getName()});'
|
||||
)
|
||||
else:
|
||||
asm_outpath = Path(
|
||||
os.path.join(asm_out_dir, self.name, func_name + ".s")
|
||||
os.path.join(asm_out_dir, self.name, func.getName() + ".s")
|
||||
)
|
||||
rel_asm_outpath = os.path.relpath(
|
||||
asm_outpath, options.get_base_path()
|
||||
|
@ -1,7 +1,15 @@
|
||||
from typing import Dict, Tuple
|
||||
from collections import OrderedDict
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
import typing
|
||||
from segtypes.common.group import CommonSegGroup
|
||||
from segtypes.common.linker_section import dotless_type
|
||||
from segtypes.segment import RomAddr, Segment
|
||||
from util import log, options
|
||||
from util.range import Range
|
||||
from util.symbols import Symbol
|
||||
|
||||
CODE_TYPES = ["c", "asm", "hasm"]
|
||||
|
||||
# code group
|
||||
class CommonSegCode(CommonSegGroup):
|
||||
def __init__(
|
||||
@ -13,11 +21,15 @@ class CommonSegCode(CommonSegGroup):
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
given_is_overlay,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
symbol_name_format,
|
||||
symbol_name_format_no_rom,
|
||||
args,
|
||||
yaml,
|
||||
):
|
||||
self.bss_size: int = yaml.get("bss_size", 0) if isinstance(yaml, dict) else 0
|
||||
|
||||
super().__init__(
|
||||
rom_start,
|
||||
rom_end,
|
||||
@ -26,30 +38,295 @@ class CommonSegCode(CommonSegGroup):
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
given_is_overlay,
|
||||
given_dir,
|
||||
args,
|
||||
yaml,
|
||||
exclusive_ram_id=exclusive_ram_id,
|
||||
given_dir=given_dir,
|
||||
symbol_name_format=symbol_name_format,
|
||||
symbol_name_format_no_rom=symbol_name_format_no_rom,
|
||||
args=args,
|
||||
yaml=yaml,
|
||||
)
|
||||
|
||||
self.reported_file_split = False
|
||||
self.labels_to_add = set()
|
||||
self.jtbl_glabels_to_add = set()
|
||||
self.jtbl_jumps = {}
|
||||
self.jumptables: Dict[int, Tuple[int, int]] = {}
|
||||
self.rodata_syms: Dict[int, List[Symbol]] = {}
|
||||
|
||||
@property
|
||||
def needs_symbols(self) -> bool:
|
||||
return True
|
||||
|
||||
@property
|
||||
def vram_end(self) -> Optional[int]:
|
||||
if self.vram_start is not None and self.size is not None:
|
||||
return self.vram_start + self.size + self.bss_size
|
||||
else:
|
||||
return None
|
||||
|
||||
# def ram_to_rom(self, ram_addr: int) -> Optional[int]:
|
||||
# size_no_bss = self.vram_start + self.size
|
||||
|
||||
# # Do not return a rom address if this is a BSS symbol
|
||||
# if ram_addr > size_no_bss:
|
||||
# return None
|
||||
|
||||
# if not self.contains_vram(ram_addr) and ram_addr != self.vram_end:
|
||||
# return None
|
||||
|
||||
# if self.vram_start is not None and isinstance(self.rom_start, int):
|
||||
# return self.rom_start + ram_addr - self.vram_start
|
||||
# else:
|
||||
# return None
|
||||
|
||||
# Prepare symbol for migration to the function
|
||||
def check_rodata_sym(self, func_addr: int, sym: Symbol):
|
||||
if self.section_boundaries[".rodata"].is_complete():
|
||||
if (
|
||||
self.section_boundaries[".rodata"].start
|
||||
<= sym.vram_start
|
||||
< self.section_boundaries[".rodata"].end
|
||||
):
|
||||
assert self.section_boundaries[".rodata"].start is not None
|
||||
assert self.section_boundaries[".rodata"].end is not None
|
||||
|
||||
rodata_start: int = self.section_boundaries[".rodata"].start
|
||||
rodata_end: int = self.section_boundaries[".rodata"].end
|
||||
if rodata_start <= sym.vram_start < rodata_end:
|
||||
if func_addr not in self.rodata_syms:
|
||||
self.rodata_syms[func_addr] = []
|
||||
self.rodata_syms[func_addr].append(sym)
|
||||
|
||||
def handle_alls(self, segs: List[Segment], base_segs) -> bool:
|
||||
for i, elem in enumerate(segs):
|
||||
if elem.type.startswith("all_"):
|
||||
alls = []
|
||||
|
||||
rep_type = f"{elem.type[4:]}"
|
||||
replace_class = Segment.get_class_for_type(rep_type)
|
||||
|
||||
for base in base_segs.items():
|
||||
if isinstance(elem.rom_start, int) and isinstance(
|
||||
self.rom_start, int
|
||||
):
|
||||
# Shoddy rom to ram
|
||||
vram_start = elem.rom_start - self.rom_start + self.vram_start
|
||||
else:
|
||||
vram_start = "auto"
|
||||
rep: Segment = replace_class(
|
||||
rom_start=elem.rom_start,
|
||||
rom_end=elem.rom_end,
|
||||
type=rep_type,
|
||||
name=base[0],
|
||||
vram_start=vram_start,
|
||||
extract=False,
|
||||
given_subalign=self.given_subalign,
|
||||
exclusive_ram_id=self.get_exclusive_ram_id(),
|
||||
given_dir=self.given_dir,
|
||||
symbol_name_format=self.symbol_name_format,
|
||||
symbol_name_format_no_rom=self.symbol_name_format_no_rom,
|
||||
args=[],
|
||||
yaml={},
|
||||
)
|
||||
rep.sibling = base[1]
|
||||
rep.parent = self
|
||||
alls.append(rep)
|
||||
|
||||
# Insert alls into segs at i
|
||||
del segs[i]
|
||||
segs[i:i] = alls
|
||||
return True
|
||||
return False
|
||||
|
||||
# Find places we should automatically add "all_data" / "all_rodata" / "all_bss"
|
||||
def find_inserts(
|
||||
self, found_sections: typing.OrderedDict[str, Range]
|
||||
) -> "OrderedDict[str, int]":
|
||||
inserts: OrderedDict[str, int] = OrderedDict()
|
||||
|
||||
section_order = self.section_order.copy()
|
||||
section_order.remove(".text")
|
||||
|
||||
for i, section in enumerate(section_order):
|
||||
if section not in options.auto_all_sections():
|
||||
continue
|
||||
|
||||
if not found_sections[section].has_start():
|
||||
search_done = False
|
||||
for j in range(i - 1, -1, -1):
|
||||
end = found_sections[section_order[j]].end
|
||||
if end is not None:
|
||||
inserts[section] = end
|
||||
search_done = True
|
||||
break
|
||||
if not search_done:
|
||||
inserts[section] = -1
|
||||
pass
|
||||
|
||||
return inserts
|
||||
|
||||
def parse_subsegments(self, segment_yaml) -> List[Segment]:
|
||||
base_segments: OrderedDict[str, Segment] = OrderedDict()
|
||||
ret = []
|
||||
prev_start: RomAddr = -1
|
||||
inserts: OrderedDict[
|
||||
str, int
|
||||
] = (
|
||||
OrderedDict()
|
||||
) # Used to manually add "all_" types for sections not otherwise defined in the yaml
|
||||
|
||||
self.section_boundaries = OrderedDict(
|
||||
(s_name, Range()) for s_name in options.get_section_order()
|
||||
)
|
||||
|
||||
found_sections = OrderedDict(
|
||||
(s_name, Range()) for s_name in self.section_boundaries
|
||||
) # Stores yaml index where a section was first found
|
||||
found_sections.pop(".text")
|
||||
|
||||
if "subsegments" not in segment_yaml:
|
||||
return []
|
||||
|
||||
# Mark any manually added dot types
|
||||
cur_section = None
|
||||
|
||||
for i, subsection_yaml in enumerate(segment_yaml["subsegments"]):
|
||||
# rompos marker
|
||||
if isinstance(subsection_yaml, list) and len(subsection_yaml) == 1:
|
||||
continue
|
||||
|
||||
typ = Segment.parse_segment_type(subsection_yaml)
|
||||
if typ.startswith("all_"):
|
||||
typ = typ[4:]
|
||||
if not typ.startswith("."):
|
||||
typ = f".{typ}"
|
||||
|
||||
if typ in found_sections:
|
||||
if cur_section is None:
|
||||
# Starting point
|
||||
found_sections[typ].start = i
|
||||
cur_section = typ
|
||||
else:
|
||||
if cur_section != typ:
|
||||
# We're changing sections
|
||||
if found_sections[cur_section].has_end():
|
||||
log.error(
|
||||
f"Section {cur_section} end encountered but was already ended earlier!"
|
||||
)
|
||||
if found_sections[typ].has_start():
|
||||
log.error(
|
||||
f"Section {typ} start encounted but has already started earlier!"
|
||||
)
|
||||
|
||||
# End the current section
|
||||
found_sections[cur_section].end = i
|
||||
|
||||
# Start the next section
|
||||
found_sections[typ].start = i
|
||||
cur_section = typ
|
||||
|
||||
if cur_section is not None:
|
||||
found_sections[cur_section].end = -1
|
||||
|
||||
inserts = self.find_inserts(found_sections)
|
||||
|
||||
for i, subsection_yaml in enumerate(segment_yaml["subsegments"]):
|
||||
# rompos marker
|
||||
if isinstance(subsection_yaml, list) and len(subsection_yaml) == 1:
|
||||
continue
|
||||
|
||||
typ = Segment.parse_segment_type(subsection_yaml)
|
||||
start = Segment.parse_segment_start(subsection_yaml)
|
||||
|
||||
# Add dummy segments to be expanded later
|
||||
if typ.startswith("all_"):
|
||||
ret.append(Segment(start, "auto", typ, "", "auto"))
|
||||
continue
|
||||
|
||||
segment_class = Segment.get_class_for_type(typ)
|
||||
|
||||
end = self.get_next_seg_start(i, segment_yaml["subsegments"])
|
||||
|
||||
if (
|
||||
isinstance(start, int)
|
||||
and isinstance(prev_start, int)
|
||||
and start < prev_start
|
||||
):
|
||||
log.error(
|
||||
f"Error: Group segment {self.name} contains subsegments which are out of ascending rom order (0x{prev_start:X} followed by 0x{start:X})"
|
||||
)
|
||||
|
||||
vram = None
|
||||
if start != "auto":
|
||||
assert isinstance(start, int)
|
||||
vram = self.get_most_parent().rom_to_ram(start)
|
||||
|
||||
segment: Segment = Segment.from_yaml(
|
||||
segment_class, subsection_yaml, start, end, vram
|
||||
)
|
||||
segment.sibling = base_segments.get(segment.name, None)
|
||||
segment.parent = self
|
||||
|
||||
for i, section in enumerate(self.section_order):
|
||||
if not self.section_boundaries[section].has_start() and dotless_type(
|
||||
section
|
||||
) == dotless_type(segment.type):
|
||||
if i > 0:
|
||||
prev_section = self.section_order[i - 1]
|
||||
self.section_boundaries[prev_section].end = segment.vram_start
|
||||
self.section_boundaries[section].start = segment.vram_start
|
||||
|
||||
ret.append(segment)
|
||||
|
||||
# todo change
|
||||
if typ in CODE_TYPES:
|
||||
base_segments[segment.name] = segment
|
||||
|
||||
prev_start = start
|
||||
|
||||
# Add the automatic all_ sections
|
||||
orig_len = len(ret)
|
||||
for section in reversed(inserts):
|
||||
idx = inserts[section]
|
||||
|
||||
if idx == -1:
|
||||
idx = orig_len
|
||||
|
||||
# bss hack TODO maybe rethink
|
||||
if section == "bss" and self.vram_start is not None:
|
||||
rom_start = self.rom_end
|
||||
vram_start = self.vram_start + self.rom_end - self.rom_start
|
||||
else:
|
||||
rom_start = "auto"
|
||||
vram_start = "auto"
|
||||
|
||||
ret.insert(
|
||||
idx,
|
||||
(
|
||||
Segment(
|
||||
rom_start,
|
||||
"auto",
|
||||
"all_" + section,
|
||||
"",
|
||||
vram_start,
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
check = True
|
||||
while check:
|
||||
check = self.handle_alls(ret, base_segments)
|
||||
|
||||
# TODO why is this necessary?
|
||||
if (
|
||||
self.section_boundaries[".rodata"].has_start()
|
||||
and not self.section_boundaries[".rodata"].has_end()
|
||||
):
|
||||
assert self.vram_end is not None
|
||||
self.section_boundaries[".rodata"].end = self.vram_end
|
||||
|
||||
return ret
|
||||
|
||||
def scan(self, rom_bytes):
|
||||
# Always scan code first
|
||||
for sub in self.subsegments:
|
||||
if sub.type in CODE_TYPES and sub.should_scan():
|
||||
sub.scan(rom_bytes)
|
||||
|
||||
# Scan everyone else
|
||||
for sub in self.subsegments:
|
||||
if sub.type not in CODE_TYPES and sub.should_scan():
|
||||
sub.scan(rom_bytes)
|
||||
|
@ -1,77 +1,39 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import List, Optional
|
||||
import typing
|
||||
from util import options
|
||||
from segtypes.common.code import CommonSegCode
|
||||
from collections import OrderedDict
|
||||
import re
|
||||
|
||||
from capstone import (
|
||||
Cs,
|
||||
CS_ARCH_MIPS,
|
||||
CS_MODE_MIPS64,
|
||||
CS_MODE_BIG_ENDIAN,
|
||||
CS_MODE_MIPS32,
|
||||
CS_MODE_LITTLE_ENDIAN,
|
||||
CsInsn,
|
||||
)
|
||||
from capstone.mips import *
|
||||
import spimdisasm
|
||||
import rabbitizer
|
||||
|
||||
from segtypes.segment import Segment
|
||||
from util.compiler import SN64
|
||||
from util.symbols import Instruction, Symbol
|
||||
from util import log
|
||||
from util.symbols import Symbol
|
||||
from util import symbols
|
||||
|
||||
|
||||
# abstract class for c, asm, data, etc
|
||||
class CommonSegCodeSubsegment(Segment):
|
||||
double_mnemonics = ["ldc1", "sdc1"]
|
||||
word_mnemonics = ["addiu", "sw", "lw", "jtbl"]
|
||||
float_mnemonics = ["lwc1", "swc1"]
|
||||
short_mnemonics = ["addiu", "lh", "sh", "lhu"]
|
||||
byte_mnemonics = ["lb", "sb", "lbu"]
|
||||
reg_numbers = {
|
||||
"$zero": "$0",
|
||||
"$at": "$1",
|
||||
"$v0": "$2",
|
||||
"$v1": "$3",
|
||||
"$a0": "$4",
|
||||
"$a1": "$5",
|
||||
"$a2": "$6",
|
||||
"$a3": "$7",
|
||||
"$t0": "$8",
|
||||
"$t1": "$9",
|
||||
"$t2": "$10",
|
||||
"$t3": "$11",
|
||||
"$t4": "$12",
|
||||
"$t5": "$13",
|
||||
"$t6": "$14",
|
||||
"$t7": "$15",
|
||||
"$s0": "$16",
|
||||
"$s1": "$17",
|
||||
"$s2": "$18",
|
||||
"$s3": "$19",
|
||||
"$s4": "$20",
|
||||
"$s5": "$21",
|
||||
"$s6": "$22",
|
||||
"$s7": "$23",
|
||||
"$t8": "$24",
|
||||
"$t9": "$25",
|
||||
"$k0": "$26",
|
||||
"$k1": "$27",
|
||||
"$gp": "$28",
|
||||
"$sp": "$sp",
|
||||
"$fp": "$30",
|
||||
"$ra": "$31",
|
||||
}
|
||||
|
||||
if options.get_endianess() == "big":
|
||||
capstone_mode = CS_MODE_MIPS64 | CS_MODE_BIG_ENDIAN
|
||||
else:
|
||||
capstone_mode = CS_MODE_MIPS32 | CS_MODE_LITTLE_ENDIAN
|
||||
|
||||
md = Cs(CS_ARCH_MIPS, capstone_mode)
|
||||
md.detail = False
|
||||
md.skipdata = True
|
||||
double_mnemonics = [
|
||||
rabbitizer.InstrId.cpu_ldc1,
|
||||
rabbitizer.InstrId.cpu_sdc1,
|
||||
]
|
||||
word_mnemonics = [
|
||||
rabbitizer.InstrId.cpu_addiu,
|
||||
rabbitizer.InstrId.cpu_sw,
|
||||
rabbitizer.InstrId.cpu_lw,
|
||||
]
|
||||
float_mnemonics = [
|
||||
rabbitizer.InstrId.cpu_lwc1,
|
||||
rabbitizer.InstrId.cpu_swc1,
|
||||
]
|
||||
short_mnemonics = [
|
||||
rabbitizer.InstrId.cpu_addiu,
|
||||
rabbitizer.InstrId.cpu_lh,
|
||||
rabbitizer.InstrId.cpu_sh,
|
||||
rabbitizer.InstrId.cpu_lhu,
|
||||
]
|
||||
byte_mnemonics = [
|
||||
rabbitizer.InstrId.cpu_lb,
|
||||
rabbitizer.InstrId.cpu_sb,
|
||||
rabbitizer.InstrId.cpu_lbu,
|
||||
]
|
||||
|
||||
@property
|
||||
def needs_symbols(self) -> bool:
|
||||
@ -80,545 +42,148 @@ class CommonSegCodeSubsegment(Segment):
|
||||
def get_linker_section(self) -> str:
|
||||
return ".text"
|
||||
|
||||
@staticmethod
|
||||
def is_nops(insns: List[CsInsn]) -> bool:
|
||||
for insn in insns:
|
||||
if insn.mnemonic != "nop":
|
||||
return False
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def is_branch_insn(mnemonic):
|
||||
return (
|
||||
mnemonic.startswith("b")
|
||||
and not mnemonic.startswith("binsl")
|
||||
and not mnemonic == "break"
|
||||
) or mnemonic == "j"
|
||||
|
||||
@staticmethod
|
||||
def replace_reg_names(op_str):
|
||||
for regname, regnum in CommonSegCodeSubsegment.reg_numbers.items():
|
||||
op_str = op_str.replace(regname, regnum)
|
||||
return op_str
|
||||
|
||||
def scan_code(self, rom_bytes, is_asm=False):
|
||||
insns: List[CsInsn] = [
|
||||
insn
|
||||
for insn in CommonSegCodeSubsegment.md.disasm(
|
||||
rom_bytes[self.rom_start : self.rom_end], self.vram_start
|
||||
)
|
||||
]
|
||||
|
||||
self.funcs: typing.OrderedDict[int, Symbol] = self.process_insns(
|
||||
insns, self.rom_start, is_asm=is_asm
|
||||
self.text_section = spimdisasm.mips.sections.SectionText(
|
||||
symbols.spim_context,
|
||||
self.rom_start,
|
||||
self.rom_end,
|
||||
self.vram_start,
|
||||
self.name,
|
||||
rom_bytes,
|
||||
self.get_most_parent().rom_start,
|
||||
self.get_exclusive_ram_id(),
|
||||
)
|
||||
|
||||
# TODO: set these in creation
|
||||
for func in self.funcs.values():
|
||||
func.define = True
|
||||
func.local_only = True
|
||||
func.size = len(func.insns) * 4
|
||||
for symbol_list in self.seg_symbols.values():
|
||||
symbols.add_symbol_to_spim_section(self.text_section, symbol_list[0])
|
||||
|
||||
self.determine_symbols()
|
||||
for sym in symbols.all_symbols:
|
||||
if sym.user_declared:
|
||||
symbols.add_symbol_to_spim_section(self.text_section, sym)
|
||||
|
||||
def split_code(self, rom_bytes):
|
||||
self.text_section.isHandwritten = is_asm
|
||||
|
||||
self.text_section.analyze()
|
||||
self.text_section.setCommentOffset(self.rom_start)
|
||||
|
||||
for func in self.text_section.symbolList:
|
||||
assert isinstance(func, spimdisasm.mips.symbols.SymbolFunction)
|
||||
|
||||
self.process_insns(func)
|
||||
|
||||
# Process jumptable labels and pass them to spimdisasm
|
||||
self.gather_jumptable_labels(rom_bytes)
|
||||
return self.add_labels()
|
||||
for jtbl_label_vram in self.parent.jtbl_glabels_to_add:
|
||||
sym = self.create_symbol(
|
||||
jtbl_label_vram, True, type="jtbl_label", define=True
|
||||
)
|
||||
sym.type = "jtbl_label"
|
||||
symbols.add_symbol_to_spim_section(self.text_section, sym)
|
||||
|
||||
def process_insns(
|
||||
self, insns: List[CsInsn], rom_addr, is_asm=False
|
||||
) -> typing.OrderedDict[int, Symbol]:
|
||||
self,
|
||||
func_spim: spimdisasm.mips.symbols.SymbolFunction,
|
||||
):
|
||||
assert isinstance(self.parent, CommonSegCode)
|
||||
assert func_spim.vram is not None
|
||||
assert func_spim.vramEnd is not None
|
||||
self.parent: CommonSegCode = self.parent
|
||||
|
||||
ret: typing.OrderedDict[int, Symbol] = OrderedDict()
|
||||
symbols.create_symbol_from_spim_symbol(
|
||||
self.get_most_parent(), func_spim.contextSym
|
||||
)
|
||||
|
||||
end_func = False
|
||||
start_new_func = True
|
||||
labels = []
|
||||
|
||||
big_endian = options.get_endianess() == "big"
|
||||
|
||||
# Collect labels
|
||||
for insn in insns:
|
||||
if self.is_branch_insn(insn.mnemonic):
|
||||
op_str_split = insn.op_str.split(" ")
|
||||
branch_target = op_str_split[-1]
|
||||
branch_addr = int(branch_target, 0)
|
||||
labels.append((insn.address, branch_addr))
|
||||
# Gather symbols found by spimdisasm and create those symbols in splat's side
|
||||
for referenced_vram in func_spim.instrAnalyzer.referencedVrams:
|
||||
context_sym = self.text_section.getSymbol(
|
||||
referenced_vram, tryPlusOffset=False
|
||||
)
|
||||
if context_sym is not None:
|
||||
if context_sym.type == spimdisasm.common.SymbolSpecialType.jumptable:
|
||||
self.parent.jumptables[referenced_vram] = (
|
||||
func_spim.vram,
|
||||
func_spim.vramEnd,
|
||||
)
|
||||
symbols.create_symbol_from_spim_symbol(
|
||||
self.get_most_parent(), context_sym
|
||||
)
|
||||
|
||||
# Main loop
|
||||
for i, insn in enumerate(insns):
|
||||
mnemonic = insn.mnemonic
|
||||
op_str = insn.op_str
|
||||
for i, insn in enumerate(func_spim.instructions):
|
||||
instr_offset = i * 4
|
||||
|
||||
# If this is non-zero, disasm size insns
|
||||
hard_size = 0
|
||||
# update pointer accesses from this function
|
||||
if instr_offset in func_spim.instrAnalyzer.symbolInstrOffset:
|
||||
sym_address = func_spim.instrAnalyzer.symbolInstrOffset[instr_offset]
|
||||
|
||||
if start_new_func:
|
||||
func: Symbol = self.parent.create_symbol(insn.address, type="func")
|
||||
start_new_func = False
|
||||
|
||||
if func.size > 4:
|
||||
hard_size = func.size / 4
|
||||
|
||||
if options.get_compiler() == SN64:
|
||||
op_str = self.replace_reg_names(op_str)
|
||||
|
||||
if mnemonic == "move":
|
||||
# Let's get the actual instruction out
|
||||
idx = 3 if big_endian else 0
|
||||
opcode = insn.bytes[idx] & 0b00111111
|
||||
|
||||
if options.get_compiler() == SN64:
|
||||
op_str += ", $0"
|
||||
else:
|
||||
op_str += ", $zero"
|
||||
|
||||
if opcode == 37:
|
||||
mnemonic = "or"
|
||||
elif opcode == 45:
|
||||
mnemonic = "daddu"
|
||||
elif opcode == 33:
|
||||
mnemonic = "addu"
|
||||
else:
|
||||
print("INVALID INSTRUCTION " + str(insn), opcode)
|
||||
elif mnemonic == "jal":
|
||||
jal_addr = int(op_str, 0)
|
||||
jump_func = self.parent.create_symbol(
|
||||
jal_addr, type="func", reference=True
|
||||
context_sym = self.text_section.getSymbol(
|
||||
sym_address, tryPlusOffset=False
|
||||
)
|
||||
op_str = jump_func.name
|
||||
elif self.is_branch_insn(insn.mnemonic):
|
||||
op_str_split = op_str.split(" ")
|
||||
branch_target = op_str_split[-1]
|
||||
branch_target_int = int(branch_target, 0)
|
||||
if context_sym is not None:
|
||||
sym = symbols.create_symbol_from_spim_symbol(
|
||||
self.get_most_parent(), context_sym
|
||||
)
|
||||
|
||||
label_sym = self.parent.get_symbol(
|
||||
branch_target_int, type="label", reference=True, local_only=True
|
||||
)
|
||||
|
||||
if label_sym:
|
||||
label_name = label_sym.name
|
||||
else:
|
||||
self.parent.labels_to_add.add(branch_target_int)
|
||||
label_name = f".L{branch_target[2:].upper()}"
|
||||
|
||||
op_str = " ".join(op_str_split[:-1] + [label_name])
|
||||
elif mnemonic in ["mtc0", "mfc0", "mtc2", "mfc2"]:
|
||||
idx = 2 if big_endian else 1
|
||||
rd = (insn.bytes[idx] & 0xF8) >> 3
|
||||
op_str = op_str.split(" ")[0] + " $" + str(rd)
|
||||
elif (
|
||||
mnemonic == "break"
|
||||
and op_str in ["6", "7"]
|
||||
and options.get_compiler() == SN64
|
||||
and not is_asm
|
||||
):
|
||||
# SN64's assembler expands div to have break if dividing by zero
|
||||
# However, the break it generates is different than the one it generates with `break N`
|
||||
# So we replace break instrutions for SN64 with the exact word that the assembler generates when expanding div
|
||||
if op_str == "6":
|
||||
mnemonic = ".word 0x0006000D"
|
||||
op_str = ""
|
||||
elif op_str == "7":
|
||||
mnemonic = ".word 0x0007000D"
|
||||
op_str = ""
|
||||
elif (
|
||||
mnemonic in ["div", "divu"]
|
||||
and options.get_compiler() == SN64
|
||||
and not is_asm
|
||||
):
|
||||
# SN64's assembler also doesn't like assembling `div $0, a, b` with .set noat active
|
||||
# Removing the $0 fixes this issue
|
||||
if op_str.startswith("$0, "):
|
||||
op_str = op_str[4:]
|
||||
|
||||
func.insns.append(Instruction(insn, mnemonic, op_str, rom_addr))
|
||||
rom_addr += 4
|
||||
|
||||
size_remaining = hard_size - len(func.insns) if hard_size > 0 else 0
|
||||
|
||||
if mnemonic == "jr":
|
||||
# Record potential jtbl jumps
|
||||
if op_str not in ["$ra", "$31"]:
|
||||
self.parent.jtbl_jumps[insn.address] = op_str
|
||||
|
||||
keep_going = False
|
||||
for label in labels:
|
||||
if (label[0] > insn.address and label[1] <= insn.address) or (
|
||||
label[0] <= insn.address and label[1] > insn.address
|
||||
if any(
|
||||
insn.uniqueId in mnemonics
|
||||
for mnemonics in (
|
||||
self.double_mnemonics,
|
||||
self.word_mnemonics,
|
||||
self.float_mnemonics,
|
||||
self.short_mnemonics,
|
||||
self.byte_mnemonics,
|
||||
)
|
||||
):
|
||||
keep_going = True
|
||||
break
|
||||
if not keep_going and not size_remaining:
|
||||
end_func = True
|
||||
continue
|
||||
self.update_access_mnemonic(sym, insn)
|
||||
|
||||
# Stop here if a size was specified and we have disassembled up to the size
|
||||
if hard_size > 0 and size_remaining == 0:
|
||||
end_func = True
|
||||
if self.parent:
|
||||
self.parent.check_rodata_sym(func_spim.vram, sym)
|
||||
|
||||
if i < len(insns) - 1 and self.parent.get_symbol(
|
||||
insns[i + 1].address, local_only=True, type="func", dead=False
|
||||
):
|
||||
end_func = True
|
||||
|
||||
if end_func:
|
||||
if (
|
||||
self.is_nops(insns[i:])
|
||||
or i < len(insns) - 1
|
||||
and insns[i + 1].mnemonic != "nop"
|
||||
):
|
||||
end_func = False
|
||||
start_new_func = True
|
||||
ret[func.vram_start] = func
|
||||
|
||||
# Add the last function (or append nops to the previous one)
|
||||
if not self.is_nops([insn.instruction for insn in func.insns]):
|
||||
ret[func.vram_start] = func
|
||||
else:
|
||||
next(reversed(ret.values())).insns.extend(func.insns)
|
||||
|
||||
return ret
|
||||
|
||||
def update_access_mnemonic(self, sym, mnemonic):
|
||||
def update_access_mnemonic(self, sym: Symbol, insn: rabbitizer.Instruction):
|
||||
if not sym.access_mnemonic:
|
||||
sym.access_mnemonic = mnemonic
|
||||
elif sym.access_mnemonic == "addiu":
|
||||
sym.access_mnemonic = mnemonic
|
||||
sym.access_mnemonic = insn.uniqueId
|
||||
elif sym.access_mnemonic in self.double_mnemonics:
|
||||
return
|
||||
elif (
|
||||
sym.access_mnemonic in self.float_mnemonics
|
||||
and mnemonic in self.double_mnemonics
|
||||
and insn.uniqueId in self.double_mnemonics
|
||||
):
|
||||
sym.access_mnemonic = mnemonic
|
||||
sym.access_mnemonic = insn.uniqueId
|
||||
elif sym.access_mnemonic == rabbitizer.InstrId.cpu_addiu:
|
||||
sym.access_mnemonic = insn.uniqueId
|
||||
elif sym.access_mnemonic in self.short_mnemonics:
|
||||
return
|
||||
elif sym.access_mnemonic in self.byte_mnemonics:
|
||||
return
|
||||
else:
|
||||
sym.access_mnemonic = mnemonic
|
||||
sym.access_mnemonic = insn.uniqueId
|
||||
|
||||
# Determine symbols
|
||||
def determine_symbols(self):
|
||||
hi_lo_max_distance = options.hi_lo_max_distance()
|
||||
def print_file_boundaries(self):
|
||||
if not options.find_file_boundaries():
|
||||
return
|
||||
|
||||
for func_addr in self.funcs:
|
||||
func = self.funcs[func_addr]
|
||||
func_end_addr = func.insns[-1].instruction.address + 4
|
||||
for in_file_offset in self.text_section.fileBoundaries:
|
||||
if (in_file_offset % 16) != 0:
|
||||
continue
|
||||
|
||||
possible_jtbl_jumps = [
|
||||
(k, v)
|
||||
for k, v in self.parent.jtbl_jumps.items()
|
||||
if k >= func_addr and k < func_end_addr
|
||||
]
|
||||
possible_jtbl_jumps.sort(key=lambda x: x[0])
|
||||
if not self.parent.reported_file_split:
|
||||
self.parent.reported_file_split = True
|
||||
|
||||
for i in range(len(func.insns)):
|
||||
hi_insn: CsInsn = func.insns[i].instruction
|
||||
# Look up for the last function in this boundary
|
||||
func_addr = 0
|
||||
for func in self.text_section.symbolList:
|
||||
funcOffset = func.inFileOffset - self.text_section.inFileOffset
|
||||
if in_file_offset == funcOffset:
|
||||
break
|
||||
func_addr = func.vram
|
||||
|
||||
# Ensure the first item in the list is always ahead of where we're looking
|
||||
while (
|
||||
len(possible_jtbl_jumps) > 0
|
||||
and possible_jtbl_jumps[0][0] < hi_insn.address
|
||||
):
|
||||
del possible_jtbl_jumps[0]
|
||||
|
||||
# Find gp relative reads and writes e.g lw $a1, 0x670($gp)
|
||||
if hi_insn.op_str.endswith("($gp)"):
|
||||
gp_base = options.get_gp()
|
||||
if gp_base is None:
|
||||
log.error(
|
||||
"gp_value not set in yaml, can't calculate %gp_rel reloc value for "
|
||||
+ hi_insn.op_str
|
||||
)
|
||||
|
||||
op_split = hi_insn.op_str.split(", ")
|
||||
gp_offset = op_split[1][:-5] # extract the 0x670 part
|
||||
if len(gp_offset) == 0:
|
||||
gp_offset = 0
|
||||
else:
|
||||
gp_offset = int(gp_offset, 16)
|
||||
symbol_addr = gp_base + gp_offset
|
||||
|
||||
sym = self.parent.create_symbol(
|
||||
symbol_addr, offsets=True, reference=True
|
||||
)
|
||||
offset = symbol_addr - sym.vram_start
|
||||
offset_str = f"+0x{offset:X}"
|
||||
|
||||
if self.parent:
|
||||
self.parent.check_rodata_sym(func_addr, sym)
|
||||
|
||||
self.update_access_mnemonic(sym, hi_insn.mnemonic)
|
||||
|
||||
func.insns[i].is_gp = True
|
||||
func.insns[i].hi_lo_sym = sym
|
||||
func.insns[i].sym_offset_str = offset_str
|
||||
# All hi/lo pairs start with a lui
|
||||
elif hi_insn.mnemonic == "lui":
|
||||
op_split = hi_insn.op_str.split(", ")
|
||||
hi_reg = op_split[0]
|
||||
|
||||
if not op_split[1].startswith("0x"):
|
||||
continue
|
||||
|
||||
lui_val = int(op_split[1], 0)
|
||||
|
||||
# Assumes all luis are going to load from 0x80000000 or higher (maybe false)
|
||||
if lui_val >= 0x8000:
|
||||
# Iterate over the next few instructions to see if we can find a matching lo
|
||||
for j in range(
|
||||
i + 1, min(i + hi_lo_max_distance, len(func.insns))
|
||||
):
|
||||
lo_insn = func.insns[j].instruction
|
||||
|
||||
s_op_split = lo_insn.op_str.split(", ")
|
||||
|
||||
if lo_insn.mnemonic == "lui" and hi_reg == s_op_split[0]:
|
||||
break
|
||||
|
||||
if lo_insn.mnemonic in ["addiu", "ori"]:
|
||||
lo_reg = s_op_split[-2]
|
||||
else:
|
||||
lo_reg = s_op_split[-1][
|
||||
s_op_split[-1].rfind("(") + 1 : -1
|
||||
]
|
||||
|
||||
if hi_reg == lo_reg:
|
||||
if lo_insn.mnemonic not in [
|
||||
"addiu",
|
||||
"lw",
|
||||
"sw",
|
||||
"lh",
|
||||
"sh",
|
||||
"lhu",
|
||||
"lb",
|
||||
"sb",
|
||||
"lbu",
|
||||
"lwc1",
|
||||
"swc1",
|
||||
"ldc1",
|
||||
"sdc1",
|
||||
]:
|
||||
break
|
||||
|
||||
# Match!
|
||||
reg_ext = ""
|
||||
|
||||
# I forgot what this is doing
|
||||
junk_search = re.search(r"[\(]", s_op_split[-1])
|
||||
if junk_search is not None:
|
||||
if junk_search.start() == 0:
|
||||
break
|
||||
s_str = s_op_split[-1][: junk_search.start()]
|
||||
reg_ext = s_op_split[-1][junk_search.start() :]
|
||||
else:
|
||||
s_str = s_op_split[-1]
|
||||
|
||||
if options.get_compiler() == SN64:
|
||||
reg_ext = CommonSegCodeSubsegment.replace_reg_names(
|
||||
reg_ext
|
||||
)
|
||||
|
||||
symbol_addr = (lui_val * 0x10000) + int(s_str, 0)
|
||||
|
||||
sym: Optional[Symbol] = None
|
||||
offset_str = ""
|
||||
|
||||
# If the symbol is likely in the rodata section
|
||||
if (
|
||||
not self.parent.text_follows_rodata
|
||||
and symbol_addr > func_addr
|
||||
) or (
|
||||
self.parent.text_follows_rodata
|
||||
and symbol_addr < func_addr
|
||||
):
|
||||
# Sanity check that the symbol is within this segment's vram
|
||||
if (
|
||||
self.parent.vram_end
|
||||
and symbol_addr < self.parent.vram_end
|
||||
):
|
||||
# If we've seen possible jumps to a jumptable and this symbol isn't too close to the end of the function
|
||||
if (
|
||||
len(possible_jtbl_jumps) > 0
|
||||
and func_end_addr - lo_insn.address >= 0x30
|
||||
):
|
||||
for jump in possible_jtbl_jumps:
|
||||
if jump[1] == s_op_split[0]:
|
||||
dist_to_jump = (
|
||||
possible_jtbl_jumps[0][0]
|
||||
- lo_insn.address
|
||||
)
|
||||
if dist_to_jump <= 16:
|
||||
sym = self.parent.create_symbol(
|
||||
symbol_addr,
|
||||
reference=True,
|
||||
type="jtbl",
|
||||
local_only=True,
|
||||
)
|
||||
|
||||
self.parent.jumptables[
|
||||
symbol_addr
|
||||
] = (func_addr, func_end_addr)
|
||||
break
|
||||
|
||||
if not sym:
|
||||
sym = self.parent.create_symbol(
|
||||
symbol_addr, offsets=True, reference=True
|
||||
)
|
||||
offset = symbol_addr - sym.vram_start
|
||||
if offset != 0:
|
||||
offset_str = f"+0x{offset:X}"
|
||||
|
||||
if self.parent:
|
||||
self.parent.check_rodata_sym(func_addr, sym)
|
||||
|
||||
self.update_access_mnemonic(sym, lo_insn.mnemonic)
|
||||
|
||||
func.insns[i].is_hi = True
|
||||
func.insns[i].hi_lo_sym = sym
|
||||
func.insns[i].sym_offset_str = offset_str
|
||||
|
||||
func.insns[j].is_lo = True
|
||||
func.insns[j].hi_lo_sym = sym
|
||||
func.insns[j].sym_offset_str = offset_str
|
||||
func.insns[j].hi_lo_reg = reg_ext
|
||||
break
|
||||
|
||||
def add_labels(self):
|
||||
ret = {}
|
||||
|
||||
function_macro = options.get_asm_function_macro()
|
||||
data_macro = options.get_asm_data_macro()
|
||||
|
||||
for func_addr in self.funcs:
|
||||
func_text = []
|
||||
func = self.funcs[func_addr]
|
||||
|
||||
# Add function label
|
||||
func_text.append(f"{function_macro} {func.name}")
|
||||
|
||||
if options.get_compiler() == SN64:
|
||||
func_text.append(f".ent {func.name}")
|
||||
func_text.append(f"{func.name}:")
|
||||
|
||||
indent_next = False
|
||||
|
||||
mnemonic_ljust = options.mnemonic_ljust()
|
||||
rom_addr_padding = options.rom_address_padding()
|
||||
|
||||
for insn in func.insns:
|
||||
insn_addr = insn.instruction.address
|
||||
# Add a label if we need one
|
||||
if insn_addr in self.parent.jtbl_glabels_to_add:
|
||||
func_text.append(f"{data_macro} L{insn_addr:X}_{insn.rom_addr:X}")
|
||||
elif insn_addr in self.parent.labels_to_add:
|
||||
self.parent.labels_to_add.remove(insn_addr)
|
||||
func_text.append(".L{:X}:".format(insn_addr))
|
||||
|
||||
if rom_addr_padding:
|
||||
rom_str = "{0:0{1}X}".format(insn.rom_addr, rom_addr_padding)
|
||||
else:
|
||||
rom_str = "{:X}".format(insn.rom_addr)
|
||||
|
||||
if options.get_compiler() == SN64:
|
||||
asm_comment = ""
|
||||
else:
|
||||
asm_comment = "/* {} {:X} {} */".format(
|
||||
rom_str, insn_addr, insn.instruction.bytes.hex().upper()
|
||||
)
|
||||
|
||||
if insn.is_hi:
|
||||
assert insn.hi_lo_sym
|
||||
op_str = ", ".join(
|
||||
insn.op_str.split(", ")[:-1]
|
||||
+ [f"%hi({insn.hi_lo_sym.name}{insn.sym_offset_str})"]
|
||||
)
|
||||
elif insn.is_lo:
|
||||
assert insn.hi_lo_sym
|
||||
op_str = ", ".join(
|
||||
insn.op_str.split(", ")[:-1]
|
||||
+ [
|
||||
f"%lo({insn.hi_lo_sym.name}{insn.sym_offset_str}){insn.hi_lo_reg}"
|
||||
]
|
||||
)
|
||||
elif insn.is_gp:
|
||||
op_str = ", ".join(
|
||||
insn.op_str.split(", ")[:-1]
|
||||
+ [f"%gp_rel({insn.hi_lo_sym.name}{insn.sym_offset_str})($gp)"]
|
||||
)
|
||||
else:
|
||||
op_str = insn.op_str
|
||||
|
||||
if self.is_branch_insn(insn.instruction.mnemonic):
|
||||
branch_addr = int(insn.instruction.op_str.split(",")[-1].strip(), 0)
|
||||
if branch_addr in self.parent.jtbl_glabels_to_add:
|
||||
label_str = f"L{branch_addr:X}_{self.ram_to_rom(branch_addr):X}"
|
||||
op_str = ", ".join(insn.op_str.split(", ")[:-1] + [label_str])
|
||||
|
||||
insn_text = insn.mnemonic
|
||||
if indent_next:
|
||||
indent_next = False
|
||||
insn_text = " " + insn_text
|
||||
|
||||
asm_insn_text = " {}{}".format(
|
||||
insn_text.ljust(mnemonic_ljust), op_str
|
||||
).rstrip()
|
||||
|
||||
func_text.append(asm_comment + asm_insn_text)
|
||||
|
||||
if (
|
||||
insn.instruction.mnemonic != "branch"
|
||||
and insn.instruction.mnemonic.startswith("b")
|
||||
or insn.instruction.mnemonic.startswith("j")
|
||||
):
|
||||
indent_next = True
|
||||
|
||||
end_label = options.get_asm_end_label()
|
||||
|
||||
if end_label:
|
||||
func_text.append(f"{end_label} {func.name}")
|
||||
|
||||
ret[func_addr] = (func_text, func.rom)
|
||||
|
||||
if options.find_file_boundaries():
|
||||
# If this is not the last function in the file
|
||||
if func_addr != list(self.funcs.keys())[-1]:
|
||||
|
||||
# Find where the function returns
|
||||
jr_pos: Optional[int] = None
|
||||
for i, insn in enumerate(reversed(func.insns)):
|
||||
if (
|
||||
insn.instruction.mnemonic == "jr"
|
||||
and insn.instruction.op_str in ["$ra", "$31"]
|
||||
):
|
||||
jr_pos = i
|
||||
break
|
||||
|
||||
# If there is more than 1 nop after the return
|
||||
if (
|
||||
jr_pos is not None
|
||||
and jr_pos > 1
|
||||
and self.is_nops(
|
||||
[insn.instruction for insn in func.insns[-jr_pos + 1 :]]
|
||||
)
|
||||
):
|
||||
new_file_addr = func.insns[-1].rom_addr + 4
|
||||
if (new_file_addr % 16) == 0:
|
||||
if not self.parent.reported_file_split:
|
||||
self.parent.reported_file_split = True
|
||||
print(
|
||||
f"Segment {self.name}, function at vram {func_addr:X} ends with extra nops, indicating a likely file split."
|
||||
)
|
||||
print(
|
||||
"File split suggestions for this segment will follow in config yaml format:"
|
||||
)
|
||||
print(f" - [0x{new_file_addr:X}, asm]")
|
||||
|
||||
return ret
|
||||
print(
|
||||
f"Segment {self.name}, function at vram {func_addr:X} ends with extra nops, indicating a likely file split."
|
||||
)
|
||||
print(
|
||||
"File split suggestions for this segment will follow in config yaml format:"
|
||||
)
|
||||
print(f" - [0x{self.rom_start+in_file_offset:X}, asm]")
|
||||
|
||||
def gather_jumptable_labels(self, rom_bytes):
|
||||
# TODO: use the seg_symbols for this
|
||||
|
@ -3,6 +3,7 @@ from segtypes.common.codesubsegment import CommonSegCodeSubsegment
|
||||
from segtypes.common.group import CommonSegGroup
|
||||
from pathlib import Path
|
||||
from typing import List, Optional
|
||||
import rabbitizer
|
||||
from util.symbols import Symbol
|
||||
from util import floats, options
|
||||
|
||||
@ -80,13 +81,15 @@ class CommonSegData(CommonSegCodeSubsegment, CommonSegGroup):
|
||||
new_sym_ram_start = self.get_most_parent().rom_to_ram(
|
||||
new_sym_rom_start
|
||||
)
|
||||
sym.size = new_sym_rom_start - sym.rom
|
||||
assert sym.rom is not None
|
||||
assert new_sym_ram_start is not None
|
||||
sym.given_size = new_sym_rom_start - sym.rom
|
||||
|
||||
# It turns out this isn't a valid jump table, so create a new symbol where it breaks
|
||||
syms.insert(
|
||||
i + 1,
|
||||
self.get_most_parent().create_symbol(
|
||||
new_sym_ram_start, define=True, local_only=True
|
||||
self.create_symbol(
|
||||
new_sym_ram_start, True, define=True, local_only=True
|
||||
),
|
||||
)
|
||||
return False
|
||||
@ -102,12 +105,13 @@ class CommonSegData(CommonSegCodeSubsegment, CommonSegGroup):
|
||||
endian = options.get_endianess()
|
||||
|
||||
# Find inter-data symbols
|
||||
assert isinstance(self.rom_start, int) and isinstance(self.rom_end, int)
|
||||
for i in range(self.rom_start, self.rom_end, 4):
|
||||
bits = int.from_bytes(rom_bytes[i : i + 4], endian)
|
||||
if self.contains_vram(bits):
|
||||
symset.add(
|
||||
self.get_most_parent().create_symbol(
|
||||
bits, define=True, local_only=True
|
||||
self.create_symbol(
|
||||
bits, in_segment=True, define=True, local_only=True
|
||||
)
|
||||
)
|
||||
|
||||
@ -123,12 +127,13 @@ class CommonSegData(CommonSegCodeSubsegment, CommonSegGroup):
|
||||
if len(ret) == 0 or ret[0].vram_start != self.vram_start:
|
||||
ret.insert(
|
||||
0,
|
||||
self.get_most_parent().create_symbol(
|
||||
self.vram_start, define=True, local_only=True
|
||||
self.create_symbol(
|
||||
self.vram_start, in_segment=True, define=True, local_only=True
|
||||
),
|
||||
)
|
||||
|
||||
# Make a dummy symbol here that marks the end of the previous symbol's disasm range
|
||||
assert self.vram_end is not None
|
||||
ret.append(Symbol(self.vram_end))
|
||||
|
||||
while True:
|
||||
@ -231,6 +236,10 @@ class CommonSegData(CommonSegCodeSubsegment, CommonSegGroup):
|
||||
if not jtbl_func:
|
||||
return False
|
||||
|
||||
# A label of a jump table shouldn't point to the start of the function
|
||||
if word == jtbl_func.vram_start:
|
||||
return False
|
||||
|
||||
for i in range(4, len(bytes), 4):
|
||||
word = int.from_bytes(bytes[i : i + 4], options.get_endianess())
|
||||
|
||||
@ -240,6 +249,10 @@ class CommonSegData(CommonSegCodeSubsegment, CommonSegGroup):
|
||||
if i < min_jtbl_len or any(b != 0 for b in bytes[i:]):
|
||||
return False
|
||||
|
||||
# A label of a jump table shouldn't point to the start of the function
|
||||
if word == jtbl_func.vram_start:
|
||||
return False
|
||||
|
||||
# Mark this symbol as a jump table and record the jump table for later
|
||||
sym.type = "jtbl"
|
||||
most_parent.jumptables[sym.vram_start] = (
|
||||
@ -287,14 +300,13 @@ class CommonSegData(CommonSegCodeSubsegment, CommonSegGroup):
|
||||
if bits == 0:
|
||||
byte_str = "0"
|
||||
else:
|
||||
rom_addr = self.get_most_parent().ram_to_rom(bits)
|
||||
|
||||
if rom_addr:
|
||||
byte_str = f"L{bits:X}_{rom_addr:X}"
|
||||
sym = self.get_symbol(bits, True)
|
||||
if sym is not None:
|
||||
byte_str = sym.name
|
||||
else:
|
||||
byte_str = f"0x{bits:X}"
|
||||
elif slen == 4 and bits >= 0x80000000:
|
||||
sym = self.get_most_parent().get_symbol(bits, reference=True)
|
||||
sym = self.get_symbol(bits, reference=True)
|
||||
if sym:
|
||||
byte_str = sym.name
|
||||
else:
|
||||
@ -336,12 +348,13 @@ class CommonSegData(CommonSegCodeSubsegment, CommonSegGroup):
|
||||
|
||||
for i in range(len(syms) - 1):
|
||||
mnemonic = syms[i].access_mnemonic
|
||||
sym = self.get_most_parent().create_symbol(
|
||||
syms[i].vram_start, define=True, local_only=True
|
||||
sym = self.create_symbol(
|
||||
syms[i].vram_start, in_segment=True, define=True, local_only=True
|
||||
)
|
||||
|
||||
dis_start = self.get_most_parent().ram_to_rom(syms[i].vram_start)
|
||||
dis_end = self.get_most_parent().ram_to_rom(syms[i + 1].vram_start)
|
||||
assert dis_start is not None and dis_end is not None
|
||||
sym_len = dis_end - dis_start
|
||||
|
||||
if self.type == "bss":
|
||||
@ -350,7 +363,10 @@ class CommonSegData(CommonSegCodeSubsegment, CommonSegGroup):
|
||||
sym_bytes = rom_bytes[dis_start:dis_end]
|
||||
|
||||
# Checking if the mnemonic is addiu may be too picky - we'll see
|
||||
if self.is_valid_ascii(sym_bytes) and mnemonic == "addiu":
|
||||
if (
|
||||
self.is_valid_ascii(sym_bytes)
|
||||
and mnemonic == rabbitizer.InstrId.cpu_addiu
|
||||
):
|
||||
stype = "ascii"
|
||||
elif sym.type == "jtbl":
|
||||
stype = "jtbl"
|
||||
@ -396,7 +412,7 @@ class CommonSegData(CommonSegCodeSubsegment, CommonSegGroup):
|
||||
# Hint to the user that we are now in the .rodata section and no longer in the .data section (assuming rodata follows data)
|
||||
if (
|
||||
not rodata_encountered
|
||||
and mnemonic == "jtbl"
|
||||
and stype == "jtbl"
|
||||
and self.get_most_parent().rodata_follows_data
|
||||
):
|
||||
rodata_encountered = True
|
||||
|
@ -1,14 +1,8 @@
|
||||
from collections import OrderedDict
|
||||
from typing import List, Dict, Optional
|
||||
import typing
|
||||
from typing import List, Optional
|
||||
from segtypes.common.linker_section import dotless_type
|
||||
from util.range import Range
|
||||
from util import log, options
|
||||
from segtypes.common.segment import CommonSegment
|
||||
from segtypes.segment import RomAddr, Segment
|
||||
from util.symbols import Symbol
|
||||
|
||||
CODE_TYPES = ["c", "asm", "hasm"]
|
||||
from util import log
|
||||
|
||||
|
||||
class CommonSegGroup(CommonSegment):
|
||||
@ -21,8 +15,10 @@ class CommonSegGroup(CommonSegment):
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
given_is_overlay,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
symbol_name_format,
|
||||
symbol_name_format_no_rom,
|
||||
args,
|
||||
yaml,
|
||||
):
|
||||
@ -34,85 +30,15 @@ class CommonSegGroup(CommonSegment):
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
given_is_overlay,
|
||||
given_dir,
|
||||
args,
|
||||
yaml,
|
||||
exclusive_ram_id=exclusive_ram_id,
|
||||
given_dir=given_dir,
|
||||
symbol_name_format=symbol_name_format,
|
||||
symbol_name_format_no_rom=symbol_name_format_no_rom,
|
||||
args=args,
|
||||
yaml=yaml,
|
||||
)
|
||||
|
||||
self.rodata_syms: Dict[int, List[Symbol]] = {}
|
||||
|
||||
# TODO: move this to CommonSegCode
|
||||
self.section_boundaries = OrderedDict(
|
||||
(s_name, Range()) for s_name in options.get_section_order()
|
||||
)
|
||||
self.subsegments = self.parse_subsegments(yaml)
|
||||
|
||||
@property
|
||||
def needs_symbols(self) -> bool:
|
||||
for seg in self.subsegments:
|
||||
if seg.needs_symbols:
|
||||
return True
|
||||
return False
|
||||
|
||||
def handle_alls(self, segs: List[Segment], base_segs) -> bool:
|
||||
for i, elem in enumerate(segs):
|
||||
if elem.type.startswith("all_"):
|
||||
alls = []
|
||||
|
||||
rep_type = f"{elem.type[4:]}"
|
||||
replace_class = Segment.get_class_for_type(rep_type)
|
||||
|
||||
for base in base_segs.items():
|
||||
if isinstance(elem.rom_start, int):
|
||||
# Shoddy rom to ram
|
||||
vram_start = elem.rom_start - self.rom_start + self.vram_start
|
||||
else:
|
||||
vram_start = "auto"
|
||||
rep = replace_class(
|
||||
elem.rom_start,
|
||||
elem.rom_end,
|
||||
rep_type,
|
||||
base[0],
|
||||
vram_start,
|
||||
False,
|
||||
self.given_subalign,
|
||||
self.given_is_overlay,
|
||||
self.given_dir,
|
||||
[],
|
||||
{},
|
||||
)
|
||||
rep.sibling = base[1]
|
||||
rep.parent = self
|
||||
alls.append(rep)
|
||||
|
||||
# Insert alls into segs at i
|
||||
del segs[i]
|
||||
segs[i:i] = alls
|
||||
return True
|
||||
return False
|
||||
|
||||
def find_inserts(
|
||||
self, found_sections: typing.OrderedDict[str, Range]
|
||||
) -> "OrderedDict[str, int]":
|
||||
inserts = OrderedDict()
|
||||
|
||||
section_order = self.section_order
|
||||
section_order.remove(".text")
|
||||
|
||||
for i, section in enumerate(section_order):
|
||||
if not found_sections[section].has_start():
|
||||
search_done = False
|
||||
for j in range(i - 1, -1, -1):
|
||||
if found_sections[section_order[j]].has_end():
|
||||
inserts[section] = found_sections[section_order[j]].end
|
||||
search_done = True
|
||||
break
|
||||
if not search_done:
|
||||
inserts[section] = -1
|
||||
pass
|
||||
|
||||
return inserts
|
||||
self.subsegments: List[Segment] = self.parse_subsegments(yaml)
|
||||
|
||||
def get_next_seg_start(self, i, subsegment_yamls):
|
||||
return (
|
||||
@ -121,87 +47,25 @@ class CommonSegGroup(CommonSegment):
|
||||
else Segment.parse_segment_start(subsegment_yamls[i + 1])
|
||||
)
|
||||
|
||||
def parse_subsegments(self, segment_yaml) -> List[Segment]:
|
||||
base_segments: OrderedDict[str, Segment] = OrderedDict()
|
||||
ret = []
|
||||
def parse_subsegments(self, yaml) -> List[Segment]:
|
||||
ret: List[Segment] = []
|
||||
|
||||
if not yaml or "subsegments" not in yaml:
|
||||
return ret
|
||||
|
||||
prev_start: RomAddr = -1
|
||||
inserts: OrderedDict[
|
||||
str, int
|
||||
] = (
|
||||
OrderedDict()
|
||||
) # Used to manually add "all_" types for sections not otherwise defined in the yaml
|
||||
|
||||
found_sections = OrderedDict(
|
||||
(s_name, Range()) for s_name in self.section_boundaries
|
||||
) # Stores yaml index where a section was first found
|
||||
|
||||
if "subsegments" not in segment_yaml:
|
||||
return []
|
||||
|
||||
# Mark any manually added dot types
|
||||
if options.auto_all_sections():
|
||||
cur_section = None
|
||||
|
||||
for i, subsection_yaml in enumerate(segment_yaml["subsegments"]):
|
||||
# rompos marker
|
||||
if isinstance(subsection_yaml, list) and len(subsection_yaml) == 1:
|
||||
if cur_section is not None:
|
||||
# End the current section
|
||||
found_sections[cur_section].end = i
|
||||
cur_section = None
|
||||
continue
|
||||
|
||||
typ = Segment.parse_segment_type(subsection_yaml)
|
||||
if typ.startswith("all_"):
|
||||
typ = typ[4:]
|
||||
if not typ.startswith("."):
|
||||
typ = f".{typ}"
|
||||
|
||||
if typ in found_sections:
|
||||
if cur_section is None:
|
||||
# Starting point
|
||||
found_sections[typ].start = i
|
||||
cur_section = typ
|
||||
else:
|
||||
if cur_section != typ:
|
||||
# We're changing sections
|
||||
if found_sections[cur_section].has_end():
|
||||
log.error(
|
||||
f"Section {cur_section} end encountered but was already ended earlier!"
|
||||
)
|
||||
if found_sections[typ].has_start():
|
||||
log.error(
|
||||
f"Section {typ} start encounted but has already started earlier!"
|
||||
)
|
||||
|
||||
# End the current section
|
||||
found_sections[cur_section].end = i
|
||||
|
||||
# Start the next section
|
||||
found_sections[typ].start = i
|
||||
cur_section = typ
|
||||
|
||||
if cur_section is not None:
|
||||
found_sections[cur_section].end = len(segment_yaml["subsegments"])
|
||||
|
||||
inserts = self.find_inserts(found_sections)
|
||||
|
||||
for i, subsection_yaml in enumerate(segment_yaml["subsegments"]):
|
||||
# rompos marker
|
||||
for i, subsection_yaml in enumerate(yaml["subsegments"]):
|
||||
# End of previous segment
|
||||
if isinstance(subsection_yaml, list) and len(subsection_yaml) == 1:
|
||||
continue
|
||||
|
||||
typ = Segment.parse_segment_type(subsection_yaml)
|
||||
start = Segment.parse_segment_start(subsection_yaml)
|
||||
|
||||
# Add dummy segments to be expanded later
|
||||
if typ.startswith("all_"):
|
||||
ret.append(Segment(start, "auto", typ, "", "auto"))
|
||||
continue
|
||||
|
||||
segment_class = Segment.get_class_for_type(typ)
|
||||
|
||||
end = self.get_next_seg_start(i, segment_yaml["subsegments"])
|
||||
end = self.get_next_seg_start(i, yaml["subsegments"])
|
||||
|
||||
if (
|
||||
isinstance(start, int)
|
||||
@ -220,72 +84,26 @@ class CommonSegGroup(CommonSegment):
|
||||
segment: Segment = Segment.from_yaml(
|
||||
segment_class, subsection_yaml, start, end, vram
|
||||
)
|
||||
segment.sibling = base_segments.get(segment.name, None)
|
||||
segment.parent = self
|
||||
|
||||
for i, section in enumerate(self.section_order):
|
||||
if not self.section_boundaries[section].has_start() and dotless_type(
|
||||
section
|
||||
) == dotless_type(segment.type):
|
||||
if i > 0:
|
||||
prev_section = self.section_order[i - 1]
|
||||
self.section_boundaries[prev_section].end = segment.vram_start
|
||||
self.section_boundaries[section].start = segment.vram_start
|
||||
|
||||
ret.append(segment)
|
||||
|
||||
# todo change
|
||||
if typ in CODE_TYPES:
|
||||
base_segments[segment.name] = segment
|
||||
|
||||
prev_start = start
|
||||
|
||||
# Add the automatic all_ sections
|
||||
orig_len = len(ret)
|
||||
for section in reversed(inserts):
|
||||
idx = inserts[section]
|
||||
|
||||
if idx == -1:
|
||||
idx = orig_len
|
||||
|
||||
# bss hack TODO maybe rethink
|
||||
if section == "bss" and self.vram_start is not None:
|
||||
rom_start = self.rom_end
|
||||
vram_start = self.vram_start + self.rom_end - self.rom_start
|
||||
else:
|
||||
rom_start = "auto"
|
||||
vram_start = "auto"
|
||||
|
||||
ret.insert(
|
||||
idx, (Segment(rom_start, "auto", "all_" + section, "", vram_start))
|
||||
)
|
||||
|
||||
check = True
|
||||
while check:
|
||||
check = self.handle_alls(ret, base_segments)
|
||||
|
||||
# TODO why is this necessary?
|
||||
if (
|
||||
self.section_boundaries[".rodata"].has_start()
|
||||
and not self.section_boundaries[".rodata"].has_end()
|
||||
):
|
||||
assert self.vram_end is not None
|
||||
self.section_boundaries[".rodata"].end = self.vram_end
|
||||
|
||||
return ret
|
||||
|
||||
@property
|
||||
def needs_symbols(self) -> bool:
|
||||
for seg in self.subsegments:
|
||||
if seg.needs_symbols:
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_linker_entries(self):
|
||||
return [entry for sub in self.subsegments for entry in sub.get_linker_entries()]
|
||||
|
||||
def scan(self, rom_bytes):
|
||||
# Always scan code first
|
||||
for sub in self.subsegments:
|
||||
if sub.type in CODE_TYPES and sub.should_scan():
|
||||
sub.scan(rom_bytes)
|
||||
|
||||
# Scan everyone else
|
||||
for sub in self.subsegments:
|
||||
if sub.type not in CODE_TYPES and sub.should_scan():
|
||||
if sub.should_scan():
|
||||
sub.scan(rom_bytes)
|
||||
|
||||
def split(self, rom_bytes):
|
||||
|
16
tools/splat/segtypes/common/hasm.py
Normal file
16
tools/splat/segtypes/common/hasm.py
Normal file
@ -0,0 +1,16 @@
|
||||
from segtypes.common.asm import CommonSegAsm
|
||||
|
||||
|
||||
class CommonSegHasm(CommonSegAsm):
|
||||
def split(self, rom_bytes: bytes):
|
||||
if not self.rom_start == self.rom_end:
|
||||
out_path = self.out_path()
|
||||
if out_path and not out_path.exists():
|
||||
out_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
self.print_file_boundaries()
|
||||
|
||||
with open(out_path, "w", newline="\n") as f:
|
||||
for line in self.get_file_header():
|
||||
f.write(line + "\n")
|
||||
f.write(self.text_section.disassemble())
|
@ -14,8 +14,10 @@ class CommonSegLib(N64Segment):
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
given_is_overlay,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
symbol_name_format,
|
||||
symbol_name_format_no_rom,
|
||||
args,
|
||||
yaml,
|
||||
):
|
||||
@ -27,11 +29,14 @@ class CommonSegLib(N64Segment):
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
given_is_overlay,
|
||||
given_dir,
|
||||
args,
|
||||
yaml,
|
||||
exclusive_ram_id=exclusive_ram_id,
|
||||
given_dir=given_dir,
|
||||
symbol_name_format=symbol_name_format,
|
||||
symbol_name_format_no_rom=symbol_name_format_no_rom,
|
||||
args=args,
|
||||
yaml=yaml,
|
||||
)
|
||||
|
||||
if isinstance(yaml, dict):
|
||||
log.error("Error: 'dict' not currently supported for 'lib' segment")
|
||||
return
|
||||
|
@ -1,6 +1,9 @@
|
||||
from typing import Union, List
|
||||
from pathlib import Path
|
||||
from segtypes.common.data import CommonSegData
|
||||
from segtypes.common.linker_section import LinkerSection, dotless_type
|
||||
from segtypes.n64.img import N64SegImg
|
||||
from segtypes.n64.palette import N64SegPalette
|
||||
from util import options
|
||||
from segtypes.segment import Segment
|
||||
import os
|
||||
@ -57,10 +60,14 @@ def to_cname(symbol: str) -> str:
|
||||
|
||||
|
||||
def get_segment_cname(segment: Segment) -> str:
|
||||
name = segment.name
|
||||
if segment.parent:
|
||||
return to_cname(segment.parent.name + "_" + segment.name)
|
||||
else:
|
||||
return to_cname(segment.name)
|
||||
name = segment.parent.name + "_" + name
|
||||
|
||||
if isinstance(segment, N64SegPalette):
|
||||
name += "_pal"
|
||||
|
||||
return to_cname(name)
|
||||
|
||||
|
||||
class LinkerEntry:
|
||||
@ -163,6 +170,15 @@ class LinkerWriter:
|
||||
)
|
||||
self._write_symbol(path_cname, ".")
|
||||
|
||||
# Write out manual entries for images inside .data segments
|
||||
seg = entry.segment
|
||||
if isinstance(seg, CommonSegData):
|
||||
for subseg in seg.subsegments:
|
||||
if isinstance(subseg, N64SegImg):
|
||||
self._write_symbol(
|
||||
get_segment_cname(subseg), f"0x{subseg.rom_start:X}"
|
||||
)
|
||||
|
||||
self._writeln(f"{entry.object_path}({cur_section});")
|
||||
|
||||
for section in section_labels:
|
||||
|
@ -19,8 +19,10 @@ class N64SegCi8(N64SegRgba16):
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
given_is_overlay,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
symbol_name_format,
|
||||
symbol_name_format_no_rom,
|
||||
args,
|
||||
yaml,
|
||||
):
|
||||
@ -32,10 +34,12 @@ class N64SegCi8(N64SegRgba16):
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
given_is_overlay,
|
||||
given_dir,
|
||||
args,
|
||||
yaml,
|
||||
exclusive_ram_id=exclusive_ram_id,
|
||||
given_dir=given_dir,
|
||||
symbol_name_format=symbol_name_format,
|
||||
symbol_name_format_no_rom=symbol_name_format_no_rom,
|
||||
args=args,
|
||||
yaml=yaml,
|
||||
)
|
||||
|
||||
self.palette: "Optional[Palette]" = None
|
||||
@ -52,7 +56,6 @@ class N64SegCi8(N64SegRgba16):
|
||||
log.error(
|
||||
f"no palette sibling segment exists\n(hint: add a segment with type 'palette' and name '{self.name}')"
|
||||
)
|
||||
return
|
||||
|
||||
w = png.Writer(
|
||||
self.width, self.height, palette=self.palette.parse_palette(rom_bytes)
|
||||
|
@ -1,7 +0,0 @@
|
||||
from segtypes.n64.c import N64SegC
|
||||
from util import options
|
||||
|
||||
|
||||
class N64SegCpp(N64SegC):
|
||||
def out_path(self):
|
||||
return options.get_src_path() / self.dir / f"{self.name}.cpp"
|
214
tools/splat/segtypes/n64/gfx.py
Normal file
214
tools/splat/segtypes/n64/gfx.py
Normal file
@ -0,0 +1,214 @@
|
||||
"""
|
||||
N64 f3dex display list splitter
|
||||
Dumps out Gfx[] as a .inc.c file.
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from pygfxd import *
|
||||
from util import log
|
||||
from util.log import error
|
||||
|
||||
from util import options
|
||||
from segtypes.common.codesubsegment import CommonSegCodeSubsegment
|
||||
|
||||
|
||||
class N64SegGfx(CommonSegCodeSubsegment):
|
||||
def __init__(
|
||||
self,
|
||||
rom_start,
|
||||
rom_end,
|
||||
type,
|
||||
name,
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
symbol_name_format,
|
||||
symbol_name_format_no_rom,
|
||||
args,
|
||||
yaml,
|
||||
):
|
||||
super().__init__(
|
||||
rom_start,
|
||||
rom_end,
|
||||
type,
|
||||
name,
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
exclusive_ram_id=exclusive_ram_id,
|
||||
given_dir=given_dir,
|
||||
symbol_name_format=symbol_name_format,
|
||||
symbol_name_format_no_rom=symbol_name_format_no_rom,
|
||||
args=args,
|
||||
yaml=yaml,
|
||||
)
|
||||
self.file_text = None
|
||||
|
||||
def get_linker_section(self) -> str:
|
||||
return ".data"
|
||||
|
||||
def out_path(self) -> Path:
|
||||
return options.get_asset_path() / self.dir / f"{self.name}.gfx.inc.c"
|
||||
|
||||
def scan(self, rom_bytes: bytes):
|
||||
self.file_text = self.disassemble_data(rom_bytes)
|
||||
|
||||
def get_gfxd_target(self):
|
||||
opt = options.get_gfx_ucode()
|
||||
|
||||
if opt == "f3d":
|
||||
return gfxd_f3d # type: ignore
|
||||
elif opt == "f3db":
|
||||
return gfxd_f3db # type: ignore
|
||||
elif opt == "f3dex":
|
||||
return gfxd_f3dex # type: ignore
|
||||
elif opt == "f3dexb":
|
||||
return gfxd_f3dexb # type: ignore
|
||||
elif opt == "f3dex2":
|
||||
return gfxd_f3dex2 # type: ignore
|
||||
else:
|
||||
log.error(f"Unknown target {opt}")
|
||||
|
||||
def tlut_handler(self, addr, idx, count):
|
||||
sym = self.create_symbol(
|
||||
addr=addr, in_segment=True, type="data", reference=True
|
||||
)
|
||||
gfxd_printf(sym.name)
|
||||
return 1
|
||||
|
||||
def timg_handler(self, addr, fmt, size, width, height, pal):
|
||||
sym = self.create_symbol(
|
||||
addr=addr, in_segment=True, type="data", reference=True
|
||||
)
|
||||
gfxd_printf(sym.name)
|
||||
return 1
|
||||
|
||||
def cimg_handler(self, addr, fmt, size, width):
|
||||
sym = self.create_symbol(
|
||||
addr=addr, in_segment=True, type="data", reference=True
|
||||
)
|
||||
gfxd_printf(sym.name)
|
||||
return 1
|
||||
|
||||
def zimg_handler(self, addr):
|
||||
sym = self.create_symbol(
|
||||
addr=addr, in_segment=True, type="data", reference=True
|
||||
)
|
||||
gfxd_printf(sym.name)
|
||||
return 1
|
||||
|
||||
def dl_handler(self, addr):
|
||||
sym = self.create_symbol(
|
||||
addr=addr, in_segment=True, type="data", reference=True
|
||||
)
|
||||
gfxd_printf(sym.name)
|
||||
return 1
|
||||
|
||||
def mtx_handler(self, addr):
|
||||
sym = self.create_symbol(
|
||||
addr=addr, in_segment=True, type="data", reference=True
|
||||
)
|
||||
gfxd_printf(sym.name)
|
||||
return 1
|
||||
|
||||
def lookat_handler(self, addr, count):
|
||||
sym = self.create_symbol(
|
||||
addr=addr, in_segment=True, type="data", reference=True
|
||||
)
|
||||
gfxd_printf(sym.name)
|
||||
return 1
|
||||
|
||||
def light_handler(self, addr, count):
|
||||
sym = self.create_symbol(
|
||||
addr=addr, in_segment=True, type="data", reference=True
|
||||
)
|
||||
gfxd_printf(sym.name)
|
||||
return 1
|
||||
|
||||
def vtx_handler(self, addr, count):
|
||||
sym = self.create_symbol(
|
||||
addr=addr, in_segment=True, type="data", reference=True
|
||||
)
|
||||
gfxd_printf(sym.name)
|
||||
return 1
|
||||
|
||||
def vp_handler(self, addr):
|
||||
sym = self.create_symbol(
|
||||
addr=addr, in_segment=True, type="data", reference=True
|
||||
)
|
||||
gfxd_printf(sym.name)
|
||||
return 1
|
||||
|
||||
def macro_fn(self):
|
||||
gfxd_puts(" ")
|
||||
gfxd_macro_dflt()
|
||||
gfxd_puts(",\n")
|
||||
return 0
|
||||
|
||||
def disassemble_data(self, rom_bytes):
|
||||
gfx_data = rom_bytes[self.rom_start : self.rom_end]
|
||||
segment_length = len(gfx_data)
|
||||
if (segment_length) % 8 != 0:
|
||||
error(
|
||||
f"Error: gfx segment {self.name} length ({segment_length}) is not a multiple of 8!"
|
||||
)
|
||||
|
||||
out_str = options.get_generated_c_premble() + "\n\n"
|
||||
|
||||
sym = self.create_symbol(
|
||||
addr=self.vram_start, in_segment=True, type="data", define=True
|
||||
)
|
||||
|
||||
gfxd_input_buffer(gfx_data)
|
||||
|
||||
# TODO terrible guess at the size we'll need - improve this
|
||||
outb = bytes([0] * segment_length * 100)
|
||||
outbuf = gfxd_output_buffer(outb, len(outb))
|
||||
|
||||
gfxd_target(self.get_gfxd_target())
|
||||
gfxd_endian(
|
||||
GfxdEndian.big if options.get_endianess() == "big" else GfxdEndian.little, 4
|
||||
)
|
||||
|
||||
# Callbacks
|
||||
gfxd_macro_fn(self.macro_fn)
|
||||
|
||||
gfxd_tlut_callback(self.tlut_handler)
|
||||
gfxd_timg_callback(self.timg_handler)
|
||||
gfxd_cimg_callback(self.cimg_handler)
|
||||
gfxd_zimg_callback(self.zimg_handler)
|
||||
gfxd_dl_callback(self.dl_handler)
|
||||
gfxd_mtx_callback(self.mtx_handler)
|
||||
gfxd_lookat_callback(self.lookat_handler)
|
||||
gfxd_light_callback(self.light_handler)
|
||||
# gfxd_seg_callback ?
|
||||
gfxd_vtx_callback(self.vtx_handler)
|
||||
gfxd_vp_callback(self.vp_handler)
|
||||
# gfxd_uctext_callback ?
|
||||
# gfxd_ucdata_callback ?
|
||||
# gfxd_dram_callback ?
|
||||
|
||||
gfxd_execute()
|
||||
out_str += "Gfx " + sym.name + "[] = {\n"
|
||||
out_str += gfxd_buffer_to_string(outbuf)
|
||||
out_str += "};\n"
|
||||
return out_str
|
||||
|
||||
def split(self, rom_bytes: bytes):
|
||||
if self.file_text and self.out_path():
|
||||
self.out_path().parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with open(self.out_path(), "w", newline="\n") as f:
|
||||
f.write(self.file_text)
|
||||
|
||||
def should_scan(self) -> bool:
|
||||
return (
|
||||
options.mode_active("gfx")
|
||||
and self.rom_start != "auto"
|
||||
and self.rom_end != "auto"
|
||||
)
|
||||
|
||||
def should_split(self) -> bool:
|
||||
return self.extract and options.mode_active("gfx")
|
@ -1,8 +1,25 @@
|
||||
from segtypes.n64.asm import N64SegAsm
|
||||
from segtypes.common.hasm import CommonSegHasm
|
||||
|
||||
from util import options
|
||||
|
||||
|
||||
class N64SegHasm(N64SegAsm):
|
||||
def split_write(self, out_path, out_lines):
|
||||
if not out_path.exists():
|
||||
with open(out_path, "w", newline="\n") as f:
|
||||
f.write("\n".join(out_lines))
|
||||
class N64SegHasm(CommonSegHasm):
|
||||
@staticmethod
|
||||
def get_file_header():
|
||||
ret = []
|
||||
|
||||
ret.append('.include "macro.inc"')
|
||||
ret.append("")
|
||||
ret.append("# assembler directives")
|
||||
ret.append(".set noat # allow manual use of $at")
|
||||
ret.append(".set noreorder # don't insert nops after branches")
|
||||
ret.append(".set gp=64 # allow use of 64-bit general purpose registers")
|
||||
ret.append("")
|
||||
preamble = options.get_generated_s_preamble()
|
||||
if preamble:
|
||||
ret.append(preamble)
|
||||
ret.append("")
|
||||
ret.append('.section .text, "ax"')
|
||||
ret.append("")
|
||||
|
||||
return ret
|
||||
|
@ -15,8 +15,10 @@ class N64SegImg(N64Segment):
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
given_is_overlay,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
symbol_name_format,
|
||||
symbol_name_format_no_rom,
|
||||
args,
|
||||
yaml,
|
||||
):
|
||||
@ -28,10 +30,12 @@ class N64SegImg(N64Segment):
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
given_is_overlay,
|
||||
given_dir,
|
||||
args,
|
||||
yaml,
|
||||
exclusive_ram_id=exclusive_ram_id,
|
||||
given_dir=given_dir,
|
||||
symbol_name_format=symbol_name_format,
|
||||
symbol_name_format_no_rom=symbol_name_format_no_rom,
|
||||
args=args,
|
||||
yaml=yaml,
|
||||
)
|
||||
|
||||
if isinstance(yaml, dict):
|
||||
|
@ -23,8 +23,10 @@ class N64SegPalette(N64Segment):
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
given_is_overlay,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
symbol_name_format,
|
||||
symbol_name_format_no_rom,
|
||||
args,
|
||||
yaml,
|
||||
):
|
||||
@ -36,10 +38,12 @@ class N64SegPalette(N64Segment):
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
given_is_overlay,
|
||||
given_dir,
|
||||
args,
|
||||
yaml,
|
||||
exclusive_ram_id=exclusive_ram_id,
|
||||
given_dir=given_dir,
|
||||
symbol_name_format=symbol_name_format,
|
||||
symbol_name_format_no_rom=symbol_name_format_no_rom,
|
||||
args=args,
|
||||
yaml=yaml,
|
||||
)
|
||||
|
||||
self.raster: "Optional[Raster]" = None
|
||||
@ -81,7 +85,6 @@ class N64SegPalette(N64Segment):
|
||||
if self.raster is None:
|
||||
# TODO: output with no raster
|
||||
log.error(f"orphaned palette segment: {self.name} lacks ci4/ci8 sibling")
|
||||
return
|
||||
|
||||
w = png.Writer(
|
||||
self.raster.width, self.raster.height, palette=self.parse_palette(rom_bytes)
|
||||
|
@ -7,7 +7,6 @@ Originally written by Mark Street (https://github.com/mkst)
|
||||
|
||||
import re
|
||||
import struct
|
||||
from typing import Optional
|
||||
from pathlib import Path
|
||||
from util.log import error
|
||||
|
||||
@ -25,10 +24,12 @@ class N64SegVtx(CommonSegCodeSubsegment):
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
given_is_overlay,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
args=[],
|
||||
yaml={},
|
||||
symbol_name_format,
|
||||
symbol_name_format_no_rom,
|
||||
args,
|
||||
yaml,
|
||||
):
|
||||
super().__init__(
|
||||
rom_start,
|
||||
@ -38,10 +39,12 @@ class N64SegVtx(CommonSegCodeSubsegment):
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
given_is_overlay,
|
||||
given_dir,
|
||||
args,
|
||||
yaml,
|
||||
exclusive_ram_id=exclusive_ram_id,
|
||||
given_dir=given_dir,
|
||||
symbol_name_format=symbol_name_format,
|
||||
symbol_name_format_no_rom=symbol_name_format_no_rom,
|
||||
args=args,
|
||||
yaml=yaml,
|
||||
)
|
||||
self.file_text = None
|
||||
|
||||
@ -68,8 +71,10 @@ class N64SegVtx(CommonSegCodeSubsegment):
|
||||
lines.append("")
|
||||
|
||||
vertex_count = segment_length // 16
|
||||
cname = re.sub(r"[^0-9a-zA-Z_]", "_", self.name)
|
||||
lines.append(f"Vtx {cname}[{vertex_count}] = {{")
|
||||
sym = self.create_symbol(
|
||||
addr=self.vram_start, in_segment=True, type="data", define=True
|
||||
)
|
||||
lines.append(f"Vtx {sym.name}[{vertex_count}] = {{")
|
||||
|
||||
for vtx in struct.iter_unpack(">hhhHhhBBBB", vertex_data):
|
||||
x, y, z, flg, t, c, r, g, b, a = vtx
|
||||
|
@ -1,8 +0,0 @@
|
||||
from segtypes.psx.asm import PsxSegAsm
|
||||
|
||||
|
||||
class PsxSegHasm(PsxSegAsm):
|
||||
def split_write(self, out_path, out_lines):
|
||||
if not out_path.exists():
|
||||
with open(out_path, "w", newline="\n") as f:
|
||||
f.write("\n".join(out_lines))
|
@ -1,7 +1,7 @@
|
||||
import importlib
|
||||
import importlib.util
|
||||
|
||||
from typing import Dict, TYPE_CHECKING, Type, Union, Optional, List
|
||||
from typing import Any, Dict, TYPE_CHECKING, Type, Union, Optional, List
|
||||
from pathlib import Path
|
||||
|
||||
from util import log
|
||||
@ -41,7 +41,7 @@ class Segment:
|
||||
require_unique_name = True
|
||||
|
||||
@staticmethod
|
||||
def get_class_for_type(seg_type):
|
||||
def get_class_for_type(seg_type) -> Type["Segment"]:
|
||||
# so .data loads SegData, for example
|
||||
if seg_type.startswith("."):
|
||||
seg_type = seg_type[1:]
|
||||
@ -126,17 +126,33 @@ class Segment:
|
||||
else:
|
||||
return str(cls.get_default_name(rom_start))
|
||||
|
||||
@staticmethod
|
||||
def parse_segment_symbol_name_format(segment: Union[dict, list]) -> str:
|
||||
if isinstance(segment, dict) and "symbol_name_format" in segment:
|
||||
return str(segment["symbol_name_format"])
|
||||
else:
|
||||
return options.get_symbol_name_format()
|
||||
|
||||
@staticmethod
|
||||
def parse_segment_symbol_name_format_no_rom(segment: Union[dict, list]) -> str:
|
||||
if isinstance(segment, dict) and "symbol_name_format_no_rom" in segment:
|
||||
return str(segment["symbol_name_format_no_rom"])
|
||||
else:
|
||||
return options.get_symbol_name_format_no_rom()
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
rom_start,
|
||||
rom_end,
|
||||
type,
|
||||
name,
|
||||
vram_start,
|
||||
extract=True,
|
||||
given_subalign=options.get_subalign(),
|
||||
given_is_overlay: Optional[bool] = False,
|
||||
rom_start: RomAddr,
|
||||
rom_end: RomAddr,
|
||||
type: str,
|
||||
name: str,
|
||||
vram_start: Any,
|
||||
extract: bool = True,
|
||||
given_subalign: int = options.get_subalign(),
|
||||
exclusive_ram_id: Optional[str] = None,
|
||||
given_dir: Path = Path(),
|
||||
symbol_name_format: str = options.get_symbol_name_format(),
|
||||
symbol_name_format_no_rom: str = options.get_symbol_name_format_no_rom(),
|
||||
args=[],
|
||||
yaml={},
|
||||
):
|
||||
@ -148,27 +164,22 @@ class Segment:
|
||||
self.extract = extract
|
||||
|
||||
self.given_subalign = given_subalign
|
||||
self.given_is_overlay = given_is_overlay
|
||||
self.exclusive_ram_id = exclusive_ram_id
|
||||
self.given_dir = given_dir
|
||||
self.given_seg_symbols: Dict[
|
||||
int, List[Symbol]
|
||||
] = {} # Symbols known to be in this segment
|
||||
self.given_ext_symbols: Dict[
|
||||
int, List[Symbol]
|
||||
] = (
|
||||
{}
|
||||
) # Symbols not in this segment but also not from other overlapping ram address ranges
|
||||
self.given_section_order: List[str] = options.get_section_order()
|
||||
|
||||
self.given_symbol_name_format = symbol_name_format
|
||||
self.given_symbol_name_format_no_rom = symbol_name_format_no_rom
|
||||
|
||||
self.parent: Optional[Segment] = None
|
||||
self.sibling: Optional[Segment] = None
|
||||
|
||||
self.args: List[str] = args
|
||||
self.yaml = yaml
|
||||
|
||||
if "skip" in self.args:
|
||||
self.extract = False
|
||||
|
||||
if self.rom_start == "auto":
|
||||
self.extract = False
|
||||
|
||||
@ -197,24 +208,30 @@ class Segment:
|
||||
vram_start = vram if vram is not None else parse_segment_vram(yaml)
|
||||
extract = bool(yaml.get("extract", True)) if isinstance(yaml, dict) else True
|
||||
given_subalign = parse_segment_subalign(yaml)
|
||||
given_is_overlay: Optional[bool] = (
|
||||
yaml.get("overlay", False) if isinstance(yaml, dict) else False
|
||||
exclusive_ram_id: Optional[str] = (
|
||||
yaml.get("exclusive_ram_id") if isinstance(yaml, dict) else None
|
||||
)
|
||||
given_dir = Path(yaml.get("dir", "")) if isinstance(yaml, dict) else Path()
|
||||
given_symbol_name_format = Segment.parse_segment_symbol_name_format(yaml)
|
||||
given_symbol_name_format_no_rom = (
|
||||
Segment.parse_segment_symbol_name_format_no_rom(yaml)
|
||||
)
|
||||
args: List[str] = [] if isinstance(yaml, dict) else yaml[3:]
|
||||
|
||||
ret = cls(
|
||||
rom_start,
|
||||
rom_end,
|
||||
type,
|
||||
name,
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
given_is_overlay,
|
||||
given_dir,
|
||||
args,
|
||||
yaml,
|
||||
rom_start=rom_start,
|
||||
rom_end=rom_end,
|
||||
type=type,
|
||||
name=name,
|
||||
vram_start=vram_start,
|
||||
extract=extract,
|
||||
given_subalign=given_subalign,
|
||||
exclusive_ram_id=exclusive_ram_id,
|
||||
given_dir=given_dir,
|
||||
symbol_name_format=given_symbol_name_format,
|
||||
symbol_name_format_no_rom=given_symbol_name_format_no_rom,
|
||||
args=args,
|
||||
yaml=yaml,
|
||||
)
|
||||
cls.given_section_order = parse_segment_section_order(yaml)
|
||||
return ret
|
||||
@ -230,6 +247,14 @@ class Segment:
|
||||
else:
|
||||
return self.given_dir
|
||||
|
||||
@property
|
||||
def symbol_name_format(self) -> str:
|
||||
return self.given_symbol_name_format
|
||||
|
||||
@property
|
||||
def symbol_name_format_no_rom(self) -> str:
|
||||
return self.given_symbol_name_format_no_rom
|
||||
|
||||
@property
|
||||
def subalign(self) -> int:
|
||||
if self.parent:
|
||||
@ -237,13 +262,15 @@ class Segment:
|
||||
else:
|
||||
return self.given_subalign
|
||||
|
||||
@property
|
||||
def is_overlay(self) -> bool:
|
||||
def get_exclusive_ram_id(self) -> Optional[str]:
|
||||
if self.parent:
|
||||
return self.parent.is_overlay
|
||||
if self.given_is_overlay is not None:
|
||||
return self.given_is_overlay
|
||||
return False
|
||||
return self.parent.get_exclusive_ram_id()
|
||||
return self.exclusive_ram_id
|
||||
|
||||
def add_symbol(self, symbol: Symbol):
|
||||
if symbol.vram_start not in self.given_seg_symbols:
|
||||
self.given_seg_symbols[symbol.vram_start] = []
|
||||
self.given_seg_symbols[symbol.vram_start].append(symbol)
|
||||
|
||||
@property
|
||||
def seg_symbols(self) -> Dict[int, List[Symbol]]:
|
||||
@ -252,13 +279,6 @@ class Segment:
|
||||
else:
|
||||
return self.given_seg_symbols
|
||||
|
||||
@property
|
||||
def ext_symbols(self) -> Dict[int, List[Symbol]]:
|
||||
if self.parent:
|
||||
return self.parent.ext_symbols
|
||||
else:
|
||||
return self.given_ext_symbols
|
||||
|
||||
@property
|
||||
def size(self) -> Optional[int]:
|
||||
if isinstance(self.rom_start, int) and isinstance(self.rom_end, int):
|
||||
@ -285,14 +305,6 @@ class Segment:
|
||||
self.section_order.index(".rodata") - self.section_order.index(".data") == 1
|
||||
)
|
||||
|
||||
@property
|
||||
def text_follows_rodata(self) -> bool:
|
||||
if ".text" not in self.section_order or ".rodata" not in self.section_order:
|
||||
return False
|
||||
return (
|
||||
self.section_order.index(".text") - self.section_order.index(".rodata") == 1
|
||||
)
|
||||
|
||||
def contains_vram(self, vram: int) -> bool:
|
||||
if self.vram_start is not None and self.vram_end is not None:
|
||||
return vram >= self.vram_start and vram < self.vram_end
|
||||
@ -395,43 +407,59 @@ class Segment:
|
||||
def get_default_name(addr) -> str:
|
||||
return f"{addr:X}"
|
||||
|
||||
def retrieve_symbol(self, d, k, t):
|
||||
if k not in d:
|
||||
@staticmethod
|
||||
def visible_ram(seg1: "Segment", seg2: "Segment") -> bool:
|
||||
if seg1.get_most_parent() == seg2.get_most_parent():
|
||||
return True
|
||||
if seg1.get_exclusive_ram_id() is None or seg2.get_exclusive_ram_id() is None:
|
||||
return True
|
||||
return seg1.get_exclusive_ram_id() != seg2.get_exclusive_ram_id()
|
||||
|
||||
def retrieve_symbol(
|
||||
self, syms: Dict[int, List[Symbol]], addr: int
|
||||
) -> Optional[Symbol]:
|
||||
if addr not in syms:
|
||||
return None
|
||||
|
||||
if t:
|
||||
items = [s for s in d[k] if s.type == t or s.type == "unknown"]
|
||||
else:
|
||||
items = d[k]
|
||||
items = syms[addr]
|
||||
|
||||
# Filter out symbols that are in different top-level segments with the same unique_ram_id
|
||||
items = [
|
||||
i
|
||||
for i in items
|
||||
if i.segment is None or Segment.visible_ram(self, i.segment)
|
||||
]
|
||||
|
||||
if len(items) > 1:
|
||||
pass # print(f"Trying to retrieve {k:X} from symbol dict but there are {len(items)} entries to pick from - picking the first")
|
||||
# print(f"Trying to retrieve {addr:X} from symbol dict but there are {len(items)} entries to pick from - picking the first")
|
||||
pass
|
||||
if len(items) == 0:
|
||||
return None
|
||||
return items[0]
|
||||
|
||||
def get_symbol(
|
||||
self,
|
||||
addr,
|
||||
type=None,
|
||||
create=False,
|
||||
define=False,
|
||||
reference=False,
|
||||
offsets=False,
|
||||
local_only=False,
|
||||
dead=True,
|
||||
addr: int,
|
||||
in_segment: bool = False,
|
||||
type: Optional[str] = None,
|
||||
create: bool = False,
|
||||
define: bool = False,
|
||||
reference: bool = False,
|
||||
offsets: bool = False,
|
||||
local_only: bool = False,
|
||||
dead: bool = True,
|
||||
) -> Optional[Symbol]:
|
||||
ret = None
|
||||
rom = None
|
||||
ret: Optional[Symbol] = None
|
||||
rom: Optional[int] = None
|
||||
|
||||
in_segment = self.contains_vram(addr)
|
||||
most_parent = self.get_most_parent()
|
||||
|
||||
if in_segment:
|
||||
# If the vram address is within this segment, we can calculate the symbol's rom address
|
||||
rom = self.ram_to_rom(addr)
|
||||
ret = self.retrieve_symbol(self.seg_symbols, addr, type)
|
||||
rom = most_parent.ram_to_rom(addr)
|
||||
ret = most_parent.retrieve_symbol(most_parent.seg_symbols, addr)
|
||||
elif not local_only:
|
||||
ret = self.retrieve_symbol(self.ext_symbols, addr, type)
|
||||
ret = most_parent.retrieve_symbol(symbols.all_symbols_dict, addr)
|
||||
|
||||
# Search for symbol ranges
|
||||
if not ret and offsets:
|
||||
@ -444,39 +472,43 @@ class Segment:
|
||||
# Create the symbol if it doesn't exist
|
||||
if not ret and create:
|
||||
ret = Symbol(addr, rom=rom, type=type)
|
||||
symbols.all_symbols.append(ret)
|
||||
symbols.add_symbol(ret)
|
||||
|
||||
if in_segment:
|
||||
if self.is_overlay:
|
||||
ret.in_overlay = True
|
||||
if addr not in self.seg_symbols:
|
||||
self.seg_symbols[addr] = []
|
||||
self.seg_symbols[addr].append(ret)
|
||||
elif not local_only:
|
||||
if addr not in self.ext_symbols:
|
||||
self.ext_symbols[addr] = []
|
||||
self.ext_symbols[addr].append(ret)
|
||||
ret.segment = most_parent
|
||||
if addr not in most_parent.seg_symbols:
|
||||
most_parent.seg_symbols[addr] = []
|
||||
most_parent.seg_symbols[addr].append(ret)
|
||||
|
||||
if ret:
|
||||
if define:
|
||||
ret.defined = True
|
||||
if reference:
|
||||
ret.referenced = True
|
||||
if ret.type is None:
|
||||
ret.type = type
|
||||
if ret.rom is None:
|
||||
ret.rom = rom
|
||||
if in_segment:
|
||||
if ret.segment is None:
|
||||
ret.segment = most_parent
|
||||
|
||||
return ret
|
||||
|
||||
def create_symbol(
|
||||
self,
|
||||
addr,
|
||||
type=None,
|
||||
define=False,
|
||||
reference=False,
|
||||
offsets=False,
|
||||
local_only=False,
|
||||
dead=True,
|
||||
addr: int,
|
||||
in_segment: bool,
|
||||
type: Optional[str] = None,
|
||||
define: bool = False,
|
||||
reference: bool = False,
|
||||
offsets: bool = False,
|
||||
local_only: bool = False,
|
||||
dead: bool = True,
|
||||
) -> Symbol:
|
||||
ret = self.get_symbol(
|
||||
addr,
|
||||
in_segment=in_segment,
|
||||
type=type,
|
||||
create=True,
|
||||
define=define,
|
||||
|
@ -3,7 +3,9 @@
|
||||
import hashlib
|
||||
from typing import Dict, List, Union, Set, Any
|
||||
import argparse
|
||||
import pylibyaml
|
||||
import spimdisasm
|
||||
import rabbitizer
|
||||
import tqdm
|
||||
import yaml
|
||||
import pickle
|
||||
from colorama import Style, Fore
|
||||
@ -13,8 +15,12 @@ from util import log
|
||||
from util import options
|
||||
from util import symbols
|
||||
from util import palettes
|
||||
from util import compiler
|
||||
from util.symbols import Symbol
|
||||
|
||||
VERSION = "0.8.1.0"
|
||||
from intervaltree import Interval, IntervalTree
|
||||
|
||||
VERSION = "0.9.0"
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Split a rom given a rom, a config, and output directory"
|
||||
@ -31,6 +37,9 @@ parser.add_argument(
|
||||
linker_writer: LinkerWriter
|
||||
config: Dict[str, Any]
|
||||
|
||||
segment_roms: IntervalTree = IntervalTree()
|
||||
segment_rams: IntervalTree = IntervalTree()
|
||||
|
||||
|
||||
def fmt_size(size):
|
||||
if size > 1000000:
|
||||
@ -42,6 +51,12 @@ def fmt_size(size):
|
||||
|
||||
|
||||
def initialize_segments(config_segments: Union[dict, list]) -> List[Segment]:
|
||||
global segment_roms
|
||||
global segment_rams
|
||||
|
||||
segment_roms = IntervalTree()
|
||||
segment_rams = IntervalTree()
|
||||
|
||||
seen_segment_names: Set[str] = set()
|
||||
ret = []
|
||||
|
||||
@ -68,35 +83,42 @@ def initialize_segments(config_segments: Union[dict, list]) -> List[Segment]:
|
||||
seen_segment_names.add(segment.name)
|
||||
|
||||
ret.append(segment)
|
||||
if (
|
||||
isinstance(segment.rom_start, int)
|
||||
and isinstance(segment.rom_end, int)
|
||||
and segment.rom_start != segment.rom_end
|
||||
):
|
||||
segment_roms.addi(segment.rom_start, segment.rom_end, segment)
|
||||
if (
|
||||
isinstance(segment.vram_start, int)
|
||||
and isinstance(segment.vram_end, int)
|
||||
and segment.vram_start != segment.vram_end
|
||||
):
|
||||
segment_rams.addi(segment.vram_start, segment.vram_end, segment)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def get_segment_symbols(segment, all_segments):
|
||||
seg_syms = {}
|
||||
other_syms = {}
|
||||
def assign_symbols_to_segments():
|
||||
seg_syms: dict[int, list[Symbol]] = {}
|
||||
|
||||
for symbol in symbols.all_symbols:
|
||||
if symbols.is_symbol_isolated(symbol, all_segments) and not symbol.rom:
|
||||
if segment.contains_vram(symbol.vram_start):
|
||||
if symbol.vram_start not in seg_syms:
|
||||
seg_syms[symbol.vram_start] = []
|
||||
seg_syms[symbol.vram_start].append(symbol)
|
||||
if symbol.rom:
|
||||
cands = segment_roms[symbol.rom]
|
||||
if len(cands) > 1:
|
||||
log.error("multiple segments rom overlap symbol", symbol)
|
||||
elif len(cands) == 0:
|
||||
log.error("no segment rom overlaps symbol", symbol)
|
||||
else:
|
||||
if symbol.vram_start not in other_syms:
|
||||
other_syms[symbol.vram_start] = []
|
||||
other_syms[symbol.vram_start].append(symbol)
|
||||
cand: Interval = cands.pop()
|
||||
seg: Segment = cand.data
|
||||
seg.add_symbol(symbol)
|
||||
else:
|
||||
if symbol.rom and segment.contains_rom(symbol.rom):
|
||||
if symbol.vram_start not in seg_syms:
|
||||
seg_syms[symbol.vram_start] = []
|
||||
seg_syms[symbol.vram_start].append(symbol)
|
||||
else:
|
||||
if symbol.vram_start not in other_syms:
|
||||
other_syms[symbol.vram_start] = []
|
||||
other_syms[symbol.vram_start].append(symbol)
|
||||
|
||||
return seg_syms, other_syms
|
||||
cands: Set[Interval] = segment_rams[symbol.vram_start]
|
||||
segs: List[Segment] = [cand.data for cand in cands]
|
||||
for seg in segs:
|
||||
if not seg.get_exclusive_ram_id():
|
||||
seg.add_symbol(symbol)
|
||||
|
||||
|
||||
def do_statistics(seg_sizes, rom_bytes, seg_split, seg_cached):
|
||||
@ -152,10 +174,84 @@ def merge_configs(main_config, additional_config):
|
||||
return main_config
|
||||
|
||||
|
||||
def configure_disassembler():
|
||||
# Configure spimdisasm
|
||||
spimdisasm.common.GlobalConfig.PRODUCE_SYMBOLS_PLUS_OFFSET = True
|
||||
spimdisasm.common.GlobalConfig.TRUST_USER_FUNCTIONS = True
|
||||
spimdisasm.common.GlobalConfig.TRUST_JAL_FUNCTIONS = True
|
||||
spimdisasm.common.GlobalConfig.GLABEL_ASM_COUNT = False
|
||||
|
||||
if options.rom_address_padding():
|
||||
spimdisasm.common.GlobalConfig.ASM_COMMENT_OFFSET_WIDTH = 6
|
||||
else:
|
||||
spimdisasm.common.GlobalConfig.ASM_COMMENT_OFFSET_WIDTH = 0
|
||||
|
||||
# spimdisasm is not performing any analyzis on non-text sections so enabling this options is pointless
|
||||
spimdisasm.common.GlobalConfig.AUTOGENERATED_NAMES_BASED_ON_SECTION_TYPE = False
|
||||
spimdisasm.common.GlobalConfig.AUTOGENERATED_NAMES_BASED_ON_DATA_TYPE = False
|
||||
|
||||
spimdisasm.common.GlobalConfig.SYMBOL_FINDER_FILTERED_ADDRESSES_AS_HILO = False
|
||||
|
||||
rabbitizer.config.regNames_userFpcCsr = False
|
||||
rabbitizer.config.regNames_vr4300Cop0NamedRegisters = False
|
||||
|
||||
rabbitizer.config.misc_opcodeLJust = options.mnemonic_ljust() - 1
|
||||
|
||||
rabbitizer.config.regNames_gprAbiNames = rabbitizer.Abi.fromStr(
|
||||
options.get_mips_abi_gpr()
|
||||
)
|
||||
rabbitizer.config.regNames_fprAbiNames = rabbitizer.Abi.fromStr(
|
||||
options.get_mips_abi_float_regs()
|
||||
)
|
||||
|
||||
if options.get_endianess() == "big":
|
||||
spimdisasm.common.GlobalConfig.ENDIAN = spimdisasm.common.InputEndian.BIG
|
||||
else:
|
||||
spimdisasm.common.GlobalConfig.ENDIAN = spimdisasm.common.InputEndian.LITTLE
|
||||
|
||||
rabbitizer.config.pseudos_pseudoMove = False
|
||||
|
||||
selectedCompiler = options.get_compiler()
|
||||
if selectedCompiler == compiler.SN64:
|
||||
rabbitizer.config.regNames_namedRegisters = False
|
||||
rabbitizer.config.toolchainTweaks_sn64DivFix = True
|
||||
rabbitizer.config.toolchainTweaks_treatJAsUnconditionalBranch = True
|
||||
spimdisasm.common.GlobalConfig.ASM_COMMENT = False
|
||||
spimdisasm.common.GlobalConfig.SYMBOL_FINDER_FILTERED_ADDRESSES_AS_HILO = False
|
||||
spimdisasm.common.GlobalConfig.COMPILER = spimdisasm.common.Compiler.SN64
|
||||
elif selectedCompiler == compiler.GCC:
|
||||
rabbitizer.config.toolchainTweaks_treatJAsUnconditionalBranch = True
|
||||
spimdisasm.common.GlobalConfig.COMPILER = spimdisasm.common.Compiler.GCC
|
||||
elif selectedCompiler == compiler.IDO:
|
||||
spimdisasm.common.GlobalConfig.COMPILER = spimdisasm.common.Compiler.IDO
|
||||
|
||||
spimdisasm.common.GlobalConfig.GP_VALUE = options.get_gp()
|
||||
|
||||
spimdisasm.common.GlobalConfig.ASM_TEXT_LABEL = options.get_asm_function_macro()
|
||||
spimdisasm.common.GlobalConfig.ASM_DATA_LABEL = options.get_asm_data_macro()
|
||||
spimdisasm.common.GlobalConfig.ASM_TEXT_END_LABEL = options.get_asm_end_label()
|
||||
|
||||
if spimdisasm.common.GlobalConfig.ASM_TEXT_LABEL == ".globl":
|
||||
spimdisasm.common.GlobalConfig.ASM_TEXT_ENT_LABEL = ".ent"
|
||||
spimdisasm.common.GlobalConfig.ASM_TEXT_FUNC_AS_LABEL = True
|
||||
|
||||
spimdisasm.common.GlobalConfig.LINE_ENDS = options.c_newline()
|
||||
|
||||
if options.get_platform() == "n64":
|
||||
symbols.spim_context.fillDefaultBannedSymbols()
|
||||
|
||||
|
||||
def brief_seg_name(seg: Segment, limit: int, ellipsis="…") -> str:
|
||||
s = seg.name.strip()
|
||||
if len(s) > limit:
|
||||
return s[:limit].strip() + ellipsis
|
||||
return s
|
||||
|
||||
|
||||
def main(config_path, base_dir, target_path, modes, verbose, use_cache=True):
|
||||
global config
|
||||
|
||||
log.write(f"splat {VERSION}")
|
||||
log.write(f"splat {VERSION} (powered by spimdisasm {spimdisasm.__version__})")
|
||||
|
||||
# Load config
|
||||
config = {}
|
||||
@ -210,21 +306,29 @@ def main(config_path, base_dir, target_path, modes, verbose, use_cache=True):
|
||||
"__options__": config.get("options"),
|
||||
}
|
||||
|
||||
configure_disassembler()
|
||||
|
||||
# Initialize segments
|
||||
all_segments = initialize_segments(config["segments"])
|
||||
|
||||
# Load and process symbols
|
||||
symbols.initialize(all_segments)
|
||||
|
||||
# Assign symbols to segments
|
||||
assign_symbols_to_segments()
|
||||
|
||||
if options.mode_active("code"):
|
||||
log.write("Loading and processing symbols")
|
||||
symbols.initialize(all_segments)
|
||||
symbols.initialize_spim_context(all_segments)
|
||||
|
||||
# Resolve raster/palette siblings
|
||||
if options.mode_active("img"):
|
||||
palettes.initialize(all_segments)
|
||||
|
||||
# Scan
|
||||
log.write("Starting scan")
|
||||
for segment in all_segments:
|
||||
scan_bar = tqdm.tqdm(all_segments, total=len(all_segments))
|
||||
for segment in scan_bar:
|
||||
assert isinstance(segment, Segment)
|
||||
scan_bar.set_description(f"Scanning {brief_seg_name(segment, 20)}")
|
||||
typ = segment.type
|
||||
if segment.type == "bin" and segment.is_name_default():
|
||||
typ = "unk"
|
||||
@ -241,13 +345,6 @@ def main(config_path, base_dir, target_path, modes, verbose, use_cache=True):
|
||||
if segment.cache() == cache.get(segment.unique_id()):
|
||||
continue
|
||||
|
||||
if segment.needs_symbols:
|
||||
segment_symbols, other_symbols = get_segment_symbols(
|
||||
segment, all_segments
|
||||
)
|
||||
segment.given_seg_symbols = segment_symbols
|
||||
segment.given_ext_symbols = other_symbols
|
||||
|
||||
segment.did_run = True
|
||||
segment.scan(rom_bytes)
|
||||
|
||||
@ -255,11 +352,12 @@ def main(config_path, base_dir, target_path, modes, verbose, use_cache=True):
|
||||
|
||||
seg_split[typ] += 1
|
||||
|
||||
log.dot(status=segment.status())
|
||||
|
||||
# Split
|
||||
log.write("Starting split")
|
||||
for segment in all_segments:
|
||||
for segment in tqdm.tqdm(
|
||||
all_segments,
|
||||
total=len(all_segments),
|
||||
desc=f"Splitting {brief_seg_name(segment, 20)}",
|
||||
):
|
||||
if use_cache:
|
||||
cached = segment.cache()
|
||||
|
||||
@ -274,12 +372,14 @@ def main(config_path, base_dir, target_path, modes, verbose, use_cache=True):
|
||||
if segment.should_split():
|
||||
segment.split(rom_bytes)
|
||||
|
||||
log.dot(status=segment.status())
|
||||
|
||||
if options.mode_active("ld"):
|
||||
global linker_writer
|
||||
linker_writer = LinkerWriter()
|
||||
for segment in all_segments:
|
||||
for segment in tqdm.tqdm(
|
||||
all_segments,
|
||||
total=len(all_segments),
|
||||
desc=f"Writing linker script {brief_seg_name(segment, 20)}",
|
||||
):
|
||||
linker_writer.add(segment)
|
||||
linker_writer.save_linker_script()
|
||||
linker_writer.save_symbol_header()
|
||||
@ -300,22 +400,27 @@ def main(config_path, base_dir, target_path, modes, verbose, use_cache=True):
|
||||
for s in symbols.all_symbols
|
||||
if s.referenced and not s.defined and not s.dead and s.type == "func"
|
||||
]
|
||||
if len(to_write) > 0:
|
||||
with open(options.get_undefined_funcs_auto_path(), "w", newline="\n") as f:
|
||||
for symbol in to_write:
|
||||
f.write(f"{symbol.name} = 0x{symbol.vram_start:X};\n")
|
||||
to_write.sort(key=lambda x: x.vram_start)
|
||||
|
||||
with open(options.get_undefined_funcs_auto_path(), "w", newline="\n") as f:
|
||||
for symbol in to_write:
|
||||
f.write(f"{symbol.name} = 0x{symbol.vram_start:X};\n")
|
||||
|
||||
# write undefined_syms_auto.txt
|
||||
if options.get_create_undefined_syms_auto():
|
||||
to_write = [
|
||||
s
|
||||
for s in symbols.all_symbols
|
||||
if s.referenced and not s.defined and not s.dead and not s.type == "func"
|
||||
if s.referenced
|
||||
and not s.defined
|
||||
and not s.dead
|
||||
and s.type not in {"func", "label", "jtbl_label"}
|
||||
]
|
||||
if len(to_write) > 0:
|
||||
with open(options.get_undefined_syms_auto_path(), "w", newline="\n") as f:
|
||||
for symbol in to_write:
|
||||
f.write(f"{symbol.name} = 0x{symbol.vram_start:X};\n")
|
||||
to_write.sort(key=lambda x: x.vram_start)
|
||||
|
||||
with open(options.get_undefined_syms_auto_path(), "w", newline="\n") as f:
|
||||
for symbol in to_write:
|
||||
f.write(f"{symbol.name} = 0x{symbol.vram_start:X};\n")
|
||||
|
||||
# print warnings during split
|
||||
for segment in all_segments:
|
||||
|
@ -24,7 +24,9 @@ SN64 = Compiler(
|
||||
c_newline="\r\n",
|
||||
)
|
||||
|
||||
compiler_for_name = {"GCC": GCC, "SN64": SN64}
|
||||
IDO = Compiler("IDO")
|
||||
|
||||
compiler_for_name = {"GCC": GCC, "SN64": SN64, "IDO": IDO}
|
||||
|
||||
|
||||
def for_name(name: str) -> Compiler:
|
||||
|
@ -31,13 +31,6 @@ def parsing_error_preamble(path, line_num, line):
|
||||
write(f"\t{line}")
|
||||
|
||||
|
||||
def dot(status: Status = None):
|
||||
global newline
|
||||
|
||||
print(status_to_ansi(status) + ".", end="")
|
||||
newline = False
|
||||
|
||||
|
||||
def status_to_ansi(status: Status):
|
||||
if status == "ok":
|
||||
return Fore.GREEN
|
||||
|
@ -1,22 +1,25 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
from capstone import *
|
||||
|
||||
from capstone import Cs, CS_ARCH_MIPS, CS_MODE_MIPS64, CS_MODE_BIG_ENDIAN
|
||||
from capstone.mips import *
|
||||
|
||||
import argparse
|
||||
import spimdisasm
|
||||
import rabbitizer
|
||||
|
||||
|
||||
def int_any_base(x):
|
||||
return int(x, 0)
|
||||
|
||||
md = Cs(CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_BIG_ENDIAN)
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Given a rom and start offset, find where the code ends"
|
||||
)
|
||||
parser.add_argument("rom", help="path to a .z64 rom")
|
||||
parser.add_argument("start", help="start offset")
|
||||
parser.add_argument("--end", help="end offset", default=None)
|
||||
parser.add_argument("start", help="start offset", type=int_any_base)
|
||||
parser.add_argument("--end", help="end offset", default=None, type=int_any_base)
|
||||
parser.add_argument(
|
||||
"--vram", help="vram address to start disassembly at", default="0x80000000"
|
||||
"--vram",
|
||||
help="vram address to start disassembly at",
|
||||
default="0x80000000",
|
||||
type=int_any_base,
|
||||
)
|
||||
|
||||
|
||||
@ -24,28 +27,35 @@ def run(rom_bytes, start_offset, vram, end_offset=None):
|
||||
rom_addr = start_offset
|
||||
last_return = rom_addr
|
||||
|
||||
for insn in md.disasm(rom_bytes[start_offset:], vram):
|
||||
if insn.mnemonic == "jr" and insn.op_str == "$ra":
|
||||
wordList = spimdisasm.common.Utils.bytesToBEWords(rom_bytes[start_offset:])
|
||||
for word in wordList:
|
||||
insn = rabbitizer.Instruction(word)
|
||||
if not insn.isImplemented():
|
||||
break
|
||||
|
||||
if insn.isJrRa():
|
||||
last_return = rom_addr
|
||||
rom_addr += 4
|
||||
if end_offset and rom_addr >= end_offset:
|
||||
break
|
||||
|
||||
return last_return + (0x10 - (last_return % 0x10))
|
||||
# align to next 0x10 boundary
|
||||
end = last_return + 0x10
|
||||
end -= end % 0x10
|
||||
return end
|
||||
|
||||
|
||||
def main():
|
||||
args = parser.parse_args()
|
||||
|
||||
rom_bytes = open(args.rom, "rb").read()
|
||||
start = int(args.start, 0)
|
||||
end = None
|
||||
vram = int(args.vram, 0)
|
||||
with open(args.rom, "rb") as f:
|
||||
rom_bytes = f.read()
|
||||
|
||||
if args.end:
|
||||
end = int(args.end, 0)
|
||||
start = args.start
|
||||
end = args.end
|
||||
vram = args.vram
|
||||
|
||||
print(f"{run(rom_bytes, start, vram, end):X}")
|
||||
print(f"0x{run(rom_bytes, start, vram, end):X}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -1,21 +1,28 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
import sys
|
||||
import argparse
|
||||
import itertools
|
||||
import struct
|
||||
import spimdisasm
|
||||
import rabbitizer
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import hashlib
|
||||
import zlib
|
||||
|
||||
from capstone import Cs, CS_ARCH_MIPS, CS_MODE_MIPS64, CS_MODE_BIG_ENDIAN
|
||||
|
||||
parser = argparse.ArgumentParser(description="Gives information on N64 roms")
|
||||
parser.add_argument("rom", help="path to an N64 rom")
|
||||
parser.add_argument(
|
||||
"--header-encoding",
|
||||
help="Text encoding the game header is using; see docs.python.org/3/library/codecs.html#standard-encodings for valid encodings",
|
||||
dest="header_encoding",
|
||||
help=(
|
||||
"Text encoding the game header is using;"
|
||||
" see docs.python.org/3/library/codecs.html#standard-encodings for valid encodings"
|
||||
),
|
||||
)
|
||||
|
||||
country_codes = {
|
||||
@ -42,27 +49,34 @@ country_codes = {
|
||||
0x59: "European",
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class CIC:
|
||||
ntsc_name: str
|
||||
pal_name: str
|
||||
offset: int
|
||||
|
||||
|
||||
crc_to_cic = {
|
||||
0x6170A4A1: {"ntsc-name": "6101", "pal-name": "7102", "offset": 0x000000},
|
||||
0x90BB6CB5: {"ntsc-name": "6102", "pal-name": "7101", "offset": 0x000000},
|
||||
0x0B050EE0: {"ntsc-name": "6103", "pal-name": "7103", "offset": 0x100000},
|
||||
0x98BC2C86: {"ntsc-name": "6105", "pal-name": "7105", "offset": 0x000000},
|
||||
0xACC8580A: {"ntsc-name": "6106", "pal-name": "7106", "offset": 0x200000},
|
||||
0x00000000: {"ntsc-name": "unknown", "pal-name": "unknown", "offset": 0x0000000},
|
||||
0x6170A4A1: CIC("6101", "7102", 0x000000),
|
||||
0x90BB6CB5: CIC("6102", "7101", 0x000000),
|
||||
0x0B050EE0: CIC("6103", "7103", 0x100000),
|
||||
0x98BC2C86: CIC("6105", "7105", 0x000000),
|
||||
0xACC8580A: CIC("6106", "7106", 0x200000),
|
||||
}
|
||||
unknown_cic = CIC("unknown", "unknown", 0x0000000)
|
||||
|
||||
|
||||
def swap_bytes(data):
|
||||
return bytes(
|
||||
itertools.chain.from_iterable(
|
||||
struct.pack(">H", x) for x, in struct.iter_unpack("<H", data)
|
||||
struct.pack(">H", x) for (x,) in struct.iter_unpack("<H", data)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def read_rom(rom_path):
|
||||
with open(rom_path, "rb") as f:
|
||||
rom_bytes = f.read()
|
||||
def read_rom(rom_path: Path):
|
||||
rom_bytes = rom_path.read_bytes()
|
||||
|
||||
if rom_path.suffix.lower() == ".n64":
|
||||
print("Warning: Input file has .n64 suffix, byte-swapping!")
|
||||
@ -70,24 +84,21 @@ def read_rom(rom_path):
|
||||
as_z64 = rom_path.with_suffix(".z64")
|
||||
if not as_z64.exists():
|
||||
print(f"Writing down {as_z64}")
|
||||
with open(as_z64, "wb") as o:
|
||||
o.write(rom_bytes)
|
||||
as_z64.write_bytes(rom_bytes)
|
||||
return rom_bytes
|
||||
|
||||
|
||||
def get_cic(rom_bytes):
|
||||
crc = zlib.crc32(rom_bytes[0x40:0x1000])
|
||||
if crc in crc_to_cic:
|
||||
return crc_to_cic[crc]
|
||||
else:
|
||||
return crc_to_cic[0]
|
||||
def get_cic(rom_bytes: bytes):
|
||||
ipl3_crc = zlib.crc32(rom_bytes[0x40:0x1000])
|
||||
|
||||
return crc_to_cic.get(ipl3_crc, unknown_cic)
|
||||
|
||||
|
||||
def get_entry_point(program_counter, cic):
|
||||
return program_counter - cic["offset"]
|
||||
def get_entry_point(program_counter: int, cic: CIC):
|
||||
return program_counter - cic.offset
|
||||
|
||||
|
||||
def guess_header_encoding(rom_bytes):
|
||||
def guess_header_encoding(rom_bytes: bytes):
|
||||
header = rom_bytes[0x20:0x34]
|
||||
encodings = ["ASCII", "shift_jis", "euc-jp"]
|
||||
for encoding in encodings:
|
||||
@ -98,12 +109,11 @@ def guess_header_encoding(rom_bytes):
|
||||
# we guessed wrong...
|
||||
pass
|
||||
|
||||
print("Unknown header encoding, please raise an Issue with us")
|
||||
exit(1)
|
||||
sys.exit("Unknown header encoding, please raise an Issue with us")
|
||||
|
||||
|
||||
def get_info(rom_path, rom_bytes=None, header_encoding=None):
|
||||
if not rom_bytes:
|
||||
def get_info(rom_path: Path, rom_bytes: bytes = None, header_encoding=None):
|
||||
if rom_bytes is None:
|
||||
rom_bytes = read_rom(rom_path)
|
||||
|
||||
if header_encoding is None:
|
||||
@ -112,31 +122,25 @@ def get_info(rom_path, rom_bytes=None, header_encoding=None):
|
||||
return get_info_bytes(rom_bytes, header_encoding)
|
||||
|
||||
|
||||
def get_info_bytes(rom_bytes, header_encoding):
|
||||
program_counter = int(rom_bytes[0x8:0xC].hex(), 16)
|
||||
def get_info_bytes(rom_bytes: bytes, header_encoding):
|
||||
(program_counter,) = struct.unpack(">I", rom_bytes[0x8:0xC])
|
||||
libultra_version = chr(rom_bytes[0xF])
|
||||
crc1 = rom_bytes[0x10:0x14].hex().upper()
|
||||
crc2 = rom_bytes[0x14:0x18].hex().upper()
|
||||
checksum = rom_bytes[0x10:0x18].hex().upper()
|
||||
|
||||
try:
|
||||
name = rom_bytes[0x20:0x34].decode(header_encoding).strip()
|
||||
except:
|
||||
print(
|
||||
"splat could not decode the game name; try using a different encoding by passing the --header-encoding argument (see docs.python.org/3/library/codecs.html#standard-encodings for valid encodings)"
|
||||
sys.exit(
|
||||
"splat could not decode the game name;"
|
||||
" try using a different encoding by passing the --header-encoding argument"
|
||||
" (see docs.python.org/3/library/codecs.html#standard-encodings for valid encodings)"
|
||||
)
|
||||
exit(1)
|
||||
|
||||
country_code = rom_bytes[0x3E]
|
||||
|
||||
cic = get_cic(rom_bytes)
|
||||
entry_point = get_entry_point(program_counter, cic)
|
||||
|
||||
# TODO: add support for
|
||||
# compression_formats = []
|
||||
# for format in ["Yay0", "vpk0"]:
|
||||
# if rom_bytes.find(bytes(format, "ASCII")) != -1:
|
||||
# compression_formats.append(format)
|
||||
|
||||
compiler = get_compiler_info(rom_bytes, entry_point, print_result=False)
|
||||
|
||||
sha1 = hashlib.sha1(rom_bytes).hexdigest()
|
||||
@ -146,8 +150,7 @@ def get_info_bytes(rom_bytes, header_encoding):
|
||||
header_encoding,
|
||||
country_code,
|
||||
libultra_version,
|
||||
crc1,
|
||||
crc2,
|
||||
checksum,
|
||||
cic,
|
||||
entry_point,
|
||||
len(rom_bytes),
|
||||
@ -159,15 +162,14 @@ def get_info_bytes(rom_bytes, header_encoding):
|
||||
class N64Rom:
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
name: str,
|
||||
header_encoding,
|
||||
country_code,
|
||||
libultra_version,
|
||||
crc1,
|
||||
crc2,
|
||||
cic,
|
||||
entry_point,
|
||||
size,
|
||||
checksum,
|
||||
cic: CIC,
|
||||
entry_point: int,
|
||||
size: int,
|
||||
compiler,
|
||||
sha1,
|
||||
):
|
||||
@ -175,8 +177,7 @@ class N64Rom:
|
||||
self.header_encoding = header_encoding
|
||||
self.country_code = country_code
|
||||
self.libultra_version = libultra_version
|
||||
self.crc1 = crc1
|
||||
self.crc2 = crc2
|
||||
self.checksum = checksum
|
||||
self.cic = cic
|
||||
self.entry_point = entry_point
|
||||
self.size = size
|
||||
@ -188,28 +189,33 @@ class N64Rom:
|
||||
|
||||
|
||||
def get_compiler_info(rom_bytes, entry_point, print_result=True):
|
||||
md = Cs(CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_BIG_ENDIAN)
|
||||
md.detail = True
|
||||
|
||||
jumps = 0
|
||||
branches = 0
|
||||
|
||||
for insn in md.disasm(rom_bytes[0x1000:], entry_point):
|
||||
if insn.mnemonic == "j":
|
||||
vram = entry_point
|
||||
wordList = spimdisasm.common.Utils.bytesToBEWords(rom_bytes[0x1000:])
|
||||
for word in wordList:
|
||||
insn = rabbitizer.Instruction(word)
|
||||
if not insn.isImplemented():
|
||||
break
|
||||
|
||||
if insn.uniqueId == rabbitizer.InstrId.cpu_j:
|
||||
jumps += 1
|
||||
elif insn.mnemonic == "b":
|
||||
elif insn.uniqueId == rabbitizer.InstrId.cpu_b:
|
||||
branches += 1
|
||||
|
||||
compiler = "IDO" if branches > jumps else "GCC"
|
||||
if print_result:
|
||||
print(
|
||||
f"{branches} branches and {jumps} jumps detected in the first code segment. Compiler is most likely {compiler}"
|
||||
f"{branches} branches and {jumps} jumps detected in the first code segment."
|
||||
f" Compiler is most likely {compiler}"
|
||||
)
|
||||
return compiler
|
||||
|
||||
|
||||
# TODO: support .n64 extension
|
||||
def main():
|
||||
rabbitizer.config.pseudos_pseudoB = True
|
||||
|
||||
args = parser.parse_args()
|
||||
rom_bytes = read_rom(Path(args.rom))
|
||||
rom = get_info(Path(args.rom), rom_bytes, args.header_encoding)
|
||||
@ -217,9 +223,8 @@ def main():
|
||||
print("Image name: " + rom.name)
|
||||
print("Country code: " + chr(rom.country_code) + " - " + rom.get_country_name())
|
||||
print("Libultra version: " + rom.libultra_version)
|
||||
print("CRC1: " + rom.crc1)
|
||||
print("CRC2: " + rom.crc2)
|
||||
print("CIC: " + rom.cic["ntsc-name"] + " / " + rom.cic["pal-name"])
|
||||
print("Checksum: " + rom.checksum)
|
||||
print("CIC: " + rom.cic.ntsc_name + " / " + rom.cic.pal_name)
|
||||
print("RAM entry point: " + hex(rom.entry_point))
|
||||
print("Header encoding: " + rom.header_encoding)
|
||||
print("")
|
||||
|
@ -226,10 +226,16 @@ def get_subalign() -> int:
|
||||
return opts.get("subalign", 16)
|
||||
|
||||
|
||||
# Determines whether to automatically configure the linker script to link against common sections for all files
|
||||
# when the yaml doesn't have specific configurations for these sections. See release notes for details
|
||||
def auto_all_sections() -> bool:
|
||||
return opts.get("auto_all_sections", False)
|
||||
# The following option determines whether to automatically configure the linker script to link against
|
||||
# specified sections for all "base" (asm/c) files when the yaml doesn't have manual configurations
|
||||
# for these sections.
|
||||
def auto_all_sections() -> List[str]:
|
||||
val = opts.get("auto_all_sections", [".data", ".rodata", ".bss"])
|
||||
if not isinstance(val, list):
|
||||
raise RuntimeError(
|
||||
'auto_all_sections must be a list (for example, [".data", ".rodata", ".bss"])'
|
||||
)
|
||||
return val
|
||||
|
||||
|
||||
# Determines the desired path to the linker symbol header, which exposes externed definitions for all segment ram/rom start/end locations
|
||||
@ -268,10 +274,12 @@ def ld_section_labels() -> List[str]:
|
||||
def get_create_c_files() -> bool:
|
||||
return opts.get("create_c_files", True)
|
||||
|
||||
|
||||
# Determines whether to "auto-decompile" empty functions
|
||||
def get_auto_decompile_empty_functions() -> bool:
|
||||
return opts.get("auto_decompile_empty_functions", True)
|
||||
|
||||
|
||||
# Determines whether to detect matched/unmatched functions in existing c files
|
||||
# so we can avoid creating .s files for already-decompiled functions
|
||||
def do_c_func_detection() -> bool:
|
||||
@ -287,6 +295,16 @@ def c_newline() -> str:
|
||||
# (Dis)assembly-related options
|
||||
################################################################################
|
||||
|
||||
# The following options determine the format that symbols should be named by default
|
||||
def get_symbol_name_format() -> str:
|
||||
return opts.get("symbol_name_format", "$VRAM")
|
||||
|
||||
|
||||
# Same as above but for symbols with no rom address
|
||||
def get_symbol_name_format_no_rom() -> str:
|
||||
return opts.get("symbol_name_format_no_rom", "$VRAM_$SEG")
|
||||
|
||||
|
||||
# Determines whether to detect and hint to the user about likely file splits when disassembling
|
||||
def find_file_boundaries() -> bool:
|
||||
return opts.get("find_file_boundaries", True)
|
||||
@ -332,6 +350,20 @@ def rom_address_padding() -> bool:
|
||||
return opts.get("rom_address_padding", False)
|
||||
|
||||
|
||||
# Determines which ABI names to use for general purpose registers
|
||||
# Valid values: 'numeric', 'o32', 'n32', 'n64'
|
||||
def get_mips_abi_gpr() -> str:
|
||||
return opts.get("mips_abi_gpr", "o32")
|
||||
|
||||
|
||||
# Determines which ABI names to use for floating point registers
|
||||
# Valid values: 'numeric', 'o32', 'n32', 'n64'
|
||||
# o32 is highly recommended, as it provides logically named registers for floating point instructions
|
||||
# For more info, see https://gist.github.com/EllipticEllipsis/27eef11205c7a59d8ea85632bc49224d
|
||||
def get_mips_abi_float_regs() -> str:
|
||||
return opts.get("mips_abi_float_regs", "numeric")
|
||||
|
||||
|
||||
################################################################################
|
||||
# N64-specific options
|
||||
################################################################################
|
||||
@ -341,6 +373,16 @@ def get_header_encoding() -> str:
|
||||
return opts.get("header_encoding", "ASCII")
|
||||
|
||||
|
||||
# Determines the type gfx ucode (used by gfx segments)
|
||||
# Valid options are ['f3d', 'f3db', 'f3dex', 'f3dexb', 'f3dex2']
|
||||
def get_gfx_ucode() -> str:
|
||||
valid_options = ["f3d", "f3db", "f3dex", "f3dexb", "f3dex2"]
|
||||
ret = opts.get("gfx_ucode", "f3dex2")
|
||||
if ret not in valid_options:
|
||||
log.error(f"Invalid gfx_ucode: {ret}. Valid options are: {valid_options}")
|
||||
return ret
|
||||
|
||||
|
||||
################################################################################
|
||||
# Compiler-specific options
|
||||
################################################################################
|
||||
|
@ -1,7 +1,11 @@
|
||||
import dataclasses
|
||||
from typing import Optional
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Range:
|
||||
def __init__(self, start=None, end=None):
|
||||
self.start = start
|
||||
self.end = end
|
||||
start: Optional[int] = None
|
||||
end: Optional[int] = None
|
||||
|
||||
def has_start(self):
|
||||
return self.start is not None
|
||||
|
@ -1,12 +1,21 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Dict, List, Optional
|
||||
from typing import Dict, List, Optional, TYPE_CHECKING, Set
|
||||
import spimdisasm
|
||||
import rabbitizer
|
||||
import tqdm
|
||||
|
||||
# circular import
|
||||
if TYPE_CHECKING:
|
||||
from segtypes.segment import Segment
|
||||
|
||||
from capstone import CsInsn
|
||||
from util import options, log
|
||||
|
||||
all_symbols: "List[Symbol]" = []
|
||||
symbol_ranges: "List[Symbol]" = []
|
||||
sym_isolated_map: "Dict[Symbol, bool]" = {}
|
||||
all_symbols: List["Symbol"] = []
|
||||
all_symbols_dict: Dict[int, List["Symbol"]] = {}
|
||||
ignored_addresses: Set[int] = set()
|
||||
symbol_ranges: List["Symbol"] = []
|
||||
|
||||
# Initialize a spimdisasm context, used to store symbols and functions
|
||||
spim_context = spimdisasm.common.Context()
|
||||
|
||||
TRUEY_VALS = ["true", "on", "yes", "y"]
|
||||
FALSEY_VALS = ["false", "off", "no", "n"]
|
||||
@ -20,19 +29,37 @@ def is_falsey(str: str) -> bool:
|
||||
return str.lower() in FALSEY_VALS
|
||||
|
||||
|
||||
def initialize(all_segments):
|
||||
def add_symbol(sym: "Symbol"):
|
||||
all_symbols.append(sym)
|
||||
if sym.vram_start is not None:
|
||||
if sym.vram_start not in all_symbols_dict:
|
||||
all_symbols_dict[sym.vram_start] = []
|
||||
all_symbols_dict[sym.vram_start].append(sym)
|
||||
|
||||
|
||||
def initialize(all_segments: "List[Segment]"):
|
||||
global all_symbols
|
||||
global all_symbols_dict
|
||||
global symbol_ranges
|
||||
|
||||
all_symbols = []
|
||||
all_symbols_dict = {}
|
||||
symbol_ranges = []
|
||||
|
||||
def get_seg_for_name(name: str) -> Optional["Segment"]:
|
||||
for segment in all_segments:
|
||||
if segment.name == name:
|
||||
return segment
|
||||
return None
|
||||
|
||||
# Manual list of func name / addrs
|
||||
for path in options.get_symbol_addrs_paths():
|
||||
if path.exists():
|
||||
with open(path) as f:
|
||||
sym_addrs_lines = f.readlines()
|
||||
for line_num, line in enumerate(sym_addrs_lines):
|
||||
for line_num, line in enumerate(
|
||||
tqdm.tqdm(sym_addrs_lines, desc=f"Loading symbols ({path.stem})")
|
||||
):
|
||||
line = line.strip()
|
||||
if not line == "" and not line.startswith("//"):
|
||||
comment_loc = line.find("//")
|
||||
@ -59,10 +86,11 @@ def initialize(all_segments):
|
||||
|
||||
sym = Symbol(addr, given_name=name)
|
||||
|
||||
ignore_sym = False
|
||||
if line_ext:
|
||||
for info in line_ext.split(" "):
|
||||
if ":" in info:
|
||||
if info.count(':') > 1:
|
||||
if info.count(":") > 1:
|
||||
log.parsing_error_preamble(path, line_num, line)
|
||||
log.write(f"Too many ':'s in '{info}'")
|
||||
log.error("")
|
||||
@ -70,14 +98,17 @@ def initialize(all_segments):
|
||||
attr_name, attr_val = info.split(":")
|
||||
if attr_name == "":
|
||||
log.parsing_error_preamble(path, line_num, line)
|
||||
log.write(f"Missing attribute name in '{info}', is there extra whitespace?")
|
||||
log.write(
|
||||
f"Missing attribute name in '{info}', is there extra whitespace?"
|
||||
)
|
||||
log.error("")
|
||||
if attr_val == "":
|
||||
log.parsing_error_preamble(path, line_num, line)
|
||||
log.write(f"Missing attribute value in '{info}', is there extra whitespace?")
|
||||
log.write(
|
||||
f"Missing attribute value in '{info}', is there extra whitespace?"
|
||||
)
|
||||
log.error("")
|
||||
|
||||
|
||||
# Non-Boolean attributes
|
||||
try:
|
||||
if attr_name == "type":
|
||||
@ -86,12 +117,27 @@ def initialize(all_segments):
|
||||
continue
|
||||
if attr_name == "size":
|
||||
size = int(attr_val, 0)
|
||||
sym.size = size
|
||||
sym.given_size = size
|
||||
continue
|
||||
if attr_name == "rom":
|
||||
rom_addr = int(attr_val, 0)
|
||||
sym.rom = rom_addr
|
||||
continue
|
||||
if attr_name == "segment":
|
||||
seg = get_seg_for_name(attr_val)
|
||||
if seg is None:
|
||||
log.parsing_error_preamble(
|
||||
path, line_num, line
|
||||
)
|
||||
log.write(
|
||||
f"Cannot find segment '{attr_val}'"
|
||||
)
|
||||
log.error("")
|
||||
else:
|
||||
# Add segment to symbol, symbol to segment
|
||||
sym.segment = seg
|
||||
seg.add_symbol(sym)
|
||||
continue
|
||||
except:
|
||||
log.parsing_error_preamble(path, line_num, line)
|
||||
log.write(
|
||||
@ -115,39 +161,180 @@ def initialize(all_segments):
|
||||
)
|
||||
log.write([*TRUEY_VALS, *FALSEY_VALS])
|
||||
log.error("")
|
||||
else:
|
||||
if attr_name == "dead":
|
||||
sym.dead = tf_val
|
||||
continue
|
||||
if attr_name == "defined":
|
||||
sym.defined = tf_val
|
||||
continue
|
||||
if attr_name == "extract":
|
||||
sym.extract = tf_val
|
||||
continue
|
||||
if attr_name == "ignore":
|
||||
ignore_sym = tf_val
|
||||
continue
|
||||
if ignore_sym:
|
||||
ignored_addresses.add(sym.vram_start)
|
||||
ignore_sym = False
|
||||
continue
|
||||
|
||||
if attr_name == "dead":
|
||||
sym.dead = tf_val
|
||||
continue
|
||||
if attr_name == "defined":
|
||||
sym.defined = tf_val
|
||||
continue
|
||||
if attr_name == "extract":
|
||||
sym.extract = tf_val
|
||||
continue
|
||||
all_symbols.append(sym)
|
||||
sym.user_declared = True
|
||||
add_symbol(sym)
|
||||
|
||||
# Symbol ranges
|
||||
if sym.size > 4:
|
||||
symbol_ranges.append(sym)
|
||||
|
||||
is_symbol_isolated(sym, all_segments)
|
||||
|
||||
def initialize_spim_context(all_segments: "List[Segment]") -> None:
|
||||
global_vrom_start = None
|
||||
global_vrom_end = None
|
||||
global_vram_start = None
|
||||
global_vram_end = None
|
||||
|
||||
def is_symbol_isolated(symbol, all_segments):
|
||||
if symbol in sym_isolated_map:
|
||||
return sym_isolated_map[symbol]
|
||||
|
||||
relevant_segs = 0
|
||||
spim_context.bannedSymbols |= ignored_addresses
|
||||
|
||||
for segment in all_segments:
|
||||
if segment.contains_vram(symbol.vram_start):
|
||||
relevant_segs += 1
|
||||
if relevant_segs > 1:
|
||||
break
|
||||
if segment.type == "code":
|
||||
# We only care about the VRAMs of code segments
|
||||
if isinstance(segment.vram_start, int) and isinstance(
|
||||
segment.vram_end, int
|
||||
):
|
||||
ram_id = segment.get_exclusive_ram_id()
|
||||
if ram_id is None:
|
||||
if global_vram_start is None:
|
||||
global_vram_start = segment.vram_start
|
||||
else:
|
||||
if segment.vram_start < global_vram_start:
|
||||
global_vram_start = segment.vram_start
|
||||
|
||||
sym_isolated_map[symbol] = relevant_segs < 2
|
||||
return sym_isolated_map[symbol]
|
||||
if global_vram_end is None:
|
||||
global_vram_end = segment.vram_end
|
||||
else:
|
||||
if global_vram_end < segment.vram_end:
|
||||
global_vram_end = segment.vram_end
|
||||
|
||||
if isinstance(segment.rom_start, int):
|
||||
if global_vrom_start is None:
|
||||
global_vrom_start = segment.rom_start
|
||||
else:
|
||||
if segment.rom_start < global_vrom_start:
|
||||
global_vrom_start = segment.rom_start
|
||||
|
||||
if isinstance(segment.rom_end, int):
|
||||
if global_vrom_end is None:
|
||||
global_vrom_end = segment.rom_end
|
||||
else:
|
||||
if global_vrom_end < segment.rom_end:
|
||||
global_vrom_end = segment.rom_end
|
||||
|
||||
else:
|
||||
spim_context.addOverlaySegment(
|
||||
ram_id,
|
||||
segment.rom_start,
|
||||
segment.rom_end,
|
||||
segment.vram_start,
|
||||
segment.vram_end,
|
||||
)
|
||||
|
||||
if (
|
||||
global_vram_start is not None
|
||||
and global_vram_end is not None
|
||||
and global_vrom_start is not None
|
||||
and global_vrom_end is not None
|
||||
):
|
||||
spim_context.globalSegment.changeRanges(
|
||||
global_vrom_start, global_vrom_end, global_vram_start, global_vram_end
|
||||
)
|
||||
|
||||
|
||||
def add_symbol_to_spim_section(
|
||||
section: spimdisasm.common.ElementBase, sym: "Symbol"
|
||||
) -> spimdisasm.common.ContextSymbol:
|
||||
if sym.type == "func":
|
||||
context_sym = section.addFunction(
|
||||
sym.vram_start, isAutogenerated=not sym.user_declared, symbolVrom=sym.rom
|
||||
)
|
||||
elif sym.type == "jtbl":
|
||||
context_sym = section.addJumpTable(
|
||||
sym.vram_start, isAutogenerated=not sym.user_declared, symbolVrom=sym.rom
|
||||
)
|
||||
elif sym.type == "jtbl_label":
|
||||
context_sym = section.addJumpTableLabel(
|
||||
sym.vram_start, isAutogenerated=not sym.user_declared, symbolVrom=sym.rom
|
||||
)
|
||||
elif sym.type == "label":
|
||||
context_sym = section.addBranchLabel(
|
||||
sym.vram_start, isAutogenerated=not sym.user_declared, symbolVrom=sym.rom
|
||||
)
|
||||
else:
|
||||
context_sym = section.addSymbol(
|
||||
sym.vram_start, isAutogenerated=not sym.user_declared, symbolVrom=sym.rom
|
||||
)
|
||||
if sym.type and sym.type != "unknown":
|
||||
context_sym.type = sym.type
|
||||
|
||||
if sym.user_declared:
|
||||
context_sym.isUserDeclared = True
|
||||
if sym.defined:
|
||||
context_sym.isDefined = True
|
||||
if sym.rom is not None:
|
||||
context_sym.vromAddress = sym.rom
|
||||
if sym.given_size is not None:
|
||||
context_sym.size = sym.size
|
||||
context_sym.setNameGetCallbackIfUnset(lambda _: sym.name)
|
||||
|
||||
return context_sym
|
||||
|
||||
|
||||
def create_symbol_from_spim_symbol(
|
||||
segment: "Segment", context_sym: spimdisasm.common.ContextSymbol
|
||||
) -> "Symbol":
|
||||
in_segment = False
|
||||
|
||||
sym_type = None
|
||||
if context_sym.type == spimdisasm.common.SymbolSpecialType.jumptable:
|
||||
in_segment = True
|
||||
sym_type = "jtbl"
|
||||
elif context_sym.type == spimdisasm.common.SymbolSpecialType.function:
|
||||
sym_type = "func"
|
||||
elif context_sym.type == spimdisasm.common.SymbolSpecialType.branchlabel:
|
||||
in_segment = True
|
||||
sym_type = "label"
|
||||
elif context_sym.type == spimdisasm.common.SymbolSpecialType.jumptablelabel:
|
||||
in_segment = True
|
||||
sym_type = "jtbl_label"
|
||||
|
||||
if not in_segment:
|
||||
if (
|
||||
context_sym.overlayCategory is None
|
||||
and segment.get_exclusive_ram_id() is None
|
||||
):
|
||||
in_segment = segment.contains_vram(context_sym.vram)
|
||||
elif context_sym.overlayCategory == segment.get_exclusive_ram_id():
|
||||
if context_sym.vromAddress is not None:
|
||||
in_segment = segment.contains_rom(context_sym.vromAddress)
|
||||
else:
|
||||
in_segment = segment.contains_vram(context_sym.vram)
|
||||
|
||||
sym = segment.create_symbol(
|
||||
context_sym.vram, in_segment, type=sym_type, reference=True
|
||||
)
|
||||
|
||||
# To keep the symbol name in sync between splat and spimdisasm
|
||||
context_sym.setNameGetCallback(lambda _: sym.name)
|
||||
|
||||
if context_sym.size is not None:
|
||||
sym.given_size = context_sym.getSize()
|
||||
if context_sym.vromAddress is not None:
|
||||
sym.rom = context_sym.getVrom()
|
||||
if context_sym.isDefined:
|
||||
sym.defined = True
|
||||
if context_sym.referenceCounter > 0:
|
||||
sym.referenced = True
|
||||
|
||||
return sym
|
||||
|
||||
|
||||
def retrieve_from_ranges(vram, rom=None):
|
||||
@ -169,36 +356,79 @@ def retrieve_from_ranges(vram, rom=None):
|
||||
return None
|
||||
|
||||
|
||||
@dataclass
|
||||
class Instruction:
|
||||
instruction: CsInsn
|
||||
mnemonic: str
|
||||
op_str: str
|
||||
rom_addr: int
|
||||
is_gp: bool = False
|
||||
is_hi: bool = False
|
||||
is_lo: bool = False
|
||||
hi_lo_sym: Optional["Symbol"] = None
|
||||
sym_offset_str: str = ""
|
||||
hi_lo_reg: str = ""
|
||||
|
||||
|
||||
class Symbol:
|
||||
def __init__(
|
||||
self,
|
||||
vram: int,
|
||||
given_name: Optional[str] = None,
|
||||
rom: Optional[int] = None,
|
||||
type: Optional[str] = "unknown",
|
||||
given_size: Optional[int] = None,
|
||||
segment: Optional["Segment"] = None,
|
||||
):
|
||||
self.defined: bool = False
|
||||
self.referenced: bool = False
|
||||
self.vram_start = vram
|
||||
self.rom = rom
|
||||
self.type = type
|
||||
self.given_size = given_size
|
||||
self.given_name = given_name
|
||||
self.access_mnemonic: Optional[rabbitizer.Enum] = None
|
||||
self.disasm_str: Optional[str] = None
|
||||
self.dead: bool = False
|
||||
self.extract: bool = True
|
||||
self.user_declared: bool = False
|
||||
self.segment: Optional["Segment"] = segment
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def format_name(self, format: str) -> str:
|
||||
ret = format
|
||||
|
||||
ret = ret.replace("$VRAM", f"{self.vram_start:08X}")
|
||||
|
||||
if "$ROM" in ret:
|
||||
if not isinstance(self.rom, int):
|
||||
log.error(
|
||||
f"Attempting to rom-name a symbol with no ROM address: {self.vram_start:X} typed {self.type}"
|
||||
)
|
||||
ret = ret.replace("$ROM", f"{self.rom:X}")
|
||||
|
||||
if "$SEG" in ret:
|
||||
if self.segment is None:
|
||||
# This probably is fine - we can't expect every symbol to have a segment. Fall back to just the ram address
|
||||
return f"{self.vram_start:X}"
|
||||
assert self.segment is not None
|
||||
ret = ret.replace("$SEG", self.segment.name)
|
||||
|
||||
return ret
|
||||
|
||||
@property
|
||||
def default_name(self) -> str:
|
||||
suffix = f"_{self.vram_start:X}"
|
||||
|
||||
if self.in_overlay:
|
||||
suffix += f"_{self.rom:X}"
|
||||
if self.segment:
|
||||
if isinstance(self.rom, int):
|
||||
suffix = self.format_name(self.segment.symbol_name_format)
|
||||
else:
|
||||
suffix = self.format_name(self.segment.symbol_name_format_no_rom)
|
||||
else:
|
||||
if isinstance(self.rom, int):
|
||||
suffix = self.format_name(options.get_symbol_name_format())
|
||||
else:
|
||||
suffix = self.format_name(options.get_symbol_name_format_no_rom())
|
||||
|
||||
if self.type == "func":
|
||||
prefix = "func"
|
||||
elif self.type == "jtbl":
|
||||
prefix = "jtbl"
|
||||
elif self.type == "jtbl_label":
|
||||
return f"L{suffix}"
|
||||
elif self.type == "label":
|
||||
return f".L{suffix}"
|
||||
else:
|
||||
prefix = "D"
|
||||
|
||||
return prefix + suffix
|
||||
return f"{prefix}_{suffix}"
|
||||
|
||||
@property
|
||||
def rom_end(self):
|
||||
@ -212,31 +442,14 @@ class Symbol:
|
||||
def name(self) -> str:
|
||||
return self.given_name if self.given_name else self.default_name
|
||||
|
||||
@property
|
||||
def size(self) -> int:
|
||||
if self.given_size is not None:
|
||||
return self.given_size
|
||||
return 4
|
||||
|
||||
def contains_vram(self, offset):
|
||||
return offset >= self.vram_start and offset < self.vram_end
|
||||
|
||||
def contains_rom(self, offset):
|
||||
return offset >= self.rom and offset < self.rom_end
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
vram,
|
||||
given_name: str = "",
|
||||
rom=None,
|
||||
type="unknown",
|
||||
in_overlay=False,
|
||||
size=4,
|
||||
):
|
||||
self.defined = False
|
||||
self.referenced = False
|
||||
self.vram_start = vram
|
||||
self.rom = rom
|
||||
self.type = type
|
||||
self.in_overlay = in_overlay
|
||||
self.size = size
|
||||
self.given_name: str = given_name
|
||||
self.insns: List[Instruction] = []
|
||||
self.access_mnemonic = None
|
||||
self.disasm_str = None
|
||||
self.dead = False
|
||||
self.extract = True
|
||||
|
@ -1,7 +1,6 @@
|
||||
from yaml.loader import Loader
|
||||
from segtypes.n64.segment import N64Segment
|
||||
from util import options
|
||||
import yaml
|
||||
import yaml as yaml_loader
|
||||
|
||||
class N64SegPm_effect_loads(N64Segment):
|
||||
effects = []
|
||||
@ -47,11 +46,40 @@ glabel {name}
|
||||
def effect_path(self, effect):
|
||||
return options.get_build_path() / "asm" / "effects" / f"{effect}.s"
|
||||
|
||||
def __init__(self, rom_start, rom_end, type, name, vram_start, extract, given_subalign, given_is_overlay, given_dir, args, yml):
|
||||
super().__init__(rom_start, rom_end, type, name, vram_start, extract, given_subalign, given_is_overlay, given_dir, args, yml)
|
||||
def __init__(
|
||||
self,
|
||||
rom_start,
|
||||
rom_end,
|
||||
type,
|
||||
name,
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
symbol_name_format,
|
||||
symbol_name_format_no_rom,
|
||||
args,
|
||||
yaml,
|
||||
):
|
||||
super().__init__(
|
||||
rom_start,
|
||||
rom_end,
|
||||
type,
|
||||
name,
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
symbol_name_format=symbol_name_format,
|
||||
symbol_name_format_no_rom=symbol_name_format_no_rom,
|
||||
args=args,
|
||||
yaml=yaml,
|
||||
)
|
||||
|
||||
with open(options.get_asm_path() / ".." / "effects.yaml") as f:
|
||||
self.effects = yaml.load(f.read(), Loader=yaml.SafeLoader)
|
||||
self.effects = yaml_loader.load(f.read(), Loader=yaml_loader.SafeLoader)
|
||||
|
||||
def split(self, rom_bytes):
|
||||
for i, effect in enumerate(self.effects):
|
||||
|
@ -1,7 +1,7 @@
|
||||
from yaml.loader import Loader
|
||||
from segtypes.n64.segment import N64Segment
|
||||
from util import options
|
||||
import yaml
|
||||
import yaml as yaml_loader
|
||||
|
||||
class N64SegPm_effect_shims(N64Segment):
|
||||
shims = []
|
||||
@ -27,11 +27,40 @@ glabel {name}
|
||||
def shim_path(self, shim):
|
||||
return options.get_build_path() / "asm" / "effect_shims" / f"{shim}.s"
|
||||
|
||||
def __init__(self, rom_start, rom_end, type, name, vram_start, extract, given_subalign, given_is_overlay, given_dir, args, yml):
|
||||
super().__init__(rom_start, rom_end, type, name, vram_start, extract, given_subalign, given_is_overlay, given_dir, args, yml)
|
||||
def __init__(
|
||||
self,
|
||||
rom_start,
|
||||
rom_end,
|
||||
type,
|
||||
name,
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
symbol_name_format,
|
||||
symbol_name_format_no_rom,
|
||||
args,
|
||||
yaml,
|
||||
):
|
||||
super().__init__(
|
||||
rom_start,
|
||||
rom_end,
|
||||
type,
|
||||
name,
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
symbol_name_format=symbol_name_format,
|
||||
symbol_name_format_no_rom=symbol_name_format_no_rom,
|
||||
args=args,
|
||||
yaml=yaml,
|
||||
)
|
||||
|
||||
with open(options.get_asm_path() / ".." / "effect_shims.yaml") as f:
|
||||
self.shims = yaml.load(f.read(), Loader=yaml.SafeLoader)
|
||||
self.shims = yaml_loader.load(f.read(), Loader=yaml_loader.SafeLoader)
|
||||
|
||||
def split(self, rom_bytes):
|
||||
for i, shim in enumerate(self.shims):
|
||||
|
@ -38,8 +38,37 @@ def add_file_ext(name: str) -> str:
|
||||
return name + ".bin"
|
||||
|
||||
class N64SegPm_map_data(N64Segment):
|
||||
def __init__(self, rom_start, rom_end, type, name, vram_start, extract, given_subalign, given_is_overlay, given_dir, args, yaml):
|
||||
super().__init__(rom_start, rom_end, type, name, vram_start, extract, given_subalign, given_is_overlay, given_dir, args, yaml)
|
||||
def __init__(
|
||||
self,
|
||||
rom_start,
|
||||
rom_end,
|
||||
type,
|
||||
name,
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
symbol_name_format,
|
||||
symbol_name_format_no_rom,
|
||||
args,
|
||||
yaml,
|
||||
):
|
||||
super().__init__(
|
||||
rom_start,
|
||||
rom_end,
|
||||
type,
|
||||
name,
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
symbol_name_format=symbol_name_format,
|
||||
symbol_name_format_no_rom=symbol_name_format_no_rom,
|
||||
args=args,
|
||||
yaml=yaml,
|
||||
)
|
||||
|
||||
self.files = yaml["files"]
|
||||
|
||||
|
@ -5,7 +5,7 @@ from util import options
|
||||
import re
|
||||
|
||||
import pylibyaml
|
||||
import yaml
|
||||
import yaml as yaml_loader
|
||||
|
||||
CHARSET = {
|
||||
0x00: "[NOTE]",
|
||||
@ -367,13 +367,42 @@ CHARSET_CREDITS = {
|
||||
}
|
||||
|
||||
class N64SegPm_msg(N64Segment):
|
||||
def __init__(self, rom_start, rom_end, type, name, vram_start, extract, given_subalign, given_is_overlay, given_dir, args, yml):
|
||||
super().__init__(rom_start, rom_end, type, name, vram_start, extract, given_subalign, given_is_overlay, given_dir, args, yml)
|
||||
def __init__(
|
||||
self,
|
||||
rom_start,
|
||||
rom_end,
|
||||
type,
|
||||
name,
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
symbol_name_format,
|
||||
symbol_name_format_no_rom,
|
||||
args,
|
||||
yaml,
|
||||
):
|
||||
super().__init__(
|
||||
rom_start,
|
||||
rom_end,
|
||||
type,
|
||||
name,
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
symbol_name_format=symbol_name_format,
|
||||
symbol_name_format_no_rom=symbol_name_format_no_rom,
|
||||
args=args,
|
||||
yaml=yaml,
|
||||
)
|
||||
|
||||
self.files = yml.get("files", []) if isinstance(yml, dict) else []
|
||||
self.files = yaml.get("files", []) if isinstance(yaml, dict) else []
|
||||
|
||||
with (Path(__file__).parent / f"{self.name}.yaml").open("r") as f:
|
||||
self.msg_names = yaml.load(f.read(), Loader=yaml.SafeLoader)
|
||||
self.msg_names = yaml_loader.load(f.read(), Loader=yaml_loader.SafeLoader)
|
||||
|
||||
def split(self, rom_bytes):
|
||||
data = rom_bytes[self.rom_start: self.rom_end]
|
||||
|
@ -10,7 +10,7 @@ import xml.etree.ElementTree as ET
|
||||
import struct
|
||||
|
||||
import pylibyaml
|
||||
import yaml
|
||||
import yaml as yaml_loader
|
||||
|
||||
class Sprite:
|
||||
def __init__(self):
|
||||
@ -253,13 +253,42 @@ class Component:
|
||||
class N64SegPm_npc_sprites(N64Segment):
|
||||
DEFAULT_SPRITE_NAMES = [f"{i:02X}" for i in range(0xEA)]
|
||||
|
||||
def __init__(self, rom_start, rom_end, type, name, vram_start, extract, given_subalign, given_is_overlay, given_dir, args, yml):
|
||||
super().__init__(rom_start, rom_end, type, name, vram_start, extract, given_subalign, given_is_overlay, given_dir, args, yml)
|
||||
def __init__(
|
||||
self,
|
||||
rom_start,
|
||||
rom_end,
|
||||
type,
|
||||
name,
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
symbol_name_format,
|
||||
symbol_name_format_no_rom,
|
||||
args,
|
||||
yaml,
|
||||
):
|
||||
super().__init__(
|
||||
rom_start,
|
||||
rom_end,
|
||||
type,
|
||||
name,
|
||||
vram_start,
|
||||
extract,
|
||||
given_subalign,
|
||||
exclusive_ram_id,
|
||||
given_dir,
|
||||
symbol_name_format=symbol_name_format,
|
||||
symbol_name_format_no_rom=symbol_name_format_no_rom,
|
||||
args=args,
|
||||
yaml=yaml,
|
||||
)
|
||||
|
||||
self.files = yml["files"]
|
||||
self.files = yaml["files"]
|
||||
|
||||
with (Path(__file__).parent / f"{self.name}.yaml").open("r") as f:
|
||||
self.sprite_cfg = yaml.load(f.read(), Loader=yaml.SafeLoader)
|
||||
self.sprite_cfg = yaml_loader.load(f.read(), Loader=yaml_loader.SafeLoader)
|
||||
|
||||
def split(self, rom_bytes):
|
||||
out_dir = options.get_asset_path() / self.dir / self.name
|
||||
|
@ -129,6 +129,7 @@ def read_elf():
|
||||
continue
|
||||
|
||||
if "/" in name or \
|
||||
"." in name or \
|
||||
name in ignores or \
|
||||
name.startswith("_") or \
|
||||
name.startswith("jtbl_") or \
|
||||
|
@ -17,7 +17,9 @@ options:
|
||||
asset_path: assets/jp
|
||||
build_path: ver/jp/build
|
||||
cache_path: ver/jp/.splat_cache
|
||||
create_undefined_funcs_auto: False
|
||||
undefined_funcs_auto_path: ver/jp/undefined_funcs_auto.txt
|
||||
create_undefined_syms_auto: False
|
||||
undefined_syms_auto_path: ver/jp/undefined_syms_auto.txt
|
||||
asset_stack:
|
||||
- jp
|
||||
|
27
ver/us/asm/data/E2CA0.data.s
Normal file
27
ver/us/asm/data/E2CA0.data.s
Normal file
@ -0,0 +1,27 @@
|
||||
.include "macro.inc"
|
||||
|
||||
.section .data
|
||||
|
||||
dlabel D_8014C5A0
|
||||
.word 0xFFF40000, 0x00000000, 0x23002300, 0x000000FF, 0x000B0000, 0x00000000, 0x20002300, 0x000000FF, 0x000B0017, 0x00000000, 0x20002000, 0x000000FF, 0xFFF40017, 0x00000000, 0x23002000, 0x000000FF
|
||||
|
||||
dlabel D_8014C5E0
|
||||
.word 0xFFF00000, 0x00000000, 0x24002400, 0x000000FF, 0x000F0000, 0x00000000, 0x20002400, 0x000000FF, 0x000F001F, 0x00000000, 0x20002000, 0x000000FF, 0xFFF0001F, 0x00000000, 0x24002000, 0x000000FF
|
||||
|
||||
dlabel D_8014C620
|
||||
.word 0xE7000000, 0x00000000, 0xD7000002, 0xFFFFFFFF, 0xFCFFFFFF, 0xFFFCF279, 0xE3000C00, 0x00080000, 0xE3000D01, 0x00000000, 0xE3000F00, 0x00000000, 0xE3001001, 0x00000000, 0xE3001201, 0x00002000, 0xE3001402, 0x00000C00, 0xE3001001, 0x00008000, 0xDF000000, 0x00000000
|
||||
|
||||
dlabel D_8014C678
|
||||
.word 0xD9DDFBFF, 0x00000000, 0x01004008, D_8014C5A0, 0x06000204, 0x00000406, 0xE7000000, 0x00000000, 0xDF000000, 0x00000000
|
||||
|
||||
dlabel D_8014C6A0
|
||||
.word 0xD9DDFBFF, 0x00000000, 0x01004008, D_8014C5E0, 0x06000204, 0x00000406, 0xE7000000, 0x00000000, 0xDF000000, 0x00000000
|
||||
|
||||
dlabel D_8014C6C8
|
||||
.word 0xFFFFFF00, 0xFFFFFF00, 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
|
||||
dlabel D_8014C6E0
|
||||
.short 0x0020, 0x0028
|
||||
|
||||
dlabel D_8014C6E4
|
||||
.short 0x0008, 0x0004, 0x0000, 0x0000, 0x0000, 0x0000
|
@ -1,182 +0,0 @@
|
||||
.set noat # allow manual use of $at
|
||||
.set noreorder # don't insert nops after branches
|
||||
|
||||
glabel func_8002D160
|
||||
/* 8560 8002D160 27BDFFC0 */ addiu $sp, $sp, -0x40
|
||||
/* 8564 8002D164 AFB60030 */ sw $s6, 0x30($sp)
|
||||
/* 8568 8002D168 3C16759A */ lui $s6, 0x759a
|
||||
/* 856C 8002D16C 26D6F6D8 */ addiu $s6, $s6, -0x928
|
||||
/* 8570 8002D170 AFB5002C */ sw $s5, 0x2c($sp)
|
||||
/* 8574 8002D174 3C15F79E */ lui $s5, %hi(D_F79DDD0F)
|
||||
/* 8578 8002D178 26B5DD0F */ addiu $s5, $s5, %lo(D_F79DDD0F)
|
||||
/* 857C 8002D17C AFB30024 */ sw $s3, 0x24($sp)
|
||||
/* 8580 8002D180 3C130B11 */ lui $s3, 0xb11
|
||||
/* 8584 8002D184 36732D28 */ ori $s3, $s3, 0x2d28
|
||||
/* 8588 8002D188 AFB00018 */ sw $s0, 0x18($sp)
|
||||
/* 858C 8002D18C 0000802D */ daddu $s0, $zero, $zero
|
||||
/* 8590 8002D190 3C05B000 */ lui $a1, 0xb000
|
||||
/* 8594 8002D194 34A50D10 */ ori $a1, $a1, 0xd10
|
||||
/* 8598 8002D198 3C04800A */ lui $a0, %hi(nuPiCartHandle)
|
||||
/* 859C 8002D19C 8C84A638 */ lw $a0, %lo(nuPiCartHandle)($a0)
|
||||
/* 85A0 8002D1A0 27A60010 */ addiu $a2, $sp, 0x10
|
||||
/* 85A4 8002D1A4 AFB20020 */ sw $s2, 0x20($sp)
|
||||
/* 85A8 8002D1A8 0200902D */ daddu $s2, $s0, $zero
|
||||
/* 85AC 8002D1AC AFB40028 */ sw $s4, 0x28($sp)
|
||||
/* 85B0 8002D1B0 3C148006 */ lui $s4, %hi(osEPiReadIo)
|
||||
/* 85B4 8002D1B4 26940DC0 */ addiu $s4, $s4, %lo(osEPiReadIo)
|
||||
/* 85B8 8002D1B8 AFBF003C */ sw $ra, 0x3c($sp)
|
||||
/* 85BC 8002D1BC AFBE0038 */ sw $fp, 0x38($sp)
|
||||
/* 85C0 8002D1C0 AFB70034 */ sw $s7, 0x34($sp)
|
||||
/* 85C4 8002D1C4 0280F809 */ jalr $s4
|
||||
/* 85C8 8002D1C8 AFB1001C */ sw $s1, 0x1c($sp)
|
||||
/* 85CC 8002D1CC 3C110031 */ lui $s1, 0x31
|
||||
/* 85D0 8002D1D0 26316D90 */ addiu $s1, $s1, 0x6d90
|
||||
/* 85D4 8002D1D4 8FA20010 */ lw $v0, 0x10($sp)
|
||||
/* 85D8 8002D1D8 3C030031 */ lui $v1, 0x31
|
||||
/* 85DC 8002D1DC 24636F30 */ addiu $v1, $v1, 0x6f30
|
||||
/* 85E0 8002D1E0 02629823 */ subu $s3, $s3, $v0
|
||||
/* 85E4 8002D1E4 0223102B */ sltu $v0, $s1, $v1
|
||||
/* 85E8 8002D1E8 1040002B */ beqz $v0, .L8002D298
|
||||
/* 85EC 8002D1EC 241E0003 */ addiu $fp, $zero, 3
|
||||
/* 85F0 8002D1F0 0060B82D */ daddu $s7, $v1, $zero
|
||||
.L8002D1F4:
|
||||
/* 85F4 8002D1F4 0220282D */ daddu $a1, $s1, $zero
|
||||
/* 85F8 8002D1F8 3C04800A */ lui $a0, %hi(nuPiCartHandle)
|
||||
/* 85FC 8002D1FC 8C84A638 */ lw $a0, %lo(nuPiCartHandle)($a0)
|
||||
/* 8600 8002D200 0280F809 */ jalr $s4
|
||||
/* 8604 8002D204 27A60010 */ addiu $a2, $sp, 0x10
|
||||
/* 8608 8002D208 8FA30010 */ lw $v1, 0x10($sp)
|
||||
/* 860C 8002D20C 2407000F */ addiu $a3, $zero, 0xf
|
||||
/* 8610 8002D210 3065FFFF */ andi $a1, $v1, 0xffff
|
||||
/* 8614 8002D214 00032402 */ srl $a0, $v1, 0x10
|
||||
/* 8618 8002D218 00A41021 */ addu $v0, $a1, $a0
|
||||
/* 861C 8002D21C 02028021 */ addu $s0, $s0, $v0
|
||||
/* 8620 8002D220 00121682 */ srl $v0, $s2, 0x1a
|
||||
/* 8624 8002D224 14470010 */ bne $v0, $a3, .L8002D268
|
||||
/* 8628 8002D228 00031682 */ srl $v0, $v1, 0x1a
|
||||
/* 862C 8002D22C 24070009 */ addiu $a3, $zero, 9
|
||||
/* 8630 8002D230 50470004 */ beql $v0, $a3, .L8002D244
|
||||
/* 8634 8002D234 00031542 */ srl $v0, $v1, 0x15
|
||||
/* 8638 8002D238 24070023 */ addiu $a3, $zero, 0x23
|
||||
/* 863C 8002D23C 1447000A */ bne $v0, $a3, .L8002D268
|
||||
/* 8640 8002D240 00031542 */ srl $v0, $v1, 0x15
|
||||
.L8002D244:
|
||||
/* 8644 8002D244 3043001F */ andi $v1, $v0, 0x1f
|
||||
/* 8648 8002D248 00121402 */ srl $v0, $s2, 0x10
|
||||
/* 864C 8002D24C 3042001F */ andi $v0, $v0, 0x1f
|
||||
/* 8650 8002D250 14620005 */ bne $v1, $v0, .L8002D268
|
||||
/* 8654 8002D254 3082001F */ andi $v0, $a0, 0x1f
|
||||
/* 8658 8002D258 14620003 */ bne $v1, $v0, .L8002D268
|
||||
/* 865C 8002D25C 3242FFFF */ andi $v0, $s2, 0xffff
|
||||
/* 8660 8002D260 02058023 */ subu $s0, $s0, $a1
|
||||
/* 8664 8002D264 02028023 */ subu $s0, $s0, $v0
|
||||
.L8002D268:
|
||||
/* 8668 8002D268 8FA40010 */ lw $a0, 0x10($sp)
|
||||
/* 866C 8002D26C 00041682 */ srl $v0, $a0, 0x1a
|
||||
/* 8670 8002D270 145E0006 */ bne $v0, $fp, .L8002D28C
|
||||
/* 8674 8002D274 26310004 */ addiu $s1, $s1, 4
|
||||
/* 8678 8002D278 3083FFFF */ andi $v1, $a0, 0xffff
|
||||
/* 867C 8002D27C 00041402 */ srl $v0, $a0, 0x10
|
||||
/* 8680 8002D280 3042FC00 */ andi $v0, $v0, 0xfc00
|
||||
/* 8684 8002D284 00621821 */ addu $v1, $v1, $v0
|
||||
/* 8688 8002D288 02038023 */ subu $s0, $s0, $v1
|
||||
.L8002D28C:
|
||||
/* 868C 8002D28C 0237102B */ sltu $v0, $s1, $s7
|
||||
/* 8690 8002D290 1440FFD8 */ bnez $v0, .L8002D1F4
|
||||
/* 8694 8002D294 0080902D */ daddu $s2, $a0, $zero
|
||||
.L8002D298:
|
||||
/* 8698 8002D298 3C02FFD5 */ lui $v0, 0xffd5
|
||||
/* 869C 8002D29C 3442B14A */ ori $v0, $v0, 0xb14a
|
||||
/* 86A0 8002D2A0 02021021 */ addu $v0, $s0, $v0
|
||||
/* 86A4 8002D2A4 02621023 */ subu $v0, $s3, $v0
|
||||
/* 86A8 8002D2A8 02C2B021 */ addu $s6, $s6, $v0
|
||||
/* 86AC 8002D2AC 3C1318F4 */ lui $s3, 0x18f4
|
||||
/* 86B0 8002D2B0 367314AB */ ori $s3, $s3, 0x14ab
|
||||
/* 86B4 8002D2B4 0000802D */ daddu $s0, $zero, $zero
|
||||
/* 86B8 8002D2B8 3C05B000 */ lui $a1, 0xb000
|
||||
/* 86BC 8002D2BC 34A50E38 */ ori $a1, $a1, 0xe38
|
||||
/* 86C0 8002D2C0 27A60014 */ addiu $a2, $sp, 0x14
|
||||
/* 86C4 8002D2C4 3C04800A */ lui $a0, %hi(nuPiCartHandle)
|
||||
/* 86C8 8002D2C8 8C84A638 */ lw $a0, %lo(nuPiCartHandle)($a0)
|
||||
/* 86CC 8002D2CC 3C148006 */ lui $s4, %hi(osEPiReadIo)
|
||||
/* 86D0 8002D2D0 26940DC0 */ addiu $s4, $s4, %lo(osEPiReadIo)
|
||||
/* 86D4 8002D2D4 0280F809 */ jalr $s4
|
||||
/* 86D8 8002D2D8 0200902D */ daddu $s2, $s0, $zero
|
||||
/* 86DC 8002D2DC 3C110031 */ lui $s1, 0x31
|
||||
/* 86E0 8002D2E0 26316F30 */ addiu $s1, $s1, 0x6f30
|
||||
/* 86E4 8002D2E4 8FA20014 */ lw $v0, 0x14($sp)
|
||||
/* 86E8 8002D2E8 3C030031 */ lui $v1, 0x31
|
||||
/* 86EC 8002D2EC 24637020 */ addiu $v1, $v1, 0x7020
|
||||
/* 86F0 8002D2F0 02629823 */ subu $s3, $s3, $v0
|
||||
/* 86F4 8002D2F4 0223102B */ sltu $v0, $s1, $v1
|
||||
/* 86F8 8002D2F8 1040002B */ beqz $v0, .L8002D3A8
|
||||
/* 86FC 8002D2FC 241E0003 */ addiu $fp, $zero, 3
|
||||
/* 8700 8002D300 0060B82D */ daddu $s7, $v1, $zero
|
||||
.L8002D304:
|
||||
/* 8704 8002D304 0220282D */ daddu $a1, $s1, $zero
|
||||
/* 8708 8002D308 3C04800A */ lui $a0, %hi(nuPiCartHandle)
|
||||
/* 870C 8002D30C 8C84A638 */ lw $a0, %lo(nuPiCartHandle)($a0)
|
||||
/* 8710 8002D310 0280F809 */ jalr $s4
|
||||
/* 8714 8002D314 27A60014 */ addiu $a2, $sp, 0x14
|
||||
/* 8718 8002D318 8FA30014 */ lw $v1, 0x14($sp)
|
||||
/* 871C 8002D31C 2407000F */ addiu $a3, $zero, 0xf
|
||||
/* 8720 8002D320 3065FFFF */ andi $a1, $v1, 0xffff
|
||||
/* 8724 8002D324 00032402 */ srl $a0, $v1, 0x10
|
||||
/* 8728 8002D328 00A41021 */ addu $v0, $a1, $a0
|
||||
/* 872C 8002D32C 02028021 */ addu $s0, $s0, $v0
|
||||
/* 8730 8002D330 00121682 */ srl $v0, $s2, 0x1a
|
||||
/* 8734 8002D334 14470010 */ bne $v0, $a3, .L8002D378
|
||||
/* 8738 8002D338 00031682 */ srl $v0, $v1, 0x1a
|
||||
/* 873C 8002D33C 24070009 */ addiu $a3, $zero, 9
|
||||
/* 8740 8002D340 50470004 */ beql $v0, $a3, .L8002D354
|
||||
/* 8744 8002D344 00031542 */ srl $v0, $v1, 0x15
|
||||
/* 8748 8002D348 24070023 */ addiu $a3, $zero, 0x23
|
||||
/* 874C 8002D34C 1447000A */ bne $v0, $a3, .L8002D378
|
||||
/* 8750 8002D350 00031542 */ srl $v0, $v1, 0x15
|
||||
.L8002D354:
|
||||
/* 8754 8002D354 3043001F */ andi $v1, $v0, 0x1f
|
||||
/* 8758 8002D358 00121402 */ srl $v0, $s2, 0x10
|
||||
/* 875C 8002D35C 3042001F */ andi $v0, $v0, 0x1f
|
||||
/* 8760 8002D360 14620005 */ bne $v1, $v0, .L8002D378
|
||||
/* 8764 8002D364 3082001F */ andi $v0, $a0, 0x1f
|
||||
/* 8768 8002D368 14620003 */ bne $v1, $v0, .L8002D378
|
||||
/* 876C 8002D36C 3242FFFF */ andi $v0, $s2, 0xffff
|
||||
/* 8770 8002D370 02058023 */ subu $s0, $s0, $a1
|
||||
/* 8774 8002D374 02028023 */ subu $s0, $s0, $v0
|
||||
.L8002D378:
|
||||
/* 8778 8002D378 8FA40014 */ lw $a0, 0x14($sp)
|
||||
/* 877C 8002D37C 00041682 */ srl $v0, $a0, 0x1a
|
||||
/* 8780 8002D380 145E0006 */ bne $v0, $fp, .L8002D39C
|
||||
/* 8784 8002D384 26310004 */ addiu $s1, $s1, 4
|
||||
/* 8788 8002D388 3083FFFF */ andi $v1, $a0, 0xffff
|
||||
/* 878C 8002D38C 00041402 */ srl $v0, $a0, 0x10
|
||||
/* 8790 8002D390 3042FC00 */ andi $v0, $v0, 0xfc00
|
||||
/* 8794 8002D394 00621821 */ addu $v1, $v1, $v0
|
||||
/* 8798 8002D398 02038023 */ subu $s0, $s0, $v1
|
||||
.L8002D39C:
|
||||
/* 879C 8002D39C 0237102B */ sltu $v0, $s1, $s7
|
||||
/* 87A0 8002D3A0 1440FFD8 */ bnez $v0, .L8002D304
|
||||
/* 87A4 8002D3A4 0080902D */ daddu $s2, $a0, $zero
|
||||
.L8002D3A8:
|
||||
/* 87A8 8002D3A8 3C04FFF1 */ lui $a0, 0xfff1
|
||||
/* 87AC 8002D3AC 34842BE4 */ ori $a0, $a0, 0x2be4
|
||||
/* 87B0 8002D3B0 02042021 */ addu $a0, $s0, $a0
|
||||
/* 87B4 8002D3B4 02642023 */ subu $a0, $s3, $a0
|
||||
/* 87B8 8002D3B8 02A42021 */ addu $a0, $s5, $a0
|
||||
/* 87BC 8002D3BC 3C050031 */ lui $a1, 0x31
|
||||
/* 87C0 8002D3C0 24A57020 */ addiu $a1, $a1, 0x7020
|
||||
/* 87C4 8002D3C4 0C00A5CF */ jal dma_copy
|
||||
/* 87C8 8002D3C8 02C0302D */ daddu $a2, $s6, $zero
|
||||
/* 87CC 8002D3CC 8FBF003C */ lw $ra, 0x3c($sp)
|
||||
/* 87D0 8002D3D0 8FBE0038 */ lw $fp, 0x38($sp)
|
||||
/* 87D4 8002D3D4 8FB70034 */ lw $s7, 0x34($sp)
|
||||
/* 87D8 8002D3D8 8FB60030 */ lw $s6, 0x30($sp)
|
||||
/* 87DC 8002D3DC 8FB5002C */ lw $s5, 0x2c($sp)
|
||||
/* 87E0 8002D3E0 8FB40028 */ lw $s4, 0x28($sp)
|
||||
/* 87E4 8002D3E4 8FB30024 */ lw $s3, 0x24($sp)
|
||||
/* 87E8 8002D3E8 8FB20020 */ lw $s2, 0x20($sp)
|
||||
/* 87EC 8002D3EC 8FB1001C */ lw $s1, 0x1c($sp)
|
||||
/* 87F0 8002D3F0 8FB00018 */ lw $s0, 0x18($sp)
|
||||
/* 87F4 8002D3F4 03E00008 */ jr $ra
|
||||
/* 87F8 8002D3F8 27BD0040 */ addiu $sp, $sp, 0x40
|
||||
/* 87FC 8002D3FC 00000000 */ nop
|
@ -7,7 +7,8 @@ options:
|
||||
mnemonic_ljust: 10
|
||||
platform: n64
|
||||
subalign: 8
|
||||
auto_all_sections: True
|
||||
auto_all_sections: [".data", ".rodata", ".bss"]
|
||||
asm_data_macro: "dlabel"
|
||||
|
||||
base_path: ../..
|
||||
target_path: ver/us/baserom.z64
|
||||
@ -37,7 +38,8 @@ segments:
|
||||
subsegments:
|
||||
- [0x0040, asm, boot]
|
||||
- [0x0B70, bin, rspboot_font]
|
||||
- type: code
|
||||
- name: main
|
||||
type: code
|
||||
start: 0x1000
|
||||
vram: 0x80025C00
|
||||
subsegments:
|
||||
@ -286,7 +288,6 @@ segments:
|
||||
type: .data
|
||||
name: curtains
|
||||
subsegments:
|
||||
- [0x4F9E0, .data, curtains]
|
||||
- [0x4F9E0, i4, sprite/unk_checkers, 16, 32]
|
||||
- [0x4FAE0]
|
||||
- [0x4FB30, rgba32, sprite/curtains, 32, 32]
|
||||
@ -758,7 +759,7 @@ segments:
|
||||
type: .data
|
||||
name: 8e790_len_2850
|
||||
subsegments:
|
||||
- [0xA2D90, .data, 8e790_len_2850]
|
||||
- [0xA2D90]
|
||||
- [0xA2E90, ia8, ui/box/corners9, 16, 64]
|
||||
- [0xA3290, ia8, ui/box/corners8, 24, 96]
|
||||
- [0xA3B90, ia8, ui/box/corners6, 16, 40]
|
||||
@ -805,7 +806,7 @@ segments:
|
||||
type: .data
|
||||
name: cd180_len_38f0
|
||||
subsegments:
|
||||
- [0xE2DF0, .data, cd180_len_38f0]
|
||||
- [0xE2DF0]
|
||||
- [0xE2E00, i4, ui/stencil/star, 32, 64]
|
||||
- [0xE3200, i4, ui/stencil/mario, 64, 64]
|
||||
- [0xE3A00, i4, ui/stencil/sharp_circle, 32, 32]
|
||||
@ -1111,7 +1112,8 @@ segments:
|
||||
- [0x161E70, .data, pause_gfx]
|
||||
- [0x162D30, .data, pause_styles]
|
||||
- [0x1632A0]
|
||||
- type: code
|
||||
- name: filemenu
|
||||
type: code
|
||||
start: 0x163400
|
||||
vram: 0x80242BA0
|
||||
subsegments:
|
||||
@ -2494,7 +2496,42 @@ segments:
|
||||
- [0x325AD0, c]
|
||||
- [0x325EE0, pm_effect_shims, effect_shims]
|
||||
- [0x326160, .data, 325AD0]
|
||||
- [0x326410, bin] # big_smoke_puff gfx
|
||||
- name: effect_gfx_big_smoke_puff
|
||||
dir: effects/gfx
|
||||
type: code
|
||||
start: 0x326410
|
||||
vram: 0x09000000
|
||||
symbol_name_format: $VRAM_$ROM
|
||||
subsegments:
|
||||
- [0x326410, c, big_smoke_puff]
|
||||
- start: 0x326410
|
||||
type: .data
|
||||
name: big_smoke_puff
|
||||
subsegments:
|
||||
- [0x326410, ci4, D_09000000_326410, 32, 32]
|
||||
- [0x326610, palette, D_09000000_326410]
|
||||
- [0x326630, ci4, D_09000220_326630, 32, 32]
|
||||
- [0x326830, palette, D_09000220_326630]
|
||||
- [0x326850, ci4, D_09000440_326850, 32, 32]
|
||||
- [0x326A50, palette, D_09000440_326850]
|
||||
- [0x326A70, ci4, D_09000660_326A70, 32, 32]
|
||||
- [0x326C70, palette, D_09000660_326A70]
|
||||
- [0x326C90, ci4, D_09000880_326C90, 32, 32]
|
||||
- [0x326E90, palette, D_09000880_326C90]
|
||||
- [0x326EB0, ci4, D_09000AA0_326EB0, 32, 32]
|
||||
- [0x3270B0, palette, D_09000AA0_326EB0]
|
||||
- [0x3270D0, ci4, D_09000CC0_3270D0, 32, 32]
|
||||
- [0x3272D0, palette, D_09000CC0_3270D0]
|
||||
- [0x3272F0, vtx, D_09000EE0_3272F0]
|
||||
- [0x327330, gfx, D_09000F20_327330]
|
||||
- [0x327398, gfx, D_09000F88_327398]
|
||||
- [0x3273B0, gfx, D_09000FA0_3273B0]
|
||||
- [0x327470, gfx, D_09001060_327470]
|
||||
- [0x327530, gfx, D_09001120_327530]
|
||||
- [0x3275F0, gfx, D_090011E0_3275F0]
|
||||
- [0x3276B0, gfx, D_090012A0_3276B0]
|
||||
- [0x327770, gfx, D_09001360_327770]
|
||||
- [0x327830, gfx, D_09001420_327830]
|
||||
- name: effect_big_smoke_puff
|
||||
dir: effects
|
||||
type: code
|
||||
@ -2528,7 +2565,37 @@ segments:
|
||||
subsegments:
|
||||
- [0x32C7A0, c, flower_splash]
|
||||
- [0x32CEB0]
|
||||
- [0x32CEC0, bin] # flower_splash, flower_trail gfx
|
||||
- name: effect_gfx_flower_splash_trail
|
||||
dir: effects/gfx
|
||||
type: code
|
||||
start: 0x32CEC0
|
||||
vram: 0x09000000
|
||||
symbol_name_format: $VRAM_$ROM
|
||||
subsegments:
|
||||
- [0x32CEC0, c, flower_splash_trail]
|
||||
- start: 0x32CEC0
|
||||
type: .data
|
||||
name: flower_splash_trail
|
||||
subsegments:
|
||||
- [0x32CEC0, ci4, D_09000000_32CEC0, 16, 16]
|
||||
- [0x32CF40, palette, D_09000000_32CEC0]
|
||||
- [0x32CF60, palette, D_09000000_32CEC0.yellow]
|
||||
- [0x32CF80, rgba16, D_090000C0_32CF80, 32, 32]
|
||||
- [0x32D780, vtx, D_090008C0_32D780]
|
||||
- [0x32D8F0, vtx, D_09000A30_32D8F0]
|
||||
- [0x32D900, vtx, D_09000A40_32D900]
|
||||
- [0x32D910, vtx, D_09000A50_32D910]
|
||||
- [0x32D950, vtx, D_09000A90_32D950]
|
||||
- [0x32D970, vtx, D_09000AB0_32D970]
|
||||
- [0x32D9B0, vtx, D_09000AF0_32D9B0]
|
||||
- [0x32DA10, gfx, D_09000B50_32DA10]
|
||||
- [0x32DAD0, gfx, D_09000C10_32DAD0]
|
||||
- [0x32DB90, gfx, D_09000CD0_32DB90]
|
||||
- [0x32DC18, gfx, D_09000D58_32DC18]
|
||||
- [0x32DC50, gfx, D_09000D90_32DC50]
|
||||
- [0x32DCC8, gfx, D_09000E08_32DCC8]
|
||||
- [0x32DCE0, gfx, D_09000E20_32DCE0]
|
||||
- [0x32DCF8, gfx, D_09000E38_32DCF8]
|
||||
- name: effect_flower_trail
|
||||
dir: effects
|
||||
type: code
|
||||
@ -2544,7 +2611,24 @@ segments:
|
||||
subsegments:
|
||||
- [0x32E490, c, cloud_puff]
|
||||
- [0x32EC10]
|
||||
- [0x32EC50, bin] # cloud_puff, cloud_trail gfx
|
||||
- name: effect_gfx_cloud_puff_trail
|
||||
dir: effects/gfx
|
||||
type: code
|
||||
start: 0x32EC50
|
||||
vram: 0x09000000
|
||||
symbol_name_format: $VRAM_$ROM
|
||||
subsegments:
|
||||
- [0x32EC50, c, cloud_puff_trail]
|
||||
- start: 0x32EC50
|
||||
type: .data
|
||||
name: cloud_puff_trail
|
||||
subsegments:
|
||||
- [0x32EC50, ci4, D_09000000_32EC50, 16, 16]
|
||||
- [0x32ECD0, palette, D_09000000_32EC50]
|
||||
- [0x32ECF0, vtx, D_090000A0_32ECF0]
|
||||
- [0x32ED30, gfx, D_090000E0_32ED30]
|
||||
- [0x32EE08, gfx, D_090001B8_32EE08]
|
||||
- [0x32EE28]
|
||||
- name: effect_cloud_trail
|
||||
dir: effects
|
||||
type: code
|
||||
@ -2560,7 +2644,22 @@ segments:
|
||||
vram: 0xE0018000
|
||||
subsegments:
|
||||
- [0x32F580, c, footprint]
|
||||
- [0x32FB50, bin] # footprint gfx
|
||||
- name: effect_gfx_footprint
|
||||
dir: effects/gfx
|
||||
type: code
|
||||
start: 0x32FB50
|
||||
vram: 0x09000000
|
||||
symbol_name_format: $VRAM_$ROM
|
||||
subsegments:
|
||||
- [0x32FB50, c, footprint]
|
||||
- start: 0x32FB50
|
||||
type: .data
|
||||
name: footprint
|
||||
subsegments:
|
||||
- [0x32FB50, i4, D_09000000_32FB50, 32, 32]
|
||||
- [0x32FD50, vtx, D_09000200_32FD50]
|
||||
- [0x32FD90, gfx, D_09000240_32FD90]
|
||||
- [0x32FE28]
|
||||
- name: effect_floating_flower
|
||||
dir: effects
|
||||
type: code
|
||||
@ -2569,7 +2668,26 @@ segments:
|
||||
subsegments:
|
||||
- [0x32FE30, c, floating_flower]
|
||||
- [0x330440]
|
||||
- [0x330460, bin] # floating_flower gfx
|
||||
- name: effect_gfx_floating_flower
|
||||
dir: effects/gfx
|
||||
type: code
|
||||
start: 0x330460
|
||||
vram: 0x09000000
|
||||
symbol_name_format: $VRAM_$ROM
|
||||
subsegments:
|
||||
- [0x330460, c, floating_flower]
|
||||
- start: 0x330460
|
||||
type: .data
|
||||
name: floating_flower
|
||||
subsegments:
|
||||
- [0x330460, ci4, D_09000000_330460, 16, 16]
|
||||
- [0x3304E0, palette, D_09000000_330460]
|
||||
- [0x330500, vtx, D_090000A0_330500]
|
||||
- [0x3305D0, vtx, D_09000170_3305D0]
|
||||
- [0x330690, vtx, D_09000230_330690]
|
||||
- [0x330750, gfx, D_090002F0_330750]
|
||||
- [0x3308B0, gfx, D_09000450_3308B0]
|
||||
- [0x330908]
|
||||
- name: effect_snowflake
|
||||
dir: effects
|
||||
type: code
|
||||
@ -2578,7 +2696,26 @@ segments:
|
||||
subsegments:
|
||||
- [0x330910, c, snowflake]
|
||||
- [0x330EF0]
|
||||
- [0x330F00, bin] # snowflake gfx
|
||||
- name: effect_gfx_snowflake
|
||||
dir: effects/gfx
|
||||
type: code
|
||||
start: 0x330F00
|
||||
vram: 0x09000000
|
||||
symbol_name_format: $VRAM_$ROM
|
||||
subsegments:
|
||||
- [0x330F00, c, snowflake]
|
||||
- start: 0x330F00
|
||||
type: .data
|
||||
name: snowflake
|
||||
subsegments:
|
||||
- [0x330F00, i4, D_09000000_330F00, 16, 16]
|
||||
- [0x330F80, i4, D_09000080_330F80, 64, 64]
|
||||
- [0x331780, vtx, D_09000880_331780]
|
||||
- [0x3317C0, vtx, D_090008C0_3317C0]
|
||||
- [0x331800, gfx, D_09000900_331800]
|
||||
- [0x3318E8, gfx, D_090009E8_3318E8]
|
||||
- [0x331910, gfx, D_09000A10_331910]
|
||||
- [0x331938]
|
||||
- name: effect_star
|
||||
dir: effects
|
||||
type: code
|
||||
@ -2721,7 +2858,62 @@ segments:
|
||||
- [0x34F4C0, c, damage_indicator]
|
||||
- [0x350160, .data, damage_indicator]
|
||||
- [0x350200, .rodata, damage_indicator]
|
||||
- [0x350220, bin] # damage_indicator gfx
|
||||
- name: effect_gfx_damage_indicator
|
||||
dir: effects/gfx
|
||||
type: code
|
||||
start: 0x350220
|
||||
vram: 0x09000000
|
||||
symbol_name_format: $VRAM_$ROM
|
||||
subsegments:
|
||||
- [0x350220, c, damage_indicator]
|
||||
- start: 0x350220
|
||||
type: .data
|
||||
name: damage_indicator
|
||||
subsegments:
|
||||
- [0x350220, i4, D_09000000_350220, 32, 32]
|
||||
- [0x350420, i4, D_09000200_350420, 32, 32]
|
||||
- [0x350620, i4, D_09000400_350620, 32, 32]
|
||||
- [0x350820, i4, D_09000600_350820, 32, 32]
|
||||
- [0x350A20, i4, D_09000800_350A20, 32, 32]
|
||||
- [0x350C20, i4, D_09000A00_350C20, 32, 32]
|
||||
- [0x350E20, i4, D_09000C00_350E20, 32, 32]
|
||||
- [0x351020, i4, D_09000E00_351020, 32, 32]
|
||||
- [0x351220, i4, D_09001000_351220, 32, 32]
|
||||
- [0x351420, i4, D_09001200_351420, 32, 32]
|
||||
- [0x351620, i4, D_09001400_351620, 32, 32]
|
||||
- [0x351820, i4, D_09001600_351820, 32, 32]
|
||||
- [0x351A20, i4, D_09001800_351A20, 32, 32]
|
||||
- [0x351C20, i4, D_09001A00_351C20, 32, 32]
|
||||
- [0x351E20, vtx, D_09001C00_351E20]
|
||||
- [0x351E30, vtx, D_09001C10_351E30]
|
||||
- [0x351E50, vtx, D_09001C30_351E50]
|
||||
- [0x351E60, vtx, D_09001C40_351E60]
|
||||
- [0x351EA0, vtx, D_09001C80_351EA0]
|
||||
- [0x351EE0, vtx, D_09001CC0_351EE0]
|
||||
- [0x351F20, vtx, D_09001D00_351F20]
|
||||
- [0x351F60, gfx, D_09001D40_351F60]
|
||||
- [0x352000, gfx, D_09001DE0_352000]
|
||||
- [0x352070, gfx, D_09001E50_352070]
|
||||
- [0x3520B0, gfx, D_09001E90_3520B0]
|
||||
- [0x3520F0, gfx, D_09001ED0_3520F0]
|
||||
- [0x352130, gfx, D_09001F10_352130]
|
||||
- [0x352170, gfx, D_09001F50_352170]
|
||||
- [0x3521B0, gfx, D_09001F90_3521B0]
|
||||
- [0x3521F0, gfx, D_09001FD0_3521F0]
|
||||
- [0x352230, gfx, D_09002010_352230]
|
||||
- [0x352270, gfx, D_09002050_352270]
|
||||
- [0x3522B0, gfx, D_09002090_3522B0]
|
||||
- [0x3522F0, gfx, D_090020D0_3522F0]
|
||||
- [0x352330, gfx, D_09002110_352330]
|
||||
- [0x352370, gfx, D_09002150_352370]
|
||||
- [0x352380, gfx, D_09002160_352380]
|
||||
- [0x352390, gfx, D_09002170_352390]
|
||||
- [0x3523A0, gfx, D_09002180_3523A0]
|
||||
- [0x3523B0, gfx, D_09002190_3523B0]
|
||||
- [0x3523C8, gfx, D_090021A8_3523C8]
|
||||
- [0x3523E0, gfx, D_090021C0_3523E0]
|
||||
- [0x352400, gfx, D_090021E0_352400]
|
||||
- [0x352420, gfx, D_09002200_352420]
|
||||
- name: effect_purple_ring
|
||||
dir: effects
|
||||
type: code
|
||||
@ -2870,7 +3062,26 @@ segments:
|
||||
subsegments:
|
||||
- [0x363160, c, big_snowflakes]
|
||||
- [0x363890]
|
||||
- [0x3638C0, bin] # big_snowflakes gfx
|
||||
- name: effect_gfx_big_snowflakes
|
||||
dir: effects/gfx
|
||||
type: code
|
||||
start: 0x3638C0
|
||||
vram: 0x09000000
|
||||
symbol_name_format: $VRAM_$ROM
|
||||
subsegments:
|
||||
- [0x3638C0, c, big_snowflakes]
|
||||
- start: 0x3638C0
|
||||
type: .data
|
||||
name: big_snowflakes
|
||||
subsegments:
|
||||
- [0x3638C0, i4, D_09000000_3638C0, 16, 16]
|
||||
- [0x363940, i4, D_09000080_363940, 64, 64]
|
||||
- [0x364140, vtx, D_09000880_364140]
|
||||
- [0x364180, vtx, D_090008C0_364180]
|
||||
- [0x3641C0, gfx, D_09000900_3641C0]
|
||||
- [0x3642A8, gfx, D_090009E8_3642A8]
|
||||
- [0x3642D0, gfx, D_09000A10_3642D0]
|
||||
- [0x3642F8]
|
||||
- name: effect_debuff
|
||||
dir: effects
|
||||
type: code
|
||||
@ -2879,7 +3090,23 @@ segments:
|
||||
subsegments:
|
||||
- [0x364300, c, debuff]
|
||||
- [0x364BC0]
|
||||
- [0x364C00, bin] # debuff gfx
|
||||
- name: effect_gfx_debuff
|
||||
dir: effects/gfx
|
||||
type: code
|
||||
start: 0x364C00
|
||||
vram: 0x09000000
|
||||
symbol_name_format: $VRAM_$ROM
|
||||
subsegments:
|
||||
- [0x364C00, c, debuff]
|
||||
- start: 0x364C00
|
||||
type: .data
|
||||
name: debuff
|
||||
subsegments:
|
||||
- [0x364C00, i4, D_09000000_364C00, 32, 32]
|
||||
- [0x364E00, vtx, D_09000200_364E00]
|
||||
- [0x364E40, gfx, D_09000240_364E40]
|
||||
- [0x364EE8, gfx, D_090002E8_364EE8]
|
||||
- [0x364F08]
|
||||
- name: effect_green_impact
|
||||
dir: effects
|
||||
type: code
|
||||
@ -3021,7 +3248,54 @@ segments:
|
||||
subsegments:
|
||||
- [0x385640, c, disable_x]
|
||||
- [0x386340]
|
||||
- [0x3863B0, bin] # disable_x gfx
|
||||
- name: effect_gfx_disable_x
|
||||
dir: effects/gfx
|
||||
type: code
|
||||
start: 0x3863B0
|
||||
vram: 0x09000000
|
||||
symbol_name_format: $VRAM_$ROM
|
||||
subsegments:
|
||||
- [0x3863B0, c, disable_x]
|
||||
- start: 0x3863B0
|
||||
type: .data
|
||||
name: disable_x
|
||||
subsegments:
|
||||
- [0x3863B0, i4, D_09000000_3863B0, 32, 32]
|
||||
- [0x3865B0, i4, D_09000200_3865B0, 32, 32]
|
||||
- [0x3867B0, i4, D_09000400_3867B0, 32, 32]
|
||||
- [0x3869B0, i4, D_09000600_3869B0, 32, 32]
|
||||
- [0x386BB0, i4, D_09000800_386BB0, 32, 32]
|
||||
- [0x386DB0, i4, D_09000A00_386DB0, 32, 32]
|
||||
- [0x386FB0, i4, D_09000C00_386FB0, 32, 32]
|
||||
- [0x3871B0, i4, D_09000E00_3871B0, 32, 32]
|
||||
- [0x3873B0, i4, D_09001000_3873B0, 32, 32]
|
||||
- [0x3875B0, i4, D_09001200_3875B0, 32, 32]
|
||||
- [0x3877B0, i4, D_09001400_3877B0, 32, 32]
|
||||
- [0x3879B0, i4, D_09001600_3879B0, 32, 32]
|
||||
- [0x387BB0, rgba16, D_09001800_387BB0, 32, 32]
|
||||
- [0x3883B0, vtx, D_09002000_3883B0]
|
||||
- [0x3883F0, vtx, D_09002040_3883F0]
|
||||
- [0x388430, vtx, D_09002080_388430]
|
||||
- [0x388470, vtx, D_090020C0_388470]
|
||||
- [0x3884B0, gfx, D_09002100_3884B0]
|
||||
- [0x388548, gfx, D_09002198_388548]
|
||||
- [0x3885E0, gfx, D_09002230_3885E0]
|
||||
- [0x388600, gfx, D_09002250_388600]
|
||||
- [0x388620, gfx, D_09002270_388620]
|
||||
- [0x388640, gfx, D_09002290_388640]
|
||||
- [0x388660, gfx, D_090022B0_388660]
|
||||
- [0x3886D0, gfx, D_09002320_3886D0]
|
||||
- [0x388710, gfx, D_09002360_388710]
|
||||
- [0x388750, gfx, D_090023A0_388750]
|
||||
- [0x388790, gfx, D_090023E0_388790]
|
||||
- [0x3887D0, gfx, D_09002420_3887D0]
|
||||
- [0x388810, gfx, D_09002460_388810]
|
||||
- [0x388850, gfx, D_090024A0_388850]
|
||||
- [0x388890, gfx, D_090024E0_388890]
|
||||
- [0x3888D0, gfx, D_09002520_3888D0]
|
||||
- [0x388910, gfx, D_09002560_388910]
|
||||
- [0x388950, gfx, D_090025A0_388950]
|
||||
- [0x388990, gfx, D_090025E0_388990]
|
||||
- name: effect_bombette_breaking
|
||||
dir: effects
|
||||
type: code
|
||||
@ -3100,7 +3374,31 @@ segments:
|
||||
subsegments:
|
||||
- [0x391D30, c, small_gold_sparkle]
|
||||
- [0x3923C0]
|
||||
- [0x392440, bin] # small_gold_sparkle gfx
|
||||
- name: effect_gfx_small_gold_sparkle
|
||||
dir: effects/gfx
|
||||
type: code
|
||||
start: 0x392440
|
||||
vram: 0x09000000
|
||||
symbol_name_format: $VRAM_$ROM
|
||||
subsegments:
|
||||
- [0x392440, c, small_gold_sparkle]
|
||||
- start: 0x392440
|
||||
type: .data
|
||||
name: small_gold_sparkle
|
||||
subsegments:
|
||||
- [0x392440, i4, D_09000000_392440, 16, 16]
|
||||
- [0x3924C0, i4, D_09000080_3924C0, 16, 16]
|
||||
- [0x392540, i4, D_09000100_392540, 16, 16]
|
||||
- [0x3925C0, i4, D_09000180_3925C0, 16, 16]
|
||||
- [0x392640, i4, D_09000200_392640, 16, 16]
|
||||
- [0x3926C0, vtx, D_09000280_3926C0]
|
||||
- [0x392700, gfx, D_090002C0_392700]
|
||||
- [0x392770, gfx, D_09000330_392770]
|
||||
- [0x3927B0, gfx, D_09000370_3927B0]
|
||||
- [0x3927F0, gfx, D_090003B0_3927F0]
|
||||
- [0x392830, gfx, D_090003F0_392830]
|
||||
- [0x392870, gfx, D_09000430_392870]
|
||||
- [0x3928B0, gfx, D_09000470_3928B0]
|
||||
- name: effect_flashing_box_shockwave
|
||||
dir: effects
|
||||
type: code
|
||||
@ -3205,7 +3503,55 @@ segments:
|
||||
subsegments:
|
||||
- [0x3AA920, c, butterflies]
|
||||
- [0x3AAFE0]
|
||||
- [0x3AB030, bin] # butterflies gfx
|
||||
- name: effect_gfx_butterflies
|
||||
dir: effects/gfx
|
||||
type: code
|
||||
start: 0x3AB030
|
||||
vram: 0x09000000
|
||||
symbol_name_format: $VRAM_$ROM
|
||||
subsegments:
|
||||
- [0x3AB030, c, butterflies]
|
||||
- start: 0x3AB030
|
||||
type: .data
|
||||
name: butterflies
|
||||
subsegments:
|
||||
- [0x3AB030, ci4, D_09000000_3AB030, 32, 64]
|
||||
- [0x3AB430, palette, D_09000000_3AB030]
|
||||
- [0x3AB450, ci4, D_09000420_3AB450, 32, 64]
|
||||
- [0x3AB850, palette, D_09000420_3AB450]
|
||||
- [0x3AB870, ci4, D_09000840_3AB870, 32, 64]
|
||||
- [0x3ABC70, palette, D_09000840_3AB870]
|
||||
- [0x3ABC80, ci4, D_09000C50_3ABC80, 32, 64]
|
||||
- [0x3AC080, palette, D_09000C50_3ABC80]
|
||||
- [0x3AC0A0, ci4, D_09001070_3AC0A0, 32, 64]
|
||||
- [0x3AC4A0, palette, D_09001070_3AC0A0]
|
||||
- [0x3AC4B0, ci4, D_09001480_3AC4B0, 32, 64]
|
||||
- [0x3AC8B0, palette, D_09001480_3AC4B0]
|
||||
- [0x3AC8D0, ci4, D_090018A0_3AC8D0, 32, 64]
|
||||
- [0x3ACCD0, palette, D_090018A0_3AC8D0]
|
||||
- [0x3ACCF0, ci4, D_09001CC0_3ACCF0, 32, 64]
|
||||
- [0x3AD0F0, palette, D_09001CC0_3ACCF0]
|
||||
- [0x3AD110, ci4, D_090020E0_3AD110, 32, 64]
|
||||
- [0x3AD510, palette, D_090020E0_3AD110]
|
||||
- [0x3AD530, ci4, D_09002500_3AD530, 32, 64]
|
||||
- [0x3AD930, palette, D_09002500_3AD530]
|
||||
- [0x3AD950, ci4, D_09002920_3AD950, 32, 64]
|
||||
- [0x3ADD50, palette, D_09002920_3AD950]
|
||||
- [0x3ADD70, vtx, D_09002D40_3ADD70]
|
||||
- [0x3AE8B0, gfx, D_09003880_3AE8B0]
|
||||
- [0x3AE928, gfx, D_090038F8_3AE928]
|
||||
- [0x3AE998, gfx, D_09003968_3AE998]
|
||||
- [0x3AEA08, gfx, D_090039D8_3AEA08]
|
||||
- [0x3AEA78, gfx, D_09003A48_3AEA78]
|
||||
- [0x3AEAE8, gfx, D_09003AB8_3AEAE8]
|
||||
- [0x3AEB58, gfx, D_09003B28_3AEB58]
|
||||
- [0x3AEBC8, gfx, D_09003B98_3AEBC8]
|
||||
- [0x3AEC38, gfx, D_09003C08_3AEC38]
|
||||
- [0x3AECA8, gfx, D_09003C78_3AECA8]
|
||||
- [0x3AED18, gfx, D_09003CE8_3AED18]
|
||||
- [0x3AED88, gfx, D_09003D58_3AED88]
|
||||
- [0x3AEDF8, gfx, D_09003DC8_3AEDF8]
|
||||
- [0x3AEE18]
|
||||
- name: effect_stat_change
|
||||
dir: effects
|
||||
type: code
|
||||
@ -3339,7 +3685,28 @@ segments:
|
||||
subsegments:
|
||||
- [0x3CF3A0, c, throw_spiny]
|
||||
- [0x3CFAB0]
|
||||
- [0x3CFAF0, bin] # throw_spiny gfx
|
||||
- name: effect_gfx_throw_spiny
|
||||
dir: effects/gfx
|
||||
type: code
|
||||
start: 0x3CFAF0
|
||||
vram: 0x09000000
|
||||
symbol_name_format: $VRAM_$ROM
|
||||
subsegments:
|
||||
- [0x3CFAF0, c, throw_spiny]
|
||||
- start: 0x3CFAF0
|
||||
type: .data
|
||||
name: throw_spiny
|
||||
subsegments:
|
||||
- [0x3CFAF0, ci4, D_09000000_3CFAF0, 32, 32]
|
||||
- [0x3CFCF0, palette, D_09000000_3CFAF0]
|
||||
- [0x3CFD10] # padding
|
||||
- [0x3CFEF0, ci4, D_09000400_3CFEF0, 32, 32]
|
||||
- [0x3D00F0, palette, D_09000400_3CFEF0]
|
||||
- [0x3D0110] # padding
|
||||
- [0x3D02F0, gfx, D_09000800_3D02F0]
|
||||
- [0x3D03C8, gfx, D_090008D8_3D03C8]
|
||||
- [0x3D04A0, vtx, D_090009B0_3D04A0]
|
||||
- [0x3D04E0, gfx, D_090009F0_3D04E0]
|
||||
- name: effect_effect_65
|
||||
dir: effects
|
||||
type: code
|
||||
@ -3808,7 +4175,6 @@ segments:
|
||||
type: .data
|
||||
name: whirlwind
|
||||
subsegments:
|
||||
- [0x424550, .data, whirlwind]
|
||||
- [0x424550, ci4, whirlwind_1, 24, 24]
|
||||
- [0x424670, palette, whirlwind_1]
|
||||
- [0x424690, ci4, whirlwind_2, 24, 24]
|
||||
@ -3929,7 +4295,6 @@ segments:
|
||||
type: .data
|
||||
name: water_block
|
||||
subsegments:
|
||||
- [0x42B650, .data, water_block]
|
||||
- [0x42B650, ci4, water_block_1, 24, 24]
|
||||
- [0x42B770, palette, water_block_1]
|
||||
- [0x42B790, ci4, water_block_2, 24, 24]
|
||||
@ -4588,7 +4953,7 @@ segments:
|
||||
type: .data
|
||||
name: actor/monstar
|
||||
subsegments:
|
||||
- [0x63F040, .data, actor/monstar]
|
||||
- [0x63F040]
|
||||
- [0x63F278, ci4, actor/img, 32, 32]
|
||||
- [0x63F478, palette, actor/img]
|
||||
- [0x63F498]
|
||||
@ -4813,7 +5178,7 @@ segments:
|
||||
vram: 0x802A1000
|
||||
overlay: True
|
||||
subsegments:
|
||||
- [0x715850, c, mushroom] # TODO fix auto_all for .data
|
||||
- [0x715850, c, mushroom]
|
||||
- [0x715E50]
|
||||
- name: fire_flower
|
||||
dir: battle/item
|
||||
@ -4920,7 +5285,7 @@ segments:
|
||||
type: .data
|
||||
name: sleepy_sheep
|
||||
subsegments:
|
||||
- [0x71EFC0, .data, sleepy_sheep]
|
||||
- [0x71EFC0]
|
||||
- [0x71F580, ci4, sleepy_sheep1, 56, 48]
|
||||
- [0x71FAC0, palette, sleepy_sheep1]
|
||||
- [0x71FAE0, ci4, sleepy_sheep2, 56, 48]
|
||||
@ -5030,7 +5395,7 @@ segments:
|
||||
type: .data
|
||||
name: egg_missile
|
||||
subsegments:
|
||||
- [0x7291D0, .data, egg_missile]
|
||||
- [0x7291D0]
|
||||
- [0x729790, ci4, egg_missile1, 32, 32]
|
||||
- [0x729990, palette, egg_missile1]
|
||||
- [0x7299B0, ci4, egg_missile2, 32, 32]
|
||||
@ -5077,7 +5442,7 @@ segments:
|
||||
type: .data
|
||||
name: mystery
|
||||
subsegments:
|
||||
- [0x72CF00, .data, mystery]
|
||||
- [0x72CF00]
|
||||
- [0x72D4C0, ci4, mystery, 32, 32]
|
||||
- [0x72D6C0, palette, mystery]
|
||||
- [0x72D6E0]
|
||||
@ -5111,7 +5476,7 @@ segments:
|
||||
type: .data
|
||||
name: coconut
|
||||
subsegments:
|
||||
- [0x72F960, .data, coconut]
|
||||
- [0x72F960]
|
||||
- [0x72FF20, ci4, coconut, 32, 32]
|
||||
- [0x730120, palette, coconut]
|
||||
- [0x730140]
|
||||
@ -5136,7 +5501,7 @@ segments:
|
||||
type: .data
|
||||
name: strange_cake
|
||||
subsegments:
|
||||
- [0x731EA0, .data, strange_cake]
|
||||
- [0x731EA0]
|
||||
- [0x732470, ci4, strange_cake1, 32, 32]
|
||||
- [0x732670, palette, strange_cake1]
|
||||
- [0x732690, ci4, strange_cake2, 32, 32]
|
||||
@ -7002,7 +7367,7 @@ segments:
|
||||
type: .data
|
||||
name: 9694C0
|
||||
subsegments:
|
||||
- [0x96CC30, .data, 9694C0]
|
||||
- [0x96CC30]
|
||||
- [0x971F98, vtx, vtx/971F98]
|
||||
- [0x9722B8, vtx, vtx/9722B8]
|
||||
- [0x973578]
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -58,25 +58,18 @@ D_F79DDD0F = 0xF79DDD0F;
|
||||
D_FA000028 = 0xFA000028;
|
||||
D_FD100008 = 0xFD100008;
|
||||
|
||||
D_7599F6D8 = 0x7599F6D8;
|
||||
|
||||
// Obfuscation symbols
|
||||
D_7012ACA1 = 0x7012ACA1;
|
||||
D_7012BC11 = 0x7012BC11;
|
||||
D_80026AC7 = 0x80026AC7;
|
||||
D_8004AA85 = 0x8004AA85;
|
||||
obfuscated_battle_heap_create = battle_heap_create - 0xFEFFFFF;
|
||||
obfuscated_general_heap_create = general_heap_create - 0xFEFEFEF;
|
||||
obfuscated_load_engine_data = load_engine_data - 0x315;
|
||||
obfuscated_create_audio_system = create_audio_system - 0x7B;
|
||||
|
||||
fx_sun_undeclared = fx_sun;
|
||||
|
||||
D_E007EC2F = 0xE007EC2F;
|
||||
|
||||
// effect_1
|
||||
D_09000FA0 = 0x09000FA0;
|
||||
D_09001060 = 0x09001060;
|
||||
D_09001120 = 0x09001120;
|
||||
D_090011E0 = 0x090011E0;
|
||||
D_090012A0 = 0x090012A0;
|
||||
D_09001360 = 0x09001360;
|
||||
D_09001420 = 0x09001420;
|
||||
|
||||
// effect_6
|
||||
D_09002780 = 0x09002780;
|
||||
D_09002868 = 0x09002868;
|
||||
@ -93,27 +86,6 @@ D_09002950 = 0x09002950;
|
||||
D_09002B20 = 0x09002B20;
|
||||
D_09002B40 = 0x09002B40;
|
||||
|
||||
// effect_8
|
||||
D_09000E08 = 0x09000E08;
|
||||
|
||||
// effect_9
|
||||
D_09000E20 = 0x09000E20;
|
||||
D_09000E38 = 0x09000E38;
|
||||
|
||||
// effect_10, effect_11
|
||||
D_090000E0 = 0x090000E0;
|
||||
D_090001B8 = 0x090001B8;
|
||||
|
||||
// effect_12
|
||||
D_09000240 = 0x09000240;
|
||||
|
||||
// effect_13
|
||||
D_090002F0 = 0x090002F0;
|
||||
|
||||
// effect_14
|
||||
D_09000900 = 0x09000900;
|
||||
D_090009E8 = 0x090009E8;
|
||||
|
||||
// effect_16
|
||||
D_09002170 = 0x09002170;
|
||||
D_09002238 = 0x09002238;
|
||||
@ -126,19 +98,6 @@ D_090024A8 = 0x090024A8;
|
||||
D_09002550 = 0x09002550;
|
||||
D_09002578 = 0x09002578;
|
||||
|
||||
// effect 31 (debuff)
|
||||
D_09000240 = 0x09000240;
|
||||
D_090002E8 = 0x090002E8;
|
||||
|
||||
// effect_73
|
||||
D_090002C0 = 0x090002C0;
|
||||
D_09000330 = 0x09000330;
|
||||
D_09000370 = 0x09000370;
|
||||
D_090003B0 = 0x090003B0;
|
||||
D_090003F0 = 0x090003F0;
|
||||
D_09000430 = 0x09000430;
|
||||
D_09000470 = 0x09000470;
|
||||
|
||||
// effect_75
|
||||
D_09001280 = 0x09001280;
|
||||
D_09001358 = 0x09001358;
|
||||
@ -223,78 +182,6 @@ D_09000B88 = 0x09000B88;
|
||||
D_09000C00 = 0x09000C00;
|
||||
D_09000C20 = 0x09000C20;
|
||||
|
||||
// effect_disable_x
|
||||
D_09002100 = 0x09002100;
|
||||
D_09002198 = 0x09002198;
|
||||
D_09002230 = 0x09002230;
|
||||
D_09002250 = 0x09002250;
|
||||
D_09002270 = 0x09002270;
|
||||
D_09002290 = 0x09002290;
|
||||
D_090022B0 = 0x090022B0;
|
||||
D_09002320 = 0x09002320;
|
||||
D_09002360 = 0x09002360;
|
||||
D_090023A0 = 0x090023A0;
|
||||
D_090023E0 = 0x090023E0;
|
||||
D_09002420 = 0x09002420;
|
||||
D_09002460 = 0x09002460;
|
||||
D_090024A0 = 0x090024A0;
|
||||
D_090024E0 = 0x090024E0;
|
||||
D_09002520 = 0x09002520;
|
||||
D_09002560 = 0x09002560;
|
||||
D_090025A0 = 0x090025A0;
|
||||
D_090025E0 = 0x090025E0;
|
||||
|
||||
// effect_throw_spiny
|
||||
D_09000800 = 0x09000800;
|
||||
D_090008D8 = 0x090008D8;
|
||||
D_090009F0 = 0x090009F0;
|
||||
|
||||
// effect_damage_indicator
|
||||
D_09001D40 = 0x09001D40;
|
||||
D_09001DE0 = 0x09001DE0;
|
||||
D_09001E50 = 0x09001E50;
|
||||
D_09001E90 = 0x09001E90;
|
||||
D_09001ED0 = 0x09001ED0;
|
||||
D_09001F10 = 0x09001F10;
|
||||
D_09001F50 = 0x09001F50;
|
||||
D_09001F90 = 0x09001F90;
|
||||
D_09001FD0 = 0x09001FD0;
|
||||
D_09002010 = 0x09002010;
|
||||
D_09002050 = 0x09002050;
|
||||
D_09002090 = 0x09002090;
|
||||
D_090020D0 = 0x090020D0;
|
||||
D_09002110 = 0x09002110;
|
||||
D_09002150 = 0x09002150;
|
||||
D_09002160 = 0x09002160;
|
||||
D_09002170 = 0x09002170;
|
||||
D_09002180 = 0x09002180;
|
||||
D_090021A8 = 0x090021A8;
|
||||
D_09002190 = 0x09002190;
|
||||
D_090021C0 = 0x090021C0;
|
||||
D_090021E0 = 0x090021E0;
|
||||
D_09002200 = 0x09002200;
|
||||
|
||||
// effect_big_snowflakes
|
||||
D_09000900 = 0x09000900;
|
||||
D_090009E8 = 0x090009E8;
|
||||
D_09000A10 = 0x09000A10;
|
||||
|
||||
// effect_butterflies
|
||||
D_09002D40 = 0x09002D40;
|
||||
D_09003880 = 0x09003880;
|
||||
D_090038F8 = 0x090038F8;
|
||||
D_09003968 = 0x09003968;
|
||||
D_090039D8 = 0x090039D8;
|
||||
D_09003A48 = 0x09003A48;
|
||||
D_09003AB8 = 0x09003AB8;
|
||||
D_09003B28 = 0x09003B28;
|
||||
D_09003B98 = 0x09003B98;
|
||||
D_09003C08 = 0x09003C08;
|
||||
D_09003C78 = 0x09003C78;
|
||||
D_09003CE8 = 0x09003CE8;
|
||||
D_09003D58 = 0x09003D58;
|
||||
D_09003DC8 = 0x09003DC8;
|
||||
|
||||
// Invalid pointers from dead code
|
||||
dead_atan2 = 0x8002AF70;
|
||||
dead_gCurrentCamID = 0x800A158C;
|
||||
|
Loading…
Reference in New Issue
Block a user