Add NO0 (Marble Gallery) overlay (#1691)

This adds this overlay to the project.

Importantly, we use a new tool (tools/auto_dedupe_new_overlay) to
process the new overlay and automatically split its C files according to
known duplicate files. As of now, this does not do any decompiling (the
whole overlay is kept as INCLUDE_ASM), but it automatically does all the
file splits and code copying needed. Hopefully this reduces some amount
of duplicated work.

To be clear, this new script is not in any build chain, but is meant to
be used after `make-config` to take the overlay from being a single
giant lump of `us.c` to being individual files, for the sake of easier
deduplicating. It will likely need some revision for future overlays,
but at least it should be a good start toward reducing tedious work.

I'll leave this overlay in place like this for about a week in case
there are any newcomers who would like to try de-duplicating some of
these files and decompiling the new functions; after that week I'll get
into doing things myself.
This commit is contained in:
bismurphy 2024-09-29 19:53:54 -04:00 committed by GitHub
parent ac5a03cf4d
commit 2e4ebb994e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 938 additions and 2 deletions

View File

@ -142,7 +142,7 @@ extract: extract_$(VERSION)
build: ##@ build game files
build: build_$(VERSION)
build_us: main dra weapon ric cen dre mad no3 np3 nz0 sel st0 wrp rwrp mar rbo3 tt_000 tt_001
build_us: main dra weapon ric cen dre mad no0 no3 np3 nz0 sel st0 wrp rwrp mar rbo3 tt_000 tt_001
build_hd: dra $(BUILD_DIR)/WRP.BIN tt_000
clean: ##@ clean extracted files, assets, and build artifacts
git clean -fdx assets/
@ -209,6 +209,7 @@ format-symbols:
./tools/symbols.py remove-orphans config/splat.hd.ric.yaml
./tools/symbols.py remove-orphans config/splat.us.stcen.yaml
./tools/symbols.py remove-orphans config/splat.us.stdre.yaml
./tools/symbols.py remove-orphans config/splat.us.stno0.yaml
./tools/symbols.py remove-orphans config/splat.us.stno3.yaml
./tools/symbols.py remove-orphans config/splat.us.stnp3.yaml
./tools/symbols.py remove-orphans config/splat.us.stnz0.yaml
@ -297,6 +298,12 @@ $(BUILD_DIR)/MAD.BIN: $(BUILD_DIR)/stmad.elf
$(BUILD_DIR)/F_MAD.BIN:
$(GFXSTAGE) e assets/st/mad $@
no0: $(BUILD_DIR)/NO0.BIN $(BUILD_DIR)/F_NO0.BIN
$(BUILD_DIR)/NO0.BIN: $(BUILD_DIR)/stno0.elf
$(OBJCOPY) -O binary $< $@
$(BUILD_DIR)/F_NO0.BIN:
$(GFXSTAGE) e assets/st/no0 $@
no3: $(BUILD_DIR)/NO3.BIN $(BUILD_DIR)/F_NO3.BIN
$(BUILD_DIR)/NO3.BIN: $(BUILD_DIR)/stno3.elf
$(OBJCOPY) -O binary $< $@
@ -492,6 +499,8 @@ disk_prepare: build $(SOTNDISK)
cp $(BUILD_DIR)/F_DRE.BIN $(DISK_DIR)/ST/DRE/F_DRE.BIN
cp $(BUILD_DIR)/MAD.BIN $(DISK_DIR)/ST/MAD/MAD.BIN
cp $(BUILD_DIR)/F_MAD.BIN $(DISK_DIR)/ST/MAD/F_MAD.BIN
cp $(BUILD_DIR)/NO3.BIN $(DISK_DIR)/ST/NO3/NO0.BIN
cp $(BUILD_DIR)/F_NO3.BIN $(DISK_DIR)/ST/NO3/F_NO0.BIN
cp $(BUILD_DIR)/NO3.BIN $(DISK_DIR)/ST/NO3/NO3.BIN
cp $(BUILD_DIR)/F_NO3.BIN $(DISK_DIR)/ST/NO3/F_NO3.BIN
cp $(BUILD_DIR)/NP3.BIN $(DISK_DIR)/ST/NP3/NP3.BIN

View File

@ -4,7 +4,7 @@ PSXCC_FLAGS := -quiet -mcpu=3000 -fgnu-linker -mgas -gcoff
# configuration
PSX_OVLS := dra ric weapon
PSX_KSTAGES := cen dre mad no3 np3 nz0 sel st0 wrp
PSX_KSTAGES := cen dre mad no0 no3 np3 nz0 sel st0 wrp
PSX_RSTAGES := rwrp
PSX_BOSTAGES := mar
PSX_RBOSTAGES := rbo3

View File

@ -22,6 +22,7 @@ This repo does not include any assets or assembly code necessary for compiling t
| ST/CEN/CEN.BIN | ![code coverage CEN.BIN](https://img.shields.io/endpoint?label=CEN%20code&url=https%3A%2F%2Fprogress.deco.mp%2Fdata%2Fsotn%2Fus%2Fcode%2F%3Fmode%3Dshield%26measure%3Dstcen) | ![decompiled functions](https://img.shields.io/endpoint?label=CEN%20funcs&url=https%3A%2F%2Fprogress.deco.mp%2Fdata%2Fsotn%2Fus%2Ffunctions%2F%3Fmode%3Dshield%26measure%3Dstcen) | Center
| ST/DRE/DRE.BIN | ![code coverage DRE.BIN](https://img.shields.io/endpoint?label=DRE%20code&url=https%3A%2F%2Fprogress.deco.mp%2Fdata%2Fsotn%2Fus%2Fcode%2F%3Fmode%3Dshield%26measure%3Dstdre) | ![decompiled functions](https://img.shields.io/endpoint?label=DRE%20funcs&url=https%3A%2F%2Fprogress.deco.mp%2Fdata%2Fsotn%2Fus%2Ffunctions%2F%3Fmode%3Dshield%26measure%3Dstdre) | Nightmare
| ST/MAD/MAD.BIN | ![code coverage MAD.BIN](https://img.shields.io/endpoint?label=MAD%20code&url=https%3A%2F%2Fprogress.deco.mp%2Fdata%2Fsotn%2Fus%2Fcode%2F%3Fmode%3Dshield%26measure%3Dstmad) | ![decompiled functions](https://img.shields.io/endpoint?label=MAD%20funcs&url=https%3A%2F%2Fprogress.deco.mp%2Fdata%2Fsotn%2Fus%2Ffunctions%2F%3Fmode%3Dshield%26measure%3Dstmad) | Debug Room
| ST/NO0/NO0.BIN | ![code coverage NO0.BIN](https://img.shields.io/endpoint?label=NO0%20code&url=https%3A%2F%2Fprogress.deco.mp%2Fdata%2Fsotn%2Fus%2Fcode%2F%3Fmode%3Dshield%26measure%3Dstno0) | ![decompiled functions](https://img.shields.io/endpoint?label=NO0%20funcs&url=https%3A%2F%2Fprogress.deco.mp%2Fdata%2Fsotn%2Fus%2Ffunctions%2F%3Fmode%3Dshield%26measure%3Dstno0) | Marble Gallery
| ST/NO3/NO3.BIN | ![code coverage NO3.BIN](https://img.shields.io/endpoint?label=NO3%20code&url=https%3A%2F%2Fprogress.deco.mp%2Fdata%2Fsotn%2Fus%2Fcode%2F%3Fmode%3Dshield%26measure%3Dstno3) | ![decompiled functions](https://img.shields.io/endpoint?label=NO3%20funcs&url=https%3A%2F%2Fprogress.deco.mp%2Fdata%2Fsotn%2Fus%2Ffunctions%2F%3Fmode%3Dshield%26measure%3Dstno3) | Entrance (first visit)
| ST/NP3/NP3.BIN | ![code coverage NP3.BIN](https://img.shields.io/endpoint?label=NP3%20code&url=https%3A%2F%2Fprogress.deco.mp%2Fdata%2Fsotn%2Fus%2Fcode%2F%3Fmode%3Dshield%26measure%3Dstnp3) | ![decompiled functions](https://img.shields.io/endpoint?label=NP3%20funcs&url=https%3A%2F%2Fprogress.deco.mp%2Fdata%2Fsotn%2Fus%2Ffunctions%2F%3Fmode%3Dshield%26measure%3Dstnp3) | Entrance
| ST/NZ0/NZ0.BIN | ![code coverage NZ0.BIN](https://img.shields.io/endpoint?label=NZ0%20code&url=https%3A%2F%2Fprogress.deco.mp%2Fdata%2Fsotn%2Fus%2Fcode%2F%3Fmode%3Dshield%26measure%3Dstnz0) | ![decompiled functions](https://img.shields.io/endpoint?label=NZ0%20funcs&url=https%3A%2F%2Fprogress.deco.mp%2Fdata%2Fsotn%2Fus%2Ffunctions%2F%3Fmode%3Dshield%26measure%3Dstnz0) | Alchemy Laboratory

View File

@ -8,6 +8,8 @@ e42976f45b47d1c4912a198ae486b77ee6d77c9c build/us/DRE.BIN
663da47afbc663548bfac8b838e3390f55ae6eaf build/us/F_DRE.BIN
adb3303e1ea707c63dfa978511a88cab4f61970a build/us/MAD.BIN
7674de58cb7b267200fd9d07638fc4086f16466a build/us/F_MAD.BIN
d07f054f9dc8ef639257aca01deb1f24a2811924 build/us/NO0.BIN
898bc0fc322f960e20c909073606baa85ae8175e build/us/F_NO0.BIN
5d06216b895ab5ff892c88b0d9eff67ff16e2bd1 build/us/NO3.BIN
7ca2a473e87fbb7e5c18e72ea0c136c0e7b364f5 build/us/F_NO3.BIN
7c78a2bec6a26acfb62456e7f517915fe0c0e3f5 build/us/NP3.BIN

View File

@ -0,0 +1,66 @@
options:
platform: psx
basename: stno0
base_path: ..
build_path: build/us
target_path: disks/us/ST/NO0/NO0.BIN
asm_path: asm/us/st/no0
asset_path: assets/st/no0
src_path: src/st/no0
ld_script_path: build/us/stno0.ld
compiler: GCC
symbol_addrs_path:
- config/symbols.us.txt
- config/symbols.us.stno0.txt
undefined_funcs_auto_path: config/undefined_funcs_auto.us.stno0.txt
undefined_syms_auto_path: config/undefined_syms_auto.us.stno0.txt
find_file_boundaries: true
use_legacy_include_asm: false
migrate_rodata_to_functions: true
asm_jtbl_label_macro: jlabel
symbol_name_format: us_$VRAM
disassemble_all: True
section_order:
- .data
- .rodata
- .text
- .bss
- .sbss
ld_bss_is_noload: false
disasm_unknown: true
include_macro_inc: false
sha1: d07f054f9dc8ef639257aca01deb1f24a2811924
segments:
- name: stno0
type: code
start: 0
vram: 0x80180000
align: 4
subalign: 4
subsegments:
- [0x0, data]
- [0x41368, .rodata, first_c_file]
- [0x4137C, .rodata, e_red_door]
- [0x41394, .rodata, e_collect]
- [0x4141C, .rodata, blit_char]
- [0x4142C, .rodata, e_misc]
- [0x414A8, .rodata, e_stage_name]
- [0x414EC, .rodata, unk_4F4A8]
- [0x4184C, .rodata, prim_helpers]
- [0x41854, c, first_c_file]
- [0x43788, c, st_update]
- [0x43BBC, c, collision]
- [0x45378, c, create_entity]
- [0x45EF0, c, e_red_door]
- [0x46BA0, c, e_room_fg]
- [0x46C8C, c, popup]
- [0x46FBC, c, e_particles]
- [0x47800, c, st_common]
- [0x48CB0, c, e_collect]
- [0x4A21C, c, blit_char]
- [0x4A4CC, c, e_misc]
- [0x4E654, c, e_stage_name]
- [0x4F4A8, c, unk_4F4A8]
- [0x5E09C, c, prim_helpers]
- [0x5E8CC, sbss]
- [0x5F58C]

170
config/symbols.us.stno0.txt Normal file
View File

@ -0,0 +1,170 @@
e_laydef_c = 0x80180778;
g_pStObjLayoutVertical = 0x8018084C;
D_80180A90 = 0x8018091C;
g_InitializeData0 = 0x80180A70;
g_InitializeEntityData0 = 0x80180A7C;
g_InitDataEnt13 = 0x80180AD0;
g_eInitGeneric2 = 0x80180AE8;
g_eDamageDisplayInit = 0x80180B18;
D_80180C94 = 0x80180BC0;
D_80180C6A = 0x80180C02;
D_80180C70 = 0x80180C08;
D_80180C88 = 0x80180C38;
D_80180CA0 = 0x80180C50;
UNK_Invincibility0 = 0x8018113C;
g_testCollEnemyLookup = 0x80181168;
g_testCollLuckCutoff = 0x80181488;
g_testColluCoords = 0x8018148C;
g_testCollvCoords = 0x80181494;
g_testCollElementLookup = 0x8018149C;
g_testColliFrames = 0x801814B0;
g_testCollPrizeTable = 0x801814BC;
g_testCollRandTable = 0x801814FC;
g_eDamageDisplayClut = 0x80181518;
eRoomForegroundInit = 0x80181554;
g_ESoulStealOrbAngles = 0x801815CC;
g_ESoulStealOrbSprt = 0x801815DC;
g_ESoulStealOrbAnim = 0x8018163C;
g_SineTable = 0x8018164C;
D_80181CA8 = 0x8018197C;
aluric_subweapons_id = 0x801819AC;
g_goldCollectTexts = 0x801819C0;
c_GoldPrizes = 0x801819E8;
c_HeartPrizes = 0x80181A78;
g_ExplosionYVelocities = 0x80181A7C;
g_bigRedFireballAnim = 0x80181AA4;
g_ExplosionAnimations = 0x80181B28;
g_eUnk14SpawnRots = 0x80181BA0;
unk15_rot = 0x80181BB0;
unk15_yVel = 0x80181BC0;
unk14_yVel = 0x80181BD8;
unk14_startFrame = 0x80181BF0;
unk14_lifetime = 0x80181BF4;
g_olroxDroolCollOffsets = 0x80181BFC;
g_UnkEntityAnimData = 0x80181C04;
anim_bone_rot = 0x801821DC;
steps = 0x801825AC;
init_velocity_x = 0x801825B4;
init_velocity_y = 0x801825C0;
bone_projectile_velocity_x = 0x8018272C;
sensors_special = 0x8018275C;
sensors_move = 0x80182764;
sprites_nz0_3 = 0x801BEBB0;
g_UnkPrimHelperRot = 0x801C184C;
func_801A7E2C = 0x801C1968;
func_801B0AA4 = 0x801C19EC;
MakeExplosions = 0x801C3334;
EntityWargExplosionPuffOpaque = 0x801C33F4;
Random = 0x801C3788;
Update = 0x801C37B8;
UpdateStageEntities = 0x801C3AB4;
HitDetection = 0x801C3BBC;
EntityDamageDisplay = 0x801C4CD4;
CreateEntityFromLayout = 0x801C5378;
CreateEntityWhenInHorizontalRange = 0x801C543C;
FindFirstEntityAbove = 0x801C566C;
FindFirstEntityBelow = 0x801C56B8;
CreateEntitiesAbove = 0x801C5710;
CreateEntitiesBelow = 0x801C580C;
InitRoomEntities = 0x801C5BD4;
UpdateRoomPosition = 0x801C5D4C;
CreateEntityFromCurrentEntity = 0x801C5E00;
CreateEntityFromEntity = 0x801C5E74;
EntityIsNearPlayer = 0x801C5EF0;
EntityRedDoor = 0x801C5F68;
EntityRoomForeground = 0x801C6BA0;
BottomCornerText = 0x801C6C8C;
EntitySoulStealOrb = 0x801C6FBC;
EntityEnemyBlood = 0x801C7350;
DestroyEntity = 0x801C7800;
DestroyEntitiesFromIndex = 0x801C786C;
PreventEntityFromRespawning = 0x801C78E8;
AnimateEntity = 0x801C7930;
UnkAnimFunc = 0x801C79E8;
GetDistanceToPlayerX = 0x801C7B00;
GetDistanceToPlayerY = 0x801C7B3C;
GetSideToPlayer = 0x801C7B70;
MoveEntity = 0x801C7BB4;
FallEntity = 0x801C7BE4;
UnkCollisionFunc3 = 0x801C7C10;
UnkCollisionFunc2 = 0x801C7E88;
AllocEntity = 0x801C8070;
GetSineScaled = 0x801C80D0;
GetSine = 0x801C80FC;
SetEntityVelocityFromAngle = 0x801C8118;
Ratan2Shifted = 0x801C8184;
GetAngleBetweenEntitiesShifted = 0x801C81BC;
GetAnglePointToEntity = 0x801C8204;
AdjustValueWithinThreshold = 0x801C824C;
UnkEntityFunc0 = 0x801C82A4;
Ratan2 = 0x801C8330;
GetAngleBetweenEntities = 0x801C8360;
GetNormalizedAngle = 0x801C83E0;
SetStep = 0x801C8440;
SetSubStep = 0x801C8460;
EntityExplosionSpawn = 0x801C847C;
InitializeEntity = 0x801C8510;
EntityDummy = 0x801C860C;
UnkCollisionFunc = 0x801C8634;
CheckFieldCollision = 0x801C875C;
GetPlayerCollisionWith = 0x801C88B4;
ReplaceBreakableWithItemDrop = 0x801C8BF8;
func_8018CAB0 = 0x801C8CB0;
func_8018CB34 = 0x801C8D34;
CollectHeart = 0x801C8E90;
CollectGold = 0x801C8F10;
CollectSubweapon = 0x801C8FEC;
CollectHeartVessel = 0x801C9104;
CollectLifeVessel = 0x801C91A8;
DestroyCurrentEntity = 0x801C91F8;
EntityPrizeDrop = 0x801C9220;
EntityExplosion = 0x801C9A94;
BlinkItem = 0x801C9B90;
EntityEquipItemDrop = 0x801C9C34;
BlitChar = 0x801CA21C;
EntityRelicOrb = 0x801CA4CC;
EntityHeartDrop = 0x801CAF9C;
EntityMessageBox = 0x801CB0B8;
CheckColliderOffsets = 0x801CB614;
EntityUnkId13 = 0x801CB704;
EntityUnkId14Spawner = 0x801CB814;
EntityUnkId15Spawner = 0x801CB944;
EntityUnkId14 = 0x801CBA2C;
EntityUnkId15 = 0x801CBB1C;
EntityOlroxDrool = 0x801CBC10;
UnkCollisionFunc5 = 0x801CBE40;
EntityIntenseExplosion = 0x801CBF3C;
InitializeUnkEntity = 0x801CC03C;
MakeEntityFromId = 0x801CC108;
EntityBigRedFireball = 0x801CC288;
ClutLerp = 0x801CC460;
PlaySfxPositional = 0x801CC658;
StageNamePopupHelper = 0x801CE654;
EntityStageNamePopup = 0x801CE824;
func_801CD78C = 0x801D2374;
EntitySkeleton = 0x801D7670;
EntitySkeletonPieces = 0x801D7B40;
func_801C3F9C = 0x801DAEBC;
func_801C4198 = 0x801DB0B8;
func_801C4550 = 0x801DB470;
EntityAxeKnight = 0x801DB4DC;
EntityAxeKnightRotateAxe = 0x801DBBE0;
EntityAxeKnightThrowingAxe = 0x801DBC38;
SkeletonAttackCheck = 0x801DCAB0;
EntitySkeletonThrownBone = 0x801DD0F8;
func_801C6678 = 0x801DD1FC;
EntityMagicallySealedDoor = 0x801DD328;
UnkPrimHelper = 0x801DE09C;
UpdateAnimation = 0x801DE484;
FindFirstUnkPrim = 0x801DE5D4;
FindFirstUnkPrim2 = 0x801DE604;
PrimToggleVisibility = 0x801DE680;
PrimResetNext = 0x801DE708;
UnkPolyFunc2 = 0x801DE7E8;
UnkPolyFunc0 = 0x801DE83C;
PrimDecreaseBrightness = 0x801DE868;
g_LayoutObjHorizontal = 0x801DE8CC;
g_LayoutObjVertical = 0x801DE8D0;
g_LayoutObjPosHorizontal = 0x801DE8D4;
g_LayoutObjPosVertical = 0x801DE8D8;
g_ItemIconSlots = 0x801DF54C;

6
src/st/no0/blit_char.c Normal file
View File

@ -0,0 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
#include "common.h"
INCLUDE_ASM("st/no0/nonmatchings/blit_char", BlitChar);
INCLUDE_RODATA("st/no0/nonmatchings/blit_char", D_us_801C141C);

6
src/st/no0/collision.c Normal file
View File

@ -0,0 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
#include "common.h"
INCLUDE_ASM("st/no0/nonmatchings/collision", HitDetection);
INCLUDE_ASM("st/no0/nonmatchings/collision", EntityDamageDisplay);

View File

@ -0,0 +1,33 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
#include "common.h"
INCLUDE_ASM("st/no0/nonmatchings/create_entity", CreateEntityFromLayout);
INCLUDE_ASM(
"st/no0/nonmatchings/create_entity", CreateEntityWhenInHorizontalRange);
INCLUDE_ASM("st/no0/nonmatchings/create_entity", func_us_801C5554);
INCLUDE_ASM("st/no0/nonmatchings/create_entity", FindFirstEntityAbove);
INCLUDE_ASM("st/no0/nonmatchings/create_entity", FindFirstEntityBelow);
INCLUDE_ASM("st/no0/nonmatchings/create_entity", CreateEntitiesAbove);
INCLUDE_ASM("st/no0/nonmatchings/create_entity", CreateEntitiesBelow);
INCLUDE_ASM("st/no0/nonmatchings/create_entity", func_us_801C5920);
INCLUDE_ASM("st/no0/nonmatchings/create_entity", func_us_801C596C);
INCLUDE_ASM("st/no0/nonmatchings/create_entity", func_us_801C59C4);
INCLUDE_ASM("st/no0/nonmatchings/create_entity", func_us_801C5AC0);
INCLUDE_ASM("st/no0/nonmatchings/create_entity", InitRoomEntities);
INCLUDE_ASM("st/no0/nonmatchings/create_entity", UpdateRoomPosition);
INCLUDE_ASM("st/no0/nonmatchings/create_entity", CreateEntityFromCurrentEntity);
INCLUDE_ASM("st/no0/nonmatchings/create_entity", CreateEntityFromEntity);

46
src/st/no0/e_collect.c Normal file
View File

@ -0,0 +1,46 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
#include "common.h"
INCLUDE_ASM("st/no0/nonmatchings/e_collect", func_8018CAB0);
INCLUDE_ASM("st/no0/nonmatchings/e_collect", func_8018CB34);
INCLUDE_ASM("st/no0/nonmatchings/e_collect", CollectHeart);
INCLUDE_ASM("st/no0/nonmatchings/e_collect", CollectGold);
INCLUDE_ASM("st/no0/nonmatchings/e_collect", CollectSubweapon);
INCLUDE_ASM("st/no0/nonmatchings/e_collect", CollectHeartVessel);
INCLUDE_ASM("st/no0/nonmatchings/e_collect", CollectLifeVessel);
INCLUDE_ASM("st/no0/nonmatchings/e_collect", DestroyCurrentEntity);
INCLUDE_RODATA("st/no0/nonmatchings/e_collect", D_us_801C1394);
INCLUDE_RODATA("st/no0/nonmatchings/e_collect", D_us_801C139C);
INCLUDE_RODATA("st/no0/nonmatchings/e_collect", D_us_801C13A4);
INCLUDE_RODATA("st/no0/nonmatchings/e_collect", D_us_801C13AC);
INCLUDE_RODATA("st/no0/nonmatchings/e_collect", D_us_801C13B4);
INCLUDE_RODATA("st/no0/nonmatchings/e_collect", D_us_801C13BC);
INCLUDE_RODATA("st/no0/nonmatchings/e_collect", D_us_801C13C4);
INCLUDE_RODATA("st/no0/nonmatchings/e_collect", D_us_801C13CC);
INCLUDE_RODATA("st/no0/nonmatchings/e_collect", D_us_801C13D4);
INCLUDE_RODATA("st/no0/nonmatchings/e_collect", D_us_801C13DC);
INCLUDE_ASM("st/no0/nonmatchings/e_collect", EntityPrizeDrop);
INCLUDE_ASM("st/no0/nonmatchings/e_collect", EntityExplosion);
INCLUDE_ASM("st/no0/nonmatchings/e_collect", BlinkItem);
INCLUDE_ASM("st/no0/nonmatchings/e_collect", EntityEquipItemDrop);

70
src/st/no0/e_misc.c Normal file
View File

@ -0,0 +1,70 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
#include "common.h"
INCLUDE_ASM("st/no0/nonmatchings/e_misc", EntityRelicOrb);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", EntityHeartDrop);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", EntityMessageBox);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", CheckColliderOffsets);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", EntityUnkId13);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", EntityUnkId14Spawner);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", EntityUnkId15Spawner);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", EntityUnkId14);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", EntityUnkId15);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", EntityOlroxDrool);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", UnkCollisionFunc5);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", EntityIntenseExplosion);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", InitializeUnkEntity);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", MakeEntityFromId);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", func_us_801CC1D0);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", EntityBigRedFireball);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", ClutLerp);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", PlaySfxPositional);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", func_us_801CC750);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", func_us_801CC8F8);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", func_us_801CC9B4);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", func_us_801CCAAC);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", func_us_801CCBE4);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", func_us_801CCC2C);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", func_us_801CCC74);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", func_us_801CD750);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", func_us_801CD864);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", func_us_801CDAD4);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", func_us_801CDB20);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", func_us_801CDE48);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", func_us_801CE058);
INCLUDE_ASM("st/no0/nonmatchings/e_misc", func_us_801CE0F8);
void func_us_801CE2D8(void) {}
INCLUDE_ASM("st/no0/nonmatchings/e_misc", func_us_801CE2E0);

