diff --git a/configure.py b/configure.py index 86acf5752..50824ddae 100644 --- a/configure.py +++ b/configure.py @@ -543,7 +543,7 @@ def MatchingFor(*versions): Object(NonMatching, "SB/Core/gc/isavegame.cpp"), Object(NonMatching, "SB/Core/gc/iScrFX.cpp"), Object(NonMatching, "SB/Core/gc/iSnd.cpp"), - Object(NonMatching, "SB/Core/gc/iSystem.cpp"), + Object(NonMatching, "SB/Core/gc/iSystem.cpp", extra_cflags=["-sym on"]), Object(Matching, "SB/Core/gc/iTime.cpp"), Object(NonMatching, "SB/Core/gc/ngcrad3d.c"), Object(Matching, "SB/Game/zNPCGoals.cpp"), diff --git a/include/rwsdk/rwplcore.h b/include/rwsdk/rwplcore.h index bfa8af8b9..495b4dc3c 100644 --- a/include/rwsdk/rwplcore.h +++ b/include/rwsdk/rwplcore.h @@ -500,13 +500,13 @@ struct RwMemoryFunctions struct RwFreeList { - RwUInt32 entrySize; - RwUInt32 entriesPerBlock; - RwUInt32 heapSize; - RwUInt32 alignment; - RwLinkList blockList; - RwUInt32 flags; - RwLLLink link; + RwUInt32 entrySize; // 0x0 + RwUInt32 entriesPerBlock; // 0x4 + RwUInt32 heapSize; // 0x8 + RwUInt32 alignment; // 0xC + RwLinkList blockList; // 0x10 + RwUInt32 flags; // 0x18 + RwLLLink link; // 0x1C }; typedef void (*RwFreeListCallBack)(void* pMem, void* pData); @@ -1131,20 +1131,20 @@ typedef RwBool (*RwIm3DRenderIndexedPrimitiveFunction)(RwPrimitiveType primtype, struct RwDevice { - RwReal gammaCorrection; - RwSystemFunc fpSystem; - RwReal zBufferNear; - RwReal zBufferFar; - RwRenderStateSetFunction fpRenderStateSet; - RwRenderStateGetFunction fpRenderStateGet; - RwIm2DRenderLineFunction fpIm2DRenderLine; - RwIm2DRenderTriangleFunction fpIm2DRenderTriangle; - RwIm2DRenderPrimitiveFunction fpIm2DRenderPrimitive; - RwIm2DRenderIndexedPrimitiveFunction fpIm2DRenderIndexedPrimitive; - RwIm3DRenderLineFunction fpIm3DRenderLine; - RwIm3DRenderTriangleFunction fpIm3DRenderTriangle; - RwIm3DRenderPrimitiveFunction fpIm3DRenderPrimitive; - RwIm3DRenderIndexedPrimitiveFunction fpIm3DRenderIndexedPrimitive; + RwReal gammaCorrection; // 0x0 + RwSystemFunc fpSystem; // 0x4 + RwReal zBufferNear; // 0x8 + RwReal zBufferFar; // 0xC + RwRenderStateSetFunction fpRenderStateSet; // 0x10 + RwRenderStateGetFunction fpRenderStateGet; // 0x14 + RwIm2DRenderLineFunction fpIm2DRenderLine; // 0x18 + RwIm2DRenderTriangleFunction fpIm2DRenderTriangle; // 0x1C + RwIm2DRenderPrimitiveFunction fpIm2DRenderPrimitive; // 0x20 + RwIm2DRenderIndexedPrimitiveFunction fpIm2DRenderIndexedPrimitive; // 0x24 + RwIm3DRenderLineFunction fpIm3DRenderLine; // 0x28 + RwIm3DRenderTriangleFunction fpIm3DRenderTriangle; // 0x2C + RwIm3DRenderPrimitiveFunction fpIm3DRenderPrimitive; // 0x30 + RwIm3DRenderIndexedPrimitiveFunction fpIm3DRenderIndexedPrimitive; // 0x34 }; struct RwMetrics @@ -1202,22 +1202,22 @@ enum RwEngineStatus struct RwGlobals { - void* curCamera; - void* curWorld; - RwUInt16 renderFrame; - RwUInt16 lightFrame; - RwUInt16 pad[2]; - RwDevice dOpenDevice; - RwStandardFunc stdFunc[29]; - RwLinkList dirtyFrameList; - RwFileFunctions fileFuncs; - RwStringFunctions stringFuncs; - RwMemoryFunctions memoryFuncs; - RwMemoryAllocFn memoryAlloc; - RwMemoryFreeFn memoryFree; - RwMetrics* metrics; - RwEngineStatus engineStatus; - RwUInt32 resArenaInitSize; + void* curCamera; // 0x0 + void* curWorld; // 0x4 + RwUInt16 renderFrame; // 0x8 + RwUInt16 lightFrame; // 0xA + RwUInt16 pad[2]; // 0xC + RwDevice dOpenDevice; // 0x10 + RwStandardFunc stdFunc[29]; // 0x48 + RwLinkList dirtyFrameList; // 0xBC + RwFileFunctions fileFuncs; // 0xC4 + RwStringFunctions stringFuncs; // 0xF0 + RwMemoryFunctions memoryFuncs; // 0x134 + RwMemoryAllocFn memoryAlloc; // 0x144 + RwMemoryFreeFn memoryFree; // 0x148 + RwMetrics* metrics; // 0x14C + RwEngineStatus engineStatus; // 0x150 + RwUInt32 resArenaInitSize; // 0x154 }; typedef struct RwResEntry; diff --git a/src/SB/Core/gc/iSystem.cpp b/src/SB/Core/gc/iSystem.cpp index b8ef79e05..2c737a9fa 100644 --- a/src/SB/Core/gc/iSystem.cpp +++ b/src/SB/Core/gc/iSystem.cpp @@ -1,42 +1,29 @@ #include "iSystem.h" -#include "dolphin/dvd/dvd.h" -#include "dolphin/gx/GXFrameBuffer.h" -#include "dolphin/gx/GXManage.h" -#include "dolphin/gx/GXStruct.h" -#include "dolphin/hio.h" -#include "dolphin/os/OSError.h" -#include "dolphin/vi.h" -#include "rpcollis.h" -#include "rphanim.h" +#include + +#include + #include "rpmatfx.h" #include "rpptank.h" #include "rpskin.h" #include "rpusrdat.h" -#include "rpworld.h" -#include "rwplcore.h" -#include "xBase.h" -#include "xFX.h" -#include "xShadow.h" -#include "xstransvc.h" -#include -#include - -#include #include "xDebug.h" -#include "xMath.h" #include "xSnd.h" -#include "xPad.h" -#include "xMemMgr.h" +#include "xFX.h" +#include "xShadow.h" +#include "xstransvc.h" #include "iMemMgr.h" #include "iSystem.h" -#include "iFile.h" #include "iFMV.h" -#include "iTime.h" #include "iTRC.h" +// .bss +static RwMemoryFunctions MemoryFunctions; + +// .comm struct { GXRenderModeObj* renderMode; @@ -45,16 +32,23 @@ struct } deviceConfig; RwVideoMode sVideoMode; +// .sbss GXDrawSyncCallback old_dsc; U16 last_error; OSContext* last_context; -U32 size; U32 add; +U32 size; S32 gEmergencyMemLevel; + +// .sdata void* bad_val = (void*)0x81abcaa0; U32 test_alloc_val = 0x210A; +static S32 rwID_DOLPHINDEVICEMODULE = 0x430; -static RwMemoryFunctions MemoryFunctions; +static RwTexture* TextureRead(const RwChar* name, const RwChar* maskName); +static void* _rwDolphinFSOpen(void*, int, int); +static void* _rwDolphinFSClose(void*, int, int); +static S32 DolphinInstallFileSystem(); static const char* __deadstripped() { @@ -217,38 +211,35 @@ static U32 RWAttachPlugins() { if (!RpWorldPluginAttach()) { - return true; + return TRUE; } if (!RpCollisionPluginAttach()) { - return true; + return TRUE; } if (!RpSkinPluginAttach()) { - return true; + return TRUE; } if (!RpHAnimPluginAttach()) { - return true; + return TRUE; } if (!RpMatFXPluginAttach()) { - return true; + return TRUE; } if (!RpUserDataPluginAttach()) { - return true; + return TRUE; } if (!RpPTankPluginAttach()) { - return true; + return TRUE; } - return false; + return FALSE; } -static S32 DolphinInstallFileSystem(); -static RwTexture* TextureRead(const RwChar* name, const RwChar* maskName); - static S32 RenderWareInit() { RwMemoryFunctions* memoryFns = psGetMemoryFunctions(); @@ -280,7 +271,7 @@ static S32 RenderWareInit() return TRUE; } RwTextureSetReadCallBack(TextureRead); - RwRenderStateSet((RwRenderState)0x14, (void*)0x2); // RwRenderState 0x14 isn't defined?? + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLBACK); xShadowInit(); xFXInit(); RwTextureSetMipmapping(TRUE); @@ -314,7 +305,7 @@ static RwTexture* TextureRead(const RwChar* name, const RwChar* maskName) if (asset->raster != NULL && asset->raster->depth < 8) { RwGameCubeRasterExt* ext = - (RwGameCubeRasterExt*)((U32)asset->raster + _RwGameCubeRasterExtOffset); + RWPLUGINOFFSET(RwGameCubeRasterExt, asset->raster, _RwGameCubeRasterExtOffset); if (ext == NULL || ext->unk_c != 14) { asset = NULL; @@ -336,7 +327,7 @@ void null_func() } extern "C" { -void mem_null(U32 param_1, U32 param_2) +static void mem_null(U32 param_1, U32 param_2) { add = param_1; size = param_2; @@ -368,7 +359,7 @@ void free(void* __ptr) } } -void _rwDolphinHeapFree(void* __ptr) +static void _rwDolphinHeapFree(void* __ptr) { if (__ptr == bad_val) { @@ -392,7 +383,8 @@ void _rwDolphinHeapFree(void* __ptr) } } -void* _rwDolphinHeapAlloc(u32 size) +// non-matching: sda scheduling +static void* _rwDolphinHeapAlloc(u32 size) { static u32 alloc_num = 0; U32 alloc = (U32)malloc(size + 0x20); @@ -425,6 +417,473 @@ void* _rwDolphinHeapAlloc(u32 size) return (void*)alloc; } +static void* _rwDolphinHeapCalloc(u32 p1, u32 p2) +{ + void* __s = _rwDolphinHeapAlloc(p1 * p2); + if (__s != NULL) + { + memset(__s, 0, p1 * p2); + } + return __s; +} + +static void* _rwDolphinHeapRealloc(void* p1, u32 p2) +{ + u32 __n; + void* __dest; + + if (p1 != NULL) + __n = *(u32*)((u8*)p1 - 0x20); + else + __n = 0; + + if (p2 < __n) + return p1; + + __dest = _rwDolphinHeapAlloc(p2); + if (__dest != NULL) + { + if (__n < p2) + memcpy(__dest, p1, __n); + else + memcpy(__dest, p1, p2); + _rwDolphinHeapFree(p1); + } + return __dest; +} + +S32 DolphinInitMemorySystem(RwMemoryFunctions* memoryFuncs) +{ + memoryFuncs->rwmalloc = _rwDolphinHeapAlloc; + memoryFuncs->rwcalloc = _rwDolphinHeapCalloc; + memoryFuncs->rwrealloc = _rwDolphinHeapRealloc; + memoryFuncs->rwfree = _rwDolphinHeapFree; + + return 1; +} + +static S32 dlAccessToMode(const char* mode) +{ + char c; + S32 ret = 0; + + if (mode == 0) + { + return 0; + } + + c = mode[0]; + + if (c == 'r' && (mode[1] == '\0' || (mode[1] == 'b' && mode[2] == '\0'))) + { + ret = 1; + } + else if (c == 'w' && (mode[1] == '\0' || (mode[1] == 'b' && mode[2] == '\0'))) + { + ret = 0xe; + } + else if (c == 'a' && (mode[1] == '\0' || (mode[1] == 'b' && mode[2] == '\0'))) + { + ret = 6; + } + else if (c == 'r' && mode[1] == '+' && (mode[2] == '\0' || (mode[2] == 'b' && mode[3] == '\0'))) + { + ret = 3; + } + else if (c == 'w' && mode[1] == '+' && (mode[2] == '\0' || (mode[2] == 'b' && mode[3] == '\0'))) + { + ret = 0xf; + } + else if (c == 'a' && mode[1] == '+' && (mode[2] == '\0' || (mode[2] == 'b' && mode[3] == '\0'))) + { + ret = 7; + } + + return ret; +} + +// both need to be after alloc_num from _rwDolphinHeapAlloc +static S32 FSOpenFiles; +struct RwModuleInfo +{ + s32 globalsOffset; + s32 numInstances; +}; +static RwModuleInfo FSModuleInfo; // Type only exists in PS2 dwarf, symbol only exists on GC + +void* dlFopen(const char* name, const char* access) +{ + U32 mode = dlAccessToMode(access); + if (mode == 0) + { + return NULL; + } + + dlFile* fp = (dlFile*)RwEngineInstance->memoryAlloc( + RWPLUGINOFFSET(dlFSUnkGlobals, RwEngineInstance, FSModuleInfo.globalsOffset)->unk_2C); + if (fp == NULL) + { + return NULL; + } + + fp->accessMode = 0; + if (mode == 1) + { + fp->accessMode = 1; + } + + if (fp->accessMode == 0) + { + RwEngineInstance->memoryFree( + RWPLUGINOFFSET(dlFSUnkGlobals, RwEngineInstance, FSModuleInfo.globalsOffset)->unk_2C, + fp); + return NULL; + } + + if (DVDOpen(name, &fp->fileInfo) == 0) + { + RwEngineInstance->memoryFree( + RWPLUGINOFFSET(dlFSUnkGlobals, RwEngineInstance, FSModuleInfo.globalsOffset)->unk_2C, + fp); + return NULL; + } + + fp->SOF = fp->fileInfo.length; + fp->POS = 0; + fp->bufferPos = DLFILE_BUF_SIZE; + FSOpenFiles++; + return fp; +} + +static S32 dlFclose(void* fptr) +{ + dlFile* fp = (dlFile*)fptr; + + if (fp != NULL && FSOpenFiles != 0 && DVDClose(&fp->fileInfo) != 0) + { + RwEngineInstance->memoryFree( + RWPLUGINOFFSET(dlFSUnkGlobals, RwEngineInstance, FSModuleInfo.globalsOffset)->unk_2C, + fp); + + FSOpenFiles--; + return 0; + } + return -1; +} + +static RwBool dlFexist(const char* name) +{ + void* fp; + + fp = ((void* (*)(const char*, const char*))((void**)RwOsGetFileInterface())[1])(name, "r"); + + if (fp != 0) + { + ((void (*)(void*))((void**)RwOsGetFileInterface())[2])(fp); + return true; + } + + return false; +} + +// non-matching: r25/r26/r27 register issue +static size_t dlFread(void* addr, size_t size, size_t count, void* fptr) +{ + S32 pos2; + S32 posTmp; + S32 bytesRead = 0; + S32 readSize; + U32 buffered; + U32 uVar1; + dlFile* fp = (dlFile*)fptr; + U32 numBytesToRead = size * count; + + if ((U32)(fp->POS + numBytesToRead) > fp->SOF) + { + numBytesToRead = fp->SOF - fp->POS; + } + if (fp->bufferPos < DLFILE_BUF_SIZE) + { + if (numBytesToRead > bytesRead) + { + buffered = DLFILE_BUF_SIZE - fp->bufferPos; + if (numBytesToRead < buffered) + { + buffered = numBytesToRead; + } + bytesRead = buffered; + memcpy(addr, fp->readBuffer + fp->bufferPos, buffered); + addr = (char*)addr + buffered; + fp->bufferPos += buffered; + fp->POS += buffered; + } + } + uVar1 = numBytesToRead - bytesRead; + if (uVar1 != 0) + { + if (uVar1 >= DLFILE_BUF_SIZE) + { + if (!((U32)addr & 0x1f) && !(uVar1 & 0x1f)) + { + uVar1 = DVDReadPrio(&fp->fileInfo, addr, uVar1, fp->POS, 2); + if ((S32)uVar1 < 0) + { + uVar1 = 0; + } + } + else + { + numBytesToRead -= bytesRead; + uVar1 = 0; + posTmp = fp->POS; + S32 loopCount = (S32)numBytesToRead / DLFILE_BUF_SIZE + 1; + while (loopCount-- != 0) + { + pos2 = fp->POS; + readSize = DLFILE_BUF_SIZE; + pos2 += uVar1; + if ((S32)(fp->SOF - pos2) <= DLFILE_BUF_SIZE) + { + readSize = (fp->SOF - pos2); + } + if (DVDReadPrio(&fp->fileInfo, fp->readBuffer, ((U32)readSize + 0x1f) & ~0x1f, + posTmp, 2) == -1) + { + return bytesRead + uVar1; + } + if ((S32)numBytesToRead >= readSize) + { + memcpy(addr, fp->readBuffer, readSize); + numBytesToRead -= readSize; + uVar1 += readSize; + posTmp += readSize; + addr = (char*)addr + readSize; + } + else + { + memcpy(addr, fp->readBuffer, numBytesToRead); + fp->bufferPos = numBytesToRead; + uVar1 += numBytesToRead; + posTmp += numBytesToRead; + } + } + } + } + else + { + buffered = ((U32)(fp->SOF - fp->POS) + 0x1f) & ~0x1f; + if ((S32)buffered > DLFILE_BUF_SIZE) + { + buffered = DLFILE_BUF_SIZE; + } + if (DVDReadPrio(&fp->fileInfo, fp->readBuffer, buffered, fp->POS, 2) == -1) + { + return bytesRead; + } + memcpy(addr, fp->readBuffer, uVar1); + fp->bufferPos = uVar1; + } + bytesRead += uVar1; + fp->POS += uVar1; + } + return bytesRead / size; +} + +static size_t dlFwrite(const void* addr, size_t size, size_t count, void* fptr) +{ + return 0; +} + +static S32 dlFseek(void* fptr, long offset, int origin) +{ + S32 oldFPos = ((dlFile*)fptr)->POS; + dlFile* fp = (dlFile*)fptr; + S32 bufStart; + + switch (origin) + { + case 1: + { + fp->POS = oldFPos + offset; + if ((S32)(fp->bufferPos + offset) >= 0 && (fp->bufferPos + offset) <= DLFILE_BUF_SIZE && + fp->POS <= fp->SOF) + { + fp->bufferPos += offset; + return 0; + } + break; + } + case 2: + { + S32 delta = (fp->POS = fp->SOF + offset) - oldFPos; + if ((S32)(fp->bufferPos + delta) >= 0 && (fp->bufferPos + delta) <= DLFILE_BUF_SIZE && + fp->POS <= fp->SOF) + { + fp->bufferPos += delta; + return 0; + } + break; + } + case 0: + { + fp->POS = offset; + S32 delta = offset - oldFPos; + if ((S32)(fp->bufferPos + delta) >= 0 && (fp->bufferPos + delta) <= DLFILE_BUF_SIZE && + fp->POS <= fp->SOF) + { + fp->bufferPos += delta; + return 0; + } + break; + } + default: + { + return -1; + } + } + + if (fp->POS > fp->SOF) + { + fp->POS = oldFPos; + return -1; + } + + bufStart = (fp->POS / (U32)DLFILE_BUF_SIZE) * DLFILE_BUF_SIZE; + + if (DVDReadPrio(&fp->fileInfo, fp->readBuffer, + (fp->SOF - bufStart <= DLFILE_BUF_SIZE) ? (fp->SOF - bufStart + 31) & ~31 : + DLFILE_BUF_SIZE, + bufStart, 2) == -1) + { + fp->POS = oldFPos; + return -1; + } + + fp->bufferPos = fp->POS - bufStart; + return 0; +} + +// non-matching: mr, subi, and li scheduling at the start +static char* dlFgets(char* buffer, S32 maxLen, void* fptr) +{ + dlFile* fp = (dlFile*)fptr; + S32 i; + S32 numBytesRead; + i = 0; + numBytesRead = dlFread(buffer, 1, maxLen - 1, fp); + if (numBytesRead == 0) + return NULL; + while (i < numBytesRead) + { + if (buffer[i] == '\n') + { + i++; + buffer[i] = '\0'; + i -= numBytesRead; + dlFseek(fp, i, 1); + return buffer; + } + if (buffer[i] == '\r') + { + if ((i < numBytesRead - 1) && (buffer[i + 1] == '\n')) + { + memcpy(&buffer[i], &buffer[i + 1], (numBytesRead - i) - 1); + numBytesRead--; + } + else + { + i++; + } + } + else + { + i++; + } + } + if ((numBytesRead < maxLen) && (fp->POS == fp->SOF)) + { + buffer[numBytesRead] = '\0'; + } + return buffer; +} + +static S32 dlFputs(const char* buffer, void* fptr) +{ + return -1; +} + +static S32 dlFeof(void* fptr) +{ + dlFile* fp = (dlFile*)fptr; + return fp->POS >= fp->SOF; +} + +static S32 dlFflush(void*) +{ + return 0; +} + +static S32 dlFtell(void* fptr) +{ + dlFile* fp = (dlFile*)fptr; + return fp->POS; +} + +static void* _rwDolphinFSOpen(void* param_1, int param_2, int param_3) +{ + FSModuleInfo.globalsOffset = param_2; + + RWPLUGINOFFSET(dlFSUnkGlobals, RwEngineInstance, FSModuleInfo.globalsOffset)->unk_2C = + RwFreeListCreate(sizeof(dlFile), 5, 0x20); + + if (RWPLUGINOFFSET(dlFSUnkGlobals, RwEngineInstance, FSModuleInfo.globalsOffset)->unk_2C == + NULL) + { + return NULL; + } + + RwFileFunctions* funcs = RwOsGetFileInterface(); + RWPLUGINOFFSET(dlFSUnkGlobals, RwEngineInstance, FSModuleInfo.globalsOffset)->fileFuncs = + *funcs; + + funcs->rwfexist = dlFexist; + funcs->rwfopen = dlFopen; + funcs->rwfclose = dlFclose; + funcs->rwfread = dlFread; + funcs->rwfwrite = dlFwrite; + funcs->rwfgets = dlFgets; + funcs->rwfputs = dlFputs; + funcs->rwfeof = dlFeof; + funcs->rwfseek = dlFseek; + funcs->rwfflush = dlFflush; + funcs->rwftell = dlFtell; + + FSModuleInfo.numInstances++; + + return param_1; +} + +static void* _rwDolphinFSClose(void* param_1, int param_2, int param_3) +{ + RwFileFunctions* osFileInterface = RwOsGetFileInterface(); + *osFileInterface = + (RWPLUGINOFFSET(dlFSUnkGlobals, RwEngineInstance, FSModuleInfo.globalsOffset))->fileFuncs; + RwFreeListDestroy( + (RWPLUGINOFFSET(dlFSUnkGlobals, RwEngineInstance, FSModuleInfo.globalsOffset))->unk_2C); + + FSModuleInfo.numInstances--; + + return param_1; +} + +static S32 DolphinInstallFileSystem() +{ + DVDInit(); + RwUInt32 plugin = + RwEngineRegisterPlugin(0x30, rwID_DOLPHINDEVICEMODULE, _rwDolphinFSOpen, _rwDolphinFSClose); + return plugin >> 0x1f ^ 1; +} + S32 iGetMinute() { OSTime ticks = OSGetTime(); @@ -457,36 +916,93 @@ S32 iGetMonth() return td.mon + 1; } -// Template for future use. TODO -char* iGetCurrFormattedDate(char* input) +char* months[] = { "January ", "February ", "March ", "April ", "May ", "June ", + "July ", "August ", "September ", "October ", "November ", "December " }; + +char* dotw[] = { + "Sunday ", "Monday ", "Tuesday ", "Wednesday ", "Thursday ", "Friday ", "Saturday " +}; + +U32 iGetCurrFormattedDate(char* str) { - return NULL; + char* start = str; + OSTime ticks = OSGetTime(); + OSCalendarTime td; + + OSTicksToCalendarTime(ticks, &td); + + strcpy(str, dotw[td.wday]); + strcat(str, months[td.mon]); + str += strlen(str); + + if (td.mday >= 10) + { + *str++ = (td.mday / 10) + '0'; + } + + *str++ = (td.mday % 10) + '0'; + *str++ = ','; + *str++ = ' '; + *str++ = (td.year / 1000) + '0'; + *str++ = ((td.year / 100) % 10) + '0'; + *str++ = ((td.year / 10) % 100) + '0'; + *str++ = (td.year % 10) + '0'; + *str++ = '\0'; + + return str - start; } -// WIP. -char* iGetCurrFormattedTime(char* input) +U32 iGetCurrFormattedTime(char* str) { + char* start = str; + S32 am = 0; + OSTime ticks = OSGetTime(); OSCalendarTime td; OSTicksToCalendarTime(ticks, &td); - bool pm = false; - // STUFF. - char* ret = input; - // STUFF. - if (pm) + + if (td.hour < 12) + { + am = 1; + } + else + { + td.hour -= 12; + } + + if (td.hour == 0) + td.hour = 12; + + if (td.hour >= 10) + { + *str++ = (td.hour / 10) + '0'; + } + + *str++ = (td.hour % 10) + '0'; + *str++ = ':'; + *str++ = (td.min / 10) + '0'; + *str++ = (td.min % 10) + '0'; + *str++ = ':'; + *str++ = (td.sec / 10) + '0'; + *str++ = (td.sec % 10) + '0'; + *str++ = ' '; + + if (am) { - ret[8] = 'P'; - ret[9] = '.'; - ret[10] = 'M'; - ret[11] = '.'; + *str++ = 'A'; + *str++ = '.'; + *str++ = 'M'; + *str++ = '.'; } else { - ret[8] = 'A'; - ret[9] = '.'; - ret[10] = 'M'; - ret[11] = '.'; + *str++ = 'P'; + *str++ = '.'; + *str++ = 'M'; + *str++ = '.'; } - ret[12] = '\0'; - return ret + (0xd - (S32)input); + + *str++ = '\0'; + + return str - start; } diff --git a/src/SB/Core/gc/iSystem.h b/src/SB/Core/gc/iSystem.h index 881f99963..14a5a1b1f 100644 --- a/src/SB/Core/gc/iSystem.h +++ b/src/SB/Core/gc/iSystem.h @@ -1,6 +1,7 @@ #ifndef ISYSTEM_H #define ISYSTEM_H +#include "rwplcore.h" #include #include @@ -9,6 +10,24 @@ void* malloc(U32 __size); void free(void* __ptr); } +#define DLFILE_BUF_SIZE 0x2800 + +struct dlFile // fabricated based on skyFile dwarf +{ + U8 readBuffer[DLFILE_BUF_SIZE]; // 0x00 + DVDFileInfo fileInfo; // 0x2800 + S32 POS; // 0x283C + U32 SOF; // 0x2840 + U32 bufferPos; // 0x2844 + S32 accessMode; // 0x2848 +}; + +struct dlFSUnkGlobals // entirely fabricated +{ + RwFileFunctions fileFuncs; // 0x00 + RwFreeList* unk_2C; // 0x2C +}; + void iVSync(); #define GET_MAKER_CODE() (*((U32*)0x80000004)) diff --git a/src/SB/Core/gc/iTime.h b/src/SB/Core/gc/iTime.h index e73b7483f..d2e03a4bf 100644 --- a/src/SB/Core/gc/iTime.h +++ b/src/SB/Core/gc/iTime.h @@ -22,8 +22,8 @@ S32 iGetMinute(); S32 iGetHour(); S32 iGetDay(); S32 iGetMonth(); -char* iGetCurrFormattedDate(char* input); -char* iGetCurrFormattedTime(char* input); +U32 iGetCurrFormattedDate(char* input); +U32 iGetCurrFormattedTime(char* input); void iTimeInit(); void iTimeExit(); iTime iTimeGet();