diff --git a/config/assets.pspeu.yaml b/config/assets.pspeu.yaml index a3334cd363..e9830f4744 100644 --- a/config/assets.pspeu.yaml +++ b/config/assets.pspeu.yaml @@ -503,3 +503,27 @@ files: - [0x80, skip] - [0xF5F8, layers, layers] - [0xF6E8, skip] + - target: disks/pspeu/PSP_GAME/USRDIR/res/ps/PSPBIN/w0_000.bin + asset_path: assets/weapon + src_path: src/weapon + splat_config_path: config/splat.pspeu.w0_000.yaml + segments: + - start: 0x80 + vram: 0x092F2E80 + assets: + - [0x80, skip] + - [0x700, spriteset, w0/w_000_1] # should be namespaced + - [0x1248, spriteset, w0/w_000_2] # should be namespaced + - [0x1248, skip] + - target: disks/pspeu/PSP_GAME/USRDIR/res/ps/PSPBIN/w1_000.bin + asset_path: assets/weapon + src_path: src/weapon + splat_config_path: config/splat.pspeu.w1_000.yaml + segments: + - start: 0x80 + vram: 0x092F6C80 + assets: + - [0x80, skip] + - [0x708, spriteset, w1/w_000_1] # should be namespaced + - [0x1250, spriteset, w1/w_000_2] # should be namespaced + - [0x1250, skip] diff --git a/config/check.pspeu.sha b/config/check.pspeu.sha index 437f2efe4c..cbe3f5368b 100644 --- a/config/check.pspeu.sha +++ b/config/check.pspeu.sha @@ -13,3 +13,6 @@ f40689641eda2ab9de69b6aed15a200717827628 build/pspeu/st0.bin 0584ddb3ba1afce61592d43497212fcb8ebf797b build/pspeu/wrp.bin c8c34ac1d46b31e2e5336df271aa2409f44c9d01 build/pspeu/tt_000.bin 38fdfe8c3e0e3260e8462aaaf2261d7d6a4b8961 build/pspeu/sel.bin +bc20b2683492352905317f0634b4db6b84f9985d build/pspeu/w0_000.bin +ae247d10da2a0c34ace1b73208b918e170883deb build/pspeu/w1_000.bin +eab66ff03cd2ff3c5c011e84f06b2b2943ca06d9 build/pspeu/w1_012.bin diff --git a/config/splat.pspeu.w0_000.yaml b/config/splat.pspeu.w0_000.yaml new file mode 100644 index 0000000000..1d165ba84f --- /dev/null +++ b/config/splat.pspeu.w0_000.yaml @@ -0,0 +1,49 @@ +options: + platform: psp + basename: w0_000 + base_path: .. + build_path: build/pspeu/weapon0 + target_path: disks/pspeu/PSP_GAME/USRDIR/res/ps/PSPBIN/w0_000.bin + asm_path: asm/pspeu/weapon/w0_000 + asset_path: assets/weapon + src_path: src/weapon + ld_script_path: build/pspeu/w0_000.ld + compiler: GCC + symbol_addrs_path: + - config/symbols.pspeu.txt + - config/symbols.pspeu.weapon.txt + - config/symbols.pspeu.w0_000.txt + undefined_funcs_auto_path: config/undefined_funcs_auto.pspeu.w0_000.txt + undefined_syms_auto_path: config/undefined_syms_auto.pspeu.w0_000.txt + find_file_boundaries: true + use_legacy_include_asm: false + migrate_rodata_to_functions: true + asm_jtbl_label_macro: jlabel + symbol_name_format: pspeu_$VRAM + section_order: + - .text + - .data + - .rodata + - .bss + ld_bss_is_noload: true + disasm_unknown: true + disassemble_all: true + global_vram_start: 0x8000000 + asm_inc_header: | + .set noat /* allow manual use of $at */ + .set noreorder /* don't insert nops after branches */ +sha1: bc20b2683492352905317f0634b4db6b84f9985d +segments: + - [0x0, bin, w0_000_mwo_header] + - name: w0_000 + type: code + start: 0x80 + vram: 0x092F2E80 + bss_size: 0x80 + align: 128 + subalign: 8 + subsegments: + - [0x80, c, w_000] + - [0x6CC, .data, w_000] + - {start: 0x1980, type: bss, vram: 0x92F4780} + - [0x1980] diff --git a/config/splat.pspeu.w1_000.yaml b/config/splat.pspeu.w1_000.yaml new file mode 100644 index 0000000000..1ee9f8f779 --- /dev/null +++ b/config/splat.pspeu.w1_000.yaml @@ -0,0 +1,49 @@ +options: + platform: psp + basename: w1_000 + base_path: .. + build_path: build/pspeu/weapon1 + target_path: disks/pspeu/PSP_GAME/USRDIR/res/ps/PSPBIN/w1_000.bin + asm_path: asm/pspeu/weapon/w1_000 + asset_path: assets/weapon1 + src_path: src/weapon + ld_script_path: build/pspeu/w1_000.ld + compiler: GCC + symbol_addrs_path: + - config/symbols.pspeu.txt + - config/symbols.pspeu.weapon.txt + - config/symbols.pspeu.w1_000.txt + undefined_funcs_auto_path: config/undefined_funcs_auto.pspeu.w1_000.txt + undefined_syms_auto_path: config/undefined_syms_auto.pspeu.w1_000.txt + find_file_boundaries: true + use_legacy_include_asm: false + migrate_rodata_to_functions: true + asm_jtbl_label_macro: jlabel + symbol_name_format: pspeu_$VRAM + section_order: + - .text + - .data + - .rodata + - .bss + ld_bss_is_noload: true + disasm_unknown: true + disassemble_all: true + global_vram_start: 0x8000000 + asm_inc_header: | + .set noat /* allow manual use of $at */ + .set noreorder /* don't insert nops after branches */ +sha1: ae247d10da2a0c34ace1b73208b918e170883deb +segments: + - [0x0, bin, w1_000_mwo_header] + - name: w1_000 + type: code + start: 0x80 + vram: 0x092F6C80 + bss_size: 0 + align: 128 + subalign: 8 + subsegments: + - [0x80, c, w_000] + - [0x700, .data, w_000] + - {start: 0x1980, type: bss, vram: 0x92F8580} + - [0x1980] diff --git a/config/splat.pspeu.w1_012.yaml b/config/splat.pspeu.w1_012.yaml new file mode 100644 index 0000000000..7df627f543 --- /dev/null +++ b/config/splat.pspeu.w1_012.yaml @@ -0,0 +1,49 @@ +options: + platform: psp + basename: w1_012 + base_path: .. + build_path: build/pspeu/weapon1 + target_path: disks/pspeu/PSP_GAME/USRDIR/res/ps/PSPBIN/w1_012.bin + asm_path: asm/pspeu/weapon/w1_012_psp + asset_path: assets/weapon1 + src_path: src/weapon + ld_script_path: build/pspeu/w1_012.ld + compiler: GCC + symbol_addrs_path: + - config/symbols.pspeu.txt + - config/symbols.pspeu.w1_012.txt + undefined_funcs_auto_path: config/undefined_funcs_auto.pspeu.w1_012.txt + undefined_syms_auto_path: config/undefined_syms_auto.pspeu.w1_012.txt + find_file_boundaries: true + use_legacy_include_asm: false + migrate_rodata_to_functions: true + asm_jtbl_label_macro: jlabel + symbol_name_format: pspeu_$VRAM + section_order: + - .text + - .data + - .rodata + - .bss + ld_bss_is_noload: true + disasm_unknown: true + disassemble_all: true + global_vram_start: 0x8000000 + asm_inc_header: | + .set noat /* allow manual use of $at */ + .set noreorder /* don't insert nops after branches */ +sha1: eab66ff03cd2ff3c5c011e84f06b2b2943ca06d9 +segments: + - [0x0, bin, w1_012_mwo_header] + - name: w1_012 + type: code + start: 0x80 + vram: 0x092F6C80 + bss_size: 0x80 + align: 128 + subalign: 8 + subsegments: + - [0x80, c, w1_012] + - [0x1900, data] + # - [0x23D8, .rodata, w1_012] + - {start: 0x2480, type: bss, vram: 0x92F9080} + - [0x2480] diff --git a/config/symbols.pspeu.w0_000.txt b/config/symbols.pspeu.w0_000.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/config/symbols.pspeu.w1_000.txt b/config/symbols.pspeu.w1_000.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/config/symbols.pspeu.w1_012.txt b/config/symbols.pspeu.w1_012.txt new file mode 100644 index 0000000000..70843fadac --- /dev/null +++ b/config/symbols.pspeu.w1_012.txt @@ -0,0 +1 @@ +w1_012_Load = 0x092F8450; diff --git a/config/symbols.pspeu.weapon.txt b/config/symbols.pspeu.weapon.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/config/symexport.pspeu.w0_000.txt b/config/symexport.pspeu.w0_000.txt new file mode 100644 index 0000000000..8d15b4d86d --- /dev/null +++ b/config/symexport.pspeu.w0_000.txt @@ -0,0 +1,2 @@ +EXTERN(_binary_assets_weapon_w0_000_mwo_header_bin_start) +EXTERN(w0_000_Load) diff --git a/config/symexport.pspeu.w1_000.txt b/config/symexport.pspeu.w1_000.txt new file mode 100644 index 0000000000..7d9e110624 --- /dev/null +++ b/config/symexport.pspeu.w1_000.txt @@ -0,0 +1,2 @@ +EXTERN(_binary_assets_weapon1_w1_000_mwo_header_bin_start) +EXTERN(w0_000_Load) diff --git a/config/symexport.pspeu.w1_012.txt b/config/symexport.pspeu.w1_012.txt new file mode 100644 index 0000000000..21f05e365c --- /dev/null +++ b/config/symexport.pspeu.w1_012.txt @@ -0,0 +1,2 @@ +EXTERN(_binary_assets_weapon1_w1_012_mwo_header_bin_start) +EXTERN(w1_012_Load) diff --git a/player.ld b/player.ld deleted file mode 100644 index ad39b501cf..0000000000 --- a/player.ld +++ /dev/null @@ -1,13 +0,0 @@ -SECTIONS { - . = 0x8013C000; - .data : { - *(.data*) - } - .rodata : { - *(.rodata*) - } - .text : { - *(.text*) - } - end = .; -} diff --git a/src/weapon/shared.h b/src/weapon/shared.h index 5f85ce62af..c1c7d720cf 100644 --- a/src/weapon/shared.h +++ b/src/weapon/shared.h @@ -9,13 +9,9 @@ static void LoadWeaponPalette(s32 clutIndex) { u16* dst; s32 i; -#if !defined(W_029) - dst = src = g_WeaponCluts[clutIndex]; - dst = D_8006EDCC[g_HandId]; -#else - dst = D_8006EDCC[g_HandId]; + dst = (u16*)&((u16*)g_Clut)[(((g_HandId * 0x18) + 0x110) * 0x10)]; src = g_WeaponCluts[clutIndex]; -#endif + if (src == NULL) { return; } @@ -24,22 +20,17 @@ static void LoadWeaponPalette(s32 clutIndex) { *dst++ = *src++; } -#if !defined(W_029) - dstRect.w = 0x100; - dstRect.h = 3; - dstRect.x = 0; - dstRect.y = 0xF1; -#else dstRect.x = 0; dstRect.w = 0x100; dstRect.h = 3; dstRect.y = 0xF1; -#endif - LoadImage(&dstRect, &D_8006EDCC); + + dst = (u16*)&((u16*)g_Clut)[0x1100]; + LoadImage(&dstRect, (u_long*)dst); } static void SetSpriteBank1(SpriteParts* animset) { - SpritePart** spriteBankDst = g_api.o.spriteBanks; + SpriteParts** spriteBankDst = (SpriteParts**)g_api.o.spriteBanks; spriteBankDst += 0x10; if (g_HandId != 0) { @@ -49,7 +40,7 @@ static void SetSpriteBank1(SpriteParts* animset) { } static void SetSpriteBank2(SpriteParts* animset) { - SpritePart** spriteBankDst = g_api.o.spriteBanks; + SpriteParts** spriteBankDst = (SpriteParts**)g_api.o.spriteBanks; spriteBankDst += 0x11; if (g_HandId != 0) { @@ -88,8 +79,10 @@ static void DestroyEntityWeapon(bool arg0) { static void SetWeaponProperties(Entity* self, s32 kind) { Equipment equip; + s32 equipId; - g_api.GetEquipProperties(g_HandId, &equip, self->ext.weapon.equipId); + equipId = self->ext.weapon.equipId; + g_api.GetEquipProperties(g_HandId, &equip, equipId); switch (kind) { case 0: case 1: diff --git a/src/weapon/w1_012.c b/src/weapon/w1_012.c new file mode 100644 index 0000000000..754ad93f6d --- /dev/null +++ b/src/weapon/w1_012.c @@ -0,0 +1,58 @@ +#include "common.h" + +INCLUDE_ASM("weapon/w1_012_psp/nonmatchings/w1_012", func_pspeu_092F6C80); + +INCLUDE_ASM("weapon/w1_012_psp/nonmatchings/w1_012", func_pspeu_092F6D18); + +INCLUDE_ASM("weapon/w1_012_psp/nonmatchings/w1_012", func_pspeu_092F6E00); + +INCLUDE_ASM("weapon/w1_012_psp/nonmatchings/w1_012", func_pspeu_092F6E48); + +INCLUDE_ASM("weapon/w1_012_psp/nonmatchings/w1_012", func_pspeu_092F6EE8); + +INCLUDE_ASM("weapon/w1_012_psp/nonmatchings/w1_012", func_pspeu_092F6F38); + +INCLUDE_ASM("weapon/w1_012_psp/nonmatchings/w1_012", func_pspeu_092F6FA8); + +INCLUDE_ASM("weapon/w1_012_psp/nonmatchings/w1_012", func_pspeu_092F70C8); + +INCLUDE_ASM("weapon/w1_012_psp/nonmatchings/w1_012", func_pspeu_092F7A70); + +INCLUDE_ASM("weapon/w1_012_psp/nonmatchings/w1_012", func_pspeu_092F8270); + +void func_pspeu_092F83E8(void) { +} + +void func_pspeu_092F83F0(void) { +} + +void func_pspeu_092F83F8(void) { +} + +INCLUDE_ASM("weapon/w1_012_psp/nonmatchings/w1_012", func_pspeu_092F8400); + +void func_pspeu_092F8410(void) { +} + +void func_pspeu_092F8418(void) { +} + +void func_pspeu_092F8420(void) { +} + +void func_pspeu_092F8428(void) { +} + +void func_pspeu_092F8430(void) { +} + +void func_pspeu_092F8438(void) { +} + +void func_pspeu_092F8440(void) { +} + +void func_pspeu_092F8448(void) { +} + +INCLUDE_ASM("weapon/w1_012_psp/nonmatchings/w1_012", w1_012_Load); diff --git a/src/weapon/w_000.c b/src/weapon/w_000.c index 18f9ea41fc..7acf31d36b 100644 --- a/src/weapon/w_000.c +++ b/src/weapon/w_000.c @@ -4,13 +4,31 @@ // Bekatowa, Damascus sword, Hunter sword, Bastard sword, Talwar, Sword of // Hador, Luminus, Harper, Gram, Mormegil, Terminus Est, Dark Blade, // Mourneblade, Badelaire, Unknown#169 - #include "weapon_private.h" +#include + +#ifdef VERSION_PSP +// when HAND_ID is zero, MetroWerks puts this in BSS. this may +// have been in a separate file because it is located at the +// front of .data (when HAND_ID = 1) on PSP/mwcc, but at the end +// of .data (regardless of value) on PSX/gcc. +static s32 g_HandId = HAND_ID; +#endif + +// clang-format:off +#define inner_path(hand, n) CPP_STR(PATH_JOIN(gen/w##hand, n)) +// clangformat:on +#define path(hand, n) inner_path(hand, n) + +#ifdef VERSION_PSP +#include path(HAND_ID, w_000_1.h) +#include path(HAND_ID, w_000_2.h) +#else #include "gen/w_000_1.h" #include "gen/w_000_2.h" +#endif // !VERSION_PSP #define g_Animset w_000_1 #define g_Animset2 w_000_2 -#include "sfx.h" static u16 g_Clut0[N_ARRAY_PAL][COLORS_PER_PAL] = { {0x0000, 0x8000, 0xA821, 0x9DC0, 0xA821, 0xA821, 0xA821, 0xA821, 0x843F, @@ -171,18 +189,20 @@ static u8* g_Anim1[] = { }; static WeaponAnimation g_SoundEvents[] = { - {g_Anim1, g_Hitboxes, 0, SFX_WEAPON_SWISH_B, 0x41, 4}, - {g_Anim0, g_Hitboxes, 0, SFX_WEAPON_SWISH_B, 0x41, 4}, - {g_Anim0, g_Hitboxes, 0, SFX_WEAPON_SWISH_C, 0x41, 4}, - {g_Anim0, g_Hitboxes, 0, SFX_ALUCARD_SWORD_SWISH, 0x41, 4}, - {g_Anim0, g_Hitboxes, 0, SFX_WEAPON_SWISH_C, 0x41, 4}, + {(u16**)g_Anim1, (s8*)g_Hitboxes, 0, SFX_WEAPON_SWISH_B, 0x41, 4}, + {(u16**)g_Anim0, (s8*)g_Hitboxes, 0, SFX_WEAPON_SWISH_B, 0x41, 4}, + {(u16**)g_Anim0, (s8*)g_Hitboxes, 0, SFX_WEAPON_SWISH_C, 0x41, 4}, + {(u16**)g_Anim0, (s8*)g_Hitboxes, 0, SFX_ALUCARD_SWORD_SWISH, 0x41, 4}, + {(u16**)g_Anim0, (s8*)g_Hitboxes, 0, SFX_WEAPON_SWISH_C, 0x41, 4}, }; static u16* g_WeaponCluts[] = { - g_Clut1, g_Clut0, g_Clut2, g_Clut3, g_Clut4, + (u16*)g_Clut1, (u16*)g_Clut0, (u16*)g_Clut2, (u16*)g_Clut3, (u16*)g_Clut4, }; +#ifndef VERSION_PSP static s32 g_HandId = HAND_ID; +#endif #include "shared.h" @@ -191,22 +211,21 @@ static void EntityWeaponAttack(Entity* self) { s32 mask; s16 subType; + subType = (self->params & 0x7FFF) >> 8; + self->posX.val = PLAYER.posX.val; self->posY.val = PLAYER.posY.val; self->facingLeft = PLAYER.facingLeft; - subType = self->params & 0x7FFF; - subType >>= 8; anim = &g_SoundEvents[subType]; if (!(PLAYER.ext.weapon.anim >= anim->frameStart && - PLAYER.ext.weapon.anim < anim->frameStart + 7 && - g_Player.unk46 != 0)) { + PLAYER.ext.weapon.anim < anim->frameStart + 7 && g_Player.unk46)) { DestroyEntity(self); return; } if (self->step == 0) { - SetSpriteBank1(g_Animset); + SetSpriteBank1((SpriteParts*)g_Animset); self->animSet = ANIMSET_OVL(0x10); self->palette = 0x110; self->unk5A = 0x64; @@ -238,6 +257,17 @@ static void EntityWeaponAttack(Entity* self) { self->rotPivotY = PLAYER.rotPivotY; } +#ifdef VERSION_PSP +static void func_ptr_80170004(void) {} + +static void func_ptr_80170008(void) {} + +static void func_ptr_8017000C(void) {} + +static void func_ptr_80170010(void) {} + +static void func_ptr_80170014(void) {} +#else static s32 func_ptr_80170004(Entity* self) {} static void func_ptr_80170008(Entity* self) {} @@ -247,14 +277,23 @@ static void func_ptr_8017000C(Entity* self) {} static s32 func_ptr_80170010(Entity* self) {} static s32 func_ptr_80170014(Entity* self) {} +#endif static int GetWeaponId(void) { return 0; } +#ifdef VERSION_PSP +static void EntityWeaponShieldSpell(void) {} + +static void func_ptr_80170024(void) {} + +static void func_ptr_80170028(void) {} +#else static void EntityWeaponShieldSpell(Entity* self) {} static void func_ptr_80170024(Entity* self) {} static void func_ptr_80170028(Entity* self) {} +#endif static void WeaponUnused2C(void) {} @@ -265,3 +304,38 @@ static void WeaponUnused34(void) {} static void WeaponUnused38(void) {} static void WeaponUnused3C(void) {} + +#ifdef VERSION_PSP +// TODO: this should be WEAPON0_PTR +#ifdef WEAPON0 +extern void D_8017A000[]; +#define WEAPON_PTR D_8017A000 +#else +extern void D_8017D000[]; +#define WEAPON_PTR D_8017D000 +#endif +extern Weapon w0_000_Overlay; + +// TODO: this should be OVL_EXPORT +void w0_000_Load(void) { memcpy(&WEAPON_PTR, &w0_000_Overlay, sizeof(Weapon)); } + +Weapon w0_000_Overlay = { + EntityWeaponAttack, + (void (*)(Entity*))func_ptr_80170004, + (void (*)(Entity*))func_ptr_80170008, + (void (*)(Entity*))func_ptr_8017000C, + func_ptr_80170010, + (void (*)(Entity*))func_ptr_80170014, + GetWeaponId, + LoadWeaponPalette, + (void (*)(Entity*))EntityWeaponShieldSpell, + (void (*)(Entity*))func_ptr_80170024, + (void (*)(Entity*))func_ptr_80170028, + WeaponUnused2C, + WeaponUnused30, + WeaponUnused34, + WeaponUnused38, + WeaponUnused3C, +}; + +#endif diff --git a/src/weapon/weapon_private.h b/src/weapon/weapon_private.h index 7ec7b0a982..10c7b7bfce 100644 --- a/src/weapon/weapon_private.h +++ b/src/weapon/weapon_private.h @@ -51,6 +51,10 @@ typedef struct { #define HAND_ID 0 #endif +#if !defined(WEAPON0) && !defined(WEAPON1) +#define WEAPON0 // forces WEAPON0 for the time being +#endif + // Weapon Factories all encode `g_HandId` at the top of the params #define WFACTORY(id, param) (((g_HandId + 1) << 12) + FACTORY(id, param)) @@ -61,14 +65,11 @@ typedef struct { #define WFACTORY2(id, param) FACTORY(((g_HandId + 1) << 12) + (id), (param)) // create function names like w_000_EntityWeaponAttack -#ifdef VERSION_PC #define CONCATENATE_DETAIL(x, y, z) x##y##_##z #define CONCATENATE(x, y, z) CONCATENATE_DETAIL(x, y, z) #define OVL_EXPORT(x) CONCATENATE(WEAPON, WEAPON_ID, x) -#else -#define OVL_EXPORT(x) x -#endif +#ifndef VERSION_PSP // exported static void EntityWeaponAttack(Entity* self); static void LoadWeaponPalette(s32 clutIndex); @@ -114,5 +115,6 @@ Weapon OVL_EXPORT(header) = { WeaponUnused30, WeaponUnused34, WeaponUnused38, WeaponUnused3C, }; +#endif #endif diff --git a/tools/builds/gen.py b/tools/builds/gen.py index b653f2c194..ab23e5f8c9 100644 --- a/tools/builds/gen.py +++ b/tools/builds/gen.py @@ -41,7 +41,9 @@ def is_hd(version: str) -> bool: def is_weapon(ovl_name: str) -> bool: - return ovl_name == "weapon" + return ( + ovl_name == "weapon" or ovl_name.startswith("w0_") or ovl_name.startswith("w1_") + ) def is_servant(ovl_name: str) -> bool: @@ -81,10 +83,18 @@ def get_cc_flags_for_exceptional_files(version: str, file_name: str): return "-Op" +seen_c_files = set() + + def add_c_psx( - nw: ninja_syntax.Writer, ver: str, file_name: str, ld_path: str, cpp_flags: str + nw: ninja_syntax.Writer, + ver: str, + file_name: str, + ld_path: str, + cpp_flags: str, + build_path: str, ): - output = f"build/{ver}/{file_name}.o" + output = f"{build_path}/{file_name}.o" if output in entries: return entries[output] = {} @@ -120,12 +130,11 @@ def add_c_psx( outputs=file_name, implicit=[f"src/.assets_build_done_{ver}"], ) - return output -def add_s_psx(nw: ninja_syntax.Writer, ver: str, file_name: str, ld_path: str): - output = f"build/{ver}/{file_name}.o" +def add_s_psx(nw: ninja_syntax.Writer, build_path: str, file_name: str, ld_path: str): + output = f"{build_path}/{file_name}.o" if output in entries: return entries[output] = {} @@ -148,8 +157,10 @@ def add_copy_psx( in_file_name: str, out_file_name: str, ld_script_path: str, + build_path: str, ): - output = f"build/{version}/{out_file_name}.o" + # TODO: needs to be build_path + output = f"{build_path}/{out_file_name}.o" if output in entries: return entries[output] = {} @@ -215,9 +226,14 @@ def add_memcard_img_psx( def add_c_psp( - nw: ninja_syntax.Writer, ver: str, file_name: str, ld_path: str, cpp_flags: str + nw: ninja_syntax.Writer, + ver: str, + file_name: str, + ld_path: str, + cpp_flags: str, + build_path: str, ): - output = f"build/{ver}/{file_name}.o" + output = f"{build_path}/{file_name}.o" if output in entries: return entries[output] = {} @@ -256,8 +272,8 @@ def add_c_psp( return output -def add_s_psp(nw: ninja_syntax.Writer, ver: str, file_name: str, ld_path: str): - output = f"build/{ver}/{file_name}.o" +def add_s_psp(nw: ninja_syntax.Writer, build_path: str, file_name: str, ld_path: str): + output = f"{build_path}/{file_name}.o" if output in entries: return entries[output] = {} @@ -389,13 +405,24 @@ def add_weapon_splat_config(nw: ninja_syntax.Writer, ver: str, splat_config): for subsegment in segment["subsegments"]: kind = subsegment[1] if kind == "data": - obj = add_s(nw, ver, f"{asm_path}/data/w_{weapon_id}.data.s", ld_path) + obj = add_s( + nw, build_path, f"{asm_path}/data/w_{weapon_id}.data.s", ld_path + ) objs.append(obj) elif kind == "sbss": - obj = add_s(nw, ver, f"{asm_path}/data/w_{weapon_id}.sbss.s", ld_path) + obj = add_s( + nw, build_path, f"{asm_path}/data/w_{weapon_id}.sbss.s", ld_path + ) objs.append(obj) elif kind == "c": - obj = add_c(nw, ver, f"{src_path}/w_{weapon_id}.c", ld_path, cpp_flags) + obj = add_c( + nw, + ver, + f"{src_path}/w_{weapon_id}.c", + ld_path, + cpp_flags, + build_path, + ) objs.insert(0, obj) # the C file needs to always be linked first elif kind == ".data": continue @@ -466,7 +493,7 @@ def add_splat_config(nw: ninja_syntax.Writer, version: str, file_name: str): outputs=dyn_syms_splat_config, ) - if is_weapon(ovl_name): + if version != "pspeu" and is_weapon(ovl_name): add_weapon_splat_config(nw, version, splat_config) return target_path = str(splat_config["options"]["target_path"]) @@ -498,15 +525,23 @@ def add_splat_config(nw: ninja_syntax.Writer, version: str, file_name: str): add_s = add_s_psp else: raise Exception(f"platform {platform} not recognized") + + cpp_flags = "" + # weapon definitions for psp weapons + if ovl_name.startswith("w0_"): + cpp_flags = "-DWEAPON0 " + elif ovl_name.startswith("w1_"): + cpp_flags = "-DWEAPON1 " + objs = [] if ovl_name == "main": - objs.append(add_s(nw, version, f"{asm_path}/header.s", ld_path)) + objs.append(add_s(nw, build_path, f"{asm_path}/header.s", ld_path)) for segment in splat_config["segments"]: if not "type" in segment: continue if segment["type"] == "data": asm_name = f"{asm_path}/data/{segment["name"]}.data.s" - objs.append(add_s(nw, version, asm_name, ld_path)) + objs.append(add_s(nw, build_path, asm_name, ld_path)) continue for subsegment in segment["subsegments"]: if isinstance(subsegment, dict): # handle PSP BSS @@ -530,12 +565,25 @@ def add_splat_config(nw: ninja_syntax.Writer, version: str, file_name: str): else: name = str.format("{0:X}", offset) if kind == "c" or kind == ".data" or kind == ".rodata" or kind == ".bss": - objs.append(add_c(nw, version, f"{src_path}/{name}.c", ld_path, "")) + # TODO: + # if this is psp and a weapon + # # rename the input C file to w_XXX.c + # # make it a dependency of wY_XXX.c.o build + objs.append( + add_c( + nw, + version, + f"{src_path}/{name}.c", + ld_path, + cpp_flags, + build_path, + ) + ) elif kind == "data" or kind == "rodata" or kind == "bss" or kind == "sbss": - obj = add_s(nw, version, f"{asm_path}/data/{name}.{kind}.s", ld_path) + obj = add_s(nw, build_path, f"{asm_path}/data/{name}.{kind}.s", ld_path) objs.append(obj) elif kind == "asm": - objs.append(add_s(nw, version, f"{asm_path}/{name}.s", ld_path)) + objs.append(add_s(nw, build_path, f"{asm_path}/{name}.s", ld_path)) elif kind == "raw" or kind == "cmp": objs.append( add_copy_psx( @@ -544,6 +592,7 @@ def add_splat_config(nw: ninja_syntax.Writer, version: str, file_name: str): f"{asset_path}/{name}.bin", f"{asset_path}/{name}", ld_path, + build_path, ) ) elif kind == "cmpgfx": @@ -554,6 +603,7 @@ def add_splat_config(nw: ninja_syntax.Writer, version: str, file_name: str): f"{asset_path}/{name}.gfxbin", f"{asset_path}/{name}", ld_path, + build_path, ) ) elif kind == "pal": @@ -564,6 +614,7 @@ def add_splat_config(nw: ninja_syntax.Writer, version: str, file_name: str): f"{asset_path}/{name}.palbin", f"{asset_path}/{name}", ld_path, + build_path, ) ) elif kind == "palette": @@ -577,13 +628,25 @@ def add_splat_config(nw: ninja_syntax.Writer, version: str, file_name: str): objs += objs_memcard else: continue + + def find_mwo_header_name(splat_config: dict[str, any]) -> str: + for segment in splat_config["segments"]: + if isinstance(segment, list) and segment[0] == 0: + return f"{segment[2]}.bin" + elif isinstance(segemnt, dict) and segment["start"] == 0: + if "name" in segment: + return f"{segment["name"]}.bin" + return f"{segment["start"]:X}.bin" + return "mwo_header.bin" + if platform == "psp" and file_name != "PS.ELF": - mwo = os.path.join(asset_path, "mwo_header.bin") - objs.append(add_copy_psx(nw, version, mwo, mwo, ld_path)) - output_elf = f"build/{version}/{ovl_name}.elf" + mwo = os.path.join(asset_path, find_mwo_header_name(splat_config)) + objs.append(add_copy_psx(nw, version, mwo, mwo, ld_path, build_path)) + output_elf = f"{build_path}/{ovl_name}.elf" sym_version = version if ovl_name == "stmad": sym_version = "beta" + # TODO: get these from splat symbols_lists = [ f"-T config/undefined_syms.{sym_version}.txt", f"-T {undefined_syms_auto_path}", @@ -599,7 +662,7 @@ def add_splat_config(nw: ninja_syntax.Writer, version: str, file_name: str): implicit=[x for x in objs if x], variables={ "ld_flags": "--gc-sections" if platform == "psp" else "", - "map_out": f"build/{version}/{ovl_name}.map", + "map_out": f"{build_path}/{ovl_name}.map", "symbols_arg": str.join(" ", symbols_lists), }, ) @@ -619,7 +682,7 @@ def add_splat_config(nw: ninja_syntax.Writer, version: str, file_name: str): gfx_name = f"F_{os.path.basename(target_path)}" if is_hd(version): gfx_name = f"f_{os.path.basename(target_path)}" - stage_gfx_path = f"build/{version}/{gfx_name}" + stage_gfx_path = f"{build_path}/{gfx_name}" target_f_path = os.path.join(os.path.dirname(target_path), gfx_name) add_gfx_stage(nw, target_f_path, asset_path, stage_gfx_path) @@ -738,6 +801,7 @@ def add_checksum(nw: ninja_syntax.Writer, version: str, file_name: str): " --asm-dir-prefix asm/pspeu --target-encoding sjis --macro-inc-path include/macro.inc" " -gccinc -Iinclude -D_internal_version_$version -DSOTN_STR -c -lang c -sdatathreshold 0 -char unsigned -fl divbyzerocheck" " $opt_level -opt nointrinsics" + " $cpp_flags" ), description="psp cc $in", ) diff --git a/tools/make-config.py b/tools/make-config.py index ea8fa64dbd..0f479378c4 100755 --- a/tools/make-config.py +++ b/tools/make-config.py @@ -651,6 +651,18 @@ def increase_indent(self, flow=False, indentless=False): str(ovl_header["name"]).split(".")[0], ) + # adjust build path for weapons + if is_weapon(ovl_name): + if ovl_name.startswith("w0_"): + build_path = f"build/{version}/weapon0" + asset_path = f"assets/weapon" + else: + build_path = f"build/{version}/weapon1" + asset_path = f"assets/weapon1" + config["options"]["build_path"] = build_path + config["options"]["asset_path"] = asset_path + config["options"]["src_path"] = "src/weapon" + # find well-known segment offsets matches = find_matches(ovl_name, version) @@ -662,6 +674,10 @@ def increase_indent(self, flow=False, indentless=False): vram_c_start = vram + 0x80 vram_c_end = vram_c_start + text_len rodata_start = -1 + # TODO: this doesn't work if data contains function pointers + # + # NOTE: weapon is always going to end data with an Overlay struct + # followed by padding to the closest 0x80 alignment with open(ovl_path, "rb") as f: byte_data = f.read()[data_start:bss_start] start = align(data_len // 2, 4) # very cheap way to skip the entity table @@ -677,14 +693,20 @@ def increase_indent(self, flow=False, indentless=False): rodata_start = data_start + data_len text_segments = [] - append_segments( - text_segments, 0x80, 8, data_start, f"{ovl_name}_psp/", "80", known_segments + if is_weapon(ovl_name): + default_segment_name = f"{ovl_name}" + append_segments( + text_segments, 0x80, 8, data_start, f"", default_segment_name, known_segments + ) + else: + default_segment_name = f"80" + append_segments( + text_segments, 0x80, 8, data_start, f"{ovl_name}_psp/", default_segment_name, known_segments ) # set global vram address to allow mapping of global symbols config["options"]["global_vram_start"] = HexInt(0x08000000) - ovl_name = config["options"]["basename"] splat_config_path = f"config/splat.{version}.{ovl_name}.yaml" with open(splat_config_path, "w") as f: f.write(yaml.dump(config, Dumper=IndentDumper, sort_keys=False)) @@ -706,15 +728,23 @@ def increase_indent(self, flow=False, indentless=False): f" subsegments:\n", ] text.extend(text_segments) - text.extend( - [ - f" - [0x{data_start:X}, data]\n", - f" - [0x{rodata_start:X}, .rodata, 80]\n", - f" - {{type: bss, vram: 0x{bss_start:X}}}\n", - f" - [0x{file_size:X}]\n", - ] - ) + text.append(f" - [0x{data_start:X}, data]\n") + print(f"rodata: {rodata_start}") + if rodata_start != -1: + text.append(f" - [0x{rodata_start:X}, .rodata, {default_segment_name}]\n") + text.append(f" - {{type: bss, vram: 0x{bss_start:X}}}\n") + text.append(f" - [0x{file_size:X}]\n") f.writelines(text) + + if is_weapon(ovl_name): + with open("config/symexport.{version}.{ovl_name}.txt", "w"): + if ovl_name.startswith("w1"): + hand_id = "1" + else: + hand_id = "" + f.write(f"EXTERN(_binary_assets_weapon{hand_id}_mwo_header_bin_start)\n") + f.write(f"EXTERN({ovl_name}_Load)") + return splat_config_path diff --git a/weapon0.ld b/weapon0.ld deleted file mode 100644 index df74534d2a..0000000000 --- a/weapon0.ld +++ /dev/null @@ -1,11 +0,0 @@ -SECTIONS { - .WEAPON_OVL 0x8017A000 : AT(0) SUBALIGN(4) - { - *(.data) - *(.rodata) - *(.text) - *(.bss) - } - - end = .; -} diff --git a/weapon1.ld b/weapon1.ld deleted file mode 100644 index dc6ff8e876..0000000000 --- a/weapon1.ld +++ /dev/null @@ -1,10 +0,0 @@ -SECTIONS { - .WEAPON_OVL 0x8017D000 : AT(0) SUBALIGN(4) - { - *(.data) - *(.rodata) - *(.text) - } - - end = .; -}