6
src/st/no0/e_particles.c Normal file
View File

@ -0,0 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
#include "common.h"
INCLUDE_ASM("st/no0/nonmatchings/e_particles", EntitySoulStealOrb);
INCLUDE_ASM("st/no0/nonmatchings/e_particles", EntityEnemyBlood);

6
src/st/no0/e_red_door.c Normal file
View File

@ -0,0 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
#include "common.h"
INCLUDE_ASM("st/no0/nonmatchings/e_red_door", EntityIsNearPlayer);
INCLUDE_ASM("st/no0/nonmatchings/e_red_door", EntityRedDoor);

4
src/st/no0/e_room_fg.c Normal file
View File

@ -0,0 +1,4 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
#include "common.h"
INCLUDE_ASM("st/no0/nonmatchings/e_room_fg", EntityRoomForeground);

View File

@ -0,0 +1,8 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
#include "common.h"
INCLUDE_ASM("st/no0/nonmatchings/e_stage_name", StageNamePopupHelper);
INCLUDE_RODATA("st/no0/nonmatchings/e_stage_name", D_us_801C14A8);
INCLUDE_ASM("st/no0/nonmatchings/e_stage_name", EntityStageNamePopup);

34
src/st/no0/first_c_file.c Normal file
View File

@ -0,0 +1,34 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
#include "common.h"
INCLUDE_ASM("st/no0/nonmatchings/first_c_file", func_us_801C1854);
INCLUDE_ASM("st/no0/nonmatchings/first_c_file", func_801A7E2C);
INCLUDE_ASM("st/no0/nonmatchings/first_c_file", func_801B0AA4);
INCLUDE_ASM("st/no0/nonmatchings/first_c_file", func_us_801C1E48);
INCLUDE_ASM("st/no0/nonmatchings/first_c_file", func_us_801C1F98);
INCLUDE_ASM("st/no0/nonmatchings/first_c_file", func_us_801C2044);
INCLUDE_ASM("st/no0/nonmatchings/first_c_file", func_us_801C2184);
INCLUDE_ASM("st/no0/nonmatchings/first_c_file", func_us_801C26B8);
INCLUDE_ASM("st/no0/nonmatchings/first_c_file", func_us_801C27A4);
INCLUDE_ASM("st/no0/nonmatchings/first_c_file", func_us_801C2A34);
INCLUDE_ASM("st/no0/nonmatchings/first_c_file", func_us_801C2B24);
INCLUDE_ASM("st/no0/nonmatchings/first_c_file", func_us_801C2CD8);
INCLUDE_ASM("st/no0/nonmatchings/first_c_file", func_us_801C2E7C);
INCLUDE_ASM("st/no0/nonmatchings/first_c_file", func_us_801C3308);
INCLUDE_ASM("st/no0/nonmatchings/first_c_file", MakeExplosions);
INCLUDE_ASM("st/no0/nonmatchings/first_c_file", EntityWargExplosionPuffOpaque);

