Added File.c, added Tex.h,
added KuonMenu.h, Menu.h, Cdvd.h Added missing struct defines, missing function defines Implement File
This commit is contained in:
+1
-1
@@ -249,7 +249,7 @@ segments:
|
||||
- [0x032110, asmtu, cs4/Seimei/src/Camera]
|
||||
- [0x034930, asmtu, cs4/Seimei/src/Debug]
|
||||
- [0x034D10, asmtu, cs4/Seimei/src/Draw]
|
||||
- [0x038710, asmtu, cs4/Seimei/src/File]
|
||||
- [0x038710, c, cs4/Seimei/src/File]
|
||||
- [0x038D00, asmtu, cs4/Seimei/src/Game]
|
||||
- [0x039A00, asmtu, cs4/Seimei/src/Load]
|
||||
- [0x03A380, c, cs4/Seimei/src/Main]
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ def make_compiler_cmd(config_dir: Path, src_path: Path, language: str):
|
||||
|
||||
game_cc_dir = f"{tools_dir}/cc/{COMPILER}"
|
||||
|
||||
compiler_includes = f"-I{src_path.parent / 'src'} -I{src_path.parent / 'include'} -Iinclude/sdk/ee"
|
||||
compiler_includes = f"-I{src_path.parent / 'src'} -I{src_path.parent / 'include'} -Iinclude/sdk/ee -I../src/cs4/Seimei/fslib"
|
||||
assembler_includes = f"-I{src_path.parent / 'include'} -I{src_path.parent}"
|
||||
common_includes = f"{compiler_includes} {assembler_includes}"
|
||||
game_compile_cmd = f"{WIBO} {game_cc_dir}/mwccps2.exe -c {common_includes} {COMPILER_FLAGS}"
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef FSFONT_H
|
||||
#define FSFONT_H
|
||||
|
||||
signed int FsFontSetTexBuf(signed int id /* r2 */, void * pTexFileBuf /* r2 */);
|
||||
|
||||
#endif // FSFONT_H
|
||||
@@ -0,0 +1,115 @@
|
||||
#ifndef CDVD_H
|
||||
#define CDVD_H
|
||||
|
||||
/*
|
||||
Compile unit: C:\cs4\Seimei\src\Cdvd.c
|
||||
Producer: MW MIPS C Compiler
|
||||
Language: C
|
||||
*/
|
||||
static // total size: 0x14C
|
||||
struct /* @anon1 */ {
|
||||
// Members
|
||||
// total size: 0x24
|
||||
struct /* @anon0 */ {
|
||||
// Members
|
||||
unsigned int lsn; // offset 0x0, size 0x4
|
||||
unsigned int size; // offset 0x4, size 0x4
|
||||
char name[16]; // offset 0x8, size 0x10
|
||||
unsigned char date[8]; // offset 0x18, size 0x8
|
||||
unsigned int flag; // offset 0x20, size 0x4
|
||||
} cdlfile; // offset 0x0, size 0x24
|
||||
char fname[128]; // offset 0x24, size 0x80
|
||||
char sname[128]; // offset 0xA4, size 0x80
|
||||
signed int state; // offset 0x124, size 0x4
|
||||
signed int fileType; // offset 0x128, size 0x4
|
||||
signed int index; // offset 0x12C, size 0x4
|
||||
signed int fhd; // offset 0x130, size 0x4
|
||||
signed int size; // offset 0x134, size 0x4
|
||||
signed int sector; // offset 0x138, size 0x4
|
||||
unsigned int align; // offset 0x13C, size 0x4
|
||||
unsigned char retry; // offset 0x140, size 0x1
|
||||
unsigned char unused[3]; // offset 0x141, size 0x3
|
||||
unsigned char * * lplpAddr; // offset 0x144, size 0x4
|
||||
unsigned char * lpDmyData; // offset 0x148, size 0x4
|
||||
} * lpSetCdvd; // size: 0x4, address: 0x257560
|
||||
static // total size: 0x14C
|
||||
struct /* @anon1 */ {
|
||||
// Members
|
||||
// total size: 0x24
|
||||
struct /* @anon0 */ {
|
||||
// Members
|
||||
unsigned int lsn; // offset 0x0, size 0x4
|
||||
unsigned int size; // offset 0x4, size 0x4
|
||||
char name[16]; // offset 0x8, size 0x10
|
||||
unsigned char date[8]; // offset 0x18, size 0x8
|
||||
unsigned int flag; // offset 0x20, size 0x4
|
||||
} cdlfile; // offset 0x0, size 0x24
|
||||
char fname[128]; // offset 0x24, size 0x80
|
||||
char sname[128]; // offset 0xA4, size 0x80
|
||||
signed int state; // offset 0x124, size 0x4
|
||||
signed int fileType; // offset 0x128, size 0x4
|
||||
signed int index; // offset 0x12C, size 0x4
|
||||
signed int fhd; // offset 0x130, size 0x4
|
||||
signed int size; // offset 0x134, size 0x4
|
||||
signed int sector; // offset 0x138, size 0x4
|
||||
unsigned int align; // offset 0x13C, size 0x4
|
||||
unsigned char retry; // offset 0x140, size 0x1
|
||||
unsigned char unused[3]; // offset 0x141, size 0x3
|
||||
unsigned char * * lplpAddr; // offset 0x144, size 0x4
|
||||
unsigned char * lpDmyData; // offset 0x148, size 0x4
|
||||
} * lpLastCdvd; // size: 0x4, address: 0x257564
|
||||
static // total size: 0x14C
|
||||
struct /* @anon1 */ {
|
||||
// Members
|
||||
// total size: 0x24
|
||||
struct /* @anon0 */ {
|
||||
// Members
|
||||
unsigned int lsn; // offset 0x0, size 0x4
|
||||
unsigned int size; // offset 0x4, size 0x4
|
||||
char name[16]; // offset 0x8, size 0x10
|
||||
unsigned char date[8]; // offset 0x18, size 0x8
|
||||
unsigned int flag; // offset 0x20, size 0x4
|
||||
} cdlfile; // offset 0x0, size 0x24
|
||||
char fname[128]; // offset 0x24, size 0x80
|
||||
char sname[128]; // offset 0xA4, size 0x80
|
||||
signed int state; // offset 0x124, size 0x4
|
||||
signed int fileType; // offset 0x128, size 0x4
|
||||
signed int index; // offset 0x12C, size 0x4
|
||||
signed int fhd; // offset 0x130, size 0x4
|
||||
signed int size; // offset 0x134, size 0x4
|
||||
signed int sector; // offset 0x138, size 0x4
|
||||
unsigned int align; // offset 0x13C, size 0x4
|
||||
unsigned char retry; // offset 0x140, size 0x1
|
||||
unsigned char unused[3]; // offset 0x141, size 0x3
|
||||
unsigned char * * lplpAddr; // offset 0x144, size 0x4
|
||||
unsigned char * lpDmyData; // offset 0x148, size 0x4
|
||||
} * lpCdvdRead; // size: 0x4, address: 0x257568
|
||||
// total size: 0x14C
|
||||
struct /* @anon1 */ {
|
||||
// Members
|
||||
// total size: 0x24
|
||||
struct /* @anon0 */ {
|
||||
// Members
|
||||
unsigned int lsn; // offset 0x0, size 0x4
|
||||
unsigned int size; // offset 0x4, size 0x4
|
||||
char name[16]; // offset 0x8, size 0x10
|
||||
unsigned char date[8]; // offset 0x18, size 0x8
|
||||
unsigned int flag; // offset 0x20, size 0x4
|
||||
} cdlfile; // offset 0x0, size 0x24
|
||||
char fname[128]; // offset 0x24, size 0x80
|
||||
char sname[128]; // offset 0xA4, size 0x80
|
||||
signed int state; // offset 0x124, size 0x4
|
||||
signed int fileType; // offset 0x128, size 0x4
|
||||
signed int index; // offset 0x12C, size 0x4
|
||||
signed int fhd; // offset 0x130, size 0x4
|
||||
signed int size; // offset 0x134, size 0x4
|
||||
signed int sector; // offset 0x138, size 0x4
|
||||
unsigned int align; // offset 0x13C, size 0x4
|
||||
unsigned char retry; // offset 0x140, size 0x1
|
||||
unsigned char unused[3]; // offset 0x141, size 0x3
|
||||
unsigned char * * lplpAddr; // offset 0x144, size 0x4
|
||||
unsigned char * lpDmyData; // offset 0x148, size 0x4
|
||||
} CdvdReadSt[256]; // size: 0x14C00, address: 0xA01200
|
||||
unsigned int GlobalLoadTimer; // size: 0x4, address: 0x257894
|
||||
|
||||
#endif // CDVD_H
|
||||
+217
-9
@@ -1,19 +1,227 @@
|
||||
#include "File.h"
|
||||
#include "Cdvd.h"
|
||||
#include "Game.h"
|
||||
#include "Model.h"
|
||||
#include "Tex.h"
|
||||
#include "Unk.h"
|
||||
#include "common.h"
|
||||
#include "lib/FsFont.h"
|
||||
#include "menu/KuonMenu.h"
|
||||
#include "menu/Menu.h"
|
||||
|
||||
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", AfterFileReadFunc);
|
||||
unsigned char ScePath[128]; // size: 0x80, address: 0x3254B0
|
||||
unsigned char RootPath[128]; // size: 0x80, address: 0x325530
|
||||
|
||||
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", FileCheckAsyncBusy);
|
||||
void AfterFileReadFunc(u8 *lpAddr, s32 index, s32 fileType, s32 size) {
|
||||
switch (fileType) {
|
||||
case 0x0:
|
||||
case 0x80:
|
||||
RemapBinderFile(lpAddr);
|
||||
SetMdlBndFile(index);
|
||||
if (GameSt.GameMode != 4) {
|
||||
if (index == 0) {
|
||||
MyAppear(0, &MdlMng[0xA0], VW, 0.0f);
|
||||
}
|
||||
if ((GameSt.PlayerId != 2) && (index == 0x10E)) {
|
||||
InitMyWeapon(GameSt.PlayerId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x1:
|
||||
RemapCamData(lpAddr);
|
||||
break;
|
||||
|
||||
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", FileBackReadControl);
|
||||
case 0x2:
|
||||
RemapMapFile(lpAddr);
|
||||
ReadMapMdlFile(lpAddr);
|
||||
break;
|
||||
|
||||
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", FileReadControl);
|
||||
case 0x3:
|
||||
break;
|
||||
|
||||
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", FileRead);
|
||||
case 0x4:
|
||||
break;
|
||||
|
||||
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", InitFileRead);
|
||||
case 0x5:
|
||||
RemapMdlLink(lpAddr);
|
||||
SetMdlData(index, lpAddr);
|
||||
break;
|
||||
|
||||
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", GetRootPath);
|
||||
case 0x6:
|
||||
RemapMdlLink(lpAddr);
|
||||
SetTexList(lpAddr, 2);
|
||||
break;
|
||||
|
||||
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", ReadRootPath);
|
||||
case 0x7:
|
||||
RemapMdlLink(lpAddr);
|
||||
SetTexList(lpAddr, 2);
|
||||
FsFontSetTexBuf(2,
|
||||
GetTexMngByName(GetGameTexList(), "iconfont.tm2")->lpTm2);
|
||||
ItemMng_CallBack_FinishLoadFile_ItemList();
|
||||
break;
|
||||
|
||||
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", InitFileSystem);
|
||||
case 0x8:
|
||||
RemapMdlLink(lpAddr);
|
||||
SetTexList(lpAddr, 1);
|
||||
SetMapTexListFile(index);
|
||||
break;
|
||||
|
||||
case 0x9:
|
||||
RemapMdlLink(lpAddr);
|
||||
SetAniData(index, lpAddr);
|
||||
break;
|
||||
|
||||
case 0xA:
|
||||
RemapMdlLink(lpAddr);
|
||||
SetHdlData(index, lpAddr);
|
||||
break;
|
||||
|
||||
case 0xB:
|
||||
RemapMdlLink(lpAddr);
|
||||
SetSdlData(index, lpAddr);
|
||||
break;
|
||||
|
||||
case 0xC:
|
||||
break;
|
||||
|
||||
case 0xD:
|
||||
RemapBinderFile(lpAddr);
|
||||
Rta_BndReadEndCallBack();
|
||||
break;
|
||||
|
||||
case 0xE:
|
||||
break;
|
||||
|
||||
case 0x11:
|
||||
RemapMdlLink(lpAddr);
|
||||
SetTexList(lpAddr, 1);
|
||||
break;
|
||||
|
||||
case 0xF:
|
||||
break;
|
||||
|
||||
case 0x10:
|
||||
RemapBinderFile(lpAddr);
|
||||
|
||||
if ((Menu_GetLastReloadType() & 0xFFFF) == 0x8000) {
|
||||
Menu_FileReadCallBack(0x8000);
|
||||
KnMenuMng_ReMakeMenu(KUON_MENU__MAKE_TITLE);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((Menu_GetLastReloadType(0x8000) & 0xFFFF) == 0x4000) {
|
||||
Menu_FileReadCallBack(KUON_MENU_RELOAD_FLAG_GAME);
|
||||
KnMenuMng_ReMakeMenu(KUON_MENU__MAKE_GAME);
|
||||
SetFixMemoryEndIndex();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
SetScript(size, lpAddr);
|
||||
break;
|
||||
|
||||
case 0x13:
|
||||
break;
|
||||
|
||||
case 0x14:
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
break;
|
||||
|
||||
case 0x15:
|
||||
RemapDramaData(lpAddr);
|
||||
if (index != 0) {
|
||||
SetDramaData();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x16:
|
||||
SND_LoadSecFromFileInMemory(index & 0xFF, lpAddr);
|
||||
break;
|
||||
|
||||
case 0x21:
|
||||
SND_LoadRandSeFromFileInMemory(lpAddr);
|
||||
break;
|
||||
|
||||
case 0x17:
|
||||
RemapBinderFile(lpAddr);
|
||||
break;
|
||||
|
||||
case 0x18:
|
||||
SND_SqPrepare();
|
||||
break;
|
||||
|
||||
case 0x19:
|
||||
SetSceneBndFile();
|
||||
break;
|
||||
|
||||
case 0x1A:
|
||||
break;
|
||||
|
||||
case 0x1B:
|
||||
SfxFIO_CallBack_FinishLoadSfxBindFile();
|
||||
break;
|
||||
|
||||
case 0x1C:
|
||||
break;
|
||||
|
||||
case 0x1D:
|
||||
SetRiddleData();
|
||||
break;
|
||||
|
||||
case 0x1E:
|
||||
break;
|
||||
|
||||
case 0x1F:
|
||||
RemapMiz(lpAddr);
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
break;
|
||||
|
||||
case 0x82:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int FileCheckAsyncBusy(void) { return CdvdCheckAsyncBusy(); }
|
||||
|
||||
void FileBackReadControl(void) { CdvdBackReadProc(); }
|
||||
|
||||
void FileReadControl(int bDraw) { CdvdAsyncProc(bDraw); }
|
||||
|
||||
signed int FileRead(char *filename /* r2 */, signed int size /* r2 */,
|
||||
unsigned char **lpBuf /* r2 */,
|
||||
unsigned char bSynch /* r2 */, signed int index /* r2 */,
|
||||
signed int filetype /* r2 */, unsigned int align /* r2 */) {
|
||||
return CdvdRead(filename, size, lpBuf, bSynch, index, filetype, align);
|
||||
}
|
||||
|
||||
void InitFileRead(void) { InitCdvdRead(); }
|
||||
|
||||
unsigned char *GetRootPath() { return RootPath; }
|
||||
|
||||
void ReadRootPath() {
|
||||
memset(RootPath, 0, 0x80);
|
||||
memset(ScePath, 0, 0x80);
|
||||
sprintf((char *)RootPath, "cdrom0:\\");
|
||||
sprintf((char *)ScePath, "cdrom0:\\");
|
||||
}
|
||||
|
||||
void InitFileSystem() {
|
||||
/* anonymous block */
|
||||
// Range: 0x138C20 -> 0x138C78
|
||||
|
||||
sceSifInitRpc(0);
|
||||
sceSifInitIopHeap();
|
||||
sceSifLoadFileReset();
|
||||
sceFsReset();
|
||||
while (!sceCdInit(0)) {
|
||||
}
|
||||
sceCdMmode(2);
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
#ifndef FILE_H
|
||||
#define FILE_H
|
||||
|
||||
extern unsigned char ScePath[128]; // size: 0x80, address: 0x3254B0
|
||||
extern unsigned char RootPath[128]; // size: 0x80, address: 0x325530
|
||||
|
||||
void InitFileRead();
|
||||
void InitFileSystem();
|
||||
void ReadRootPath();
|
||||
|
||||
@@ -52,4 +52,5 @@ extern GameState GameSt; // size: 0x30, address: 0x3A5E10
|
||||
int GameLoop();
|
||||
void InitGameData();
|
||||
void InitGameDataAfterLoad();
|
||||
void * GetGameTexList();
|
||||
#endif // GAME_H
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
#ifndef TEX_H
|
||||
#define TEX_H
|
||||
|
||||
/*
|
||||
Compile unit: C:\cs4\Seimei\src\Tex.c
|
||||
Producer: MW MIPS C Compiler
|
||||
Language: C
|
||||
Code range: 0x0013FA80 -> 0x0013FB18
|
||||
*/
|
||||
// Range: 0x13FA80 -> 0x13FB18
|
||||
// total size: 0x60
|
||||
struct /* @anon0 */ {
|
||||
// Members
|
||||
unsigned char bUse; // offset 0x0, size 0x1
|
||||
unsigned char unused0; // offset 0x1, size 0x1
|
||||
unsigned short id; // offset 0x2, size 0x2
|
||||
// total size: 0x20
|
||||
struct /* @anon1 */ {
|
||||
// Members
|
||||
unsigned int size; // offset 0x0, size 0x4
|
||||
unsigned int wnum; // offset 0x4, size 0x4
|
||||
unsigned char dummy[5]; // offset 0x8, size 0x5
|
||||
unsigned char compare; // offset 0xD, size 0x1
|
||||
unsigned short tex_id; // offset 0xE, size 0x2
|
||||
// total size: 0x8
|
||||
struct /* @anon5 */ {
|
||||
// Members
|
||||
unsigned long TBP0 : 14; // offset 0x0, size 0x4
|
||||
unsigned long TBW : 6; // offset 0x0, size 0x4
|
||||
unsigned long PSM : 6; // offset 0x0, size 0x4
|
||||
unsigned long TW : 4; // offset 0x0, size 0x4
|
||||
unsigned long TH : 4; // offset 0x0, size 0x4
|
||||
unsigned long TCC : 1; // offset 0x0, size 0x4
|
||||
unsigned long TFX : 2; // offset 0x0, size 0x4
|
||||
unsigned long CBP : 14; // offset 0x0, size 0x4
|
||||
unsigned long CPSM : 4; // offset 0x0, size 0x4
|
||||
unsigned long CSM : 1; // offset 0x0, size 0x4
|
||||
unsigned long CSA : 5; // offset 0x0, size 0x4
|
||||
unsigned long CLD : 3; // offset 0x0, size 0x4
|
||||
} tex0; // offset 0x10, size 0x8
|
||||
// total size: 0x8
|
||||
struct /* @anon7 */ {
|
||||
// Members
|
||||
unsigned long LCM : 1; // offset 0x0, size 0x4
|
||||
unsigned long pad01 : 1; // offset 0x0, size 0x4
|
||||
unsigned long MXL : 3; // offset 0x0, size 0x4
|
||||
unsigned long MMAG : 1; // offset 0x0, size 0x4
|
||||
unsigned long MMIN : 3; // offset 0x0, size 0x4
|
||||
unsigned long MTBA : 1; // offset 0x0, size 0x4
|
||||
unsigned long pad10 : 9; // offset 0x0, size 0x4
|
||||
unsigned long L : 2; // offset 0x0, size 0x4
|
||||
unsigned long pad21 : 11; // offset 0x0, size 0x4
|
||||
unsigned long K : 12; // offset 0x0, size 0x4
|
||||
unsigned long pad44 : 20; // offset 0x0, size 0x4
|
||||
} tex1; // offset 0x18, size 0x8
|
||||
} * lpTm2; // offset 0x4, size 0x4
|
||||
void * lpTexList; // offset 0x8, size 0x4
|
||||
signed int unused1[1]; // offset 0xC, size 0x4
|
||||
unsigned char texName[32]; // offset 0x10, size 0x20
|
||||
unsigned char texNameBase[32]; // offset 0x30, size 0x20
|
||||
signed int texW; // offset 0x50, size 0x4
|
||||
signed int texH; // offset 0x54, size 0x4
|
||||
signed int texTBW; // offset 0x58, size 0x4
|
||||
signed int texPSM; // offset 0x5C, size 0x4
|
||||
} * GetTexMngByName(void * lpTexList /* r18 */, char * texname /* r17 */);
|
||||
|
||||
|
||||
#endif // TEX_H
|
||||
@@ -31,6 +31,8 @@ extern struct /* @anon0 */ {
|
||||
unsigned short cam_id; // offset 0x6, size 0x2
|
||||
}* lpSceneLoad; // size: 0x4, address: 0x257530
|
||||
|
||||
static float VZ[4]; // size: 0x10, address: 0x228720
|
||||
static float VW[4]; // size: 0x10, address: 0x228730
|
||||
|
||||
|
||||
#endif // UNK_H
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef KUONMENU_H
|
||||
#define KUONMENU_H
|
||||
|
||||
enum _KUON_MENU__RELOAD_FLAG_EN {
|
||||
KUON_MENU_RELOAD_FLAG_NONE = 0,
|
||||
KUON_MENU_RELOAD_FLAG_TITLE_ = 1,
|
||||
KUON_MENU_RELOAD_FLAG_START = 2,
|
||||
KUON_MENU_RELOAD_FLAG_MAIN = 4,
|
||||
KUON_MENU_RELOAD_FLAG_SAVE = 8,
|
||||
KUON_MENU_RELOAD_FLAG_LOAD = 16,
|
||||
KUON_MENU_RELOAD_FLAG_DEAD = 32,
|
||||
KUON_MENU_RELOAD_FLAG_MM_TOP = 64,
|
||||
KUON_MENU_RELOAD_FLAG_MM_EQUIP = 128,
|
||||
KUON_MENU_RELOAD_FLAG_MM_ITEM = 256,
|
||||
KUON_MENU_RELOAD_FLAG_MM_BOOK = 512,
|
||||
KUON_MENU_RELOAD_FLAG_MM_MAP = 1024,
|
||||
KUON_MENU_RELOAD_FLAG_MM_SET = 2048,
|
||||
KUON_MENU_RELOAD_FLAG_MM_END = 4096,
|
||||
KUON_MENU_RELOAD_FLAG_DOC = 8192,
|
||||
KUON_MENU_RELOAD_FLAG_GAME = 16384,
|
||||
KUON_MENU_RELOAD_FLAG_TITLE = -32768,
|
||||
};
|
||||
|
||||
#endif // KUONMENU_H
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef MENU_H
|
||||
#define MENU_H
|
||||
|
||||
enum _KUON_MENU__TYPE_EN {
|
||||
KUON_MENU__TEST_MENU = 0,
|
||||
KUON_MENU__TITLE_MENU = 1,
|
||||
KUON_MENU__START_MENU = 2,
|
||||
KUON_MENU__MAIN_MENU = 3,
|
||||
KUON_MENU__SAVE_MENU = 4,
|
||||
KUON_MENU__LOAD_MENU = 5,
|
||||
KUON_MENU__MAP_MENU = 6,
|
||||
KUON_MENU__ITEM_MENU = 7,
|
||||
KUON_MENU__MSG_MENU = 8,
|
||||
KUON_MENU__SET_MENU = 9,
|
||||
KUON_MENU__END_SAVE_MENU = 10,
|
||||
KUON_MENU__DEAD_MENU = 11,
|
||||
KUON_MENU__MENU_NUM = 12,
|
||||
KUON_MENU__MAKE_NONE = 100,
|
||||
KUON_MENU__MAKE_TITLE = 101,
|
||||
KUON_MENU__MAKE_GAME = 102,
|
||||
KUON_MENU__DMY_MENU = 999,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // MENU_H
|
||||
@@ -0,0 +1,240 @@
|
||||
'''
|
||||
alessatool/annotate
|
||||
|
||||
mark up assembly with line numbers.
|
||||
can also be used to create full-tu scratches in decomp.me.
|
||||
|
||||
example:
|
||||
|
||||
alessatool annotate \
|
||||
--asm-path silent-hill-2/config/SLUS_202.28/asm/Effect2/hh_class_water_03.s \
|
||||
--tu
|
||||
|
||||
run `alessatool annotate --help` for more information.
|
||||
'''
|
||||
|
||||
from sys import stdout, stdin
|
||||
from pathlib import Path
|
||||
from subprocess import run
|
||||
from dataclasses import dataclass
|
||||
from constants import *
|
||||
from struct import unpack
|
||||
|
||||
@dataclass
|
||||
class AnnotationArgs:
|
||||
vram_start: int | None
|
||||
vram_end: int | None
|
||||
elf_path: Path
|
||||
asm_path: Path | None
|
||||
out_path: Path
|
||||
addr2line_path: Path
|
||||
line_file_path: Path | None
|
||||
tu: bool
|
||||
encoding: str
|
||||
stdout: bool
|
||||
verbose: bool
|
||||
|
||||
def annotate_asm(args: AnnotationArgs):
|
||||
if args.asm_path:
|
||||
with open(args.asm_path, "r") as asm_file:
|
||||
asm_contents = asm_file.read()
|
||||
else:
|
||||
asm_contents = stdin.read()
|
||||
|
||||
asm_lines = asm_contents.splitlines()
|
||||
asm_line_index = 0
|
||||
|
||||
vram_start = args.vram_start
|
||||
vram_end = args.vram_end
|
||||
|
||||
if vram_start is None or vram_end is None:
|
||||
vram_start, vram_end = find_vram_bounds(asm_lines)
|
||||
|
||||
line_file_path = get_line_file_path(args)
|
||||
|
||||
if line_file_path is None or not line_file_path.exists():
|
||||
addresses = (f"0x{v:X}" for v in range(vram_start, vram_end, 0x4))
|
||||
proc = run([args.addr2line_path, "-e", args.elf_path, *addresses], capture_output=True, encoding=args.encoding)
|
||||
addr2line_output_lines = proc.stdout.splitlines()
|
||||
else:
|
||||
# parse the binary line number file.
|
||||
|
||||
# the format is a list of u_shorts, one per line number.
|
||||
# there should be one line number per vram address, and each vram
|
||||
# address should be exactly 4 bytes apart, mirroring how the addr2line
|
||||
# output is formatted
|
||||
|
||||
with open(line_file_path, "rb") as line_file:
|
||||
line_data = line_file.read()
|
||||
line_numbers = unpack(f"<{len(line_data) // 2}H", line_data)
|
||||
compile_unit = args.asm_path.with_suffix(".c").name
|
||||
addr2line_output_lines = list(map(lambda n : to_addr2line_format(compile_unit, n), line_numbers))
|
||||
|
||||
main_tu_name = None
|
||||
prev_tu_name = None
|
||||
prev_line_number = -1
|
||||
function_count = 0
|
||||
is_in_function_label = False
|
||||
is_in_text_section = False
|
||||
current_vram_addr = vram_start
|
||||
annotated_asm_lines = []
|
||||
|
||||
for addr_index in range(0, len(addr2line_output_lines) - 1):
|
||||
line = addr2line_output_lines[addr_index]
|
||||
|
||||
if line.startswith("?"):
|
||||
current_vram_addr += 0x4
|
||||
continue
|
||||
|
||||
separator_index = line.rfind(":")
|
||||
current_line_number = int(line[separator_index+1:])
|
||||
|
||||
if current_line_number == prev_line_number:
|
||||
current_vram_addr += 0x4
|
||||
continue
|
||||
|
||||
vram_addr_str = f"{current_vram_addr:X}"
|
||||
|
||||
current_tu_name = line[0:separator_index]
|
||||
if current_tu_name != main_tu_name and current_tu_name != prev_tu_name:
|
||||
if main_tu_name:
|
||||
print(f"[warn] alessatool/annotate: address at {vram_addr_str} belongs to {current_tu_name}")
|
||||
else:
|
||||
main_tu_name = current_tu_name
|
||||
prev_tu_name = current_tu_name
|
||||
|
||||
while True:
|
||||
if asm_line_index >= len(asm_lines):
|
||||
raise AssertionError(
|
||||
f"address 0x{current_vram_addr:X} not found in asm"
|
||||
)
|
||||
|
||||
asm_line = asm_lines[asm_line_index]
|
||||
|
||||
if asm_line.startswith(SECTION_DIRECTIVE):
|
||||
is_in_text_section = asm_line.startswith(TEXT_SECTION_DIRECTIVE)
|
||||
|
||||
if not is_in_text_section:
|
||||
annotated_asm_lines.append(asm_line)
|
||||
asm_line_index += 1
|
||||
continue
|
||||
|
||||
if line_has_vram_addr(asm_line, vram_addr_str):
|
||||
break
|
||||
|
||||
should_append_asm_line = True
|
||||
if args.tu:
|
||||
asm_line_trimmed = asm_line.strip()
|
||||
|
||||
# track when we go in & out of function symbols
|
||||
if asm_line_trimmed.startswith(FUNCTION_SYMBOL_LABEL):
|
||||
function_count += 1
|
||||
is_in_function_label = True
|
||||
annotated_asm_lines.append(f"{UNIQUE_TEXT_SECTION_DIRECTIVE}{function_count}")
|
||||
annotated_asm_lines.append("")
|
||||
elif asm_line_trimmed.startswith(END_FUNCTION_SYMBOL_LABEL):
|
||||
is_in_function_label = False
|
||||
|
||||
# remove `nop`s
|
||||
if not is_in_function_label and asm_line_trimmed.endswith("nop"):
|
||||
should_append_asm_line = False
|
||||
|
||||
# remove `macro.inc` include directive
|
||||
elif asm_line_trimmed == INCLUDE_MACRO_INC_DIRECTIVE:
|
||||
should_append_asm_line = False
|
||||
|
||||
if should_append_asm_line:
|
||||
annotated_asm_lines.append(asm_line)
|
||||
|
||||
asm_line_index += 1
|
||||
|
||||
annotated_asm_lines.append(f"\t.loc 1 {current_line_number}")
|
||||
annotated_asm_lines.append(asm_line)
|
||||
asm_line_index += 1
|
||||
|
||||
prev_line_number = current_line_number
|
||||
current_vram_addr += 0x4
|
||||
|
||||
while asm_line_index < len(asm_lines) - 1:
|
||||
annotated_asm_lines.append(asm_lines[asm_line_index])
|
||||
asm_line_index += 1
|
||||
|
||||
assert main_tu_name, "no valid compilation unit found"
|
||||
annotated_asm_lines = [
|
||||
".section .debug",
|
||||
".previous",
|
||||
".text",
|
||||
f".file 1 \"{main_tu_name}\"",
|
||||
*annotated_asm_lines
|
||||
]
|
||||
|
||||
append_final_new_line(annotated_asm_lines)
|
||||
annotated_asm_contents = "\n".join(annotated_asm_lines)
|
||||
|
||||
if not args.stdout and args.out_path:
|
||||
with open(args.out_path, "w") as out_file:
|
||||
out_file.write(annotated_asm_contents)
|
||||
if args.verbose:
|
||||
print(f"alessatool/annotate: wrote asm to {args.out_path}")
|
||||
else:
|
||||
stdout.write(annotated_asm_contents)
|
||||
|
||||
def get_line_file_path(args: AnnotationArgs):
|
||||
if args.line_file_path is not None:
|
||||
return args.line_file_path
|
||||
|
||||
if args.elf_path.name == SH2_SERIAL and args.asm_path and "Event/stage" in args.asm_path.as_posix():
|
||||
return Path(f"{TOOLS}/alessatool/dwarf") / Path(args.asm_path.name).with_suffix(".line")
|
||||
|
||||
return None
|
||||
|
||||
def to_addr2line_format(compile_unit: str, line_number: int):
|
||||
return f"{compile_unit}:{line_number}"
|
||||
|
||||
def find_vram_bounds(asm_lines: list[str]):
|
||||
start = None
|
||||
passed_first_label = False
|
||||
end = None
|
||||
|
||||
for line in asm_lines:
|
||||
# assumes first address comment is on line after first label
|
||||
if "label" in line and not passed_first_label:
|
||||
passed_first_label = True
|
||||
continue
|
||||
|
||||
if passed_first_label and start is None:
|
||||
start = get_vram_addr_from_line(line)
|
||||
|
||||
# assumes .text section comes first
|
||||
if line.startswith(SECTION_DIRECTIVE) and not line.startswith(TEXT_SECTION_DIRECTIVE):
|
||||
break
|
||||
|
||||
vram_addr = get_vram_addr_from_line(line)
|
||||
if vram_addr is None:
|
||||
continue
|
||||
|
||||
end = vram_addr
|
||||
|
||||
return (start, end)
|
||||
|
||||
def get_vram_addr_from_line(line: str):
|
||||
if "/*" not in line:
|
||||
return None
|
||||
|
||||
_before_comment, after_comment = line.split("/* ", 1)
|
||||
_file_addr, vram_addr, _rest = after_comment.split(" ", 2)
|
||||
|
||||
try:
|
||||
return int(vram_addr, 0x10)
|
||||
except:
|
||||
return None
|
||||
|
||||
def line_has_vram_addr(line: str, addr_str: str) -> bool:
|
||||
if addr_str not in line or "*/" not in line:
|
||||
return False
|
||||
|
||||
return line.index("*/") > line.index(addr_str)
|
||||
|
||||
def append_final_new_line(lines: list[str]):
|
||||
if lines[-1] != "":
|
||||
lines.append("")
|
||||
Reference in New Issue
Block a user