From 7eff38a5f9f968994a964501d39232a312e6cb22 Mon Sep 17 00:00:00 2001 From: petrie911 <69443847+petrie911@users.noreply.github.com> Date: Wed, 8 May 2024 13:57:11 -0500 Subject: [PATCH] Add quick boot and add ram editing to object ram watch (#236) * upgrades * one cleanup * streamlining * whoops mods * more ub * cast cleanup --- .vscode/settings.json | 4 +- include/mods.h | 9 + src/audio/audio_heap.c | 6 +- src/audio/audio_load.c | 2 +- src/engine/fox_demo.c | 2 +- src/engine/fox_display.c | 14 -- src/engine/fox_game.c | 34 ++++ src/engine/fox_play.c | 1 - src/libc_sprintf.c | 8 +- src/mods/levelselect.c | 7 +- src/mods/object_ram.c | 410 +++++++++++++++++++++++---------------- src/mods/object_ram.h | 96 +++++++++ src/sys/sys_fault.c | 4 +- 13 files changed, 399 insertions(+), 198 deletions(-) create mode 100644 src/mods/object_ram.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 5c687cb9..8d3a478f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -143,7 +143,9 @@ "os_motor.h": "c", "os_pfs.h": "c", "semaphore": "c", - "bgm.h": "c" + "bgm.h": "c", + "*.tcc": "c", + "object_ram.h": "c" }, "C_Cpp_Runner.msvcBatchPath": "" } \ No newline at end of file diff --git a/include/mods.h b/include/mods.h index 9c463869..232bfb7c 100644 --- a/include/mods.h +++ b/include/mods.h @@ -1,6 +1,15 @@ #ifndef MODS_H #define MODS_H +/** + * Quick Boot: + * Define this variable to a game state to boot into that + * state. Two presets (map and main menu) are provided. + * For the full list of game states, see sf64thread.h. +*/ +// #define MODS_BOOT_STATE 3 // main menu +// #define MODS_BOOT_STATE 4 // map + /** * Level Select: * Use the D-Pad to select a level. Press L to start in diff --git a/src/audio/audio_heap.c b/src/audio/audio_heap.c index a7bb79e9..a0ccd63e 100644 --- a/src/audio/audio_heap.c +++ b/src/audio/audio_heap.c @@ -464,15 +464,15 @@ void* AudioHeap_SearchRegularCaches(s32 tableType, s32 cache, s32 id) { switch (tableType) { case SEQUENCE_TABLE: - loadedCache = (AudioCache*) &gSeqCache; + loadedCache = &gSeqCache; break; case FONT_TABLE: - loadedCache = (AudioCache*) &gFontCache; + loadedCache = &gFontCache; break; case SAMPLE_TABLE: - loadedCache = (AudioCache*) &gSampleBankCache; + loadedCache = &gSampleBankCache; break; } diff --git a/src/audio/audio_load.c b/src/audio/audio_load.c index 7cf8671e..dc4a23ca 100644 --- a/src/audio/audio_load.c +++ b/src/audio/audio_load.c @@ -737,7 +737,7 @@ void* AudioLoad_AsyncLoadInner(s32 tableType, s32 id, s32 nChunks, s32 retData, ramAddr = AudioLoad_SearchCaches(tableType, id); if (ramAddr != NULL) { loadStatus = 2; - osSendMesg(retQueue, (void*) (retData << 0x18), OS_MESG_NOBLOCK); + osSendMesg(retQueue, (OSMesg) (retData << 0x18), OS_MESG_NOBLOCK); } else { table = AudioLoad_GetLoadTable(tableType); size = table->entries[id].size; diff --git a/src/engine/fox_demo.c b/src/engine/fox_demo.c index ebc2a85c..f3efc421 100644 --- a/src/engine/fox_demo.c +++ b/src/engine/fox_demo.c @@ -2823,7 +2823,7 @@ void ActorCutscene_Draw(Actor* actor) { sp2B8.y = 0.0f; sp2B8.z = 40.0f; - Matrix_MultVec3fNoTranslate(gCalcMatrix, (Vec3f*) (&sp2B8), &sp2AC); + Matrix_MultVec3fNoTranslate(gCalcMatrix, &sp2B8, &sp2AC); Matrix_Translate(gGfxMatrix, actor->obj.pos.x + sp2AC.x, actor->obj.pos.y + sp2AC.y, actor->obj.pos.z + sp2AC.z, MTXF_APPLY); Matrix_Scale(gGfxMatrix, actor->fwork[6], actor->fwork[6], actor->fwork[6], MTXF_APPLY); diff --git a/src/engine/fox_display.c b/src/engine/fox_display.c index e725bd51..99a85e1d 100644 --- a/src/engine/fox_display.c +++ b/src/engine/fox_display.c @@ -1,4 +1,3 @@ -#include "mods.h" #include "global.h" #include "assets/ast_arwing.h" #include "assets/ast_allies.h" @@ -1738,17 +1737,4 @@ void Play_Draw(void) { func_display_80051B30(); sPlayersVisible[gPlayerNum] = 0; Matrix_Pop(&gGfxMatrix); -#if MODS_FPS_COUNTER == 1 - Play_RenderFps(); -#endif -#if MODS_OBJECT_RAM == 1 - ObjectRam_Update(); -#endif } - -#if MODS_FPS_COUNTER == 1 -#include "../mods/fpscounter.c" -#endif -#if MODS_OBJECT_RAM == 1 -#include "../mods/object_ram.c" -#endif diff --git a/src/engine/fox_game.c b/src/engine/fox_game.c index 5c9769f7..3852212e 100644 --- a/src/engine/fox_game.c +++ b/src/engine/fox_game.c @@ -2,6 +2,7 @@ #include "global.h" #include "sf64dma.h" #include "assets/ast_logo.h" +#include "mods.h" f32 D_game_80161A10; f32 D_game_80161A14; @@ -54,6 +55,18 @@ void Game_Initialize(void) { Rand_Init(); Rand_SetSeed(1, 29000, 9876); gGameState = GSTATE_BOOT; +#ifdef MODS_BOOT_STATE + gNextGameState = GSTATE_INIT; + if (Save_Read() != 0) { +#ifdef AVOID_UB + gSaveFile.save = gDefaultSave; + gSaveFile.backup = gDefaultSave; +#else + gSaveFile = *((SaveFile*) &gDefaultSave); +#endif + Save_Write(); + } +#endif gNextGameStateTimer = 0; gBgColor = 0; gBlurAlpha = 255; @@ -361,7 +374,12 @@ void Game_Update(void) { break; case GSTATE_CHECK_SAVE: if (Save_Read() != 0) { +#ifdef AVOID_UB + gSaveFile.save = gDefaultSave; + gSaveFile.backup = gDefaultSave; +#else gSaveFile = *((SaveFile*) &gDefaultSave); +#endif Save_Write(); } gGameState++; @@ -396,6 +414,9 @@ void Game_Update(void) { gFillScreenAlpha = 0; gNextGameState = D_ctx_80177C94 = D_ctx_80177CAC = D_ctx_80177CB4 = D_ctx_80177CBC = D_ctx_80177CC4 = D_ctx_80177C9C = D_ctx_80177CA4 = D_play_80161A5C = D_game_80161A34 = 0; +#ifdef MODS_BOOT_STATE + gNextGameState = MODS_BOOT_STATE; +#endif for (i = 0; i < 4; i++) { gBoostButton[i] = L_CBUTTONS; gBrakeButton[i] = D_CBUTTONS; @@ -553,9 +574,22 @@ void Game_Update(void) { gFillScreenGreen, gFillScreenBlue, gFillScreenAlpha); } Audio_dummy_80016A50(); +#if MODS_OBJECT_RAM == 1 + ObjectRam_Update(); +#endif +#if MODS_FPS_COUNTER == 1 + Play_RenderFps(); +#endif } } +#if MODS_FPS_COUNTER == 1 +#include "../mods/fpscounter.c" +#endif +#if MODS_OBJECT_RAM == 1 +#include "../mods/object_ram.c" +#endif + Actor* Game_SpawnActor(ObjectId objId) { Actor* actor = gActors; s32 i; diff --git a/src/engine/fox_play.c b/src/engine/fox_play.c index a07a6f01..617a6412 100644 --- a/src/engine/fox_play.c +++ b/src/engine/fox_play.c @@ -1374,7 +1374,6 @@ bool Play_CheckPolyCollision(ObjectId objId, f32 arg1, f32 arg2, f32 arg3, f32 a return false; } -// arg5 could be Vec3f (not Vec3f*) s32 Player_CheckPolyCollision(Player* player, ObjectId objId, f32 arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, f32 arg7) { Vec3f sp84; diff --git a/src/libc_sprintf.c b/src/libc_sprintf.c index 0b2e506f..7fd93154 100644 --- a/src/libc_sprintf.c +++ b/src/libc_sprintf.c @@ -2,12 +2,12 @@ char D_800C7C80[] = "$Id: sprintf.c,v 1.5 1997/03/19 02:28:53 hayakawa Exp $"; -void* proutSprintf(void* dst, const char* fmt, size_t size) { - return (void*) ((uintptr_t) memcpy(dst, fmt, size) + size); +char* proutSprintf(char* dst, const char* fmt, size_t size) { + return (char*) ((uintptr_t) memcpy(dst, fmt, size) + size); } s32 vsprintf(char* dst, const char* fmt, va_list args) { - s32 ret = _Printf((outfun*) proutSprintf, dst, fmt, args); + s32 ret = _Printf(proutSprintf, dst, fmt, args); if (ret > -1) { dst[ret] = 0; @@ -20,7 +20,7 @@ int sprintf(char* s, const char* fmt, ...) { va_list args; va_start(args, fmt); - ret = _Printf((outfun*) proutSprintf, s, fmt, args); + ret = _Printf(proutSprintf, s, fmt, args); if (ret >= 0) { s[ret] = 0; diff --git a/src/mods/levelselect.c b/src/mods/levelselect.c index 941b8d8f..1a515339 100644 --- a/src/mods/levelselect.c +++ b/src/mods/levelselect.c @@ -45,7 +45,7 @@ void Map_LevelSelect(void) { if (difficulty > 2) { difficulty = 0; } - if ((difficulty == 1) && ((mission == 1) || (mission == 5))) { + if ((difficulty == 1) && ((mission == 1) || (mission == 5) || (mission == 6))) { difficulty = 2; } } else if ((gControllerPress[0].button & D_JPAD) && (mission != 0)) { @@ -84,7 +84,7 @@ void Map_LevelSelect(void) { } else if (sCurrentPlanetId == PLANET_VENOM) { Graphics_DisplaySmallText(80, 210, 1.0f, 1.0f, "ANDROSS"); } else if (sCurrentPlanetId == PLANET_AREA_6) { - Graphics_DisplaySmallText(80, 210, 1.0f, 1.0f, "UNKNOWN 4"); + Graphics_DisplaySmallText(80, 210, 1.0f, 1.0f, "BETA SB"); } } } @@ -97,8 +97,7 @@ void Map_LevelSelect(void) { } else if (sPlanetArray[mission][difficulty] == SAVE_SLOT_VENOM_2) { gCurrentLevel = LEVEL_VENOM_2; } - } - if (startOption && (sCurrentPlanetId == PLANET_AREA_6)) { + } else if ((sCurrentPlanetId == PLANET_AREA_6) && startOption) { gCurrentLevel = LEVEL_UNK_4; } Map_801A61B4(gCurrentLevel); diff --git a/src/mods/object_ram.c b/src/mods/object_ram.c index 6816444b..4fa55fe3 100644 --- a/src/mods/object_ram.c +++ b/src/mods/object_ram.c @@ -1,81 +1,39 @@ -#include "global.h" - -typedef struct RamEntry { - u8 type; - u8 index; - s16 offset; - u8 width; - u8 fmt; - u16 x; - u16 y; -} RamEntry; +#include "object_ram.h" static RamEntry oRamEntries[7] = { - { 1, 0, offsetof(Player, pos.x), 2, 3, 0, 0 }, { 1, 0, offsetof(Player, pos.y), 2, 3, 0, 0 }, - { 1, 0, offsetof(Player, pos.z), 2, 3, 0, 0 }, { 0, 0, offsetof(Player, zPath), 2, 3, 0, 0 }, - { 0, 0, offsetof(Player, vel.x), 2, 3, 0, 0 }, { 0, 0, offsetof(Player, vel.y), 2, 3, 0, 0 }, - { 0, 0, offsetof(Player, vel.z), 2, 3, 0, 0 }, + ORAM_ENTRY(PlayerShot, 15, obj.id, u8), + ORAM_ENTRY(Player, 0, pos.y, f32), + ORAM_ENTRY(Player, 0, pos.z, f32), + ORAM_ENTRY(Actor, 0, obj.status, x32), + ORAM_OFF, + ORAM_OFF, + ORAM_OFF, }; -static u32 selectIndex = 0; -static s32 oRamActive = 0; -static u32 editMode = 0; -static s32 editing = 0; +static u32 selectNum = 0; +static s32 oRamActive = true; +static u32 editMode = EDM_TYPE; +static s32 editing = false; +static s32 editingValue = false; +static fu dataTemp; static OSContPad* contPress; +static OSContPad* contHold; -typedef enum ObjectRamType { - ORAM_NONE, - ORAM_PLAYER, - ORAM_SCENE360, - ORAM_SCENERY, - ORAM_SPRITE, - ORAM_ACTOR, - ORAM_BOSS, - ORAM_ITEM, - ORAM_EFFECT, - ORAM_SHOT, - ORAM_MAX, -} ObjectRamType; - -typedef enum EditMode { - EDM_TYPE, - EDM_OFFSET, - EDM_FORMAT, - EDM_POS, - EDM_MAX, -} EditMode; - -typedef enum FormatType { - FMT_HEX, - FMT_SIGN, - FMT_UNSIGN, - FMT_FLOAT, - FMT_MAX, -} FormatType; - -#define WRAP_MODE(val, max) ((u8) ((val) + (max)) % max) - -static void* objPointers[] = { NULL, NULL, NULL, gScenery, gSprites, gActors, gBosses, gItems, gEffects, gPlayerShots }; -static size_t objSizes[] = { 0, - sizeof(Player), - sizeof(Scenery360), - sizeof(Scenery), - sizeof(Sprite), - sizeof(Actor), - sizeof(Boss), - sizeof(Item), - sizeof(Effect), - sizeof(PlayerShot) }; -static s32 objCounts[] = { 1, - 1, - 200, - ARRAY_COUNT(gScenery), - ARRAY_COUNT(gSprites), - ARRAY_COUNT(gActors), - ARRAY_COUNT(gBosses), - ARRAY_COUNT(gItems), - ARRAY_COUNT(gEffects), - ARRAY_COUNT(gPlayerShots) }; +static ObjArrayInfo objArrays[] = { + { NULL, 0, 1, "--" }, + { NULL, sizeof(Player), 1, "PL" }, + { NULL, sizeof(Scenery360), 200, "SC" }, + OBJ_ARRAY_INFO(gScenery, "SC"), + OBJ_ARRAY_INFO(gSprites, "SP"), + OBJ_ARRAY_INFO(gActors, "AC"), + OBJ_ARRAY_INFO(gBosses, "BS"), + OBJ_ARRAY_INFO(gItems, "IT"), + OBJ_ARRAY_INFO(gEffects, "EF"), + OBJ_ARRAY_INFO(gPlayerShots, "SH"), + OBJ_ARRAY_INFO(gTexturedLines, "TL"), + OBJ_ARRAY_INFO(gRadarMarks, "RM"), + OBJ_ARRAY_INFO(gBonusText, "BT"), +}; void ObjectRam_EditPosition(RamEntry* entry) { if ((contPress->button & U_JPAD) && (entry->y > 0)) { @@ -92,90 +50,124 @@ void ObjectRam_EditPosition(RamEntry* entry) { void ObjectRam_EditObject(RamEntry* entry) { if (contPress->button & U_JPAD) { entry->type++; - if ((entry->type == ORAM_SCENE360) && (gLevelMode != LEVELMODE_ALL_RANGE)) { - entry->type = ORAM_SCENERY; - } else if ((entry->type == ORAM_SCENERY) && (gLevelClearScreenTimer == LEVELMODE_ALL_RANGE)) { - entry->type = ORAM_SPRITE; + if ((entry->type == ORAM_Scenery360) && (gLevelMode != LEVELMODE_ALL_RANGE)) { + entry->type = ORAM_Scenery; + } else if ((entry->type == ORAM_Scenery) && (gLevelMode == LEVELMODE_ALL_RANGE)) { + entry->type = ORAM_Sprite; } } else if (contPress->button & D_JPAD) { entry->type--; - if ((entry->type == ORAM_SCENE360) && (gLevelMode != LEVELMODE_ALL_RANGE)) { - entry->type = ORAM_PLAYER; - } else if ((entry->type == ORAM_SCENERY) && (gLevelClearScreenTimer == LEVELMODE_ALL_RANGE)) { - entry->type = ORAM_SCENE360; + if ((entry->type == ORAM_Scenery360) && (gLevelMode != LEVELMODE_ALL_RANGE)) { + entry->type = ORAM_Player; + } else if ((entry->type == ORAM_Scenery) && (gLevelMode == LEVELMODE_ALL_RANGE)) { + entry->type = ORAM_Scenery360; } } entry->type = WRAP_MODE(entry->type, ORAM_MAX); - if (entry->type == 0) { - return; - } - if (entry->index >= objCounts[entry->type]) { - entry->index = objCounts[entry->type] - 1; - } - if (entry->offset >= objSizes[entry->type]) { - entry->offset = objSizes[entry->type] - (1 << entry->width); - } - if (contPress->button & L_JPAD) { - entry->index--; - } else if (contPress->button & R_JPAD) { +} + +void ObjectRam_EditIndex(RamEntry* entry) { + ObjArrayInfo* objInfo = &objArrays[entry->type]; + + entry->index = MIN(entry->index, objInfo->count - 1); + + if (contPress->button & U_JPAD) { entry->index++; + } else if (contPress->button & D_JPAD) { + entry->index--; } - entry->index = WRAP_MODE(entry->index, objCounts[entry->type]); + entry->index = WRAP_MODE(entry->index, objInfo->count); } void ObjectRam_EditFormat(RamEntry* entry) { + if (contPress->button & U_JPAD) { + entry->fmt--; + } else if (contPress->button & D_JPAD) { + entry->fmt++; + } + entry->fmt = WRAP_MODE(entry->fmt, FMT_MAX); + if (entry->fmt == FMT_FLOAT) { + entry->width = 2; + entry->offset &= ~((1 << entry->width) - 1); + } +} + +void ObjectRam_EditWidth(RamEntry* entry) { if ((contPress->button & U_JPAD) && (entry->width < 2)) { entry->width++; } else if ((contPress->button & D_JPAD) && (entry->width > 0)) { entry->width--; - } else if (contPress->button & L_JPAD) { - entry->fmt--; - } else if (contPress->button & R_JPAD) { - entry->fmt++; } - entry->fmt = WRAP_MODE(entry->fmt, FMT_MAX); if (entry->fmt == FMT_FLOAT) { entry->width = 2; } entry->offset &= ~((1 << entry->width) - 1); } -void ObjectRam_EditAddress(RamEntry* entry) { - if (contPress->button & U_JPAD) { - entry->offset += 0x10; - } else if (contPress->button & D_JPAD) { - entry->offset -= 0x10; - } else if (contPress->button & L_JPAD) { - entry->offset -= 1 << entry->width; - } else if (contPress->button & R_JPAD) { - entry->offset += 1 << entry->width; - } else if (contPress->button & R_TRIG) { - entry->offset += 0x100; - } else if (contPress->button & Z_TRIG) { - entry->offset -= 0x100; +void ObjectRam_EditOffset(RamEntry* entry) { + s32 inc; + ObjArrayInfo* objInfo = &objArrays[entry->type]; + + entry->offset = MIN(entry->offset, objInfo->size - (1 << entry->width)); + + if (contHold->button & Z_TRIG) { + inc = 0x10; + } else if (contHold->button & R_TRIG) { + inc = 0x100; + } else { + inc = 1 << entry->width; + } + inc *= (contPress->button & D_JPAD) ? -1 : 1; + if (contPress->button & (U_JPAD | D_JPAD)) { + entry->offset += inc; } if (entry->offset < 0) { entry->offset = 0; - } else if (entry->offset >= objSizes[entry->type]) { - entry->offset = objSizes[entry->type] - (1 << entry->width); + } else if (entry->offset >= objInfo->size) { + entry->offset = objInfo->size - (1 << entry->width); + } +} + +void ObjectRam_EditValue(RamEntry* entry) { + fu* data = entry->dataPtr; + s32 inc; + + if (contHold->button & Z_TRIG) { + inc = (entry->fmt == FMT_HEX) ? 0x10 : 10; + } else if (contHold->button & R_TRIG) { + inc = (entry->fmt == FMT_HEX) ? 0x100 : 100; + } else { + inc = 1; + } + inc *= (contPress->button & D_JPAD) ? -1 : 1; + + if (contPress->button & (U_JPAD | D_JPAD)) { + if (!editingValue) { + dataTemp.i = ObjectRam_GetData(entry); + editingValue = true; + } + if (entry->fmt == FMT_FLOAT) { + dataTemp.f += inc; + } else { + dataTemp.i += inc; + } } } void ObjectRam_Select(void) { - if (contPress->button & U_JPAD) { - selectIndex--; - } else if (contPress->button & D_JPAD) { - selectIndex++; + if ((contPress->button & U_JPAD) && !editing) { + selectNum--; + } else if ((contPress->button & D_JPAD) && !editing) { + selectNum++; } else if (contPress->button & L_JPAD) { editMode--; } else if (contPress->button & R_JPAD) { editMode++; - ; } - selectIndex = WRAP_MODE(selectIndex, ARRAY_COUNT(oRamEntries)); + selectNum = WRAP_MODE(selectNum, ARRAY_COUNT(oRamEntries)); editMode = WRAP_MODE(editMode, EDM_MAX); - if (oRamEntries[selectIndex].type == ORAM_NONE) { + if (oRamEntries[selectNum].type == ORAM_NONE) { editMode = EDM_TYPE; } } @@ -183,103 +175,154 @@ void ObjectRam_Select(void) { u32 ObjectRam_GetData(RamEntry* entry) { fu data; uintptr_t ptr; + s32 offset; + s32 index; if ((entry->type <= ORAM_NONE) || (entry->type >= ORAM_MAX)) { return 0; } - ptr = (uintptr_t) objPointers[entry->type] + entry->index * objSizes[entry->type]; switch (entry->width) { case 0: - data.i = *((u8*) (ptr + entry->offset)); + data.i = *((u8*) entry->dataPtr); if ((entry->fmt == FMT_SIGN) && (data.i >= 0x80)) { data.i -= 0x80; } break; case 1: - data.i = *((u16*) (ptr + entry->offset)); + data.i = *((u16*) entry->dataPtr); if ((entry->fmt == FMT_SIGN) && (data.i >= 0x8000)) { data.i -= 0x8000; } break; case 2: if (entry->fmt == FMT_FLOAT) { - data.f = *((f32*) (ptr + entry->offset)); + data.f = *((f32*) entry->dataPtr); } else { - data.i = *((u32*) (ptr + entry->offset)); + data.i = *((u32*) entry->dataPtr); } break; } return data.i; } -static char* objTypes[] = { "NONE", "PLYR", "S360", "SCEN", "SPRT", "ACTR", "BOSS", "ITEM", "EFCT", "SHOT" }; +void ObjectRam_WriteValue(RamEntry* entry) { + switch (entry->width) { + case 0: + *((u8*) entry->dataPtr) = dataTemp.i; + break; + case 1: + *((u16*) entry->dataPtr) = dataTemp.i; + break; + case 2: + if (entry->fmt == FMT_FLOAT) { + *((f32*) entry->dataPtr) = dataTemp.f; + } else { + *((u32*) entry->dataPtr) = dataTemp.i; + } + break; + } +} + +static char* objTypes[] = { "--", "PL", "SC", "SC", "SP", "AC", "BS", "IT", "EF", "SH", "TL", "RM", "BT" }; static char* fmtTypes[] = { "X", "S", "U", "F" }; #define SET_DRAW_COLOR(mode) \ - if ((index == selectIndex) && (editMode == mode)) { \ - if (editing) { \ + if (num == selectNum) { \ + if (editing && (editMode == mode)) { \ gDPSetPrimColor(gMasterDisp++, 0, 0, 255, 0, 0, 255); \ + } else if (editing || (editMode == mode)) { \ + gDPSetPrimColor(gMasterDisp++, 0, 0, 255, 85, 0, 255); \ } else { \ - gDPSetPrimColor(gMasterDisp++, 0, 0, 255, 128, 0, 255); \ + gDPSetPrimColor(gMasterDisp++, 0, 0, 255, 170, 0, 255); \ } \ } else { \ gDPSetPrimColor(gMasterDisp++, 0, 0, 255, 255, 0, 255); \ } -void ObjectRam_DrawEntry(RamEntry* entry, s32 index) { +void ObjectRam_DrawEntry(RamEntry* entry, s32 num) { fu data; - s32 y = entry->y + 50 + 27 * index; + s32 x = entry->x; + s32 y = entry->y + 50 + 27 * num; + s32 i; + s32 offset; + s32 index; + ObjArrayInfo* objInfo; - SET_DRAW_COLOR(EDM_TYPE) - Graphics_DisplaySmallText(entry->x + 10, y, 1.0f, 1.0f, objTypes[entry->type]); - - if (entry->type == 0) { + if ((entry->type < ORAM_NONE) || (entry->type >= ORAM_MAX)) { return; } - Graphics_Printf("%2d", entry->index); - Graphics_DisplaySmallText(entry->x + 45, y, 1.0f, 1.0f, D_801619A0); - SET_DRAW_COLOR(EDM_OFFSET) - Graphics_Printf("%03X", entry->offset); - Graphics_DisplaySmallText(entry->x + 70, y, 1.0f, 1.0f, D_801619A0); - SET_DRAW_COLOR(EDM_FORMAT) - Graphics_DisplaySmallText(entry->x + 10, y + 10, 1.0f, 1.0f, fmtTypes[entry->fmt]); - Graphics_Printf("%-2d", 1 << (entry->width + 3)); - Graphics_DisplaySmallText(entry->x + 20, y + 10, 1.0f, 1.0f, D_801619A0); + objInfo = &objArrays[entry->type]; - if (index == selectIndex) { - gDPSetPrimColor(gMasterDisp++, 0, 0, 255, 192, 0, 255); + offset = MIN(entry->offset, objInfo->size - (1 << entry->width)); + index = MIN(entry->index, objInfo->count - 1); + + entry->objPtr = (uintptr_t) objInfo->ptr + index * objInfo->size; + entry->dataPtr = (uintptr_t) entry->objPtr + offset; + + SET_DRAW_COLOR(EDM_TYPE) + Graphics_DisplaySmallText(x + 10, y, 1.0f, 1.0f, objInfo->name); + + if (entry->type == ORAM_NONE) { + return; + } + SET_DRAW_COLOR(EDM_MAX) + Graphics_DisplaySmallText(x + 26, y, 1.0f, 1.0f, "-"); + + SET_DRAW_COLOR(EDM_INDEX) + Graphics_Printf("%02d", index); + Graphics_DisplaySmallText(entry->x + 32, y, 1.0f, 1.0f, D_801619A0); + + SET_DRAW_COLOR(EDM_MAX) + Graphics_DisplaySmallText(x + 50, y, 1.0f, 1.0f, "."); + + SET_DRAW_COLOR(EDM_OFFSET) + Graphics_Printf("%03X", offset); + Graphics_DisplaySmallText(entry->x + 56, y, 1.0f, 1.0f, D_801619A0); + + SET_DRAW_COLOR(EDM_FORMAT) + Graphics_DisplaySmallText(x + 90, y, 1.0f, 1.0f, fmtTypes[entry->fmt]); + SET_DRAW_COLOR(EDM_WIDTH) + Graphics_Printf("%-2d", 1 << (entry->width + 3)); + Graphics_DisplaySmallText(x + 100, y, 1.0f, 1.0f, D_801619A0); + + SET_DRAW_COLOR(EDM_VALUE) + if ((num != selectNum) || !editingValue) { + data.i = ObjectRam_GetData(entry); + } else if (entry->fmt == FMT_FLOAT) { + data.f = dataTemp.f; } else { - gDPSetPrimColor(gMasterDisp++, 0, 0, 255, 255, 0, 255); + data.i = dataTemp.i; } - data.i = ObjectRam_GetData(entry); switch (entry->fmt) { case FMT_HEX: - Graphics_Printf("%0*X", 1 << (entry->width + 1), data.i); + Graphics_Printf("0X%0*X", 1 << (entry->width + 1), data.i); + x += (8 - (1 << (entry->width + 1))) * 9; break; case FMT_SIGN: - Graphics_Printf("%d", data.i); + Graphics_Printf("%10d", data.i); break; case FMT_UNSIGN: - Graphics_Printf("%u", data.i); + Graphics_Printf("%10u", data.i); break; case FMT_FLOAT: Graphics_Printf("%10.2f", data.f); break; } - Graphics_DisplaySmallText(entry->x + 40, y + 10, 1.0f, 1.0f, D_801619A0); + Graphics_DisplaySmallText(x + 25, y + 12, 1.0f, 1.0f, D_801619A0); } -static char* omStr[] = { "OBJECT", "OFFSET", "FORMAT", "POSITION" }; +// static char* omStr[] = { "OBJECT", "INDEX", "OFFSET", "FORMAT", "WIDTH", "VALUE" }; // "POSITION" }; void ObjectRam_Update(void) { s32 i; - objPointers[ORAM_PLAYER] = gPlayer; - objPointers[ORAM_SCENE360] = gScenery360; - objCounts[ORAM_PLAYER] = gCamCount; + objArrays[ORAM_Player].ptr = gPlayer; + objArrays[ORAM_Scenery360].ptr = gScenery360; + objArrays[ORAM_Player].count = gCamCount; contPress = &gControllerPress[gMainController]; + contHold = &gControllerHold[gMainController]; if ((gPlayState == PLAY_PAUSE) && (contPress->button & R_CBUTTONS)) { oRamActive = 1 - oRamActive; @@ -290,22 +333,37 @@ void ObjectRam_Update(void) { if (contPress->button & L_TRIG) { editing ^= 1; } - if (!editing) { - ObjectRam_Select(); - } else { + + ObjectRam_Select(); + + if (editingValue && !(editing && (editMode == EDM_VALUE))) { + ObjectRam_WriteValue(&oRamEntries[selectNum]); + editingValue = false; + } + + if (editing) { switch (editMode) { - case 0: - ObjectRam_EditObject(&oRamEntries[selectIndex]); + case EDM_TYPE: + ObjectRam_EditObject(&oRamEntries[selectNum]); break; - case 1: - ObjectRam_EditAddress(&oRamEntries[selectIndex]); + case EDM_INDEX: + ObjectRam_EditIndex(&oRamEntries[selectNum]); break; - case 2: - ObjectRam_EditFormat(&oRamEntries[selectIndex]); + case EDM_OFFSET: + ObjectRam_EditOffset(&oRamEntries[selectNum]); break; - case 3: - ObjectRam_EditPosition(&oRamEntries[selectIndex]); + case EDM_FORMAT: + ObjectRam_EditFormat(&oRamEntries[selectNum]); break; + case EDM_WIDTH: + ObjectRam_EditWidth(&oRamEntries[selectNum]); + break; + case EDM_VALUE: + ObjectRam_EditValue(&oRamEntries[selectNum]); + break; + // case EDM_POS: + // ObjectRam_EditPosition(&oRamEntries[selectNum]); + // break; } } RCP_SetupDL(&gMasterDisp, 0x4C); @@ -314,4 +372,22 @@ void ObjectRam_Update(void) { for (i = 0; i < ARRAY_COUNT(oRamEntries); i++) { ObjectRam_DrawEntry(&oRamEntries[i], i); } + + if ((oRamEntries[selectNum].type > ORAM_Player) && (oRamEntries[selectNum].type < ORAM_TexturedLine)) { + gTexturedLines[99].mode = 3; + gTexturedLines[99].xyScale = 3.0f; + gTexturedLines[99].posAA.x = gPlayer[0].pos.x; + gTexturedLines[99].posAA.y = gPlayer[0].pos.y; + gTexturedLines[99].posAA.z = gPlayer[0].pos.z - 100.0f; + if (oRamEntries[selectNum].objPtr->status != OBJ_FREE) { + gTexturedLines[99].timer = 15; + } + gTexturedLines[99].red = 255; + gTexturedLines[99].green = (editing) ? 128 : 255; + gTexturedLines[99].blue = 0; + gTexturedLines[99].alpha = 255; + gTexturedLines[99].posBB.x = oRamEntries[selectNum].objPtr->pos.x; + gTexturedLines[99].posBB.y = oRamEntries[selectNum].objPtr->pos.y; + gTexturedLines[99].posBB.z = oRamEntries[selectNum].objPtr->pos.z; + } } diff --git a/src/mods/object_ram.h b/src/mods/object_ram.h new file mode 100644 index 00000000..540919d3 --- /dev/null +++ b/src/mods/object_ram.h @@ -0,0 +1,96 @@ +#ifndef OBJECT_RAM_H +#define OBJECT_RAM_H + +#include "global.h" + +#define ORAM_ENTRY(struct, index, field, format) \ + { ORAM_##struct, index, offsetof(struct, field), NULL, 0, FMT_##format, WIDTH_##format, 0, 0 } +#define ORAM_OFF \ + { 0, 0, 0, 0, 0, 0, 0, 0, 0 } + +#define WRAP_MODE(val, max) ((u8) ((val) + (max)) % max) + +#define OBJ_ARRAY_INFO(objarr, name) \ + { objarr, sizeof(*objarr), ARRAY_COUNT(objarr), name } + +typedef struct ObjArrayInfo { + void* ptr; + size_t size; + s32 count; + char* name; +} ObjArrayInfo; + +typedef struct RamEntry { + u8 type; + u8 index; + s16 offset; + Object* objPtr; + void* dataPtr; + u8 fmt; + u8 width; + u16 x; + u16 y; +} RamEntry; + +typedef enum ObjectRamType { + ORAM_NONE, + ORAM_Player, + ORAM_Scenery360, + ORAM_Scenery, + ORAM_Sprite, + ORAM_Actor, + ORAM_Boss, + ORAM_Item, + ORAM_Effect, + ORAM_PlayerShot, + ORAM_TexturedLine, + ORAM_RadarMark, + ORAM_BonusText, + ORAM_MAX, +} ObjectRamType; + +typedef enum FormatType { + FMT_HEX, + FMT_SIGN, + FMT_UNSIGN, + FMT_FLOAT, + FMT_MAX, +} FormatType; + +typedef enum EditMode { + EDM_TYPE, + EDM_INDEX, + EDM_OFFSET, + EDM_FORMAT, + EDM_WIDTH, + EDM_VALUE, + // EDM_POS, + EDM_MAX, +} EditMode; + +#define FMT_f32 FMT_FLOAT +#define WIDTH_f32 2 +#define FMT_s32 FMT_SIGN +#define WIDTH_s32 2 +#define FMT_u32 FMT_UNSIGN +#define WIDTH_u32 2 +#define FMT_x32 FMT_HEX +#define WIDTH_x32 2 + +#define FMT_s16 FMT_SIGN +#define WIDTH_s16 1 +#define FMT_u16 FMT_UNSIGN +#define WIDTH_u16 1 +#define FMT_x16 FMT_HEX +#define WIDTH_x16 1 + +#define FMT_s8 FMT_SIGN +#define WIDTH_s8 0 +#define FMT_u8 FMT_UNSIGN +#define WIDTH_u8 0 +#define FMT_x8 FMT_HEX +#define WIDTH_x8 0 + +u32 ObjectRam_GetData(RamEntry* entry); + +#endif diff --git a/src/sys/sys_fault.c b/src/sys/sys_fault.c index c4144236..11745831 100644 --- a/src/sys/sys_fault.c +++ b/src/sys/sys_fault.c @@ -90,7 +90,7 @@ void func_800074AC(s32 arg0, s32 arg1, s32 arg2) { } } -void* func_80007604(void* arg0, const char* arg1, size_t arg2) { +char* func_80007604(char* arg0, const char* arg1, size_t arg2) { return (char*) memcpy(arg0, arg1, arg2) + arg2; } @@ -106,7 +106,7 @@ void func_8000762C(s32 arg0, s32 arg1, const char* fmt, ...) { sp40[i] = 0; } - if (_Printf((outfun*) func_80007604, sp40, fmt, args) <= 0) { + if (_Printf(func_80007604, sp40, fmt, args) <= 0) { return; } for (var_s0 = sp40; *var_s0 != 0; var_s0++) {