4
src/st/no0/popup.c Normal file
View File

@ -0,0 +1,4 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
#include "common.h"
INCLUDE_ASM("st/no0/nonmatchings/popup", BottomCornerText);

22
src/st/no0/prim_helpers.c Normal file
View File

@ -0,0 +1,22 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
#include "common.h"
INCLUDE_ASM("st/no0/nonmatchings/prim_helpers", UnkPrimHelper);
INCLUDE_ASM("st/no0/nonmatchings/prim_helpers", UpdateAnimation);
INCLUDE_ASM("st/no0/nonmatchings/prim_helpers", FindFirstUnkPrim);
INCLUDE_ASM("st/no0/nonmatchings/prim_helpers", FindFirstUnkPrim2);
INCLUDE_ASM("st/no0/nonmatchings/prim_helpers", PrimToggleVisibility);
INCLUDE_ASM("st/no0/nonmatchings/prim_helpers", PrimResetNext);
INCLUDE_ASM("st/no0/nonmatchings/prim_helpers", UnkPolyFunc2);
INCLUDE_ASM("st/no0/nonmatchings/prim_helpers", UnkPolyFunc0);
INCLUDE_ASM("st/no0/nonmatchings/prim_helpers", PrimDecreaseBrightness);
INCLUDE_RODATA("st/no0/nonmatchings/prim_helpers", g_UnkPrimHelperRot);

