diff --git a/.gitignore b/.gitignore index a381014599..a1839ff34e 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,5 @@ compile_commands.json *.ini *.controller pipeline_cache.bin + +extract diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a074ea869..66c86bb5f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,7 +94,7 @@ message(STATUS "dusk: TP Version: ${DUSK_TP_VERSION}") source_group("dolzel" FILES ${DOLZEL_FILES} ${Z2AUDIOLIB_FILES} ${JSYSTEM_FILES} ${JSYSTEM_DEBUG_FILES} ${REL_FILES}) source_group("dusk" FILES ${DUSK_FILES}) -set(GAME_COMPILE_DEFS TARGET_PC AVOID_UB=1 VERSION=0 +set(GAME_COMPILE_DEFS TARGET_PC WIDESCREEN_SUPPORT=1 AVOID_UB=1 VERSION=0 DUSK_TP_VERSION="${DUSK_TP_VERSION}" DUSK_GAME_NAME="${DUSK_GAME_NAME}" DUSK_GAME_VERSION="${DUSK_GAME_VERSION}") set(GAME_INCLUDE_DIRS @@ -104,9 +104,7 @@ set(GAME_INCLUDE_DIRS libs/JSystem/include libs extern/aurora/include/dolphin - extern - ${CMAKE_SOURCE_DIR}/build/${DUSK_TP_VERSION}/include - build/${DUSK_TP_VERSION}/include) + extern) set(GAME_LIBS aurora::core aurora::gx aurora::gd aurora::si aurora::vi aurora::pad aurora::mtx aurora::os aurora::dvd aurora::card freeverb cxxopts::cxxopts absl::flat_hash_map nlohmann_json::nlohmann_json) @@ -139,8 +137,8 @@ add_library(game_base OBJECT ${DOLZEL_FILES} ${Z2AUDIOLIB_FILES} ${JSYSTEM_FILES src/dusk/imgui/ImGuiStubLog.cpp src/dusk/imgui/ImGuiAudio.cpp) -target_compile_definitions(game_debug PRIVATE ${GAME_COMPILE_DEFS} $<$:DEBUG=1>) -target_compile_definitions(game_base PRIVATE ${GAME_COMPILE_DEFS} NDEBUG=1 NDEBUG_DEFINED=1 DEBUG_DEFINED=0) +target_compile_definitions(game_debug PRIVATE ${GAME_COMPILE_DEFS} $<$:DEBUG=1> $<$:PARTIAL_DEBUG=1>) +target_compile_definitions(game_base PRIVATE ${GAME_COMPILE_DEFS} NDEBUG=1 NDEBUG_DEFINED=1 DEBUG_DEFINED=0 $<$:PARTIAL_DEBUG=1>) # only apply PCH to game_base since not all headers are necessarily validated with DEBUG=1 target_precompile_headers(game_base PRIVATE "$<$:${CMAKE_SOURCE_DIR}/include/dusk_pch.hpp>") diff --git a/README.md b/README.md index 200913770a..59f12abc2a 100644 --- a/README.md +++ b/README.md @@ -37,25 +37,24 @@ sudo dnf groupinstall "Development Tools" "Development Libraries" ``` #### Setup -1. Clone and initialize the Dusk repository +Clone and initialize the Dusk repository ```sh git clone --recursive https://github.com/TakaRikka/dusk.git cd dusk git pull git submodule update --recursive ``` -2. Generate assets -```sh -cp /path/to/GZ2E01.iso orig/GZ2E01/. -python3 ./configure.py -ninja -``` #### Building **Visual Studio (Recommended for Windows)** ```sh cmake -B build/dusk -G "Visual Studio 17 2022" -A x64 # Win32 for 32bit ``` + +**Visual Studio Code with ninja** + +Project has support for the CMakeTools extension with variants and has a debug launch target + **ninja (Windows/macOS/Linux)** ```sh cmake -B build/dusk -GNinja diff --git a/configure.py b/configure.py index 313d24f55c..147b7150e7 100755 --- a/configure.py +++ b/configure.py @@ -1,5 +1,9 @@ #!/usr/bin/env python3 +print("You do not need to run configure.py for Dusk! This file is here to avoid conflicts with decomp.") +print("Use CMake to configure your build instead.") +exit(1) + ### # Generates build files for the project. # This file also includes the project configuration, diff --git a/extern/aurora b/extern/aurora index b17da31593..b1bf531884 160000 --- a/extern/aurora +++ b/extern/aurora @@ -1 +1 @@ -Subproject commit b17da315932b85d7d708eaf3e44914f70045a44e +Subproject commit b1bf531884172075dd97403edddc7d3301f4ca46 diff --git a/files.cmake b/files.cmake index c6cf3b5d3d..ee2f5ee39a 100644 --- a/files.cmake +++ b/files.cmake @@ -1333,6 +1333,8 @@ set(DOLPHIN_FILES set(DUSK_FILES include/dusk/endian_gx.hpp include/dusk/config.hpp + include/dusk/dvd_asset.hpp + src/dusk/dvd_asset.cpp src/d/actor/d_a_alink_dusk.cpp src/dusk/asserts.cpp src/dusk/config.cpp diff --git a/include/SSystem/SComponent/c_cc_s.h b/include/SSystem/SComponent/c_cc_s.h index 62815fb3b6..525781279b 100644 --- a/include/SSystem/SComponent/c_cc_s.h +++ b/include/SSystem/SComponent/c_cc_s.h @@ -15,7 +15,7 @@ public: /* 0x0400 */ cCcD_Obj* mpObjTg[0x300]; /* 0x1000 */ cCcD_Obj* mpObjCo[0x100]; /* 0x1400 */ cCcD_Obj* mpObj[0x500]; -#if DEBUG +#if TARGET_PC || DEBUG /* 0x2800 */ u32 m_debug_code; #endif /* 0x2800 */ u16 mObjAtCount; diff --git a/include/d/d_bright_check.h b/include/d/d_bright_check.h index d8686944e6..dc9ae941cf 100644 --- a/include/d/d_bright_check.h +++ b/include/d/d_bright_check.h @@ -29,6 +29,9 @@ public: void _move(); void modeWait(); void modeMove(); + #if TARGET_PC + void brightCheckWide(); + #endif void _draw(); void draw() { diff --git a/include/d/d_camera.h b/include/d/d_camera.h index 37b634d18f..85e930c395 100644 --- a/include/d/d_camera.h +++ b/include/d/d_camera.h @@ -1154,7 +1154,7 @@ public: static engine_fn engine_tbl[]; /* 0x000 */ camera_class* field_0x0; -#if DEBUG +#if PARTIAL_DEBUG || DEBUG // Ensure struct layout consistent in all TUs. cXyz dbg_field_0x04[16]; s8 dbg_field_0xc4[0x10]; u32 dbg_field_0xd4; diff --git a/include/d/d_file_select.h b/include/d/d_file_select.h index 810831a830..72f7cb7f42 100644 --- a/include/d/d_file_select.h +++ b/include/d/d_file_select.h @@ -367,6 +367,9 @@ public: void menuCursorShow(); void yesnoWakuAlpahAnmInit(u8, u8, u8, u8); bool yesnoWakuAlpahAnm(u8); + #if TARGET_PC + void fileSelectWide(); + #endif void _draw(); void errorMoveAnmInitSet(int, int); bool errorMoveAnm(); diff --git a/include/d/d_menu_collect.h b/include/d/d_menu_collect.h index 01ee32f6d4..55d5373c71 100644 --- a/include/d/d_menu_collect.h +++ b/include/d/d_menu_collect.h @@ -29,6 +29,11 @@ public: class dMenu_Collect2D_c : public dDlst_base_c { public: dMenu_Collect2D_c(JKRExpHeap*, STControl*, CSTControl*); + + #if TARGET_PC + void menuCollectWide(); + #endif + void _create(); void _delete(); void initialize(); @@ -45,7 +50,11 @@ public: void changeShield(); void changeClothe(); void setArrowMaxNum(u8); +#if TARGET_PC + void setWalletSizeNum(u16); +#else void setWalletMaxNum(u16); +#endif void setSmellType(); void setHeartPiece(); void setPohMaxNum(u8); diff --git a/include/d/d_menu_save.h b/include/d/d_menu_save.h index a6b174bbf4..4a70d1d045 100644 --- a/include/d/d_menu_save.h +++ b/include/d/d_menu_save.h @@ -263,6 +263,11 @@ public: void setSaveData(); void setInitSaveData(); void _draw(); + + #if TARGET_PC + void menuSaveWide(); + #endif + void _draw2(); virtual ~dMenu_save_c() {} diff --git a/include/d/d_name.h b/include/d/d_name.h index 0d877e6b09..e685871738 100644 --- a/include/d/d_name.h +++ b/include/d/d_name.h @@ -110,6 +110,11 @@ public: void menuCursorMove(); void menuCursorMove2(); void selectCursorPosSet(int); + + #if TARGET_PC + void nameWide(); + #endif + void _draw(); void screenSet(); void displayInit(); diff --git a/include/dusk/audio/DuskAudioSystem.h b/include/dusk/audio/DuskAudioSystem.h index 1b31db6e7c..724776f5f1 100644 --- a/include/dusk/audio/DuskAudioSystem.h +++ b/include/dusk/audio/DuskAudioSystem.h @@ -8,6 +8,8 @@ namespace dusk::audio { */ void Initialize(); + void SetEnableReverb(bool value); + void SetMasterVolume(f32 value); u32 GetResetCount(int channelIdx); diff --git a/include/dusk/dusk.h b/include/dusk/dusk.h index 7fc2a23070..b751990d9c 100644 --- a/include/dusk/dusk.h +++ b/include/dusk/dusk.h @@ -3,7 +3,22 @@ #include +#include "aurora/gfx.h" + extern AuroraInfo auroraInfo; extern const char* configPath; +namespace dusk { + extern AuroraStats lastFrameAuroraStats; + extern float frameUsagePct; +} + +constexpr u32 defaultWindowWidth = 608; +constexpr u32 defaultWindowHeight = 448; + +constexpr u32 defaultAspectRatioW = 19; +constexpr u32 defaultAspectRatioH = 14; + +static_assert(defaultWindowWidth / defaultAspectRatioW == defaultWindowHeight / defaultAspectRatioH); + #endif // DUSK_DUSK_H diff --git a/include/dusk/dvd_asset.hpp b/include/dusk/dvd_asset.hpp new file mode 100644 index 0000000000..014c683d44 --- /dev/null +++ b/include/dusk/dvd_asset.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "dolphin/types.h" + +namespace dusk { + +/** + * Load bytes from the main DOL by GameCube virtual address + */ +bool LoadDolAsset(void* dst, u32 virtualAddress, s32 size); + +/** + * Load bytes from a REL file in the ISO filesystem, dst must be 32-byte aligned + */ +bool LoadRelAsset(void* dst, const char* dvdPath, s32 offset, s32 size); + +/** + * Load bytes from a REL inside RELS.arc + */ +bool LoadArchivedRelAsset(void* dst, u32 memType, const char* relFileName, s32 offset, s32 size); + +} // namespace dusk diff --git a/include/dusk/hotkeys.h b/include/dusk/hotkeys.h index c40f35925f..6e98d62521 100644 --- a/include/dusk/hotkeys.h +++ b/include/dusk/hotkeys.h @@ -3,7 +3,11 @@ namespace dusk::hotkeys { +#if __APPLE__ +constexpr const char* DO_RESET = "Cmd+R"; +#else constexpr const char* DO_RESET = "Ctrl+R"; +#endif constexpr const char* TOGGLE_FULLSCREEN = "F11"; diff --git a/include/dusk/settings.h b/include/dusk/settings.h index cf4d79f6ac..8b818801a7 100644 --- a/include/dusk/settings.h +++ b/include/dusk/settings.h @@ -15,6 +15,8 @@ struct UserSettings { struct { // Video ConfigVar enableFullscreen; + ConfigVar enableVsync; + ConfigVar lockAspectRatio; } video; struct { @@ -42,6 +44,7 @@ struct UserSettings { ConfigVar fastClimbing; ConfigVar noMissClimbing; ConfigVar fastTears; + ConfigVar instantSaves; // Preferences ConfigVar enableMirrorMode; @@ -58,6 +61,8 @@ struct UserSettings { // Cheats ConfigVar enableFastIronBoots; ConfigVar canTransformAnywhere; + ConfigVar fastSpinner; + ConfigVar freeMagicArmor; // Technical ConfigVar restoreWiiGlitches; diff --git a/include/m_Do/m_Do_graphic.h b/include/m_Do/m_Do_graphic.h index 3d560efeb6..421e1ae47f 100644 --- a/include/m_Do/m_Do_graphic.h +++ b/include/m_Do/m_Do_graphic.h @@ -8,7 +8,7 @@ #include #endif -#if WIDESCREEN_SUPPORT +#if WIDESCREEN_SUPPORT && !TARGET_PC #define FB_WIDTH (640) #define FB_HEIGHT (456) #else @@ -117,6 +117,13 @@ public: static void setTickRate(u32 rate) { JFWDisplay::getManager()->setTickRate(rate); } static void waitBlanking(int wait) { JFWDisplay::getManager()->waitBlanking(wait); } +#if TARGET_PC + static f32 hudAspectScaleDown; + static f32 hudAspectScaleUp; + static f32 ScaleHUDXLeft(f32 baseX) { return getMinXF() + baseX; } + static f32 ScaleHUDXRight(f32 baseX) { return -getMinXF() + baseX; } +#endif + static void setBlureMtx(const Mtx m) { cMtx_copy(m, mBlureMtx); } @@ -266,7 +273,12 @@ public: #if WIDESCREEN_SUPPORT static void setTvSize(); + #if TARGET_PC + static void onWide(f32 width, f32 height); + #else static void onWide(); + #endif + static void offWide(); static u8 isWide(); diff --git a/include/m_Do/m_Do_machine.h b/include/m_Do/m_Do_machine.h index 53c47c07a7..eeea7e77ce 100644 --- a/include/m_Do/m_Do_machine.h +++ b/include/m_Do/m_Do_machine.h @@ -15,6 +15,9 @@ void my_SysPrintHeap(char const*, void*, u32); void mDoMch_HeapCheckAll(); void mDoMch_HeapFreeFillAll(); int mDoMch_Create(); +#if TARGET_PC +void mDoMch_Destroy(); +#endif extern GXRenderModeObj g_ntscZeldaProg; diff --git a/libs/JSystem/include/JSystem/JFramework/JFWSystem.h b/libs/JSystem/include/JSystem/JFramework/JFWSystem.h index bb4dfa01cd..288b5f03d8 100644 --- a/libs/JSystem/include/JSystem/JFramework/JFWSystem.h +++ b/libs/JSystem/include/JSystem/JFramework/JFWSystem.h @@ -33,6 +33,9 @@ struct JFWSystem { static void firstInit(); static void init(); +#if TARGET_PC + static void shutdown(); +#endif static JUTConsole* getSystemConsole() { return systemConsole; } static JKRExpHeap* getSystemHeap() { return systemHeap; } diff --git a/libs/JSystem/include/JSystem/JKernel/JKRAram.h b/libs/JSystem/include/JSystem/JKernel/JKRAram.h index 9c8ebd88d1..dd3bf54f9c 100644 --- a/libs/JSystem/include/JSystem/JKernel/JKRAram.h +++ b/libs/JSystem/include/JSystem/JKernel/JKRAram.h @@ -39,6 +39,9 @@ public: public: static JKRAram* create(u32, u32, s32, s32, s32); +#if TARGET_PC + static void destroy(); +#endif static void checkOkAddress(u8*, u32, JKRAramBlock*, u32); static void changeGroupIdIfNeed(u8*, int); static JKRAramBlock* mainRamToAram(u8*, u32, u32, JKRExpandSwitch, u32, JKRHeap*, int, u32*); diff --git a/libs/JSystem/include/JSystem/JKernel/JKRDecomp.h b/libs/JSystem/include/JSystem/JKernel/JKRDecomp.h index 9131ecfbaa..2e7ce0ef1c 100644 --- a/libs/JSystem/include/JSystem/JKernel/JKRDecomp.h +++ b/libs/JSystem/include/JSystem/JKernel/JKRDecomp.h @@ -48,6 +48,9 @@ private: public: static JKRDecomp* create(s32); +#if TARGET_PC + static void destroy(); +#endif static JKRDecompCommand* prepareCommand(u8*, u8*, u32, u32, JKRDecompCommand::AsyncCallback); static void sendCommand(JKRDecompCommand*); static bool sync(JKRDecompCommand*, int); diff --git a/libs/JSystem/include/JSystem/JUtility/JUTResFont.h b/libs/JSystem/include/JSystem/JUtility/JUTResFont.h index 09d3303da0..8709822d7b 100644 --- a/libs/JSystem/include/JSystem/JUtility/JUTResFont.h +++ b/libs/JSystem/include/JSystem/JUtility/JUTResFont.h @@ -18,6 +18,10 @@ struct BlockHeader { BE(u32) size; }; +#if TARGET_PC +struct GlyphTextures; +#endif + /** * @ingroup jsystem-jutility * @@ -64,7 +68,11 @@ public: // some types uncertain, may need to be fixed /* 0x1C */ int mWidth; /* 0x20 */ int mHeight; +#if TARGET_PC + GlyphTextures* mGlyphTextures; +#else /* 0x24 */ TGXTexObj mTexObj; +#endif /* 0x44 */ int mTexPageIdx; /* 0x48 */ const ResFONT* mResFont; /* 0x4C */ ResFONT::INF1* mInf1Ptr; diff --git a/libs/JSystem/src/J3DGraphLoader/J3DModelLoader.cpp b/libs/JSystem/src/J3DGraphLoader/J3DModelLoader.cpp index 72a48007c0..3d064e33de 100644 --- a/libs/JSystem/src/J3DGraphLoader/J3DModelLoader.cpp +++ b/libs/JSystem/src/J3DGraphLoader/J3DModelLoader.cpp @@ -242,7 +242,7 @@ void J3DModelLoader::setupBBoardInfo() { J3DMaterial* mesh = mpModelData->getJointNodePointer(i)->getMesh(); if (mesh != NULL) { u32 shape_index = mesh->getShape()->getIndex(); - u16* index_table = JSUConvertOffsetToPtr(mpShapeBlock, + BE(u16)* index_table = JSUConvertOffsetToPtr(mpShapeBlock, (uintptr_t)mpShapeBlock->mpIndexTable); J3DShapeInitData* shape_init_data = JSUConvertOffsetToPtr(mpShapeBlock, diff --git a/libs/JSystem/src/JAudio2/JASSeqParser.cpp b/libs/JSystem/src/JAudio2/JASSeqParser.cpp index 7b417f2c82..b2077ce499 100644 --- a/libs/JSystem/src/JAudio2/JASSeqParser.cpp +++ b/libs/JSystem/src/JAudio2/JASSeqParser.cpp @@ -813,9 +813,15 @@ s32 JASSeqParser::cmdDump(JASTrack* param_0, u32* param_1) { } s32 JASSeqParser::cmdPrintf(JASTrack* param_0, u32* param_1) { +#if AVOID_UB + u8 stack_c[4] = {0}; + u32 stack_10[4] = {0}; + char buffer[128] = {0}; +#else u8 stack_c[4]; u32 stack_10[4]; char buffer[128]; +#endif JASSeqCtrl* seqCtrl = param_0->getSeqCtrl(); u32 r30 = 0; @@ -884,6 +890,19 @@ s32 JASSeqParser::cmdPrintf(JASTrack* param_0, u32* param_1) { s32 JASSeqParser::execNoteOnGate(JASTrack* param_0, u32 param_1, u32 param_2, u32 param_3, u32 param_4) { JASSeqCtrl* seqCtrl = param_0->getSeqCtrl(); + + int r31 = 0; + +#if TARGET_PC + // CodeWarrior on PPC allocates MSB-first for bit fields i think, which is stupid + // so in reality these are stored in bit 6 and 7 not but 0 and 1, do this to get around it + if (param_4 & 0x40) { + r31 |= 2; + } + if (param_4 & 0x80) { + r31 |= 1; + } +#else // likely fake match, this may use some actual union defined somewhere else union { u8 val; @@ -893,13 +912,13 @@ s32 JASSeqParser::execNoteOnGate(JASTrack* param_0, u32 param_1, u32 param_2, u3 } bits; } tmp; tmp.val = param_4; - int r31 = 0; if (tmp.bits.bit1) { r31 |= 2; } if (tmp.bits.bit0) { r31 |= 1; } +#endif if (param_3 == 0) { r31 |= 4; } diff --git a/libs/JSystem/src/JFramework/JFWDisplay.cpp b/libs/JSystem/src/JFramework/JFWDisplay.cpp index 6a257f5244..26788f9f38 100644 --- a/libs/JSystem/src/JFramework/JFWDisplay.cpp +++ b/libs/JSystem/src/JFramework/JFWDisplay.cpp @@ -13,6 +13,7 @@ #include "JSystem/JUtility/JUTDbPrint.h" #include "JSystem/JUtility/JUTProcBar.h" #include "aurora/aurora.h" +#include "dusk/dusk.h" #include "dusk/gx_helper.h" #include "dusk/logging.h" #include "dusk/settings.h" @@ -358,10 +359,12 @@ static void waitForTick(u32 p1, u16 p2) { { static OSTime nextTick = OSGetTime(); OSTime time = OSGetTime(); + OSTime waitTime = (nextTick > time) ? (nextTick - time) : 0; while (time < nextTick) { JFWDisplay::getManager()->threadSleep((nextTick - time)); time = OSGetTime(); } + dusk::frameUsagePct = 100.0f * (1.0f - (float)waitTime / (float)p1); nextTick = time + p1; } else { static u32 nextCount = VIGetRetraceCount(); @@ -374,6 +377,7 @@ static void waitForTick(u32 p1, u16 p2) { msg = 0; } } while (((intptr_t)msg - (intptr_t)nextCount) < 0); + dusk::frameUsagePct = 100.0f; nextCount = (intptr_t)msg + uVar1; } } diff --git a/libs/JSystem/src/JFramework/JFWSystem.cpp b/libs/JSystem/src/JFramework/JFWSystem.cpp index b4effd547a..d6322f34c9 100644 --- a/libs/JSystem/src/JFramework/JFWSystem.cpp +++ b/libs/JSystem/src/JFramework/JFWSystem.cpp @@ -116,3 +116,9 @@ void JFWSystem::init() { void* buffer = systemHeap->alloc(CSetUpParam::exConsoleBufferSize, 4); JUTException::createConsole(buffer, CSetUpParam::exConsoleBufferSize); } + +#if TARGET_PC +void JFWSystem::shutdown() { + JKRAram::destroy(); +} +#endif diff --git a/libs/JSystem/src/JKernel/JKRAram.cpp b/libs/JSystem/src/JKernel/JKRAram.cpp index 32afe1cef4..2770328afa 100644 --- a/libs/JSystem/src/JKernel/JKRAram.cpp +++ b/libs/JSystem/src/JKernel/JKRAram.cpp @@ -42,6 +42,12 @@ JKRAram* JKRAram::create(u32 aram_audio_buffer_size, u32 aram_audio_graph_size, return sAramObject; } +#if TARGET_PC +void JKRAram::destroy() { + JKRDecomp::destroy(); +} +#endif + OSMessage JKRAram::sMessageBuffer[4] = { NULL, NULL, diff --git a/libs/JSystem/src/JKernel/JKRDecomp.cpp b/libs/JSystem/src/JKernel/JKRDecomp.cpp index 776823531d..a97edea0a3 100644 --- a/libs/JSystem/src/JKernel/JKRDecomp.cpp +++ b/libs/JSystem/src/JKernel/JKRDecomp.cpp @@ -20,6 +20,15 @@ JKRDecomp* JKRDecomp::create(s32 priority) { return sDecompObject; } +#if TARGET_PC +void JKRDecomp::destroy() { + if (sDecompObject) { + OSSendMessage(&sMessageQueue, nullptr, OS_MESSAGE_NOBLOCK); + OSJoinThread(sDecompObject->getThreadRecord(), nullptr); + } +} +#endif + OSMessage JKRDecomp::sMessageBuffer[8] = {0}; OSMessageQueue JKRDecomp::sMessageQueue = {0}; @@ -34,15 +43,15 @@ void* JKRDecomp::run() { OSInitMessageQueue(&sMessageQueue, sMessageBuffer, 8); for (;;) { OSMessage message; -#ifdef TARGET_PC - if (!OSReceiveMessage(&sMessageQueue, &message, OS_MESSAGE_BLOCK)) { - break; - } -#else OSReceiveMessage(&sMessageQueue, &message, OS_MESSAGE_BLOCK); -#endif JKRDecompCommand* command = (JKRDecompCommand*)message; +#if TARGET_PC + if (!command) { + break; + } +#endif + decode(command->mSrcBuffer, command->mDstBuffer, command->mSrcLength, command->mDstLength); if (command->field_0x20 != 0) { diff --git a/libs/JSystem/src/JUtility/JUTException.cpp b/libs/JSystem/src/JUtility/JUTException.cpp index 509acbfb3e..514ec6dd8a 100644 --- a/libs/JSystem/src/JUtility/JUTException.cpp +++ b/libs/JSystem/src/JUtility/JUTException.cpp @@ -101,6 +101,9 @@ JUTException* JUTException::create(JUTDirectPrint* directPrint) { OSMessage JUTException::sMessageBuffer[1] = {0}; void* JUTException::run() { +#ifdef TARGET_PC + return NULL; +#else u32 msr = PPCMfmsr(); msr &= ~0x0900; PPCMtmsr(msr); @@ -132,6 +135,7 @@ void* JUTException::run() { sErrorManager->mDirectPrint->changeFrameBuffer(mFrameMemory); sErrorManager->printContext(error, context, r24, r23); } +#endif } void* JUTException::sConsoleBuffer; @@ -145,6 +149,7 @@ u32 JUTException::msr; u32 JUTException::fpscr; void JUTException::errorHandler(OSError error, OSContext* context, u32 param_3, u32 param_4) { +#ifndef TARGET_PC msr = PPCMfmsr(); fpscr = context->fpscr; OSFillFPUContext(context); @@ -165,6 +170,7 @@ void JUTException::errorHandler(OSError error, OSContext* context, u32 param_3, OSSendMessage(&sMessageQueue, &exCallbackObject, OS_MESSAGE_BLOCK); OSEnableScheduler(); OSYieldThread(); +#endif } void JUTException::panic_f_va(char const* file, int line, char const* format, va_list args) { @@ -234,6 +240,7 @@ void JUTException::showFloatSub(int index, f32 value) { } void JUTException::showFloat(OSContext* context) { +#ifndef TARGET_PC if (!sConsole) { return; } @@ -251,6 +258,7 @@ void JUTException::showFloat(OSContext* context) { sConsole->print(" "); showFloatSub(21, context->fpr[21]); sConsole->print("\n"); +#endif } bool JUTException::searchPartialModule(u32 address, u32* module_id, u32* section_id, @@ -333,6 +341,7 @@ void JUTException::showStack(OSContext* context) { } void JUTException::showMainInfo(u16 error, OSContext* context, u32 dsisr, u32 dar) { +#ifndef TARGET_PC if (!sConsole) { return; } @@ -391,9 +400,11 @@ void JUTException::showMainInfo(u16 error, OSContext* context, u32 dsisr, u32 da } sConsole->print_f("SRR0: %08XH SRR1:%08XH\n", context->srr0, context->srr1); sConsole->print_f("DSISR: %08XH DAR: %08XH\n", dsisr, dar); +#endif } void JUTException::showGPR(OSContext* context) { +#ifndef TARGET_PC if (!sConsole) { return; } @@ -404,6 +415,7 @@ void JUTException::showGPR(OSContext* context) { context->gpr[i + 11], i + 22, context->gpr[i + 22]); } sConsole->print_f("R%02d:%08XH R%02d:%08XH\n", 10, context->gpr[10], 21, context->gpr[21]); +#endif } bool JUTException::showMapInfo_subroutine(u32 address, bool begin_with_newline) { @@ -454,6 +466,7 @@ bool JUTException::showMapInfo_subroutine(u32 address, bool begin_with_newline) } void JUTException::showGPRMap(OSContext* context) { +#ifndef TARGET_PC if (!sConsole) { return; } @@ -480,9 +493,11 @@ void JUTException::showGPRMap(OSContext* context) { if (!found_address_register) { sConsole->print(" no register which seem to address.\n"); } +#endif } void JUTException::showSRR0Map(OSContext* context) { +#ifndef TARGET_PC if (!sConsole) { return; } @@ -497,6 +512,7 @@ void JUTException::showSRR0Map(OSContext* context) { } JUTConsoleManager::getManager()->drawDirect(true); } +#endif } void JUTException::printDebugInfo(JUTException::EInfoPage page, OSError error, OSContext* context, diff --git a/libs/JSystem/src/JUtility/JUTResFont.cpp b/libs/JSystem/src/JUtility/JUTResFont.cpp index e6410defdc..10443d6404 100644 --- a/libs/JSystem/src/JUtility/JUTResFont.cpp +++ b/libs/JSystem/src/JUtility/JUTResFont.cpp @@ -6,19 +6,39 @@ #include "JSystem/JUtility/JUTAssert.h" #include "JSystem/JUtility/JUTConsole.h" #include +#include "absl/container/node_hash_map.h" + +#if TARGET_PC +struct GlyphTextures { + absl::node_hash_map textures; +}; +#endif JUTResFont::JUTResFont() { +#if TARGET_PC + mGlyphTextures = new GlyphTextures(); +#endif initialize_state(); JUTFont::initialize_state(); } JUTResFont::JUTResFont(const ResFONT* pFont, JKRHeap* pHeap) { +#if TARGET_PC + mGlyphTextures = new GlyphTextures(); +#endif initialize_state(); JUTFont::initialize_state(); initiate(pFont, pHeap); } JUTResFont::~JUTResFont() { +#if TARGET_PC + for (auto& pair : mGlyphTextures->textures) { + pair.second.reset(); + } + delete mGlyphTextures; +#endif + if (mValid) { delete_and_initialize(); JUTFont::initialize_state(); @@ -414,12 +434,30 @@ void JUTResFont::loadImage(int code, GXTexMapID id){ mWidth = cellCol * cellW; mHeight = cellRow * cellH; +#if TARGET_PC + const auto found = mGlyphTextures->textures.find(code); + GXTexObj* texObj; + if (found == mGlyphTextures->textures.end()) { + texObj = &mGlyphTextures->textures[code]; + void* pImg = &mpGlyphBlocks[i]->data[pageIdx * mpGlyphBlocks[i]->textureSize]; + GXInitTexObj(texObj, pImg, mpGlyphBlocks[i]->textureWidth, + mpGlyphBlocks[i]->textureHeight, (GXTexFmt)(u16)mpGlyphBlocks[i]->textureFormat, + GX_CLAMP, GX_CLAMP, 0); + + GXInitTexObjLOD(texObj, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, 0U, 0U, GX_ANISO_1); + } else { + texObj = &found->second; + } + + GXLoadTexObj(texObj, id); + + // Gets used by some other code. + mTexPageIdx = pageIdx; + field_0x66 = i; +#else if (pageIdx != mTexPageIdx || i != field_0x66) { void* pImg = &mpGlyphBlocks[i]->data[pageIdx * mpGlyphBlocks[i]->textureSize]; -#ifdef TARGET_PC - mTexObj.reset(); -#endif GXInitTexObj(&mTexObj, pImg, mpGlyphBlocks[i]->textureWidth, mpGlyphBlocks[i]->textureHeight, (GXTexFmt)(u16)mpGlyphBlocks[i]->textureFormat, GX_CLAMP, GX_CLAMP, 0); @@ -430,6 +468,7 @@ void JUTResFont::loadImage(int code, GXTexMapID id){ } GXLoadTexObj(&mTexObj, id); +#endif } } diff --git a/libs/freeverb/allpass.hpp b/libs/freeverb/allpass.hpp index 4fc294d139..b9c5904229 100644 --- a/libs/freeverb/allpass.hpp +++ b/libs/freeverb/allpass.hpp @@ -6,7 +6,6 @@ #ifndef _allpass_ #define _allpass_ -#include "denormals.h" class allpass { @@ -29,18 +28,12 @@ public: inline float allpass::process(float input) { - float output; - float bufout; - - bufout = buffer[bufidx]; - undenormalise(bufout); - - output = -input + bufout; + float bufout = buffer[bufidx]; buffer[bufidx] = input + (bufout*feedback); if(++bufidx>=bufsize) bufidx = 0; - return output; + return -input + bufout; } #endif//_allpass diff --git a/libs/freeverb/comb.hpp b/libs/freeverb/comb.hpp index 4a73b615fb..52c01b070e 100644 --- a/libs/freeverb/comb.hpp +++ b/libs/freeverb/comb.hpp @@ -7,7 +7,6 @@ #ifndef _comb_ #define _comb_ -#include "denormals.h" class comb { @@ -35,14 +34,9 @@ private: inline float comb::process(float input) { - float output; - - output = buffer[bufidx]; - undenormalise(output); + float output = buffer[bufidx]; filterstore = (output*damp2) + (filterstore*damp1); - undenormalise(filterstore); - buffer[bufidx] = input + (filterstore*feedback); if(++bufidx>=bufsize) bufidx = 0; diff --git a/libs/freeverb/denormals.h b/libs/freeverb/denormals.h index f871412714..d68cb444f7 100644 --- a/libs/freeverb/denormals.h +++ b/libs/freeverb/denormals.h @@ -1,15 +1,58 @@ -// Macro for killing denormalled numbers -// -// Written by Jezar at Dreampoint, June 2000 -// http://www.dreampoint.co.uk -// Based on IS_DENORMAL macro by Jon Watte -// This code is public domain - #ifndef _denormals_ #define _denormals_ -#define undenormalise(sample) if(((*(unsigned int*)&sample)&0x7f800000)==0) sample=0.0f +#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) -#endif//_denormals_ +#include +using denormal_state = unsigned int; +inline denormal_state denormals_enable() +{ + denormal_state saved = _mm_getcsr(); + _mm_setcsr(saved | 0x8040); // FTZ (0x8000) | DAZ (0x0040) + return saved; +} +inline void denormals_restore(denormal_state saved) { _mm_setcsr(saved); } -//ends +#elif defined(__aarch64__) || defined(_M_ARM64) + +#include +using denormal_state = uint64_t; +inline denormal_state denormals_enable() +{ + denormal_state saved; + asm volatile("mrs %0, fpcr" : "=r"(saved)); + asm volatile("msr fpcr, %0" :: "r"(saved | (1ULL << 24))); // FZ + return saved; +} +inline void denormals_restore(denormal_state saved) +{ + asm volatile("msr fpcr, %0" :: "r"(saved)); +} + +#elif defined(__arm__) || defined(_M_ARM) + +#include +using denormal_state = uint32_t; +inline denormal_state denormals_enable() +{ + denormal_state saved; + asm volatile("vmrs %0, fpscr" : "=r"(saved)); + asm volatile("vmsr fpscr, %0" :: "r"(saved | (1U << 24))); // FZ + return saved; +} +inline void denormals_restore(denormal_state saved) +{ + asm volatile("vmsr fpscr, %0" :: "r"(saved)); +} + +#else + +// unknown platform so denormals will be preserved +#warning "This platform is not supported for denormals, reverb will be very slow!" +using denormal_state = int; +inline denormal_state denormals_enable() { return 0; } +inline void denormals_restore(denormal_state) {} + +#endif + +#endif diff --git a/libs/freeverb/revmodel.cpp b/libs/freeverb/revmodel.cpp index feaa3bc04c..d4f9cf2513 100644 --- a/libs/freeverb/revmodel.cpp +++ b/libs/freeverb/revmodel.cpp @@ -5,6 +5,7 @@ // This code is public domain #include "revmodel.hpp" +#include "denormals.h" revmodel::revmodel() { @@ -71,14 +72,17 @@ void revmodel::mute() } } -void revmodel::processreplace(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip) +float revmodel::processreplace(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip, float inputGain) { - float outL,outR,input; + float outL,outR; + float wetSumSqL = 0.0f, wetSumSqR = 0.0f; + long totalSamples = numsamples; + auto savedCSR = denormals_enable(); while(numsamples-- > 0) { outL = outR = 0; - input = (*inputL + *inputR) * gain; + float input = (*inputL + *inputR) * gain * inputGain; // Accumulate comb filters in parallel for(int i=0; i 0) { outL = outR = 0; - input = (*inputL + *inputR) * gain; + float input = (*inputL + *inputR) * gain * inputGain; // Accumulate comb filters in parallel for(int i=0; i +#include "dusk/logging.h" #define CHECK_FLOAT_RANGE(line, x) JUT_ASSERT(line, -1.0e32f < x && x < 1.0e32f); @@ -65,9 +66,23 @@ void cCcD_DivideArea::CalcDivideInfo(cCcD_DivideInfo* pDivideInfo, const cM3dGAa if (!mXDiffIsZero) { s32 var1 = mInvScaledXDiff * (aab.GetMinP()->x - GetMinP()->x); s32 var3 = mInvScaledXDiff * (aab.GetMaxP()->x - GetMinP()->x); +#if TARGET_PC + // yDiv seems to be the problematic part here, but I clamped xDiv and zDiv too just in case. + // Unlike var1, var3 being greater than 31 isn't logged because it is every frame and the original code accounted for that. + // This goes for yDiv and zDiv as well. + if (var1 < 0 || var1 > 31) { + DuskLog.warn("CalcDivideInfo: xDiv var1 out of range: {}", var1); + } + if (var3 < 0) { + DuskLog.warn("CalcDivideInfo: xDiv var3 out of range: {}", var3); + } + var1 = var1 < 0 ? 0 : var1 > 31 ? 31 : var1; + var3 = var3 < 0 ? 0 : var3 > 31 ? 31 : var3; +#else if (31 < var3) { var3 = 31; } +#endif xDivInfo = l_base[var3]; if (0 < var1) { @@ -81,9 +96,22 @@ void cCcD_DivideArea::CalcDivideInfo(cCcD_DivideInfo* pDivideInfo, const cM3dGAa if (!mYDiffIsZero) { s32 var1 = mInvScaledYDiff * (aab.GetMinP()->y - GetMinP()->y); s32 var3 = mInvScaledYDiff * (aab.GetMaxP()->y - GetMinP()->y); +#if TARGET_PC + // When the Epona taming minigame starts as Wolf Link, yDiv var1 can be 32. + // When the Epona taming minigame ends, yDiv var1 and var3 can both be INT_MIN. + if (var1 < 0 || var1 > 31) { + DuskLog.warn("CalcDivideInfo: yDiv var1 out of range: {}", var1); + } + if (var3 < 0) { + DuskLog.warn("CalcDivideInfo: yDiv var3 out of range: {}", var3); + } + var1 = var1 < 0 ? 0 : var1 > 31 ? 31 : var1; + var3 = var3 < 0 ? 0 : var3 > 31 ? 31 : var3; +#else if (31 < var3) { var3 = 31; } +#endif yDivInfo = l_base[var3]; if (0 < var1) { @@ -97,9 +125,20 @@ void cCcD_DivideArea::CalcDivideInfo(cCcD_DivideInfo* pDivideInfo, const cM3dGAa if (!mZDiffIsZero) { s32 var1 = mInvScaledZDiff * (aab.GetMinP()->z - GetMinP()->z); s32 var3 = mInvScaledZDiff * (aab.GetMaxP()->z - GetMinP()->z); +#if TARGET_PC + if (var1 < 0 || var1 > 31) { + DuskLog.warn("CalcDivideInfo: zDiv var1 out of range: {}", var1); + } + if (var3 < 0) { + DuskLog.warn("CalcDivideInfo: zDiv var3 out of range: {}", var3); + } + var1 = var1 < 0 ? 0 : var1 > 31 ? 31 : var1; + var3 = var3 < 0 ? 0 : var3 > 31 ? 31 : var3; +#else if (31 < var3) { var3 = 31; } +#endif zDivInfo = l_base[var3]; if (0 < var1) { diff --git a/src/SSystem/SComponent/c_math.cpp b/src/SSystem/SComponent/c_math.cpp index 2cc54fece9..7baeea689c 100644 --- a/src/SSystem/SComponent/c_math.cpp +++ b/src/SSystem/SComponent/c_math.cpp @@ -7,6 +7,7 @@ #include "SSystem/SComponent/c_m3d.h" #include #include +#include "dusk/logging.h" s16 cM_rad2s(f32 rad) { s32 s = (std::fmod(rad, 2 * M_PI) * (0x8000 / M_PI)); @@ -109,6 +110,13 @@ static u16 atntable[1025] = { u16 U_GetAtanTable(f32 f0, f32 f1) { int idx = f0 / f1 * 0x400; +#if TARGET_PC + // When Wolf Link is playing a Human Link animation, idx can be INT_MIN every frame + if (idx < 0 || idx > 0x400) { + DuskLog.warn("U_GetAtanTable: idx out of range: {}", idx); + } + idx = idx < 0 ? 0 : idx > 0x400 ? 0x400 : idx; +#endif return atntable[idx]; } diff --git a/src/d/actor/d_a_alink.cpp b/src/d/actor/d_a_alink.cpp index 48269ddc56..670dd169c3 100644 --- a/src/d/actor/d_a_alink.cpp +++ b/src/d/actor/d_a_alink.cpp @@ -12677,7 +12677,11 @@ void daAlink_c::setMagicArmorBrk(int i_status) { } BOOL daAlink_c::checkMagicArmorHeavy() const { +#if TARGET_PC + return checkMagicArmorWearAbility() && (dComIfGs_getRupee() == 0 && !dusk::getSettings().game.freeMagicArmor); +#else return checkMagicArmorWearAbility() && dComIfGs_getRupee() == 0; +#endif } BOOL daAlink_c::checkBootsOrArmorHeavy() const { @@ -18583,7 +18587,13 @@ int daAlink_c::execute() { field_0x372c = cXyz::Zero; field_0x2fb8 = 0; +#if TARGET_PC + // This handles rupee drain and transitions between rupees/no rupees + // We can skip all of that if the magic armor doesn't use rupees + if (!dusk::getSettings().game.freeMagicArmor && checkMagicArmorWearAbility() && mClothesChangeWaitTimer == 0) { +#else if (checkMagicArmorWearAbility() && mClothesChangeWaitTimer == 0) { +#endif if (checkMagicArmorNoDamage() && !checkEventRun()) { if (field_0x2fc3 == 0) { field_0x2fc3 = 10; diff --git a/src/d/actor/d_a_alink_damage.inc b/src/d/actor/d_a_alink_damage.inc index 420011cfd6..ac5175e314 100644 --- a/src/d/actor/d_a_alink_damage.inc +++ b/src/d/actor/d_a_alink_damage.inc @@ -187,6 +187,11 @@ int daAlink_c::setDamagePoint(int i_dmgAmount, BOOL i_checkZoraMag, BOOL i_setDm } if (checkMagicArmorNoDamage()) { +#if TARGET_PC + if(dusk::getSettings().game.freeMagicArmor) { + i_dmgAmount = 0; + } +#endif dComIfGp_setItemRupeeCount(-i_dmgAmount * 10); } else #if DEBUG diff --git a/src/d/actor/d_a_alink_effect.inc b/src/d/actor/d_a_alink_effect.inc index 6e76280ff6..d595cd4293 100644 --- a/src/d/actor/d_a_alink_effect.inc +++ b/src/d/actor/d_a_alink_effect.inc @@ -1562,6 +1562,10 @@ void daAlink_c::setMetamorphoseEffectStartLink() { emitter->setGlobalParticleScale(effScale); } #endif + + #if TARGET_PC + emitter->setGlobalParticleScale(mDoGph_gInf_c::getScale(), 1.0f); + #endif } void daAlink_c::setMetamorphoseEffect() { diff --git a/src/d/actor/d_a_alink_swindow.inc b/src/d/actor/d_a_alink_swindow.inc index cf3593dfce..81c7a1ca18 100644 --- a/src/d/actor/d_a_alink_swindow.inc +++ b/src/d/actor/d_a_alink_swindow.inc @@ -40,6 +40,9 @@ void daAlink_c::setOriginalHeap(JKRExpHeap** i_ppheap, u32 i_size) { u32 var_r29 = 0x90; u32 var_r28 = 0x10; u32 size = ROUND(i_size, 16); +#if TARGET_PC + size *= 2; +#endif JKRHeap* parent = mDoExt_getGameHeap(); JKRExpHeap* heap = JKRExpHeap::create(size + (var_r29 + var_r28), parent, true); diff --git a/src/d/actor/d_a_alink_wolf.inc b/src/d/actor/d_a_alink_wolf.inc index 2bf1129f17..2e38298090 100644 --- a/src/d/actor/d_a_alink_wolf.inc +++ b/src/d/actor/d_a_alink_wolf.inc @@ -313,7 +313,12 @@ void daAlink_c::changeLink(int param_0) { mpLinkHandModel = initModel(static_cast(dComIfG_getObjectRes(l_mArcName, "al_hands.bmd")), 0); - if (dComIfGs_getRupee() != 0) { +#if TARGET_PC + if (dComIfGs_getRupee() != 0 || dusk::getSettings().game.freeMagicArmor) +#else + if (dComIfGs_getRupee() != 0) +#endif + { setMagicArmorBrk(1); } else { setMagicArmorBrk(0); @@ -398,7 +403,11 @@ void daAlink_c::changeLink(int param_0) { field_0x06ec = field_0x064C->getMaterialNodePointer(1)->getShape(); field_0x06f0 = field_0x064C->getMaterialNodePointer(2)->getShape(); +#if TARGET_PC + if (dComIfGs_getRupee() != 0 || dusk::getSettings().game.freeMagicArmor) { +#else if (dComIfGs_getRupee() != 0) { +#endif var_r27 = 4; } else { var_r27 = 5; diff --git a/src/d/actor/d_a_e_ph.cpp b/src/d/actor/d_a_e_ph.cpp index dc20cb2361..3213c2716e 100644 --- a/src/d/actor/d_a_e_ph.cpp +++ b/src/d/actor/d_a_e_ph.cpp @@ -1154,6 +1154,18 @@ int daE_PH_c::create() { int phase_state = dComIfG_resLoad(&mPhase, "E_PH"); if (phase_state == cPhs_COMPLEATE_e) { + +#if TARGET_PC + // Due to our loads being so much faster, peahats can initialize *before* the camera. + // This breaks the peahat used for camera focus during transition to phase 2 of Argorok. + // as it caches incorrect camera parameters in its init. + if (auto cam = dComIfGp_getCamera(0)) { + if (cam->phase_request.mpHandlerTable != nullptr) { + return cPhs_INIT_e; + } + } +#endif + mAction = fopAcM_GetParam(this) & 0xF; if (dComIfGs_isZoneSwitch(2, fopAcM_GetRoomNo(this)) && mAction == 4) { diff --git a/src/d/actor/d_a_mant.cpp b/src/d/actor/d_a_mant.cpp index a3b48f1098..bcd7f05986 100644 --- a/src/d/actor/d_a_mant.cpp +++ b/src/d/actor/d_a_mant.cpp @@ -10,11 +10,21 @@ #include "d/actor/d_a_b_gnd.h" #include "d/d_com_inf_game.h" +#if TARGET_PC +#include "dusk/dvd_asset.hpp" +static u8* l_Egnd_mantTEX_get() { alignas(32) static u8 buf[0x4000]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", 0x1C00, 0x4000), true); return buf; } +static u8* l_Egnd_mantTEX_U_get() { alignas(32) static u8 buf[0x4000]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", 0x5C00, 0x4000), true); return buf; } +static u8* l_Egnd_mantPAL_get() { alignas(32) static u8 buf[0x60]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", 0x9C00, 0x60), true); return buf; } +#define l_Egnd_mantTEX (l_Egnd_mantTEX_get()) +#define l_Egnd_mantTEX_U (l_Egnd_mantTEX_U_get()) +#define l_Egnd_mantPAL (l_Egnd_mantPAL_get()) +#else #include "assets/l_Egnd_mantTEX.h" #include "assets/l_Egnd_mantTEX_U.h" #include "assets/l_Egnd_mantPAL.h" +#endif #include "d/d_s_play.h" static u32 l_pos[507] = { @@ -239,20 +249,32 @@ static u32 l_texCoord[338] = { 0x3F800000, 0x00000000, }; +#if TARGET_PC +static u8* l_Egnd_mantDL_get() { alignas(32) static u8 buf[0x3EC]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", 0xA9A0, 0x3EC), true); return buf; } +#define l_Egnd_mantDL (l_Egnd_mantDL_get()) +#else #include "assets/l_Egnd_mantDL.h" +#endif +#if !TARGET_PC static void* pal_d = (void*)&l_Egnd_mantPAL; static void* tex_d[2] = { (void*)&l_Egnd_mantTEX, (void*)&l_Egnd_mantTEX_U, }; +#endif static char lbl_277_bss_0; void daMant_packet_c::draw() { +#if TARGET_PC + void* image = l_Egnd_mantTEX; + void* lut = l_Egnd_mantPAL; +#else void* image = tex_d[0]; void* lut = pal_d; +#endif j3dSys.reinitGX(); GXSetNumIndStages(0); diff --git a/src/d/actor/d_a_movie_player.cpp b/src/d/actor/d_a_movie_player.cpp index 4573684b2f..c3074ac877 100644 --- a/src/d/actor/d_a_movie_player.cpp +++ b/src/d/actor/d_a_movie_player.cpp @@ -4473,7 +4473,9 @@ int daMP_c::daMP_c_Get_arg_movieNo() { int daMP_c::daMP_c_Init() { JUT_ASSERT(9469, m_myObj == NULL); +#if !TARGET_PC // We don't properly simulate retrace interval so this doesn't work. mDoGph_gInf_c::setFrameRate(1); +#endif daMP_Fail_alloc = FALSE; int demoNo = daMP_c_Get_arg_demoNo(); diff --git a/src/d/actor/d_a_obj_groundwater.cpp b/src/d/actor/d_a_obj_groundwater.cpp index 2d3d05a36c..ab6b7af922 100644 --- a/src/d/actor/d_a_obj_groundwater.cpp +++ b/src/d/actor/d_a_obj_groundwater.cpp @@ -300,11 +300,19 @@ int daGrdWater_c::Draw() { J3DTexMtxInfo* mtxInfo = &material->getTexGenBlock()->getTexMtx(0)->getTexMtxInfo(); if (mtxInfo != NULL) { Mtx afStack_50; + + #if TARGET_PC + C_MTXLightPerspective(afStack_50, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect, + 1.0f, 1.0f, dusk::getSettings().game.useWaterProjectionOffset ? -0.01f : 0.0f, 0.0f); + #else C_MTXLightPerspective(afStack_50, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect, 1.0f, 1.0f, -0.01f, 0.0f); + #endif + #if WIDESCREEN_SUPPORT mDoGph_gInf_c::setWideZoomLightProjection(afStack_50); #endif + mtxInfo->setEffectMtx(afStack_50); modelData2->simpleCalcMaterial(0, (MtxP)j3dDefaultMtx); } diff --git a/src/d/actor/d_a_obj_lv3Water.cpp b/src/d/actor/d_a_obj_lv3Water.cpp index a228b2cbc8..934cb3140d 100644 --- a/src/d/actor/d_a_obj_lv3Water.cpp +++ b/src/d/actor/d_a_obj_lv3Water.cpp @@ -371,8 +371,14 @@ int daLv3Water_c::Draw() { texMtxInfo = &material->getTexGenBlock()->getTexMtx(0)->getTexMtxInfo(); if (texMtxInfo != NULL) { Mtx lightProjMtx; + + #if TARGET_PC + C_MTXLightPerspective(lightProjMtx, dComIfGd_getView()->fovy, + dComIfGd_getView()->aspect, 1.0f, 1.0f, dusk::getSettings().game.useWaterProjectionOffset ? -0.01f : 0.0f, 0.0f); + #else C_MTXLightPerspective(lightProjMtx, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect, 1.0f, 1.0f, -0.01f, 0.0f); + #endif #if WIDESCREEN_SUPPORT mDoGph_gInf_c::setWideZoomLightProjection(lightProjMtx); diff --git a/src/d/actor/d_a_obj_lv3Water2.cpp b/src/d/actor/d_a_obj_lv3Water2.cpp index b6814875cc..55fc94d605 100644 --- a/src/d/actor/d_a_obj_lv3Water2.cpp +++ b/src/d/actor/d_a_obj_lv3Water2.cpp @@ -197,7 +197,13 @@ int daLv3Water2_c::Draw() { texMtxInfo = &btkMaterial->getTexGenBlock()->getTexMtx(0)->getTexMtxInfo(); if(texMtxInfo) { Mtx lightProjMtx; + + #if TARGET_PC + C_MTXLightPerspective(lightProjMtx, dComIfGd_getView()->fovy, + dComIfGd_getView()->aspect, 1.0f, 1.0f, dusk::getSettings().game.useWaterProjectionOffset ? -0.01f : 0.0f, 0); + #else C_MTXLightPerspective(lightProjMtx, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect, 1.0f, 1.0f, -0.01f, 0); + #endif #if WIDESCREEN_SUPPORT mDoGph_gInf_c::setWideZoomLightProjection(lightProjMtx); diff --git a/src/d/actor/d_a_obj_lv3WaterB.cpp b/src/d/actor/d_a_obj_lv3WaterB.cpp index f4ad49685d..33285d975f 100644 --- a/src/d/actor/d_a_obj_lv3WaterB.cpp +++ b/src/d/actor/d_a_obj_lv3WaterB.cpp @@ -27,8 +27,15 @@ static int daObj_Lv3waterB_Draw(obj_lv3WaterB_class* i_this) { J3DTexMtxInfo* tex_mtx_info = &material_p->getTexGenBlock()->getTexMtx(0)->getTexMtxInfo(); if (tex_mtx_info != NULL) { Mtx m; + + #if TARGET_PC + C_MTXLightPerspective(m, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect, 1.0f, 1.0f, + dusk::getSettings().game.useWaterProjectionOffset ? -0.015f : 0.0f, 0.0f); + #else C_MTXLightPerspective(m, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect, 1.0f, 1.0f, -0.015f, 0.0f); + #endif + #if WIDESCREEN_SUPPORT mDoGph_gInf_c::setWideZoomLightProjection(m); #endif diff --git a/src/d/actor/d_a_obj_rstair.cpp b/src/d/actor/d_a_obj_rstair.cpp index 609a0cf7b8..7e44cc3700 100644 --- a/src/d/actor/d_a_obj_rstair.cpp +++ b/src/d/actor/d_a_obj_rstair.cpp @@ -313,8 +313,15 @@ int daObjRotStair_c::Draw() { J3DTexMtxInfo* texMtxInfo = &material->getTexGenBlock()->getTexMtx(0)->getTexMtxInfo(); if (texMtxInfo != NULL) { Mtx lightMtx; + + #if TARGET_PC + C_MTXLightPerspective(lightMtx, dComIfGd_getView()->fovy, + dComIfGd_getView()->aspect, 1.0f, 1.0f, dusk::getSettings().game.useWaterProjectionOffset ? -0.01f : 0.0f, 0); + #else C_MTXLightPerspective(lightMtx, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect, 1.0f, 1.0f, -0.01f, 0); + #endif + #if WIDESCREEN_SUPPORT mDoGph_gInf_c::setWideZoomLightProjection(lightMtx); #endif diff --git a/src/d/actor/d_a_obj_tp.cpp b/src/d/actor/d_a_obj_tp.cpp index 2690de3e04..e2ede47b15 100644 --- a/src/d/actor/d_a_obj_tp.cpp +++ b/src/d/actor/d_a_obj_tp.cpp @@ -36,8 +36,15 @@ static int daObj_Tp_Draw(obj_tp_class* i_this) { &material->getTexGenBlock()->getTexMtx(0)->getTexMtxInfo(); if (texMtxInfo != NULL) { Mtx lightProjMtx; + + #if TARGET_PC + C_MTXLightPerspective(lightProjMtx, dComIfGd_getView()->fovy, + dComIfGd_getView()->aspect, 1.0f, 1.0f, dusk::getSettings().game.useWaterProjectionOffset ? -0.01f : 0.0f, 0); + #else C_MTXLightPerspective(lightProjMtx, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect, 1.0f, 1.0f, -0.01f, 0); + #endif + #if WIDESCREEN_SUPPORT mDoGph_gInf_c::setWideZoomLightProjection(lightProjMtx); #endif diff --git a/src/d/actor/d_a_player.cpp b/src/d/actor/d_a_player.cpp index f38fe15a3b..4c8b31c4c6 100644 --- a/src/d/actor/d_a_player.cpp +++ b/src/d/actor/d_a_player.cpp @@ -237,11 +237,7 @@ void* daPy_anmHeap_c::mallocBuffer() { return mBuffer; } -#if TARGET_PC void daPy_anmHeap_c::createHeap(daPy_anmHeap_c::daAlinkHEAP_TYPE i_heapType, const char* name) { -#else -void daPy_anmHeap_c::createHeap(daPy_anmHeap_c::daAlinkHEAP_TYPE i_heapType, const char* name) { -#endif u32 size; if (i_heapType == 4) { @@ -255,6 +251,9 @@ void daPy_anmHeap_c::createHeap(daPy_anmHeap_c::daAlinkHEAP_TYPE i_heapType, con } else { size = 0xA0; } +#if TARGET_PC + size *= 2; +#endif char* tmpWork; mDoExt_transAnmBas* tmpTransBas; @@ -368,7 +367,30 @@ JKRHeap* daPy_anmHeap_c::setAnimeHeap() { } #if !PLATFORM_WII +#if TARGET_PC +#include "dusk/dvd_asset.hpp" +static const u8* l_sightDL_get() { + static u8 buf[0x89]; + static bool _ = ( + dusk::LoadDolAsset( + buf, + #if VERSION == VERSION_GCN_PAL + 0x803BBDA0, + #elif VERSION == VERSION_GCN_JPN + 0x803B4220, + #elif VERSION == VERSION_GCN_USA + 0x803BA0C0, + #endif + 0x89 + ), + true + ); + return buf; +} +#define l_sightDL (l_sightDL_get()) +#else #include "assets/l_sightDL__d_a_player.h" +#endif void daPy_sightPacket_c::draw() { TGXTexObj texObj; diff --git a/src/d/actor/d_flower.inc b/src/d/actor/d_flower.inc index 762b1e02e9..4fb53ffaa7 100644 --- a/src/d/actor/d_flower.inc +++ b/src/d/actor/d_flower.inc @@ -13,7 +13,13 @@ const u16 l_J_Ohana00_64TEX__width = 63; const u16 l_J_Ohana00_64TEX__height = 63; #endif +#if TARGET_PC +#include "dusk/dvd_asset.hpp" +static u8* l_J_Ohana00_64TEX_get() { static u8 buf[0x800]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0x9060, 0x800), true); return buf; } +#define l_J_Ohana00_64TEX (l_J_Ohana00_64TEX_get()) +#else #include "assets/l_J_Ohana00_64TEX.h" +#endif static u8 l_flowerPos[708] = { 0xC0, 0x8C, 0x2C, 0xF7, 0x42, 0x05, 0xBC, 0xDF, 0xC1, 0xA1, 0x00, 0x70, 0xBF, 0x50, 0x51, 0xB9, @@ -104,6 +110,16 @@ static u8 l_flowerTexCoord[] = { 0x3E, 0xA7, 0x67, 0x4D, 0x3C, 0x14, 0x46, 0x74, 0x3E, 0xA7, 0x73, 0xE2, 0xBC, 0x2F, 0x46, 0xAA, 0x3E, 0xA7, 0x72, 0xD6, 0xBD, 0x2F, 0x46, 0xAA}; +#if TARGET_PC +static u8* l_J_hana00DL_get() { static u8 buf[0x150]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0x9D20, 0x150), true); return buf; } +static u8* l_J_hana00_cDL_get() { static u8 buf[0xDE]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0x9E80, 0xDE), true); return buf; } +static u8* l_matDL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0x9F60, 0x99), true); return buf; } +static u8* l_matLight4DL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0xA000, 0x99), true); return buf; } +#define l_J_hana00DL (l_J_hana00DL_get()) +#define l_J_hana00_cDL (l_J_hana00_cDL_get()) +#define l_matDL (l_matDL_get()) +#define l_matLight4DL (l_matLight4DL_get()) +#else #include "assets/l_J_hana00DL.h" #include "assets/l_J_hana00_cDL.h" @@ -113,6 +129,7 @@ l_matDL__d_a_grass(l_J_Ohana00_64TEX) #include "assets/l_matLight4DL.h" l_matLight4DL(l_J_Ohana00_64TEX) +#endif #if TARGET_PC const u16 l_J_Ohana01_64128_0419TEX__width = 64; @@ -122,7 +139,12 @@ const u16 l_J_Ohana01_64128_0419TEX__width = 63; const u16 l_J_Ohana01_64128_0419TEX__height = 127; #endif +#if TARGET_PC +static u8* l_J_Ohana01_64128_0419TEX_get() { static u8 buf[0x1000]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0xA0A0, 0x1000), true); return buf; } +#define l_J_Ohana01_64128_0419TEX (l_J_Ohana01_64128_0419TEX_get()) +#else #include "assets/l_J_Ohana01_64128_0419TEX.h" +#endif static u8 l_flowerPos2[1224] = { 0x40, 0x25, 0x9F, 0x34, 0x42, 0xC2, 0x95, 0x72, 0xC1, 0x22, 0x34, 0x78, 0x41, 0x4D, 0xF9, 0x63, @@ -249,6 +271,18 @@ static u8 l_flowerTexCoord2[] = { 0x40, 0x1B, 0x7D, 0x52, 0x3F, 0x97, 0xF6, 0xBA, 0x40, 0x04, 0x26, 0x74, 0x3F, 0x80, 0x3F, 0x79, 0x40, 0x1B, 0x7D, 0x52, 0x3F, 0x80, 0x3F, 0x79, 0x40, 0x1B, 0x7D, 0x52, 0x3F, 0x51, 0x10, 0x6F}; +#if TARGET_PC +static u8* l_J_hana01DL_get() { static u8 buf[0x138]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0xB7C0, 0x138), true); return buf; } +static u8* l_J_hana01_c_00DL_get() { static u8 buf[0xDE]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0xB900, 0xDE), true); return buf; } +static u8* l_J_hana01_c_01DL_get() { static u8 buf[0x128]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0xB9E0, 0x128), true); return buf; } +static u8* l_mat2DL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0xBB20, 0x99), true); return buf; } +static u8* l_mat2Light4DL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0xBBC0, 0x99), true); return buf; } +#define l_J_hana01DL (l_J_hana01DL_get()) +#define l_J_hana01_c_00DL (l_J_hana01_c_00DL_get()) +#define l_J_hana01_c_01DL (l_J_hana01_c_01DL_get()) +#define l_mat2DL (l_mat2DL_get()) +#define l_mat2Light4DL (l_mat2Light4DL_get()) +#else #include "assets/l_J_hana01DL.h" #include "assets/l_J_hana01_c_00DL.h" @@ -260,6 +294,7 @@ l_mat2DL__d_a_grass(l_J_Ohana01_64128_0419TEX) #include "assets/l_mat2Light4DL.h" l_mat2Light4DL(l_J_Ohana01_64128_0419TEX) +#endif void dFlower_data_c::WorkCo(fopAc_ac_c* i_hitActor, u32 i_massFlg, int i_roomNo) { cXyz sp8; @@ -521,6 +556,32 @@ dFlower_packet_c::dFlower_packet_c() { unused += 0x2000; } +#if TARGET_LITTLE_ENDIAN + static bool initialized = false; + if (!initialized) { + for (int i = 0; i < (ARRAY_SIZE(l_flowerPos) / sizeof(Vec)); i++) { + be_swap(((Vec*)l_flowerPos)[i]); + } + for (int i = 0; i < (ARRAY_SIZE(l_flowerTexCoord) / sizeof(Vec)); i++) { + be_swap(((Vec*)l_flowerTexCoord)[i]); + } + for (int i = 0; i < (ARRAY_SIZE(l_flowerPos2) / sizeof(Vec)); i++) { + be_swap(((Vec*)l_flowerPos2)[i]); + } + for (int i = 0; i < (ARRAY_SIZE(l_flowerTexCoord2) / sizeof(Vec)); i++) { + be_swap(((Vec*)l_flowerTexCoord2)[i]); + } + for (int i = 0; i < (ARRAY_SIZE(l_flowerNormal) / sizeof(Vec)); i++) { + be_swap(((Vec*)l_flowerNormal)[i]); + } + for (int i = 0; i < (ARRAY_SIZE(l_flowerNormal2) / sizeof(Vec)); i++) { + be_swap(((Vec*)l_flowerNormal2)[i]); + } + + initialized = true; + } +#endif + #if TARGET_PC GXInitTexObj(&mTexObj_l_J_Ohana00_64TEX, l_J_Ohana00_64TEX, l_J_Ohana00_64TEX__width, l_J_Ohana00_64TEX__height, GX_TF_CMPR, GX_MIRROR, GX_MIRROR, GX_FALSE @@ -553,10 +614,10 @@ void dFlower_packet_c::draw() { GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); - GXSETARRAY(GX_VA_POS, &l_flowerPos, sizeof(l_flowerPos), 0xC, false); - GXSETARRAY(GX_VA_NRM, &l_flowerNormal, sizeof(l_flowerNormal), 0xC, false); - GXSETARRAY(GX_VA_CLR0, &l_flowerColor, sizeof(l_flowerColor), 4, false); - GXSETARRAY(GX_VA_TEX0, &l_flowerTexCoord, sizeof(l_flowerTexCoord), 8, false); + GXSETARRAY(GX_VA_POS, &l_flowerPos, sizeof(l_flowerPos), sizeof(Vec), true); + GXSETARRAY(GX_VA_NRM, &l_flowerNormal, sizeof(l_flowerNormal), sizeof(Vec), true); + GXSETARRAY(GX_VA_CLR0, &l_flowerColor, sizeof(l_flowerColor), sizeof(GXColor), true); + GXSETARRAY(GX_VA_TEX0, &l_flowerTexCoord, sizeof(l_flowerTexCoord), 8, true); GXColor sp64; dFlower_room_c* sp5C = m_room; @@ -584,9 +645,9 @@ void dFlower_packet_c::draw() { } if (sp4C <= 2) { - GXCallDisplayList(&l_matLight4DL, 0x80); + GXCallDisplayList(l_matLight4DL, 0x80); } else { - GXCallDisplayList(&l_matDL, 0x80); + GXCallDisplayList(l_matDL, 0x80); } GXSetTevColorS10(GX_TEVREG0, sp80); @@ -642,9 +703,9 @@ void dFlower_packet_c::draw() { #endif if (!cLib_checkBit(sp44->m_state, 8)) { - GXCallDisplayList(&l_J_hana00DL, 0x140); + GXCallDisplayList(l_J_hana00DL, 0x140); } else { - GXCallDisplayList(&l_J_hana00_cDL, 0xC0); + GXCallDisplayList(l_J_hana00_cDL, 0xC0); } } } @@ -652,9 +713,9 @@ void dFlower_packet_c::draw() { sp5C++; } - GXSETARRAY(GX_VA_POS, mp_pos, sizeof(l_flowerPos2), 0xC, true); - GXSETARRAY(GX_VA_NRM, &l_flowerNormal2, sizeof(l_flowerNormal2), 0xC, false); - GXSETARRAY(GX_VA_CLR0, mp_colors, sizeof(l_flowerColor2), 4, true); + GXSETARRAY(GX_VA_POS, mp_pos, sizeof(l_flowerPos2), sizeof(Vec), true); + GXSETARRAY(GX_VA_NRM, &l_flowerNormal2, sizeof(l_flowerNormal2), sizeof(Vec), true); + GXSETARRAY(GX_VA_CLR0, mp_colors, sizeof(l_flowerColor2), sizeof(GXColor), true); GXSETARRAY(GX_VA_TEX0, mp_texCoords, sizeof(l_flowerTexCoord2), 8, true); sp5C = m_room; @@ -791,7 +852,7 @@ void dFlower_packet_c::draw() { if (!cLib_checkBit(sp34->m_state, 0x10)) { GXCallDisplayList(mp_Jhana01DL, m_Jhana01DL_size); } else { - GXCallDisplayList(&l_J_hana01_c_00DL, 0xC0); + GXCallDisplayList(l_J_hana01_c_00DL, 0xC0); } } else { GXCallDisplayList(mp_Jhana01_cDL, m_Jhana01_cDL_size); diff --git a/src/d/actor/d_grass.inc b/src/d/actor/d_grass.inc index 6351cc75fc..3645488b0f 100644 --- a/src/d/actor/d_grass.inc +++ b/src/d/actor/d_grass.inc @@ -13,11 +13,19 @@ const u16 l_M_Hijiki00TEX__width = 31; const u16 l_M_Hijiki00TEX__height = 31; -#include "assets/l_M_kusa05_RGBATEX.h" // ALIGN 32 - const u16 l_M_kusa05_RGBATEX__width = 31; const u16 l_M_kusa05_RGBATEX__height = 31; -#include "assets/l_M_Hijiki00TEX.h" // ALIGN 32 + +#if TARGET_PC +#include "dusk/dvd_asset.hpp" +static u8* l_M_kusa05_RGBATEX_get() { static u8 buf[0x800]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0x7680, 0x800), true); return buf; } +static u8* l_M_Hijiki00TEX_get() { static u8 buf[0x800]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0x7E80, 0x800), true); return buf; } +#define l_M_kusa05_RGBATEX (l_M_kusa05_RGBATEX_get()) +#define l_M_Hijiki00TEX (l_M_Hijiki00TEX_get()) +#else +#include "assets/l_M_kusa05_RGBATEX.h" // ALIGN 32 +#include "assets/l_M_Hijiki00TEX.h" // ALIGN 32 +#endif static u8 l_pos[960] = { 0x3F, 0x4A, 0x56, 0xEF, 0xC2, 0x20, 0x00, 0x00, 0x41, 0xFB, 0x17, 0xE4, 0x41, 0xAA, 0xBB, 0xEA, @@ -102,6 +110,20 @@ static u8 l_texCoord[160] = { 0x3F, 0x94, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0xBD, 0xC0, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, }; +#if TARGET_PC +static u8* l_M_Kusa_9qDL_get() { static u8 buf[0xCB]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0x8B00, 0xCB), true); return buf; } +static u8* l_M_Kusa_9q_cDL_get() { static u8 buf[0xCB]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0x8BE0, 0xCB), true); return buf; } +static u8* l_M_TenGusaDL_get() { static u8 buf[0xD4]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0x8CC0, 0xD4), true); return buf; } +static u8* l_Tengusa_matDL_get() { static u8 buf[0xA8]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0x8DA0, 0xA8), true); return buf; } +static u8* l_kusa9q_matDL_get() { static u8 buf[0xA8]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0x8E60, 0xA8), true); return buf; } +static u8* l_kusa9q_l4_matDL_get() { static u8 buf[0xA8]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", 0x8F20, 0xA8), true); return buf; } +#define l_M_Kusa_9qDL (l_M_Kusa_9qDL_get()) +#define l_M_Kusa_9q_cDL (l_M_Kusa_9q_cDL_get()) +#define l_M_TenGusaDL (l_M_TenGusaDL_get()) +#define l_Tengusa_matDL (l_Tengusa_matDL_get()) +#define l_kusa9q_matDL (l_kusa9q_matDL_get()) +#define l_kusa9q_l4_matDL (l_kusa9q_l4_matDL_get()) +#else #include "assets/l_M_Kusa_9qDL.h" #include "assets/l_M_Kusa_9q_cDL.h" @@ -117,6 +139,7 @@ l_kusa9q_matDL(l_M_kusa05_RGBATEX) #include "assets/l_kusa9q_l4_matDL.h" l_kusa9q_l4_matDL(l_M_kusa05_RGBATEX) +#endif void dGrass_data_c::WorkCo(fopAc_ac_c* i_hitActor, u32 i_massFlg, int i_roomNo) { cXyz sp18; diff --git a/src/d/d_bright_check.cpp b/src/d/d_bright_check.cpp index 36f24ebd72..ac28e46838 100644 --- a/src/d/d_bright_check.cpp +++ b/src/d/d_bright_check.cpp @@ -143,7 +143,56 @@ void dBrightCheck_c::modeMove() { } } +#if TARGET_PC +void dBrightCheck_c::brightCheckWide() { + // Main Canvas + mBrightCheck.Scr->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f); + mBrightCheck.Scr->translate(mDoGph_gInf_c::getMinXF(), 0.0f); + + // Right Square + mBrightCheck.Scr->search(MULTI_CHAR('fuchi_1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBrightCheck.Scr->search(MULTI_CHAR('big_squa'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Middle Square + mBrightCheck.Scr->search(MULTI_CHAR('fuchi_3'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBrightCheck.Scr->search(MULTI_CHAR('big_squ1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Left Square + mBrightCheck.Scr->search(MULTI_CHAR('fuchi_4'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBrightCheck.Scr->search(MULTI_CHAR('big_squ2'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Gray Squares + mBrightCheck.Scr->search(MULTI_CHAR('gray_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBrightCheck.Scr->search(MULTI_CHAR('fuchi_2'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Confirm A Button + mBrightCheck.Scr->search(MULTI_CHAR('abtn_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBrightCheck.Scr->search(MULTI_CHAR('gcabtn_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Text + mBrightCheck.Scr->search(MULTI_CHAR('menu_6n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBrightCheck.Scr->search(MULTI_CHAR('menu_9n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBrightCheck.Scr->search(MULTI_CHAR('menu_10n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBrightCheck.Scr->search(MULTI_CHAR('menu_7n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBrightCheck.Scr->search(MULTI_CHAR('menu_8n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBrightCheck.Scr->search(MULTI_CHAR('fmenu_8n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBrightCheck.Scr->search(MULTI_CHAR('fmenu_7n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBrightCheck.Scr->search(MULTI_CHAR('fmenu_10'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBrightCheck.Scr->search(MULTI_CHAR('fmenu_6n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBrightCheck.Scr->search(MULTI_CHAR('fmenu_9n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBrightCheck.Scr->search(MULTI_CHAR('t_t00'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBrightCheck.Scr->search(MULTI_CHAR('f_t00'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Spirals + mBrightCheck.Scr->search(MULTI_CHAR('t_mo_l_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBrightCheck.Scr->search(MULTI_CHAR('t_mo_r_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); +} +#endif + void dBrightCheck_c::_draw() { + #if TARGET_PC + brightCheckWide(); + #endif dComIfGd_set2DOpa(&mBrightCheck); } diff --git a/src/d/d_error_msg.cpp b/src/d/d_error_msg.cpp index faa40ae543..efd2512c11 100644 --- a/src/d/d_error_msg.cpp +++ b/src/d/d_error_msg.cpp @@ -15,6 +15,7 @@ #include "m_Do/m_Do_Reset.h" #include "m_Do/m_Do_graphic.h" +#if !TARGET_PC #include "assets/black_tex.h" #include "assets/msg_data.h" #if VERSION == VERSION_GCN_PAL @@ -24,6 +25,7 @@ #include "assets/msg_data_it.h" #endif #include "assets/font_data.h" +#endif #define MSG_READING_DISC 0 #define MSG_COVER_OPEN 1 @@ -49,6 +51,7 @@ struct BMG_INF1 : JUTDataBlockHeader { #endif static void messageSet(u32 status, bool i_drawBg) { + #if !TARGET_PC BMG_INF1* inf1; const char* msg_p; @@ -177,9 +180,11 @@ static void messageSet(u32 status, bool i_drawBg) { tpane.draw(x, y + 10.0f, FB_WIDTH, HBIND_LEFT); #endif #endif + #endif } void dDvdErrorMsg_c::draw(s32 status) { + #if !TARGET_PC JUtility::TColor backColor = g_clearColor; JFWDisplay::getManager()->setClearColor(backColor); mDoGph_gInf_c::beginRender(); @@ -207,6 +212,7 @@ void dDvdErrorMsg_c::draw(s32 status) { mDoGph_gInf_c::endRender(); JFWDisplay::getManager()->resetFader(); + #endif } bool dDvdErrorMsg_c::execute() { @@ -237,16 +243,12 @@ bool dDvdErrorMsg_c::execute() { static u8 l_captureAlpha = 0xFF; static void drawCapture(u8 alpha) { + #if !TARGET_PC static bool l_texCopied = false; if (!l_texCopied) { -#if TARGET_PC - GXSetTexCopySrc(0, 0, mDoGph_gInf_c::getWidth(), mDoGph_gInf_c::getHeight()); - GXSetTexCopyDst(mDoGph_gInf_c::getWidth(), mDoGph_gInf_c::getHeight(), (GXTexFmt)mDoGph_gInf_c::getFrameBufferTimg()->format, GX_TRUE); -#else GXSetTexCopySrc(0, 0, FB_WIDTH, FB_HEIGHT); GXSetTexCopyDst(FB_WIDTH / 2, FB_HEIGHT / 2, (GXTexFmt)mDoGph_gInf_c::getFrameBufferTimg()->format, GX_TRUE); -#endif GXCopyTex(mDoGph_gInf_c::getFrameBufferTex(), GX_FALSE); l_texCopied = true; } @@ -256,9 +258,6 @@ static void drawCapture(u8 alpha) { GXSetAlphaUpdate(GX_FALSE); j3dSys.drawInit(); -#ifdef TARGET_PC - mDoGph_gInf_c::getFrameBufferTexObj()->reset(); -#endif GXInitTexObj(mDoGph_gInf_c::getFrameBufferTexObj(), mDoGph_gInf_c::getFrameBufferTex(), FB_WIDTH / 2, FB_HEIGHT / 2, (GXTexFmt)mDoGph_gInf_c::getFrameBufferTimg()->format, GX_CLAMP, GX_CLAMP, GX_FALSE); GXInitTexObjLOD(mDoGph_gInf_c::getFrameBufferTexObj(), GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1); GXLoadTexObj(mDoGph_gInf_c::getFrameBufferTexObj(), GX_TEXMAP0); @@ -298,6 +297,7 @@ static void drawCapture(u8 alpha) { mDoGph_drawFilterQuad(1, 1); mDoGph_gInf_c::endRender(); JFWDisplay::getManager()->resetFader(); + #endif } bool dShutdownErrorMsg_c::execute() { @@ -325,6 +325,5 @@ bool dShutdownErrorMsg_c::execute() { mDoRst_reset(1, 1, 1); } } - return true; } diff --git a/src/d/d_file_select.cpp b/src/d/d_file_select.cpp index 16aafb721f..8d4f98187b 100644 --- a/src/d/d_file_select.cpp +++ b/src/d/d_file_select.cpp @@ -70,7 +70,11 @@ dFs_HIO_c::dFs_HIO_c() { select_icon_appear_frames = 5; appear_display_wait_frames = 15; field_0x000d = 15; + #if TARGET_PC + card_wait_frames = 0; + #else card_wait_frames = 90; + #endif test_frame_counts[0] = 1.11f; test_frame_counts[1] = 1.11f; test_frame_counts[2] = 1.11f; @@ -1189,7 +1193,13 @@ void dFile_select_c::menuSelect() { // Handles copy / start / delete actions depending on which menu is selected from menuSelect void dFile_select_c::menuSelectStart() { - mDoAud_seStart(Z2SE_SY_CURSOR_OK, NULL, 0, 0); + #if TARGET_PC + if (!dusk::getSettings().game.hideTvSettingsScreen || mSelectMenuNum != 1) { + mDoAud_seStart(Z2SE_SY_CURSOR_OK, NULL, 0, 0); + } + #else + mDoAud_seStart(Z2SE_SY_CURSOR_OK, NULL, 0, 0); + #endif if (mSelectMenuNum == 1) { dComIfGs_setCardToMemory((u8*)mSaveData, mSelectNum); @@ -2091,7 +2101,12 @@ void dFile_select_c::yesnoCursorShow() { Vec pos = mYnSelPane[field_0x0268]->getGlobalVtxCenter(0, 0); mSelIcon->setPos(pos.x, pos.y, mYnSelPane[field_0x0268]->getPanePtr(), true); mSelIcon->setAlphaRate(1.0f); + + #if TARGET_PC + mSelIcon->setParam(0.96f * mDoGph_gInf_c::hudAspectScaleUp, 0.84f, 0.06f, 0.5f, 0.5f); + #else mSelIcon->setParam(0.96f, 0.84f, 0.06f, 0.5f, 0.5f); + #endif } } @@ -2243,7 +2258,12 @@ void dFile_select_c::YesNoCancelMove() { mSelIcon->setPos(vtxCenter.x, vtxCenter.y, m3mSelPane[mSelectMenuNum]->getPanePtr(), true); mSelIcon->setAlphaRate(1.0f); + + #if TARGET_PC + mSelIcon->setParam(0.96f * mDoGph_gInf_c::hudAspectScaleUp, 0.84f, 0.06f, 0.5f, 0.5f); + #else mSelIcon->setParam(0.96f, 0.84f, 0.06f, 0.5f, 0.5f); + #endif #if PLATFORM_WII || PLATFORM_SHIELD field_0x4333 = mSelectMenuNum; @@ -3126,7 +3146,13 @@ void dFile_select_c::screenSet() { mSelIcon = JKR_NEW dSelect_cursor_c(0, 1.0f, NULL); JUT_ASSERT(5209, mSelIcon != NULL); + + #if TARGET_PC + mSelIcon->setParam(0.96f * mDoGph_gInf_c::hudAspectScaleUp, 0.94f, 0.03f, 0.7f, 0.7f); + #else mSelIcon->setParam(0.96f, 0.94f, 0.03f, 0.7f, 0.7f); + #endif + Vec vtxCenter; vtxCenter = mSelFilePanes[mSelectNum]->getGlobalVtxCenter(false, 0); mSelIcon->setPos(vtxCenter.x, vtxCenter.y, mSelFilePanes[mSelectNum]->getPanePtr(), true); @@ -3257,7 +3283,13 @@ void dFile_select_c::screenSetCopySel() { mSelIcon2 = JKR_NEW dSelect_cursor_c(0, 1.0f, NULL); JUT_ASSERT(5406, mSelIcon2 != NULL); + + #if TARGET_PC + mSelIcon2->setParam(0.96f * mDoGph_gInf_c::hudAspectScaleUp, 0.94f, 0.03f, 0.7f, 0.7f); + #else mSelIcon2->setParam(0.96f, 0.94f, 0.03f, 0.7f, 0.7f); + #endif + Vec center = mCpSelPane[0]->getGlobalVtxCenter(false, 0); mSelIcon2->setPos(center.x, center.y, mCpSelPane[0]->getPanePtr(), true); mSelIcon2->setAlphaRate(0.0f); @@ -3647,7 +3679,12 @@ void dFile_select_c::selFileCursorShow() { Vec local_1c = mSelFilePanes[mSelectNum]->getGlobalVtxCenter(false, 0); mSelIcon->setPos(local_1c.x, local_1c.y, mSelFilePanes[mSelectNum]->getPanePtr(), true); mSelIcon->setAlphaRate(1.0f); + + #if TARGET_PC + mSelIcon->setParam(0.96f * mDoGph_gInf_c::hudAspectScaleUp, 0.94f, 0.03f, 0.7f, 0.7f); + #else mSelIcon->setParam(0.96f, 0.94f, 0.03f, 0.7f, 0.7f); + #endif } void dFile_select_c::menuWakuAlpahAnmInit(u8 i_idx, u8 param_1, u8 param_2, u8 param_3) { @@ -3689,7 +3726,12 @@ void dFile_select_c::menuCursorShow() { Vec local_24 = m3mSelPane[mSelectMenuNum]->getGlobalVtxCenter(false, 0); mSelIcon->setPos(local_24.x, local_24.y, m3mSelPane[mSelectMenuNum]->getPanePtr(), true); mSelIcon->setAlphaRate(1.0f); + + #if TARGET_PC + mSelIcon->setParam(0.96f * mDoGph_gInf_c::hudAspectScaleUp, 0.84f, 0.06f, 0.5f, 0.5f); + #else mSelIcon->setParam(0.96f, 0.84f, 0.06f, 0.5f, 0.5f); + #endif } } @@ -3731,7 +3773,74 @@ bool dFile_select_c::yesnoWakuAlpahAnm(u8 param_1) { return rv; } +#if TARGET_PC +void dFile_select_c::fileSelectWide() { + mYnSel.ScrYn->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f); + mYnSel.ScrYn->translate(mDoGph_gInf_c::getMinXF(), 0.0f); + + mYnSel.ScrYn->search(MULTI_CHAR('w_no_t'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mYnSel.ScrYn->search(MULTI_CHAR('f_no_t'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mYnSel.ScrYn->search(MULTI_CHAR('w_yes_t'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mYnSel.ScrYn->search(MULTI_CHAR('f_yes_t'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + m3mSel.Scr3m->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f); + m3mSel.Scr3m->translate(mDoGph_gInf_c::getMinXF(), 0.0f); + + m3mSel.Scr3m->search(MULTI_CHAR('w_sta'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + m3mSel.Scr3m->search(MULTI_CHAR('f_sta'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + m3mSel.Scr3m->search(MULTI_CHAR('w_del'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + m3mSel.Scr3m->search(MULTI_CHAR('f_del'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + m3mSel.Scr3m->search(MULTI_CHAR('w_cop_t'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + m3mSel.Scr3m->search(MULTI_CHAR('f_cop_t'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + fileSel.Scr->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f); + fileSel.Scr->translate(mDoGph_gInf_c::getMinXF(), 0.0f); + + fileSel.Scr->search(MULTI_CHAR('t_for'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + fileSel.Scr->search(MULTI_CHAR('t_for1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + fileSel.Scr->search(MULTI_CHAR('w_btn_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + fileSel.Scr->search(MULTI_CHAR('w_n_bk00'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + fileSel.Scr->search(MULTI_CHAR('w_n_bk01'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + fileSel.Scr->search(MULTI_CHAR('w_n_bk02'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + fileSel.Scr->search(MULTI_CHAR('w_dat_i0'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + fileSel.Scr->search(MULTI_CHAR('w_dat_i1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + fileSel.Scr->search(MULTI_CHAR('w_dat_i2'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + mCpSel.Scr->search(MULTI_CHAR('w_dat_i1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mCpSel.Scr->search(MULTI_CHAR('w_dat_i2'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mCpSel.Scr->search(MULTI_CHAR('w_n_bk01'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mCpSel.Scr->search(MULTI_CHAR('w_n_bk02'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + mSelDt.ScrDt->search(MULTI_CHAR('tate_n0'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSelDt.ScrDt->search(MULTI_CHAR('tate_n1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSelDt.ScrDt->search(MULTI_CHAR('ken_n0'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSelDt.ScrDt->search(MULTI_CHAR('ken_n1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSelDt.ScrDt->search(MULTI_CHAR('fuku_n0'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSelDt.ScrDt->search(MULTI_CHAR('fuku_n1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSelDt.ScrDt->search(MULTI_CHAR('fuku_n2'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Spirals + fileSel.Scr->search(MULTI_CHAR('w_uzu00'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + fileSel.Scr->search(MULTI_CHAR('w_uzu01'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + fileSel.Scr->search(MULTI_CHAR('w_uzu02'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + fileSel.Scr->search(MULTI_CHAR('w_uzu03'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + fileSel.Scr->search(MULTI_CHAR('w_uzu04'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + fileSel.Scr->search(MULTI_CHAR('w_uzu05'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + fileSel.Scr->search(MULTI_CHAR('w_uzu06'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + fileSel.Scr->search(MULTI_CHAR('w_uzu07'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + fileSel.Scr->search(MULTI_CHAR('w_uzu08'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + fileSel.Scr->search(MULTI_CHAR('w_uzu09'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); +} +#endif + void dFile_select_c::_draw() { + #if TARGET_PC + fileSelectWide(); + #endif + if (!mHasDrawn) { dComIfGd_set2DOpa(&fileSel); diff --git a/src/d/d_gameover.cpp b/src/d/d_gameover.cpp index 693bcf371e..baec970a32 100644 --- a/src/d/d_gameover.cpp +++ b/src/d/d_gameover.cpp @@ -432,7 +432,14 @@ void dDlst_GameOverScrnDraw_c::draw() { img_white.a = 255; mpBackImg->setBlackWhite(img_black, img_white); + + #if TARGET_PC + mpBackImg->draw(mDoGph_gInf_c::getMinXF(), mDoGph_gInf_c::getMinYF(), + mDoGph_gInf_c::getWidthF(), mDoGph_gInf_c::getHeightF(), false, false, + false); + #else mpBackImg->draw(0.0f, 0.0f, FB_WIDTH, FB_HEIGHT, false, false, false); + #endif } else { JUtility::TColor img_black; JUtility::TColor img_white; @@ -447,7 +454,13 @@ void dDlst_GameOverScrnDraw_c::draw() { img_white.b = l_HIO.mWhite.b; img_white.a = l_HIO.mWhite.a; + #if TARGET_PC + mpBackImg->draw(mDoGph_gInf_c::getMinXF(), mDoGph_gInf_c::getMinYF(), + mDoGph_gInf_c::getWidthF(), mDoGph_gInf_c::getHeightF(), false, false, + false); + #else mpBackImg->draw(0.0f, 0.0f, FB_WIDTH, FB_HEIGHT, false, false, false); + #endif static f32 offset[8] = {-138.0f, -96.0f, -56.0f, -18.0f, 42.0f, 75.0f, 110.0f, 143.0f}; diff --git a/src/d/d_k_wmark.cpp b/src/d/d_k_wmark.cpp index 379b55f532..b93ab14211 100644 --- a/src/d/d_k_wmark.cpp +++ b/src/d/d_k_wmark.cpp @@ -6,6 +6,7 @@ #include "d/dolzel.h" // IWYU pragma: keep #include "d/d_k_wmark.h" +#include "dusk/memory.h" #include "JSystem/J3DGraphBase/J3DMaterial.h" #include "SSystem/SComponent/c_math.h" #include "d/actor/d_a_player.h" @@ -33,7 +34,7 @@ int dkWmark_c::create() { mColorType = this->parameters; } - mpHeap = mDoExt_createSolidHeapFromGameToCurrent(0x880, 0x20); + mpHeap = mDoExt_createSolidHeapFromGameToCurrent(HEAP_SIZE(0x880, 0x1100), 0x20); if (mpHeap != NULL) { JKRHEAP_NAME(mpHeap, "dkWmark_c::mpHeap"); J3DModelData* modelData = (J3DModelData*)dComIfG_getObjectRes("Alink", 0x23); diff --git a/src/d/d_kankyo.cpp b/src/d/d_kankyo.cpp index 50f9d716fc..8644d433aa 100644 --- a/src/d/d_kankyo.cpp +++ b/src/d/d_kankyo.cpp @@ -1,6 +1,7 @@ #include "d/dolzel.h" // IWYU pragma: keep #include "d/d_kankyo.h" +#include "dusk/memory.h" #ifdef __REVOLUTION_SDK__ #include #else @@ -775,7 +776,7 @@ static void dKy_FiveSenses_fullthrottle_dark_static1() { particle_size.y = 1.0f; particle_size.z = 1.0f; - #if !PLATFORM_GCN + #if !PLATFORM_GCN || TARGET_PC particle_size.x *= mDoGph_gInf_c::getScale(); #endif @@ -820,12 +821,20 @@ static void dKy_FiveSenses_fullthrottle_dark_static1() { } if (kankyo->senses_ef_emitter1 != NULL) { + #if TARGET_PC + kankyo->senses_ef_emitter1->setGlobalParticleScale(mDoGph_gInf_c::getScale(), 1.0f); + #endif + kankyo->senses_ef_emitter1->setGlobalTranslation(particle_pos.x, particle_pos.y, particle_pos.z); kankyo->senses_ef_emitter1->setGlobalAlpha(kankyo->senses_effect_strength * 255.0f); } if (kankyo->senses_ef_emitter2 != NULL) { + #if TARGET_PC + kankyo->senses_ef_emitter2->setGlobalParticleScale(mDoGph_gInf_c::getScale(), 1.0f); + #endif + kankyo->senses_ef_emitter2->setGlobalTranslation(particle_pos.x, particle_pos.y, particle_pos.z); @@ -1175,7 +1184,7 @@ static void undwater_init() { J3DModelData* modelData2 = (J3DModelData*)dComIfG_getObjectRes("Always", 0x1D); JUT_ASSERT(1867, modelData2 != NULL); - g_env_light.undwater_ef_heap = mDoExt_createSolidHeapFromGameToCurrent(0x600, 0x20); + g_env_light.undwater_ef_heap = mDoExt_createSolidHeapFromGameToCurrent(HEAP_SIZE(0x600, 0xC00), 0x20); JKRHEAP_NAME(g_env_light.undwater_ef_heap, "g_env_light.undwater_ef_heap"); if (g_env_light.undwater_ef_heap != NULL) { diff --git a/src/d/d_menu_collect.cpp b/src/d/d_menu_collect.cpp index c1281a86c2..72a390a0cc 100644 --- a/src/d/d_menu_collect.cpp +++ b/src/d/d_menu_collect.cpp @@ -95,6 +95,78 @@ dMenu_Collect2D_c::~dMenu_Collect2D_c() { } } +#if TARGET_PC +void dMenu_Collect2D_c::menuCollectWide() { + // Main Canvas + mpScreen->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f); + mpScreen->translate(mDoGph_gInf_c::getMinXF(), 0.0f); + + // Pieces of Heart + mpScreen->search(MULTI_CHAR('heart_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Scents + mpScreen->search(MULTI_CHAR('wolf_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Quiver + mpScreen->search(MULTI_CHAR('item_0_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Wallet + mpScreen->search(MULTI_CHAR('item_1_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Poes + mpScreen->search(MULTI_CHAR('item_2_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Fish Bestiary + mpScreen->search(MULTI_CHAR('fish_3_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Letters + mpScreen->search(MULTI_CHAR('lett_4_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Hidden Skills + mpScreen->search(MULTI_CHAR('maki_5_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Green Tunic + mpScreen->search(MULTI_CHAR('fuku_n0'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Zora Armor + mpScreen->search(MULTI_CHAR('fuku_n1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Magic Armor + mpScreen->search(MULTI_CHAR('fuku_n2'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Ordon Shield + mpScreen->search(MULTI_CHAR('tate_n0'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Hylian Shield + mpScreen->search(MULTI_CHAR('tate_n1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Ordon Sword + mpScreen->search(MULTI_CHAR('ken_n0'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Master Sword + mpScreen->search(MULTI_CHAR('ken_n1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Bugs + mpScreen->search(MULTI_CHAR('kabu_6n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // "Collection" Text + mpScreen->search(MULTI_CHAR('t_t00'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mpScreen->search(MULTI_CHAR('f_t00'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // "Save" Text + mpScreen->search(MULTI_CHAR('sa_tex_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // "Options" Text + mpScreen->search(MULTI_CHAR('op_tex_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Item Name Text + mpScreen->search(MULTI_CHAR('itemn_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Item Description Text + mpScreen->search(MULTI_CHAR('infotxtn'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); +} +#endif + void dMenu_Collect2D_c::_create() { mpHeap->getTotalFreeSize(); mpScreen = JKR_NEW J2DScreen(); @@ -108,7 +180,17 @@ void dMenu_Collect2D_c::_create() { mpButtonAB[i] = NULL; mpButtonText[i] = NULL; } + + #if TARGET_PC + mpScreenIcon->translate(-mDoGph_gInf_c::getMinXF(), 0.0f); + #endif + dPaneClass_showNullPane(mpScreenIcon); + + #if TARGET_PC + menuCollectWide(); + #endif + mpDraw2DTop = JKR_NEW dMenu_Collect2DTop_c(this); ResTIMG* image = (ResTIMG*)dComIfGp_getMain2DArchive()->getResource('TIMG', "tt_block8x8.bti"); mpBlackTex = JKR_NEW J2DPicture(image); @@ -508,6 +590,15 @@ void dMenu_Collect2D_c::screenSet() { field_0x184[4][2] = 0x196; field_0x184[5][2] = 0x195; field_0x184[6][2] = 0; +#if TARGET_PC // Since we allow changing wallet sizes, do something more robust. + if (dComIfGs_getWalletSize() == WALLET) { + field_0x184[0][3] = 0x199; + } else if (dComIfGs_getWalletSize() == BIG_WALLET) { + field_0x184[0][3] = 0x19a; + } else { + field_0x184[0][3] = 0x19b; + } +#else if (dComIfGs_getRupeeMax() == WALLET_MAX) { field_0x184[0][3] = 0x199; } else if (dComIfGs_getRupeeMax() == BIG_WALLET_MAX) { @@ -515,6 +606,7 @@ void dMenu_Collect2D_c::screenSet() { } else { field_0x184[0][3] = 0x19b; } +#endif if (dComIfGs_getArrowMax() == QUIVER_MAX) { field_0x184[1][3] = 0x1b9; } else if (dComIfGs_getArrowMax() == BIG_QUIVER_MAX) { @@ -675,7 +767,11 @@ void dMenu_Collect2D_c::screenSet() { setItemNameString(mCursorX, mCursorY); cursorPosSet(); setArrowMaxNum(dComIfGs_getArrowMax()); +#if TARGET_PC + setWalletSizeNum(dComIfGs_getWalletSize()); +#else setWalletMaxNum(dComIfGs_getRupeeMax()); +#endif setSmellType(); setHeartPiece(); setPohMaxNum(dComIfGs_getPohSpiritNum()); @@ -1004,11 +1100,23 @@ void dMenu_Collect2D_c::cursorPosSet() { Vec pos = mpSelPm[mCursorX][mCursorY]->getGlobalVtxCenter(false, 0); mpDrawCursor->setPos(pos.x, pos.y, mpSelPm[mCursorX][mCursorY]->getPanePtr(), false); if (mCursorY == 5) { + #if TARGET_PC + mpDrawCursor->setParam(1.1f * mDoGph_gInf_c::hudAspectScaleUp, 0.85f, 0.05f, 0.5f, 0.5f); + #else mpDrawCursor->setParam(1.1f, 0.85f, 0.05f, 0.5f, 0.5f); + #endif } else if (mCursorX == 6 && mCursorY == 0) { + #if TARGET_PC + mpDrawCursor->setParam(0.6f * mDoGph_gInf_c::hudAspectScaleUp, 0.85f, 0.03f, 0.6f, 0.6f); + #else mpDrawCursor->setParam(0.6f, 0.85f, 0.03f, 0.6f, 0.6f); + #endif } else { + #if TARGET_PC + mpDrawCursor->setParam(1.0f * mDoGph_gInf_c::hudAspectScaleUp, 1.0f, 0.1f, 0.7f, 0.7f); + #else mpDrawCursor->setParam(1.0f, 1.0f, 0.1f, 0.7f, 0.7f); + #endif } } @@ -1148,6 +1256,27 @@ void dMenu_Collect2D_c::setArrowMaxNum(u8 param_0) { } } +#if TARGET_PC +void dMenu_Collect2D_c::setWalletSizeNum(u16 i_walletSize) { + switch (i_walletSize) { + case WALLET: + mpScreen->search(MULTI_CHAR('item_1_0'))->show(); + mpScreen->search(MULTI_CHAR('item_1_1'))->hide(); + mpScreen->search(MULTI_CHAR('item_1_2'))->hide(); + break; + case BIG_WALLET: + mpScreen->search(MULTI_CHAR('item_1_0'))->hide(); + mpScreen->search(MULTI_CHAR('item_1_1'))->show(); + mpScreen->search(MULTI_CHAR('item_1_2'))->hide(); + break; + case GIANT_WALLET: + mpScreen->search(MULTI_CHAR('item_1_0'))->hide(); + mpScreen->search(MULTI_CHAR('item_1_1'))->hide(); + mpScreen->search(MULTI_CHAR('item_1_2'))->show(); + break; + } +} +#else void dMenu_Collect2D_c::setWalletMaxNum(u16 i_walletSize) { switch (i_walletSize) { case 300: @@ -1167,6 +1296,7 @@ void dMenu_Collect2D_c::setWalletMaxNum(u16 i_walletSize) { break; } } +#endif void dMenu_Collect2D_c::setSmellType() { static const u64 smell_tag[5] = { @@ -2028,6 +2158,10 @@ void dMenu_Collect2D_c::_move() { void dMenu_Collect2D_c::_draw() { + #if TARGET_PC + menuCollectWide(); + #endif + J2DGrafContext* grafPort = dComIfGp_getCurrentGrafPort(); grafPort->setup2D(); mpScreen->draw(0.0f, 0.0f, grafPort); @@ -2555,7 +2689,7 @@ f32 dMenu_Collect3D_c::mViewOffsetY = -100.0f; void dMenu_Collect3D_c::setupItem3D(Mtx param_0) { #if TARGET_PC - f32 scaleFactor = mDoGph_gInf_c::getWidth() / FB_WIDTH; // TODO: get display pixel density from aurora + f32 scaleFactor = mDoGph_gInf_c::getHeight() / FB_HEIGHT; GXSetViewport(0.0f, mViewOffsetY * scaleFactor, mDoGph_gInf_c::getWidth(), mDoGph_gInf_c::getHeight(), 0.0f, 1.0f); #else GXSetViewport(0.0f, mViewOffsetY, FB_WIDTH, FB_HEIGHT, 0.0f, 1.0f); diff --git a/src/d/d_menu_dmap.cpp b/src/d/d_menu_dmap.cpp index 97721d9dd2..739dfc7843 100644 --- a/src/d/d_menu_dmap.cpp +++ b/src/d/d_menu_dmap.cpp @@ -864,7 +864,16 @@ void dMenu_DmapBg_c::draw() { J2DOrthoGraph* grafContext = (J2DOrthoGraph*)dComIfGp_getCurrentGrafPort(); grafContext->setup2D(); +#if TARGET_PC + // GXGetScissor uses 11-bit GC register fields (max 2047) which overflow + // at window widths > ~1705px, producing garbage values on restore. + scissor_left = 0; + scissor_top = 0; + scissor_width = (u32)mDoGph_gInf_c::getWidth(); + scissor_height = (u32)mDoGph_gInf_c::getHeight(); +#else GXGetScissor(&scissor_left, &scissor_top, &scissor_width, &scissor_height); +#endif #if TARGET_PC grafContext->scissor(field_0xd94, 0.0f, mDoGph_gInf_c::getWidth(), mDoGph_gInf_c::getHeight()); #else @@ -876,8 +885,8 @@ void dMenu_DmapBg_c::draw() { dMenu_Dmap_c::myclass->drawFloorScreenBack(mFloorScreen, field_0xd94, field_0xd98, grafContext); #if TARGET_PC - f32 dVar21 = mDoGph_gInf_c::getWidth() / FB_WIDTH; - f32 dVar16 = mDoGph_gInf_c::getHeight() / FB_HEIGHT; + f32 dVar21 = mDoGph_gInf_c::getWidthF() / mDoGph_gInf_c::getWidth(); + f32 dVar16 = mDoGph_gInf_c::getHeightF() / mDoGph_gInf_c::getHeight(); #else f32 dVar21 = mDoGph_gInf_c::getWidthF() / FB_WIDTH; f32 dVar16 = mDoGph_gInf_c::getHeightF() / FB_HEIGHT; @@ -890,8 +899,15 @@ void dMenu_DmapBg_c::draw() { Mtx mtx; Vec local_200 = pane.getGlobalVtx(center_pane, &mtx, 0, false, 0); Vec local_20c = pane.getGlobalVtx(center_pane, &mtx, 3, false, 0); +#if TARGET_PC + grafContext->scissor(((local_200.x - mDoGph_gInf_c::getMinXF()) / dVar21), + ((local_200.y - mDoGph_gInf_c::getMinYF()) / dVar16), + ((local_20c.x - local_200.x) / dVar21), + (2.0f + (local_20c.y - local_200.y)) / dVar16); +#else grafContext->scissor(((local_200.x - mDoGph_gInf_c::getMinXF()) / dVar21), ((local_200.y / dVar16) / dVar16), ((local_20c.x - local_200.x) / dVar21), 2.0f + (local_20c.y - local_200.y)); +#endif grafContext->setScissor(); f32 dVar17 = field_0xd8c / 255.0f; @@ -925,10 +941,17 @@ void dMenu_DmapBg_c::draw() { Mtx local_110; Vec local_218 = pane.getGlobalVtx(center_pane, &local_110, 0, false, 0); Vec local_224 = pane.getGlobalVtx(center_pane, &local_110, 3, false, 0); +#if TARGET_PC + f32 local_294 = ((local_218.x - mDoGph_gInf_c::getMinXF()) / dVar21); + f32 local_298 = ((local_218.y - mDoGph_gInf_c::getMinYF()) / dVar16); + f32 local_29c = ((local_224.x - local_218.x) / dVar21); + f32 local_2a0 = (2.0f + (local_224.y - local_218.y)) / dVar16; +#else f32 local_294 = ((local_218.x - mDoGph_gInf_c::getMinXF()) / dVar21); f32 local_298 = ((local_218.y / dVar16) / dVar16); f32 local_29c = ((local_224.x - local_218.x) / dVar21); f32 local_2a0 = 2.0f + (local_224.y - local_218.y); +#endif grafContext->scissor(local_294, local_298, local_29c, local_2a0); grafContext->setScissor(); diff --git a/src/d/d_menu_fishing.cpp b/src/d/d_menu_fishing.cpp index 189ce57e0f..615323767b 100644 --- a/src/d/d_menu_fishing.cpp +++ b/src/d/d_menu_fishing.cpp @@ -114,7 +114,14 @@ void dMenu_Fishing_c::_draw() { if (mpArchive) { J2DGrafContext* grafPort = dComIfGp_getCurrentGrafPort(); mpBlackTex->setAlpha(0xff); + + #if TARGET_PC + mpBlackTex->draw(mDoGph_gInf_c::getMinXF(), mDoGph_gInf_c::getMinYF(), + mDoGph_gInf_c::getWidthF(), mDoGph_gInf_c::getHeightF(), 0, 0, 0); + #else mpBlackTex->draw(0.0f, 0.0f, FB_WIDTH, FB_HEIGHT, 0, 0, 0); + #endif + mpScreen->draw(0.0f, 0.0f, grafPort); mpIconScreen->draw(0.0f, 0.0f, grafPort); } diff --git a/src/d/d_menu_fmap2D.cpp b/src/d/d_menu_fmap2D.cpp index 29ec5db854..c9ab812400 100644 --- a/src/d/d_menu_fmap2D.cpp +++ b/src/d/d_menu_fmap2D.cpp @@ -359,7 +359,11 @@ void dMenu_Fmap2DBack_c::draw() { drawDebugRegionArea(); } +#if TARGET_PC + grafPort->scissor(scissorLeft, scissorTop, mDoGph_gInf_c::getWidth(), mDoGph_gInf_c::getHeight()); +#else grafPort->scissor(scissorLeft, scissorTop, scissorWidth, scissorHeight); +#endif grafPort->setScissor(); if (isArrowDrawFlag()) { @@ -1191,7 +1195,7 @@ f32 dMenu_Fmap2DBack_c::getMapScissorAreaSizeX() { } f32 dMenu_Fmap2DBack_c::getMapScissorAreaSizeRealX() { -#if PLATFORM_GCN +#if PLATFORM_GCN && !TARGET_PC return getMapScissorAreaSizeX(); #else return getMapScissorAreaSizeX() * mDoGph_gInf_c::getScale(); diff --git a/src/d/d_menu_insect.cpp b/src/d/d_menu_insect.cpp index 82be9287b6..7558fe61b4 100644 --- a/src/d/d_menu_insect.cpp +++ b/src/d/d_menu_insect.cpp @@ -161,12 +161,26 @@ void dMenu_Insect_c::_draw() { if (mpArchive != NULL) { J2DGrafContext* grafPort = dComIfGp_getCurrentGrafPort(); mpBlackTex->setAlpha(0xff); + + #if TARGET_PC + mpBlackTex->draw(mDoGph_gInf_c::getMinXF(), mDoGph_gInf_c::getMinYF(), + mDoGph_gInf_c::getWidthF(), mDoGph_gInf_c::getHeightF(), 0, 0, 0); + #else mpBlackTex->draw(0.0f, 0.0f, FB_WIDTH, FB_HEIGHT, 0, 0, 0); + #endif + mpScreen->draw(0.0f, 0.0f, grafPort); mpDrawCursor->draw(); field_0xfc = mpExpParent->getAlphaRate() * 150.0f; mpBlackTex->setAlpha(field_0xfc); + + #if TARGET_PC + mpBlackTex->draw(mDoGph_gInf_c::getMinXF(), mDoGph_gInf_c::getMinYF(), + mDoGph_gInf_c::getWidthF(), mDoGph_gInf_c::getHeightF(), 0, 0, 0); + #else mpBlackTex->draw(0.0f, 0.0f, FB_WIDTH, FB_HEIGHT, 0, 0, 0); + #endif + mpExpScreen->draw(0.0f, 0.0f, grafPort); mpSelect_c->setOffsetX(g_drawHIO.mInsectListScreen.mConfirmOptionPosX_4x3); mpSelect_c->translate(g_drawHIO.mInsectListScreen.mConfirmOptionPosX_4x3 + 486.0f, diff --git a/src/d/d_menu_item_explain.cpp b/src/d/d_menu_item_explain.cpp index 21a3a32fdd..c106b4bd8c 100644 --- a/src/d/d_menu_item_explain.cpp +++ b/src/d/d_menu_item_explain.cpp @@ -310,7 +310,12 @@ void dMenu_ItemExplain_c::draw(J2DOrthoGraph* i_graph) { mpLabel->scale(g_ringHIO.mItemDescTitleScale, g_ringHIO.mItemDescTitleScale); mpLabel->paneTrans(g_ringHIO.mItemDescTitlePosX, g_ringHIO.mItemDescTitlePosY); if (mpBackTex != NULL) { + #if TARGET_PC + mpBackTex->draw(mDoGph_gInf_c::ScaleHUDXLeft(0.0f), 0.0f, mDoGph_gInf_c::getWidthF(), + FB_HEIGHT, false, false, false); + #else mpBackTex->draw(0.0f, 0.0f, FB_WIDTH, FB_HEIGHT, false, false, false); + #endif } if (field_0xc8 != field_0xd0) { field_0xd0 = field_0xc8; diff --git a/src/d/d_menu_option.cpp b/src/d/d_menu_option.cpp index abe9f864ce..9384bc06b9 100644 --- a/src/d/d_menu_option.cpp +++ b/src/d/d_menu_option.cpp @@ -555,13 +555,25 @@ void dMenu_Option_c::_draw() { #endif mpBlackTex->setAlpha(0xff); +#if TARGET_PC + mpBlackTex->draw(mDoGph_gInf_c::getMinXF(), mDoGph_gInf_c::getMinYF(), mDoGph_gInf_c::getWidthF(), mDoGph_gInf_c::getHeightF(), 0, 0, 0); +#else mpBlackTex->draw(0.0f, 0.0f, FB_WIDTH, FB_HEIGHT, 0, 0, 0); +#endif mpBackScreen->draw(0.0f, 0.0f, ctx); f32 alpha = (f32)g_drawHIO.mOptionScreen.mBackgroundAlpha * (f32)field_0x374; mpBlackTex->setAlpha(alpha); +#if TARGET_PC + mpBlackTex->draw(mDoGph_gInf_c::getMinXF(), mDoGph_gInf_c::getMinYF(), mDoGph_gInf_c::getWidthF(), mDoGph_gInf_c::getHeightF(), 0, 0, 0); +#else mpBlackTex->draw(0.0f, 0.0f, FB_WIDTH, FB_HEIGHT, 0, 0, 0); +#endif mpScreen->draw(0.0f, 0.0f, ctx); mpClipScreen->draw(0.0f, 0.0f, ctx); +#if TARGET_PC + ctx->scissor(0.0f, 0.0f, mDoGph_gInf_c::getWidth(), mDoGph_gInf_c::getHeight()); + ctx->setScissor(); +#endif mpShadowScreen->draw(0.0f, 0.0f, ctx); if (field_0x3f3 == 1 || field_0x3f3 == 2 || field_0x3f3 == 3) { mpTVScreen->draw(0.0f, 0.0f, ctx); diff --git a/src/d/d_menu_save.cpp b/src/d/d_menu_save.cpp index ef1fb9d61e..618677866b 100644 --- a/src/d/d_menu_save.cpp +++ b/src/d/d_menu_save.cpp @@ -18,6 +18,7 @@ #include "m_Do/m_Do_controller_pad.h" #include "m_Do/m_Do_graphic.h" #include "d/d_msg_scrn_explain.h" +#include "dusk/settings.h" #include "JSystem/J2DGraph/J2DAnmLoader.h" #include "f_op/f_op_msg_mng.h" @@ -384,7 +385,12 @@ void dMenu_save_c::screenSet() { mSelectedFile = dComIfGs_getDataNum(); mSelIcon = JKR_NEW dSelect_cursor_c(0, 1.0f, NULL); + + #if TARGET_PC + mSelIcon->setParam(0.96f * mDoGph_gInf_c::hudAspectScaleUp, 0.94f, 0.03f, 0.7f, 0.7f); + #else mSelIcon->setParam(0.96f, 0.94f, 0.03f, 0.7f, 0.7f); + #endif Vec pos; pos = mpSelData[mSelectedFile]->getGlobalVtxCenter(false, 0); @@ -1177,7 +1183,7 @@ void dMenu_save_c::cardFormatYesSel2Disp() { bool moveAnm = yesnoMenuMoveAnm(); if (txtChangeAnm == true && moveAnm == true) { - mWaitTimer = g_msHIO.mCardWaitFrames; + mWaitTimer = dusk::getSettings().game.instantSaves ? 0 : g_msHIO.mCardWaitFrames; g_mDoMemCd_control.command_format(); mMenuProc = PROC_MEMCARD_FORMAT; } @@ -1249,7 +1255,7 @@ void dMenu_save_c::makeGameFileDisp() { bool ketteiDispAnm = ketteiTxtDispAnm(); if (txtChangeAnm == true && moveAnm == true && ketteiDispAnm == true) { - mWaitTimer = g_msHIO.mCardWaitFrames; + mWaitTimer = dusk::getSettings().game.instantSaves ? 0 : g_msHIO.mCardWaitFrames; setInitSaveData(); dataSave(); mMenuProc = PROC_MEMCARD_MAKE_GAME_FILE; @@ -1943,7 +1949,7 @@ void dMenu_save_c::saveMoveDisp() { if (headerTxtChanged == true && yesnoAnmComplete == true && ketteiAnmComplete == true && modoruAnmComplete == 1 && check == 1) { - mWaitTimer = g_msHIO.mCardWaitFrames; + mWaitTimer = dusk::getSettings().game.instantSaves ? 0 : g_msHIO.mCardWaitFrames; dataWrite(); mMenuProc = PROC_MEMCARD_DATA_SAVE_WAIT; } @@ -1961,7 +1967,7 @@ void dMenu_save_c::saveMoveDisp2() { if (headerTxtChanged == true && dataMoveAnm == true && wakuAnmComplete == true && ketteiAnmComplete == true && modoruAnmComplete == 1 && check == 1) { - mWaitTimer = g_msHIO.mCardWaitFrames; + mWaitTimer = dusk::getSettings().game.instantSaves ? 0 : g_msHIO.mCardWaitFrames; dataWrite(); mMenuProc = PROC_MEMCARD_DATA_SAVE_WAIT; } @@ -2516,7 +2522,12 @@ void dMenu_save_c::yesnoCursorShow() { Vec pos = mpNoYes[mYesNoCursor]->getGlobalVtxCenter(false, 0); mSelIcon->setPos(pos.x, pos.y, mpNoYes[mYesNoCursor]->getPanePtr(), true); mSelIcon->setAlphaRate(1.0f); + + #if TARGET_PC + mSelIcon->setParam(0.96f * mDoGph_gInf_c::hudAspectScaleUp, 0.84f, 0.06f, 0.5f, 0.5f); + #else mSelIcon->setParam(0.96f, 0.84f, 0.06f, 0.5f, 0.5f); + #endif } } @@ -2664,7 +2675,12 @@ void dMenu_save_c::selFileCursorShow() { Vec pos = mpSelData[mSelectedFile]->getGlobalVtxCenter(false, 0); mSelIcon->setPos(pos.x, pos.y, mpSelData[mSelectedFile]->getPanePtr(), true); mSelIcon->setAlphaRate(1.0f); + + #if TARGET_PC + mSelIcon->setParam(0.96f * mDoGph_gInf_c::hudAspectScaleUp, 0.94f, 0.03f, 0.7f, 0.7f); + #else mSelIcon->setParam(0.96f, 0.94f, 0.03f, 0.7f, 0.7f); + #endif } void dMenu_save_c::yesnoWakuAlpahAnmInit(u8 yesnoIdx, u8 startAlpha, u8 endAlpha, u8 anmTimer) { @@ -2763,6 +2779,43 @@ void dMenu_save_c::_draw() { } } +#if TARGET_PC +void dMenu_save_c::menuSaveWide() { + mSaveSel.Scr->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f); + mSaveSel.Scr->translate(mDoGph_gInf_c::getMinXF(), 0.0f); + + mSaveSel.Scr->search(MULTI_CHAR('t_for'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSaveSel.Scr->search(MULTI_CHAR('t_for1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + mSaveSel.Scr->search(MULTI_CHAR('w_btn_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + mSaveSel.Scr->search(MULTI_CHAR('w_n_bk00'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSaveSel.Scr->search(MULTI_CHAR('w_n_bk01'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSaveSel.Scr->search(MULTI_CHAR('w_n_bk02'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + mSaveSel.Scr->search(MULTI_CHAR('w_dat_i0'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSaveSel.Scr->search(MULTI_CHAR('w_dat_i1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSaveSel.Scr->search(MULTI_CHAR('w_dat_i2'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + mSaveSel.Scr->search(MULTI_CHAR('w_no_t'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSaveSel.Scr->search(MULTI_CHAR('f_no_t'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSaveSel.Scr->search(MULTI_CHAR('w_yes_t'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSaveSel.Scr->search(MULTI_CHAR('f_yes_t'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Spirals + mSaveSel.Scr->search(MULTI_CHAR('w_uzu00'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSaveSel.Scr->search(MULTI_CHAR('w_uzu01'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSaveSel.Scr->search(MULTI_CHAR('w_uzu02'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSaveSel.Scr->search(MULTI_CHAR('w_uzu03'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSaveSel.Scr->search(MULTI_CHAR('w_uzu04'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSaveSel.Scr->search(MULTI_CHAR('w_uzu05'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSaveSel.Scr->search(MULTI_CHAR('w_uzu06'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSaveSel.Scr->search(MULTI_CHAR('w_uzu07'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSaveSel.Scr->search(MULTI_CHAR('w_uzu08'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mSaveSel.Scr->search(MULTI_CHAR('w_uzu09'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); +} +#endif + void dMenu_save_c::_draw2() { if (field_0x21a1 == 0) { if (mpScrnExplain != NULL) { @@ -2770,6 +2823,10 @@ void dMenu_save_c::_draw2() { } if (mDisplayMenu) { + #if TARGET_PC + menuSaveWide(); + #endif + dComIfGd_set2DOpa(&mSaveSel); for (int i = 0; i < 3; i++) { diff --git a/src/d/d_menu_skill.cpp b/src/d/d_menu_skill.cpp index cc22e136c7..78ab82af94 100644 --- a/src/d/d_menu_skill.cpp +++ b/src/d/d_menu_skill.cpp @@ -143,12 +143,26 @@ void dMenu_Skill_c::_draw() { J2DGrafContext* context = dComIfGp_getCurrentGrafPort(); u8 alpha = mpBlackTex->mAlpha; mpBlackTex->setAlpha(0xff); + + #if TARGET_PC + mpBlackTex->draw(mDoGph_gInf_c::getMinXF(), mDoGph_gInf_c::getMinYF(), + mDoGph_gInf_c::getWidthF(), mDoGph_gInf_c::getHeightF(), 0, 0, 0); + #else mpBlackTex->draw(0.0f, 0.0f, FB_WIDTH, FB_HEIGHT, 0, 0, 0); + #endif + mpBlackTex->setAlpha(alpha); mpMenuScreen->draw(mPosX, 0.0f, context); mpDrawCursor->draw(); if (mProcess == 1 || mProcess == 2 || mProcess == 3) { + + #if TARGET_PC + mpBlackTex->draw(mDoGph_gInf_c::getMinXF(), mDoGph_gInf_c::getMinYF(), + mDoGph_gInf_c::getWidthF(), mDoGph_gInf_c::getHeightF(), 0, 0, 0); + #else mpBlackTex->draw(0.0f, 0.0f, FB_WIDTH, FB_HEIGHT, 0, 0, 0); + #endif + mpLetterScreen->draw(0.0f, 0.0f, context); if (mStringID != 0) { mpString->getString(mStringID, (J2DTextBox*)mpTextPane->getPanePtr(), NULL, NULL, diff --git a/src/d/d_menu_window.cpp b/src/d/d_menu_window.cpp index 3e173049bd..7fd5ea31a2 100644 --- a/src/d/d_menu_window.cpp +++ b/src/d/d_menu_window.cpp @@ -32,7 +32,7 @@ public: if (getDrawFlag() == 1) { setDrawFlag(); dComIfGp_onPauseFlag(); - + #if TARGET_PC GXSetTexCopySrc(0, 0, mDoGph_gInf_c::getWidth(), mDoGph_gInf_c::getHeight()); #else @@ -46,17 +46,23 @@ public: #endif GXCopyTex(mDoGph_gInf_c::getFrameBufferTex(), GX_FALSE); GXPixModeSync(); - } else { - TGXTexObj tex; #if TARGET_PC - GXInitTexObj(&tex, mDoGph_gInf_c::getFrameBufferTex(), mDoGph_gInf_c::getWidth(), mDoGph_gInf_c::getHeight(), + // init mTexObj at capture time so the gpu ref survives window resizes + GXInitTexObj(&mTexObj, mDoGph_gInf_c::getFrameBufferTex(), mDoGph_gInf_c::getWidth(), mDoGph_gInf_c::getHeight(), (GXTexFmt)mDoGph_gInf_c::getFrameBufferTimg()->format, GX_CLAMP, GX_CLAMP, GX_FALSE); + GXInitTexObjLOD(&mTexObj, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1); +#endif + } else { +#if TARGET_PC + // reuse the persistent mTexObj + GXLoadTexObj(&mTexObj, GX_TEXMAP0); #else + TGXTexObj tex; GXInitTexObj(&tex, mDoGph_gInf_c::getFrameBufferTex(), FB_WIDTH / 2, FB_HEIGHT / 2, (GXTexFmt)mDoGph_gInf_c::getFrameBufferTimg()->format, GX_CLAMP, GX_CLAMP, GX_FALSE); -#endif GXInitTexObjLOD(&tex, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1); GXLoadTexObj(&tex, GX_TEXMAP0); +#endif GXSetNumChans(0); GXSetNumTexGens(1); GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 60, GX_FALSE, 125); @@ -119,6 +125,9 @@ private: /* 0x4 */ u8 mFlag; /* 0x5 */ u8 mAlpha; /* 0x6 */ u8 mTopFlag; +#if TARGET_PC + TGXTexObj mTexObj; +#endif }; BOOL dMw_UP_TRIGGER() { @@ -1507,7 +1516,11 @@ void dMw_c::checkMemSize() { OS_REPORT("memory check ===> diff ==> %d, start ==> %d, now ==> %d\n", diff, mMemSize, now_size); +#if TARGET_PC + if (diff > 0x40) { +#else if (diff > 0x20) { +#endif OSReport_Error("memory free error!!\n"); } mMemSize = 0; diff --git a/src/d/d_meter2_draw.cpp b/src/d/d_meter2_draw.cpp index f222ee752a..58c6e24dc9 100644 --- a/src/d/d_meter2_draw.cpp +++ b/src/d/d_meter2_draw.cpp @@ -564,6 +564,7 @@ void dMeter2Draw_c::exec(u32 i_status) { { mButtonsPosX = g_drawHIO.mMainHUDButtonsPosX; mButtonsPosY = g_drawHIO.mMainHUDButtonsPosY; + mpButtonParent->paneTrans(g_drawHIO.mMainHUDButtonsPosX, g_drawHIO.mMainHUDButtonsPosY); } @@ -1589,7 +1590,9 @@ void dMeter2Draw_c::drawKanteraScreen(u8 i_meterType) { mpMagicFrameR->move(field_0x59c[i_meterType], field_0x5a8[i_meterType]); mpMagicBase->resize(field_0x5b4[i_meterType], field_0x5c0[i_meterType]); mpMagicParent->scale(field_0x5cc[i_meterType], field_0x5d8[i_meterType]); + mpMagicParent->paneTrans(field_0x5e4[i_meterType], field_0x5f0[i_meterType]); + mpKanteraScreen->draw(0.0f, 0.0f, graf_ctx); } @@ -1854,6 +1857,7 @@ void dMeter2Draw_c::drawLightDrop(u8 i_num, u8 i_needNum, f32 i_posX, f32 i_posY mLightDropVesselScale = i_vesselScale; mpLightDropParent->scale(mLightDropVesselScale * field_0x6f8, mLightDropVesselScale * field_0x6f8); + mpLightDropParent->paneTrans(i_posX, i_posY); } @@ -2001,6 +2005,7 @@ void dMeter2Draw_c::drawRupee(s16 i_rupeeNum) { mpRupeeKeyParent->scale(g_drawHIO.mRupeeKeyScale * field_0x718, g_drawHIO.mRupeeKeyScale * field_0x718); + mpRupeeKeyParent->paneTrans(g_drawHIO.mRupeeKeyPosX, g_drawHIO.mRupeeKeyPosY); mpRupeeParent[0]->scale(g_drawHIO.mRupeeScale, g_drawHIO.mRupeeScale); @@ -2582,6 +2587,7 @@ void dMeter2Draw_c::drawButtonCross(f32 i_posX, f32 i_posY) { mpButtonCrossParent->scale(g_drawHIO.mButtonCrossScale, g_drawHIO.mButtonCrossScale); mpTextI->scale(g_drawHIO.mButtonCrossTextScale, g_drawHIO.mButtonCrossTextScale); mpTextM->scale(g_drawHIO.mButtonCrossTextScale, g_drawHIO.mButtonCrossTextScale); + mpButtonCrossParent->paneTrans(i_posX, i_posY); } diff --git a/src/d/d_meter2_info.cpp b/src/d/d_meter2_info.cpp index 3e8d2601c1..7307755c04 100644 --- a/src/d/d_meter2_info.cpp +++ b/src/d/d_meter2_info.cpp @@ -1639,7 +1639,7 @@ u8 dMeter2Info_getPixel(f32 i_posX, f32 i_posY, f32 param_2, f32 param_3, f32 i_ JUT_ASSERT(3074, *pixel < i_resTimg->numColors); - u16* palette_p = (u16*)((uintptr_t)i_resTimg + i_resTimg->paletteOffset); + BE(u16)* palette_p = (BE(u16)*)((uintptr_t)i_resTimg + i_resTimg->paletteOffset); u16 var_r24 = (u16)palette_p[*pixel]; if (var_r24 & 0x8000) { return 1; @@ -1868,12 +1868,16 @@ f32 dMeter2Info_getWide2DPosX(f32* param_0) { } void dMeter2Info_onWide2D() { +#if !TARGET_PC g_ringHIO.updateOnWide(); +#endif g_drawHIO.updateOnWide(); } void dMeter2Info_offWide2D() { +#if !TARGET_PC g_ringHIO.updateOffWide(); +#endif g_drawHIO.updateOffWide(); } #endif diff --git a/src/d/d_meter_HIO.cpp b/src/d/d_meter_HIO.cpp index 685f9c580c..c23e6c3230 100644 --- a/src/d/d_meter_HIO.cpp +++ b/src/d/d_meter_HIO.cpp @@ -2287,7 +2287,22 @@ dMeter_drawHIO_c::dMeter_drawHIO_c() { } #if WIDESCREEN_SUPPORT -void dMeter_drawHIO_c::updateOnWide() {} +void dMeter_drawHIO_c::updateOnWide() { +#if TARGET_PC + g_drawHIO = {}; // this might be a bad idea + + g_drawHIO.mMainHUDButtonsPosX = mDoGph_gInf_c::ScaleHUDXRight(g_drawHIO.mMainHUDButtonsPosX); + g_drawHIO.mRingHUDButtonsPosX = mDoGph_gInf_c::ScaleHUDXRight(g_drawHIO.mRingHUDButtonsPosX); + g_drawHIO.mLightDrop.mVesselPosX = mDoGph_gInf_c::ScaleHUDXRight(g_drawHIO.mLightDrop.mVesselPosX); + g_drawHIO.mLightDrop.mVesselTalkPosX = mDoGph_gInf_c::ScaleHUDXRight(g_drawHIO.mLightDrop.mVesselTalkPosX); + g_drawHIO.mRupeeKeyPosX = mDoGph_gInf_c::ScaleHUDXRight(g_drawHIO.mRupeeKeyPosX); + g_drawHIO.mOxygenMeterPosX = mDoGph_gInf_c::ScaleHUDXLeft(g_drawHIO.mOxygenMeterPosX); + g_drawHIO.mButtonCrossOFFPosX = mDoGph_gInf_c::ScaleHUDXLeft(g_drawHIO.mButtonCrossOFFPosX); + g_drawHIO.mButtonCrossONPosX = mDoGph_gInf_c::ScaleHUDXLeft(g_drawHIO.mButtonCrossONPosX); + g_drawHIO.mLifeGaugePosX = mDoGph_gInf_c::ScaleHUDXLeft(g_drawHIO.mLifeGaugePosX); + g_drawHIO.mLanternMeterPosX = mDoGph_gInf_c::ScaleHUDXLeft(g_drawHIO.mLanternMeterPosX); +#endif +} void dMeter_drawHIO_c::updateOffWide() {} #endif @@ -3003,7 +3018,7 @@ void dMeter_drawHIO_c::updateFMsgDebug() { #endif dMeter_ringHIO_c::dMeter_ringHIO_c() { -#if WIDESCREEN_SUPPORT +#if WIDESCREEN_SUPPORT && !TARGET_PC updateOnWide(); #else mRingRadiusH = 175.0f; diff --git a/src/d/d_meter_map.cpp b/src/d/d_meter_map.cpp index 7e55d899fd..b5900a4be5 100644 --- a/src/d/d_meter_map.cpp +++ b/src/d/d_meter_map.cpp @@ -596,7 +596,8 @@ void dMeterMap_c::_draw() { #if TARGET_PC // Optimization: don't draw map if it's off-screen/invisible. // Especially useful in debug builds on Hyrule field etc., it's slow! - if ((!mMapIsInside && mSlidePositionOffset == getDispPosOutSide_OffsetX()) || mMapAlpha == 0) { + // That +3 is an arbitrary bias to avoid rounding issues causing this to fail. + if ((!mMapIsInside && mSlidePositionOffset <= getDispPosOutSide_OffsetX() + 3) || mMapAlpha == 0) { return; } #endif @@ -628,7 +629,13 @@ void dMeterMap_c::draw() { #endif mMapJ2DPicture->setAlpha(alpha); + #if TARGET_PC + mMapJ2DPicture->draw(mDoGph_gInf_c::ScaleHUDXLeft(drawPosX), drawPosY, sizeX, sizeY, false, + false, false); + #else mMapJ2DPicture->draw(drawPosX, drawPosY, sizeX, sizeY, false, false, false); + #endif + mMapJ2DPicture->calcMtx(); } } diff --git a/src/d/d_msg_scrn_item.cpp b/src/d/d_msg_scrn_item.cpp index 7cba6c7b86..40732eff25 100644 --- a/src/d/d_msg_scrn_item.cpp +++ b/src/d/d_msg_scrn_item.cpp @@ -411,7 +411,7 @@ void dMsgScrnItem_c::drawSelf() { f32 globalPosX = mpTm_c[0]->getGlobalPosX(); - #if WIDESCREEN_SUPPORT + #if WIDESCREEN_SUPPORT && !TARGET_PC if (mDoGph_gInf_c::isWide()) { drawOutFont(g_MsgObject_HIO_c.mBoxItemTextPosX + 7.0f + YREG_F(2), g_MsgObject_HIO_c.mBoxItemTextPosY, 1.0f); diff --git a/src/d/d_msg_scrn_place.cpp b/src/d/d_msg_scrn_place.cpp index 881852c259..b2c28efc95 100644 --- a/src/d/d_msg_scrn_place.cpp +++ b/src/d/d_msg_scrn_place.cpp @@ -101,13 +101,25 @@ void dMsgScrnPlace_c::exec() { mpFontParent->scale(g_MsgObject_HIO_c.mStageTitleCharSizeX, g_MsgObject_HIO_c.mStageTitleCharSizeY); + +#if TARGET_PC + mpFontParent->paneTrans(mDoGph_gInf_c::ScaleHUDXLeft(g_MsgObject_HIO_c.mStageTitleCharPosX), + g_MsgObject_HIO_c.mStageTitleCharPosY - mScaleX); +#else mpFontParent->paneTrans(g_MsgObject_HIO_c.mStageTitleCharPosX, g_MsgObject_HIO_c.mStageTitleCharPosY - mScaleX); +#endif mpBaseParent->scale(g_MsgObject_HIO_c.mStageTitleBaseSizeX, g_MsgObject_HIO_c.mStageTitleBaseSizeY); + +#if TARGET_PC + mpBaseParent->paneTrans(mDoGph_gInf_c::ScaleHUDXLeft(g_MsgObject_HIO_c.mStageTitleBasePosX), + g_MsgObject_HIO_c.mStageTitleBasePosY - mScaleY); +#else mpBaseParent->paneTrans(g_MsgObject_HIO_c.mStageTitleBasePosX, g_MsgObject_HIO_c.mStageTitleBasePosY - mScaleY); +#endif if (isTalkNow()) { fukiAlpha(1.0f); diff --git a/src/d/d_name.cpp b/src/d/d_name.cpp index ee51e2e583..120bcff752 100644 --- a/src/d/d_name.cpp +++ b/src/d/d_name.cpp @@ -918,6 +918,10 @@ void dName_c::selectCursorMove() { g_nmHIO.mSelCharScale); ((J2DTextBox*)mMojiIcon[mCharRow + mCharColumn * 5]->getPanePtr()) ->setWhite(JUtility::TColor(0xC8, 0xC8, 0xC8, 0xFF)); + + #if TARGET_PC + nameWide(); + #endif Vec pos = mMojiIcon[mCharRow + mCharColumn * 5]->getGlobalVtxCenter(false, 0); mSelIcon->setPos(pos.x, pos.y, mMojiIcon[mCharRow + mCharColumn * 5]->getPanePtr(), true); @@ -1281,7 +1285,58 @@ void dName_c::selectCursorPosSet(int row) { } } +#if TARGET_PC +void dName_c::nameWide() { + //Resize Select Icon + mSelIcon->setParam(0.82f * mDoGph_gInf_c::hudAspectScaleUp, 0.77f, 0.05f, 0.4f, 0.4f); + + // List of Characters Box + static u64 l_tagName[65] = { + MULTI_CHAR('m_00_0'), MULTI_CHAR('m_00_1'), MULTI_CHAR('m_00_2'), MULTI_CHAR('m_00_3'), MULTI_CHAR('m_00_4'), MULTI_CHAR('m_01_0'), MULTI_CHAR('m_01_1'), MULTI_CHAR('m_01_2'), MULTI_CHAR('m_01_3'), + MULTI_CHAR('m_01_4'), MULTI_CHAR('m_02_0'), MULTI_CHAR('m_02_1'), MULTI_CHAR('m_02_2'), MULTI_CHAR('m_02_3'), MULTI_CHAR('m_02_4'), MULTI_CHAR('m03_0'), MULTI_CHAR('m03_1'), MULTI_CHAR('m03_2'), + MULTI_CHAR('m03_3'), MULTI_CHAR('m03_4'), MULTI_CHAR('m_04_0'), MULTI_CHAR('m_04_1'), MULTI_CHAR('m_04_2'), MULTI_CHAR('m_04_3'), MULTI_CHAR('m_04_4'), MULTI_CHAR('m_05_0'), MULTI_CHAR('m_05_1'), + MULTI_CHAR('m_05_2'), MULTI_CHAR('m_05_3'), MULTI_CHAR('m_05_4'), MULTI_CHAR('m_06_0'), MULTI_CHAR('m_06_1'), MULTI_CHAR('m_06_2'), MULTI_CHAR('m_06_3'), MULTI_CHAR('m_06_4'), MULTI_CHAR('m_07_0'), + MULTI_CHAR('m_07_1'), MULTI_CHAR('m_07_2'), MULTI_CHAR('m_07_3'), MULTI_CHAR('m_07_4'), MULTI_CHAR('m_08_0'), MULTI_CHAR('m_08_1'), MULTI_CHAR('m_08_2'), MULTI_CHAR('m_08_3'), MULTI_CHAR('m_08_4'), + MULTI_CHAR('m_09_0'), MULTI_CHAR('m_09_1'), MULTI_CHAR('m_09_2'), MULTI_CHAR('m_09_3'), MULTI_CHAR('m_09_4'), MULTI_CHAR('m_10_0'), MULTI_CHAR('m_10_1'), MULTI_CHAR('m_10_2'), MULTI_CHAR('m_10_3'), + MULTI_CHAR('m_10_4'), MULTI_CHAR('m_11_0'), MULTI_CHAR('m_11_1'), MULTI_CHAR('m_11_2'), MULTI_CHAR('m_11_3'), MULTI_CHAR('m_11_4'), MULTI_CHAR('m12_0'), MULTI_CHAR('m12_1'), MULTI_CHAR('m12_2'), + MULTI_CHAR('m12_3'), MULTI_CHAR('m12_4'), + }; + + for (u32 i = 0; i < 65; i++) { + nameIn.NameInScr->search(l_tagName[i])->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + } + + // "END" Text + nameIn.NameInScr->search(MULTI_CHAR('p_end_2'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + nameIn.NameInScr->search(MULTI_CHAR('p_end_1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + nameIn.NameInScr->search(MULTI_CHAR('p_end_0'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Letters being typed + static u64 l_nameTagName[8] = { + MULTI_CHAR('name_00'), MULTI_CHAR('name_01'), MULTI_CHAR('name_02'), MULTI_CHAR('name_03'), MULTI_CHAR('name_04'), MULTI_CHAR('name_05'), MULTI_CHAR('name_06'), MULTI_CHAR('name_07'), + }; + + for (u32 i = 0; i < 8; i++) { + nameIn.NameInScr->search(l_nameTagName[i])->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + } + + // Underscores when typing below letters + static u64 l_nameCurTagName[8] = { + MULTI_CHAR('s__n_00'), MULTI_CHAR('s__n_01'), MULTI_CHAR('s__n_02'), MULTI_CHAR('s__n_03'), MULTI_CHAR('s__n_04'), MULTI_CHAR('s__n_05'), MULTI_CHAR('s__n_06'), MULTI_CHAR('s__n_07'), + }; + + for (u32 i = 0; i < 8; i++) { + nameIn.NameInScr->search(l_nameCurTagName[i]) + ->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + } +} +#endif + void dName_c::_draw() { + #if TARGET_PC + nameWide(); + #endif + dComIfGd_set2DOpa(&nameIn); dComIfGd_set2DOpa(mSelIcon); } @@ -1484,7 +1539,12 @@ void dName_c::screenSet() { mSelIcon = JKR_NEW dSelect_cursor_c(0, 1.0f, NULL); JUT_ASSERT(0, mSelIcon != NULL); + + #if TARGET_PC + mSelIcon->setParam(0.82f * mDoGph_gInf_c::hudAspectScaleUp, 0.77f, 0.05f, 0.4f, 0.4f); + #else mSelIcon->setParam(0.82f, 0.77f, 0.05f, 0.4f, 0.4f); + #endif Vec pos = mMojiIcon[mCharRow + mCharColumn * 5]->getGlobalVtxCenter(false, 0); mSelIcon->setPos(pos.x, pos.y, mMojiIcon[mCharRow + mCharColumn * 5]->getPanePtr(), true); diff --git a/src/d/d_ovlp_fade2.cpp b/src/d/d_ovlp_fade2.cpp index 093aaadddd..37dbeedba2 100644 --- a/src/d/d_ovlp_fade2.cpp +++ b/src/d/d_ovlp_fade2.cpp @@ -51,8 +51,14 @@ void dOvlpFd2_dlst_c::draw() { GXEnd(); Mtx44 m; + + #if TARGET_PC + C_MTXPerspective(m, 60.0f, 1.3571428f, 100.0f, 100000.0f); + #else C_MTXPerspective(m, 60.0f, mDoGph_gInf_c::getWidthF() / mDoGph_gInf_c::getHeightF(), 100.0f, 100000.0f); + #endif + GXSetProjection(m, GX_PERSPECTIVE); #ifdef TARGET_PC mDoGph_gInf_c::getFrameBufferTexObj()->reset(); diff --git a/src/d/d_ovlp_fade3.cpp b/src/d/d_ovlp_fade3.cpp index 70304451fb..d6f432f3ee 100644 --- a/src/d/d_ovlp_fade3.cpp +++ b/src/d/d_ovlp_fade3.cpp @@ -64,8 +64,14 @@ void dOvlpFd3_dlst_c::draw() { GXEnd(); Mtx44 m; + + #if TARGET_PC + C_MTXPerspective(m, 60.0f, 1.3571428f, 100.0f, 100000.0f); + #else C_MTXPerspective(m, 60.0f, mDoGph_gInf_c::getWidthF() / mDoGph_gInf_c::getHeightF(), 100.0f, 100000.0f); + #endif + GXSetProjection(m, GX_PERSPECTIVE); #ifdef TARGET_PC mDoGph_gInf_c::getFrameBufferTexObj()->reset(); diff --git a/src/d/d_stage.cpp b/src/d/d_stage.cpp index 057bcdf4ff..f3cdfed17b 100644 --- a/src/d/d_stage.cpp +++ b/src/d/d_stage.cpp @@ -393,13 +393,7 @@ static void dummy1(dStage_roomControl_c* roomControl) { JKRExpHeap* dStage_roomControl_c::createMemoryBlock(int i_blockIdx, u32 i_heapSize) { #if TARGET_PC - // Cave of Ordeals crashes around floor 29 due to no free heap space - // Increasing the size here avoids that, though its ugly. maybe TODO a better fix - if (strcmp(dComIfGp_getStartStageName(), "D_SB01") == 0) { - u32 prev = i_heapSize; - i_heapSize *= 2; - DuskLog.warn("Doubling heap size for D_SB01... ({}) -> ({})", prev, i_heapSize); - } + i_heapSize *= 2; #endif if (mMemoryBlock[i_blockIdx] == NULL) { diff --git a/src/dusk/OSContext.cpp b/src/dusk/OSContext.cpp index 9aa6932e52..d2bb1803ea 100644 --- a/src/dusk/OSContext.cpp +++ b/src/dusk/OSContext.cpp @@ -23,16 +23,11 @@ void OSSetCurrentContext(OSContext* context) { } void OSClearContext(OSContext* context) { - if (!context) return; - context->mode = 0; - context->state = 0; + // No-op on PC } void OSInitContext(OSContext* context, u32 pc, u32 newsp) { - if (!context) return; - memset(context, 0, sizeof(OSContext)); - context->srr0 = pc; - context->gpr[1] = newsp; + // No-op on PC } void OSDumpContext(OSContext* context) { diff --git a/src/dusk/OSThread.cpp b/src/dusk/OSThread.cpp index ea9c568eef..af339e8656 100644 --- a/src/dusk/OSThread.cpp +++ b/src/dusk/OSThread.cpp @@ -101,7 +101,7 @@ static thread_local OSThread* tls_currentThread = nullptr; static OSThread sDefaultThread; static u8 sDefaultStack[64 * 1024]; -static u32 sDefaultStackEnd = OS_THREAD_STACK_MAGIC; +static u8 sDefaultStackEnd = OS_THREAD_STACK_MAGIC; // Global interrupt mutex (coarse-grained lock replacing interrupt disable) // Lazy-initialized to avoid DLL static init crashes @@ -237,7 +237,7 @@ int OSCreateThread(OSThread* thread, void* (*func)(void*), void* param, // Stack (stack points to TOP on GameCube) thread->stackBase = (u8*)stack; - thread->stackEnd = (u32*)((uintptr_t)stack - stackSize); + thread->stackEnd = (u8*)((uintptr_t)stack - stackSize); *thread->stackEnd = OS_THREAD_STACK_MAGIC; OSClearContext(&thread->context); @@ -496,7 +496,7 @@ void OSDetachThread(OSThread* thread) { OSWakeupThread(&thread->queueJoin); } -int OSJoinThread(OSThread* thread, void* val) { +BOOL OSJoinThread(OSThread* thread, void** val) { if (!thread) return 0; if (!(thread->attr & OS_THREAD_ATTR_DETACH)) { diff --git a/src/dusk/audio/DuskAudioSystem.cpp b/src/dusk/audio/DuskAudioSystem.cpp index c7313749c2..7b464e4f0e 100644 --- a/src/dusk/audio/DuskAudioSystem.cpp +++ b/src/dusk/audio/DuskAudioSystem.cpp @@ -76,6 +76,12 @@ void dusk::audio::SetMasterVolume(const f32 value) { MasterVolume = value; } +void dusk::audio::SetEnableReverb(const bool value) { + JASCriticalSection section; + + EnableReverb = value; +} + void SDLCALL GetNewAudio( void*, SDL_AudioStream*, diff --git a/src/dusk/audio/DuskDsp.cpp b/src/dusk/audio/DuskDsp.cpp index 3e32d3e7ff..e7dff6a2a5 100644 --- a/src/dusk/audio/DuskDsp.cpp +++ b/src/dusk/audio/DuskDsp.cpp @@ -9,6 +9,7 @@ #include #include "Adpcm.hpp" +#include "freeverb/revmodel.hpp" #include "JSystem/JAudio2/JASDriverIF.h" #include "dusk/audio/DuskAudioSystem.h" #include "dusk/endian.h" @@ -18,6 +19,9 @@ using namespace dusk::audio; ChannelAuxData dusk::audio::ChannelAux[DSP_CHANNELS] = {}; +static revmodel SharedReverb; +static bool ReverbHasTail = false; + static bool sDumpWasActive = false; static FILE* sChannelDumpFiles[DSP_CHANNELS] = {}; @@ -140,37 +144,37 @@ void dusk::audio::DspRender(OutputSubframe& subframe) { std::span channels(JASDsp::CH_BUF, DSP_CHANNELS); + DspSubframe reverbInputL = {}; + DspSubframe reverbInputR = {}; + bool anyReverbInput = false; + for (int i = 0; i < channels.size(); i++) { auto& channel = channels[i]; auto& channelAux = ChannelAux[i]; - bool skipRender = false; - if (!channel.mIsActive) { - skipRender = true; + continue; } else if (channel.mPauseFlag) { // Not really sure what the practical difference between pause and // deactivation is. Either avoids clearing state or allows the DSP to avoid popping? - skipRender = true; + continue; } else if (channel.mForcedStop) { channel.mIsFinished = true; - skipRender = true; + continue; } else if (channel.mWaveAramAddress == 0) { // I think these are oscillator channels? Not backed by audio. // No idea how to implement these yet, so skip them. channel.mIsFinished = true; - skipRender = true; + continue; } + ValidateChannel(channel); + OutputSubframe channelSubframe = {}; - - if (!skipRender) { - ValidateChannel(channel); - RenderChannel(channel, channelAux, channelSubframe); - } + RenderChannel(channel, channelAux, channelSubframe); if (EnableReverb) { // scale the input to the reverb rather than using wet/dry on the output. @@ -178,31 +182,23 @@ void dusk::audio::DspRender(OutputSubframe& subframe) { // so any tail always decays at the correct level regardless of mAutoMixerFxMix changes // prevents transients when the next sound starts playing with a different reverb level // 600.0f was pulled out of my ass and just sounds good enough for console - f32 inputGain = (!skipRender) ? (channel.mAutoMixerFxMix >> 8) / 600.0f : 0.0f; - - OutputSubframe reverbSubframe = {}; - for (int j = 0; j < DSP_SUBFRAME_SIZE; j++) { - reverbSubframe.channels[0][j] = channelSubframe.channels[0][j] * inputGain; - reverbSubframe.channels[1][j] = channelSubframe.channels[1][j] * inputGain; - } - - channelAux.reverb.processreplace( - reverbSubframe.channels[0].data(), reverbSubframe.channels[1].data(), - reverbSubframe.channels[0].data(), reverbSubframe.channels[1].data(), - DSP_SUBFRAME_SIZE, 1 - ); - - for (int j = 0; j < DSP_SUBFRAME_SIZE; j++) { - channelSubframe.channels[0][j] += reverbSubframe.channels[0][j]; - channelSubframe.channels[1][j] += reverbSubframe.channels[1][j]; + f32 inputGain = (channel.mAutoMixerFxMix >> 8) / 600.0f; + if (inputGain > 0) { + anyReverbInput = true; + for (int j = 0; j < DSP_SUBFRAME_SIZE; j++) { + reverbInputL[j] += channelSubframe.channels[0][j] * inputGain; + reverbInputR[j] += channelSubframe.channels[1][j] * inputGain; + } } } if (DumpAudio && sChannelDumpFiles[i]) { + f32 interleaved[DSP_SUBFRAME_SIZE * 2]; for (int j = 0; j < DSP_SUBFRAME_SIZE; j++) { - fwrite(&channelSubframe.channels[0][j], sizeof(f32), 1, sChannelDumpFiles[i]); - fwrite(&channelSubframe.channels[1][j], sizeof(f32), 1, sChannelDumpFiles[i]); + interleaved[j * 2 + 0] = channelSubframe.channels[0][j]; + interleaved[j * 2 + 1] = channelSubframe.channels[1][j]; } + fwrite(interleaved, sizeof(f32), DSP_SUBFRAME_SIZE * 2, sChannelDumpFiles[i]); } for (int o = 0; o < subframe.channels.size(); o++) { @@ -210,6 +206,17 @@ void dusk::audio::DspRender(OutputSubframe& subframe) { } } + if (EnableReverb && (anyReverbInput || ReverbHasTail)) { + // Equivalent to -80 dBFS: rms = 1e-4, rms^2 = 1e-8, sumSq = 2 * N * 1e-8 + constexpr f32 REVERB_ENERGY_EPSILON = 2.0f * DSP_SUBFRAME_SIZE * 1e-8f; + f32 wetEnergy = SharedReverb.processmix( + reverbInputL.data(), reverbInputR.data(), + subframe.channels[0].data(), subframe.channels[1].data(), + DSP_SUBFRAME_SIZE, 1, 1.0f + ); + ReverbHasTail = wetEnergy >= REVERB_ENERGY_EPSILON; + } + for (auto& channel : subframe.channels) { ApplyVolume(channel, channel, PrevMasterVolume, MasterVolume); } @@ -341,7 +348,7 @@ static void FillDecodeBuf(JASDsp::TChannel& channel, ChannelAuxData& aux, int ne } aux.decodeBufCount += ReadChannelSamplesChunk( - channel, aux, std::min(remainingDecodeSpace, needed - aux.decodeBufCount), + channel, aux, std::min(remainingDecodeSpace, needed - aux.decodeBufCount), aux.decodeBuf + aux.decodeBufCount, remainingDecodeSpace ); } @@ -491,17 +498,17 @@ static void RenderChannel( } DspSubframe audioLoadBuffer = {}; - f64 pos = channelAux.resamplePos; + f32 pos = channelAux.resamplePos; s16 prev = channelAux.resamplePrev; s16 next = channelAux.decodeBufCount > 0 ? channelAux.decodeBuf[0] : prev; int srcIdx = 0; // linear resampling and f32 conversion for (int i = 0; i < DSP_SUBFRAME_SIZE; i++) { - audioLoadBuffer[i] = static_cast(prev + pos * (next - prev)) / 32768.0f; + audioLoadBuffer[i] = (prev + pos * (next - prev)) / 32768.0f; pos += step; - while (pos >= 1.0) { - pos -= 1.0; + while (pos >= 1.0f) { + pos -= 1.0f; prev = next; srcIdx++; next = srcIdx < channelAux.decodeBufCount ? channelAux.decodeBuf[srcIdx] : prev; @@ -529,16 +536,13 @@ static void RenderChannel( } void dusk::audio::DspInit() { - for (int i = 0; i < DSP_CHANNELS; i++) { - auto& channelAux = ChannelAux[i]; - channelAux.reverb.setwet(1.0f); - channelAux.reverb.setdry(0.0f); - channelAux.reverb.setroomsize(0.5f); - channelAux.reverb.setdamp(0.7f); - channelAux.reverb.setwidth(1.0f); - channelAux.reverb.setmode(0.0f); - channelAux.reverb.mute(); - } + SharedReverb.setwet(1.0f); + SharedReverb.setdry(0.0f); + SharedReverb.setroomsize(0.5f); + SharedReverb.setdamp(0.7f); + SharedReverb.setwidth(1.0f); + SharedReverb.setmode(0.0f); + SharedReverb.mute(); } void dusk::audio::ApplyVolume( @@ -549,15 +553,13 @@ void dusk::audio::ApplyVolume( assert(dst.size() >= src.size()); if (startVolume == endVolume) { - for (int i = 0; i < src.size(); i++) { + for (int i = 0; i < (int)src.size(); i++) { dst[i] = src[i] * startVolume; } } else { const f32 step = (endVolume - startVolume) / static_cast(src.size()); - auto curVolume = startVolume; - for (int i = 0; i < src.size(); i++) { - dst[i] = src[i] * curVolume; - curVolume += step; + for (int i = 0; i < (int)src.size(); i++) { + dst[i] = src[i] * (startVolume + i * step); } } } diff --git a/src/dusk/audio/DuskDsp.hpp b/src/dusk/audio/DuskDsp.hpp index 728234b75c..c7cb751458 100644 --- a/src/dusk/audio/DuskDsp.hpp +++ b/src/dusk/audio/DuskDsp.hpp @@ -8,8 +8,6 @@ #include "SDL3/SDL_audio.h" #include -#include "freeverb/revmodel.hpp" - // ReSharper disable once CppUnusedIncludeDirective #include "global.h" @@ -31,7 +29,6 @@ namespace dusk::audio { // Used for debugging tools. u32 resetCount; - revmodel reverb; /** * Previous volume values, per output channel. diff --git a/src/dusk/dvd_asset.cpp b/src/dusk/dvd_asset.cpp new file mode 100644 index 0000000000..b9e0729be9 --- /dev/null +++ b/src/dusk/dvd_asset.cpp @@ -0,0 +1,125 @@ +#include "dusk/dvd_asset.hpp" +#include "dusk/logging.h" +#include "dusk/endian.h" +#include "dolphin/dvd.h" +#include "DynamicLink.h" +#include "JSystem/JKernel/JKRArchive.h" +#include "JSystem/JKernel/JKRDvdRipper.h" + +#include + +namespace dusk { + +static const u8* s_dolData = nullptr; // pointer to dol data +static size_t s_dolSize = 0; + +struct DolHeader { + BE(u32) textOffset[7]; + BE(u32) dataOffset[11]; + BE(u32) textAddr[7]; + BE(u32) dataAddr[11]; + BE(u32) textSize[7]; + BE(u32) dataSize[11]; +}; + +struct DolSection { + u32 fileOffset; + u32 vaddr; + u32 size; +}; + +static DolSection s_dolSections[18]; // 7 text + 11 data +static int s_dolSectionCount = 0; + +static bool EnsureDolParsed() { + if (s_dolData) return true; + + s32 sz = 0; + const u8* p = DVDGetDOLLocation(&sz); + if (!p || sz < 256) { + DuskLog.fatal("dvd_asset: DVDGetDOLLocation failed (size={})", sz); + return false; + } + + s_dolData = p; + s_dolSize = sz; + + const auto* hdr = (const DolHeader*)s_dolData; + s_dolSectionCount = 0; + + for (int i = 0; i < 7; i++) { + u32 off = hdr->textOffset[i]; + u32 addr = hdr->textAddr[i]; + u32 sz = hdr->textSize[i]; + if (sz > 0 && off > 0) { + s_dolSections[s_dolSectionCount++] = {off, addr, sz}; + } + } + + for (int i = 0; i < 11; i++) { + u32 off = hdr->dataOffset[i]; + u32 addr = hdr->dataAddr[i]; + u32 sz = hdr->dataSize[i]; + if (sz > 0 && off > 0) { + s_dolSections[s_dolSectionCount++] = {off, addr, sz}; + } + } + + return true; +} + +static s32 DolVaToFileOffset(u32 va) { + if (!EnsureDolParsed()) return -1; + for (int i = 0; i < s_dolSectionCount; i++) { + const auto& sec = s_dolSections[i]; + if (va >= sec.vaddr && va < sec.vaddr + sec.size) { + return static_cast(sec.fileOffset + (va - sec.vaddr)); + } + } + DuskLog.fatal("dvd_asset: VA 0x{:08X} not found in any DOL section", va); + return -1; +} + +bool LoadDolAsset(void* dst, u32 virtualAddress, s32 size) { + s32 fileOffset = DolVaToFileOffset(virtualAddress); + if (fileOffset < 0) { + return false; + } + + if (size <= 0 || (size_t)(fileOffset + size) > s_dolSize) { + DuskLog.fatal("dvd_asset: DOL read out of range (offset={:#x} size={:#x} dolSize={})", fileOffset, size, s_dolSize); + return false; + } + + std::memcpy(dst, s_dolData + fileOffset, size); + return true; +} + +bool LoadRelAsset(void* dst, const char* dvdPath, s32 offset, s32 size) { + void* p = JKRDvdRipper::loadToMainRAM(dvdPath, (u8*)dst, EXPAND_SWITCH_UNKNOWN1, (u32)size, nullptr, JKRDvdRipper::ALLOC_DIRECTION_FORWARD, (u32)offset, nullptr, nullptr); + if (!p) DuskLog.fatal("dvd_asset: failed to load {} (offset={:#x} size={:#x})", dvdPath, offset, size); + return p != nullptr; +} + +bool LoadArchivedRelAsset(void* dst, u32 memType, const char* relFileName, s32 offset, s32 size) { + // On TARGET_PC, cDyl_InitCallback skips DynamicModuleControl::initialize() due to static linking + // Mount RELS.arc on first use so sArchive is available + static bool s_mountAttempted = false; + if (!DynamicModuleControl::sArchive && !s_mountAttempted) { + s_mountAttempted = true; DynamicModuleControl::initialize(); + } + + if (!DynamicModuleControl::sArchive) { + DuskLog.fatal("dvd_asset: RELS archive not mounted"); return false; + } + + const u8* rel = static_cast(DynamicModuleControl::sArchive->getResource(memType, relFileName)); + if (!rel) { + DuskLog.fatal("dvd_asset: {} not found in RELS archive", relFileName); return false; + } + + std::memcpy(dst, rel + offset, size); + return true; +} + +} // namespace dusk diff --git a/src/dusk/imgui/ImGuiConfig.hpp b/src/dusk/imgui/ImGuiConfig.hpp index fc5aa34bbd..e3e80b9920 100644 --- a/src/dusk/imgui/ImGuiConfig.hpp +++ b/src/dusk/imgui/ImGuiConfig.hpp @@ -5,36 +5,48 @@ #include "imgui.h" namespace dusk::config { - inline void ImGuiCheckbox(const char* title, ConfigVar& var) { + inline bool ImGuiCheckbox(const char* title, ConfigVar& var) { bool copy = var.getValue(); if (ImGui::Checkbox(title, ©)) { var.setValue(copy); Save(); + return true; } + + return false; } - static void ImGuiSliderFloat(const char* label, ConfigVar& var, float v_min, float v_max, const char* format = "%.3f", ImGuiSliderFlags flags = 0) { + static bool ImGuiSliderFloat(const char* label, ConfigVar& var, float v_min, float v_max, const char* format = "%.3f", ImGuiSliderFlags flags = 0) { float val = var; if (ImGui::SliderFloat(label, &val, v_min, v_max, format, flags)) { var.setValue(val); Save(); + return true; } + + return false; } - static void ImGuiSliderInt(const char* label, ConfigVar& var, int v_min, int v_max, const char* format = "%d", ImGuiSliderFlags flags = 0) { + static bool ImGuiSliderInt(const char* label, ConfigVar& var, int v_min, int v_max, const char* format = "%d", ImGuiSliderFlags flags = 0) { int val = var; if (ImGui::SliderInt(label, &val, v_min, v_max, format, flags)) { var.setValue(val); Save(); + return true; } + + return false; } - static void ImGuiMenuItem(const char* label, const char* shortcut, ConfigVar& p_selected, bool enabled = true) { + static bool ImGuiMenuItem(const char* label, const char* shortcut, ConfigVar& p_selected, bool enabled = true) { bool copy = p_selected.getValue(); if (ImGui::MenuItem(label, shortcut, ©, enabled)) { p_selected.setValue(copy); Save(); + return true; } + + return false; } } diff --git a/src/dusk/imgui/ImGuiConsole.cpp b/src/dusk/imgui/ImGuiConsole.cpp index 5b025e15ab..8bc526ef53 100644 --- a/src/dusk/imgui/ImGuiConsole.cpp +++ b/src/dusk/imgui/ImGuiConsole.cpp @@ -7,14 +7,16 @@ #include "fmt/format.h" #include "imgui.h" -#include "aurora/gfx.h" #include #include "ImGuiConsole.hpp" #include "JSystem/JUtility/JUTGamePad.h" +#include "SDL3/SDL_mouse.h" #include "dusk/config.hpp" #include "dusk/settings.h" +#include "dusk/audio/DuskAudioSystem.h" +#include "dusk/dusk.h" #if _WIN32 #define NOMINMAX @@ -156,10 +158,13 @@ namespace dusk { auto itemMin = ImGui::GetItemRectMin(); auto itemMax = ImGui::GetItemRectMax(); + float frameSpacingY = 8.0f; + float frameBottomPadding = 10.0f; + ImVec2 halfFrame = ImVec2((frameHeight * 0.25f) * 0.5f, frameHeight * 0.5f); ImGui::GetWindowDrawList()->AddRect( - ImVec2(itemMin.x + halfFrame.x, itemMin.y + halfFrame.y), - ImVec2(itemMax.x - halfFrame.x, itemMax.y), + ImVec2(itemMin.x + halfFrame.x, itemMin.y + halfFrame.y + frameSpacingY), + ImVec2(itemMax.x - halfFrame.x, itemMax.y + frameBottomPadding), ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Border)), halfFrame.x); @@ -178,6 +183,22 @@ namespace dusk { ImGuiConsole::ImGuiConsole() {} + void ImGuiConsole::InitSettings() { + bool lockAspect = getSettings().video.lockAspectRatio; + if (lockAspect) { + VILockAspectRatio(defaultAspectRatioW, defaultAspectRatioH); + } else { + VIUnlockAspectRatio(); + } + + dusk::audio::SetMasterVolume(getSettings().audio.masterVolume / 100.0f); + dusk::audio::SetEnableReverb(getSettings().audio.enableReverb); + } + + void ImGuiConsole::UpdateSettings() { + getTransientSettings().skipFrameRateLimit = getSettings().game.enableTurboKeybind && ImGui::IsKeyDown(ImGuiKey_Tab); + } + void ImGuiConsole::PreDraw() { if (config::IsConfigFileMissing()) { m_firstRunPreset.draw(); @@ -185,11 +206,13 @@ namespace dusk { } if (!m_isLaunchInitialized) { + InitSettings(); + m_toasts.emplace_back("Press F1 to toggle menu"s, 5.f); m_isLaunchInitialized = true; } - getTransientSettings().skipFrameRateLimit = getSettings().game.enableTurboKeybind && ImGui::IsKeyDown(ImGuiKey_Tab); + UpdateSettings(); if ((ImGui::IsKeyDown(ImGuiKey_LeftCtrl) || ImGui::IsKeyDown(ImGuiKey_RightCtrl)) && ImGui::IsKeyPressed(ImGuiKey_R)) @@ -203,9 +226,14 @@ namespace dusk { if (CheckMenuViewToggle(ImGuiKey_F1, m_isHidden)) { ShowToasts(); + ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange; + SDL_HideCursor(); return; } + ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NoMouseCursorChange; + // Imgui will re-show cursor. + // TODO: we need to be able to render the menu bar & any overlays separately // The code currently ties them all together, so hiding the menu hides all windows diff --git a/src/dusk/imgui/ImGuiConsole.hpp b/src/dusk/imgui/ImGuiConsole.hpp index 75da71f6a3..cefc2c57c9 100644 --- a/src/dusk/imgui/ImGuiConsole.hpp +++ b/src/dusk/imgui/ImGuiConsole.hpp @@ -15,6 +15,8 @@ namespace dusk { class ImGuiConsole { public: ImGuiConsole(); + void InitSettings(); + void UpdateSettings(); void PreDraw(); void PostDraw(); diff --git a/src/dusk/imgui/ImGuiMenuEnhancements.cpp b/src/dusk/imgui/ImGuiMenuEnhancements.cpp index a7a1e1d698..c623a910e0 100644 --- a/src/dusk/imgui/ImGuiMenuEnhancements.cpp +++ b/src/dusk/imgui/ImGuiMenuEnhancements.cpp @@ -52,6 +52,11 @@ namespace dusk { if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Hides the TV calibration screen shown when loading a save"); } + + config::ImGuiCheckbox("Instant Saves", getSettings().game.instantSaves); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Skip the delay when writing to the Memory Card"); + } ImGui::EndMenu(); } @@ -101,6 +106,16 @@ namespace dusk { ImGui::SetTooltip("Allows you to transform even if NPCs are looking"); } + config::ImGuiCheckbox("Fast Spinner", getSettings().game.fastSpinner); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Speeds up Spinner movement when holding R."); + } + + config::ImGuiCheckbox("Free Magic Armor", getSettings().game.freeMagicArmor); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Makes the magic armor work without rupees."); + } + ImGui::EndMenu(); } diff --git a/src/dusk/imgui/ImGuiMenuGame.cpp b/src/dusk/imgui/ImGuiMenuGame.cpp index b2ed26b20a..8125583c8b 100644 --- a/src/dusk/imgui/ImGuiMenuGame.cpp +++ b/src/dusk/imgui/ImGuiMenuGame.cpp @@ -7,11 +7,15 @@ #include #include "JSystem/JUtility/JUTGamePad.h" -#include "dusk/audio/DuskDsp.hpp" #include "dusk/audio/DuskAudioSystem.h" +#include "dusk/audio/DuskDsp.hpp" +#include "dusk/dusk.h" #include "dusk/hotkeys.h" #include "dusk/settings.h" #include "m_Do/m_Do_controller_pad.h" +#include "m_Do/m_Do_graphic.h" + +#include namespace dusk { void ImGuiMenuGame::ToggleFullscreen() { @@ -35,13 +39,45 @@ namespace dusk { ToggleFullscreen(); } + if (ImGui::MenuItem("Default Window Size")) { + getSettings().video.enableFullscreen.setValue(false); + VISetWindowFullscreen(false); + VISetWindowSize(FB_WIDTH * 2, FB_HEIGHT * 2); + VICenterWindow(); + } + + bool vsync = getSettings().video.enableVsync; + if (ImGui::Checkbox("Enable Vsync", &vsync)) { + getSettings().video.enableVsync.setValue(vsync); + aurora_enable_vsync(vsync); + config::Save(); + } + + bool lockAspect = getSettings().video.lockAspectRatio; + if (ImGui::Checkbox("Force 4:3 Aspect Ratio", &lockAspect)) { + getSettings().video.lockAspectRatio.setValue(lockAspect); + + if (lockAspect) { + VILockAspectRatio(defaultAspectRatioW, defaultAspectRatioH); + } else { + VIUnlockAspectRatio(); + } + + config::Save(); + } + ImGui::EndMenu(); } if (ImGui::BeginMenu("Audio")) { ImGui::Text("Master Volume"); - config::ImGuiSliderInt("##masterVolume", getSettings().audio.masterVolume, 0, 100); - config::ImGuiCheckbox("Enable Reverb", getSettings().audio.enableReverb); + if (config::ImGuiSliderInt("##masterVolume", getSettings().audio.masterVolume, 0, 100)) { + dusk::audio::SetMasterVolume(getSettings().audio.masterVolume / 100.0f); + } + + if (config::ImGuiCheckbox("Enable Reverb", getSettings().audio.enableReverb)) { + dusk::audio::SetEnableReverb(getSettings().audio.enableReverb); + } /* // TODO: Implement additional settings ImGui::Text("Main Music Volume"); @@ -61,9 +97,6 @@ namespace dusk { } */ - audio::SetMasterVolume(getSettings().audio.masterVolume / 100.0f); - audio::EnableReverb = getSettings().audio.enableReverb; - ImGui::EndMenu(); } @@ -83,9 +116,9 @@ namespace dusk { static void drawVirtualStick(const char* id, const ImVec2& stick) { float scale = ImGuiScale(); - ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPos().x + 5 * scale, ImGui::GetCursorPos().y)); + ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPos().x + 45 * scale, ImGui::GetCursorPos().y + 10)); - ImGui::BeginChild(id, ImVec2(80 * scale, 80 * scale)); + ImGui::BeginChild(id, ImVec2(80 * scale, 80 * scale), 0, ImGuiWindowFlags_NoBackground); ImDrawList* dl = ImGui::GetWindowDrawList(); ImVec2 p = ImGui::GetCursorScreenPos(); @@ -189,6 +222,7 @@ namespace dusk { // controller selection combo box bool changedController = false; int changedControllerIndex = 0; + ImGui::SetNextItemWidth(400.0f * scale); if (ImGui::BeginCombo("##ControllerDeviceList", currentName.c_str())) { for (int i = 0; const auto& name : controllerList) { if (ImGui::Selectable(name.c_str(), currentName == name)) { @@ -267,7 +301,7 @@ namespace dusk { uint32_t axisCount; PADAxisMapping* axisMappingList = PADGetAxisMappings(m_controllerConfig.m_selectedPort, &axisCount); - ImGuiBeginGroupPanel("Triggers", ImVec2(150 * scale, 20 * scale)); + ImGuiBeginGroupPanel("Analog Triggers", ImVec2(150 * scale, 20 * scale)); PADAxis triggers[] = {PAD_AXIS_TRIGGER_L, PAD_AXIS_TRIGGER_R}; if (axisMappingList != nullptr) { @@ -301,11 +335,34 @@ namespace dusk { } } + int port = m_controllerConfig.m_selectedPort; + PADDeadZones* deadZones = PADGetDeadZones(port); + + if (deadZones != nullptr) { + ImGui::Text("L Threshold"); + ImGui::SameLine(); + { + float tmp = static_cast(deadZones->leftTriggerActivationZone * 100.f) / 32767.f; + if (ImGui::DragFloat("##LThreshold", &tmp, 0.5f, 0.f, 100.f, "%.3f%%")) { + deadZones->leftTriggerActivationZone = static_cast((tmp / 100.f) * 32767); + } + } + } + + if (deadZones != nullptr) { + ImGui::Text("R Threshold"); + ImGui::SameLine(); + { + float tmp = static_cast(deadZones->rightTriggerActivationZone * 100.f) / 32767.f; + if (ImGui::DragFloat("##RThreshold", &tmp, 0.5f, 0.f, 100.f, "%.3f%%")) { + deadZones->rightTriggerActivationZone = static_cast((tmp / 100.f) * 32767); + } + } + } + ImGuiEndGroupPanel(); ImGui::SameLine(); - int port = m_controllerConfig.m_selectedPort; - // main stick panel ImGuiBeginGroupPanel("Control Stick", ImVec2(150 * scale, 20 * scale)); @@ -355,8 +412,6 @@ namespace dusk { } } - PADDeadZones* deadZones = PADGetDeadZones(port); - if (deadZones != nullptr) { ImGui::Text("Dead Zone"); { @@ -432,32 +487,6 @@ namespace dusk { ImGuiEndGroupPanel(); ImGui::SameLine(); - // Triggers Panel - ImGuiBeginGroupPanel("Triggers", ImVec2(150 * scale, 20 * scale)); - - if (deadZones != nullptr) { - ImGui::Text("L Threshold"); - { - float tmp = static_cast(deadZones->leftTriggerActivationZone * 100.f) / 32767.f; - if (ImGui::DragFloat("##LThreshold", &tmp, 0.5f, 0.f, 100.f, "%.3f%%")) { - deadZones->leftTriggerActivationZone = static_cast((tmp / 100.f) * 32767); - } - } - } - - if (deadZones != nullptr) { - ImGui::Text("R Threshold"); - { - float tmp = static_cast(deadZones->rightTriggerActivationZone * 100.f) / 32767.f; - if (ImGui::DragFloat("##RThreshold", &tmp, 0.5f, 0.f, 100.f, "%.3f%%")) { - deadZones->rightTriggerActivationZone = static_cast((tmp / 100.f) * 32767); - } - } - } - - ImGuiEndGroupPanel(); - ImGui::SameLine(); - // Options panel ImGuiBeginGroupPanel("Options", ImVec2(150 * scale, 20 * scale)); diff --git a/src/dusk/imgui/ImGuiMenuTools.cpp b/src/dusk/imgui/ImGuiMenuTools.cpp index 7478adc0e5..44e92a4082 100644 --- a/src/dusk/imgui/ImGuiMenuTools.cpp +++ b/src/dusk/imgui/ImGuiMenuTools.cpp @@ -10,6 +10,7 @@ #include "d/actor/d_a_alink.h" #include "d/actor/d_a_horse.h" #include "d/d_com_inf_game.h" +#include "dusk/dusk.h" #include "m_Do/m_Do_main.h" namespace dusk { @@ -96,6 +97,7 @@ namespace dusk { hasPrevious = true; ImGuiStringViewText(fmt::format(FMT_STRING("FPS: {:.2f}\n"), io.Framerate)); + ImGuiStringViewText(fmt::format(FMT_STRING("Frame usage: {:.1f}%\n"), frameUsagePct)); if (hasPrevious) { ImGui::Separator(); @@ -109,31 +111,31 @@ namespace dusk { } hasPrevious = true; - AuroraStats const* stats = aurora_get_stats(); + const auto& stats = lastFrameAuroraStats; ImGuiStringViewText( - fmt::format(FMT_STRING("Queued pipelines: {}\n"), stats->queuedPipelines)); + fmt::format(FMT_STRING("Queued pipelines: {}\n"), stats.queuedPipelines)); ImGuiStringViewText( - fmt::format(FMT_STRING("Done pipelines: {}\n"), stats->createdPipelines)); + fmt::format(FMT_STRING("Done pipelines: {}\n"), stats.createdPipelines)); ImGuiStringViewText( - fmt::format(FMT_STRING("Draw call count: {}\n"), stats->drawCallCount)); + fmt::format(FMT_STRING("Draw call count: {}\n"), stats.drawCallCount)); ImGuiStringViewText(fmt::format(FMT_STRING("Merged draw calls: {}\n"), - stats->mergedDrawCallCount)); + stats.mergedDrawCallCount)); ImGuiStringViewText(fmt::format(FMT_STRING("Vertex size: {}\n"), - BytesToString(stats->lastVertSize))); + BytesToString(stats.lastVertSize))); ImGuiStringViewText(fmt::format(FMT_STRING("Uniform size: {}\n"), - BytesToString(stats->lastUniformSize))); + BytesToString(stats.lastUniformSize))); ImGuiStringViewText(fmt::format(FMT_STRING("Index size: {}\n"), - BytesToString(stats->lastIndexSize))); + BytesToString(stats.lastIndexSize))); ImGuiStringViewText(fmt::format(FMT_STRING("Storage size: {}\n"), - BytesToString(stats->lastStorageSize))); + BytesToString(stats.lastStorageSize))); ImGuiStringViewText(fmt::format(FMT_STRING("Tex upload size: {}\n"), - BytesToString(stats->lastTextureUploadSize))); + BytesToString(stats.lastTextureUploadSize))); ImGuiStringViewText(fmt::format( FMT_STRING("Total: {}\n"), - BytesToString(stats->lastVertSize + stats->lastUniformSize + - stats->lastIndexSize + stats->lastStorageSize + - stats->lastTextureUploadSize))); + BytesToString(stats.lastVertSize + stats.lastUniformSize + + stats.lastIndexSize + stats.lastStorageSize + + stats.lastTextureUploadSize))); // TODO: persist to config ShowCornerContextMenu(m_debugOverlayCorner, m_cameraOverlayCorner); diff --git a/src/dusk/settings.cpp b/src/dusk/settings.cpp index 6a9887c27f..dec70f9882 100644 --- a/src/dusk/settings.cpp +++ b/src/dusk/settings.cpp @@ -6,6 +6,8 @@ namespace dusk { UserSettings g_userSettings = { .video = { .enableFullscreen {"video.enableFullscreen", false}, + .enableVsync {"video.enableVsync", true}, + .lockAspectRatio {"video.lockAspectRatio", false}, }, .audio = { @@ -30,6 +32,7 @@ UserSettings g_userSettings = { .fastClimbing {"game.fastClimbing", false}, .noMissClimbing {"game.noMissClimbing", false}, .fastTears {"game.fastTears", false}, + .instantSaves {"game.instantSaves", false}, // Preferences .enableMirrorMode {"game.enableMirrorMode", false}, @@ -46,6 +49,8 @@ UserSettings g_userSettings = { // Cheats .enableFastIronBoots {"game.enableFastIronBoots", false}, .canTransformAnywhere {"game.canTransformAnywhere", false}, + .fastSpinner {"game.fastSpinner", false}, + .freeMagicArmor {"game.freeMagicArmor", false}, // Technical .restoreWiiGlitches {"game.restoreWiiGlitches", false}, @@ -62,6 +67,8 @@ UserSettings& getSettings() { void registerSettings() { // Video Register(g_userSettings.video.enableFullscreen); + Register(g_userSettings.video.enableVsync); + Register(g_userSettings.video.lockAspectRatio); // Audio Register(g_userSettings.audio.masterVolume); @@ -82,17 +89,20 @@ void registerSettings() { Register(g_userSettings.game.instantDeath); Register(g_userSettings.game.fastClimbing); Register(g_userSettings.game.fastTears); + Register(g_userSettings.game.instantSaves); Register(g_userSettings.game.enableMirrorMode); Register(g_userSettings.game.invertCameraXAxis); Register(g_userSettings.game.enableBloom); Register(g_userSettings.game.useWaterProjectionOffset); Register(g_userSettings.game.enableFastIronBoots); Register(g_userSettings.game.canTransformAnywhere); + Register(g_userSettings.game.freeMagicArmor); Register(g_userSettings.game.restoreWiiGlitches); Register(g_userSettings.game.noMissClimbing); Register(g_userSettings.game.noLowHpSound); Register(g_userSettings.game.midnasLamentNonStop); Register(g_userSettings.game.enableTurboKeybind); + Register(g_userSettings.game.fastSpinner); } // Transient settings diff --git a/src/dusk/stubs.cpp b/src/dusk/stubs.cpp index 2cb385966e..e655ed6d7d 100644 --- a/src/dusk/stubs.cpp +++ b/src/dusk/stubs.cpp @@ -94,7 +94,7 @@ static void ClearMsgQueueMap() { map.clear(); } -void OSInitMessageQueue(OSMessageQueue* mq, void* msgArray, s32 msgCount) { +void OSInitMessageQueue(OSMessageQueue* mq, OSMessage* msgArray, s32 msgCount) { if (!mq) return; mq->queueSend.head = mq->queueSend.tail = nullptr; mq->queueReceive.head = mq->queueReceive.tail = nullptr; @@ -128,7 +128,7 @@ int OSSendMessage(OSMessageQueue* mq, void* msg, s32 flags) { return 1; } -int OSReceiveMessage(OSMessageQueue* mq, void* msg, s32 flags) { +BOOL OSReceiveMessage(OSMessageQueue* mq, OSMessage* msg, s32 flags) { if (!mq) return 0; PCMessageQueueData& data = GetMsgQueueData(mq); diff --git a/src/f_ap/f_ap_game.cpp b/src/f_ap/f_ap_game.cpp index 1cbbb7449f..b1edb7fa23 100644 --- a/src/f_ap/f_ap_game.cpp +++ b/src/f_ap/f_ap_game.cpp @@ -738,6 +738,16 @@ void fapGm_Execute() { dynamic_cast(link)->handleQuickTransform(); } } + + if (dusk::getSettings().game.fastSpinner && mDoCPd_c::getHoldR(PAD_1)) { + if (const auto link = g_dComIfG_gameInfo.play.getPlayer(0)) { + auto spinnerActor = (fopAc_ac_c*)dynamic_cast(link)->getSpinnerActor(); + if (spinnerActor) { + if (spinnerActor->speedF < 60.f) + spinnerActor->speedF += 2.f; + } + } + } #endif fpcM_Management(NULL, fapGm_After); diff --git a/src/f_op/f_op_actor_mng.cpp b/src/f_op/f_op_actor_mng.cpp index 36217076bf..dca07f98ba 100644 --- a/src/f_op/f_op_actor_mng.cpp +++ b/src/f_op/f_op_actor_mng.cpp @@ -730,6 +730,9 @@ u8 var_r30 = fopAcM::HeapAdjustEntry; #endif u32 size = i_size & 0xFFFFFF; +#if TARGET_PC + size *= 2; +#endif bool result = fopAcM_entrySolidHeap_(i_actor, i_heapCallback, size); #if DEBUG fopAcM::HeapDummyCheck = var_r29; diff --git a/src/m_Do/m_Do_ext.cpp b/src/m_Do/m_Do_ext.cpp index d744d048ba..0593815b1d 100644 --- a/src/m_Do/m_Do_ext.cpp +++ b/src/m_Do/m_Do_ext.cpp @@ -2873,7 +2873,10 @@ void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16 sp_38++; } } + +#if !TARGET_PC #include "assets/l_mat2DL__d_a_grass.h" +#endif void mDoExt_3DlineMat2_c::setMaterial() { j3dSys.reinitGX(); diff --git a/src/m_Do/m_Do_graphic.cpp b/src/m_Do/m_Do_graphic.cpp index a7a09a8d87..5887c22495 100644 --- a/src/m_Do/m_Do_graphic.cpp +++ b/src/m_Do/m_Do_graphic.cpp @@ -552,8 +552,16 @@ const tvSize l_tvSize[2] = { {808, 448}, }; +#if TARGET_PC +tvSize pc_tvSize = {608, 448}; +#endif + void mDoGph_gInf_c::setTvSize() { +#if TARGET_PC + const tvSize* tvsize = &pc_tvSize; +#else const tvSize* tvsize = &l_tvSize[mWide]; +#endif m_width = tvsize->width; m_height = tvsize->height; @@ -572,13 +580,28 @@ void mDoGph_gInf_c::setTvSize() { m_aspect = m_widthF / m_heightF; m_scale = m_aspect / 1.3571428f; m_invScale = 1.0f / m_scale; + +#if TARGET_PC + hudAspectScaleDown = 1.3571428f / mDoGph_gInf_c::getAspect(); + hudAspectScaleUp = 1.0f / hudAspectScaleDown; +#endif } +#if TARGET_PC +void mDoGph_gInf_c::onWide(f32 width, f32 height) { + mWide = TRUE; + pc_tvSize.width = width; + pc_tvSize.height = height; + setTvSize(); + dMeter2Info_onWide2D(); +} +#else void mDoGph_gInf_c::onWide() { mWide = TRUE; setTvSize(); dMeter2Info_onWide2D(); } +#endif void mDoGph_gInf_c::offWide() { mWide = FALSE; @@ -686,10 +709,16 @@ void mDoGph_gInf_c::setWideZoomLightProjection(Mtx& m) { #endif #if TARGET_PC +f32 mDoGph_gInf_c::hudAspectScaleDown = 1.0f; +f32 mDoGph_gInf_c::hudAspectScaleUp = 1.0f; + void mDoGph_gInf_c::setWindowSize(AuroraWindowSize const& size) { JUTVideo::getManager()->setWindowSize(size); dComIfGp_setWindow(0, 0.0f, 0.0f, getWidth(), getHeight(), 0.0f, 1.0f, 0, 2); mFader->mBox.set(0, 0, getWidth(), getHeight()); + + f32 newWidth = (getWidth() / getHeight()) * 448.0f; + onWide(newWidth, 448.0f); } #endif @@ -911,8 +940,15 @@ static void drawDepth2(view_class* param_0, view_port_class* param_1, int param_ GX_FALSE, 0); } + #if TARGET_PC + // use full size for pc for higher quality background elements + u16 halfWidth = width; + u16 halfHeight = height; + #else u16 halfWidth = width >> 1; u16 halfHeight = height >> 1; + #endif + GXRenderModeObj* sp24 = JUTGetVideoManager()->getRenderMode(); GXSetCopyFilter(GX_FALSE, NULL, GX_TRUE, sp24->vfilter); GXSetTexCopySrc(x_orig, y_orig_pos, width, height); @@ -1285,7 +1321,13 @@ void mDoGph_gInf_c::bloom_c::draw() { GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c); for (int texCoord = (int)GX_TEXCOORD1; texCoord < (int)GX_MAX_TEXCOORD; texCoord++) { GXSetTexCoordGen((GXTexCoordID)texCoord, GX_TG_MTX2x4, GX_TG_TEX0, iVar11); + + #if TARGET_PC + f32 dVar15 = mBlureSize * ((448.0f / getHeight()) / 6400.0f); + #else f32 dVar15 = mBlureSize * (1.0f / 6400.0f); + #endif + mDoMtx_stack_c::transS((dVar15 * cM_scos(sVar10)) * getInvScale(), dVar15 * cM_ssin(sVar10), 0.0f); GXLoadTexMtxImm(mDoMtx_stack_c::get(), iVar11, GX_MTX2x4); @@ -2014,7 +2056,13 @@ int mDoGph_Painter() { Mtx m2; Mtx44 m; + + #if TARGET_PC + C_MTXPerspective(m, AREG_F(8) + 60.0f, 1.3571428f, 1.0f, 100000.0f); + #else C_MTXPerspective(m, AREG_F(8) + 60.0f, mDoGph_gInf_c::getAspect(), 1.0f, 100000.0f); + #endif + GXSetProjection(m, GX_PERSPECTIVE); cXyz sp38c(0.0f, 0.0f, AREG_F(7) + -2.0f); cXyz sp398(0.0f, 1.0f, 0.0f); diff --git a/src/m_Do/m_Do_machine.cpp b/src/m_Do/m_Do_machine.cpp index d5258b6f98..6b186a77e6 100644 --- a/src/m_Do/m_Do_machine.cpp +++ b/src/m_Do/m_Do_machine.cpp @@ -592,6 +592,7 @@ void myExceptionCallback(u16, OSContext*, u32, u32) { VIFlush(); } +#ifndef TARGET_PC static void fault_callback_scroll(u16, OSContext* p_context, u32, u32) { JUTException* manager = JUTException::getManager(); JUTConsole* exConsole = manager->getConsole(); @@ -714,6 +715,7 @@ static void fault_callback_scroll(u16, OSContext* p_context, u32, u32) { } while (true); } while (true); } +#endif static void dummy_string() { DEAD_STRING("\x1B[32m%-24s = size=%d KB\n\x1B[m"); @@ -1008,3 +1010,9 @@ int mDoMch_Create() { return 1; } + +#if TARGET_PC +void mDoMch_Destroy() { + JFWSystem::shutdown(); +} +#endif diff --git a/src/m_Do/m_Do_main.cpp b/src/m_Do/m_Do_main.cpp index 632d696ae9..bcf958780e 100644 --- a/src/m_Do/m_Do_main.cpp +++ b/src/m_Do/m_Do_main.cpp @@ -110,6 +110,8 @@ s32 LOAD_COPYDATE(void*) { } AuroraInfo auroraInfo; +AuroraStats dusk::lastFrameAuroraStats; +float dusk::frameUsagePct = 0.0f; const char* configPath; void main01(void) { @@ -182,6 +184,7 @@ void main01(void) { VIWaitForRetrace(); #if TARGET_PC + dusk::lastFrameAuroraStats = *aurora_get_stats(); if (!aurora_begin_frame()) { DuskLog.debug("aurora_begin_frame returned false, skipping draw this frame"); continue; @@ -319,10 +322,12 @@ int game_main(int argc, char* argv[]) { AuroraConfig config{}; config.appName = dusk::AppName; config.configPath = configPath; + config.vsync = dusk::getSettings().video.enableVsync; + config.startFullscreen = dusk::getSettings().video.enableFullscreen; config.windowPosX = -1; config.windowPosY = -1; - config.windowWidth = 608 * 2; - config.windowHeight = 448 * 2; + config.windowWidth = defaultWindowWidth * 2; + config.windowHeight = defaultWindowHeight * 2; config.desiredBackend = ParseAuroraBackend(parsed_arg_options["backend"].as()); config.logCallback = &aurora_log_callback; config.logLevel = (AuroraLogLevel)parsed_arg_options["log-level"].as(); @@ -364,6 +369,8 @@ int game_main(int argc, char* argv[]) { fflush(stdout); fflush(stderr); + mDoMch_Destroy(); + // Notifies all CVs and causes threads to exit OSResetSystem(OS_RESET_SHUTDOWN, 0, 0);