#include #include #define KALEIDO_OVERLAY(name) \ { \ NULL, (u32)_ovl_##name##SegmentRomStart, (u32)_ovl_##name##SegmentRomEnd, _ovl_##name##SegmentStart, \ _ovl_##name##SegmentEnd, 0, #name, \ } KaleidoManagerOvl gKaleidoMgrOverlayTable[] = { KALEIDO_OVERLAY(kaleido_scope), KALEIDO_OVERLAY(player_actor), }; void* sKaleidoAreaPtr = NULL; KaleidoManagerOvl* gKaleidoMgrCurOvl = NULL; u32 D_8012D1E0 = 0; void KaleidoManager_LoadOvl(KaleidoManagerOvl* ovl) { LogUtils_CheckNullPointer("KaleidoArea_allocp", sKaleidoAreaPtr, "../z_kaleido_manager.c", 99); ovl->loadedRamAddr = sKaleidoAreaPtr; Overlay_Load(ovl->vromStart, ovl->vromEnd, ovl->vramStart, ovl->vramEnd, ovl->loadedRamAddr); osSyncPrintf(VT_FGCOL(GREEN)); osSyncPrintf("OVL(k):Seg:%08x-%08x Ram:%08x-%08x Off:%08x %s\n", ovl->vramStart, ovl->vramEnd, ovl->loadedRamAddr, ((u32)ovl->loadedRamAddr + ovl->vramEnd) - (u32)ovl->vramStart, (u32)ovl->vramStart - (u32)ovl->loadedRamAddr, ovl->name); osSyncPrintf(VT_RST); ovl->off = (u32)ovl->loadedRamAddr - (u32)ovl->vramStart; gKaleidoMgrCurOvl = ovl; } void KaleidoManager_ClearOvl(KaleidoManagerOvl* ovl) { if (ovl->loadedRamAddr) { ovl->off = 0; bzero(ovl->loadedRamAddr, ovl->vramEnd - (u32)ovl->vramStart); ovl->loadedRamAddr = NULL; gKaleidoMgrCurOvl = NULL; } } void KaleidoManager_Init(GlobalContext* globalCtx) { s32 largestOvl; s32 vramSize; u32 idx; largestOvl = 0; for (idx = 0; idx < ARRAY_COUNT(gKaleidoMgrOverlayTable); idx++) { vramSize = gKaleidoMgrOverlayTable[idx].vramEnd - (u32)gKaleidoMgrOverlayTable[idx].vramStart; if (largestOvl < vramSize) { largestOvl = vramSize; } } osSyncPrintf(VT_FGCOL(GREEN)); osSyncPrintf("KaleidoArea の最大サイズは %d バイトを確保します\n", largestOvl); osSyncPrintf(VT_RST); sKaleidoAreaPtr = GameState_Alloc(&globalCtx->state, largestOvl, "../z_kaleido_manager.c", 150); LogUtils_CheckNullPointer("KaleidoArea_allocp", sKaleidoAreaPtr, "../z_kaleido_manager.c", 151); osSyncPrintf(VT_FGCOL(GREEN)); osSyncPrintf("KaleidoArea %08x - %08x\n", sKaleidoAreaPtr, (u32)sKaleidoAreaPtr + largestOvl); osSyncPrintf(VT_RST); gKaleidoMgrCurOvl = 0; } void KaleidoManager_Destroy() { if (gKaleidoMgrCurOvl) { KaleidoManager_ClearOvl(gKaleidoMgrCurOvl); gKaleidoMgrCurOvl = NULL; } sKaleidoAreaPtr = NULL; } // NOTE: this function looks messed up and probably doesn't work like how the devs wanted it to work void* KaleidoManager_GetRamAddr(void* vram) { KaleidoManagerOvl* iter; KaleidoManagerOvl* ovl; u32 idx; iter = gKaleidoMgrCurOvl; ovl = iter; if (!ovl) { iter = &gKaleidoMgrOverlayTable[0]; for (idx = 0; idx != ARRAY_COUNT(gKaleidoMgrOverlayTable); idx++) { if ((u32)vram >= (u32)iter->vramStart && (u32)iter->vramEnd >= (u32)vram) { KaleidoManager_LoadOvl(iter); ovl = iter; goto KaleidoManager_GetRamAddr_end; } // BUG: devs probably forgot iter++ here } osSyncPrintf("異常\n"); // Abnormal return NULL; } KaleidoManager_GetRamAddr_end: if (!ovl || (u32)vram < (u32)ovl->vramStart || (u32)vram >= (u32)ovl->vramEnd) { return NULL; } return (void*)((u32)vram + ovl->off); }