70
src/st/no0/st_common.c Normal file
View File

@ -0,0 +1,70 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
#include "common.h"
INCLUDE_ASM("st/no0/nonmatchings/st_common", DestroyEntity);
INCLUDE_ASM("st/no0/nonmatchings/st_common", DestroyEntitiesFromIndex);
INCLUDE_ASM("st/no0/nonmatchings/st_common", PreventEntityFromRespawning);
INCLUDE_ASM("st/no0/nonmatchings/st_common", AnimateEntity);
INCLUDE_ASM("st/no0/nonmatchings/st_common", UnkAnimFunc);
INCLUDE_ASM("st/no0/nonmatchings/st_common", GetDistanceToPlayerX);
INCLUDE_ASM("st/no0/nonmatchings/st_common", GetDistanceToPlayerY);
INCLUDE_ASM("st/no0/nonmatchings/st_common", GetSideToPlayer);
INCLUDE_ASM("st/no0/nonmatchings/st_common", MoveEntity);
INCLUDE_ASM("st/no0/nonmatchings/st_common", FallEntity);
INCLUDE_ASM("st/no0/nonmatchings/st_common", UnkCollisionFunc3);
INCLUDE_ASM("st/no0/nonmatchings/st_common", UnkCollisionFunc2);
INCLUDE_ASM("st/no0/nonmatchings/st_common", AllocEntity);
INCLUDE_ASM("st/no0/nonmatchings/st_common", GetSineScaled);
INCLUDE_ASM("st/no0/nonmatchings/st_common", GetSine);
INCLUDE_ASM("st/no0/nonmatchings/st_common", SetEntityVelocityFromAngle);
INCLUDE_ASM("st/no0/nonmatchings/st_common", Ratan2Shifted);
INCLUDE_ASM("st/no0/nonmatchings/st_common", GetAngleBetweenEntitiesShifted);
INCLUDE_ASM("st/no0/nonmatchings/st_common", GetAnglePointToEntity);
INCLUDE_ASM("st/no0/nonmatchings/st_common", AdjustValueWithinThreshold);
INCLUDE_ASM("st/no0/nonmatchings/st_common", UnkEntityFunc0);
INCLUDE_ASM("st/no0/nonmatchings/st_common", Ratan2);
INCLUDE_ASM("st/no0/nonmatchings/st_common", GetAngleBetweenEntities);
INCLUDE_ASM("st/no0/nonmatchings/st_common", func_us_801C8398);
INCLUDE_ASM("st/no0/nonmatchings/st_common", GetNormalizedAngle);
INCLUDE_ASM("st/no0/nonmatchings/st_common", SetStep);
INCLUDE_ASM("st/no0/nonmatchings/st_common", SetSubStep);
INCLUDE_ASM("st/no0/nonmatchings/st_common", EntityExplosionSpawn);
INCLUDE_ASM("st/no0/nonmatchings/st_common", InitializeEntity);
INCLUDE_ASM("st/no0/nonmatchings/st_common", EntityDummy);
INCLUDE_ASM("st/no0/nonmatchings/st_common", UnkCollisionFunc);
INCLUDE_ASM("st/no0/nonmatchings/st_common", CheckFieldCollision);
INCLUDE_ASM("st/no0/nonmatchings/st_common", GetPlayerCollisionWith);
INCLUDE_ASM("st/no0/nonmatchings/st_common", ReplaceBreakableWithItemDrop);

