/** * @file z_overlay.c * * Functions for handling transition overlays in memory */ #include "z64transition.h" #include "libu64/loadfragment.h" #include "z64lib.h" #include "zelda_arena.h" void* TransitionOverlay_VramToRam(TransitionOverlay* overlayEntry, void* vramAddr) { void* loadedRamAddr = Lib_PhysicalToVirtual(overlayEntry->loadInfo.addr); if ((loadedRamAddr != NULL) && (vramAddr >= overlayEntry->vramStart) && (vramAddr < overlayEntry->vramEnd)) { return (void*)(((uintptr_t)loadedRamAddr - (uintptr_t)overlayEntry->vramStart) + (uintptr_t)vramAddr); } return vramAddr; } void TransitionOverlay_VramToRamArray(TransitionOverlay* overlayEntry, void** vramAddrs, s32 count) { s32 i; for (i = 0; i < count; i++) { vramAddrs[i] = TransitionOverlay_VramToRam(overlayEntry, vramAddrs[i]); } } TransitionOverlayStatus TransitionOverlay_Load(TransitionOverlay* overlayEntry) { s32 count; void* loadedRamAddr; if (overlayEntry->file.vromStart == 0) { return TRANSITION_OVERLAY_STATUS_INTERNAL; } if (Lib_PhysicalToVirtual(overlayEntry->loadInfo.addr) == NULL) { loadedRamAddr = ZeldaArena_Malloc((uintptr_t)overlayEntry->vramEnd - (uintptr_t)overlayEntry->vramStart); if (loadedRamAddr == NULL) { return TRANSITION_OVERLAY_STATUS_FAILED; } Overlay_Load(overlayEntry->file.vromStart, overlayEntry->file.vromEnd, overlayEntry->vramStart, overlayEntry->vramEnd, loadedRamAddr); overlayEntry->loadInfo.addr = Lib_VirtualToPhysical(loadedRamAddr); overlayEntry->loadInfo.count = 1; return TRANSITION_OVERLAY_STATUS_LOAD_FREE; } count = overlayEntry->loadInfo.count; if (count != 0) { count++; overlayEntry->loadInfo.count = count; if (count == 0) { return TRANSITION_OVERLAY_STATUS_LOADED_NO_INSTANCES; } else { return TRANSITION_OVERLAY_STATUS_ADD_REMOVAL; } } return TRANSITION_OVERLAY_STATUS_LOADED_NO_INSTANCES; } TransitionOverlayStatus TransitionOverlay_Free(TransitionOverlay* overlayEntry) { s32 count; void* loadedRamAddr; if (overlayEntry->file.vromStart == 0) { return TRANSITION_OVERLAY_STATUS_INTERNAL; } loadedRamAddr = Lib_PhysicalToVirtual(overlayEntry->loadInfo.addr); if (loadedRamAddr != NULL) { count = overlayEntry->loadInfo.count; if (count != 0) { count--; overlayEntry->loadInfo.count = count; if (count == 0) { ZeldaArena_Free(loadedRamAddr); overlayEntry->loadInfo.addr = Lib_VirtualToPhysical(NULL); return TRANSITION_OVERLAY_STATUS_LOAD_FREE; } return TRANSITION_OVERLAY_STATUS_ADD_REMOVAL; } return TRANSITION_OVERLAY_STATUS_LOADED_NO_INSTANCES; } return TRANSITION_OVERLAY_STATUS_FAILED; } void TransitionOverlay_ClearLoadInfo(TransitionOverlay* overlayEntry) { overlayEntry->loadInfo.word = 0; // Equivalent to overlayEntry->loadInfo.count = 0, overlayEntry->loadInfo.addr = 0; } void TransitionOverlay_SetSegment(TransitionOverlay* overlayEntry, void* vramStart, void* vramEnd, uintptr_t vromStart, uintptr_t vromEnd) { overlayEntry->vramStart = vramStart; overlayEntry->vramEnd = vramEnd; overlayEntry->file.vromStart = vromStart; overlayEntry->file.vromEnd = vromEnd; }