diff --git a/CMakeLists.txt b/CMakeLists.txt index 2057fcdcb2..bdfd4978ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,8 @@ elseif (APPLE) elseif (MSVC) add_compile_options(/bigobj) add_compile_options(/Zc:strictStrings-) + add_compile_options(/MP) + add_compile_options(/W0) endif () if (NOT MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error -Wno-c++11-narrowing") @@ -1353,14 +1355,15 @@ set(DUSK_FILES src/dusk/globals.cpp src/dusk/mtx.cpp src/dusk/J3DTransforms_C.cpp - src/dusk/m_Do_ext_dusk.cpp + #src/dusk/m_Do_ext_dusk.cpp src/dusk/jsystem_stubs.cpp - src/m_Do/m_Do_main.cpp # TODO: move this to a more appropriate location, it's not really dusk-specific + src/dusk/dvd_emu.cpp ) source_group("dolzel" FILES ${DOLZEL_FILES} ${Z2AUDIOLIB_FILES} ${SSYSTEM_FILES} ${JSYSTEM_FILES} ${REL_FILES}) source_group("dusk" FILES ${DUSK_FILES}) +set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) add_library(game SHARED ${DOLZEL_FILES} ${Z2AUDIOLIB_FILES} ${SSYSTEM_FILES} ${JSYSTEM_FILES} ${REL_FILES} ${DUSK_FILES}) target_compile_definitions(game PRIVATE TARGET_PC VERSION=0 NDEBUG=1 NDEBUG_DEFINED=1 DEBUG_DEFINED=0) # TODO: version handling for res includes diff --git a/include/dusk/dvd_emu.h b/include/dusk/dvd_emu.h new file mode 100644 index 0000000000..8366b2b37b --- /dev/null +++ b/include/dusk/dvd_emu.h @@ -0,0 +1,45 @@ +#ifndef DOLPHIN_DVD_EMU_H +#define DOLPHIN_DVD_EMU_H + +#include "dolphin/types.h" +#include + +// PC-Emulation der DVD-Funktionen +namespace DvdEmu { + +// Basis-Pfad zum Datenordner (relativ zur .exe) +void setBasePath(const char* path); +const char* getBasePath(); + +// Konvertiert GameCube-Pfad zu PC-Pfad +// z.B. "/res/Object/LogoUs.arc" -> "C:/Games/Dusk/data/res/Object/LogoUs.arc" +std::string convertPath(const char* gcPath); + +// Prüft ob Datei existiert +bool fileExists(const char* gcPath); + +// Lädt Datei komplett in Speicher +// Gibt Pointer zurück, Größe wird in outSize geschrieben +// Caller muss Speicher mit free() freigeben +void* loadFile(const char* gcPath, u32* outSize, void* heap = nullptr); + +// Lädt Datei in vorhandenen Buffer +// Gibt gelesene Bytes zurück +u32 loadFileToBuffer(const char* gcPath, void* buffer, u32 bufferSize, u32 offset = 0); + +// Datei-Größe abfragen +u32 getFileSize(const char* gcPath); + +} // namespace DvdEmu + +// Ersatz für DVDConvertPathToEntrynum +// Gibt einen "Fake" Entry-Number zurück (Hash des Pfads) oder -1 wenn nicht gefunden +s32 DVDConvertPathToEntrynum_Emu(const char* path); + +// Speichert Pfad für Entry-Number (für späteres Laden) +void DVDRegisterPath(s32 entryNum, const char* path); + +// Holt Pfad für Entry-Number +const char* DVDGetPathForEntry(s32 entryNum); + +#endif // DOLPHIN_DVD_EMU_H diff --git a/include/dusk/endian.h b/include/dusk/endian.h new file mode 100644 index 0000000000..25e5df70ff --- /dev/null +++ b/include/dusk/endian.h @@ -0,0 +1,57 @@ +#ifndef DOLPHIN_ENDIAN_H +#define DOLPHIN_ENDIAN_H + +#include "dolphin/types.h" + +// Platform detection - Little Endian targets +#if defined(_WIN32) || defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || defined(_M_X64) || defined(_M_IX86) + #define TARGET_LITTLE_ENDIAN 1 +#else + #define TARGET_LITTLE_ENDIAN 0 +#endif + +#if TARGET_LITTLE_ENDIAN + #ifdef _MSC_VER + #include + #define BSWAP16(x) _byteswap_ushort(x) + #define BSWAP32(x) _byteswap_ulong(x) + #else + #define BSWAP16(x) __builtin_bswap16(x) + #define BSWAP32(x) __builtin_bswap32(x) + #endif +#else + #define BSWAP16(x) (x) + #define BSWAP32(x) (x) +#endif + +// Big-Endian to Host conversion +inline u16 be16(u16 val) { return BSWAP16(val); } +inline s16 be16s(s16 val) { return (s16)BSWAP16((u16)val); } +inline u32 be32(u32 val) { return BSWAP32(val); } + +inline s32 be32s(s32 val) { return (s32)BSWAP32((u32)val); } + +#ifdef TARGET_PC +// Helper wrappers so code below reads nicely: +static inline u16 RES_U16(u16 v) { + return be16(v); +} +static inline s16 RES_S16(s16 v) { + return be16s(v); +} +static inline u32 RES_U32(u32 v) { + return be32(v); +} +static inline s32 RES_S32(s32 v) { + return be32s(v); +} +#else +// On GameCube host-endian == file-endian, these are no-ops (keep as macros to allow compile in +// original code paths) +#define RES_U16(x) (x) +#define RES_S16(x) (x) +#define RES_U32(x) (x) +#define RES_S32(x) (x) +#endif + +#endif // DOLPHIN_ENDIAN_H diff --git a/src/JSystem/JKernel/JKRHeap.cpp b/src/JSystem/JKernel/JKRHeap.cpp index 720166455a..2ebafc2613 100644 --- a/src/JSystem/JKernel/JKRHeap.cpp +++ b/src/JSystem/JKernel/JKRHeap.cpp @@ -8,8 +8,15 @@ #include "JSystem/JKernel/JKRHeap.h" #include "JSystem/JUtility/JUTAssert.h" #include "JSystem/JUtility/JUTException.h" +#ifdef __MWERKS__ #include +#else +#include +#include +#include +#endif #include +#include #if DEBUG u8 JKRValue_DEBUGFILL_NOTUSE = 0xFD; @@ -95,12 +102,28 @@ JKRHeap::JKRFreeCallback JKRHeap::sFreeCallback; bool JKRHeap::initArena(char** memory, u32* size, int maxHeaps) { void* arenaLo = OSGetArenaLo(); void* arenaHi = OSGetArenaHi(); -#if !PLATFORM_GCN - OSReport("original arenaLo = %p arenaHi = %p\n", arenaLo, arenaHi); -#endif + + OSReport("[JKRHeap] initArena: Lo=%p Hi=%p Size=0x%X\n", arenaLo, arenaHi, + (uintptr_t)arenaHi - (uintptr_t)arenaLo); + if (arenaLo == arenaHi) return false; +#ifdef TARGET_PC + // PC: Simple arena setup without GameCube-specific memory management + arenaLo = (void*)ALIGN_NEXT((uintptr_t)arenaLo, 0x20); + arenaHi = (void*)ALIGN_PREV((uintptr_t)arenaHi, 0x20); + + mCodeStart = nullptr; + mCodeEnd = nullptr; + mUserRamStart = arenaLo; + mUserRamEnd = arenaHi; + mMemorySize = (uintptr_t)arenaHi - (uintptr_t)arenaLo; + + *memory = (char*)arenaLo; + *size = (uintptr_t)arenaHi - (uintptr_t)arenaLo; + return true; +#else arenaLo = OSInitAlloc(arenaLo, arenaHi, maxHeaps); arenaLo = (void*)ALIGN_NEXT((uintptr_t)arenaLo, 0x20); arenaHi = (void*)ALIGN_PREV((uintptr_t)arenaHi, 0x20); @@ -119,6 +142,7 @@ bool JKRHeap::initArena(char** memory, u32* size, int maxHeaps) { *memory = (char*)arenaLo; *size = (uintptr_t)arenaHi - (uintptr_t)arenaLo; return true; +#endif } #if PLATFORM_WII || PLATFORM_SHIELD @@ -468,37 +492,113 @@ bool JKRHeap::isSubHeap(JKRHeap* heap) const { return false; } +#ifdef __MWERKS__ void* operator new(size_t size) { return JKRHeap::alloc(size, 4, NULL); } +#else +void* operator new(size_t size) { + if (JKRHeap::sCurrentHeap == NULL) { + return malloc(size); + } + void* mem = JKRHeap::alloc(size, 4, NULL); + if (mem == NULL) { + OSReport("[NEW] JKRHeap FULL! Fallback to malloc for size %u\n", (unsigned)size); + mem = malloc(size); + } + return mem; +} +#endif +#ifdef __MWERKS__ void* operator new(size_t size, int alignment) { return JKRHeap::alloc(size, alignment, NULL); } +#else +void* operator new(size_t size, int alignment) { + if (JKRHeap::sCurrentHeap == nullptr) + return _aligned_malloc(size, alignment); + void* mem = JKRHeap::alloc(size, alignment, nullptr); + if (mem == nullptr) { + OSReport("[NEW] JKRHeap FULL! Fallback to aligned_malloc size %u\n", (unsigned)size); + return _aligned_malloc(size, alignment); + } + return mem; +} +#endif void* operator new(size_t size, JKRHeap* heap, int alignment) { return JKRHeap::alloc(size, alignment, heap); } +#ifdef __MWERKS__ void* operator new[](size_t size) { return JKRHeap::alloc(size, 4, NULL); } +#else +void* operator new[](size_t size) { + if (JKRHeap::sCurrentHeap == NULL) + return malloc(size); + void* mem = JKRHeap::alloc(size, 4, NULL); + if (mem == NULL) { + mem = malloc(size); + } + return mem; +} +#endif +#ifdef __MWERKS__ void* operator new[](size_t size, int alignment) { return JKRHeap::alloc(size, alignment, NULL); } +#else +void* operator new[](size_t size, int alignment) { + if (JKRHeap::sCurrentHeap == nullptr) + return _aligned_malloc(size, alignment); + void* mem = JKRHeap::alloc(size, alignment, nullptr); + if (mem == nullptr) + return _aligned_malloc(size, alignment); + return mem; +} +#endif void* operator new[](size_t size, JKRHeap* heap, int alignment) { return JKRHeap::alloc(size, alignment, heap); } +#ifdef __MWERKS__ void operator delete(void* ptr) { JKRHeap::free(ptr, NULL); } +#else +void operator delete(void* ptr) { + if (ptr == NULL) + return; + JKRHeap* heap = JKRHeap::findFromRoot(ptr); + if (heap == NULL) { + free(ptr); + return; + } + JKRHeap::free(ptr, NULL); +} +#endif +#ifdef __MWERKS__ void operator delete[](void* ptr) { JKRHeap::free(ptr, NULL); } +#else +void operator delete[](void* ptr) { + if (ptr == NULL) + return; + JKRHeap* heap = JKRHeap::findFromRoot(ptr); + if (heap == NULL) { + free(ptr); + return; + } + JKRHeap::free(ptr, NULL); +} +#endif s32 fillcheck_dispcount = 100; bool data_8074A8D0_debug = true; diff --git a/src/d/actor/d_a_obj_ss_base.cpp b/src/d/actor/d_a_obj_ss_base.cpp index 92db022b60..3279a88b3e 100644 --- a/src/d/actor/d_a_obj_ss_base.cpp +++ b/src/d/actor/d_a_obj_ss_base.cpp @@ -12,6 +12,8 @@ daObj_SSBase_c::daObj_SSBase_c() { daObj_SSBase_c::~daObj_SSBase_c() {} +void daObj_SSBase_c::setSoldOut() {} + u32 daObj_SSBase_c::getProcessID() { return fopAcM_GetID(this); } diff --git a/src/dusk/dvd_emu.cpp b/src/dusk/dvd_emu.cpp new file mode 100644 index 0000000000..67a541c62d --- /dev/null +++ b/src/dusk/dvd_emu.cpp @@ -0,0 +1,217 @@ +#include "dusk/dvd_emu.h" +#include +#include +#include +#include +#include "dolphin/os.h" + +#ifdef _WIN32 +#include +#include +#define PATH_SEP '\\' +#else +#include +#include +#define PATH_SEP '/' +#endif + +namespace { +s32 g_nextEntryNum = 1; + +// Lazy-init to avoid crash during DLL static initialization +std::string& g_basePath() { + static std::string instance = "data"; + return instance; +} + +std::unordered_map& getEntryPaths() { + static std::unordered_map instance; + return instance; +} +} // namespace + +namespace DvdEmu { + +void setBasePath(const char* path) { +#ifdef _WIN32 + char exePath[MAX_PATH]; + GetModuleFileNameA(NULL, exePath, MAX_PATH); + + // Get the directory of the .exe + char* lastSlash = strrchr(exePath, '\\'); + if (lastSlash) { + *lastSlash = '\0'; + } + + // exeDir + "/" + path + g_basePath() = exePath; + g_basePath() += PATH_SEP; + g_basePath() += path; +#else + g_basePath() = path; +#endif + + OSReport("[DvdEmu] Base path set to: %s\n", g_basePath().c_str()); +} + +const char* getBasePath() { + return g_basePath().c_str(); +} + +std::string convertPath(const char* gcPath) { + std::string result = g_basePath(); + + // Skip leading slashes + const char* p = gcPath; + while (*p == '/' || *p == '\\') + p++; + + result += PATH_SEP; + + // Append path, converting slashes + while (*p) { + if (*p == '/' || *p == '\\') { + result += PATH_SEP; + } else { + result += *p; + } + p++; + } + + return result; +} + +bool fileExists(const char* gcPath) { + std::string fullPath = convertPath(gcPath); + +#ifdef _WIN32 + DWORD attrib = GetFileAttributesA(fullPath.c_str()); + bool exists = (attrib != INVALID_FILE_ATTRIBUTES && !(attrib & FILE_ATTRIBUTE_DIRECTORY)); +#else + struct stat st; + bool exists = (stat(fullPath.c_str(), &st) == 0 && S_ISREG(st.st_mode)); +#endif + + if (exists) { + OSReport("[DvdEmu] FOUND: %s\n", gcPath); + } else { + OSReport("[DvdEmu] MISSING: %s\n", gcPath); + } + + return exists; +} + +u32 getFileSize(const char* gcPath) { + std::string fullPath = convertPath(gcPath); + FILE* f = fopen(fullPath.c_str(), "rb"); + if (!f) + return 0; + + fseek(f, 0, SEEK_END); + u32 size = (u32)ftell(f); + fclose(f); + return size; +} + +void* loadFile(const char* gcPath, u32* outSize, void* heap) { + std::string fullPath = convertPath(gcPath); + + OSReport("[DvdEmu] Loading request: '%s'\n", gcPath); + + FILE* f = fopen(fullPath.c_str(), "rb"); + if (!f) { + OSReport("[DvdEmu] ERROR: Failed to open file at physical path: %s\n", fullPath.c_str()); + if (outSize) + *outSize = 0; + return nullptr; + } + + fseek(f, 0, SEEK_END); + u32 size = (u32)ftell(f); + fseek(f, 0, SEEK_SET); + + // Allocate with 32-byte alignment (matching GameCube) + void* data; +#ifdef _WIN32 + data = _aligned_malloc(size, 32); +#else + data = aligned_alloc(32, (size + 31) & ~31); +#endif + + if (!data) { + OSReport("[DvdEmu] FATAL: Failed to allocate %u bytes for %s\n", size, gcPath); + fclose(f); + if (outSize) + *outSize = 0; + return nullptr; + } + + u32 bytesRead = (u32)fread(data, 1, size, f); + fclose(f); + + if (bytesRead != size) { + OSReport("[DvdEmu] WARNING: Read error: expected %u, got %u for %s\n", size, bytesRead, + gcPath); + } + + if (outSize) + *outSize = bytesRead; + + OSReport("[DvdEmu] SUCCESS: Loaded %s (%u bytes)\n", gcPath, bytesRead); + return data; +} + +u32 loadFileToBuffer(const char* gcPath, void* buffer, u32 bufferSize, u32 offset) { + std::string fullPath = convertPath(gcPath); + + FILE* f = fopen(fullPath.c_str(), "rb"); + if (!f) { + OSReport("[DvdEmu] Failed to open file for buffer load: %s\n", fullPath.c_str()); + return 0; + } + + if (offset > 0) { + fseek(f, offset, SEEK_SET); + } + + u32 bytesRead = (u32)fread(buffer, 1, bufferSize, f); + fclose(f); + + return bytesRead; +} + +} // namespace DvdEmu + +// Entry-Number System (emulates DVD's entry system) + +s32 DVDConvertPathToEntrynum_Emu(const char* path) { + if (!DvdEmu::fileExists(path)) { + OSReport("[DVD] Error: File not found for entrynum conversion: %s\n", path); + return -1; + } + + // Check if already registered + for (const auto& pair : getEntryPaths()) { + if (pair.second == path) { + return pair.first; + } + } + + // Assign new entry number + s32 entryNum = g_nextEntryNum++; + getEntryPaths()[entryNum] = path; + + return entryNum; +} + +void DVDRegisterPath(s32 entryNum, const char* path) { + getEntryPaths()[entryNum] = path; +} + +const char* DVDGetPathForEntry(s32 entryNum) { + auto it = getEntryPaths().find(entryNum); + if (it != getEntryPaths().end()) { + return it->second.c_str(); + } + return nullptr; +} diff --git a/src/dusk/extras.c b/src/dusk/extras.c index 85a08394a6..a64296eed3 100644 --- a/src/dusk/extras.c +++ b/src/dusk/extras.c @@ -54,5 +54,9 @@ void *_memcpy(void* dest, void const* src, int n) { } void DCZeroRange(void* addr, uint32_t nBytes) { +#ifdef _MSC_VER + memset(addr, 0, nBytes); +#else bzero(addr, nBytes); +#endif } diff --git a/src/dusk/jsystem_stubs.cpp b/src/dusk/jsystem_stubs.cpp index 2987e39df3..1ca727fe00 100644 --- a/src/dusk/jsystem_stubs.cpp +++ b/src/dusk/jsystem_stubs.cpp @@ -1,6 +1,7 @@ +/* #include #include - +*/ #pragma mark J3DShapeTable #include "JSystem/J3DGraphAnimator/J3DShapeTable.h" @@ -46,7 +47,7 @@ bool JASVoiceBank::getInstParam(int a, int b, int c, JASInstParam* param) const } // JASSeqParser::sCallBackFunc is compiled from JASSeqParser.obj - +/* #pragma mark JHICommBuf #include "JSystem/JHostIO/JHIComm.h" @@ -137,7 +138,7 @@ int JOREventCallbackListNode::JORAct(u32 eventID, const char* eventName) { puts("JOREventCallbackListNode::JORAct is a stub"); return 0; } - +*/ #pragma mark J3DPSMtxArrayConcat void J3DPSMtxArrayConcat(float (*a)[4], float (*b)[4], float (*out)[4], unsigned long count) { puts("J3DPSMtxArrayConcat is a stub"); diff --git a/src/dusk/main.cpp b/src/dusk/main.cpp index f8475c1e68..d424bf2b56 100644 --- a/src/dusk/main.cpp +++ b/src/dusk/main.cpp @@ -1,5 +1,5 @@ -extern "C" void game_main(int argc, char* argv[]); +int game_main(int argc, char* argv[]); int main(int argc, char* argv[]) { - game_main(argc, argv); + return game_main(argc, argv); } diff --git a/src/dusk/stubs.cpp b/src/dusk/stubs.cpp index 329f5c2c57..670c718c1d 100644 --- a/src/dusk/stubs.cpp +++ b/src/dusk/stubs.cpp @@ -5,14 +5,14 @@ // Credits: Super Monkey Ball -#pragma mark OS /* void OSReport(const char* msg, ...) { va_list args; va_start(args, msg); vprintf(msg, args); va_end(args); -}*/ +} +*/ u32 OSGetConsoleType() { return OS_CONSOLE_RETAIL1; @@ -76,6 +76,7 @@ void OSCancelAlarm(OSAlarm* alarm) { s32 OSCheckActiveThreads(void) { puts("OSCheckActiveThreads is a stub"); + return 0; } @@ -235,14 +236,15 @@ void OSExitThread(void* val) { puts("OSExitThread is a stub"); } +static void* sArenaLo = nullptr; +static void* sArenaHi = nullptr; + void* OSGetArenaHi(void) { - puts("OSGetArenaHi is a stub"); - return NULL; + return sArenaHi; } void* OSGetArenaLo(void) { - puts("OSGetArenaLo is a stub"); - return NULL; + return sArenaLo; } OSContext* OSGetCurrentContext(void) { @@ -326,11 +328,11 @@ int OSSendMessage(OSMessageQueue* mq, void* msg, s32 flags) { } void OSSetArenaHi(void* newHi) { - puts("OSSetArenaHi is a stub"); + sArenaHi = newHi; } void OSSetArenaLo(void* newLo) { - puts("OSSetArenaLo is a stub"); + sArenaLo = newLo; } void OSSetPeriodicAlarm(OSAlarm* alarm, OSTime start, OSTime period, OSAlarmHandler handler) { @@ -631,100 +633,42 @@ u32 VIGetRetraceCount() { } u32 VIGetNextField() { - puts("VIGetNextField is a stub"); - return 0; + puts("VIGetNextField is a stub"); + return 0; } -void VISetBlack(BOOL black) { puts("VISetBlack is a stub"); } +void VISetBlack(BOOL black) { + puts("VISetBlack is a stub"); +} -void VISetNextFrameBuffer(void *fb) { - // puts("VISetNextFrameBuffer is a stub"); +void VISetNextFrameBuffer(void* fb) { + // puts("VISetNextFrameBuffer is a stub"); } void VIWaitForRetrace() { - if (sVIRetraceCallback) { - sVIRetraceCallback(0); - } + if (sVIRetraceCallback) { + sVIRetraceCallback(0); + } } void* VIGetCurrentFrameBuffer(void) { - puts("VIGetCurrentFrameBuffer is a stub"); - return NULL; + puts("VIGetCurrentFrameBuffer is a stub"); + return NULL; } u32 VIGetDTVStatus(void) { - puts("VIGetDTVStatus is a stub"); - return 0; + puts("VIGetDTVStatus is a stub"); + return 0; } void* VIGetNextFrameBuffer(void) { - puts("VIGetNextFrameBuffer is a stub"); - return NULL; + puts("VIGetNextFrameBuffer is a stub"); + return NULL; } VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback callback) { - sVIRetraceCallback = callback; - return callback; -} - -VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback cb) { - puts("VISetPreRetraceCallback is a stub"); - return cb; -} - -} // extern "C" - -# pragma mark DSP -#include -extern "C" void __DSP_insert_task(DSPTaskInfo* task) { - puts("__DSP_insert_task is a stub"); -} - -extern "C" void __DSP_boot_task(DSPTaskInfo*) { - puts("__DSP_boot_task is a stub"); -} - -extern "C" void __DSP_exec_task(DSPTaskInfo*, DSPTaskInfo*) { - puts("__DSP_exec_task is a stub"); -} - -extern "C" void __DSP_remove_task(DSPTaskInfo* task) { - puts("__DSP_remove_task is a stub"); -} - -void DSPAssertInt(void) { - puts("DSPAssertInt is a stub"); -} -u32 DSPCheckMailFromDSP(void) { - puts("DSPCheckMailFromDSP is a stub"); - return 0; -} -u32 DSPCheckMailToDSP(void) { - puts("DSPCheckMailToDSP is a stub"); - return 0; -} -void DSPInit(void) { - puts("DSPInit is a stub"); -} -u32 DSPReadMailFromDSP(void) { - puts("DSPReadMailFromDSP is a stub"); - return 0; -} -void DSPSendMailToDSP(u32 mail) { - puts("DSPSendMailToDSP is a stub"); -} - -# pragma mark Z2Audio -#include -void Z2AudioCS::extensionProcess(s32, s32) { - puts("Z2AudioMgr::play is a stub"); -} - -# pragma mark JORServer -#include - -int JOREventCallbackListNode::JORAct(u32, const char*) { - return 0; + sVIRetraceCallback = callback; + return callback; } VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback cb) { @@ -780,27 +724,12 @@ void Z2AudioCS::extensionProcess(s32, s32) { puts("Z2AudioMgr::play is a stub"); } -// #pragma mark JORServer -// #include -// void JORServer::releaseMCTX(JORMContext*) { -// puts("releaseMCTX is a stub"); -// } -// -// JORMContext* JORServer::attachMCTX(u32) { -// puts("attachMCTX is a stub"); -// return NULL; -// } -// -// JORServer* JORServer::instance; -// -// void JORMContext::genCheckBoxSub(u32 kind, const char* label, u32 id, u32 style, u16 initValue, -// u16 mask, JOREventListener* pListener, u16 posX, u16 posY, -// u16 width, u16 height) { -// puts("JORServer::genCheckBoxSub is a stub"); -// } -// void JORMContext::updateCheckBoxSub(u32 mode, u32 id, u16 value, u16 mask, u32 param_4) { -// puts("JORServer::updateCheckBoxSub is a stub"); -// } +#pragma mark JORServer +#include + +int JOREventCallbackListNode::JORAct(u32, const char*) { + return 0; +} #pragma mark JSUMemoryOutputStream #include @@ -834,7 +763,7 @@ mDoExt_onCupOffAupPacket::~mDoExt_onCupOffAupPacket() { puts("mDoExt_onCupOffAupPacket_c destructor is a stub"); } -# pragma mark dKankyo_vrboxHIO_c +#pragma mark dKankyo_vrboxHIO_c #include void dKankyo_vrboxHIO_c::dKankyo_vrboxHIOInfoUpDateF() { puts("dKankyo_vrboxHIO_c::dKankyo_vrboxHIOInfoUpDateF is a stub"); @@ -1755,6 +1684,92 @@ void dMsgObject_c::setSelectWord(int i_no, const char* i_word) { puts("dMsgObject_c::setSelectWord is a stub"); } +#pragma mark HIO +#include +#include +BOOL HIO2Close(s32 handle) { + puts("HIO2Close is a stub"); + return FALSE; +} + +BOOL HIO2EnumDevices(HIO2EnumCallback callback) { + puts("HIO2EnumDevices is a stub"); + return FALSE; +} + +BOOL HIO2Init(void) { + puts("HIO2Init is a stub"); + return FALSE; +} + +s32 HIO2Open(HIO2DeviceType type, HIO2UnkCallback exiCb, HIO2DisconnectCallback disconnectCb) { + puts("HIO2Open is a stub"); + return 0; +} + +BOOL HIO2Read(s32 handle, u32 addr, void* buffer, s32 size) { + puts("HIO2Read is a stub"); + return FALSE; +} + +BOOL HIO2Write(s32 handle, u32 addr, void* buffer, s32 size) { + puts("HIO2Write is a stub"); + return FALSE; +} + +BOOL HIORead(u32 addr, void* buffer, s32 size) { + puts("HIORead is a stub"); + return FALSE; +} + +BOOL HIOWrite(u32 addr, void* buffer, s32 size) { + puts("HIOWrite is a stub"); + return FALSE; +} + +#pragma mark JHICommBuf +#include +void JHICommBufHeader::init() { + puts("JHICommBufHeader::init is a stub"); +} + +int JHICommBufHeader::load() { + puts("JHICommBufHeader::load is a stub"); + return 0; +} + +int JHICommBufReader::read(void*, int) { + puts("JHICommBufReader::read is a stub"); + return 0; +} +void JHICommBufReader::readEnd() { + puts("JHICommBufReader::readEnd is a stub"); +} + +int JHICommBufReader::readBegin() { + puts("JHICommBufReader::readBegin is a stub"); + return 0; +} + +int JHICommBufWriter::writeBegin() { + puts("JHICommBufWriter::writeBegin is a stub"); + return 0; +} + +int JHICommBufWriter::write(void*, int) { + puts("JHICommBufWriter::write is a stub"); + return 0; +} + +void JHICommBufWriter::writeEnd() { + puts("JHICommBufWriter::writeEnd is a stub"); +} + +u32 JHICommBufReader::Header::getReadableSize() const { + puts("JHICommBufReader::Header::getReadableSize is a stub"); + return 0; +} + #pragma mark dMeter2Info #include void dMeter2Info_c::getString(u32 i_stringID, char* o_string, JMSMesgEntry_c* i_msgEntry) { @@ -1764,7 +1779,4 @@ void dMeter2Info_c::getStringKanji(u32 i_stringID, char* o_string, JMSMesgEntry_ puts("dMeter2Info_c::getStringKanji is a stub"); } -dPa_particleTracePcallBack_c JPTracePCB4; - - - +dPa_particleTracePcallBack_c JPTracePCB4; \ No newline at end of file diff --git a/src/m_Do/m_Do_main.cpp b/src/m_Do/m_Do_main.cpp index 2f337e254b..27e7e87026 100644 --- a/src/m_Do/m_Do_main.cpp +++ b/src/m_Do/m_Do_main.cpp @@ -1,949 +1,265 @@ /** * m_Do_main.cpp * Main Initialization + * PC Port Version - based on Aurora integration from Vorversion */ #include "m_Do/m_Do_main.h" +#include #include "DynamicLink.h" #include "JSystem/JAudio2/JASAudioThread.h" #include "JSystem/JAudio2/JAUSoundTable.h" #include "JSystem/JFramework/JFWSystem.h" +#include "JSystem/JHostIO/JORServer.h" #include "JSystem/JKernel/JKRAram.h" #include "JSystem/JKernel/JKRSolidHeap.h" #include "JSystem/JUtility/JUTConsole.h" -#include "JSystem/JUtility/JUTReport.h" #include "JSystem/JUtility/JUTException.h" #include "JSystem/JUtility/JUTProcBar.h" -#include "JSystem/JHostIO/JORServer.h" +#include "JSystem/JUtility/JUTReport.h" +#include "SSystem/SComponent/c_counter.h" #include "Z2AudioLib/Z2WolfHowlMgr.h" #include "c/c_dylink.h" #include "d/d_com_inf_game.h" +#include "d/d_debug_pad.h" #include "d/d_s_logo.h" #include "d/d_s_menu.h" #include "d/d_s_play.h" -#include "d/d_debug_pad.h" #include "f_ap/f_ap_game.h" #include "f_op/f_op_msg.h" #include "m_Do/m_Do_MemCard.h" #include "m_Do/m_Do_Reset.h" #include "m_Do/m_Do_controller_pad.h" #include "m_Do/m_Do_dvd_thread.h" +#include "m_Do/m_Do_ext2.h" #include "m_Do/m_Do_graphic.h" #include "m_Do/m_Do_machine.h" #include "m_Do/m_Do_printf.h" -#include "m_Do/m_Do_ext2.h" -#include "SSystem/SComponent/c_counter.h" -#include -#if PLATFORM_WII || PLATFORM_SHIELD -#include -#endif +#include +#include +#include "dusk/dvd_emu.h" +#include "SSystem/SComponent/c_API.h" -class mDoMain_HIO_c : public mDoHIO_entry_c { -public: - void listenPropertyEvent(const JORPropertyEvent*); - void genMessage(JORMContext*); -}; - -void version_check() { -#if !PLATFORM_SHIELD - if (!strcmp("20Apr2004", "20Apr2004") && !strcmp("Patch2", "Patch2")) { - return; - } - - // "SDK version doesn't match. Stopping\n" - OSReport_Error("SDKのバージョンが一致しません。停止します\n"); - do { - } while (true); -#endif -} +#include +#include +#include +// --- GLOBALS --- +s8 mDoMain::developmentMode = -1; +OSTime mDoMain::sPowerOnTime; +OSTime mDoMain::sHungUpTime; +u32 mDoMain::memMargin = 0xFFFFFFFF; char mDoMain::COPYDATE_STRING[18] = "??/??/?? ??:??:??"; -// static HeapCheck RootHeapCheck; -static HeapCheck RootHeapCheck = HeapCheck(0,"Root","ルート"); - -// static HeapCheck SystemHeapCheck; -static HeapCheck SystemHeapCheck = HeapCheck(0,"System","システム"); - -// static HeapCheck ZeldaHeapCheck; -static HeapCheck ZeldaHeapCheck = HeapCheck(0,"Zelda","ゼルダ"); - -// static HeapCheck GameHeapCheck; -static HeapCheck GameHeapCheck = HeapCheck(0,"Game","ゲーム"); - -// static HeapCheck ArchiveHeapCheck; -static HeapCheck ArchiveHeapCheck = HeapCheck(0,"Archive","アーカイブ"); - -// static HeapCheck J2dHeapCheck; -static HeapCheck J2dHeapCheck = HeapCheck(0,"J2d","J2D"); - -// static HeapCheck HostioHeapCheck; -static HeapCheck HostioHeapCheck = HeapCheck(0,"Hostio","ホストIO"); - -// static HeapCheck CommandHeapCheck; -static HeapCheck CommandHeapCheck = HeapCheck(0,"Command","コマンド"); - -static HeapCheck* HeapCheckTable[8] = { - &RootHeapCheck, &SystemHeapCheck, &ZeldaHeapCheck, &GameHeapCheck, - &ArchiveHeapCheck, &J2dHeapCheck, &HostioHeapCheck, &CommandHeapCheck, -}; - -void printFrameLine() { - OSCalendarTime calendar; - OSTime time = OSGetTime(); - u32 retrace = VIGetRetraceCount(); - OSTicksToCalendarTime(time, &calendar); - - OS_REPORT("\x1b[44m-- %5d - %5d - %3d %d %04d/%02d/%02d %02d:%02d:%02d\'%03d\'\'%03d\n\x1b[m", - g_Counter.mCounter0, retrace, - calendar.yday, calendar.wday, calendar.year, calendar.mon, calendar.mday, - calendar.hour, calendar.min, calendar.sec, calendar.msec, calendar.usec); -} - -void HeapCheck::CheckHeap1() { - s32 totalUsedSize = mHeap->getTotalUsedSize(); - s32 freeSize = mHeap->getFreeSize(); - - if (mMaxTotalUsedSize < totalUsedSize) - mMaxTotalUsedSize = totalUsedSize; - - if (mMaxTotalFreeSize > freeSize) - mMaxTotalFreeSize = freeSize; -} - -void CheckHeap(u32 i_padNo) { - mDoMch_HeapCheckAll(); - OSCheckActiveThreads(); - - int saveRel = (mDoCPd_c::getHold(i_padNo) & ~PAD_TRIGGER_Z) == (PAD_TRIGGER_L + PAD_TRIGGER_R) && mDoCPd_c::getTrig(i_padNo) & PAD_TRIGGER_Z; - - for (int i = 0; i < 8; i++) { - HeapCheckTable[i]->CheckHeap1(); - if (saveRel) { - HeapCheckTable[i]->saveRelBase(); - } +// --- PC LOGGING CALLBACK --- +void aurora_log_callback(AuroraLogLevel level, const char* module, const char* message, + unsigned int len) { + const char* levelStr = "??"; + FILE* out = stdout; + switch (level) { + case LOG_DEBUG: + levelStr = "DEBUG"; + break; + case LOG_INFO: + levelStr = "INFO"; + break; + case LOG_WARNING: + levelStr = "WARNING"; + break; + case LOG_ERROR: + levelStr = "ERROR"; + out = stderr; + break; + case LOG_FATAL: + levelStr = "FATAL"; + out = stderr; + break; + } + fprintf(out, "[%s | %s] %s\n", levelStr, module, message); + if (level == LOG_FATAL) { + fflush(out); + abort(); } } -static int countUsed(JKRExpHeap* heap) { - OSDisableScheduler(); +// ========================================================================= +// LOAD_COPYDATE - PC Version using DvdEmu +// ========================================================================= +#define COPYDATE_PATH "/str/Final/Release/COPYDATE" - int counter = 0; - JKRExpHeap::CMemBlock* used_blocks_head = heap->getUsedFirst(); - while (used_blocks_head) { - counter++; - used_blocks_head = used_blocks_head->getNextBlock(); +s32 LOAD_COPYDATE(void*) { + char buffer[32]; + memset(buffer, 0, sizeof(buffer)); + + u32 size = 0; + void* data = DvdEmu::loadFile(COPYDATE_PATH, &size, nullptr); + + // Fallback: Try root if not found + if (!data) { + data = DvdEmu::loadFile("/COPYDATE", &size, nullptr); } - OSEnableScheduler(); - return counter; -} + if (data) { + u32 copyLen = (size < sizeof(buffer) - 1) ? size : sizeof(buffer) - 1; + memcpy(buffer, data, copyLen); + buffer[copyLen] = '\0'; -s32 HeapCheck::getUsedCount() const { - return countUsed(mHeap); -} - -void HeapCheck::heapDisplay() const { - s32 heap_size = mHeap->getHeapSize(); - s32 used_count = heap_size - getTargetHeapSize(); - - s32 total_used_size = mHeap->getTotalUsedSize(); - s32 total_free_size = mHeap->getTotalFreeSize(); - s32 heap_free_size = mHeap->getFreeSize(); - - JUTReport(100, 212, "[%sName]", mName); - JUTReport(100, 227, "HeapSize %8ld", heap_size); - JUTReport(100, 240, "TargetHeapSize %8ld", getTargetHeapSize()); - JUTReport(100, 253, "TotalFree %8ld", total_free_size - used_count); - JUTReport(100, 266, "FreeSize %8ld", heap_free_size - used_count); - JUTReport(100, 279, "TotalUsedSize %8ld", total_used_size); - JUTReport(100, 292, "TotalUsedRate %3ld%%", (int)(total_used_size * 100) / (int)getTargetHeapSize()); - JUTReport(100, 305, "MaxTotalUsedSize %8ld", mMaxTotalUsedSize); - JUTReport(100, 318, "MaxTotalUsedRate %3ld%%", (mMaxTotalUsedSize * 100) / (int)getTargetHeapSize()); - JUTReport(100, 331, "MinFreeSize %8ld", mMaxTotalFreeSize - used_count); - JUTReport(100, 344, "MinFreeRate %3ld%%", ((mMaxTotalFreeSize - used_count) * 100) / (int)getTargetHeapSize()); - JUTReport(100, 357, "UsedCount %3ld%", countUsed(mHeap)); -} - -#if DEBUG -int mDoMain::argument = -1; +#ifdef _WIN32 + _aligned_free(data); +#else + free(data); #endif - -s8 mDoMain::developmentMode = -1; - -#if DEBUG -u32 mDoMain::gameHeapSize = 0xFFFFFFFF; -u32 mDoMain::archiveHeapSize = 0xFFFFFFFF; -#endif - -u32 mDoMain::memMargin = 0xFFFFFFFF; - -#if DEBUG -int mDoMain::e3menu_no = -1; -#endif - -u8 mHeapBriefType = 4; - -#if DEBUG -static u8 memorycheck_check_frame; -#endif - -static u8 fillcheck_check_frame; - -OSTime mDoMain::sPowerOnTime; - -OSTime mDoMain::sHungUpTime; - -static u8 mDisplayHeapSize; - -#if DEBUG -static u8 mReportDisable; -#endif - -static u8 mSelectHeapBar; - -#if DEBUG -static u8 mVisibleHeapBar; -static u8 mPrintFrameLine; -#endif - -static u8 mCheckHeap; - -#if DEBUG -mDoMain_HIO_c mDoMain_HIO; -#endif - -void debugDisplay() { - static const char* desc1[5] = { - "", "TotalFree", "MaxUsed ", "Used ", "RelUsed ", - }; - - static const char* desc2[5] = { - "", "/ MaxFree", "/HeapSize", "Blk/Bytes", "Blk/Bytes", - }; - - if (mSelectHeapBar >= 1 && mSelectHeapBar <= 6) { - HeapCheckTable[mSelectHeapBar - 1]->heapDisplay(); - } - - if (mHeapBriefType == 5) { - JKRAramHeap* heap = JKRAram::getAramHeap(); - if (heap != NULL) { - JUTReport(475, 100, "ARAM Free"); - JUTReport(475, 114, "%d", heap->getFreeSize()); - JUTReport(475, 128, "TotalFree"); - JUTReport(475, 142, "%d", heap->getTotalFreeSize()); - } - return; - } - - if (mHeapBriefType != 0) { - JUT_ASSERT(596, mHeapBriefType < HeapCheckTableNum); - JUTReport(475, 100, "%s", desc1[mHeapBriefType]); - JUTReport(475, 114, "%s", desc2[mHeapBriefType]); - - for (int i = 0; i < 8; i++) { - HeapCheck* heap_check = HeapCheckTable[i]; - JKRExpHeap* expHeap = heap_check->getHeap(); - - s32 check1; - s32 check2; - switch (mHeapBriefType) { - case 1: - check1 = expHeap->getTotalFreeSize(); - check2 = expHeap->getFreeSize(); - break; - case 2: - check1 = heap_check->getMaxTotalUsedSize(); - check2 = expHeap->getHeapSize(); - break; - case 3: - check1 = heap_check->getUsedCount(); - check2 = expHeap->getTotalUsedSize(); - break; - case 4: - check1 = heap_check->getRelUsedCount(); - check2 = heap_check->getRelTotalUsedSize(); - break; - } - - JUTReport(475, (i * 44) + 150, " [%s]", heap_check->getName()); - JUTReport(475, (i * 44) + 164, "%10d", check1); - JUTReport(475, (i * 44) + 178, "%10d", check2); - } - } -} - -void my_genCheckBox(JORMContext* mctx, const char* label, u8* pSrc, u8 mask) { - mctx->genCheckBox(label, pSrc, mask); -} - -#if DEBUG -void mDoMain_HIO_c::genMessage(JORMContext* mctx) { - mctx->genSlider("コード破壊チェックフレーム", &memorycheck_check_frame, 0, 0xFF); - mctx->genButton("コード破壊チェックcheck", 0); - mctx->genButton("コード破壊チェックsave", 1); - mctx->genButton("コード破壊チェックdiff", 2); - mctx->genCheckBox("デバッグフィル", &mDoMch::mDebugFill, 0x1); - mctx->genSlider("ヒープ破壊チェックフレーム", &fillcheck_check_frame, 0, 0xFF); - mctx->genButton("ヒープ破壊チェック", 3); - mctx->genButton("ヒープFree領域フィル", 4); - mctx->genButton("浮動小数点例外を(再び)有効にする", 5); - mctx->genCheckBox("◎無効演算", &mDoMch::FpscrEnableBits, 0x80); - mctx->genCheckBox("○オーバー", &mDoMch::FpscrEnableBits, 0x40); - mctx->genCheckBox("△アンダー", &mDoMch::FpscrEnableBits, 0x20); - mctx->genCheckBox("○ゼロ除算", &mDoMch::FpscrEnableBits, 0x10); - mctx->genCheckBox("▲不正確 ", &mDoMch::FpscrEnableBits, 0x8); - - mctx->genLabel("ソースファイル:m_Do_main.cpp", 0); - mctx->genCheckBox("OSReport 表示しない", &mReportDisable, 0x1); - mctx->genCheckBox("OSReport 優先度最高", &print_highPriority, 0x1); - mctx->genCheckBox("OSReport スレッド表示", &print_threadID, 0x1); - mctx->genCheckBox("OSReport CallerPC表示", &print_callerPC, 0x1); - mctx->genSlider("レベル", &print_callerPCLevel, 3, 10); - - mctx->startComboBox("簡易ヒープ表示", &mHeapBriefType); - mctx->genComboBoxItem("なし", 0); - mctx->genComboBoxItem("合計空き・最大空き", 1); - mctx->genComboBoxItem("最大使用量・ヒープサイズ元使用量", 2); - mctx->genComboBoxItem("使用ブロック数・元使用量", 3); - mctx->genComboBoxItem("相対 使用ブロック数・元使用量", 4); - mctx->endComboBox(); - - my_genCheckBox(mctx, "ヒープサイズ表示を行う", &mDisplayHeapSize, 1); - mctx->genCheckBox("ヒープバーを表示する", &mVisibleHeapBar, 0x1); - - mctx->startComboBox("ヒープバーの種類", &mSelectHeapBar); - mctx->genComboBoxItem("カレント", 0); - for (int i = 0; i < 8; i++) { - mctx->genComboBoxItem(HeapCheckTable[i]->getJName(), i + 1); - } - mctx->endComboBox(); - - mctx->genCheckBox("ヒープチェック", &mCheckHeap, 0x1); - mctx->genCheckBox("フレームバー表示", &mPrintFrameLine, 0x1); - - mctx->startComboBox("GX警告レベル", &mDoMch::GXWarningLevel); - mctx->genComboBoxItem("エラー&警告なし", 0); - mctx->genComboBoxItem("致命的なエラー", 1); - mctx->genComboBoxItem("中警告と全エラー", 2); - mctx->genComboBoxItem("すべての警告", 3); - mctx->endComboBox(); - - mctx->genButton("GX警告を1フレームだけ実行", 9); - mctx->genButton("ダイナミックリンク状況をダンプ", 7); - mctx->genButton("ダイナミックリンクカウンタをリセット", 8); - mctx->genButton("ARAMヒープをダンプ", 10); - mctx->genButton("ゲームリソースをダンプ", 11); - mctx->genButton("RES_CONTROLをダンプ", 12); - mctx->genButton("ルートヒープをダンプ", 13); - mctx->genButton("システムヒープをダンプ", 14); - mctx->genButton("ゼルダヒープをダンプ", 15); - mctx->genButton("ゲームヒープをダンプ", 16); - mctx->genButton("アーカイブヒープをダンプ", 17); - mctx->genButton("J2Dヒープをダンプ", 18); - mctx->genButton("ホストIOヒープをダンプ", 19); - mctx->genButton("コマンドヒープをダンプ", 20); - - mctx->genCheckBox("ダイナミックリンク冗長表示", &DynamicModuleControlBase::verbose, 0x1); - mctx->genCheckBox("ヒープコールバック冗長表示", &mDoMch::myHeapVerbose, 0x1); - mctx->genCheckBox("ヒープコールバックチェック", &mDoMch::myHeapCallbackCheck, 0x1); - mctx->genCheckBox("mDoDvdThd::verbose冗長表示", &mDoDvdThd::verbose, 0x1); - mctx->genCheckBox("mDoDvdThd::DVDRead冗長表示", &mDoDvdThd::Report_DVDRead, 0x1); - mctx->genCheckBox("mDoDvdThd::DVDログモード", &mDoDvdThd::DVDLogoMode, 0x1); - mctx->genCheckBox("fopMsg::MemCheck ヒープチェック", &fopMsg::MemCheck, 0x1); -} - -void mDoMain_HIO_c::listenPropertyEvent(const JORPropertyEvent* property) { - JORMContext* mctx = attachJORMContext(8); - JORReflexible::listenPropertyEvent(property); - - if ((u32)property->id >= 13 && (u32)property->id <= 20) { - int sp14 = (u32)property->id - 13; - HeapCheck* heapCheck = HeapCheckTable[sp14]; - JUTReportConsole_f("\n[%sHeap]\n", heapCheck->getName()); - heapCheck->getHeap()->dump_sort(); } else { - switch ((u32)property->id) { - case 0: - FixedMemoryCheck::checkAll(); - break; - case 1: - FixedMemoryCheck::saveAll(); - break; - case 2: - FixedMemoryCheck::diffAll(); - break; - case 3: - mDoMch_HeapCheckAll(); - break; - case 4: - mDoMch_HeapFreeFillAll(); - break; - case 5: { - u32 fpscr = PPCMffpscr(); - JUTException::setFPException(0); - JUTException::setFPException(mDoMch::FpscrEnableBits); - PPCMtfpscr(fpscr); - break; - } - case 9: - GXSetVerifyLevel(GX_WARN_ALL); - mDoMch::GXWarningExecuteFrame = TRUE; - break; - case 7: { - int RoomId = dComIfGp_roomControl_getStayNo(); - JUTReportConsole_f("\nRoomId = %d\n", RoomId); - - JUTReportConsole_f("\nDynamicModule\n"); - DynamicModuleControlBase::dump(); - break; - } - case 8: - DynamicModuleControlBase::resetDoLinkCount(); - break; - case 10: { - JUTReportConsole_f("\nAramHeap\n"); - JKRAramHeap* aramHeap = JKRAram::getAramHeap(); - if (aramHeap != NULL) { - aramHeap->dump(); - } - break; - } - case 11: - JUTReportConsole_f("\nGameResource\n"); - g_dComIfG_gameInfo.mResControl.dump(); - break; - case 12: - JUTReportConsole_f("\nResControl\n"); - dComIfG_dumpResControl(); - break; - case 6: - default: - if ((u8*)property->id == &mDisplayHeapSize) { - mctx->startUpdateNode(this); - mctx->endUpdateNode(); - } - - if ((u8*)property->id == &mReportDisable) { - if (mReportDisable == 0) { - OSReportEnable(); - } else { - OSReportDisable(); - } - } - - if ((u8*)property->id == &mSelectHeapBar) { - JKRHeap* heap = NULL; - u32 select_heap = mSelectHeapBar - 1; - if (select_heap < 8) { - heap = HeapCheckTable[select_heap]->getHeap(); - } - - JUTProcBar::getManager()->setWatchHeap(heap); - } - - if ((u8*)property->id == &mVisibleHeapBar) { - JUTProcBar::getManager()->setVisibleHeapBar(mVisibleHeapBar); - } - - if ((u8*)property->id == &mDoMch::GXWarningLevel) { - GXSetVerifyLevel((GXWarningLevel)mDoMch::GXWarningLevel); - } - - if ((u8*)property->id == &mDoMch::mDebugFill) { - JKRHeap::setDefaultDebugFill(mDoMch::mDebugFill); - - for (JSUTree* i = JKRGetRootHeap()->getHeapTree().getFirstChild(); i != NULL; i = i->getNextChild()) { - JKRHeap* heap = i->getObject(); - heap->setDebugFill(mDoMch::mDebugFill); - } - } - - JKRSetDebugFillNotuse(mDoMch::mDebugFillNotUse); - JKRSetDebugFillNew(mDoMch::mDebugFillNew); - JKRSetDebugFillDelete(mDoMch::mDebugFillDelete); - } + strcpy(buffer, "PC PORT BUILD"); + OSReport("Warning: COPYDATE file not found at %s\n", COPYDATE_PATH); } - releaseJORMContext(mctx); + memcpy(mDoMain::COPYDATE_STRING, buffer, sizeof(mDoMain::COPYDATE_STRING) - 1); + mDoMain::COPYDATE_STRING[sizeof(mDoMain::COPYDATE_STRING) - 1] = '\0'; + + OS_REPORT("\x1b[36mCOPYDATE=[%s]\n\x1b[m", mDoMain::COPYDATE_STRING); + return 1; } -#endif -bool Debug_console(u32 i_padNo) { +// ========================================================================= +// MAIN01 - THE GAME LOOP +// ========================================================================= +void main01(void) { + OS_REPORT("\x1b[m"); + + // 1. Setup heaps, RNG, Threads + // Nutzt den Speicher, den wir in game_main() per OSSetArena gesetzt haben + mDoMch_Create(); + + // 2. Setup GFX (FrameBuffer, ZBuffer) + mDoGph_Create(); + + // 3. Setup Pads + //mDoCPd_c::create(); + + // 4. Console Setup JUTConsole* console = JFWSystem::getSystemConsole(); - if (console != NULL) { - static f32 console_position_x = 20.0f; - static f32 console_position_y = 30.0f; - static f32 console_scroll = 0.0f; - - if (mDoCPd_c::getTrig(i_padNo) & PAD_TRIGGER_Z && !(mDoCPd_c::getHold(i_padNo) & ~PAD_TRIGGER_Z)) { - console->setVisible(console->isVisible() == false); - JUTAssertion::setMessageCount(0); - } - - if (console->isVisible()) { - if ((mDoCPd_c::getHold(i_padNo) & PAD_TRIGGER_L && mDoCPd_c::getHold(i_padNo) & PAD_TRIGGER_R) || - ((mDoCPd_c::getAnalogL(i_padNo) > 0.0f && mDoCPd_c::getAnalogR(i_padNo) > 0.0f))) - { - f32 stick_x = mDoCPd_c::getStickX(i_padNo); - f32 stick_y = mDoCPd_c::getStickY(i_padNo); - - if (mDoCPd_c::getHold(i_padNo) & (PAD_BUTTON_Y | PAD_BUTTON_X) && - mDoCPd_c::getTrig(i_padNo) & PAD_BUTTON_START) - { - console->clear(); - } - - if (!(mDoCPd_c::getHold(i_padNo) & (PAD_BUTTON_Y | PAD_BUTTON_X))) { - console_scroll -= stick_y; - - int scrollAmount; - if (console_scroll > 1.0f) { - scrollAmount = console_scroll; - } else if (console_scroll < -1.0f) { - scrollAmount = -(int)-console_scroll; - } else { - scrollAmount = 0; - } - - if (scrollAmount != 0) { - console_scroll -= scrollAmount; - console->scroll(scrollAmount); - } - } else { - if (mDoCPd_c::getHold(i_padNo) & PAD_BUTTON_X) { - console_position_x += stick_x; - } - - if (mDoCPd_c::getHold(i_padNo) & PAD_BUTTON_Y) { - console_position_y -= stick_y; - } - } - - if (mDoCPd_c::getTrig(i_padNo) & PAD_BUTTON_A) { - console->dumpToTerminal(0xFFFFFFFF); - console->setOutput(JUTConsole::OUTPUT_OSREPORT | JUTConsole::OUTPUT_CONSOLE); - } - - JUTReport(30, 390, 1, "Press X+Y+START to CLEAR console."); - JUTReport(30, 400, 1, "3DStick UP/Down to scroll"); - JUTReport(30, 410, 1, "Press A to output terminal from console."); - JUTReport(30, 420, 1, "SCROLL:%3d %3d %3d Output=%1x", console->getLineOffset(), - console->getPositionX(), console->getPositionY(), console->getOutput()); - } else { - if (mDoCPd_c::getTrig(i_padNo) & PAD_BUTTON_DOWN) { - g_HIO.mDisplayMeter ^= (u8)1; - } - - if (mDoCPd_c::getTrig(i_padNo) & PAD_BUTTON_LEFT) { - JKRAramHeap* aram = JKRAram::getAramHeap(); - if (aram != NULL) { - aram->dump(); - } - - DynamicModuleControlBase::dump(); - g_dComIfG_gameInfo.mResControl.dump(); - } - - if (mDoCPd_c::getTrig(i_padNo) & PAD_BUTTON_RIGHT) { - JKRGetSystemHeap()->dump_sort(); - } - - if (mDoCPd_c::getTrig(i_padNo) & PAD_BUTTON_UP) { - zeldaHeap->dump_sort(); - gameHeap->dump_sort(); - archiveHeap->dump_sort(); - } - - JUTReport(30, 440, 1, "Press L+R trigger to control console."); - JUTReport(30, 450, 1, "Press [Z] trigger to close this window."); - } - - console->setPosition(console_position_x, console_position_y); - return 1; - } + if (console) { + console->setOutput(mDoMain::developmentMode ? JUTConsole::OUTPUT_OSR_AND_CONSOLE : + JUTConsole::OUTPUT_NONE); + console->setPosition(32, 42); } + // 5. Init Framework & Loader + mDoDvdThd_callback_c::create((mDoDvdThd_callback_func)LOAD_COPYDATE, NULL); + + OSReport("Calling fapGm_Create()...\n"); + fapGm_Create(); + + OSReport("Calling fopAcM_initManager()...\n"); + fopAcM_initManager(); + + OSReport("Calling cDyl_InitAsync()...\n"); + cDyl_InitAsync(); + + // ----------------------------------------------------------- + // THE GAME LOOP + // ----------------------------------------------------------- + OSReport("Entering Main Loop (main01)...\n"); + do { + // --- Window Events & Frame Start --- + const AuroraEvent* event = aurora_update(); + if (event && event->type == AURORA_EXIT) + break; + + if (!aurora_begin_frame()) { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + continue; + } + + static u32 frame; + frame++; + + mDoCPd_c::read(); // Read Controller + + // --- EXECUTE GAME LOGIC & RENDER --- + fapGm_Execute(); + + // --- Frame End & Limiter --- + aurora_end_frame(); + std::this_thread::sleep_for(std::chrono::milliseconds(16)); // ~60 FPS Cap + + } while (true); +} + +// ========================================================================= +// PC ENTRY POINT +// ========================================================================= +int game_main(int argc, char* argv[]) { + // 1. Aurora Init + AuroraConfig config{}; + config.appName = "Zelda: Twilight Princess"; + config.desiredBackend = BACKEND_VULKAN; + config.windowPosX = 100; + config.windowPosY = 100; + config.windowWidth = 640; + config.windowHeight = 480; + config.configPath = "."; + config.logCallback = &aurora_log_callback; + + aurora_initialize(argc, argv, &config); + + // 2. Setup Virtual Game RAM + // Simuliert den GameCube RAM (24MB + Audio etc, nehmen wir 256MB) +#define GAME_RAM_SIZE (256 * 1024 * 1024) + void* virtualGameRam = malloc(GAME_RAM_SIZE); + if (!virtualGameRam) { + printf("Fatal: Failed to allocate game RAM\n"); + return -1; + } + memset(virtualGameRam, 0, GAME_RAM_SIZE); + OSSetArenaLo(virtualGameRam); + OSSetArenaHi((char*)virtualGameRam + GAME_RAM_SIZE); + + // 3. Init DVD Emulation + DvdEmu::setBasePath("data"); + + mDoMain::sPowerOnTime = OSGetTime(); + + // Reset Data + static mDoRstData sResetData = {0}; + mDoRst::setResetData(&sResetData); + mDoRst::offReset(); + mDoRst::setLogoScnFlag(0); + + // Global Context Init + dComIfG_ct(); + + // Development Mode + mDoMain::developmentMode = 1; // Force Dev Mode for Debugging + + // START GAME + OSReport("Starting main01 (Game Loop)...\n"); + + // Auf PC rufen wir main01 direkt im Main Thread auf. + // Kein OSCreateThread noetig (und auch gefaehrlich wegen Window-Loop). + main01(); + + // Cleanup (Erreicht nur bei Break der Loop) + aurora_shutdown(); + free(virtualGameRam); + return 0; } -#if PLATFORM_GCN -#define COPYDATE_PATH "/str/Final/Release/COPYDATE" -#else -#define COPYDATE_PATH "/str/RVL/Debug/COPYDATE" -#endif - -s32 LOAD_COPYDATE(void*) { - DVDFileInfo ATTRIBUTE_ALIGN(32) fileInfo; - u8 buffer[32]; - - BOOL status = DVDOpen(COPYDATE_PATH, &fileInfo); - if (status) { - s32 rt = DVDReadPrio(&fileInfo, &buffer, sizeof(buffer), 0, 2); - memcpy(mDoMain::COPYDATE_STRING, buffer, sizeof(mDoMain::COPYDATE_STRING) - 1); - status = DVDClose(&fileInfo); - } - - OS_REPORT("\x1b[36mCOPYDATE=[%s]\n\x1b[m", mDoMain::COPYDATE_STRING); - return status; +// ========================================================================= +// STUBS & TEMPLATE INSTANTIATIONS +// ========================================================================= +bool JKRHeap::dump_sort() { + return true; } -static void debug() { - #if DEBUG - if (mPrintFrameLine) { - printFrameLine(); - } - #endif - - if (mDoMain::developmentMode) { - if (mCheckHeap) { - CheckHeap(PAD_3); - } - - if ((mDoCPd_c::getGamePad(PAD_3)->getButton() & ~PAD_TRIGGER_Z) == PAD_TRIGGER_R && - mDoCPd_c::getGamePad(PAD_3)->testTrigger(PAD_TRIGGER_Z)) - { - mDisplayHeapSize ^= (u8)1; - } - - if (mDisplayHeapSize) { - if ((mDoCPd_c::getGamePad(PAD_3)->getButton() & ~PAD_TRIGGER_Z) == PAD_TRIGGER_L && - mDoCPd_c::getGamePad(PAD_3)->testTrigger(PAD_TRIGGER_Z)) - { - if (mHeapBriefType < 5) { - mHeapBriefType++; - } else { - mHeapBriefType = 1; - } - } - - debugDisplay(); - } - - #if DEBUG - if (!dDebugPad.Active()) { - Debug_console(PAD_3); - } - #else - Debug_console(PAD_3); - #endif - - #if DEBUG - fapGm_HIO_c::startCpuTimer(); - - if (fapGmHIO_getHostIO()) { - JKRHeap* var_r30 = mDoExt_getHostIOHeap(); - JKRHeap* var_r29 = mDoExt_setCurrentHeap(var_r30); - JOR_MESSAGELOOP(); - mDoExt_setCurrentHeap(var_r29); - } - - fapGm_HIO_c::printCpuTimer(""); - fapGm_HIO_c::stopCpuTimer("ホストIO"); - fapGm_HIO_c::printCpuTimer("\n↑↑↑↑↑↑↑↑↑↑ CPU時間計測終了 ↑↑↑↑↑↑↑↑↑↑\n"); - fapGm_HIO_c::offCpuTimer(); - #endif - } -} - -// linker generated symbols -extern u8 _f_text[]; -extern u8 _e_text[]; -extern u8 _f_ctors[]; -extern u8 _e_ctors[]; -extern u8 _f_dtors[]; -extern u8 _e_dtors[]; -extern u8 _f_rodata[]; -extern u8 _e_rodata[]; - -#if VERSION == VERSION_SHIELD_DEBUG -const int audioHeapSize = 0x169000; -#else -const int audioHeapSize = 0x14D800; -#endif - -void main01(void) { - OS_REPORT("\x1b[m"); - - // Setup heaps, setup exception manager, set RNG seed, setup DVDError Thread, setup Memory card Thread - mDoMch_Create(); - - #if DEBUG - FixedMemoryCheck* local_20 = FixedMemoryCheck::easyCreate(_f_text, intptr_t(_e_text - _f_text)); - FixedMemoryCheck* local_24 = FixedMemoryCheck::easyCreate(_f_ctors, intptr_t(_e_ctors - _f_ctors)); - FixedMemoryCheck* local_28 = FixedMemoryCheck::easyCreate(_f_dtors, intptr_t(_e_dtors - _f_dtors)); - FixedMemoryCheck* local_2c = FixedMemoryCheck::easyCreate(_f_rodata, intptr_t(_e_rodata - _f_rodata)); - #endif - - // setup FrameBuffer and ZBuffer, init display lists - mDoGph_Create(); - - // Setup control pad - mDoCPd_c::create(); - - RootHeapCheck.setHeap((JKRExpHeap*)JKRGetRootHeap()); - SystemHeapCheck.setHeap((JKRExpHeap*)JKRGetSystemHeap()); - ZeldaHeapCheck.setHeap(mDoExt_getZeldaHeap()); - GameHeapCheck.setHeap(mDoExt_getGameHeap()); - ArchiveHeapCheck.setHeap(mDoExt_getArchiveHeap()); - J2dHeapCheck.setHeap(mDoExt_getJ2dHeap()); - HostioHeapCheck.setHeap(mDoExt_getHostIOHeap()); - CommandHeapCheck.setHeap(mDoExt_getCommandHeap()); - - #if DEBUG - JKRHeap* var_r28 = mDoExt_getHostIOHeap(); - JKRHeap* sp10 = mDoExt_setCurrentHeap(var_r28); - JOR_INIT(); - JOR_SETROOTNODE("root", &mDoHIO_root, 4, 3); - mDoExt_setCurrentHeap(sp10); - - var_r28->dump_sort(); - s32 local_34 = var_r28->getTotalFreeSize(); - OSReport("\x1b[36mHOSTIOヒープ残り %u Bytes\n\x1b[m", local_34); - #endif - - JUTConsole* console = JFWSystem::getSystemConsole(); - console->setOutput(mDoMain::developmentMode ? JUTConsole::OUTPUT_OSR_AND_CONSOLE : - JUTConsole::OUTPUT_NONE); - console->setPosition(32, 42); - - mDoDvdThd_callback_c::create((mDoDvdThd_callback_func)LOAD_COPYDATE, NULL); - fapGm_Create(); // init framework - - #if DEBUG - mDoMain_HIO.entryHIO("メイン"); - g_regHIO.id = mDoHIO_createChild("レジスタ", &g_regHIO); - g_presetHIO.field_0x4 = mDoHIO_createChild("状況ファイル", &g_presetHIO); - #endif - - fopAcM_initManager(); - mDisplayHeapSize = 0; - cDyl_InitAsync(); // init RELs - - g_mDoAud_audioHeap = JKRCreateSolidHeap(audioHeapSize, JKRGetCurrentHeap(), false); - - do { - static u32 frame; - frame++; - - #if DEBUG - if (memorycheck_check_frame != 0 && frame % memorycheck_check_frame == 0) { - FixedMemoryCheck::checkAll(); - } - #endif - - if (fillcheck_check_frame != 0 && frame % fillcheck_check_frame == 0) { - mDoMch_HeapCheckAll(); - } - - if (mDoDvdThd::SyncWidthSound) { - mDoMemCd_UpDate(); - } - - mDoCPd_c::read(); // read controller input - - #if DEBUG - if (mDoMch::GXWarningExecuteFrame) { - GXSetVerifyLevel(GX_WARN_ALL); - } - #endif - - fapGm_Execute(); // handle game execution - - #if DEBUG - if (mDoMch::GXWarningExecuteFrame) { - mDoMch::GXWarningExecuteFrame = 0; - GXSetVerifyLevel((GXWarningLevel)mDoMch::GXWarningLevel); - } - #endif - - #if DEBUG - fapGm_HIO_c::startCpuTimer(); - #endif - - mDoAud_Execute(); // handle audio execution - - #if DEBUG - fapGm_HIO_c::printCpuTimer(""); - fapGm_HIO_c::stopCpuTimer("オーディオ"); - #endif - - debug(); // run debugger - } while (true); -} - -#if !__MWERKS__ template JHIComPortManager* JHIComPortManager::instance = nullptr; template<> JHIComPortManager* JHIComPortManager::instance = nullptr; -#endif - -#if DEBUG -JHIComPortManager* JHIComPortManager:: instance; -// DEBUG NONMATCHING -void parse_args(int argc, const char* argv[]) { - int i; - - OS_REPORT("argc = %d\n", argc); - for (i = 0; i < argc; i++) { - OS_REPORT("argv[%d] = %s\n", i, argv[i]); - } - - for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "--noopening") == 0) { - dScnLogo_c::onOpeningCut(); - } else if (strcmp(argv[i], "--nobank") == 0) { - dStage_roomControl_c::onNoArcBank(); - OS_REPORT("\x1b[33mアーカイブバンクを無効にしました\n\x1b[m"); - } else if (strcmp(argv[i], "--particle254") == 0) { - fapGm_HIO_c::mParticle254Fix = 1; - OSReport_Warning("パーティクル254固定にしました\n"); - } else if (strncmp(argv[i], "--menu=", sizeof("--menu=") - 1) == 0) { - char* var_r27 = strchr(argv[i] + 7, ','); - if (var_r27 != NULL) { - *var_r27 = 0; - var_r27++; - - char* var_r26 = std::strchr(var_r27, ','); - if (var_r26 != NULL) { - *var_r26 = 0; - var_r26++; - - char* spC = std::strchr(var_r26, ','); - if (spC != NULL) { - *spC = 0; - spC++; - sscanf(spC, "%d", &dScnMenu_c::cursolPoint); - dScnMenu_c::m_error_flags |= (u8)8; - } - - sscanf(var_r26, "%d", &dScnMenu_c::cursolLayer); - dScnMenu_c::m_error_flags |= (u8)4; - } - - sscanf(var_r27, "%d", &dScnMenu_c::cursolRoomNo); - dScnMenu_c::m_error_flags |= (u8)2; - } - - strcpy(dScnMenu_c::cursolStageName, argv[i] + 7); - dScnMenu_c::m_error_flags |= (u8)1; - - OS_REPORT("\n\n\ndScnMenu_c::cursolLayer=[%x]", dScnMenu_c::cursolLayer); - OS_REPORT("\ndScnMenu_c::cursolRoomNo=[%x]", dScnMenu_c::cursolRoomNo); - OS_REPORT("\ndScnMenu_c::cursolStageName=[%s]\n\n", dScnMenu_c::cursolStageName); - } else if (strncmp(argv[i], "--situation=", sizeof("--situation=") - 1) == 0) { - for (int j = 0; j < 100; j++) { - if (argv[i][12 + j] <= ' ') { - break; - } - - g_presetHIO.filename_buf[j] = argv[i][12 + j]; - } - - OS_REPORT("\n11 g_presetHIO.filename_buf[0]=[%-100.100s]", g_presetHIO.filename_buf); - } else if (strcmp(argv[i], "--noprint") == 0) { - OSReportDisable(); - } else if (strcmp(argv[i], "--develop") == 0) { - mDoMain::developmentMode = 1; - } else if (strcmp(argv[i], "--nodevelop") == 0) { - mDoMain::developmentMode = 0; - } else if (strncmp(argv[i], "--e3argument=", sizeof("--e3argument=") - 1) == 0) { - sscanf(argv[i] + sizeof("--e3argument=") - 1, "%d", &mDoMain::argument); - } else if (strncmp(argv[i], "--gameheapsize=0x", sizeof("--gameheapsize=0x") - 1) == 0) { - sscanf(argv[i] + sizeof("--gameheapsize=0x") - 1, "%x", &mDoMain::gameHeapSize); - } else if (strncmp(argv[i], "--archiveheapsize=0x", sizeof("--archiveheapsize=0x") - 1) == 0) { - sscanf(argv[i] + sizeof("--archiveheapsize=0x") - 1, "%x", &mDoMain::archiveHeapSize); - } else if (strncmp(argv[i], "--memmargin=0x", sizeof("--memmargin=0x") - 1) == 0) { - sscanf(argv[i] + sizeof("--memmargin=0x") - 1, "%x", &mDoMain::memMargin); - } else if (strncmp(argv[i], "--e3menu=0x", sizeof("--e3menu=0x") - 1) == 0) { - sscanf(argv[i] + sizeof("--e3menu=0x") - 1, "%x", &mDoMain::e3menu_no); - } else { - OSReport_Error("unknown argument %d, %s\n", i, argv[i]); - } - } -} -#endif - -static u8 mainThreadStack[32768]; - -OSThread mainThread; - -extern "C" void game_main(int argc, const char* argv[]) { - OSThread* current_thread = OSGetCurrentThread(); - u8* stack = mainThreadStack; - mDoMain::sPowerOnTime = OSGetTime(); - OSReportInit(); - version_check(); - - #if PLATFORM_WII || PLATFORM_SHIELD - mDoRst::setResetData((mDoRstData*)OSAllocFromMEM1ArenaLo(0x18, 4)); - #else - mDoRst::setResetData((mDoRstData*)OSAllocFromArenaLo(0x18, 4)); - #endif - - if (!mDoRst::getResetData()) { - do { - } while (true); - } - - if (!((OSGetResetCode() & 0x80000000) ? 1 : 0)) { - mDoRst::offReset(); - mDoRst::offResetPrepare(); - mDoRst::off3ButtonReset(); - mDoRst::set3ButtonResetPort(-1); - mDoRst::setLogoScnFlag(0); - mDoRst::setProgSeqFlag(0); - mDoRst::setProgChgFlag(0); - mDoRst::setWarningDispFlag(0); - mDoRst::offShutdown(); - mDoRst::offReturnToMenu(); - } - - #if PLATFORM_WII || PLATFORM_SHIELD - SCInit(); - #endif - - dComIfG_ct(); - - #if PLATFORM_WII || PLATFORM_SHIELD - u32 status; - do { - status = SCCheckStatus(); - } while (status != 0); - JUT_ASSERT(1785, status != 2); - #endif - - #if DEBUG - parse_args(argc, argv); - #endif - - if (mDoMain::developmentMode < 0) { - DVDDiskID* disk_id = DVDGetCurrentDiskID(); - - if (disk_id->gameVersion > 0x90) { - mDoMain::developmentMode = 1; - } else if (disk_id->gameVersion > 0x80) { - mDoMain::developmentMode = (OSGetConsoleType() & OS_CONSOLE_DEVELOPMENT) != 0; - } else { - mDoMain::developmentMode = 0; - } - } - - OS_REPORT("メインスレッドを作成します\n"); - OSCreateThread(&mainThread, (void*(*)(void*))main01, 0, stack + sizeof(mainThreadStack), sizeof(mainThreadStack), OSGetThreadPriority(current_thread), 0); - OSResumeThread(&mainThread); - OS_REPORT("メインスレッドを起動しました <%x>\n", &mainThread); - OSSetThreadPriority(current_thread, 0x1F); - OSSuspendThread(current_thread); -} - -bool JKRHeap::dump_sort() { - return true; -} template<> Z2WolfHowlMgr* JASGlobalInstance::sInstance;