8
src/st/no0/st_update.c Normal file
View File

@ -0,0 +1,8 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
#include "common.h"
INCLUDE_ASM("st/no0/nonmatchings/st_update", Random);
INCLUDE_ASM("st/no0/nonmatchings/st_update", Update);
INCLUDE_ASM("st/no0/nonmatchings/st_update", UpdateStageEntities);

140
src/st/no0/unk_4F4A8.c Normal file
View File

@ -0,0 +1,140 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
#include "common.h"
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801CF4A8);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801CF670);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801CF910);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801CFBE8);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D0718);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D0898);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D0990);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D0E7C);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D191C);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D20A4);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D2318);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_801CD78C);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D2424);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D26CC);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D274C);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D27C4);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D29F8);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D2A64);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D4324);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D44A0);
INCLUDE_RODATA("st/no0/nonmatchings/unk_4F4A8", D_us_801C1684);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D4AA4);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D4CAC);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D4E30);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D4E94);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D4FCC);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D5074);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D51EC);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D5250);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D52E0);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D5384);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D542C);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D5E4C);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D606C);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D6254);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D6474);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D66F8);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D75E4);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", EntitySkeleton);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", EntitySkeletonPieces);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D7C20);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D7D00);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D7DAC);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D8150);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D8DF0);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D8FFC);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D91C4);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801D9264);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801DA488);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801DA6B4);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801DADD0);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_801C3F9C);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_801C4198);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_801C4550);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", EntityAxeKnight);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", EntityAxeKnightRotateAxe);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", EntityAxeKnightThrowingAxe);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801DBDCC);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801DC194);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801DC64C);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801DC754);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801DC788);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", SkeletonAttackCheck);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801DCB48);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801DD018);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", EntitySkeletonThrownBone);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_801C6678);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", func_us_801DD2B0);
INCLUDE_ASM("st/no0/nonmatchings/unk_4F4A8", EntityMagicallySealedDoor);

View File

@ -0,0 +1,217 @@
# Automatically de-duplicates a newly created overlay. The overlay should have its code in src/st/{OVL}/us.c
# Does not work for different versions, does not work for non-stage overlays (familiars, bosses, etc)
import argparse
import re
import os
# functions which appear at the start of our deduplicated files in existing stages.
# If you have "Random": ["st_update"] that means "Random" is the first function in the st_update.c file.
# Optionally, you can include a final function, like this:
# "StageNamePopupHelper" : ["e_stage_name", "EntityStageNamePopup"],
# Maybe the dictionary should be changed so the file name is the key, but eh.
file_start_funcs = {
"Random": ["st_update"],
"HitDetection": ["collision"],
"CreateEntityFromLayout": ["create_entity"],
"EntityIsNearPlayer": ["e_red_door"],
"DestroyEntity": ["st_common"],
"func_8018CAB0": ["e_collect"],
"BlitChar": ["blit_char"],
"EntityRelicOrb": ["e_misc"],
"StageNamePopupHelper": ["e_stage_name", "EntityStageNamePopup"],
"EntitySoulStealOrb": ["e_particles"],
"EntityRoomForeground": ["e_room_fg"],
"BottomCornerText": ["popup"],
"UnkPrimHelper": ["prim_helpers"],
}
def get_file_splits(overlay_name):
with open(f"src/st/{overlay_name}/us.c") as f:
clines = f.readlines()
with open(f"config/splat.us.st{overlay_name}.yaml") as f:
splatlines = f.readlines()
with open(f"config/symbols.us.st{overlay_name}.txt") as f:
symbollines = f.readlines()
file_splits = []
file_last_func = ""
force_next_func_split = False
for line in clines:
match = re.search(r'INCLUDE_ASM\("[^"]+",\s*(\w+)\);', line)
if match:
function_name = match.group(1)
if function_name in file_start_funcs:
filename = file_start_funcs[function_name][0]
if len(file_start_funcs[function_name]) == 2:
file_last_func = file_start_funcs[function_name][1]
else:
file_last_func = ""
split_location = get_symbol_addr(function_name, overlay_name)
file_splits.append([f"0x{split_location}", filename, function_name])
elif function_name == file_last_func:
force_next_func_split = True
elif force_next_func_split:
split_location = get_symbol_addr(function_name, overlay_name)
file_splits.append(
[f"0x{split_location}", f"unk_{split_location}", function_name]
)
force_next_func_split = False
return file_splits
def write_file_splits_to_yaml(overlay_name, new_segments):
yaml_filename = f"config/splat.us.st{overlay_name}.yaml"
# initially open for reading. Then we'll mess with it, and open for writing.
with open(yaml_filename, "r") as f:
raw_yaml_lines = f.read().splitlines()
outlines = []
for line in raw_yaml_lines:
if ", c," not in line:
outlines.append(line)
else:
# now we output the lines which list the C segments
# Start with the first block of C, before our first identified segment.
first_line = line.replace("us", "first_c_file")
outlines.append(first_line)
for seg in new_segments:
addr, filename, _ = seg
outlines.append(f" - [{addr}, c, {filename}]")
with open(yaml_filename, "w") as f:
f.write("\n".join(outlines))
def split_c_files(overlay_name, new_segments):
seg_dict = {s[2]: s[1] for s in new_segments}
c_file_in = f"src/st/{overlay_name}/us.c"
with open(c_file_in, "r") as f:
c_file_lines = f.read().splitlines()
# output buffer holds the lines that will write to the current file.
# Once we reach a new C file, we dump the buffer and start a new one.
file_header = '// SPDX-License-Identifier: AGPL-3.0-or-later\n#include "common.h"\n'
output_buffer = []
overlay_dir = f"src/st/{overlay_name}/"
output_filename = "first_c_file"
for line in c_file_lines:
match = re.search(r'INCLUDE_ASM\("[^"]+",\s*(\w+)\);', line)
if match:
function_name = match.group(1)
if function_name in seg_dict:
dest_file = seg_dict[function_name]
print(f"got a split on {function_name} to {dest_file}")
# Now that we have a new destination file, dump the buffer.
with open(overlay_dir + output_filename + ".c", "w") as f:
f.write("\n".join(output_buffer))
# Create our new file
output_buffer = [file_header]
output_filename = dest_file
output_buffer.append(
line.replace("nonmatchings/us", f"nonmatchings/{output_filename}")
)
# Flush the last one
with open(overlay_dir + output_filename + ".c", "w") as f:
f.write("\n".join(output_buffer))
os.remove(c_file_in)
# Looks in the .map file to find the location of a symbol.
# Returns address as a string, representing hex location in the ROM (not RAM!)
# Might return "4ADC8" for example.
def get_symbol_addr(symbol_name, overlay_name):
with open("build/us/st" + overlay_name + ".map") as f:
symlines = f.read().splitlines()
for line in symlines:
lineparts = line.split()
if len(lineparts) != 2:
continue
if symbol_name == lineparts[1]:
address = int(lineparts[0], 16)
# change from ram offset to rom offset
address -= 0x80180000
return f"{address:X}"
def split_rodata(overlay_name, new_segments):
# Get the rodata and create splat segments
# Do this by searching for INCLUDE_RODATA in the c files, and make the rodata parse to that file
overlay_dir = f"src/st/{overlay_name}/"
yaml_rodata_lines = []
for seg in new_segments:
c_file = overlay_dir + seg[1] + ".c"
with open(c_file) as f:
c_lines = f.read().splitlines()
for line in c_lines:
match = re.search(r'INCLUDE_RODATA\("[^"]+",\s*(\w+)\);', line)
if match:
# Found a line. Need to add rodata line to yaml.
# To do that, we need the rodata address.
rodata_name = match.group(1)
addr = get_symbol_addr(rodata_name, overlay_name)
yaml_rodata_lines.append(f" - [0x{addr}, .rodata, {seg[1]}]")
# We have now extracted the rodata from any INCLUDE_RODATA lines. Now also do any jump tables in any functions.
for line in c_lines:
match = re.search(r'INCLUDE_ASM\("[^"]+",\s*(\w+)\);', line)
if match:
funcname = match.group(1)
with open(
f"asm/us/st/{overlay_name}/nonmatchings/us/{funcname}.s"
) as asmfile:
asmlines = asmfile.read().splitlines()
for i, line in enumerate(asmlines):
if "glabel jtbl" in line:
nextline = asmlines[i + 1]
jtbl_addr = "0x" + nextline.split()[1]
yaml_rodata_lines.append(
f" - [{jtbl_addr}, .rodata, {seg[1]}]"
)
# yaml rodata comes from multiple places. Sort the lines to make splat in right order.
yaml_rodata_lines.sort()
# We need to have only one rodata segment per file. This was found in testing.
deduped_yaml_rodata = []
curr_rodata_seg = ""
for line in yaml_rodata_lines:
seg = line.split(",")[-1]
if seg != curr_rodata_seg:
deduped_yaml_rodata.append(line)
curr_rodata_seg = seg
yaml_rodata_lines = deduped_yaml_rodata
# Now we have the yaml rodata lines. open the yaml file and write the lines into it.
yaml_filename = f"config/splat.us.st{overlay_name}.yaml"
# initially open for reading. Then we'll mess with it, and open for writing.
with open(yaml_filename, "r") as f:
raw_yaml_lines = f.read().splitlines()
outlines = []
for line in raw_yaml_lines:
if ".rodata," not in line:
outlines.append(line)
else:
first_line = line.replace("us", "first_c_file")
outlines.append(first_line)
for roline in yaml_rodata_lines:
outlines.append(roline)
with open(yaml_filename, "w") as f:
f.write("\n".join(outlines))
parser = argparse.ArgumentParser(
description="Perform initial splitting out of files for new overlays"
)
parser.add_argument(
"ovl",
help="Name of overlay (for example, no0)",
)
if __name__ == "__main__":
args = parser.parse_args()
splits = get_file_splits(args.ovl)
write_file_splits_to_yaml(args.ovl, splits)
split_c_files(args.ovl, splits)
split_rodata(args.ovl, splits)

View File

@ -277,6 +277,13 @@ fn do_dups_report(output_file: Option<String>, threshold: f64) {
include_asm: get_all_include_asm("../../src/st/mad/"),
path_matcher: "st/mad".to_string(),
},
SrcAsmPair {
asm_dir: String::from("../../asm/us/st/no0/nonmatchings/"),
src_dir: String::from("../../src/st/no0/"),
overlay_name: String::from("NO0"),
include_asm: get_all_include_asm("../../src/st/no0/"),
path_matcher: "st/no0".to_string(),
},
SrcAsmPair {
asm_dir: String::from("../../asm/us/st/no3/nonmatchings/"),
src_dir: String::from("../../src/st/no3/"),

View File

@ -359,6 +359,7 @@ if __name__ == "__main__":
progress["stcen"] = DecompProgressStats("stcen", "st/cen")
progress["stdre"] = DecompProgressStats("stdre", "st/dre")
progress["stmad"] = DecompProgressStats("stmad", "st/mad")
progress["stno0"] = DecompProgressStats("stno0", "st/no0")
progress["stno3"] = DecompProgressStats("stno3", "st/no3")
progress["stnp3"] = DecompProgressStats("stnp3", "st/np3")
progress["stnz0"] = DecompProgressStats("stnz0", "st/nz0")