diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index ab91aca242..467849f761 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -68,13 +68,18 @@ body: required: true - type: dropdown - id: game-region + id: game-disc attributes: - label: Game Region - description: The game region you are playing on + label: Game Disc + description: The game disc you are playing on options: - - NTSC-U (North America) - - PAL (Europe) + - GameCube NTSC-U (North America) + - GameCube PAL (Europe) + - GameCube NTSC-J (Japan) + - Wii NTSC-U (North America) Revision 0 + - Wii NTSC-U (North America) Revision 2 + - Wii PAL (Europe) + - Wii NTSC-J (Japan) validations: required: true diff --git a/README.md b/README.md index b5a9ecae72..473efd8b68 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,10 @@ It aims to be as accurate as possible to the original while also providing new o You must dump your own copy of the game. Please see [this article](https://wiki.dolphin-emu.org/index.php?title=Ripping_Games) for instructions. After dumping, you can use a program like [Dolphin](https://dolphin-emu.org/) or [nodtool](https://github.com/encounter/nod/releases) to convert the `.iso` to `.rvz` to save space. -Currently, only the GameCube releases are supported. Support for other versions of the game is planned in the future. +Dusklight currently supports all commercial discs except for Wii's Korean release. + +> [!NOTE] +> Dusklight is based on the [Twilight Princess decompilation](https://github.com/zeldaret/tp), which is currently only matching for GameCube. As a result, even when playing Dusklight with a Wii disc, you will be presented with the GameCube version's HUD and certain other specificities. ### 2. Install Dusklight diff --git a/docs/ios-install-altstore.md b/docs/ios-install-altstore.md index 5c0f071878..0c2e9e36a6 100644 --- a/docs/ios-install-altstore.md +++ b/docs/ios-install-altstore.md @@ -5,7 +5,13 @@ - A Windows, Linux, or macOS device - iOS device connected to computer via USB - Dusklight IPA file (download the latest `Dusklight-vX.X.X-ios-arm64.ipa` from the [releases page](https://github.com/TwilitRealm/dusklight/releases)) -- Legally acquired game disc - `GZ2E01` (Gamecube USA) or `GZ2PE01` (Gamecube PAL) +- Legally acquired game disc: + - `GZ2E01` (GameCube USA) + - `GZ2P01` (GameCube PAL) + - `GZ2J01` (GameCube JPN) + - `RZDE01` (Wii USA Rev. 0 *or* Rev. 2) + - `RZDP01` (Wii PAL) + - `RZDJ01` (Wii JPN) ## 1. Install iloader diff --git a/extern/aurora b/extern/aurora index 1f84646de4..cf3ffc9886 160000 --- a/extern/aurora +++ b/extern/aurora @@ -1 +1 @@ -Subproject commit 1f84646de4c35483e580b07ab5c537c681a55e5e +Subproject commit cf3ffc98865ab209b02cb3eefe778a3f057c6db4 diff --git a/files.cmake b/files.cmake index 675ba70fdc..60c862053e 100644 --- a/files.cmake +++ b/files.cmake @@ -1457,6 +1457,8 @@ set(DUSK_FILES src/dusk/imgui/ImGuiStubLog.cpp src/dusk/io.cpp src/dusk/iso_validate.cpp + src/dusk/language.cpp + src/dusk/language.hpp src/dusk/layout.cpp src/dusk/livesplit.cpp src/dusk/logging.cpp diff --git a/libs/JSystem/src/JUtility/JUTResFont.cpp b/libs/JSystem/src/JUtility/JUTResFont.cpp index 4ec23dff44..3f31961d1f 100644 --- a/libs/JSystem/src/JUtility/JUTResFont.cpp +++ b/libs/JSystem/src/JUtility/JUTResFont.cpp @@ -71,7 +71,7 @@ void JUTResFont::initJoinedTexture() { int pageCount = 0; u32 pageNumCells = block.numRows * block.numColumns; - if (dusk::version::getGameVersion() == dusk::version::GameVersion::GcnJpn) { + if (dusk::version::isRegionJpn()) { pageCount = 1; if (pageNumCells > 0 && block.endCode > block.startCode) { pageCount = (block.endCode - block.startCode + pageNumCells - 1) / pageNumCells; diff --git a/libs/JSystem/src/JUtility/JUTVideo.cpp b/libs/JSystem/src/JUtility/JUTVideo.cpp index b9a51ab6f3..663c357e17 100644 --- a/libs/JSystem/src/JUtility/JUTVideo.cpp +++ b/libs/JSystem/src/JUtility/JUTVideo.cpp @@ -70,6 +70,11 @@ void JUTVideo::preRetraceProc(u32 retrace_count) { OSTick tick = DUSK_IF_ELSE(static_cast(OSGetNativeTime()), OSGetTick()); sVideoInterval = tick - sVideoLastTick; +#if TARGET_PC + if (sVideoInterval <= 0) { + sVideoInterval = 1; + } +#endif sVideoLastTick = tick; JUTXfb* xfb = JUTXfb::getManager(); diff --git a/mods/ao_mod/src/mod.cpp b/mods/ao_mod/src/mod.cpp index fb36ddb40c..8a96ae3c95 100644 --- a/mods/ao_mod/src/mod.cpp +++ b/mods/ao_mod/src/mod.cpp @@ -53,6 +53,7 @@ ResourceBuffer g_denoiseSource = RESOURCE_BUFFER_INIT; ResourceBuffer g_compositeSource = RESOURCE_BUFFER_INIT; GfxDeviceInfo g_deviceInfo = GFX_DEVICE_INFO_INIT; +GfxRenderTargetLayout g_sceneTargetLayout = GFX_RENDER_TARGET_LAYOUT_INIT; WGPUComputePipeline g_preprocessPipeline = nullptr; WGPUComputePipeline g_mip4Pipeline = nullptr; WGPUComputePipeline g_gtaoPipeline = nullptr; @@ -226,19 +227,17 @@ bool build_composite_pipeline( .dstFactor = WGPUBlendFactor_One, }, }; - WGPUColorTargetState colorTarget = WGPU_COLOR_TARGET_STATE_INIT; - colorTarget.format = g_deviceInfo.color_format; - if (blend) { - colorTarget.blend = &blendState; - } + WGPUColorTargetState colorTargets[GFX_MAX_COLOR_ATTACHMENTS]; + const uint32_t colorTargetCount = gfx_init_color_target_states( + &g_sceneTargetLayout, colorTargets, blend ? &blendState : nullptr, WGPUColorWriteMask_All); WGPUFragmentState fragment = WGPU_FRAGMENT_STATE_INIT; fragment.module = module; fragment.entryPoint = {"fs_main", WGPU_STRLEN}; - fragment.targetCount = 1; - fragment.targets = &colorTarget; + fragment.targetCount = colorTargetCount; + fragment.targets = colorTargets; // Depth state must match the EFB pass despite never touching depth. WGPUDepthStencilState depthStencil = WGPU_DEPTH_STENCIL_STATE_INIT; - depthStencil.format = g_deviceInfo.depth_format; + depthStencil.format = g_sceneTargetLayout.depth_stencil_format; depthStencil.depthWriteEnabled = WGPUOptionalBool_False; depthStencil.depthCompare = WGPUCompareFunction_Always; @@ -248,7 +247,7 @@ bool build_composite_pipeline( pipelineDesc.vertex.entryPoint = {"vs_main", WGPU_STRLEN}; pipelineDesc.primitive.topology = WGPUPrimitiveTopology_TriangleList; pipelineDesc.depthStencil = &depthStencil; - pipelineDesc.multisample.count = g_deviceInfo.sample_count; + pipelineDesc.multisample.count = g_sceneTargetLayout.sample_count; pipelineDesc.fragment = &fragment; outPipeline = wgpuDeviceCreateRenderPipeline(g_deviceInfo.device, &pipelineDesc); wgpuShaderModuleRelease(module); @@ -504,7 +503,7 @@ void on_compute( // Render worker thread: composite the AO over the scene (or show it, in debug view). void on_draw( ModContext*, const GfxDrawContext* ctx, const void* payload, size_t payloadSize, void*) { - if (payloadSize != sizeof(CompositePayload)) { + if (payloadSize != sizeof(CompositePayload) || ctx->layout.key != g_sceneTargetLayout.key) { return; } CompositePayload data; @@ -816,6 +815,9 @@ MOD_EXPORT ModResult mod_initialize(ModError* error) { if (svc_gfx->get_device_info(mod_ctx, &g_deviceInfo) != MOD_OK) { return mods::set_error(error, MOD_ERROR, "failed to query device info"); } + if (svc_gfx->get_scene_target_layout(mod_ctx, &g_sceneTargetLayout) != MOD_OK) { + return mods::set_error(error, MOD_ERROR, "failed to query scene target layout"); + } if (!build_compute_pipeline("AO preprocess depth", g_preprocessSource, "preprocess_depth", g_preprocessPipeline, g_preprocessLayout) || !build_compute_pipeline("AO downsample mip4", g_preprocessSource, "downsample_mip4", diff --git a/mods/randomizer/generator/data/entrance_shuffle_data.yaml b/mods/randomizer/generator/data/entrance_shuffle_data.yaml index d967cc0e48..510bbbb3fc 100644 --- a/mods/randomizer/generator/data/entrance_shuffle_data.yaml +++ b/mods/randomizer/generator/data/entrance_shuffle_data.yaml @@ -7,10 +7,10 @@ Connection: Links Spawn -> Outside Links House Stage: 43 Room: 1 - Spawn: "01" + Spawn: 1 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 ############################### # WARP PORTALS # @@ -19,152 +19,152 @@ - Type: Warp Portal Forward: Connection: Ordon Spring Warp Portal -> Ordon Spring - Stage: -1 - Room: -1 - Spawn: "" + Stage: 44 + Room: 1 + Spawn: -4 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Warp Portal Forward: Connection: South Faron Woods Warp Portal -> South Faron Woods - Stage: -1 - Room: -1 - Spawn: "" + Stage: 45 + Room: 0 + Spawn: -4 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Warp Portal Forward: Connection: North Faron Woods Warp Portal -> North Faron Woods - Stage: -1 - Room: -1 - Spawn: "" + Stage: 45 + Room: 6 + Spawn: -4 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Warp Portal Forward: Connection: Sacred Grove Warp Portal -> Sacred Grove Lower - Stage: -1 - Room: -1 - Spawn: "" + Stage: 54 + Room: 1 + Spawn: -4 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Warp Portal Forward: Connection: Kakariko Gorge Warp Portal -> Kakariko Gorge - Stage: -1 - Room: -1 - Spawn: "" + Stage: 56 + Room: 3 + Spawn: -4 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Warp Portal Forward: Connection: Kakariko Village Warp Portal -> Lower Kakariko Village - Stage: -1 - Room: -1 - Spawn: "" + Stage: 46 + Room: 0 + Spawn: -4 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Warp Portal Forward: Connection: Death Mountain Warp Portal -> Death Mountain Volcano - Stage: -1 - Room: -1 - Spawn: "" + Stage: 47 + Room: 3 + Spawn: -4 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Warp Portal Forward: Connection: Bridge of Eldin Warp Portal -> Eldin Field North of Bridge - Stage: -1 - Room: -1 - Spawn: "" + Stage: 56 + Room: 0 + Spawn: -4 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Warp Portal Forward: Connection: Castle Town Warp Portal -> Outside Castle Town West - Stage: -1 - Room: -1 - Spawn: "" + Stage: 57 + Room: 8 + Spawn: -4 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Warp Portal Forward: Connection: Lake Hylia Warp Portal -> Lake Hylia - Stage: -1 - Room: -1 - Spawn: "" + Stage: 52 + Room: 0 + Spawn: -4 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Warp Portal Forward: Connection: Upper Zoras River Warp Portal -> Upper Zoras River - Stage: -1 - Room: -1 - Spawn: "" + Stage: 61 + Room: 0 + Spawn: -4 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Warp Portal Forward: Connection: Zoras Domain Warp Portal -> Zoras Throne Room - Stage: -1 - Room: -1 - Spawn: "" + Stage: 50 + Room: 0 + Spawn: -4 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Warp Portal Forward: Connection: Snowpeak Warp Portal -> Snowpeak Summit Upper - Stage: -1 - Room: -1 - Spawn: "" + Stage: 51 + Room: 1 + Spawn: -4 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Warp Portal Forward: Connection: Gerudo Desert Warp Portal -> Gerudo Desert Cave of Ordeals Plateau - Stage: -1 - Room: -1 - Spawn: "" + Stage: 59 + Room: 0 + Spawn: -4 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Warp Portal Forward: Connection: Mirror Chamber Warp Portal -> Mirror Chamber Upper - Stage: -1 - Room: -1 - Spawn: "" + Stage: 60 + Room: 4 + Spawn: -4 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 ############################### # DUNGEONS # @@ -176,19 +176,19 @@ Alias: Faron Woods -> Forest Temple Stage: 6 Room: 22 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Forest Temple Entrance -> North Faron Woods Alias: Forest Temple -> Faron Woods Stage: 45 Room: 6 - Spawn: "01" + Spawn: 1 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 - Type: Dungeon Forward: @@ -196,19 +196,19 @@ Alias: Death Mountain Sumo Hall -> Goron Mines Stage: 3 Room: 1 - Spawn: "01" + Spawn: 1 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Goron Mines Entrance -> Death Mountain Sumo Hall Goron Mines Tunnel Alias: Goron Mines -> Death Mountain Sumo Hall Stage: 69 Room: 0 - Spawn: "01" + Spawn: 1 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 - Type: Dungeon Forward: @@ -216,19 +216,19 @@ Alias: Lake Hylia -> Lakebed Temple Stage: 0 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Lakebed Temple Entrance -> Lake Hylia Lakebed Temple Entrance Alias: Lakebed Temple -> Lake Hylia Stage: 52 Room: 0 - Spawn: "0B" + Spawn: 11 Spawn Type: "D0" Parameters: "F01F" - State: "FF" + State: -1 - Type: Dungeon Forward: @@ -236,61 +236,61 @@ Alias: Outside Arbiters Grounds -> Arbiters Grounds Stage: 24 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Arbiters Grounds Entrance -> Outside Arbiters Grounds Alias: Arbiters Grounds -> Outside Arbiters Grounds Stage: 55 Room: 3 - Spawn: "03" + Spawn: 3 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 - Type: Dungeon - Door Couple Tag: Snowpeak Ruins Entrance + Entrance Couple Tag: Snowpeak Ruins Entrance Forward: Connection: Snowpeak Ruins East Door Exterior -> Snowpeak Ruins East Door Interior Alias: Outside Snowpeak Ruins -> Snowpeak Ruins East Door Stage: 27 Room: 0 - Spawn: "02" + Spawn: 2 Spawn Type: "A0" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Snowpeak Ruins East Door Interior -> Snowpeak Ruins East Door Exterior Alias: Snowpeak Ruins East Door -> Outside Snowpeak Ruins Stage: 51 Room: 1 - Spawn: "0A" + Spawn: 10 Spawn Type: "0B" Parameters: "F01F" - State: "FF" + State: -1 - Type: Dungeon - Door Couple Tag: Snowpeak Ruins Entrance + Entrance Couple Tag: Snowpeak Ruins Entrance Forward: Connection: Snowpeak Ruins West Door Exterior -> Snowpeak Ruins West Door Interior Alias: Outside Snowpeak Ruins -> Snowpeak Ruins West Door Stage: 27 Room: 0 - Spawn: "01" + Spawn: 1 Spawn Type: "A0" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Snowpeak Ruins West Door Interior -> Snowpeak Ruins West Door Exterior Alias: Snowpeak Ruins West Door -> Outside Snowpeak Ruins Stage: 51 Room: 1 - Spawn: "09" + Spawn: 9 Spawn Type: "0B" Parameters: "F01F" - State: "FF" + State: -1 - Type: Dungeon Forward: @@ -298,19 +298,19 @@ Alias: Sacred Grove Past -> Temple of Time Stage: 9 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Temple of Time Entrance -> Sacred Grove Past Behind Window Alias: Temple of Time -> Sacred Grove Past Stage: 54 Room: 2 - Spawn: "01" + Spawn: 1 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 - Type: Dungeon Forward: @@ -318,19 +318,19 @@ Alias: Lake Hylia -> City in the Sky Stage: 12 Room: 0 - Spawn: "02" + Spawn: 2 Spawn Type: "00" Parameters: "C00F" - State: "FF" + State: -1 Return: Connection: City in the Sky Entrance -> Lake Hylia Alias: City in the Sky -> Lake Hylia Stage: 52 Room: 0 - Spawn: "4D" + Spawn: 77 Spawn Type: "40" Parameters: "C00F" - State: "FF" + State: -1 - Type: Dungeon Forward: @@ -338,19 +338,19 @@ Alias: Mirror Chamber -> Palace of Twilight Stage: 15 Room: 0 - Spawn: "0A" + Spawn: 10 Spawn Type: "00" Parameters: "F01F" - State: "E" + State: 14 Return: Connection: Palace of Twilight Entrance -> Twilight Realm Portal Alias: Palace of Twilight -> Mirror Chamber Stage: 60 Room: 4 - Spawn: "04" + Spawn: 4 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 - Type: Dungeon Forward: @@ -358,19 +358,19 @@ Alias: Castle Town -> Hyrule Castle Stage: 20 Room: 11 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Hyrule Castle Entrance -> Castle Town North Inside Barrier Alias: Hyrule Castle -> Castle Town Stage: 53 Room: 1 - Spawn: "32" + Spawn: 50 Spawn Type: "10" Parameters: "F01F" - State: "FF" + State: -1 ############################### # BOSSES # @@ -382,19 +382,19 @@ Alias: Forest Temple -> Forest Temple Boss Room Stage: 7 Room: 50 - Spawn: "01" + Spawn: 0 Spawn Type: "60" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Forest Temple Boss Room -> South Faron Woods Alias: Forest Temple Boss Room -> Faron Woods - Stage: -1 - Room: -1 - Spawn: "" + Stage: 45 + Room: 1 + Spawn: 1 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Boss Forward: @@ -402,19 +402,19 @@ Alias: Goron Mines -> Goron Mines Boss Room Stage: 4 Room: 50 - Spawn: "01" + Spawn: 0 Spawn Type: "60" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Goron Mines Boss Room -> Lower Kakariko Village Alias: Goron Mines Boss Room -> Kakariko Village - Stage: -1 - Room: -1 - Spawn: "" + Stage: 46 + Room: 0 + Spawn: 70 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Boss Forward: @@ -422,19 +422,19 @@ Alias: Lakebed Temple -> Lakebed Temple Boss Room Stage: 1 Room: 50 - Spawn: "01" + Spawn: 1 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Lakebed Temple Boss Room -> Lake Hylia Lanayru Spring Alias: Lakebed Temple Boss Room -> Lanayru Spring - Stage: -1 - Room: -1 - Spawn: "" + Stage: 52 + Room: 1 + Spawn: 22 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Boss Forward: @@ -442,19 +442,40 @@ Alias: Arbiters Grounds -> Arbiters Grounds Boss Room Stage: 25 Room: 50 - Spawn: "00" + Spawn: 0 Spawn Type: "60" Parameters: "F01F" - State: "FF" + State: -1 Return: - Connection: Arbiters Grounds Boss Room -> Mirror Chamber Lower + Connection: Mirror Chamber Lower -> Arbiters Grounds Boss Room Alias: Arbiters Grounds Boss Room -> Mirror Chamber - Stage: 60 - Room: 4 - Spawn: "00" + Stage: 25 + Room: 50 + Spawn: 3 Spawn Type: "10" Parameters: "501F" - State: "FF" + State: -1 + +# Leave disabled for now: Mirror Chamber is the return location from Arbiters Grounds Boss +# - Type: Overworld +# Forward: +# Connection: Arbiters Grounds Boss Room -> Mirror Chamber Lower +# Alias: Arbiters Grounds Boss Room -> Mirror Chamber +# Stage: 60 +# Room: 4 +# Spawn: 0 +# Spawn Type: "10" +# Parameters: "501F" +# State: -1 +# Return: +# Connection: Mirror Chamber Lower -> Arbiters Grounds Boss Room +# Alias: Arbiters Grounds Boss Room -> Mirror Chamber +# Stage: 25 +# Room: 50 +# Spawn: 3 +# Spawn Type: "10" +# Parameters: "501F" +# State: -1 - Type: Boss Forward: @@ -462,19 +483,19 @@ Alias: Snowpeak Ruins -> Snowpeak Ruins Boss Room Stage: 28 Room: 50 - Spawn: "01" + Spawn: 1 Spawn Type: "60" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Snowpeak Ruins Boss Room -> Snowpeak Summit Lower Alias: Snowpeak Ruins Boss Room -> Outside Snowpeak Ruins - Stage: -1 - Room: -1 - Spawn: "" + Stage: 51 + Room: 1 + Spawn: 11 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Boss Forward: @@ -482,19 +503,19 @@ Alias: Temple of Time -> Temple of Time Boss Room Stage: 10 Room: 50 - Spawn: "00" + Spawn: 0 Spawn Type: "60" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Temple of Time Boss Room -> Sacred Grove Past Behind Window Alias: Temple of Time Boss Room -> Sacred Grove Past - Stage: -1 - Room: -1 - Spawn: "" + Stage: 54 + Room: 2 + Spawn: 101 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Boss Forward: @@ -502,18 +523,18 @@ Alias: City in the Sky -> City in the Sky Boss Room Stage: 13 Room: 50 - Spawn: "01" + Spawn: 1 Spawn Type: "60" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: City in the Sky Boss Room -> City in the Sky Entrance - Stage: -1 - Room: -1 - Spawn: "" + Stage: 12 + Room: 0 + Spawn: 4 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 - Type: Boss Forward: @@ -521,18 +542,18 @@ Alias: Palace of Twilight -> Palace of Twilight Boss Room Stage: 16 Room: 10 - Spawn: "00" + Spawn: 0 Spawn Type: "60" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Palace of Twilight Boss Room -> Palace of Twilight Entrance - Stage: -1 - Room: -1 - Spawn: "" + Stage: 15 + Room: 0 + Spawn: 4 Spawn Type: "" Parameters: "" - State: "FF" + State: -1 ############################### # GROTTOS # @@ -543,18 +564,18 @@ Connection: Ordon Ranch -> Ordon Ranch Grotto Stage: 35 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "C0" Parameters: "F013" - State: "2" + State: 2 Return: Connection: Ordon Ranch Grotto -> Ordon Ranch Stage: 41 Room: 0 - Spawn: "05" + Spawn: 5 Spawn Type: "90" Parameters: "F01F" - State: "FF" + State: -1 - Type: Grotto Forward: @@ -562,109 +583,109 @@ Alias: Lost Woods -> Lost Woods Baba Serpent Grotto Stage: 36 Room: 1 - Spawn: "00" + Spawn: 0 Spawn Type: "C0" Parameters: "F01F" - State: "2" + State: 2 Return: Connection: Lost Woods Baba Serpent Grotto -> Lost Woods Lower Battle Arena Alias: Lost Woods Baba Serpent Grotto -> Lost Woods Stage: 54 Room: 3 - Spawn: "05" + Spawn: 5 Spawn Type: "90" Parameters: "F01F" - State: "FF" + State: -1 - Type: Grotto Forward: Connection: Faron Field -> Faron Field Corner Grotto Stage: 36 Room: 1 - Spawn: "00" + Spawn: 0 Spawn Type: "C0" Parameters: "F01F" - State: "1" + State: 1 Return: Connection: Faron Field Corner Grotto -> Faron Field Stage: 56 Room: 6 - Spawn: "02" + Spawn: 2 Spawn Type: "90" Parameters: "F01F" - State: "FF" + State: -1 - Type: Grotto Forward: Connection: Faron Field -> Faron Field Fishing Grotto Stage: 39 Room: 4 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F010" - State: "1" + State: 1 Return: Connection: Faron Field Fishing Grotto -> Faron Field Stage: 56 Room: 6 - Spawn: "03" + Spawn: 3 Spawn Type: "90" Parameters: "F01F" - State: "FF" + State: -1 - Type: Grotto Forward: Connection: Kakariko Gorge -> Kakariko Gorge Keese Grotto Stage: 36 Room: 1 - Spawn: "00" + Spawn: 0 Spawn Type: "C0" Parameters: "F01F" - State: "3" + State: 3 Return: Connection: Kakariko Gorge Keese Grotto -> Kakariko Gorge Stage: 56 Room: 3 - Spawn: "04" + Spawn: 4 Spawn Type: "90" Parameters: "F01F" - State: "FF" + State: -1 - Type: Grotto Forward: Connection: Eldin Field -> Eldin Field Bomskit Grotto Stage: 35 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "C0" Parameters: "F013" - State: "1" + State: 1 Return: Connection: Eldin Field Bomskit Grotto -> Eldin Field Stage: 56 Room: 0 - Spawn: "0C" + Spawn: 12 Spawn Type: "90" Parameters: "F01F" - State: "FF" + State: -1 - Type: Grotto Forward: Connection: Eldin Field -> Eldin Field Water Bomb Fish Grotto Stage: 39 Room: 4 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F010" - State: "3" + State: 3 Return: Connection: Eldin Field Water Bomb Fish Grotto -> Eldin Field Stage: 56 Room: 0 - Spawn: "0D" + Spawn: 13 Spawn Type: "90" Parameters: "F01F" - State: "FF" + State: -1 - Type: Grotto Forward: @@ -672,73 +693,73 @@ Alias: Eldin Field -> Eldin Field Stalfos Grotto Stage: 36 Room: 1 - Spawn: "00" + Spawn: 0 Spawn Type: "C0" Parameters: "F01F" - State: "0" + State: 0 Return: Connection: Eldin Field Stalfos Grotto -> Eldin Field Grotto Platform Alias: Eldin Field Stalfos Grotto -> Eldin Field Stage: 56 Room: 7 - Spawn: "02" + Spawn: 2 Spawn Type: "90" Parameters: "F01F" - State: "FF" + State: -1 - Type: Grotto Forward: Connection: Lanayru Field -> Lanayru Field Chu Grotto Stage: 37 Room: 2 - Spawn: "00" + Spawn: 0 Spawn Type: "C0" Parameters: "F013" - State: "3" + State: 3 Return: Connection: Lanayru Field Chu Grotto -> Lanayru Field Stage: 56 Room: 10 - Spawn: "08" + Spawn: 8 Spawn Type: "90" Parameters: "F01F" - State: "FF" + State: -1 - Type: Grotto Forward: Connection: Lanayru Field -> Lanayru Field Skulltula Grotto Stage: 38 Room: 3 - Spawn: "00" + Spawn: 0 Spawn Type: "C0" Parameters: "F013" - State: "3" + State: 3 Return: Connection: Lanayru Field Skulltula Grotto -> Lanayru Field Stage: 56 Room: 10 - Spawn: "06" + Spawn: 6 Spawn Type: "90" Parameters: "F01F" - State: "FF" + State: -1 - Type: Grotto Forward: Connection: Lanayru Field -> Lanayru Field Poe Grotto Stage: 35 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "C0" Parameters: "F013" - State: "3" + State: 3 Return: Connection: Lanayru Field Poe Grotto -> Lanayru Field Stage: 56 Room: 10 - Spawn: 07"" + Spawn: 7 Spawn Type: "90" Parameters: "F01F" - State: "FF" + State: -1 - Type: Grotto Forward: @@ -746,19 +767,19 @@ Alias: Outside Castle Town West -> Outside Castle Town West Helmasaur Grotto Stage: 35 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "C0" Parameters: "F013" - State: "0" + State: 0 Return: Connection: Outside Castle Town West Helmasaur Grotto -> Outside Castle Town West Grotto Exit Alias: Outside Castle Town West Helmasaur Grotto -> Outside Castle Town West Stage: 57 Room: 8 - Spawn: "05" + Spawn: 5 Spawn Type: "90" Parameters: F01F"" - State: "FF" + State: -1 - Type: Grotto Forward: @@ -766,19 +787,19 @@ Alias: Outside Castle Town South -> Outside Castle Town South Tektite Grotto Stage: 39 Room: 4 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F010" - State: "0" + State: 0 Return: Connection: Outside Castle Town South Tektite Grotto -> Outside Castle Town South Tektite Grotto Platform Alias: Outside Castle Town South Tektite Grotto -> Outside Castle Town South Stage: 57 Room: 16 - Spawn: "03" + Spawn: 3 Spawn Type: "90" Parameters: "F01F" - State: "FF" + State: -1 - Type: Grotto Forward: @@ -786,19 +807,19 @@ Alias: Lake Hylia Bridge -> Lake Hylia Bridge Bubble Grotto Stage: 38 Room: 3 - Spawn: "00" + Spawn: 0 Spawn Type: "C0" Parameters: "F013" - State: "0" + State: 0 Return: Connection: Lake Hylia Bridge Bubble Grotto -> Lake Hylia Bridge Grotto Ledge Alias: Lake Hylia Bridge Bubble Grotto -> Lake Hylia Bridge Stage: 56 Room: 13 - Spawn: "03" + Spawn: 3 Spawn Type: "90" Parameters: "F01F" - State: "FF" + State: -1 - Type: Grotto Forward: @@ -806,19 +827,19 @@ Alias: Lake Hylia -> Lake Hylia Water Toadpoli Grotto Stage: 39 Room: 4 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F010" - State: "2" + State: 2 Return: Connection: Lake Hylia Water Toadpoli Grotto -> Lake Hylia Upper Area Alias: Lake Hylia Water Toadpoli Grotto -> Lake Hylia Stage: 52 Room: 0 - Spawn: "04" + Spawn: 4 Spawn Type: "90" Parameters: "F01F" - State: "FF" + State: -1 - Type: Grotto Forward: @@ -826,37 +847,37 @@ Alias: Lake Hylia -> Lake Hylia Shell Blade Grotto Stage: 39 Room: 4 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F010" - State: "4" + State: 4 Return: Connection: Lake Hylia Shell Blade Grotto -> Lake Hylia Shell Blade Grotto Ledge Alias: Lake Hylia Shell Blade Grotto -> Lake Hylia Stage: 52 Room: 0 - Spawn: "63" + Spawn: 99 Spawn Type: "90" Parameters: "F01F" - State: "FF" + State: -1 - Type: Grotto Forward: Connection: Gerudo Desert -> Gerudo Desert Skulltula Grotto Stage: 38 Room: 3 - Spawn: "00" + Spawn: 0 Spawn Type: "C0" Parameters: "F013" - State: "1" + State: 1 Return: Connection: Gerudo Desert Skulltula Grotto -> Gerudo Desert Stage: 59 Room: 0 - Spawn: "08" + Spawn: 8 Spawn Type: "90" Parameters: "F01F" - State: "0" + State: 0 - Type: Grotto Forward: @@ -864,19 +885,19 @@ Alias: Gerudo Desert -> Gerudo Desert Chu Grotto Stage: 37 Room: 2 - Spawn: "00" + Spawn: 0 Spawn Type: "C0" Parameters: "F013" - State: "1" + State: 1 Return: Connection: Gerudo Desert Chu Grotto -> Gerudo Desert Basin Alias: Gerudo Desert Chu Grotto -> Gerudo Desert Stage: 59 Room: 0 - Spawn: "0A" + Spawn: 10 Spawn Type: "90" Parameters: "F01F" - State: "0" + State: 0 - Type: Grotto Forward: @@ -884,19 +905,19 @@ Alias: Gerudo Desert -> Gerudo Desert Rock Grotto Stage: 37 Room: 2 - Spawn: "00" + Spawn: 0 Spawn Type: "C0" Parameters: "F013" - State: "0" + State: 0 Return: Connection: Gerudo Desert Rock Grotto -> Gerudo Desert North East Ledge Alias: Gerudo Desert Rock Grotto -> Gerudo Desert Stage: 59 Room: 0 - Spawn: "09" + Spawn: 9 Spawn Type: "90" Parameters: "F01F" - State: "0" + State: 0 - Type: Grotto Forward: @@ -904,19 +925,19 @@ Alias: Snowpeak Climb -> Snowpeak Ice Keese Grotto Stage: 37 Room: 2 - Spawn: "00" + Spawn: 0 Spawn Type: "C0" Parameters: "F013" - State: "2" + State: 2 Return: Connection: Snowpeak Ice Keese Grotto -> Snowpeak Climb Upper Alias: Snowpeak Ice Keese Grotto -> Snowpeak Climb Stage: 51 Room: 0 - Spawn: "02" + Spawn: 2 Spawn Type: "90" Parameters: "F01F" - State: "FF" + State: -1 - Type: Grotto Forward: @@ -924,19 +945,19 @@ Alias: Snowpeak Climb -> Snowpeak Freezard Grotto Stage: 38 Room: 3 - Spawn: "00" + Spawn: 0 Spawn Type: "C0" Parameters: "F013" - State: "2" + State: 2 Return: Connection: Snowpeak Freezard Grotto -> Snowpeak Climb Upper Alias: Snowpeak Freezard Grotto -> Snowpeak Climb Stage: 51 Room: 0 - Spawn: "01" + Spawn: 1 Spawn Type: "90" Parameters: "F01F" - State: "FF" + State: -1 ############################### # INTERIORS # @@ -948,151 +969,151 @@ Alias: Outside Links House -> Links House Stage: 65 Room: 4 - Spawn: "00" + Spawn: 0 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Ordon Links House -> Outside Links House Alias: Links House -> Outside Links House Stage: 43 Room: 1 - Spawn: "03" + Spawn: 3 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior Forward: Connection: Ordon Village -> Ordon Seras Shop Stage: 65 Room: 1 - Spawn: "00" + Spawn: 0 Spawn Type: "10" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Ordon Seras Shop -> Ordon Village Stage: 43 Room: 0 - Spawn: "05" + Spawn: 5 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior Forward: Connection: Ordon Village -> Ordon Sword House Stage: 65 Room: 5 - Spawn: "00" + Spawn: 0 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Ordon Sword House -> Ordon Village Stage: 43 Room: 0 - Spawn: "09" + Spawn: 9 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior Forward: Connection: Ordon Village -> Ordon Shield House Stage: 65 Room: 2 - Spawn: "00" + Spawn: 0 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Ordon Shield House -> Ordon Village Stage: 43 Room: 0 - Spawn: "06" + Spawn: 6 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 + +# - Type: Interior +# Forward: +# Connection: Ordon Village -> Ordon Shield House Upper Ledge +# Stage: +# Room: +# Spawn: +# Spawn Type: "" +# Parameters: "" +# State: -1 +# Return: +# Connection: Ordon Shield House Upper Ledge -> Ordon Village +# Stage: +# Room: +# Spawn: +# Spawn Type: "" +# Parameters: "" +# State: -1 + +# - Type: Interior +# Forward: +# Connection: Ordon Village -> Ordon Fados House +# Stage: +# Room: +# Spawn: +# Spawn Type: "" +# Parameters: "" +# State: -1 +# Return: +# Connection: Ordon Fados House -> Ordon Village +# Stage: +# Room: +# Spawn: +# Spawn Type: "" +# Parameters: "" +# State: -1 - Type: Interior - Forward: - Connection: Ordon Village -> Ordon Shield House Upper Ledge - Stage: - Room: - Spawn: "" - Spawn Type: "" - Parameters: "" - State: "FF" - Return: - Connection: Ordon Shield House Upper Ledge -> Ordon Village - Stage: - Room: - Spawn: "" - Spawn Type: "" - Parameters: "" - State: "FF" - -- Type: Interior - Forward: - Connection: Ordon Village -> Ordon Fados House - Stage: - Room: - Spawn: "" - Spawn Type: "" - Parameters: "" - State: "FF" - Return: - Connection: Ordon Fados House -> Ordon Village - Stage: - Room: - Spawn: "" - Spawn Type: "" - Parameters: "" - State: "FF" - -- Type: Interior - Door Couple Tag: Ordon Bos House + Entrance Couple Tag: Ordon Bos House Forward: Connection: Ordon Bos House Left Door Exterior -> Ordon Bos House Left Door Interior Alias: Ordon Village -> Ordon Bos House Left Door Stage: 65 Room: 0 - Spawn: "01" + Spawn: 1 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Ordon Bos House Left Door Interior -> Ordon Bos House Left Door Exterior Alias: Ordon Bos House Left Door -> Ordon Village Stage: 43 Room: 0 - Spawn: "0B" + Spawn: 11 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior - Door Couple Tag: Ordon Bos House + Entrance Couple Tag: Ordon Bos House Forward: Connection: Ordon Bos House Right Door Exterior -> Ordon Bos House Right Door Interior Alias: Ordon Village -> Ordon Bos House Right Door Stage: 65 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Ordon Bos House Right Door Interior -> Ordon Bos House Right Door Exterior Alias: Ordon Bos House Right Door -> Ordon Village Stage: 43 Room: 0 - Spawn: "04" + Spawn: 4 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior Forward: @@ -1100,19 +1121,19 @@ Alias: Faron Woods -> Coros House Door Stage: 67 Room: 0 - Spawn: "01" + Spawn: 1 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Faron Woods Coros House Lower -> South Faron Woods Alias: Coros House Door -> Faron Woods Stage: 45 Room: 4 - Spawn: "01" + Spawn: 1 Spawn Type: "A0" Parameters: "F01F" - State: "FF" + State: -1 - Type: Interior Forward: @@ -1120,121 +1141,121 @@ Alias: Faron Woods -> Coros House Window Stage: 67 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F05F" - State: "FF" + State: -1 Return: Connection: Faron Woods Coros House Upper -> South Faron Woods Coros Ledge Alias: Coros House Window -> Faron Woods Stage: 45 Room: 4 - Spawn: "09" + Spawn: 9 Spawn Type: "00" Parameters: "F05F" - State: "FF" + State: -1 - Type: Interior - Door Couple Tag: Renados Sanctuary Front Door + Entrance Couple Tag: Renados Sanctuary Front Door Forward: Connection: Renados Sanctuary Front East Door Exterior -> Renados Sanctuary Front East Door Interior Alias: Kakriko Village -> Renados Sanctuary Front East Door Stage: 68 Room: 0 - Spawn: "06" + Spawn: 6 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Renados Sanctuary Front East Door Interior -> Renados Sanctuary Front East Door Exterior Alias: Renados Sanctuary Front East Door -> Kakariko Village Stage: 46 Room: 0 - Spawn: "30" + Spawn: 48 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior - Door Couple Tag: Renados Sanctuary Front Door + Entrance Couple Tag: Renados Sanctuary Front Door Forward: Connection: Renados Sanctuary Front West Door Exterior -> Renados Sanctuary Front West Door Interior Alias: Kakriko Village -> Renados Sanctuary Front West Door Stage: 68 Room: 0 - Spawn: "05" + Spawn: 5 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Renados Sanctuary Front West Door Interior -> Renados Sanctuary Front West Door Exterior Alias: Renados Sanctuary Front West Door -> Kakariko Village Stage: 46 Room: 0 - Spawn: "2E" + Spawn: 46 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior - Door Couple Tag: Renados Sanctuary Back Door + Entrance Couple Tag: Renados Sanctuary Back Door Forward: Connection: Renados Sanctuary Back East Door Exterior -> Renados Sanctuary Back East Door Interior Alias: Kakriko Village -> Renados Sanctuary Back East Door Stage: 68 Room: 0 - Spawn: "08" + Spawn: 8 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Renados Sanctuary Back East Door Interior -> Renados Sanctuary Back East Door Exterior Alias: Renados Sanctuary Back East Door -> Kakariko Village Stage: 46 Room: 0 - Spawn: "33" + Spawn: 51 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior - Door Couple Tag: Renados Sanctuary Back Door + Entrance Couple Tag: Renados Sanctuary Back Door Forward: Connection: Renados Sanctuary Back West Door Exterior -> Renados Sanctuary Back West Door Interior Alias: Kakriko Village -> Renados Sanctuary Back West Door Stage: 68 Room: 0 - Spawn: "07" + Spawn: 7 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Renados Sanctuary Back West Door Interior -> Renados Sanctuary Back West Door Exterior Alias: Renados Sanctuary Back West Door -> Kakariko Village Stage: 46 Room: 0 - Spawn: "32" + Spawn: 50 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior Forward: Connection: Kakariko Renados Sanctuary -> Kakariko Renados Sanctuary Basement Stage: 75 Room: 7 - Spawn: "00" + Spawn: 0 Spawn Type: "FF" Parameters: "FFFF" - State: "FF" + State: -1 Return: Connection: Kakariko Renados Sanctuary Basement -> Kakariko Renados Sanctuary Stage: 68 Room: 0 - Spawn: "02" + Spawn: 2 Spawn Type: "FF" Parameters: "FFFF" - State: "FF" + State: -1 - Type: Interior Forward: @@ -1242,61 +1263,61 @@ Alias: Kakariko Village -> Kakariko Malo Mart Stage: 68 Room: 3 - Spawn: "00" + Spawn: 0 Spawn Type: "10" Parameters: "f09f" - State: "FF" + State: -1 Return: Connection: Kakariko Malo Mart -> Lower Kakariko Village Alias: Kakariko Malo Mart -> Kakariko Village Stage: 46 Room: 0 - Spawn: "28" + Spawn: 40 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior - Door Couple Tag: Elde Inn + Entrance Couple Tag: Elde Inn Forward: Connection: Elde Inn North Door Exterior -> Elde Inn North Door Interior Alias: Kakariko Village -> Edle Inn North Door Stage: 68 Room: 2 - Spawn: "02" + Spawn: 2 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Elde Inn North Door Interior -> Elde Inn North Door Exterior Alias: Elde Inn North Door -> Kakariko Village Stage: 46 Room: 0 - Spawn: "31" + Spawn: 49 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior - Door Couple Tag: Elde Inn + Entrance Couple Tag: Elde Inn Forward: Connection: Elde Inn South Door Exterior -> Elde Inn South Door Interior Alias: Kakariko Village -> Elde Inn South Door Stage: 68 Room: 2 - Spawn: "00" + Spawn: 0 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Elde Inn South Door Interior -> Elde Inn South Door Exterior Alias: Elde Inn South Door -> Kakariko Village Stage: 46 Room: 0 - Spawn: "2A" + Spawn: 42 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior Forward: @@ -1304,19 +1325,19 @@ Alias: Kakariko Village -> Kakariko Bug House Door Stage: 68 Room: 6 - Spawn: "05" + Spawn: 5 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Kakariko Bug House -> Kakariko Bug House Door Alias: Kakariko Bug House Door -> Kakariko Village Stage: 46 Room: 0 - Spawn: "29" + Spawn: 41 Spawn Type: "90" Parameters: "F03F" - State: "FF" + State: -1 - Type: Interior Forward: @@ -1324,19 +1345,19 @@ Alias: Kakariko Village -> Kakariko Bug House Ceiling Hole Stage: 68 Room: 6 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F03F" - State: "FF" + State: -1 Return: Connection: Kakariko Bug House -> Kakariko Bug House Ceiling Hole Alias: Kakariko Bug House Ceiling Hole -> Kakariko Village Stage: 46 Room: 0 - Spawn: "04" + Spawn: 4 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 - Type: Interior Forward: @@ -1344,19 +1365,19 @@ Alias: Kakariko Village -> Kakariko Barnes Bomb Shop Door Stage: 68 Room: 1 - Spawn: "02" + Spawn: 2 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Kakariko Barnes Bomb Shop Lower -> Lower Kakariko Village Alias: Kakariko Barnes Bomb Shop Door -> Kakariko Village Stage: 46 Room: 0 - Spawn: "2C" + Spawn: 44 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior Forward: @@ -1364,19 +1385,19 @@ Alias: Kakariko Village -> Kakariko Barnes Bomb Shop Window Stage: 68 Room: 1 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Kakariko Barnes Bomb Shop Upper -> Upper Kakariko Village Alias: Kakariko Barnes Bomb Shop Window -> Kakariko Village Stage: 46 Room: 0 - Spawn: "0A" + Spawn: 10 Spawn Type: "10" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior Forward: @@ -1384,19 +1405,19 @@ Alias: Kakariko Village -> Kakariko Watchtower Lower Door Stage: 68 Room: 4 - Spawn: "00" + Spawn: 0 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Kakariko Watchtower Lower Interior -> Kakariko Watchtower Lower Door Alias: Kakariko Watchtower Lower Door -> Kakariko Village Stage: 46 Room: 0 - Spawn: "2D" + Spawn: 45 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior Forward: @@ -1404,19 +1425,19 @@ Alias: Kakariko Village -> Kakariko Watchtower Dig Spot Stage: 68 Room: 4 - Spawn: "01" + Spawn: 1 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Kakariko Watchtower Lower Interior -> Kakariko Watchtower Dig Spot Alias: Kakariko Watchtower Dig Spot -> Kakariko Village Stage: 46 Room: 0 - Spawn: "03" + Spawn: 3 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 - Type: Interior Forward: @@ -1424,19 +1445,19 @@ Alias: Kakariko Village -> Kakariko Watchtower Upper Door Stage: 68 Room: 4 - Spawn: "02" + Spawn: 2 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Kakariko Watchtower Upper Interior -> Kakariko Top of Watchtower Alias: Kakariko Watchtower Upper Door -> Kakariko Village Stage: 46 Room: 0 - Spawn: "2F" + Spawn: 47 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 - Type: Interior Forward: @@ -1444,19 +1465,19 @@ Alias: Death Mountain -> Death Mountain Sumo Hall Stage: 69 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Death Mountain Sumo Hall -> Death Mountain Outside Sumo Hall Alias: Death Mountain Sumo Hall -> Death Mountain Stage: 47 Room: 3 - Spawn: "01" + Spawn: 1 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 - Type: Interior Forward: @@ -1464,194 +1485,194 @@ Alias: Death Mountain Elevator -> Death Mountain Sumo Hall Stage: 69 Room: 0 - Spawn: "03" + Spawn: 3 Spawn Type: "E0" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Death Mountain Sumo Hall Elevator -> Death Mountain Lower Elevator Alias: Death Mountain Sumo Hall -> Death Mountain Elevator Stage: 47 Room: 3 - Spawn: "03" + Spawn: 3 Spawn Type: "E0" Parameters: "F01F" - State: "FF" + State: -1 - Type: Interior Forward: Connection: Hidden Village -> Hidden Village Impaz House Stage: 72 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Hidden Village Impaz House -> Hidden Village Stage: 63 Room: 0 - Spawn: "01" + Spawn: 1 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior Forward: Connection: Upper Zoras River -> Upper Zoras River Izas House Stage: 49 Room: 1 - Spawn: "01" + Spawn: 1 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Upper Zoras River Izas House -> Upper Zoras River Stage: 61 Room: 0 - Spawn: "04" + Spawn: 4 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior Forward: Connection: Fishing Hole -> Fishing Hole House Stage: 71 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "A0" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Fishing Hole House -> Fishing Hole Stage: 62 Room: 0 - Spawn: "03" + Spawn: 3 Spawn Type: "B0" Parameters: "F01F" - State: "FF" + State: -1 + +# Leave Disabled for now: The Spawn point changes based on progression +# - Type: Interior +# Forward: +# Connection: Castle Town West -> Castle Town STAR Game +# Stage: 74 +# Room: 7 +# Spawn: 3 +# Spawn Type: "10" +# Parameters: "F090" +# State: -1 +# Return: +# Connection: Castle Town STAR Game -> Castle Town West +# Stage: 53 +# Room: 2 +# Spawn: 1 +# Spawn Type: "10" +# Parameters: "F01F" +# State: -1 - Type: Interior - Forward: - Connection: Castle Town West -> Castle Town STAR Game - Stage: 74 - Room: 7 - Spawn: "03" - Spawn Type: "10" - Parameters: "F090" - State: "FF" - Return: - Connection: Castle Town STAR Game -> Castle Town West - Stage: 53 - Room: 2 - Spawn: "01" - Spawn Type: "10" - Parameters: "F01F" - State: "FF" - - -- Type: Interior - Door Couple Tag: Castle Town Goron House + Entrance Couple Tag: Castle Town Goron House Forward: Connection: Castle Town Goron House West Door Exterior -> Castle Town Goron House West Door Interior Alias: Castle Town Center -> Castle Town Goron House West Door Stage: 73 Room: 4 - Spawn: "00" + Spawn: 0 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Castle Town Goron House West Door Interior -> Castle Town Goron House West Door Exterior Alias: Castle Town Goron House West Door -> Castle Town Center Stage: 53 Room: 0 - Spawn: "0E" + Spawn: 14 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 - Type: Interior - Door Couple Tag: Castle Town Goron House + Entrance Couple Tag: Castle Town Goron House Forward: Connection: Castle Town Goron House East Door Exterior -> Castle Town Goron House East Door Interior Alias: Castle Town Center -> Castle Town Goron House East Door Stage: 73 Room: 4 - Spawn: "02" + Spawn: 2 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Castle Town Goron House East Door Interior -> Castle Town Goron House East Door Exterior Alias: Castle Town Goron House East Door -> Castle Town Center Stage: 53 Room: 0 - Spawn: "10" + Spawn: 16 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 - Type: Interior Forward: Connection: Castle Town Center -> Castle Town Malo Mart Stage: 73 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Castle Town Malo Mart -> Castle Town Center Stage: 53 Room: 0 - Spawn: "0C" + Spawn: 12 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior - Door Couple Tag: Castle Town Doctors Office + Entrance Couple Tag: Castle Town Doctors Office Forward: Connection: Castle Town Doctors Office West Door Exterior -> Castle Town Doctors Office West Door Interior Alias: Castle Town East -> Castle Town Doctors Office West Door Stage: 73 Room: 2 - Spawn: "01" + Spawn: 1 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Castle Town Doctors Office West Door Interior -> Castle Town Doctors Office West Door Exterior Alias: Castle Town Doctors Office West Door -> Castle Town East Stage: 53 Room: 4 - Spawn: "04" + Spawn: 4 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior - Door Couple Tag: Castle Town Doctors Office + Entrance Couple Tag: Castle Town Doctors Office Forward: Connection: Castle Town Doctors Office East Door Exterior -> Castle Town Doctors Office East Door Interior Alias: Castle Town East -> Castle Town Doctors Office East Door Stage: 73 Room: 2 - Spawn: "00" + Spawn: 0 Spawn Type: "B0" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Castle Town Doctors Office East Door Interior -> Castle Town Doctors Office East Door Exterior Alias: Castle Town Doctors Office East Door -> Castle Town East Stage: 53 Room: 4 - Spawn: "03" + Spawn: 3 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior Forward: @@ -1659,91 +1680,91 @@ Alias: Castle Town Doctors Office Balcony -> Castle Town Doctors Office Stage: 73 Room: 2 - Spawn: "02" + Spawn: 2 Spawn Type: "10" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Castle Town Doctors Office Upper -> Castle Town Doctors Office Balcony Alias: Castle Town Doctors Office -> Castle Town Doctors Office Balcony Stage: 53 Room: 4 - Spawn: "05" + Spawn: 5 Spawn Type: "00" Parameters: "F05F" - State: "FF" + State: -1 - Type: Interior Forward: Connection: Castle Town South -> Castle Town Agithas House Stage: 73 Room: 3 - Spawn: "01" + Spawn: 1 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Castle Town Agithas House -> Castle Town South Stage: 53 Room: 3 - Spawn: "05" + Spawn: 5 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior Forward: Connection: Castle Town South -> Castle Town Seer House Stage: 73 Room: 1 - Spawn: "00" + Spawn: 0 Spawn Type: "10" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Castle Town Seer House -> Castle Town South Stage: 53 Room: 3 - Spawn: "04" + Spawn: 4 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 - Type: Interior Forward: Connection: Castle Town South -> Castle Town Jovanis House Stage: 73 Room: 5 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Castle Town Jovanis House -> Castle Town South Stage: 53 Room: 3 - Spawn: "0A" + Spawn: 10 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 - Type: Interior Forward: Connection: Castle Town South -> Castle Town Telmas Bar Stage: 70 Room: 5 - Spawn: "00" + Spawn: 0 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Castle Town Telmas Bar -> Castle Town South Stage: 53 Room: 3 - Spawn: "01" + Spawn: 1 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 ############################### # CAVES # @@ -1755,19 +1776,19 @@ Alias: South Faron Woods -> Faron Woods Cave Stage: 40 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Faron Woods Cave South -> South Faron Woods Behind Gate Alias: Faron Woods Cave -> South Faron Woods Stage: 45 Room: 3 - Spawn: "63" + Spawn: 99 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Cave Forward: @@ -1775,19 +1796,19 @@ Alias: Faron Woods Mist Area -> Faron Woods Cave Stage: 40 Room: 0 - Spawn: "01" + Spawn: 1 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Faron Woods Cave North -> Mist Area Near Faron Woods Cave Alias: Faron Woods Cave -> Faron Woods Mist Area Stage: 45 Room: 5 - Spawn: "04" + Spawn: 4 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 - Type: Cave Forward: @@ -1795,19 +1816,19 @@ Alias: Faron Woods Mist Area -> Faron Woods Mist Cave Stage: 45 Room: 14 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Mist Area Faron Mist Cave -> Mist Area Outside Faron Mist Cave Alias: Faron Woods Mist Cave -> Faron Woods Mist Area Stage: 45 Room: 5 - Spawn: "06" + Spawn: 6 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Cave Forward: @@ -1815,19 +1836,19 @@ Alias: Kakariko Gorge -> Eldin Lantern Cave Stage: 32 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Eldin Lantern Cave -> Kakariko Gorge Cave Entrance Alias: Eldin Lantern Cave -> Kakariko Gorge Stage: 56 Room: 3 - Spawn: "0F" + Spawn: 15 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 - Type: Cave Forward: @@ -1835,19 +1856,19 @@ Alias: Eldin Field -> Eldin Field Lava Cave Upper Stage: 34 Room: 10 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Eldin Field Lava Cave Upper -> Eldin Field Lava Cave Upper Ledge Alias: Eldin Field Lava Cave Upper -> Eldin Field Stage: 56 Room: 0 - Spawn: "14" + Spawn: 20 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Cave Forward: @@ -1855,19 +1876,19 @@ Alias: Eldin Field Lava Cave Lower -> Eldin Field Stage: 56 Room: 0 - Spawn: "15" + Spawn: 21 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Eldin Field Lava Cave Lower Ledge -> Eldin Field Lava Cave Lower Alias: Eldin Field -> Eldin Field Lava Cave Lower Stage: 34 Room: 10 - Spawn: "01" + Spawn: 1 Spawn Type: "00" Parameters: "F09F" - State: "FF" + State: -1 - Type: Cave Forward: @@ -1875,19 +1896,19 @@ Alias: Lanayru Field -> Lanayru Ice Puzzle Cave Stage: 30 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Lanayru Ice Puzzle Cave -> Lanayru Field Cave Entrance Alias: Lanayru Ice Puzzle Cave -> Lanayru Field Stage: 56 Room: 10 - Spawn: "0F" + Spawn: 15 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 - Type: Cave Forward: @@ -1895,19 +1916,19 @@ Alias: Lake Hylia -> Lanayru Spring Stage: 52 Room: 1 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "C000" - State: "FF" + State: -1 Return: Connection: Lake Hylia Lanayru Spring -> Lake Hylia Alias: Lanayru Spring -> Lake Hylia Stage: 52 Room: 0 - Spawn: "07" + Spawn: 7 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Cave Forward: @@ -1915,19 +1936,19 @@ Alias: Lake Hylia -> Lake Hylia Long Cave Stage: 33 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Lake Hylia Long Cave -> Lake Hylia Cave Entrance Alias: Lake Hylia Long Cave -> Lake Hylia Stage: 52 Room: 0 - Spawn: "1D" + Spawn: 29 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 - Type: Cave Forward: @@ -1935,19 +1956,19 @@ Alias: Gerudo Desert -> Cave of Ordeals Stage: 31 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Cave of Ordeals -> Gerudo Desert Cave of Ordeals Plateau Alias: Cave of Ordeals -> Gerudo Desert Stage: 59 Room: 0 - Spawn: "06" + Spawn: 6 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 ############################### # OVERWORLD # @@ -1958,36 +1979,36 @@ Connection: Outside Links House -> Ordon Village Stage: 43 Room: 0 - Spawn: "01" + Spawn: 1 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Ordon Village -> Outside Links House Stage: 43 Room: 1 - Spawn: "00" + Spawn: 0 Spawn Type: "10" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: Connection: Outside Links House -> Ordon Spring Stage: 44 Room: 1 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Ordon Spring -> Outside Links House Stage: 43 Room: 1 - Spawn: "02" + Spawn: 2 Spawn Type: "50" Parameters: "3091" - State: "FF" + State: -1 - Type: Overworld Forward: @@ -1995,37 +2016,37 @@ Alias: Ordon Village -> Ordon Ranch Stage: 41 Room: 0 - Spawn: "01" + Spawn: 1 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Ordon Ranch Village Pathway -> Ordon Village Alias: Ordon Ranch -> Ordon Village Stage: 43 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 - Type: Overworld Forward: Connection: Ordon Bridge -> South Faron Woods Stage: 45 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: South Faron Woods -> Ordon Bridge Stage: 44 Room: 1 - Spawn: "01" + Spawn: 1 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 - Type: Overworld Forward: @@ -2033,19 +2054,19 @@ Alias: South Faron Woods -> Faron Woods Mist Area Stage: 45 Room: 5 - Spawn: "62" + Spawn: 98 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Mist Area Near Owl Statue Chest -> South Faron Woods Above Owl Statue Alias: Faron Woods Mist Area -> South Faron Woods Stage: 45 Room: 8 - Spawn: "02" + Spawn: 2 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: @@ -2053,19 +2074,19 @@ Alias: Faron Woods Mist Area -> North Faron Woods Stage: 45 Room: 6 - Spawn: "02" + Spawn: 2 Spawn Type: "00" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: North Faron Woods -> Mist Area Near North Faron Woods Alias: North Faron Woods -> Faron Woods Mist Area Stage: 45 Room: 11 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 - Type: Overworld Forward: @@ -2073,19 +2094,19 @@ Alias: North Faron Woods -> Lost Woods Stage: 54 Room: 3 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Lost Woods -> North Faron Lost Woods Ledge Alias: Lost Woods -> North Faron Woods Stage: 45 Room: 6 - Spawn: "03" + Spawn: 3 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 - Type: Overworld Forward: @@ -2093,19 +2114,19 @@ Alias: Lost Woods Lower Battle Arena -> Sacred Grove Stage: 54 Room: 1 - Spawn: "03" + Spawn: 3 Spawn Type: "50" Parameters: "" - State: "FF" + State: -1 Return: Connection: Sacred Grove Lower -> Lost Woods Lower Battle Arena Alias: Sacred Grove -> Lost Woods Lower Battle Arena Stage: 54 Room: 1 - Spawn: "01" + Spawn: 1 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 - Type: Overworld Forward: @@ -2113,19 +2134,19 @@ Alias: Lost Woods Upper Battle Arena -> Sacred Grove Stage: 54 Room: 1 - Spawn: "06" + Spawn: 6 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Sacred Grove Before Block -> Lost Woods Upper Battle Arena Alias: Sacred Grove -> Lost Woods Upper Battle Arena Stage: 54 Room: 3 - Spawn: "02" + Spawn: 2 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 - Type: Overworld Forward: @@ -2133,37 +2154,37 @@ Alias: Sacred Grove -> Sacred Grove Past Stage: 54 Room: 2 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F012" - State: "FF" + State: 2 Return: Connection: Sacred Grove Past -> Sacred Grove Upper Alias: Sacred Grove Past -> Sacred Grove Stage: 54 Room: 1 - Spawn: "05" + Spawn: 5 Spawn Type: "10" Parameters: "F032" - State: "FF" + State: 2 - Type: Overworld Forward: Connection: South Faron Woods -> Faron Field Stage: 56 Room: 6 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Faron Field -> South Faron Woods Stage: 45 Room: 4 - Spawn: "08" + Spawn: 8 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: @@ -2171,19 +2192,19 @@ Alias: Faron Field -> Outside Castle Town South Stage: 57 Room: 16 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Outside Castle Town South -> Faron Field Behind Boulder Alias: Outside Castle Town South -> Faron Field Stage: 56 Room: 6 - Spawn: "01" + Spawn: 1 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 - Type: Overworld Forward: @@ -2191,19 +2212,19 @@ Alias: Kakariko Gorge -> Kakariko Village Stage: 46 Room: 0 - Spawn: "3C" + Spawn: 60 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Lower Kakariko Village -> Kakariko Gorge Behind Gate Alias: Kakariko Village -> Kakariko Gorge Stage: 56 Room: 3 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: @@ -2211,19 +2232,19 @@ Alias: Kakariko Village -> Kakariko Graveyard Stage: 48 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Kakariko Graveyard -> Lower Kakariko Village Alias: Kakariko Graveyard -> Kakariko Village Stage: 46 Room: 0 - Spawn: "06" + Spawn: 6 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: @@ -2231,39 +2252,40 @@ Alias: Kakariko Village -> Death Mountain Stage: 47 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Death Mountain Near Kakariko -> Lower Kakariko Village Alias: Death Mountain -> Kakariko Village Stage: 46 Room: 0 - Spawn: "01" + Spawn: 1 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 -- Type: Overworld - Forward: - Connection: Kakariko Graveyard Pond -> Lake Hylia - Alias: Kakariko Graveyard -> Lake Hylia - Stage: 52 - Room: 0 - Spawn: "19" - Spawn Type: "D0" - Parameters: "00FF" - State: "FF" - Return: - Connection: Lake Hylia -> Kakariko Graveyard Pond - Alias: Lake Hylia -> Kakariko Graveyard - Stage: -1 - Room: -1 - Spawn: "" - Spawn Type: "" - Parameters: "" - State: "FF" +# Disabled until we use stage service to create a spawn in graveyard +# - Type: Overworld +# Forward: +# Connection: Kakariko Graveyard Pond -> Lake Hylia +# Alias: Kakariko Graveyard -> Lake Hylia +# Stage: 52 +# Room: 0 +# Spawn: 25 +# Spawn Type: "D0" +# Parameters: "00FF" +# State: -1 + # Return: + # Connection: Lake Hylia -> Kakariko Graveyard Pond + # Alias: Lake Hylia -> Kakariko Graveyard + # Stage: -1 + # Room: -1 + # Spawn: + # Spawn Type: "" + # Parameters: "" + # State: -1 - Type: Overworld Forward: @@ -2271,19 +2293,19 @@ Alias: Kakariko Village -> Eldin Field Stage: 56 Room: 0 - Spawn: "01" + Spawn: 1 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Eldin Field -> Kakariko Village Behind Gate Alias: Eldin Field -> Kakariko Village Stage: 46 Room: 0 - Spawn: "08" + Spawn: 8 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: @@ -2291,19 +2313,19 @@ Alias: Eldin Field -> Outside Castle Town East Stage: 57 Room: 17 - Spawn: "01" + Spawn: 1 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Outside Castle Town East -> Eldin Field Near Castle Town Alias: Outside Castle Town East -> Eldin Field Stage: 56 Room: 0 - Spawn: "07" + Spawn: 7 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: @@ -2311,19 +2333,19 @@ Alias: Eldin Field -> Hidden Village Stage: 63 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Hidden Village -> Eldin Field Outside Hidden Village Alias: Hidden Village -> Eldin Field Stage: 56 Room: 7 - Spawn: "01" + Spawn: 1 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: @@ -2331,93 +2353,203 @@ Alias: Lanayru Field -> Zoras Domain Stage: 50 Room: 1 - Spawn: "0F" + Spawn: 15 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Zoras Domain West Ledge -> Lanayru Field Near Zoras Domain Alias: Zoras Domain -> Lanayru Field Stage: 56 Room: 10 - Spawn: "03" + Spawn: 3 Spawn Type: "00" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: Connection: Upper Zoras River -> Fishing Hole Stage: 62 Room: 0 - Spawn: "02" + Spawn: 2 Spawn Type: "B0" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Fishing Hole -> Upper Zoras River Stage: 61 Room: 0 - Spawn: "0A" + Spawn: 10 Spawn Type: "A0" Parameters: "F01F" - State: "FF" + State: -1 + +# Disabled until we use stage service to create a spawn in Upper Zoras River +# - Type: Overworld +# Forward: +# Connection: Upper Zoras River -> Lanayru Field +# Stage: 56 +# Room: 10 +# Spawn: 2 +# Spawn Type: D0"" +# Parameters: "00FF" +# State: -1 + # Return: + # Connection: Lanayru Field -> Upper Zoras River + # Stage: + # Room: + # Spawn: + # Spawn Type: "" + # Parameters: "" + # State: -1 - Type: Overworld + Entrance Couple Tag: Zoras Domain From Upper Zoras River Forward: - Connection: Upper Zoras River -> Lanayru Field - Stage: 56 - Room: 10 - Spawn: "02" - Spawn Type: D0"" - Parameters: "00FF" - State: "FF" - Return: - Connection: Lanayru Field -> Upper Zoras River - Stage: - Room: - Spawn: "" - Spawn Type: "" - Parameters: "" - State: "FF" - -- Type: Overworld - Forward: - Connection: Upper Zoras River -> Zoras Domain + Connection: Upper Zoras River To Zoras Domain (Swimming) -> Zoras Domain To Upper Zoras River (Swimming) + Alias: Upper Zoras River -> Zoras Domain Stage: 50 Room: 1 - Spawn: "0A" + Spawn: 11 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: - Connection: Zoras Domain -> Upper Zoras River + Connection: Zoras Domain To Upper Zoras River (Swimming) -> Upper Zoras River To Zoras Domain (Swimming) + Alias: Zoras Domain -> Upper Zoras River Stage: 61 Room: 0 - Spawn: "07" + Spawn: 6 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld + Entrance Couple Tag: Zoras Domain From Upper Zoras River Forward: - Connection: Zoras Domain Top of Waterfall -> Zoras Throne Room + Connection: Upper Zoras River To Zoras Domain (Underwater) -> Zoras Domain To Upper Zoras River (Underwater) + Alias: Upper Zoras River -> Zoras Domain + Stage: 50 + Room: 1 + Spawn: 12 + Spawn Type: "50" + Parameters: "F09F" + State: -1 + Return: + Connection: Zoras Domain To Upper Zoras River (Underwater) -> Upper Zoras River To Zoras Domain (Underwater) + Alias: Zoras Domain -> Upper Zoras River + Stage: 61 + Room: 0 + Spawn: 8 + Spawn Type: "50" + Parameters: "F09F" + State: -1 + +- Type: Overworld + Entrance Couple Tag: Zoras Domain From Upper Zoras River + Forward: + Connection: Upper Zoras River To Zoras Domain (On Land) -> Zoras Domain To Upper Zoras River (On Land) + Alias: Upper Zoras River -> Zoras Domain + Stage: 50 + Room: 1 + Spawn: 10 + Spawn Type: "50" + Parameters: "F09F" + State: -1 + Return: + Connection: Zoras Domain To Upper Zoras River (On Land) -> Upper Zoras River To Zoras Domain (On Land) + Alias: Zoras Domain -> Upper Zoras River + Stage: 61 + Room: 0 + Spawn: 7 + Spawn Type: "50" + Parameters: "F09F" + State: -1 + +- Type: Overworld + Entrance Couple Tag: Zoras Domain Throne Room + Forward: + Connection: Zoras Domain Top of Waterfall Underwater -> Zoras Throne Room Underwater Alias: Zoras Domain -> Zoras Throne Room Stage: 50 Room: 0 - Spawn: "01" - Spawn Type: "50" + Spawn: 7 + Spawn Type: "80" Parameters: "F09F" - State: "FF" + State: -1 Return: - Connection: Zoras Throne Room -> Zoras Domain Top of Waterfall + Connection: Zoras Throne Room Underwater -> Zoras Domain Top of Waterfall Underwater Alias: Zoras Throne Room -> Zoras Domain Stage: 50 Room: 1 - Spawn: "00" + Spawn: 9 + Spawn Type: "80" + Parameters: "F09F" + State: -1 + +- Type: Overworld + Entrance Couple Tag: Zoras Domain Throne Room + Forward: + Connection: Zoras Domain Top of Waterfall West -> Zoras Throne Room West + Alias: Zoras Domain -> Zoras Throne Room + Stage: 50 + Room: 0 + Spawn: 1 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 + Return: + Connection: Zoras Throne Room West -> Zoras Domain Top of Waterfall West + Alias: Zoras Throne Room -> Zoras Domain + Stage: 50 + Room: 1 + Spawn: 0 + Spawn Type: "50" + Parameters: "F09F" + State: -1 + +- Type: Overworld + Entrance Couple Tag: Zoras Domain Throne Room + Forward: + Connection: Zoras Domain Top of Waterfall East -> Zoras Throne Room East + Alias: Zoras Domain -> Zoras Throne Room + Stage: 50 + Room: 0 + Spawn: 4 + Spawn Type: "50" + Parameters: "F09F" + State: -1 + Return: + Connection: Zoras Throne Room East -> Zoras Domain Top of Waterfall East + Alias: Zoras Throne Room -> Zoras Domain + Stage: 50 + Room: 1 + Spawn: 4 + Spawn Type: "50" + Parameters: "F09F" + State: -1 + +- Type: Overworld + Entrance Couple Tag: Zoras Domain Throne Room + Forward: + Connection: Zoras Domain Top of Waterfall Center -> Zoras Throne Room Center + Alias: Zoras Domain -> Zoras Throne Room + Stage: 50 + Room: 0 + Spawn: 3 + Spawn Type: "50" + Parameters: "F09F" + State: -1 + Return: + Connection: Zoras Throne Room Center -> Zoras Domain Top of Waterfall Center + Alias: Zoras Throne Room -> Zoras Domain + Stage: 50 + Room: 1 + Spawn: 8 + Spawn Type: "50" + Parameters: "F09F" + State: -1 - Type: Overworld Forward: @@ -2425,19 +2557,19 @@ Alias: Zoras Domain -> Snowpeak Province Stage: 51 Room: 0 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Snowpeak Climb Lower -> Zoras Domain Alias: Snowpeak Province -> Zoras Domain Stage: 50 Room: 1 - Spawn: "06" + Spawn: 6 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: @@ -2445,271 +2577,273 @@ Alias: Snowpeak Climb -> Snowpeak Summit Cave Stage: 51 Room: 2 - Spawn: "08" + Spawn: 8 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Snowpeak Summit Cave -> Snowpeak Climb Upper Alias: Snowpeak Summit Cave -> Snowpeak Climb Stage: 51 Room: 0 - Spawn: "0F" + Spawn: 15 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 - Type: Overworld Forward: Connection: Lanayru Field -> Outside Castle Town West Stage: 57 Room: 8 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Outside Castle Town West -> Lanayru Field Stage: 56 Room: 10 - Spawn: "04" + Spawn: 4 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: Connection: Outside Castle Town West -> Lake Hylia Bridge Stage: 56 Room: 12 - Spawn: "01" + Spawn: 1 Spawn Type: "00" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Lake Hylia Bridge -> Outside Castle Town West Stage: 57 Room: 8 - Spawn: "02" + Spawn: 2 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: Connection: Outside Castle Town West -> Castle Town West Stage: 53 Room: 2 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Castle Town West -> Outside Castle Town West Stage: 57 Room: 8 - Spawn: "01" + Spawn: 1 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: Connection: Castle Town West -> Castle Town Center Stage: 53 Room: 0 - Spawn: "04" + Spawn: 4 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Castle Town Center -> Castle Town West Stage: 53 Room: 2 - Spawn: "02" + Spawn: 2 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 - Type: Overworld Forward: Connection: Castle Town West -> Castle Town South Stage: 53 Room: 3 - Spawn: "08" + Spawn: 8 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Castle Town South -> Castle Town West Stage: 53 Room: 2 - Spawn: "03" + Spawn: 3 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: Connection: Castle Town Center -> Castle Town North Stage: 53 Room: 1 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Castle Town North -> Castle Town Center Stage: 53 Room: 0 - Spawn: "03" + Spawn: 3 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: Connection: Castle Town Center -> Castle Town East Stage: 53 Room: 4 - Spawn: "02" + Spawn: 2 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Castle Town East -> Castle Town Center Stage: 53 Room: 0 - Spawn: "06" + Spawn: 6 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: Connection: Castle Town Center -> Castle Town South Stage: 53 Room: 3 - Spawn: "02" + Spawn: 2 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Castle Town South -> Castle Town Center Stage: 53 Room: 0 - Spawn: "05" + Spawn: 5 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: Connection: Castle Town East -> Outside Castle Town East Stage: 57 Room: 17 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Outside Castle Town East -> Castle Town East Stage: 53 Room: 4 - Spawn: "00" + Spawn: 0 Spawn Type: "10" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: Connection: Castle Town East -> Castle Town South Stage: 53 Room: 3 - Spawn: "09" + Spawn: 9 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Castle Town South -> Castle Town East Stage: 53 Room: 4 - Spawn: "06" + Spawn: 6 Spawn Type: "50" Parameters: "F09F" - State: "FF" + State: -1 - Type: Overworld Forward: Connection: Castle Town South -> Outside Castle Town South Stage: 57 Room: 16 - Spawn: "01" + Spawn: 1 Spawn Type: "05" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Outside Castle Town South -> Castle Town South Stage: 53 Room: 3 - Spawn: "00" + Spawn: 0 Spawn Type: "10" Parameters: "F09F" - State: "FF" + State: -1 -- Type: Overworld - Forward: - Connection: Outside Castle Town South -> Lake Hylia - Stage: 57 - Room: 16 - Spawn: "01" - Spawn Type: "05" - Parameters: "F09F" - State: "FF" - Return: - Connection: Lake Hylia -> Outside Castle Town South - Stage: -1 - Room: -1 - Spawn: "" - Spawn Type: "" - Parameters: "" - State: "FF" +# Disabled until we use stage service to create a spawn Outside Castle Town +# - Type: Overworld +# Forward: +# Connection: Outside Castle Town South -> Lake Hylia +# Stage: 57 +# Room: 16 +# Spawn: 1 +# Spawn Type: "05" +# Parameters: "F09F" +# State: -1 + # Return: + # Connection: Lake Hylia -> Outside Castle Town South + # Stage: -1 + # Room: -1 + # Spawn: + # Spawn Type: "" + # Parameters: "" + # State: -1 - Type: Overworld Forward: Connection: Lake Hylia Bridge -> Flight by Fowl Stage: 52 Room: 0 - Spawn: "08" + Spawn: 8 Spawn Type: "B0" Parameters: "F09F" - State: "FF" + State: -1 Return: Connection: Flight by Fowl -> Lake Hylia Bridge Stage: 56 Room: 13 - Spawn: "01" + Spawn: 1 Spawn Type: "A0" Parameters: "F09F" - State: "FF" + State: -1 -- Type: Overworld - Forward: - Connection: Lake Hylia -> Gerudo Desert - Stage: 59 - Room: 0 - Spawn: "00" - Spawn Type: "00" - Parameters: "F018" - State: "FF" - Return: - Connection: Gerudo Desert -> Lake Hylia - Stage: - Room: - Spawn: "" - Spawn Type: "" - Parameters: "" - State: "FF" +# Disabled until we use stage service to create a spawn in Lake Hylia +# - Type: Overworld +# Forward: +# Connection: Lake Hylia -> Gerudo Desert +# Stage: 59 +# Room: 0 +# Spawn: 0 +# Spawn Type: "00" +# Parameters: "F018" +# State: -1 + # Return: + # Connection: Gerudo Desert -> Lake Hylia + # Stage: + # Room: + # Spawn: + # Spawn Type: "" + # Parameters: "" + # State: -1 - Type: Overworld Forward: @@ -2717,34 +2851,34 @@ Alias: Gerudo Desert -> Bulblin Camp Stage: 55 Room: 1 - Spawn: "00" + Spawn: 0 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Bulblin Camp -> Gerudo Desert Outside Bulblin Camp Alias: Bulblin Camp -> Gerudo Desert Stage: 59 Room: 0 - Spawn: "02" + Spawn: 2 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 - Type: Overworld Forward: Connection: Bulblin Camp -> Outside Arbiters Grounds Stage: 55 Room: 3 - Spawn: "07" + Spawn: 7 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 Return: Connection: Outside Arbiters Grounds -> Bulblin Camp Stage: 55 Room: 1 - Spawn: "02" + Spawn: 2 Spawn Type: "50" Parameters: "F01F" - State: "FF" + State: -1 diff --git a/mods/randomizer/generator/data/world/overworld/Lanayru Province.yaml b/mods/randomizer/generator/data/world/overworld/Lanayru Province.yaml index 2a26a3e65f..6bd59e4216 100644 --- a/mods/randomizer/generator/data/world/overworld/Lanayru Province.yaml +++ b/mods/randomizer/generator/data/world/overworld/Lanayru Province.yaml @@ -665,9 +665,35 @@ Exits: Upper Zoras River Izas House: Can_Open_Doors and Upper_Zoras_River_Portal Fishing Hole: Can_Open_Doors - Zoras Domain: Nothing + Upper Zoras River To Zoras Domain (On Land): Nothing + Upper Zoras River To Zoras Domain (Swimming): Nothing + Upper Zoras River To Zoras Domain (Underwater): Iron_Boots or Zora_Armor Lanayru Field: Nothing +- Name: Upper Zoras River To Zoras Domain (On Land) + Map Sector: Lanayru Province + Region: Upper Zoras River + Twilight: Lanayru + Exits: + Zoras Domain To Upper Zoras River (On Land): Nothing + Upper Zoras River: Nothing + +- Name: Upper Zoras River To Zoras Domain (Swimming) + Map Sector: Lanayru Province + Region: Upper Zoras River + Twilight: Lanayru + Exits: + Zoras Domain To Upper Zoras River (Swimming): Nothing + Upper Zoras River: Nothing + +- Name: Upper Zoras River To Zoras Domain (Underwater) + Map Sector: Lanayru Province + Region: Upper Zoras River + Twilight: Lanayru + Exits: + Zoras Domain To Upper Zoras River (Underwater): Iron_Boots or Zora_Armor + Upper Zoras River: Nothing + - Name: Upper Zoras River Izas House Can Warp: True Locations: @@ -718,7 +744,33 @@ Zoras Domain West Ledge: Clawshot or Can_Midna_Jump or Twilight Zoras Domain Top of Waterfall: Clawshot or Can_Midna_Jump or Twilight Snowpeak Climb Lower: Not_Twilight - Upper Zoras River: Nothing + Zoras Domain To Upper Zoras River (On Land): Nothing + Zoras Domain To Upper Zoras River (Swimming): Nothing + Zoras Domain To Upper Zoras River (Underwater): Iron_Boots or Zora_Armor + +- Name: Zoras Domain To Upper Zoras River (On Land) + Map Sector: Lanayru Province + Region: Zoras Domain + Twilight: Lanayru + Exits: + Upper Zoras River To Zoras Domain (On Land): Nothing + Zoras Domain: Nothing + +- Name: Zoras Domain To Upper Zoras River (Swimming) + Map Sector: Lanayru Province + Region: Zoras Domain + Twilight: Lanayru + Exits: + Upper Zoras River To Zoras Domain (Swimming): Nothing + Zoras Domain: Nothing + +- Name: Zoras Domain To Upper Zoras River (Underwater) + Map Sector: Lanayru Province + Region: Zoras Domain + Twilight: Lanayru + Exits: + Upper Zoras River To Zoras Domain (Underwater): Nothing + Zoras Domain: Iron_Boots or Zora_Armor - Name: Zoras Domain West Ledge Map Sector: Lanayru Province @@ -747,10 +799,45 @@ Zoras Domain Shortcut Lower Boulder Rupee: Can_Smash Zoras Domain Shortcut Upper Boulder Rupee: Can_Smash Exits: - Zoras Throne Room: Nothing + Zoras Domain Top of Waterfall Center: Nothing + Zoras Domain Top of Waterfall West: Nothing + Zoras Domain Top of Waterfall East: Nothing + Zoras Domain Top of Waterfall Underwater: Iron_Boots or Zora_Armor Zoras Domain West Ledge: Can_Smash Zoras Domain: Nothing +- Name: Zoras Domain Top of Waterfall Center + Map Sector: Lanayru Province + Region: Zoras Domain + Twilight: Lanayru + Exits: + Zoras Domain Top of Waterfall: Nothing + Zoras Throne Room Center: Nothing + +- Name: Zoras Domain Top of Waterfall West + Map Sector: Lanayru Province + Region: Zoras Domain + Twilight: Lanayru + Exits: + Zoras Domain Top of Waterfall: Nothing + Zoras Throne Room West: Nothing + +- Name: Zoras Domain Top of Waterfall East + Map Sector: Lanayru Province + Region: Zoras Domain + Twilight: Lanayru + Exits: + Zoras Domain Top of Waterfall: Nothing + Zoras Throne Room East: Iron_Boots or Zora_Armor + +- Name: Zoras Domain Top of Waterfall Underwater + Map Sector: Lanayru Province + Region: Zoras Domain + Twilight: Lanayru + Exits: + Zoras Domain Top of Waterfall: Nothing + Zoras Throne Room Underwater: Iron_Boots or Zora_Armor + - Name: Zoras Throne Room Map Sector: Lanayru Province Region: Zoras Domain @@ -769,4 +856,39 @@ Zoras Domain Underwater Goron: Water_Bombs and Iron_Boots and Zora_Armor Zoras Domain Throne Room Twilit Insect: Can_Defeat_Lanayru_Twilit_Insect Exits: - Zoras Domain Top of Waterfall: Nothing + Zoras Throne Room Center: Nothing + Zoras Throne Room West: Nothing + Zoras Throne Room East: Nothing + Zoras Throne Room Underwater: Iron_Boots or Zora_Armor + +- Name: Zoras Throne Room Center + Map Sector: Lanayru Province + Region: Zoras Domain + Twilight: Lanayru + Exits: + Zoras Domain Top of Waterfall Center: Nothing + Zoras Throne Room: Nothing + +- Name: Zoras Throne Room West + Map Sector: Lanayru Province + Region: Zoras Domain + Twilight: Lanayru + Exits: + Zoras Domain Top of Waterfall West: Nothing + Zoras Throne Room: Nothing + +- Name: Zoras Throne Room East + Map Sector: Lanayru Province + Region: Zoras Domain + Twilight: Lanayru + Exits: + Zoras Domain Top of Waterfall East: Nothing + Zoras Throne Room: Nothing + +- Name: Zoras Throne Room Underwater + Map Sector: Lanayru Province + Region: Zoras Domain + Twilight: Lanayru + Exits: + Zoras Domain Top of Waterfall Underwater: Nothing + Zoras Throne Room: Iron_Boots or Zora_Armor diff --git a/mods/randomizer/generator/logic/entrance.cpp b/mods/randomizer/generator/logic/entrance.cpp index a9095d914b..cecd220a81 100644 --- a/mods/randomizer/generator/logic/entrance.cpp +++ b/mods/randomizer/generator/logic/entrance.cpp @@ -357,30 +357,10 @@ namespace randomizer::logic::entrance return {parentAreaName, connectedAreaName}; } - bool Entrance::SetGameInfo(const YAML::Node& node) { - bool ret = true; - std::string stageIdString = node["Stage"].as(); - if (stageIdString == "null") { - stageIdString = "-1"; - ret = false; - } - int stageId = std::stoi(stageIdString); - if (stageId == -1) { - stageId = 0xFF; - } - SetStageId(static_cast(stageId)); - std::string roomNoString = node["Room"].as(); - if (roomNoString == "null") { - roomNoString = "-1"; - ret = false; - } - SetRoomNo(static_cast(std::stoi(roomNoString))); - SetPointNo(static_cast(std::stoi("0x0"+node["Spawn"].as(),nullptr,16))); - int layer = std::stoi("0x0"+node["State"].as(),nullptr,16); - if (layer == 0xFF) { - layer = -1; - } - SetLayerNo(static_cast(layer)); - return ret; + void Entrance::SetGameInfo(const YAML::Node& node) { + SetStageId(node["Stage"].as()); + SetRoomNo(node["Room"].as()); + SetPointNo(node["Spawn"].as()); + SetLayerNo(node["State"].as()); } } // namespace randomizer::logic::entrance diff --git a/mods/randomizer/generator/logic/entrance.hpp b/mods/randomizer/generator/logic/entrance.hpp index 78c1df9bf2..01762fdc35 100644 --- a/mods/randomizer/generator/logic/entrance.hpp +++ b/mods/randomizer/generator/logic/entrance.hpp @@ -158,9 +158,9 @@ namespace randomizer::logic::entrance int8_t GetRoomNo() const { return _roomNo; } int8_t GetLayerNo() const { return _layerNo; } int16_t GetPointNo() const { return _pointNo; } - bool SetGameInfo(const YAML::Node& node); - void SetCoupledDoor(int16_t entrance) { _coupledEntrance = entrance; } - int16_t getCoupledDoor() { return _coupledEntrance; } + void SetGameInfo(const YAML::Node& node); + void SetCoupledEntrances(const std::vector& entrances) { _coupledEntrances = entrances; } + const std::vector& getCoupledEntrances() const { return _coupledEntrances; } private: int _id = -1; @@ -223,7 +223,7 @@ namespace randomizer::logic::entrance Entrance* _assumed = nullptr; // If the entrance is a coupled door, this is the other door's point to override - int16_t _coupledEntrance = -1; + std::vector _coupledEntrances = {}; }; using EntrancePool = std::vector; diff --git a/mods/randomizer/generator/logic/entrance_shuffle.cpp b/mods/randomizer/generator/logic/entrance_shuffle.cpp index d042f2d264..8868d1d8dc 100644 --- a/mods/randomizer/generator/logic/entrance_shuffle.cpp +++ b/mods/randomizer/generator/logic/entrance_shuffle.cpp @@ -42,8 +42,8 @@ namespace randomizer::logic::entrance_shuffle void SetAllEntrancesData(world::World* world) { - // Keep track of which double door entrances are together - std::unordered_map> coupledDoors = {}; + // Keep track of which entrances are together + std::unordered_map> coupledEntrances = {}; auto entranceDataTree = LOAD_EMBED_YAML(RANDO_DATA_PATH "entrance_shuffle_data.yaml"); for (const auto& entranceDataNode : entranceDataTree) @@ -60,6 +60,21 @@ namespace randomizer::logic::entrance_shuffle } auto& forwardEntry = entranceDataNode["Forward"]; + + // If the entrance can't actually be mapped in-game, skip it + auto stageString = forwardEntry["Stage"].as(); + auto roomString = forwardEntry["Stage"].as(); + if (stageString == "null" || stageString == "-1" || roomString == "null" || roomString == "-1") { + continue; + } + if (entranceDataNode["Return"]) { + stageString = entranceDataNode["Return"]["Stage"].as(); + roomString = entranceDataNode["Return"]["Stage"].as(); + if (stageString == "null" || stageString == "-1" || roomString == "null" || roomString == "-1") { + continue; + } + } + // Check to make sure all required fields are present for the forward entry YAMLVerifyFields(forwardEntry, "Connection" /*, "Info" */); @@ -84,45 +99,50 @@ namespace randomizer::logic::entrance_shuffle returnEntry["Alias"] ? returnEntry["Alias"].as() : ""); forwardEntrance->BindTwoWay(returnEntrance); - // Add double door entrances to their respective tag group - if (entranceDataNode["Door Couple Tag"]) + // Add coupled entrances to their respective tag group + if (entranceDataNode["Entrance Couple Tag"]) { - auto tag = entranceDataNode["Door Couple Tag"].as(); - if (!coupledDoors.contains(tag)) + auto tag = entranceDataNode["Entrance Couple Tag"].as(); + if (!coupledEntrances.contains(tag)) { - coupledDoors[tag] = {}; + coupledEntrances[tag] = {}; } - coupledDoors.at(tag).push_back(forwardEntrance); - coupledDoors.at(tag).push_back(returnEntrance); + coupledEntrances.at(tag).push_back(forwardEntrance); + coupledEntrances.at(tag).push_back(returnEntrance); } } } - // If double doors are coupled, add the coupled door's info to the main door, remove the coupled door entrance, and + // If entrances are coupled, add the coupled entrance's spawn point to the main door, remove the coupled door entrance, and // rename the main door to be more general if (world->Setting("Decouple Double Door Entrances") == "Off") { - for (auto& [tag, doors] : coupledDoors) + for (auto& [tag, entrances] : coupledEntrances) { - while (!doors.empty()) + while (!entrances.empty()) { - auto mainDoor = doors.back(); - doors.pop_back(); + auto mainEntrance = entrances.back(); + entrances.pop_back(); - auto coupledDoorItr = - std::ranges::find_if(doors, - [&](const auto& door) { return door->IsPrimary() == mainDoor->IsPrimary(); }); - auto coupledDoor = *coupledDoorItr; + std::vector coupledPoints; + for (auto it = entrances.begin(); it != entrances.end();) { + auto coupledEntrance = *it; + if (coupledEntrance->IsPrimary() == mainEntrance->IsPrimary()) { + coupledPoints.push_back(coupledEntrance->GetPointNo()); - mainDoor->SetCoupledDoor(coupledDoor->GetPointNo()); + // Completely remove the coupled door from the world graph + coupledEntrance->GetConnectedArea()->RemoveEntrance(coupledEntrance); + coupledEntrance->GetParentArea()->RemoveExit(coupledEntrance); + it = entrances.erase(it); + }else{ + ++it; + } + } - // Completely remove the coupled door from the world graph - doors.erase(coupledDoorItr); - coupledDoor->GetConnectedArea()->RemoveEntrance(coupledDoor); - coupledDoor->GetParentArea()->RemoveExit(coupledDoor); + mainEntrance->SetCoupledEntrances(std::move(coupledPoints)); // Change the main door's name to be more general - mainDoor->GeneralizeName(); + mainEntrance->GeneralizeName(); } } } diff --git a/mods/randomizer/src/hooks.cpp b/mods/randomizer/src/hooks.cpp index 0c76793ee1..5accb327c2 100644 --- a/mods/randomizer/src/hooks.cpp +++ b/mods/randomizer/src/hooks.cpp @@ -133,7 +133,7 @@ DEFINE_HOOK(&daNpc_ykW_c::isDelete, daNpc_ykW_c__isDelete); DEFINE_HOOK_SYMBOL("daE_MD_Create", int(fopAc_ac_c*), daE_MD_c__create); -DEFINE_HOOK(&daObjMasterSword_c::executeWait, daObjMasterSword_c__executeWait); +DEFINE_HOOK(&fopAcM_orderMapToolEvent, orderMapToolEvent); DEFINE_HOOK_SYMBOL("daObjMasterSword_Execute", int(daObjMasterSword_c*), daObjMasterSword_c__execute); DEFINE_HOOK(&dScnName_c::changeGameScene, dScnName_c__changeGameScene); @@ -179,7 +179,6 @@ dialogSelectModeState g_dialogSelectModeState = SelectReady; namespace randomizer::hooks { namespace { -UiDialogHandle playModeDialog{0}; HookAction hookPreDataSelect(ModContext*, void* args, void* retval, void* userdata) { ui::g_dialogSelectModeState = ui::SelectReady; ui::g_file_select_window_ctx.is_proceed = false; @@ -198,57 +197,12 @@ HookAction hookPreSelectDataNameMove(ModContext*, void* args, void* retval, void bool isFileRecScale = i_this->fileRecScaleAnm2(); bool isModoruTxtDisp = i_this->modoruTxtDispAnm(); - // if selected vanilla mode, let transition occur as normal - if (ui::g_dialogSelectModeState == ui::SelectVanilla) { - return HOOK_CONTINUE; - } - if (ui::g_dialogSelectModeState == ui::SelectReady && isHeaderTxtChange == true && isFileRecScale == true && isModoruTxtDisp == true) { ui::g_dialogSelectModeState = ui::SelectWait; - auto buildDialog = [i_this]() { - UiDialogDesc desc = UI_DIALOG_DESC_INIT; - desc.title = "Play Type"; - desc.body_rml = "What mode would you like to play?"; - desc.icon = "question-mark"; - desc.variant = UI_DIALOG_NORMAL; - - UiDialogAction actions[2]; - actions[0] = { - .label = "Vanilla", - .on_pressed = [](ModContext* ctx, UiDialogHandle dialogHandle, void*) { - mDoAud_seStartMenu(Z2SE_SY_CURSOR_OK); - randomizer_GetContext() = RandomizerContext(); - ui::g_dialogSelectModeState = ui::SelectVanilla; - session::svc_mng.ui->dialog_close(ctx, dialogHandle); - }, - .user_data = nullptr, - .keep_open = false, - }; - actions[1] = { - .label = "Randomizer", - .on_pressed = [](ModContext* ctx, UiDialogHandle dialogHandle, void* userdata) { - mDoAud_seStartMenu(Z2SE_SY_CURSOR_OK); - ui::g_dialogSelectModeState = ui::SelectRandomizer; - ui::buildFileSelectGateMenu(static_cast(userdata)); - session::svc_mng.ui->dialog_close(ctx, dialogHandle); - }, - .user_data = i_this, - .keep_open = false, - }; - desc.actions = actions; - desc.action_count = 2; - - if (session::svc_mng.ui->dialog_push(session::svc_mng.mod_ctx, &desc, &playModeDialog) != MOD_OK) { - mods::log::error("Failed to push dialog"); - return MOD_ERROR; - } - - return MOD_OK; - }; - - if (buildDialog() != MOD_OK) { - mods::log::error("Failed to build dialog"); + ModResult rt = ui::buildFileSelectGateMenu(i_this); + if (rt != MOD_OK) { + mods::log::error("Failed to build menu"); return HOOK_CONTINUE; } } @@ -1863,7 +1817,7 @@ void hookPostChangeScene4Event(ModContext*, void* args, void* retval, void*) { stage_scls_info_class* scls_info = &scls->m_entries[i_exitId]; // If randomizer is active and we're loading the first spawn, set our starting time of day - if (std::strcmp(scls_info->mStage, "F_SP103") + if (std::strcmp(scls_info->mStage, "F_SP103") == 0 && scls_info->mRoom == 1 && scls_info->mStart == 1) { @@ -2152,47 +2106,36 @@ void hookPostEMdCreate(ModContext*, void* args, void*, void*) { hookEMdCreate_prevSkipInfo = 0; } -// functions are simple enough that replacing isn't too bad -// todo: item service needs to be properly hooked up to this check i think instead of -// using "randomizer_getItemAtLocation" -void hookReplaceMasterSwordExecuteWait(ModContext*, void* args, void*, void*) { - auto* i_this = mods::arg(args, 0); - - if (daPy_getPlayerActorClass()->checkPriActorOwn(i_this)) { - for (int i = 0; i < dComIfGp_getAttention()->GetActionCount(); i++) { - if (dComIfGp_getAttention()->ActionTarget(i) == i_this) { - if (dComIfGp_getAttention()->getActionBtnB() != NULL && - dComIfGp_getAttention()->getActionBtnB()->mType == fopAc_attn_CARRY_e) - { - dComIfGp_setDoStatusForce(8, 0); - } - } - } - } - - if (fopAcM_checkCarryNow(i_this)) { - u8 itemToGive = randomizer_getItemAtLocation("Sacred Grove Pedestal Master Sword"); - g_randomizerState.addItemToEventQueue(itemToGive); - - itemToGive = randomizer_getItemAtLocation("Sacred Grove Pedestal Shadow Crystal"); - g_randomizerState.addItemToEventQueue(itemToGive); +HookAction hookPreOrderMapToolEvent(ModContext*, void* args, void*, void*) { + auto eventId = mods::arg(args, 1); + // skip starting the master sword cutscene so we can handle the checks manually + if (daAlink_c::checkStageName("F_SP117") && eventId == 2) { + // Set the necessary flags to de-spawn the MS and set the save file event flag. dComIfGs_onTmpBit(0x820); dComIfGs_onEventBit(0x2120); + return HOOK_SKIP_ORIGINAL; } + + return HOOK_CONTINUE; } HookAction hookPreMasterSwordExecute(ModContext*, void* args, void* retval, void*) { auto* i_this = mods::arg(args, 0); + (i_this->*i_this->mActionFunc[1])(); + dComIfG_Ccsp()->Set(&i_this->mCyl); + + i_this->mBtk.play(); + i_this->mBrk.play(); + if (dComIfGs_isTmpBit(dSv_event_tmp_flag_c::tempBitLabels[73])) { // Don't automatically give the master sword in randomizer fopAcM_delete(i_this); - *static_cast(retval) = 1; - return HOOK_SKIP_ORIGINAL; } - return HOOK_CONTINUE; + *static_cast(retval) = 1; + return HOOK_SKIP_ORIGINAL; } void hookPost_dScnName_c__changeGameScene(ModContext* ctx, void* args, void* retval, void* userdata) { @@ -2628,7 +2571,7 @@ ModResult initialize() { ADD_HOOK_PRE(daE_MD_c__create, hookPreEMdCreate); ADD_HOOK_POST(daE_MD_c__create, hookPostEMdCreate); - ADD_HOOK_REPLACE(daObjMasterSword_c__executeWait, hookReplaceMasterSwordExecuteWait); + ADD_HOOK_PRE(orderMapToolEvent, hookPreOrderMapToolEvent); ADD_HOOK_PRE(daObjMasterSword_c__execute, hookPreMasterSwordExecute); ADD_HOOK_POST(dScnName_c__changeGameScene, hookPost_dScnName_c__changeGameScene); @@ -2746,7 +2689,7 @@ ModResult uninstall() { mods::hook::uninstall(svc_hook); - mods::hook::uninstall(svc_hook); + mods::hook::uninstall(svc_hook); mods::hook::uninstall(svc_hook); mods::hook::uninstall(); diff --git a/mods/randomizer/src/item.cpp b/mods/randomizer/src/item.cpp index 4004b83378..6dd33f92f6 100644 --- a/mods/randomizer/src/item.cpp +++ b/mods/randomizer/src/item.cpp @@ -11,7 +11,8 @@ #include "tools.h" #include "verify_item_functions.h" -static void item_func_FOOLISH_ITEM() { +namespace { +void item_func_FOOLISH_ITEM() { // Failsafe: Make sure the count does not somehow exceed 100 if (g_randomizerState.mFoolishItemCount < 100) { @@ -19,15 +20,15 @@ static void item_func_FOOLISH_ITEM() { } } -static void item_func_ORDON_PORTAL() { +void item_func_ORDON_PORTAL() { dComIfGs_onStageSwitch(0x0, 0x34); // Unlock Ordon Portal } -static void item_func_SOUTH_FARON_PORTAL() { +void item_func_SOUTH_FARON_PORTAL() { dComIfGs_onStageSwitch(0x2, 0x47); // Unlock S Faron Portal } -static void item_func_UPPER_ZORAS_RIVER_PORTAL() { +void item_func_UPPER_ZORAS_RIVER_PORTAL() { dComIfGs_onStageSwitch(0x4, 0x17); // Talked to Iza before portal dComIfGs_onStageSwitch(0x4, 0x37); // Talked to Iza after portal dComIfGs_onStageSwitch(0x4, 0x15); // Unlock UZR Portal @@ -36,201 +37,201 @@ static void item_func_UPPER_ZORAS_RIVER_PORTAL() { dComIfGs_onEventBit(0xB02); // Iza 1 Minigame Unlocked } -static void item_func_CASTLE_TOWN_PORTAL() { +void item_func_CASTLE_TOWN_PORTAL() { dComIfGs_onStageSwitch(0x6, 0x3); // Unlock Castle Town Portal } -static void item_func_GERUDO_DESERT_PORTAL() { +void item_func_GERUDO_DESERT_PORTAL() { dComIfGs_onStageSwitch(0xA, 0x15); // Unlock Desert Portal } -static void item_func_NORTH_FARON_PORTAL() { +void item_func_NORTH_FARON_PORTAL() { dComIfGs_onStageSwitch(0x2, 0x2); // Unlock N Faron Portal } -static void item_func_KAKARIKO_GORGE_PORTAL() { +void item_func_KAKARIKO_GORGE_PORTAL() { dComIfGs_onStageSwitch(0x6, 0x15); // Unlock Gorge Portal } -static void item_func_KAKARIKO_VILLAGE_PORTAL() { +void item_func_KAKARIKO_VILLAGE_PORTAL() { dComIfGs_onStageSwitch(0x3, 0x1F); // Unlock Kak Portal } -static void item_func_DEATH_MOUNTAIN_PORTAL() { +void item_func_DEATH_MOUNTAIN_PORTAL() { dComIfGs_onStageSwitch(0x3, 0x15); // Unlock DM Portal } -static void item_func_ZORAS_DOMAIN_PORTAL() { +void item_func_ZORAS_DOMAIN_PORTAL() { dComIfGs_onStageSwitch(0x4, 0x2); // Unlock ZD Portal } -static void item_func_FOREST_SMALL_KEY() { +void item_func_FOREST_SMALL_KEY() { u8 currentKeys = getAreaKeyNum(0x10); dComIfGs_setKeyNum(0x10, currentKeys + 1); } -static void item_func_MINES_SMALL_KEY() { +void item_func_MINES_SMALL_KEY() { u8 currentKeys = getAreaKeyNum(0x11); dComIfGs_setKeyNum(0x11, currentKeys + 1); } -static void item_func_LAKEBED_SMALL_KEY() { +void item_func_LAKEBED_SMALL_KEY() { u8 currentKeys = getAreaKeyNum(0x12); dComIfGs_setKeyNum(0x12, currentKeys + 1); } -static void item_func_ARBITERS_SMALL_KEY() { +void item_func_ARBITERS_SMALL_KEY() { u8 currentKeys = getAreaKeyNum(0x13); dComIfGs_setKeyNum(0x13, currentKeys + 1); } -static void item_func_SNOWPEAK_SMALL_KEY() { +void item_func_SNOWPEAK_SMALL_KEY() { u8 currentKeys = getAreaKeyNum(0x14); dComIfGs_setKeyNum(0x14, currentKeys + 1); } -static void item_func_TEMPLE_OF_TIME_SMALL_KEY() { +void item_func_TEMPLE_OF_TIME_SMALL_KEY() { u8 currentKeys = getAreaKeyNum(0x15); dComIfGs_setKeyNum(0x15, currentKeys + 1); } -static void item_func_CITY_SMALL_KEY() { +void item_func_CITY_SMALL_KEY() { u8 currentKeys = getAreaKeyNum(0x16); dComIfGs_setKeyNum(0x16, currentKeys + 1); } -static void item_func_PALACE_SMALL_KEY() { +void item_func_PALACE_SMALL_KEY() { u8 currentKeys = getAreaKeyNum(0x17); dComIfGs_setKeyNum(0x17, currentKeys + 1); } -static void item_func_HYRULE_SMALL_KEY() { +void item_func_HYRULE_SMALL_KEY() { u8 currentKeys = getAreaKeyNum(0x18); dComIfGs_setKeyNum(0x18, currentKeys + 1); } -static void item_func_CAMP_SMALL_KEY() { +void item_func_CAMP_SMALL_KEY() { u8 currentKeys = getAreaKeyNum(0xA); dComIfGs_setKeyNum(0xA, currentKeys + 1); } -static void item_func_LAKE_HYLIA_PORTAL() { +void item_func_LAKE_HYLIA_PORTAL() { dComIfGs_onStageSwitch(0x4, 0xA); // Unlock Lake Portal } -static void item_func_FOREST_BOSS_KEY() { +void item_func_FOREST_BOSS_KEY() { dComIfGs_onDungeonItemBossKey(0x10); } -static void item_func_LAKEBED_BOSS_KEY() { +void item_func_LAKEBED_BOSS_KEY() { dComIfGs_onDungeonItemBossKey(0x12); } -static void item_func_ARBITERS_BOSS_KEY() { +void item_func_ARBITERS_BOSS_KEY() { dComIfGs_onDungeonItemBossKey(0x13); } -static void item_func_TEMPLE_OF_TIME_BOSS_KEY() { +void item_func_TEMPLE_OF_TIME_BOSS_KEY() { dComIfGs_onDungeonItemBossKey(0x15); } -static void item_func_CITY_BOSS_KEY() { +void item_func_CITY_BOSS_KEY() { dComIfGs_onDungeonItemBossKey(0x16); } -static void item_func_PALACE_BOSS_KEY() { +void item_func_PALACE_BOSS_KEY() { dComIfGs_onDungeonItemBossKey(0x17); } -static void item_func_HYRULE_BOSS_KEY() { +void item_func_HYRULE_BOSS_KEY() { dComIfGs_onDungeonItemBossKey(0x18); } -static void item_func_FOREST_COMPASS() { +void item_func_FOREST_COMPASS() { dComIfGs_onDungeonItemCompass(0x10); } -static void item_func_MINES_COMPASS() { +void item_func_MINES_COMPASS() { dComIfGs_onDungeonItemCompass(0x11); } -static void item_func_LAKEBED_COMPASS() { +void item_func_LAKEBED_COMPASS() { dComIfGs_onDungeonItemCompass(0x12); } -static void item_func_ARBITERS_COMPASS() { +void item_func_ARBITERS_COMPASS() { dComIfGs_onDungeonItemCompass(0x13); } -static void item_func_SNOWPEAK_COMPASS() { +void item_func_SNOWPEAK_COMPASS() { dComIfGs_onDungeonItemCompass(0x14); } -static void item_func_TEMPLE_OF_TIME_COMPASS() { +void item_func_TEMPLE_OF_TIME_COMPASS() { dComIfGs_onDungeonItemCompass(0x15); } -static void item_func_CITY_COMPASS() { +void item_func_CITY_COMPASS() { dComIfGs_onDungeonItemCompass(0x16); } -static void item_func_PALACE_COMPASS() { +void item_func_PALACE_COMPASS() { dComIfGs_onDungeonItemCompass(0x17); } -static void item_func_HYRULE_COMPASS() { +void item_func_HYRULE_COMPASS() { dComIfGs_onDungeonItemCompass(0x18); } -static void item_func_MIRROR_CHAMBER_PORTAL() { +void item_func_MIRROR_CHAMBER_PORTAL() { dComIfGs_onStageSwitch(0xA, 0x28); // Unlock MC Portal } -static void item_func_SNOWPEAK_PORTAL() { +void item_func_SNOWPEAK_PORTAL() { dComIfGs_onStageSwitch(0x8, 0x15); // Unlock Snowpeak Portal } -static void item_func_FOREST_MAP() { +void item_func_FOREST_MAP() { dComIfGs_onDungeonItemMap(0x10); } -static void item_func_MINES_MAP() { +void item_func_MINES_MAP() { dComIfGs_onDungeonItemMap(0x11); } -static void item_func_LAKEBED_MAP() { +void item_func_LAKEBED_MAP() { dComIfGs_onDungeonItemMap(0x12); } -static void item_func_ARBITERS_MAP() { +void item_func_ARBITERS_MAP() { dComIfGs_onDungeonItemMap(0x13); } -static void item_func_SNOWPEAK_MAP() { +void item_func_SNOWPEAK_MAP() { dComIfGs_onDungeonItemMap(0x14); } -static void item_func_TEMPLE_OF_TIME_MAP() { +void item_func_TEMPLE_OF_TIME_MAP() { dComIfGs_onDungeonItemMap(0x15); } -static void item_func_CITY_MAP() { +void item_func_CITY_MAP() { dComIfGs_onDungeonItemMap(0x16); } -static void item_func_PALACE_MAP() { +void item_func_PALACE_MAP() { dComIfGs_onDungeonItemMap(0x17); } -static void item_func_HYRULE_MAP() { +void item_func_HYRULE_MAP() { dComIfGs_onDungeonItemMap(0x18); } -static void item_func_SACRED_GROVE_PORTAL() { +void item_func_SACRED_GROVE_PORTAL() { dComIfGs_onStageSwitch(0x7, 0x64); // Unlock Grove Portal } -static void item_func_FUSED_SHADOW_1() { +void item_func_FUSED_SHADOW_1() { dComIfGs_onCollectCrystal(0); /* Adding rando code until framework is implemented @@ -242,7 +243,7 @@ static void item_func_FUSED_SHADOW_1() { */ } -static void item_func_FUSED_SHADOW_2() { +void item_func_FUSED_SHADOW_2() { dComIfGs_onCollectCrystal(1); /* Adding rando code until framework is implemented @@ -254,7 +255,7 @@ static void item_func_FUSED_SHADOW_2() { */ } -static void item_func_FUSED_SHADOW_3() { +void item_func_FUSED_SHADOW_3() { dComIfGs_onCollectCrystal(2); /* Adding rando code until framework is implemented @@ -272,150 +273,272 @@ static void item_func_FUSED_SHADOW_3() { */ } -static void item_func_MIRROR_PIECE_1() { +void item_func_MIRROR_PIECE_1() { dComIfGs_onCollectMirror(0); } -static void item_func_ENDING_BLOW() { +void item_func_ENDING_BLOW() { dComIfGs_onEventBit(0x2904); } -static void item_func_SHIELD_ATTACK() { +void item_func_SHIELD_ATTACK() { dComIfGs_onEventBit(0x2908); } -static void item_func_BACK_SLICE() { +void item_func_BACK_SLICE() { dComIfGs_onEventBit(0x2902); } -static void item_func_HELM_SPLITTER() { +void item_func_HELM_SPLITTER() { dComIfGs_onEventBit(0x2901); } -static void item_func_MORTAL_DRAW() { +void item_func_MORTAL_DRAW() { dComIfGs_onEventBit(0x2A80); } -static void item_func_JUMP_STRIKE() { +void item_func_JUMP_STRIKE() { dComIfGs_onEventBit(0x2A40); } -static void item_func_GREAT_SPIN() { +void item_func_GREAT_SPIN() { dComIfGs_onEventBit(0x2A20); } -static void item_func_ELDIN_BRIDGE_PORTAL() { +void item_func_ELDIN_BRIDGE_PORTAL() { dComIfGs_onStageSwitch(0x6, 0x63); // Unlock Eldin Bridge Portal } -static int item_getcheck_func_ORDON_PORTAL() { +int item_getcheck_func_ORDON_PORTAL() { return dComIfGs_isStageSwitch(0x0, 0x34); // Unlock Ordon Portal } -static int item_getcheck_func_SOUTH_FARON_PORTAL() { +int item_getcheck_func_SOUTH_FARON_PORTAL() { return dComIfGs_isStageSwitch(0x2, 0x47); // Unlock S Faron Portal } -static int item_getcheck_func_UPPER_ZORAS_RIVER_PORTAL() { +int item_getcheck_func_UPPER_ZORAS_RIVER_PORTAL() { return dComIfGs_isStageSwitch(0x4, 0x15); // Unlock UZR Portal } -static int item_getcheck_func_CASTLE_TOWN_PORTAL() { +int item_getcheck_func_CASTLE_TOWN_PORTAL() { return dComIfGs_isStageSwitch(0x6, 0x3); // Unlock Castle Town Portal } -static int item_getcheck_func_GERUDO_DESERT_PORTAL() { +int item_getcheck_func_GERUDO_DESERT_PORTAL() { return dComIfGs_isStageSwitch(0xA, 0x15); // Unlock Desert Portal } -static int item_getcheck_func_NORTH_FARON_PORTAL() { +int item_getcheck_func_NORTH_FARON_PORTAL() { return dComIfGs_isStageSwitch(0x2, 0x2); // Unlock N Faron Portal } -static int item_getcheck_func_KAKARIKO_GORGE_PORTAL() { +int item_getcheck_func_KAKARIKO_GORGE_PORTAL() { return dComIfGs_isStageSwitch(0x6, 0x15); // Unlock Gorge Portal } -static int item_getcheck_func_KAKARIKO_VILLAGE_PORTAL() { +int item_getcheck_func_KAKARIKO_VILLAGE_PORTAL() { return dComIfGs_isStageSwitch(0x3, 0x1F); // Unlock Kak Portal } -static int item_getcheck_func_DEATH_MOUNTAIN_PORTAL() { +int item_getcheck_func_DEATH_MOUNTAIN_PORTAL() { return dComIfGs_isStageSwitch(0x3, 0x15); // Unlock DM Portal } -static int item_getcheck_func_ZORAS_DOMAIN_PORTAL() { +int item_getcheck_func_ZORAS_DOMAIN_PORTAL() { return dComIfGs_isStageSwitch(0x4, 0x2); // Unlock ZD Portal } -static int item_getcheck_func_CAMP_SMALL_KEY() { +int item_getcheck_func_CAMP_SMALL_KEY() { return dComIfGs_isItemFirstBit(dItemNo_Randomizer_CAMP_SMALL_KEY_e); } -static int item_getcheck_func_LAKE_HYLIA_PORTAL() { +int item_getcheck_func_LAKE_HYLIA_PORTAL() { return dComIfGs_isStageSwitch(0x4, 0xA); // Unlock Lake Portal } -static int item_getcheck_func_MIRROR_CHAMBER_PORTAL() { +int item_getcheck_func_MIRROR_CHAMBER_PORTAL() { return dComIfGs_isStageSwitch(0xA, 0x28); // Unlock MC Portal } -static int item_getcheck_func_SNOWPEAK_PORTAL() { +int item_getcheck_func_SNOWPEAK_PORTAL() { return dComIfGs_isStageSwitch(0x8, 0x15); // Unlock Snowpeak Portal } -static int item_getcheck_func_SACRED_GROVE_PORTAL() { +int item_getcheck_func_SACRED_GROVE_PORTAL() { return dComIfGs_isStageSwitch(0x7, 0x64); // Unlock Grove Portal } -static int item_getcheck_func_FUSED_SHADOW_1() { +int item_getcheck_func_FUSED_SHADOW_1() { return dComIfGs_isItemFirstBit(dItemNo_Randomizer_FUSED_SHADOW_1_e); } -static int item_getcheck_func_FUSED_SHADOW_2() { +int item_getcheck_func_FUSED_SHADOW_2() { return dComIfGs_isItemFirstBit(dItemNo_Randomizer_FUSED_SHADOW_2_e); } -static int item_getcheck_func_FUSED_SHADOW_3() { +int item_getcheck_func_FUSED_SHADOW_3() { return dComIfGs_isItemFirstBit(dItemNo_Randomizer_FUSED_SHADOW_3_e); } -static int item_getcheck_func_MIRROR_PIECE_1() { +int item_getcheck_func_MIRROR_PIECE_1() { return dComIfGs_isItemFirstBit(dItemNo_Randomizer_MIRROR_PIECE_1_e); } -static int item_getcheck_func_ENDING_BLOW() { +int item_getcheck_func_ENDING_BLOW() { return dComIfGs_isItemFirstBit(dItemNo_Randomizer_ENDING_BLOW_e); } -static int item_getcheck_func_SHIELD_ATTACK() { +int item_getcheck_func_SHIELD_ATTACK() { return dComIfGs_isItemFirstBit(dItemNo_Randomizer_SHIELD_ATTACK_e); } -static int item_getcheck_func_BACK_SLICE() { +int item_getcheck_func_BACK_SLICE() { return dComIfGs_isItemFirstBit(dItemNo_Randomizer_BACK_SLICE_e); } -static int item_getcheck_func_HELM_SPLITTER() { +int item_getcheck_func_HELM_SPLITTER() { return dComIfGs_isItemFirstBit(dItemNo_Randomizer_HELM_SPLITTER_e); } -static int item_getcheck_func_MORTAL_DRAW() { +int item_getcheck_func_MORTAL_DRAW() { return dComIfGs_isItemFirstBit(dItemNo_Randomizer_MORTAL_DRAW_e); } -static int item_getcheck_func_JUMP_STRIKE() { +int item_getcheck_func_JUMP_STRIKE() { return dComIfGs_isItemFirstBit(dItemNo_Randomizer_JUMP_STRIKE_e); } -static int item_getcheck_func_GREAT_SPIN() { +int item_getcheck_func_GREAT_SPIN() { return dComIfGs_isItemFirstBit(dItemNo_Randomizer_GREAT_SPIN_e); } -static int item_getcheck_func_ELDIN_BRIDGE_PORTAL() { +int item_getcheck_func_ELDIN_BRIDGE_PORTAL() { return dComIfGs_isStageSwitch(0x6, 0x63); // Unlock Eldin Bridge Portal } +void randomizer_item_func_MAGIC_LV1() { + dComIfGs_onEventBit(0xD04); // Can transform at will + dComIfGs_onEventBit(0x501); // Midna Charge Unlocked +} + +void randomizer_item_func_WOOD_STICK() { + dComIfGs_setCollectSword(COLLECT_WOODEN_SWORD); + dComIfGs_setSelectEquipSword(dItemNo_WOOD_STICK_e); +} + +void randomizer_item_func_COPY_ROD_2() { + dComIfGs_onEventBit(0x2580); // Power up dominion rod +} + +void randomizer_item_func_LETTER() { + if (dComIfGs_getItem(SLOT_21, true) != dItemNo_Randomizer_HORSE_FLUTE_e) + dComIfGs_setItem(SLOT_21, dItemNo_Randomizer_LETTER_e); +} + +void randomizer_item_func_BILL() { + if (dComIfGs_getItem(SLOT_21, true) != dItemNo_Randomizer_HORSE_FLUTE_e) + dComIfGs_setItem(SLOT_21, dItemNo_Randomizer_BILL_e); +} + +void randomizer_item_func_WOOD_STATUE() { + /* dSv_event_flag_c::F_283 - Hyrule Field - Get wood carving */ + dComIfGs_onEventBit(dSv_event_flag_c::saveBitLabels[283]); + if (dComIfGs_getItem(SLOT_21, true) != dItemNo_Randomizer_HORSE_FLUTE_e) + dComIfGs_setItem(SLOT_21, dItemNo_Randomizer_WOOD_STATUE_e); +} + +void randomizer_item_func_IRIAS_PENDANT() { + if (dComIfGs_getItem(SLOT_21, true) != dItemNo_Randomizer_HORSE_FLUTE_e) + dComIfGs_setItem(SLOT_21, dItemNo_Randomizer_IRIAS_PENDANT_e); +} + +void randomizer_item_func_HORSE_FLUTE() { + if (dComIfGs_getItem(SLOT_21, true) == dItemNo_Randomizer_NONE_e) + dComIfGs_setItem(SLOT_21, dItemNo_Randomizer_HORSE_FLUTE_e); +} + +void randomizer_item_func_RAFRELS_MEMO() { + dComIfGs_setItem(SLOT_7, dItemNo_Randomizer_RAFRELS_MEMO_e); +} + +void randomizer_item_func_ASHS_SCRIBBLING() { + if (!dComIfGs_isEventBit(0x3B80)) { // Got earring from Ralis + dComIfGs_setItem(SLOT_19, dItemNo_Randomizer_ASHS_SCRIBBLING_e); + } +} + +void randomizer_item_func_DROP_CONTAINER03() { + dComIfGs_onLightDropGetFlag(LANAYRU_VESSEL); + dComIfGs_onEventBit(0x1E80); // Malo Mart Fundraising Starts +} + +void randomizer_item_func_MIRROR_PIECE_2() { + dComIfGs_onCollectMirror(1); +} + +void randomizer_item_func_MIRROR_PIECE_3() { + dComIfGs_onCollectMirror(2); +} + +void randomizer_item_func_MIRROR_PIECE_4() { + dComIfGs_onCollectMirror(3); +} + +void randomizer_item_func_POU_SPIRIT() { + dComIfGs_addPohSpiritNum(); +} + +void randomizer_item_func_AIR_LETTER() { + u8 letterCount = getAncientDocumentNum(); + setAncientDocumentNum(letterCount + 1); +} + +void randomizer_item_func_ANCIENT_DOCUMENT2() { + dComIfGs_onEventBit(0x3B08); // Repaired Cannon at Lake + setAncientDocumentNum(6); +} + +void randomizer_item_func_SMALL_KEY2() { + dComIfGs_onStageSwitch(0x2, 0x14); // Unlock North Faron Gate +} + +void randomizer_item_func_BOSSRIDER_KEY() { + dComIfGs_onStageSwitch(0x3, 0x69); // Started Escort + dComIfGs_onStageSwitch(0x3, 0x65); // Followed Rutella to Graveyard + dComIfGs_onEventBit(0x840); // Started Zora Escort + dComIfGs_onEventBit(0x810); // Completed Zora Escort +} + +void randomizer_item_func_TOMATO_PUREE() { + dComIfGs_onEventBit(0x480); // Told Yeta about Pumpkin + dComIfGs_onEventBit(0x2); // Yeto put Pumpkin in Soup + dComIfGs_onEventBit(0x1440); // SPR Lobby Door Unlocked + dComIfGs_onStageSwitch(0x14, 0x12); // Unlock North Door +} + +void randomizer_item_func_TASTE() { + dComIfGs_onEventBit(0x120); // Told Yeta about Cheese + dComIfGs_onEventBit(0x1); // Yeto put Pumpkin in Soup + dComIfGs_onEventBit(0x1420); // SPR Lobby west Door Unlocked + dComIfGs_onStageSwitch(0x14, 0x13); // Unlock West Door +} + +void randomizer_item_func_LV5_BOSS_KEY() { + dComIfGs_onDungeonItemBossKey(0x14); +} + +void randomizer_item_func_LV2_BOSS_KEY() { + dComIfGs_onDungeonItemBossKey(0x11); + execItemGet(dItemNo_Randomizer_L2_KEY_PIECES3_e); +} + +void randomizer_item_func_KEY_OF_FILONE() { + dComIfGs_onStageSwitch(0x2, 0xC); // Unlock Coro Gate +} + +} + static void (*item_func_ptr_randomizer[256])() = { /* 0x00 */ item_func_HEART, /* 0x01 */ item_func_GREEN_RUPEE, @@ -467,7 +590,7 @@ static void (*item_func_ptr_randomizer[256])() = { /* 0x2F */ item_func_WEAR_KOKIRI, /* 0x30 */ item_func_ARMOR, /* 0x31 */ item_func_WEAR_ZORA, - /* 0x32 */ item_func_MAGIC_LV1, + /* 0x32 */ randomizer_item_func_MAGIC_LV1, /* 0x33 */ item_func_DUNGEON_EXIT_2, /* 0x34 */ item_func_WALLET_LV1, /* 0x35 */ item_func_WALLET_LV2, @@ -480,7 +603,7 @@ static void (*item_func_ptr_randomizer[256])() = { /* 0x3C */ item_func_NORTH_FARON_PORTAL, /* 0x3D */ item_func_ZORAS_JEWEL, /* 0x3E */ item_func_HAWK_EYE, - /* 0x3F */ item_func_WOOD_STICK, + /* 0x3F */ randomizer_item_func_WOOD_STICK, /* 0x40 */ item_func_BOOMERANG, /* 0x41 */ item_func_SPINNER, /* 0x42 */ item_func_IRONBALL, @@ -493,7 +616,7 @@ static void (*item_func_ptr_randomizer[256])() = { /* 0x49 */ item_func_LIGHT_SWORD, /* 0x4A */ item_func_FISHING_ROD_1, /* 0x4B */ item_func_PACHINKO, - /* 0x4C */ item_func_COPY_ROD_2, + /* 0x4C */ randomizer_item_func_COPY_ROD_2, /* 0x4D */ item_func_KAKARIKO_GORGE_PORTAL, /* 0x4E */ item_func_KAKARIKO_VILLAGE_PORTAL, /* 0x4F */ item_func_BOMB_BAG_LV2, @@ -545,11 +668,11 @@ static void (*item_func_ptr_randomizer[256])() = { /* 0x7D */ item_func_LV1_SOUP, /* 0x7E */ item_func_LV2_SOUP, /* 0x7F */ item_func_LV3_SOUP, - /* 0x80 */ item_func_LETTER, - /* 0x81 */ item_func_BILL, - /* 0x82 */ item_func_WOOD_STATUE, - /* 0x83 */ item_func_IRIAS_PENDANT, - /* 0x84 */ item_func_HORSE_FLUTE, + /* 0x80 */ randomizer_item_func_LETTER, + /* 0x81 */ randomizer_item_func_BILL, + /* 0x82 */ randomizer_item_func_WOOD_STATUE, + /* 0x83 */ randomizer_item_func_IRIAS_PENDANT, + /* 0x84 */ randomizer_item_func_HORSE_FLUTE, /* 0x85 */ item_func_FOREST_SMALL_KEY, /* 0x86 */ item_func_MINES_SMALL_KEY, /* 0x87 */ item_func_LAKEBED_SMALL_KEY, @@ -561,8 +684,8 @@ static void (*item_func_ptr_randomizer[256])() = { /* 0x8D */ item_func_HYRULE_SMALL_KEY, /* 0x8E */ item_func_CAMP_SMALL_KEY, /* 0x8F */ item_func_LAKE_HYLIA_PORTAL, - /* 0x90 */ item_func_RAFRELS_MEMO, - /* 0x91 */ item_func_ASHS_SCRIBBLING, + /* 0x90 */ randomizer_item_func_RAFRELS_MEMO, + /* 0x91 */ randomizer_item_func_ASHS_SCRIBBLING, /* 0x92 */ item_func_FOREST_BOSS_KEY, /* 0x93 */ item_func_LAKEBED_BOSS_KEY, /* 0x94 */ item_func_ARBITERS_BOSS_KEY, @@ -580,11 +703,11 @@ static void (*item_func_ptr_randomizer[256])() = { /* 0xA0 */ item_func_LIGHT_DROP, /* 0xA1 */ item_func_DROP_CONTAINER, /* 0xA2 */ item_func_DROP_CONTAINER02, - /* 0xA3 */ item_func_DROP_CONTAINER03, + /* 0xA3 */ randomizer_item_func_DROP_CONTAINER03, /* 0xA4 */ item_func_FILLED_CONTAINER, - /* 0xA5 */ item_func_MIRROR_PIECE_2, - /* 0xA6 */ item_func_MIRROR_PIECE_3, - /* 0xA7 */ item_func_MIRROR_PIECE_4, + /* 0xA5 */ randomizer_item_func_MIRROR_PIECE_2, + /* 0xA6 */ randomizer_item_func_MIRROR_PIECE_3, + /* 0xA7 */ randomizer_item_func_MIRROR_PIECE_4, /* 0xA8 */ item_func_ARBITERS_COMPASS, /* 0xA9 */ item_func_SNOWPEAK_COMPASS, /* 0xAA */ item_func_TEMPLE_OF_TIME_COMPASS, @@ -641,7 +764,7 @@ static void (*item_func_ptr_randomizer[256])() = { /* 0xDD */ item_func_noentry, /* 0xDE */ item_func_noentry, /* 0xDF */ item_func_noentry, - /* 0xE0 */ item_func_POU_SPIRIT, + /* 0xE0 */ randomizer_item_func_POU_SPIRIT, /* 0xE1 */ item_func_ENDING_BLOW, /* 0xE2 */ item_func_SHIELD_ATTACK, /* 0xE3 */ item_func_BACK_SLICE, @@ -651,30 +774,81 @@ static void (*item_func_ptr_randomizer[256])() = { /* 0xE7 */ item_func_GREAT_SPIN, /* 0xE8 */ item_func_ELDIN_BRIDGE_PORTAL, /* 0xE9 */ item_func_ANCIENT_DOCUMENT, - /* 0xEA */ item_func_AIR_LETTER, - /* 0xEB */ item_func_ANCIENT_DOCUMENT2, + /* 0xEA */ randomizer_item_func_AIR_LETTER, + /* 0xEB */ randomizer_item_func_ANCIENT_DOCUMENT2, /* 0xEC */ item_func_LV7_DUNGEON_EXIT, /* 0xED */ item_func_LINKS_SAVINGS, - /* 0xEE */ item_func_SMALL_KEY2, + /* 0xEE */ randomizer_item_func_SMALL_KEY2, /* 0xEF */ item_func_POU_FIRE1, /* 0xF0 */ item_func_POU_FIRE2, /* 0xF1 */ item_func_POU_FIRE3, /* 0xF2 */ item_func_POU_FIRE4, - /* 0xF3 */ item_func_BOSSRIDER_KEY, - /* 0xF4 */ item_func_TOMATO_PUREE, - /* 0xF5 */ item_func_TASTE, - /* 0xF6 */ item_func_LV5_BOSS_KEY, + /* 0xF3 */ randomizer_item_func_BOSSRIDER_KEY, + /* 0xF4 */ randomizer_item_func_TOMATO_PUREE, + /* 0xF5 */ randomizer_item_func_TASTE, + /* 0xF6 */ randomizer_item_func_LV5_BOSS_KEY, /* 0xF7 */ item_func_SURFBOARD, /* 0xF8 */ item_func_KANTERA2, /* 0xF9 */ item_func_L2_KEY_PIECES1, /* 0xFA */ item_func_L2_KEY_PIECES2, /* 0xFB */ item_func_L2_KEY_PIECES3, /* 0xFC */ item_func_KEY_OF_CARAVAN, - /* 0xFD */ item_func_LV2_BOSS_KEY, - /* 0xFE */ item_func_KEY_OF_FILONE, + /* 0xFD */ randomizer_item_func_LV2_BOSS_KEY, + /* 0xFE */ randomizer_item_func_KEY_OF_FILONE, /* 0xFF */ item_func_noentry, }; +namespace { +int randomizer_item_getcheck_func_MAGIC_LV1() { + return dComIfGs_isItemFirstBit(dItemNo_Randomizer_MAGIC_LV1_e); +} + +int randomizer_item_getcheck_func_WALLET_LV2() { + return dComIfGs_isItemFirstBit(dItemNo_Randomizer_WALLET_LV2_e); +} + +int randomizer_item_getcheck_func_WALLET_LV3() { + return dComIfGs_isItemFirstBit(dItemNo_Randomizer_WALLET_LV3_e); +} + +int randomizer_item_getcheck_func_LETTER() { + return dComIfGs_isItemFirstBit(dItemNo_Randomizer_LETTER_e); +} + +int randomizer_item_getcheck_func_BILL() { + return dComIfGs_isItemFirstBit(dItemNo_Randomizer_BILL_e); +} + +int randomizer_item_getcheck_func_WOOD_STATUE() { + return dComIfGs_isItemFirstBit(dItemNo_Randomizer_WOOD_STATUE_e); +} + +int randomizer_item_getcheck_func_IRIAS_PENDANT() { + return dComIfGs_isItemFirstBit(dItemNo_Randomizer_IRIAS_PENDANT_e); +} + +int randomizer_item_getcheck_func_HORSE_FLUTE() { + return dComIfGs_isItemFirstBit(dItemNo_Randomizer_HORSE_FLUTE_e); +} + +int randomizer_item_getcheck_func_MIRROR_PIECE_2() { + return dComIfGs_isItemFirstBit(dItemNo_Randomizer_MIRROR_PIECE_2_e); +} + +int randomizer_item_getcheck_func_MIRROR_PIECE_3() { + return dComIfGs_isItemFirstBit(dItemNo_Randomizer_MIRROR_PIECE_3_e); +} + +int randomizer_item_getcheck_func_MIRROR_PIECE_4() { + return dComIfGs_isItemFirstBit(dItemNo_Randomizer_MIRROR_PIECE_4_e); +} + +int randomizer_item_getcheck_func_BOSSRIDER_KEY() { + return dComIfGs_isItemFirstBit(dItemNo_Randomizer_BOSSRIDER_KEY_e); +} + +} + static int (*item_getcheck_func_ptr_randomizer[256])() = { /* 0x00 */ item_getcheck_func_HEART, /* 0x01 */ item_getcheck_func_GREEN_RUPEE, @@ -726,11 +900,11 @@ static int (*item_getcheck_func_ptr_randomizer[256])() = { /* 0x2F */ item_getcheck_func_WEAR_KOKIRI, /* 0x30 */ item_getcheck_func_ARMOR, /* 0x31 */ item_getcheck_func_WEAR_ZORA, - /* 0x32 */ item_getcheck_func_MAGIC_LV1, + /* 0x32 */ randomizer_item_getcheck_func_MAGIC_LV1, /* 0x33 */ item_getcheck_func_DUNGEON_EXIT_2, /* 0x34 */ item_getcheck_func_WALLET_LV1, - /* 0x35 */ item_getcheck_func_WALLET_LV2, - /* 0x36 */ item_getcheck_func_WALLET_LV3, + /* 0x35 */ randomizer_item_getcheck_func_WALLET_LV2, + /* 0x36 */ randomizer_item_getcheck_func_WALLET_LV3, /* 0x37 */ item_getcheck_func_noentry, /* 0x38 */ item_getcheck_func_noentry, /* 0x39 */ item_getcheck_func_UPPER_ZORAS_RIVER_PORTAL, @@ -804,11 +978,11 @@ static int (*item_getcheck_func_ptr_randomizer[256])() = { /* 0x7D */ item_getcheck_func_LV1_SOUP, /* 0x7E */ item_getcheck_func_LV2_SOUP, /* 0x7F */ item_getcheck_func_LV3_SOUP, - /* 0x80 */ item_getcheck_func_LETTER, - /* 0x81 */ item_getcheck_func_BILL, - /* 0x82 */ item_getcheck_func_WOOD_STATUE, - /* 0x83 */ item_getcheck_func_IRIAS_PENDANT, - /* 0x84 */ item_getcheck_func_HORSE_FLUTE, + /* 0x80 */ randomizer_item_getcheck_func_LETTER, + /* 0x81 */ randomizer_item_getcheck_func_BILL, + /* 0x82 */ randomizer_item_getcheck_func_WOOD_STATUE, + /* 0x83 */ randomizer_item_getcheck_func_IRIAS_PENDANT, + /* 0x84 */ randomizer_item_getcheck_func_HORSE_FLUTE, /* 0x85 */ item_getcheck_func_noentry, /* 0x86 */ item_getcheck_func_noentry, /* 0x87 */ item_getcheck_func_noentry, @@ -841,9 +1015,9 @@ static int (*item_getcheck_func_ptr_randomizer[256])() = { /* 0xA2 */ item_getcheck_func_DROP_CONTAINER02, /* 0xA3 */ item_getcheck_func_DROP_CONTAINER03, /* 0xA4 */ item_getcheck_func_FILLED_CONTAINER, - /* 0xA5 */ item_getcheck_func_MIRROR_PIECE_2, - /* 0xA6 */ item_getcheck_func_MIRROR_PIECE_3, - /* 0xA7 */ item_getcheck_func_MIRROR_PIECE_4, + /* 0xA5 */ randomizer_item_getcheck_func_MIRROR_PIECE_2, + /* 0xA6 */ randomizer_item_getcheck_func_MIRROR_PIECE_3, + /* 0xA7 */ randomizer_item_getcheck_func_MIRROR_PIECE_4, /* 0xA8 */ item_getcheck_func_noentry, /* 0xA9 */ item_getcheck_func_noentry, /* 0xAA */ item_getcheck_func_noentry, @@ -919,7 +1093,7 @@ static int (*item_getcheck_func_ptr_randomizer[256])() = { /* 0xF0 */ item_getcheck_func_POU_FIRE2, /* 0xF1 */ item_getcheck_func_POU_FIRE3, /* 0xF2 */ item_getcheck_func_POU_FIRE4, - /* 0xF3 */ item_getcheck_func_BOSSRIDER_KEY, + /* 0xF3 */ randomizer_item_getcheck_func_BOSSRIDER_KEY, /* 0xF4 */ item_getcheck_func_TOMATO_PUREE, /* 0xF5 */ item_getcheck_func_TASTE, /* 0xF6 */ item_getcheck_func_LV5_BOSS_KEY, diff --git a/mods/randomizer/src/randomizer_context.cpp b/mods/randomizer/src/randomizer_context.cpp index 55edcd5ab9..25d60b29f2 100644 --- a/mods/randomizer/src/randomizer_context.cpp +++ b/mods/randomizer/src/randomizer_context.cpp @@ -867,17 +867,17 @@ void randomizer_checkAndOverrideEntranceData(const char*& stageName, s8& roomNo, // Debugging: Dump mEntranceOverrides // for (const auto& [key,val] : randomizer_GetContext().mEntranceOverrides) { - // mods::log::debug("({},{},{},{}) -> ({},{},{},{})",key.stageId,key.roomNo,key.mapLayer,key.pointNo,val.stageId,val.roomNo,val.mapLayer,val.pointNo); + // mods::log::info("({},{},{},{}) -> ({},{},{},{})",key.stageId,key.roomNo,key.mapLayer,key.pointNo,val.stageId,val.roomNo,val.mapLayer,val.pointNo); // } - // mods::log::debug("Original Stage:{}, {}, {}, {}",stageName,roomNo,pointNo,mapLayer); + // mods::log::info("Original Stage:{}, {}, {}, {}",stageName,roomNo,pointNo,mapLayer); if (randomizer_GetContext().mEntranceOverrides.contains(override)) { auto& newOverride = randomizer_GetContext().mEntranceOverrides[override]; stageName = allStages[newOverride.stageId]; pointNo = newOverride.pointNo; roomNo = newOverride.roomNo; mapLayer = newOverride.mapLayer; - // mods::log::debug("New Stage:{}, {}, {}, {}",stageName,roomNo,pointNo,mapLayer); + // mods::log::info("New Stage:{}, {}, {}, {}",stageName,roomNo,pointNo,mapLayer); } } @@ -1751,7 +1751,6 @@ RandomizerContext WriteSeedData(randomizer::logic::world::World* world) { } // Apply entrance randomization - auto shuffleData = LOAD_EMBED_YAML(RANDO_DATA_PATH "entrance_shuffle_data.yaml"); if (world->AnyEntranceRandomizerEnabled()) { for (const auto& entrance : world->GetShuffledEntrances()) { randomizer::logic::entrance::Entrance* replacesEntrance = entrance->GetReplaces(); @@ -1762,9 +1761,9 @@ RandomizerContext WriteSeedData(randomizer::logic::world::World* world) { } randoData.mEntranceOverrides[forward] = replaces; - // Set an override for the second door, if the entrance is coupled - if (entrance->getCoupledDoor() != -1) { - RandomizerContext::EntranceOverride coupled = {.stageId = entrance->GetStageId(), .roomNo = entrance->GetRoomNo(), .mapLayer = entrance->GetLayerNo(), .pointNo = entrance->getCoupledDoor()}; + // Set overrides for all coupled entrances + for (const auto& point : entrance->getCoupledEntrances()) { + RandomizerContext::EntranceOverride coupled = {.stageId = entrance->GetStageId(), .roomNo = entrance->GetRoomNo(), .mapLayer = entrance->GetLayerNo(), .pointNo = point}; randoData.mEntranceOverrides[coupled] = replaces; } } diff --git a/mods/randomizer/src/session.cpp b/mods/randomizer/src/session.cpp index dc5c74218f..ee88e8dca9 100644 --- a/mods/randomizer/src/session.cpp +++ b/mods/randomizer/src/session.cpp @@ -300,7 +300,7 @@ void registerStartingLocation() { return; } - // Check that we aren't playing only with the setting "Mirror Chamber Access") == "Closed" + // Check that we aren't playing only with the setting Mirror Chamber Access set to Closed bool isExclusivelyMirrorChamber = false; const auto& mirrorChamberIt = ctx.mEntranceOverrides.find(RandomizerContext::EntranceOverride{ .stageId = StageIDs::Mirror_Chamber, @@ -323,20 +323,10 @@ void registerStartingLocation() { return; } - constexpr std::array kDungeonNames = { - "D_MN01","D_MN04","D_MN05","D_MN06","D_MN07","D_MN08","D_MN09","D_MN10","D_MN11" - }; - dSv_player_return_place_c& returnPlace = dComIfGs_getSaveData()->mPlayer.getPlayerReturnPlace(); - bool isDungeon = false; - for (const auto& name : kDungeonNames) { - if (returnPlace.getName() == name) { - isDungeon = true; - break; - } - } - - if (isDungeon) { + + // If we are loading into a dungeon, preserve our original return place + if (std::string(returnPlace.getName()).find("D_MN") == 0) { // Force-set the entrance without the override g_dComIfG_gameInfo.play.mNextStage.getStartStage()->set(returnPlace.getName(), returnPlace.getRoomNo(), returnPlace.mPlayerStatus, -1); return; @@ -344,7 +334,6 @@ void registerStartingLocation() { // Set the spawn to outside of link's house, which will get overrided later if we are replacing it returnPlace.set("F_SP103",1,1); - // g_dComIfG_gameInfo.play.mNextStage.getStartStage()->set("F_SP103", 1, 1, -1); dComIfGp_setNextStage("F_SP103", 1, 1, -1); } @@ -383,6 +372,11 @@ void onSaveLoaded(ModContext*, uint32_t, void*) { loadAncientDocumentNum(); } +void onSaveWritten(ModContext*, uint32_t, void*) { + const std::string hash = randomizer_GetContext().mHash; + svc_mng.save->set_blob(svc_mng.mod_ctx, kSeedHashBlobName, hash.data(), hash.size()); +} + ModResult initialize(const ServiceManager& services) { svc_mng = services; @@ -390,7 +384,7 @@ ModResult initialize(const ServiceManager& services) { svc_mng.mod_ctx, onNewSave, onSaveLoaded, - nullptr, + onSaveWritten, nullptr, &s_save_observer); if (rt != MOD_OK) { diff --git a/mods/randomizer/src/ui/rando_config.cpp b/mods/randomizer/src/ui/rando_config.cpp index d4b7d85a95..9b8a17c8a9 100644 --- a/mods/randomizer/src/ui/rando_config.cpp +++ b/mods/randomizer/src/ui/rando_config.cpp @@ -264,9 +264,11 @@ ModResult buildSeedManagementTab(ModContext* ctx, UiWindowHandle, UiElementHandl add_string_input(leftPane, "Seed String", "Current value of the seed used by the randomizer for generation. Leave blank for a random value.", - 32, + 31, [](ModContext*, void*, UiControlValue* out_value) { - out_value->string_value = GetRandomizerConfig().GetSeed().c_str(); + static char buffer[32]; + strncpy(buffer,GetRandomizerConfig().GetSeed().c_str(),31); + out_value->string_value = buffer; }, [](ModContext*, void*, const UiControlValue* value) { GetRandomizerConfig().SetSeed(value->string_value); diff --git a/mods/randomizer/src/ui/rando_config.hpp b/mods/randomizer/src/ui/rando_config.hpp index b3c8dedcb7..1e086931cf 100644 --- a/mods/randomizer/src/ui/rando_config.hpp +++ b/mods/randomizer/src/ui/rando_config.hpp @@ -16,8 +16,6 @@ namespace randomizer::ui { enum dialogSelectModeState : uint8_t { SelectReady, SelectWait, - SelectVanilla, - SelectRandomizer }; extern dialogSelectModeState g_dialogSelectModeState; diff --git a/mods/shadow_mod/src/mod.cpp b/mods/shadow_mod/src/mod.cpp index 36f33de41d..fa4056040b 100644 --- a/mods/shadow_mod/src/mod.cpp +++ b/mods/shadow_mod/src/mod.cpp @@ -20,12 +20,12 @@ #include "dolphin/gx/GXPixel.h" #include "dolphin/gx/GXTransform.h" #include "m_Do/m_Do_mtx.h" -#include "mods/svc/hook.hpp" #include "mods/service.hpp" #include "mods/svc/camera.h" #include "mods/svc/config.h" #include "mods/svc/gfx.h" #include "mods/svc/hook.h" +#include "mods/svc/hook.hpp" #include "mods/svc/log.h" #include "mods/svc/resource.h" #include "mods/svc/ui.h" @@ -69,6 +69,7 @@ GfxStageHookHandle g_frameBeforeHudHook = 0; UiWindowHandle g_controlsWindow = 0; ResourceBuffer g_shaderSource = RESOURCE_BUFFER_INIT; GfxDeviceInfo g_deviceInfo = GFX_DEVICE_INFO_INIT; +GfxRenderTargetLayout g_sceneTargetLayout = GFX_RENDER_TARGET_LAYOUT_INIT; WGPURenderPipeline g_compositePipeline = nullptr; // multiply blend WGPURenderPipeline g_compositeDebugPipeline = nullptr; // no blend (debug views) WGPUBindGroupLayout g_compositeLayout = nullptr; @@ -399,18 +400,16 @@ bool build_composite_pipeline( .srcFactor = WGPUBlendFactor_Zero, .dstFactor = WGPUBlendFactor_One}, }; - WGPUColorTargetState colorTarget = WGPU_COLOR_TARGET_STATE_INIT; - colorTarget.format = g_deviceInfo.color_format; - if (blend) { - colorTarget.blend = &blendState; - } + WGPUColorTargetState colorTargets[GFX_MAX_COLOR_ATTACHMENTS]; + const uint32_t colorTargetCount = gfx_init_color_target_states( + &g_sceneTargetLayout, colorTargets, blend ? &blendState : nullptr, WGPUColorWriteMask_All); WGPUFragmentState fragment = WGPU_FRAGMENT_STATE_INIT; fragment.module = module; fragment.entryPoint = {"fs_main", WGPU_STRLEN}; - fragment.targetCount = 1; - fragment.targets = &colorTarget; + fragment.targetCount = colorTargetCount; + fragment.targets = colorTargets; WGPUDepthStencilState depthStencil = WGPU_DEPTH_STENCIL_STATE_INIT; - depthStencil.format = g_deviceInfo.depth_format; + depthStencil.format = g_sceneTargetLayout.depth_stencil_format; depthStencil.depthWriteEnabled = WGPUOptionalBool_False; depthStencil.depthCompare = WGPUCompareFunction_Always; @@ -420,7 +419,7 @@ bool build_composite_pipeline( pipelineDesc.vertex.entryPoint = {"vs_main", WGPU_STRLEN}; pipelineDesc.primitive.topology = WGPUPrimitiveTopology_TriangleList; pipelineDesc.depthStencil = &depthStencil; - pipelineDesc.multisample.count = g_deviceInfo.sample_count; + pipelineDesc.multisample.count = g_sceneTargetLayout.sample_count; pipelineDesc.fragment = &fragment; outPipeline = wgpuDeviceCreateRenderPipeline(g_deviceInfo.device, &pipelineDesc); wgpuShaderModuleRelease(module); @@ -518,7 +517,7 @@ WGPUBindGroup create_composite_bind_group(WGPUDevice device, WGPUBindGroupLayout // Render worker thread: fullscreen deferred-shadow composite. void on_draw( ModContext*, const GfxDrawContext* ctx, const void* payload, size_t payloadSize, void*) { - if (payloadSize != sizeof(DrawPayload)) { + if (payloadSize != sizeof(DrawPayload) || ctx->layout.key != g_sceneTargetLayout.key) { return; } DrawPayload data; @@ -1243,6 +1242,9 @@ MOD_EXPORT ModResult mod_initialize(ModError* error) { if (svc_gfx->get_device_info(mod_ctx, &g_deviceInfo) != MOD_OK) { return mods::set_error(error, MOD_ERROR, "failed to query device info"); } + if (svc_gfx->get_scene_target_layout(mod_ctx, &g_sceneTargetLayout) != MOD_OK) { + return mods::set_error(error, MOD_ERROR, "failed to query scene target layout"); + } if (!build_composite_pipeline(true, g_compositePipeline, g_compositeLayout) || !build_composite_pipeline(false, g_compositeDebugPipeline, g_compositeDebugLayout)) { diff --git a/mods/window_demo/src/mod.cpp b/mods/window_demo/src/mod.cpp index fb3cc31809..00d6f1240b 100644 --- a/mods/window_demo/src/mod.cpp +++ b/mods/window_demo/src/mod.cpp @@ -189,12 +189,6 @@ MOD_EXPORT ModResult mod_initialize(ModError* error) { return mods::set_error(error, MOD_ERROR, "failed to register mod panel"); } - if (open_window() != MOD_OK) { - svc_gfx->unregister_stage_hook(mod_ctx, g_stageHook); - g_stageHook = 0; - return mods::set_error(error, MOD_ERROR, "failed to open auxiliary window"); - } - mods::log::info("auxiliary WebGPU window ready"); return MOD_OK; } diff --git a/sdk/include/mods/svc/gfx.h b/sdk/include/mods/svc/gfx.h index 5041c611e3..0eee026984 100644 --- a/sdk/include/mods/svc/gfx.h +++ b/sdk/include/mods/svc/gfx.h @@ -33,10 +33,68 @@ #define GFX_SERVICE_ID "dev.twilitrealm.dusklight.gfx" #define GFX_SERVICE_MAJOR 1u -#define GFX_SERVICE_MINOR 1u +#define GFX_SERVICE_MINOR 2u /* Maximum size for push_draw payload */ #define GFX_INLINE_DRAW_PAYLOAD_SIZE 128u +#define GFX_MAX_COLOR_ATTACHMENTS 8u +#define GFX_SCENE_COLOR_ATTACHMENT_INDEX 0u + +typedef enum GfxAttachmentSemantic { + GFX_ATTACHMENT_SCENE_COLOR, + GFX_ATTACHMENT_NORMAL, + GFX_ATTACHMENT_AUXILIARY, +} GfxAttachmentSemantic; + +typedef struct GfxColorAttachmentLayout { + GfxAttachmentSemantic semantic; + WGPUTextureFormat format; + uint32_t width; + uint32_t height; +} GfxColorAttachmentLayout; + +typedef struct GfxRenderTargetLayout { + uint32_t struct_size; + uint64_t key; + /* At least one; scene color is at GFX_SCENE_COLOR_ATTACHMENT_INDEX. */ + uint32_t color_attachment_count; + GfxColorAttachmentLayout color_attachments[GFX_MAX_COLOR_ATTACHMENTS]; + WGPUTextureFormat depth_stencil_format; + uint32_t sample_count; +} GfxRenderTargetLayout; + +#define GFX_RENDER_TARGET_LAYOUT_INIT \ + {sizeof(GfxRenderTargetLayout), 0u, 0u, \ + {{GFX_ATTACHMENT_AUXILIARY, WGPUTextureFormat_Undefined}}, WGPUTextureFormat_Undefined, \ + 1u} + +/* + * Initializes pipeline color targets for a render-target layout. Only scene color is writable; + * callers that write another semantic should override that target afterward. + */ +static uint32_t gfx_init_color_target_states(const GfxRenderTargetLayout* layout, + WGPUColorTargetState targets[GFX_MAX_COLOR_ATTACHMENTS], const WGPUBlendState* scene_blend, + WGPUColorWriteMask scene_write_mask) { + if (layout == NULL || targets == NULL) { + return 0; + } + const uint32_t count = layout->color_attachment_count < GFX_MAX_COLOR_ATTACHMENTS ? + layout->color_attachment_count : + GFX_MAX_COLOR_ATTACHMENTS; + for (uint32_t i = 0; i < GFX_MAX_COLOR_ATTACHMENTS; ++i) { + WGPUColorTargetState target = WGPU_COLOR_TARGET_STATE_INIT; + if (i < count) { + target.format = layout->color_attachments[i].format; + target.writeMask = WGPUColorWriteMask_None; + } + targets[i] = target; + } + if (count != 0) { + targets[GFX_SCENE_COLOR_ATTACHMENT_INDEX].blend = scene_blend; + targets[GFX_SCENE_COLOR_ATTACHMENT_INDEX].writeMask = scene_write_mask; + } + return count; +} /* 0 is never a valid handle. */ typedef uint64_t GfxDrawTypeHandle; @@ -51,8 +109,8 @@ typedef struct GfxRange { } GfxRange; /* - * Device and scene pass configuration. Valid from mod_initialize onward and stable for the - * session. Offscreen passes from create_pass are always single-sample. + * Device and legacy primary scene-pass configuration. Use get_scene_target_layout when creating + * scene pipelines. Offscreen passes from create_pass are always single-sample. */ typedef struct GfxDeviceInfo { uint32_t struct_size; @@ -83,12 +141,18 @@ typedef struct GfxDrawContext { WGPUBuffer index_buffer; WGPUBuffer uniform_buffer; WGPUBuffer storage_buffer; + /* deprecated: use layout.color_attachments[GFX_SCENE_COLOR_ATTACHMENT_INDEX].format */ WGPUTextureFormat color_format; + /* deprecated: use layout.depth_stencil_format */ WGPUTextureFormat depth_format; + /* deprecated: use layout.sample_count */ uint32_t sample_count; + /* deprecated: use layout.color_attachments[GFX_SCENE_COLOR_ATTACHMENT_INDEX].width */ uint32_t target_width; + /* deprecated: use layout.color_attachments[GFX_SCENE_COLOR_ATTACHMENT_INDEX].height */ uint32_t target_height; bool uses_reversed_z; + GfxRenderTargetLayout layout; /* added in GfxService 1.2 */ } GfxDrawContext; typedef void (*GfxDrawFn)(ModContext* ctx, const GfxDrawContext* draw_ctx, const void* payload, @@ -269,6 +333,10 @@ typedef struct GfxService { */ ModResult (*push_present)( ModContext* ctx, GfxPresentTargetHandle handle, const void* payload, size_t payload_size); + + /* Minor version 2 */ + + ModResult (*get_scene_target_layout)(ModContext* ctx, GfxRenderTargetLayout* out_layout); } GfxService; MOD_DECLARE_SERVICE(GfxService, svc_gfx, GFX_SERVICE_ID, GFX_SERVICE_MAJOR, GFX_SERVICE_MINOR); diff --git a/src/Z2AudioLib/Z2SeqMgr.cpp b/src/Z2AudioLib/Z2SeqMgr.cpp index a3e45d8acd..0658f7eb54 100644 --- a/src/Z2AudioLib/Z2SeqMgr.cpp +++ b/src/Z2AudioLib/Z2SeqMgr.cpp @@ -11,7 +11,10 @@ #include "Z2AudioLib/SpotName.h" #include "os_report.h" +#if TARGET_PC #include "dusk/audio.h" +#include "dusk/version.hpp" +#endif Z2SeqMgr::Z2SeqMgr() : JASGlobalInstance(true) { mMainBgmMaster.forceIn(); @@ -584,7 +587,7 @@ void Z2SeqMgr::bgmStreamPlay() { } #if !PLATFORM_SHIELD - else if (getStreamBgmID() == 0x2000000) { + else if (getStreamBgmID() == 0x2000000 IF_DUSK(&& dusk::version::isGcn())) { if (mStreamBgmHandle) { mStreamBgmHandle->stop(); } diff --git a/src/d/actor/d_a_mant.cpp b/src/d/actor/d_a_mant.cpp index 449efcd672..cc83028b9c 100644 --- a/src/d/actor/d_a_mant.cpp +++ b/src/d/actor/d_a_mant.cpp @@ -15,12 +15,50 @@ #include "dusk/dvd_asset.hpp" #include "dusk/frame_interpolation.h" -using GameVersion = dusk::version::GameVersion; +#include + +using namespace dusk::version; + +#define MANT_REL_PATH platformSelect("/rel/Final/Release/d_a_mant.rel", "/rel/Rfinal/Release/d_a_mant.rel") + +#define DEFINE_MANT_ASSET(name, type, count, ...) \ + static type* name##_get() { \ + alignas(32) static std::remove_cv_t buf[count]; \ + static bool _ = (dusk::LoadRelAsset(buf, MANT_REL_PATH, __VA_ARGS__), true); \ + return buf; \ + } // keep the original version of the cape texture const so we don't need to reload the file -static u8 const * l_Egnd_mantTEX_get() { alignas(32) static u8 buf[0x4000]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0x1C00}, {GameVersion::GcnPal, 0x1C00}, {GameVersion::GcnJpn, 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", {{GameVersion::GcnUsa, 0x5C00}, {GameVersion::GcnPal, 0x5C00}, {GameVersion::GcnJpn, 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", {{GameVersion::GcnUsa, 0x9C00}, {GameVersion::GcnPal, 0x9C00}, {GameVersion::GcnJpn, 0x9C00}}, 0x60), true); return buf; } +DEFINE_MANT_ASSET(l_Egnd_mantTEX, u8 const, 0x4000, { + {GameVersion::GcnUsa, 0x1C00}, + {GameVersion::GcnPal, 0x1C00}, + {GameVersion::GcnJpn, 0x1C00}, + {GameVersion::WiiUsaRev0, 0x1B00}, + {GameVersion::WiiUsa, 0x1900}, + {GameVersion::WiiPal, 0x1900}, + {GameVersion::WiiJpn, 0x1900}, +}); + +DEFINE_MANT_ASSET(l_Egnd_mantTEX_U, u8, 0x4000, { + {GameVersion::GcnUsa, 0x5C00}, + {GameVersion::GcnPal, 0x5C00}, + {GameVersion::GcnJpn, 0x5C00}, + {GameVersion::WiiUsaRev0, 0x5B00}, + {GameVersion::WiiUsa, 0x5900}, + {GameVersion::WiiPal, 0x5900}, + {GameVersion::WiiJpn, 0x5900}, +}); + +DEFINE_MANT_ASSET(l_Egnd_mantPAL, u8, 0x60, { + {GameVersion::GcnUsa, 0x9C00}, + {GameVersion::GcnPal, 0x9C00}, + {GameVersion::GcnJpn, 0x9C00}, + {GameVersion::WiiUsaRev0, 0x9B00}, + {GameVersion::WiiUsa, 0x9900}, + {GameVersion::WiiPal, 0x9900}, + {GameVersion::WiiJpn, 0x9900}, +}); + #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()) @@ -35,14 +73,39 @@ static TGXTexObj mainTexObj; static TGXTexObj undersideTexObj; // l_pos is unused -//static f32* l_pos_get() { alignas(32) static f32 buf[507]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0xA44C}, {GameVersion::GcnPal, 0xA44C}}, sizeof(buf)), true); return buf; } -static f32* l_normal_get() { alignas(32) static f32 buf[3]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0x9C60}, {GameVersion::GcnPal, 0x9C60}, {GameVersion::GcnJpn, 0x9C60}}, sizeof(buf)), true); return buf; } -static f32* l_texCoord_get() { alignas(32) static f32 buf[338]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0xA458}, {GameVersion::GcnPal, 0xA458}, {GameVersion::GcnJpn, 0xA458}}, sizeof(buf)), true); return buf; } -//#define l_pos (l_pos_get()) -#define l_normal (l_normal_get()) +// DEFINE_MANT_ASSET(l_pos, f32, 507, { +// {GameVersion::GcnUsa, 0x9C60}, +// {GameVersion::GcnPal, 0x9C60}, +// }); + +alignas(32) static f32 const l_normal[3] = {0.0f, 1.0f, 0.0f}; + +DEFINE_MANT_ASSET(l_texCoord, f32, 338, { + {GameVersion::GcnUsa, 0xA458}, + {GameVersion::GcnPal, 0xA458}, + {GameVersion::GcnJpn, 0xA458}, + {GameVersion::WiiUsaRev0, 0x9B60}, + {GameVersion::WiiUsa, 0x9960}, + {GameVersion::WiiPal, 0x9960}, + {GameVersion::WiiJpn, 0x9960}, +}); + +// #define l_pos (l_pos_get()) #define l_texCoord (l_texCoord_get()) static bool l_Egnd_mantTEX_hasReplacement = false; + +DEFINE_MANT_ASSET(l_Egnd_mantDL, u8, 0x3EC, { + {GameVersion::GcnUsa, 0xA9A0}, + {GameVersion::GcnPal, 0xA9A0}, + {GameVersion::GcnJpn, 0xA9A0}, + {GameVersion::WiiUsaRev0, 0xA0C0}, + {GameVersion::WiiUsa, 0x9EC0}, + {GameVersion::WiiPal, 0x9EC0}, + {GameVersion::WiiJpn, 0x9EC0}, +}); + +#define l_Egnd_mantDL (l_Egnd_mantDL_get()) #else #include "assets/l_Egnd_mantTEX.h" @@ -52,16 +115,9 @@ static bool l_Egnd_mantTEX_hasReplacement = false; #endif #include "d/d_s_play.h" -#if TARGET_PC -using GameVersion = dusk::version::GameVersion; - -static u8* l_Egnd_mantDL_get() { alignas(32) static u8 buf[0x3EC]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0xA9A0}, {GameVersion::GcnPal, 0xA9A0}, {GameVersion::GcnJpn, 0xA9A0}}, 0x3EC), true); return buf; } -#define l_Egnd_mantDL (l_Egnd_mantDL_get()) -#else -#include "assets/l_Egnd_mantDL.h" -#endif - #if !TARGET_PC +#include "assets/l_Egnd_mantDL.h" + static void* pal_d = (void*)&l_Egnd_mantPAL; static void* tex_d[2] = { diff --git a/src/d/actor/d_a_player.cpp b/src/d/actor/d_a_player.cpp index 8ab70d8907..48ad37e2ec 100644 --- a/src/d/actor/d_a_player.cpp +++ b/src/d/actor/d_a_player.cpp @@ -375,10 +375,14 @@ static const u8* l_sightDL_get() { static bool _ = ( dusk::LoadDolAsset( buf, -{ - {GameVersion::GcnUsa, 0x803BA0C0}, - {GameVersion::GcnPal, 0x803BBDA0}, - {GameVersion::GcnJpn, 0x803B4220} + { + {GameVersion::GcnUsa, 0x803BA0C0}, + {GameVersion::GcnPal, 0x803BBDA0}, + {GameVersion::GcnJpn, 0x803B4220}, + {GameVersion::WiiUsaRev0, 0x803F63C0}, + {GameVersion::WiiUsa, 0x803E1640}, + {GameVersion::WiiPal, 0x803E23A0}, + {GameVersion::WiiJpn, 0x803DF600} }, 0x89 ), diff --git a/src/d/actor/d_a_title.cpp b/src/d/actor/d_a_title.cpp index 5ff7dad881..b9edd72fa1 100644 --- a/src/d/actor/d_a_title.cpp +++ b/src/d/actor/d_a_title.cpp @@ -52,7 +52,7 @@ static u8 const lit_3772[12] = { #if TARGET_PC using namespace dusk::version; -#define l_arcName versionSelect({{GameVersion::GcnPal, "TitlePal"}}, "Title") +#define l_arcName regionSelect("Title", "TitlePal", "Title") #elif VERSION == VERSION_GCN_PAL static char const l_arcName[] = "TitlePal"; #else diff --git a/src/d/actor/d_flower.inc b/src/d/actor/d_flower.inc index f8fe0bed10..9e3d77efd0 100644 --- a/src/d/actor/d_flower.inc +++ b/src/d/actor/d_flower.inc @@ -11,9 +11,16 @@ const u16 l_J_Ohana00_64TEX__width = 63; const u16 l_J_Ohana00_64TEX__height = 63; #if TARGET_PC -#include "dusk/dvd_asset.hpp" -using GameVersion = dusk::version::GameVersion; -static u8* l_J_Ohana00_64TEX_get() { static u8 buf[0x800]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x9060}, {GameVersion::GcnPal, 0x9060}, {GameVersion::GcnJpn, 0x9060}}, 0x800), true); return buf; } +DEFINE_GRASS_ASSET(l_J_Ohana00_64TEX, u8, 0x800, { + {GameVersion::GcnUsa, 0x9060}, + {GameVersion::GcnPal, 0x9060}, + {GameVersion::GcnJpn, 0x9060}, + {GameVersion::WiiUsaRev0, 0x7B60}, + {GameVersion::WiiUsa, 0x7BC0}, + {GameVersion::WiiPal, 0x7BC0}, + {GameVersion::WiiJpn, 0x7BC0}, +}); + #define l_J_Ohana00_64TEX (l_J_Ohana00_64TEX_get()) // from d_grass.inc @@ -115,12 +122,46 @@ static u8 l_flowerTexCoord[] = { 0x3E, 0xA7, 0x72, 0xD6, 0xBD, 0x2F, 0x46, 0xAA}; #if TARGET_PC -using GameVersion = dusk::version::GameVersion; +DEFINE_GRASS_ASSET(l_J_hana00DL, u8, 0x150, { + {GameVersion::GcnUsa, 0x9D20}, + {GameVersion::GcnPal, 0x9D20}, + {GameVersion::GcnJpn, 0x9D20}, + {GameVersion::WiiUsaRev0, 0x8820}, + {GameVersion::WiiUsa, 0x8880}, + {GameVersion::WiiPal, 0x8880}, + {GameVersion::WiiJpn, 0x8880}, +}); + +DEFINE_GRASS_ASSET(l_J_hana00_cDL, u8, 0xDE, { + {GameVersion::GcnUsa, 0x9E80}, + {GameVersion::GcnPal, 0x9E80}, + {GameVersion::GcnJpn, 0x9E80}, + {GameVersion::WiiUsaRev0, 0x8980}, + {GameVersion::WiiUsa, 0x89E0}, + {GameVersion::WiiPal, 0x89E0}, + {GameVersion::WiiJpn, 0x89E0}, +}); + +DEFINE_GRASS_ASSET(l_matDL, u8, 0x99, { + {GameVersion::GcnUsa, 0x9F60}, + {GameVersion::GcnPal, 0x9F60}, + {GameVersion::GcnJpn, 0x9F60}, + {GameVersion::WiiUsaRev0, 0x8A60}, + {GameVersion::WiiUsa, 0x8AC0}, + {GameVersion::WiiPal, 0x8AC0}, + {GameVersion::WiiJpn, 0x8AC0}, +}); + +DEFINE_GRASS_ASSET(l_matLight4DL, u8, 0x99, { + {GameVersion::GcnUsa, 0xA000}, + {GameVersion::GcnPal, 0xA000}, + {GameVersion::GcnJpn, 0xA000}, + {GameVersion::WiiUsaRev0, 0x8B00}, + {GameVersion::WiiUsa, 0x8B60}, + {GameVersion::WiiPal, 0x8B60}, + {GameVersion::WiiJpn, 0x8B60}, +}); -static u8* l_J_hana00DL_get() { static u8 buf[0x150]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x9D20}, {GameVersion::GcnPal, 0x9D20}, {GameVersion::GcnJpn, 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", {{GameVersion::GcnUsa, 0x9E80}, {GameVersion::GcnPal, 0x9E80}, {GameVersion::GcnJpn, 0x9E80}}, 0xDE), true); return buf; } -static u8* l_matDL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x9F60}, {GameVersion::GcnPal, 0x9F60}, {GameVersion::GcnJpn, 0x9F60}}, 0x99), true); return buf; } -static u8* l_matLight4DL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xA000}, {GameVersion::GcnPal, 0xA000}, {GameVersion::GcnJpn, 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()) @@ -141,8 +182,16 @@ const u16 l_J_Ohana01_64128_0419TEX__width = 63; const u16 l_J_Ohana01_64128_0419TEX__height = 127; #if TARGET_PC -using GameVersion = dusk::version::GameVersion; -static u8* l_J_Ohana01_64128_0419TEX_get() { static u8 buf[0x1000]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xA0A0}, {GameVersion::GcnPal, 0xA0A0}, {GameVersion::GcnJpn, 0xA0A0}}, 0x1000), true); return buf; } +DEFINE_GRASS_ASSET(l_J_Ohana01_64128_0419TEX, u8, 0x1000, { + {GameVersion::GcnUsa, 0xA0A0}, + {GameVersion::GcnPal, 0xA0A0}, + {GameVersion::GcnJpn, 0xA0A0}, + {GameVersion::WiiUsaRev0, 0x8BA0}, + {GameVersion::WiiUsa, 0x8C00}, + {GameVersion::WiiPal, 0x8C00}, + {GameVersion::WiiJpn, 0x8C00}, +}); + #define l_J_Ohana01_64128_0419TEX (l_J_Ohana01_64128_0419TEX_get()) #else #include "assets/l_J_Ohana01_64128_0419TEX.h" @@ -274,13 +323,56 @@ static u8 l_flowerTexCoord2[] = { 0x40, 0x1B, 0x7D, 0x52, 0x3F, 0x80, 0x3F, 0x79, 0x40, 0x1B, 0x7D, 0x52, 0x3F, 0x51, 0x10, 0x6F}; #if TARGET_PC -using GameVersion = dusk::version::GameVersion; +DEFINE_GRASS_ASSET(l_J_hana01DL, u8, 0x138, { + {GameVersion::GcnUsa, 0xB7C0}, + {GameVersion::GcnPal, 0xB7C0}, + {GameVersion::GcnJpn, 0xB7C0}, + {GameVersion::WiiUsaRev0, 0xA2C0}, + {GameVersion::WiiUsa, 0xA320}, + {GameVersion::WiiPal, 0xA320}, + {GameVersion::WiiJpn, 0xA320}, +}); + +DEFINE_GRASS_ASSET(l_J_hana01_c_00DL, u8, 0xDE, { + {GameVersion::GcnUsa, 0xB900}, + {GameVersion::GcnPal, 0xB900}, + {GameVersion::GcnJpn, 0xB900}, + {GameVersion::WiiUsaRev0, 0xA400}, + {GameVersion::WiiUsa, 0xA460}, + {GameVersion::WiiPal, 0xA460}, + {GameVersion::WiiJpn, 0xA460}, +}); + +DEFINE_GRASS_ASSET(l_J_hana01_c_01DL, u8, 0x128, { + {GameVersion::GcnUsa, 0xB9E0}, + {GameVersion::GcnPal, 0xB9E0}, + {GameVersion::GcnJpn, 0xB9E0}, + {GameVersion::WiiUsaRev0, 0xA4E0}, + {GameVersion::WiiUsa, 0xA540}, + {GameVersion::WiiPal, 0xA540}, + {GameVersion::WiiJpn, 0xA540}, +}); + +DEFINE_GRASS_ASSET(l_mat2DL, u8, 0x99, { + {GameVersion::GcnUsa, 0xBB20}, + {GameVersion::GcnPal, 0xBB20}, + {GameVersion::GcnJpn, 0xBB20}, + {GameVersion::WiiUsaRev0, 0xA620}, + {GameVersion::WiiUsa, 0xA680}, + {GameVersion::WiiPal, 0xA680}, + {GameVersion::WiiJpn, 0xA680}, +}); + +DEFINE_GRASS_ASSET(l_mat2Light4DL, u8, 0x99, { + {GameVersion::GcnUsa, 0xBBC0}, + {GameVersion::GcnPal, 0xBBC0}, + {GameVersion::GcnJpn, 0xBBC0}, + {GameVersion::WiiUsaRev0, 0xA6C0}, + {GameVersion::WiiUsa, 0xA720}, + {GameVersion::WiiPal, 0xA720}, + {GameVersion::WiiJpn, 0xA720}, +}); -static u8* l_J_hana01DL_get() { static u8 buf[0x138]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xB7C0}, {GameVersion::GcnPal, 0xB7C0}, {GameVersion::GcnJpn, 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", {{GameVersion::GcnUsa, 0xB900}, {GameVersion::GcnPal, 0xB900}, {GameVersion::GcnJpn, 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", {{GameVersion::GcnUsa, 0xB9E0}, {GameVersion::GcnPal, 0xB9E0}, {GameVersion::GcnJpn, 0xB9E0}}, 0x128), true); return buf; } -static u8* l_mat2DL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xBB20}, {GameVersion::GcnPal, 0xBB20}, {GameVersion::GcnJpn, 0xBB20}}, 0x99), true); return buf; } -static u8* l_mat2Light4DL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xBBC0}, {GameVersion::GcnPal, 0xBBC0}, {GameVersion::GcnJpn, 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()) diff --git a/src/d/actor/d_grass.inc b/src/d/actor/d_grass.inc index 2e20394620..6c7a898c56 100644 --- a/src/d/actor/d_grass.inc +++ b/src/d/actor/d_grass.inc @@ -21,8 +21,39 @@ const u16 l_M_kusa05_RGBATEX__height = 31; #if TARGET_PC #include "dusk/dvd_asset.hpp" using GameVersion = dusk::version::GameVersion; -static u8* l_M_kusa05_RGBATEX_get() { static u8 buf[0x800]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x7680}, {GameVersion::GcnPal, 0x7680}, {GameVersion::GcnJpn, 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", {{GameVersion::GcnUsa, 0x7E80}, {GameVersion::GcnPal, 0x7E80}, {GameVersion::GcnJpn, 0x7E80}}, 0x800), true); return buf; } + +template +static bool LoadGrassAsset(T (&dst)[N], std::initializer_list offset) { + return dusk::LoadArchivedRelAsset(dst, 'AMEM', "d_a_grass.rel", offset); +} + +#define DEFINE_GRASS_ASSET(name, type, count, ...) \ + static type* name##_get() { \ + static type buf[count]; \ + static bool _ = (LoadGrassAsset(buf, __VA_ARGS__), true); \ + return buf; \ + } + +DEFINE_GRASS_ASSET(l_M_kusa05_RGBATEX, u8, 0x800, { + {GameVersion::GcnUsa, 0x7680}, + {GameVersion::GcnPal, 0x7680}, + {GameVersion::GcnJpn, 0x7680}, + {GameVersion::WiiUsaRev0, 0x6180}, + {GameVersion::WiiUsa, 0x61E0}, + {GameVersion::WiiPal, 0x61E0}, + {GameVersion::WiiJpn, 0x61E0}, +}); + +DEFINE_GRASS_ASSET(l_M_Hijiki00TEX, u8, 0x800, { + {GameVersion::GcnUsa, 0x7E80}, + {GameVersion::GcnPal, 0x7E80}, + {GameVersion::GcnJpn, 0x7E80}, + {GameVersion::WiiUsaRev0, 0x6980}, + {GameVersion::WiiUsa, 0x69E0}, + {GameVersion::WiiPal, 0x69E0}, + {GameVersion::WiiJpn, 0x69E0}, +}); + #define l_M_kusa05_RGBATEX (l_M_kusa05_RGBATEX_get()) #define l_M_Hijiki00TEX (l_M_Hijiki00TEX_get()) #else @@ -114,14 +145,66 @@ static u8 l_texCoord[160] = { }; #if TARGET_PC -using GameVersion = dusk::version::GameVersion; +DEFINE_GRASS_ASSET(l_M_Kusa_9qDL, u8, 0xCB, { + {GameVersion::GcnUsa, 0x8B00}, + {GameVersion::GcnPal, 0x8B00}, + {GameVersion::GcnJpn, 0x8B00}, + {GameVersion::WiiUsaRev0, 0x7600}, + {GameVersion::WiiUsa, 0x7660}, + {GameVersion::WiiPal, 0x7660}, + {GameVersion::WiiJpn, 0x7660}, +}); + +DEFINE_GRASS_ASSET(l_M_Kusa_9q_cDL, u8, 0xCB, { + {GameVersion::GcnUsa, 0x8BE0}, + {GameVersion::GcnPal, 0x8BE0}, + {GameVersion::GcnJpn, 0x8BE0}, + {GameVersion::WiiUsaRev0, 0x76E0}, + {GameVersion::WiiUsa, 0x7740}, + {GameVersion::WiiPal, 0x7740}, + {GameVersion::WiiJpn, 0x7740}, +}); + +DEFINE_GRASS_ASSET(l_M_TenGusaDL, u8, 0xD4, { + {GameVersion::GcnUsa, 0x8CC0}, + {GameVersion::GcnPal, 0x8CC0}, + {GameVersion::GcnJpn, 0x8CC0}, + {GameVersion::WiiUsaRev0, 0x77C0}, + {GameVersion::WiiUsa, 0x7820}, + {GameVersion::WiiPal, 0x7820}, + {GameVersion::WiiJpn, 0x7820}, +}); + +DEFINE_GRASS_ASSET(l_Tengusa_matDL, u8, 0xA8, { + {GameVersion::GcnUsa, 0x8DA0}, + {GameVersion::GcnPal, 0x8DA0}, + {GameVersion::GcnJpn, 0x8DA0}, + {GameVersion::WiiUsaRev0, 0x78A0}, + {GameVersion::WiiUsa, 0x7900}, + {GameVersion::WiiPal, 0x7900}, + {GameVersion::WiiJpn, 0x7900}, +}); + +DEFINE_GRASS_ASSET(l_kusa9q_matDL, u8, 0xA8, { + {GameVersion::GcnUsa, 0x8E60}, + {GameVersion::GcnPal, 0x8E60}, + {GameVersion::GcnJpn, 0x8E60}, + {GameVersion::WiiUsaRev0, 0x7960}, + {GameVersion::WiiUsa, 0x79C0}, + {GameVersion::WiiPal, 0x79C0}, + {GameVersion::WiiJpn, 0x79C0}, +}); + +DEFINE_GRASS_ASSET(l_kusa9q_l4_matDL, u8, 0xA8, { + {GameVersion::GcnUsa, 0x8F20}, + {GameVersion::GcnPal, 0x8F20}, + {GameVersion::GcnJpn, 0x8F20}, + {GameVersion::WiiUsaRev0, 0x7A20}, + {GameVersion::WiiUsa, 0x7A80}, + {GameVersion::WiiPal, 0x7A80}, + {GameVersion::WiiJpn, 0x7A80}, +}); -static u8* l_M_Kusa_9qDL_get() { static u8 buf[0xCB]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8B00}, {GameVersion::GcnPal, 0x8B00}, {GameVersion::GcnJpn, 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", {{GameVersion::GcnUsa, 0x8BE0}, {GameVersion::GcnPal, 0x8BE0}, {GameVersion::GcnJpn, 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", {{GameVersion::GcnUsa, 0x8CC0}, {GameVersion::GcnPal, 0x8CC0}, {GameVersion::GcnJpn, 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", {{GameVersion::GcnUsa, 0x8DA0}, {GameVersion::GcnPal, 0x8DA0}, {GameVersion::GcnJpn, 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", {{GameVersion::GcnUsa, 0x8E60}, {GameVersion::GcnPal, 0x8E60}, {GameVersion::GcnJpn, 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", {{GameVersion::GcnUsa, 0x8F20}, {GameVersion::GcnPal, 0x8F20}, {GameVersion::GcnJpn, 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()) diff --git a/src/d/d_bright_check.cpp b/src/d/d_bright_check.cpp index cbea55100a..3d36e72232 100644 --- a/src/d/d_bright_check.cpp +++ b/src/d/d_bright_check.cpp @@ -83,7 +83,9 @@ void dBrightCheck_c::screenSet() { JUT_ASSERT(0, mBrightCheck.Scr != NULL); mBrightCheck.Scr->setPriority("zelda_option_check.blo", 0x1100000, mArchive); + IF_DUSK_BLOCK(dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) mBrightCheck.Scr->search(MULTI_CHAR('g_abtn_n'))->hide(); + IF_DUSK_BLOCK_END #if TARGET_PC J2DTextBox* settings_text; @@ -113,9 +115,11 @@ void dBrightCheck_c::screenSet() { J2DTextBox* btna_text[5]; for (int i = 0; i < 5; i++) { #if TARGET_PC - if (dusk::version::isRegionJpn()) { + if (dusk::version::isJpnOrLessThanWiiJpn()) { btna_text[i] = (J2DTextBox*)mBrightCheck.Scr->search(tv_btnA[i]); - mBrightCheck.Scr->search(ftv_btnA[i])->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mBrightCheck.Scr->search(ftv_btnA[i])->hide(); + } } else { btna_text[i] = (J2DTextBox*)mBrightCheck.Scr->search(ftv_btnA[i]); mBrightCheck.Scr->search(tv_btnA[i])->hide(); @@ -222,7 +226,9 @@ void dBrightCheck_c::brightCheckWide() { // 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); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + 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); diff --git a/src/d/d_menu_dmap.cpp b/src/d/d_menu_dmap.cpp index 6feb191562..4557edfb4c 100644 --- a/src/d/d_menu_dmap.cpp +++ b/src/d/d_menu_dmap.cpp @@ -363,13 +363,15 @@ void dMenu_DmapBg_c::buttonIconScreenInit() { for (int i = 0; i < 5; i++) { #if TARGET_PC - if (dusk::version::isRegionJpn()) { + if (dusk::version::isJpnOrLessThanWiiJpn()) { ((J2DTextBox*)mButtonScreen->search(cont_at[i]))->setFont(mDoExt_getMesgFont()); ((J2DTextBox*)mButtonScreen->search(cont_bt[i]))->setFont(mDoExt_getMesgFont()); ((J2DTextBox*)mButtonScreen->search(cont_at[i]))->setString(32, ""); ((J2DTextBox*)mButtonScreen->search(cont_bt[i]))->setString(32, ""); - ((J2DTextBox*)mButtonScreen->search(font_at[i]))->hide(); - ((J2DTextBox*)mButtonScreen->search(font_bt[i]))->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + ((J2DTextBox*)mButtonScreen->search(font_at[i]))->hide(); + ((J2DTextBox*)mButtonScreen->search(font_bt[i]))->hide(); + } } else { ((J2DTextBox*)mButtonScreen->search(font_at[i]))->setFont(mDoExt_getMesgFont()); ((J2DTextBox*)mButtonScreen->search(font_bt[i]))->setFont(mDoExt_getMesgFont()); @@ -400,7 +402,7 @@ void dMenu_DmapBg_c::buttonIconScreenInit() { J2DTextBox* textBox; for (int i = 0; i < 2; i++) { - textBox = ((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? c_tag_jpn[i] : c_tag[i], c_tag[i]))); + textBox = (J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? c_tag_jpn[i] : c_tag[i], c_tag[i])); textBox->setFont(mDoExt_getMesgFont()); textBox->setString(32, ""); } @@ -436,9 +438,9 @@ void dMenu_DmapBg_c::setAButtonString(u32 i_msgNo) { for (int i = 0; i < 5; i++) { if (i_msgNo == 0) { - SAFE_STRCPY(((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? cont_at_jpn[i] : cont_at[i], cont_at[i])))->getStringPtr(), ""); + SAFE_STRCPY(((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? cont_at_jpn[i] : cont_at[i], cont_at[i])))->getStringPtr(), ""); } else { - dMeter2Info_getStringKanji(i_msgNo, ((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? cont_at_jpn[i] : cont_at[i], cont_at[i])))->getStringPtr(), NULL); + dMeter2Info_getStringKanji(i_msgNo, ((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? cont_at_jpn[i] : cont_at[i], cont_at[i])))->getStringPtr(), NULL); } } } @@ -463,9 +465,9 @@ void dMenu_DmapBg_c::setBButtonString(u32 i_msgNo) { for (int i = 0; i < 5; i++) { if (i_msgNo == 0) { - SAFE_STRCPY(((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? cont_bt_jpn[i] : cont_bt[i], cont_bt[i])))->getStringPtr(), ""); + SAFE_STRCPY(((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? cont_bt_jpn[i] : cont_bt[i], cont_bt[i])))->getStringPtr(), ""); } else { - dMeter2Info_getStringKanji(i_msgNo, ((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? cont_bt_jpn[i] : cont_bt[i], cont_bt[i])))->getStringPtr(), NULL); + dMeter2Info_getStringKanji(i_msgNo, ((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? cont_bt_jpn[i] : cont_bt[i], cont_bt[i])))->getStringPtr(), NULL); } } } @@ -504,12 +506,12 @@ void dMenu_DmapBg_c::setCButtonString(u32 i_msgNo) { if (msgNo == 0) { for (i = 0; i < 2; i++) { - SAFE_STRCPY(((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? c_tag_jpn[i] : c_tag[i], c_tag[i])))->getStringPtr(), ""); + SAFE_STRCPY(((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? c_tag_jpn[i] : c_tag[i], c_tag[i])))->getStringPtr(), ""); } mpCButton->setAlphaRate(0.5f); } else { for (i = 0; i < 2; i++) { - dMeter2Info_getStringKanji(msgNo, ((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? c_tag_jpn[i] : c_tag[i], c_tag[i])))->getStringPtr(), NULL); + dMeter2Info_getStringKanji(msgNo, ((J2DTextBox*)mButtonScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? c_tag_jpn[i] : c_tag[i], c_tag[i])))->getStringPtr(), NULL); } mpCButton->setAlphaRate(1.0f); } @@ -979,8 +981,10 @@ void dMenu_DmapBg_c::dMapBgWide() { mButtonScreen->search(MULTI_CHAR('c_btn'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); mButtonScreen->search(MULTI_CHAR('c_text_s'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); mButtonScreen->search(MULTI_CHAR('c_text'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); - mButtonScreen->search(MULTI_CHAR('f_text_s'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); - mButtonScreen->search(MULTI_CHAR('f_text'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mButtonScreen->search(MULTI_CHAR('f_text_s'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mButtonScreen->search(MULTI_CHAR('f_text'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + } // Decorations mButtonScreen->search(MULTI_CHAR('kazari_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); diff --git a/src/d/d_menu_fishing.cpp b/src/d/d_menu_fishing.cpp index eb24852160..2579d328fb 100644 --- a/src/d/d_menu_fishing.cpp +++ b/src/d/d_menu_fishing.cpp @@ -343,7 +343,9 @@ void dMenu_Fishing_c::screenSetBase() { field_0x19c[1][i]->setString(0x20, ""); mpFishNameString[i] = (J2DTextBox*)mpScreen->search(name_0[i]); + IF_DUSK_BLOCK(dusk::version::isGcn()) mpScreen->search(fname_0[i])->hide(); + IF_DUSK_BLOCK_END mpFishNameString[i]->setFont(mDoExt_getSubFont()); mpFishNameString[i]->setString(0x20, ""); dMeter2Info_getStringKanji(name_id[i], mpFishNameString[i]->getStringPtr(), NULL); diff --git a/src/d/d_menu_fmap2D.cpp b/src/d/d_menu_fmap2D.cpp index 9d1d17ca0e..cd2e09c6d7 100644 --- a/src/d/d_menu_fmap2D.cpp +++ b/src/d/d_menu_fmap2D.cpp @@ -2420,10 +2420,12 @@ dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) { static const u64 farea_name[3] = {MULTI_CHAR('f_name_1'), MULTI_CHAR('f_name3'), MULTI_CHAR('f_name2')}; for (int i = 0; i < 3; i++) { #if TARGET_PC - if (dusk::version::isRegionJpn()) { + if (dusk::version::isJpnOrLessThanWiiJpn()) { static_cast(mpTitleScreen->search(area_name[i]))->setFont(mDoExt_getRubyFont()); static_cast(mpTitleScreen->search(area_name[i]))->setString(0x40, ""); - mpTitleScreen->search(farea_name[i])->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mpTitleScreen->search(farea_name[i])->hide(); + } } else { static_cast(mpTitleScreen->search(farea_name[i]))->setFont(mDoExt_getRubyFont()); static_cast(mpTitleScreen->search(farea_name[i]))->setString(0x40, ""); @@ -2458,10 +2460,12 @@ dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) { #endif for (int i = 0; i < 7; i++) { #if TARGET_PC - if (dusk::version::isRegionJpn()) { + if (dusk::version::isJpnOrLessThanWiiJpn()) { static_cast(mpTitleScreen->search(sfont_name[i]))->setFont(mDoExt_getRubyFont()); static_cast(mpTitleScreen->search(sfont_name[i]))->setString(0x40, ""); - mpTitleScreen->search(ffont_name[i])->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mpTitleScreen->search(ffont_name[i])->hide(); + } } else { static_cast(mpTitleScreen->search(ffont_name[i]))->setFont(mDoExt_getRubyFont()); static_cast(mpTitleScreen->search(ffont_name[i]))->setString(0x40, ""); @@ -2485,10 +2489,12 @@ dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) { static const u64 font_zt[5] = {MULTI_CHAR('font_zt1'), MULTI_CHAR('font_zt2'), MULTI_CHAR('font_zt3'), MULTI_CHAR('font_zt4'), MULTI_CHAR('font_zt5')}; for (int i = 0; i < 5; i++) { #if TARGET_PC - if (dusk::version::isRegionJpn()) { + if (dusk::version::isJpnOrLessThanWiiJpn()) { static_cast(mpTitleScreen->search(cont_zt[i]))->setFont(mDoExt_getMesgFont()); static_cast(mpTitleScreen->search(cont_zt[i]))->setString(0x20, ""); - mpTitleScreen->search(font_zt[i])->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mpTitleScreen->search(font_zt[i])->hide(); + } } else { static_cast(mpTitleScreen->search(font_zt[i]))->setFont(mDoExt_getMesgFont()); static_cast(mpTitleScreen->search(font_zt[i]))->setString(0x20, ""); @@ -2516,10 +2522,12 @@ dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) { #endif for (int i = 0; i < 5; i++) { #if TARGET_PC - if (dusk::version::isRegionJpn()) { + if (dusk::version::isJpnOrLessThanWiiJpn()) { static_cast(mpTitleScreen->search(cont_bt[i]))->setFont(mDoExt_getMesgFont()); static_cast(mpTitleScreen->search(cont_bt[i]))->setString(0x20, ""); - mpTitleScreen->search(font_bt[i])->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mpTitleScreen->search(font_bt[i])->hide(); + } } else { static_cast(mpTitleScreen->search(font_bt[i]))->setFont(mDoExt_getMesgFont()); static_cast(mpTitleScreen->search(font_bt[i]))->setString(0x20, ""); @@ -2543,10 +2551,12 @@ dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) { static const u64 font_at[5] = {MULTI_CHAR('font_at1'), MULTI_CHAR('font_at2'), MULTI_CHAR('font_at3'), MULTI_CHAR('font_at4'), MULTI_CHAR('font_at5')}; for (int i = 0; i < 5; i++) { #if TARGET_PC - if (dusk::version::isRegionJpn()) { + if (dusk::version::isJpnOrLessThanWiiJpn()) { static_cast(mpTitleScreen->search(cont_at[i]))->setFont(mDoExt_getMesgFont()); static_cast(mpTitleScreen->search(cont_at[i]))->setString(0x20, ""); - mpTitleScreen->search(font_at[i])->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mpTitleScreen->search(font_at[i])->hide(); + } } else { static_cast(mpTitleScreen->search(font_at[i]))->setFont(mDoExt_getMesgFont()); static_cast(mpTitleScreen->search(font_at[i]))->setString(0x20, ""); @@ -2571,10 +2581,12 @@ dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) { static const u64 fuji_c[5] = {MULTI_CHAR('fuji_c00'), MULTI_CHAR('fuji_c01'), MULTI_CHAR('fuji_c02'), MULTI_CHAR('fuji_c03'), MULTI_CHAR('fuji_c04')}; for (int i = 0; i < 5; i++) { #if TARGET_PC - if (dusk::version::isRegionJpn()) { + if (dusk::version::isJpnOrLessThanWiiJpn()) { static_cast(mpTitleScreen->search(juji_c[i]))->setFont(mDoExt_getMesgFont()); static_cast(mpTitleScreen->search(juji_c[i]))->setString(0x20, ""); - mpTitleScreen->search(fuji_c[i])->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mpTitleScreen->search(fuji_c[i])->hide(); + } } else { static_cast(mpTitleScreen->search(fuji_c[i]))->setFont(mDoExt_getMesgFont()); static_cast(mpTitleScreen->search(fuji_c[i]))->setString(0x20, ""); @@ -2598,10 +2610,12 @@ dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) { static const u64 fst_c[5] = {MULTI_CHAR('fst_00'), MULTI_CHAR('fst_01'), MULTI_CHAR('fst_02'), MULTI_CHAR('fst_03'), MULTI_CHAR('fst_04')}; for (int i = 0; i < 5; i++) { #if TARGET_PC - if (dusk::version::isRegionJpn()) { + if (dusk::version::isJpnOrLessThanWiiJpn()) { static_cast(mpTitleScreen->search(ast_c[i]))->setFont(mDoExt_getMesgFont()); static_cast(mpTitleScreen->search(ast_c[i]))->setString(0x20, ""); - mpTitleScreen->search(fst_c[i])->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mpTitleScreen->search(fst_c[i])->hide(); + } } else { static_cast(mpTitleScreen->search(fst_c[i]))->setFont(mDoExt_getMesgFont()); static_cast(mpTitleScreen->search(fst_c[i]))->setString(0x20, ""); @@ -2863,8 +2877,7 @@ void dMenu_Fmap2DTop_c::setTitleNameString(u32 param_0) { static const u64 ffont_name[7] = { MULTI_CHAR('ffont00'), MULTI_CHAR('ffontl0'), MULTI_CHAR('ffontl1'), MULTI_CHAR('ffontl2'), MULTI_CHAR('ffontb0'), MULTI_CHAR('ffontb3'), MULTI_CHAR('ffontb4') }; - - auto setTitleNameString_font_name = dusk::version::isRegionJpn() ? sfont_name : ffont_name; + auto setTitleNameString_font_name = dusk::version::isJpnOrLessThanWiiJpn() ? sfont_name : ffont_name; #elif VERSION == VERSION_GCN_JPN static const u64 sfont_name[7] = { MULTI_CHAR('sfont00'), MULTI_CHAR('sfontl0'), MULTI_CHAR('sfontl1'), MULTI_CHAR('sfontl2'), MULTI_CHAR('sfontb0'), MULTI_CHAR('sfontb1'), MULTI_CHAR('sfontb2') @@ -2883,15 +2896,9 @@ void dMenu_Fmap2DTop_c::setTitleNameString(u32 param_0) { #endif for (int i = 0; i < 7; i++) { if (param_0 == 0) { - SAFE_STRCPY(((J2DTextBox*)(mpTitleScreen->search(setTitleNameString_font_name[i]))) - ->getStringPtr(), - ""); + SAFE_STRCPY(((J2DTextBox*)(mpTitleScreen->search(setTitleNameString_font_name[i])))->getStringPtr(), ""); } else { - dMeter2Info_getStringKanji( - param_0, - ((J2DTextBox*)(mpTitleScreen->search(setTitleNameString_font_name[i]))) - ->getStringPtr(), - NULL); + dMeter2Info_getStringKanji(param_0, ((J2DTextBox*)(mpTitleScreen->search(setTitleNameString_font_name[i])))->getStringPtr(), NULL); } } } @@ -2900,7 +2907,7 @@ void dMenu_Fmap2DTop_c::setAreaNameString(u32 param_0) { #if TARGET_PC static const u64 iarea_name[3] = {MULTI_CHAR('i_name_s'), MULTI_CHAR('i_name'), MULTI_CHAR('i_name1')}; static const u64 farea_name[3] = {MULTI_CHAR('f_name_1'), MULTI_CHAR('f_name3'), MULTI_CHAR('f_name2')}; - auto setAreaNameString_area_name = dusk::version::isRegionJpn() ? iarea_name : farea_name; + auto setAreaNameString_area_name = dusk::version::isJpnOrLessThanWiiJpn() ? iarea_name : farea_name; #elif VERSION == VERSION_GCN_JPN static const u64 iarea_name[3] = {MULTI_CHAR('i_name_s'), MULTI_CHAR('i_name'), MULTI_CHAR('i_name1')}; #define setAreaNameString_area_name iarea_name @@ -2910,15 +2917,9 @@ void dMenu_Fmap2DTop_c::setAreaNameString(u32 param_0) { #endif for (int i = 0; i < 3; i++) { if (param_0 == 0) { - SAFE_STRCPY(((J2DTextBox*)(mpTitleScreen->search(setAreaNameString_area_name[i]))) - ->getStringPtr(), - ""); + SAFE_STRCPY(((J2DTextBox*)(mpTitleScreen->search(setAreaNameString_area_name[i])))->getStringPtr(), ""); } else { - dMeter2Info_getStringKanji( - param_0, - ((J2DTextBox*)(mpTitleScreen->search(setAreaNameString_area_name[i]))) - ->getStringPtr(), - NULL); + dMeter2Info_getStringKanji(param_0, ((J2DTextBox*)(mpTitleScreen->search(setAreaNameString_area_name[i])))->getStringPtr(), NULL); } } } @@ -2937,7 +2938,7 @@ void dMenu_Fmap2DTop_c::setZButtonString(u32 param_0, u8 i_alpha) { #if TARGET_PC static const u64 cont_zt[5] = {MULTI_CHAR('cont_zt'), MULTI_CHAR('cont_zt1'), MULTI_CHAR('cont_zt2'), MULTI_CHAR('cont_zt3'), MULTI_CHAR('cont_zt4')}; static const u64 font_zt[5] = {MULTI_CHAR('font_zt1'), MULTI_CHAR('font_zt2'), MULTI_CHAR('font_zt3'), MULTI_CHAR('font_zt4'), MULTI_CHAR('font_zt5')}; - auto setZButtonString_font_zt = dusk::version::isRegionJpn() ? cont_zt : font_zt; + auto setZButtonString_font_zt = dusk::version::isJpnOrLessThanWiiJpn() ? cont_zt : font_zt; #elif VERSION == VERSION_GCN_JPN static const u64 cont_zt[5] = {MULTI_CHAR('cont_zt'), MULTI_CHAR('cont_zt1'), MULTI_CHAR('cont_zt2'), MULTI_CHAR('cont_zt3'), MULTI_CHAR('cont_zt4')}; #define setZButtonString_font_zt cont_zt @@ -2953,10 +2954,7 @@ void dMenu_Fmap2DTop_c::setZButtonString(u32 param_0, u8 i_alpha) { #endif } else { for (int i = 0; i < 5; i++) { - dMeter2Info_getStringKanji( - param_0, - ((J2DTextBox*)(mpTitleScreen->search(setZButtonString_font_zt[i])))->getStringPtr(), - NULL); + dMeter2Info_getStringKanji(param_0, ((J2DTextBox*)(mpTitleScreen->search(setZButtonString_font_zt[i])))->getStringPtr(), NULL); } if (i_alpha == ALPHA_DEFAULT) { @@ -2975,7 +2973,7 @@ void dMenu_Fmap2DTop_c::setBButtonString(u32 param_0, u8 i_alpha) { #if TARGET_PC static const u64 cont_bt[5] = {MULTI_CHAR('cont_bt1'), MULTI_CHAR('cont_bt2'), MULTI_CHAR('cont_bt3'), MULTI_CHAR('cont_bt4'), MULTI_CHAR('cont_bt')}; static const u64 font_bt[5] = {MULTI_CHAR('font_bt1'), MULTI_CHAR('font_bt2'), MULTI_CHAR('font_bt3'), MULTI_CHAR('font_bt4'), MULTI_CHAR('font_bt5')}; - auto setBButtonString_font_bt = dusk::version::isRegionJpn() ? cont_bt : font_bt; + auto setBButtonString_font_bt = dusk::version::isJpnOrLessThanWiiJpn() ? cont_bt : font_bt; #elif VERSION == VERSION_GCN_JPN static const u64 cont_bt[5] = {MULTI_CHAR('cont_bt1'), MULTI_CHAR('cont_bt2'), MULTI_CHAR('cont_bt3'), MULTI_CHAR('cont_bt4'), MULTI_CHAR('cont_bt')}; #define setBButtonString_font_bt cont_bt @@ -2987,10 +2985,7 @@ void dMenu_Fmap2DTop_c::setBButtonString(u32 param_0, u8 i_alpha) { mAlphaButtonB = ALPHA_MIN; } else { for (int i = 0; i < 5; i++) { - dMeter2Info_getStringKanji( - param_0, - ((J2DTextBox*)(mpTitleScreen->search(setBButtonString_font_bt[i])))->getStringPtr(), - NULL); + dMeter2Info_getStringKanji(param_0, ((J2DTextBox*)(mpTitleScreen->search(setBButtonString_font_bt[i])))->getStringPtr(), NULL); } if (i_alpha == ALPHA_DEFAULT) { @@ -3005,7 +3000,7 @@ void dMenu_Fmap2DTop_c::setAButtonString(u32 param_0, u8 i_alpha) { #if TARGET_PC static const u64 cont_at[5] = {MULTI_CHAR('cont_at'), MULTI_CHAR('cont_at1'), MULTI_CHAR('cont_at2'), MULTI_CHAR('cont_at3'), MULTI_CHAR('cont_at4')}; static const u64 font_at[5] = {MULTI_CHAR('font_at1'), MULTI_CHAR('font_at2'), MULTI_CHAR('font_at3'), MULTI_CHAR('font_at4'), MULTI_CHAR('font_at5')}; - auto setAButtonString_font_at = dusk::version::isRegionJpn() ? cont_at : font_at; + auto setAButtonString_font_at = dusk::version::isJpnOrLessThanWiiJpn() ? cont_at : font_at; #elif VERSION == VERSION_GCN_JPN static const u64 cont_at[5] = {MULTI_CHAR('cont_at'), MULTI_CHAR('cont_at1'), MULTI_CHAR('cont_at2'), MULTI_CHAR('cont_at3'), MULTI_CHAR('cont_at4')}; #define setAButtonString_font_at cont_at @@ -3017,10 +3012,7 @@ void dMenu_Fmap2DTop_c::setAButtonString(u32 param_0, u8 i_alpha) { mAlphaButtonA = ALPHA_MIN; } else { for (int i = 0; i < 5; i++) { - dMeter2Info_getStringKanji( - param_0, - ((J2DTextBox*)(mpTitleScreen->search(setAButtonString_font_at[i])))->getStringPtr(), - NULL); + dMeter2Info_getStringKanji(param_0, ((J2DTextBox*)(mpTitleScreen->search(setAButtonString_font_at[i])))->getStringPtr(), NULL); } if (i_alpha == ALPHA_DEFAULT) { @@ -3034,8 +3026,8 @@ void dMenu_Fmap2DTop_c::setAButtonString(u32 param_0, u8 i_alpha) { void dMenu_Fmap2DTop_c::setCrossLRString(u32 param_0) { #if PLATFORM_GCN || (VERSION == VERSION_SHIELD) #if TARGET_PC - static const u64 juji_c_jpn[5] = {MULTI_CHAR('juji_c00'), MULTI_CHAR('juji_c01'), MULTI_CHAR('juji_c02'), MULTI_CHAR('juji_c03'), MULTI_CHAR('juji_c04')}; - static const u64 juji_c[5] = {MULTI_CHAR('fuji_c00'), MULTI_CHAR('fuji_c01'), MULTI_CHAR('fuji_c02'), MULTI_CHAR('fuji_c03'), MULTI_CHAR('fuji_c04')}; + static const u64 juji_c[5] = {MULTI_CHAR('juji_c00'), MULTI_CHAR('juji_c01'), MULTI_CHAR('juji_c02'), MULTI_CHAR('juji_c03'), MULTI_CHAR('juji_c04')}; + static const u64 fuji_c[5] = {MULTI_CHAR('fuji_c00'), MULTI_CHAR('fuji_c01'), MULTI_CHAR('fuji_c02'), MULTI_CHAR('fuji_c03'), MULTI_CHAR('fuji_c04')}; #elif VERSION == VERSION_GCN_JPN static const u64 juji_c[5] = {MULTI_CHAR('juji_c00'), MULTI_CHAR('juji_c01'), MULTI_CHAR('juji_c02'), MULTI_CHAR('juji_c03'), MULTI_CHAR('juji_c04')}; #else @@ -3043,14 +3035,14 @@ void dMenu_Fmap2DTop_c::setCrossLRString(u32 param_0) { #endif if (param_0 == 0) { for (int i = 0; i < 5; i++) { - J2DTextBox* text_box = static_cast(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? juji_c_jpn[i] : juji_c[i], juji_c[i]))); + J2DTextBox* text_box = static_cast(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? juji_c[i] : fuji_c[i], juji_c[i]))); SAFE_STRCPY(text_box->getStringPtr(), ""); } mpTitleScreen->search(MULTI_CHAR('juy_sha0'))->show(); mAlphaDpad = 1; } else { for (int i = 0; i < 5; i++) { - J2DTextBox* text_box = static_cast(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? juji_c_jpn[i] : juji_c[i], juji_c[i]))); + J2DTextBox* text_box = static_cast(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? juji_c[i] : fuji_c[i], juji_c[i]))); dMeter2Info_getStringKanji(param_0, text_box->getStringPtr(), NULL); } mpTitleScreen->search(MULTI_CHAR('juy_sha0'))->show(); @@ -3062,8 +3054,8 @@ void dMenu_Fmap2DTop_c::setCrossLRString(u32 param_0) { void dMenu_Fmap2DTop_c::set3DStickString(u32 param_0) { #if PLATFORM_GCN || (VERSION == VERSION_SHIELD) #if TARGET_PC - static const u64 ast_c_jpn[5] = {MULTI_CHAR('ast_00'), MULTI_CHAR('ast_01'), MULTI_CHAR('ast_02'), MULTI_CHAR('ast_03'), MULTI_CHAR('ast_04')}; - static const u64 ast_c[5] = {MULTI_CHAR('fst_00'), MULTI_CHAR('fst_01'), MULTI_CHAR('fst_02'), MULTI_CHAR('fst_03'), MULTI_CHAR('fst_04')}; + static const u64 ast_c[5] = {MULTI_CHAR('ast_00'), MULTI_CHAR('ast_01'), MULTI_CHAR('ast_02'), MULTI_CHAR('ast_03'), MULTI_CHAR('ast_04')}; + static const u64 fst_c[5] = {MULTI_CHAR('fst_00'), MULTI_CHAR('fst_01'), MULTI_CHAR('fst_02'), MULTI_CHAR('fst_03'), MULTI_CHAR('fst_04')}; #elif VERSION == VERSION_GCN_JPN static const u64 ast_c[5] = {MULTI_CHAR('ast_00'), MULTI_CHAR('ast_01'), MULTI_CHAR('ast_02'), MULTI_CHAR('ast_03'), MULTI_CHAR('ast_04')}; #else @@ -3071,14 +3063,14 @@ void dMenu_Fmap2DTop_c::set3DStickString(u32 param_0) { #endif if (param_0 == 0) { for (int i = 0; i < 5; i++) { - J2DTextBox* text_box = static_cast(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? ast_c_jpn[i] : ast_c[i], ast_c[i]))); + J2DTextBox* text_box = static_cast(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? ast_c[i] : fst_c[i], ast_c[i]))); SAFE_STRCPY(text_box->getStringPtr(), ""); } mpTitleScreen->search(MULTI_CHAR('as_sha0'))->show(); mAlphaAnalogStick = 1; } else { for (int i = 0; i < 5; i++) { - J2DTextBox* text_box = static_cast(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? ast_c_jpn[i] : ast_c[i], ast_c[i]))); + J2DTextBox* text_box = static_cast(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isJpnOrLessThanWiiJpn() ? ast_c[i] : fst_c[i], ast_c[i]))); dMeter2Info_getStringKanji(param_0, text_box->getStringPtr(), NULL); } mpTitleScreen->search(MULTI_CHAR('as_sha0'))->show(); diff --git a/src/d/d_menu_option.cpp b/src/d/d_menu_option.cpp index cb9af850c0..9d6f0816e2 100644 --- a/src/d/d_menu_option.cpp +++ b/src/d/d_menu_option.cpp @@ -73,6 +73,26 @@ static calibrationFunc calibration_process[] = { static dusk::menu_pointer::TargetId option_yes_no_target(u8 index) noexcept { return static_cast(0x100 + index); } + +static u8 option_to_proc(u8 select) noexcept { + if (!dusk::version::isRegionJpn() && select >= 1) { + return static_cast(select + 1); + } + return select; +} + +static u8 option_to_select(u8 proc) noexcept { + if (!dusk::version::isRegionJpn() && proc >= 2) { + return static_cast(proc - 1); + } + return proc; +} + +#define OPTION_SELECT(proc_e) (option_to_select(proc_e)) +#define OPTION_PROC(select) (option_to_proc(select)) +#else +#define OPTION_SELECT(proc_e) (proc_e) +#define OPTION_PROC(select) (select) #endif dMenu_Option_c::dMenu_Option_c(JKRArchive* i_archive, STControl* i_stick) { @@ -159,7 +179,9 @@ void dMenu_Option_c::_create() { mpTVButtonText = JKR_NEW CPaneMgr(mpTVScreen, MULTI_CHAR('a_text_n'), 0, NULL); JUT_ASSERT(298, mpTVButtonText != NULL); + IF_DUSK_BLOCK(dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) mpTVScreen->search(MULTI_CHAR('g_abtn_n'))->hide(); + IF_DUSK_BLOCK_END mpScreenIcon = JKR_NEW J2DScreen(); JUT_ASSERT(325, mpScreenIcon != NULL); @@ -257,11 +279,11 @@ void dMenu_Option_c::_create() { field_0x3e1 = 10; field_0x3e2 = 0xff; field_0x3e3 = 0xc0; - field_0x3ef = PROC_ATTEN_e; + field_0x3ef = OPTION_SELECT(PROC_ATTEN_e); field_0x3f0 = 0xff; field_0x3f1 = 0xff; field_0x3f2 = 0; - field_0x3f5 = PROC_ATTEN_e; + field_0x3f5 = OPTION_SELECT(PROC_ATTEN_e); field_0x3f3 = 5; field_0x3f4 = 5; field_0x334 = 0.0f; @@ -485,9 +507,9 @@ void dMenu_Option_c::_move() { } if (mDoGph_gInf_c::getFader()->getStatus() == 1) { - if (mDoCPd_c::getTrigA(PAD_1) != 0 && field_0x3ef != PROC_CHANGE_MOVE_e && field_0x3f3 == 5) { - if (field_0x3f4 == 5 && field_0x3ef != PROC_CONFIRM_OPEN_MOVE_e && field_0x3ef != PROC_CONFIRM_MOVE_MOVE_e && field_0x3ef != PROC_CONFIRM_SELECT_MOVE_e && - field_0x3ef != PROC_CONFIRM_CLOSE_MOVE_e) + if (mDoCPd_c::getTrigA(PAD_1) != 0 && field_0x3ef != OPTION_SELECT(PROC_CHANGE_MOVE_e) && field_0x3f3 == 5) { + if (field_0x3f4 == 5 && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_MOVE_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_SELECT_MOVE_e) && + field_0x3ef != OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e)) { if (mDoCPd_c::getTrigStart(PAD_1) == 0 && mDoCPd_c::getTrigB(PAD_1) == 0) { if (mDoCPd_c::getTrigUp(PAD_1) == 0 && mDoCPd_c::getTrigDown(PAD_1) == 0 && @@ -495,17 +517,17 @@ void dMenu_Option_c::_move() { { field_0x3f7 = 1; field_0x3f5 = field_0x3ef; - field_0x3ef = PROC_CONFIRM_OPEN_MOVE_e; + field_0x3ef = OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e); dMeter2Info_set2DVibration(); - (this->*init[field_0x3ef])(); + (this->*init[OPTION_PROC(field_0x3ef)])(); goto skip; } } } } - if (mDoCPd_c::getTrigB(PAD_1) != 0 && field_0x3ef != PROC_CHANGE_MOVE_e && field_0x3f3 == 5 && - field_0x3ef != PROC_CONFIRM_OPEN_MOVE_e && field_0x3ef != PROC_CONFIRM_MOVE_MOVE_e && field_0x3ef != PROC_CONFIRM_SELECT_MOVE_e && field_0x3ef != PROC_CONFIRM_CLOSE_MOVE_e) + if (mDoCPd_c::getTrigB(PAD_1) != 0 && field_0x3ef != OPTION_SELECT(PROC_CHANGE_MOVE_e) && field_0x3f3 == 5 && + field_0x3ef != OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_MOVE_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_SELECT_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e)) { if (field_0x3f4 == 5 && mDoCPd_c::getTrigStart(PAD_1) == 0 && mDoCPd_c::getTrigA(PAD_1) == 0 && mDoCPd_c::getTrigUp(PAD_1) == 0 && @@ -514,16 +536,16 @@ void dMenu_Option_c::_move() { { field_0x3f7 = 0; field_0x3f5 = field_0x3ef; - field_0x3ef = PROC_CONFIRM_OPEN_MOVE_e; + field_0x3ef = OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e); dMeter2Info_set2DVibration(); - (this->*init[field_0x3ef])(); + (this->*init[OPTION_PROC(field_0x3ef)])(); } } #if TARGET_PC - if (field_0x3f4 == 5 && field_0x3ef != PROC_CHANGE_MOVE_e && field_0x3f3 == 5 && - field_0x3ef != PROC_CONFIRM_OPEN_MOVE_e && field_0x3ef != PROC_CONFIRM_MOVE_MOVE_e && field_0x3ef != PROC_CONFIRM_SELECT_MOVE_e && - field_0x3ef != PROC_CONFIRM_CLOSE_MOVE_e && pointerConfirmSelect()) + if (field_0x3f4 == 5 && field_0x3ef != OPTION_SELECT(PROC_CHANGE_MOVE_e) && field_0x3f3 == 5 && + field_0x3ef != OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_MOVE_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_SELECT_MOVE_e) && + field_0x3ef != OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e) && pointerConfirmSelect()) { goto skip; } @@ -531,7 +553,7 @@ void dMenu_Option_c::_move() { } skip: u8 oldValue = field_0x3ef; - if (field_0x3f3 == 5 && oldValue != PROC_CONFIRM_OPEN_MOVE_e && oldValue != PROC_CONFIRM_MOVE_MOVE_e && oldValue != PROC_CONFIRM_SELECT_MOVE_e && oldValue != PROC_CONFIRM_CLOSE_MOVE_e) { + if (field_0x3f3 == 5 && oldValue != OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e) && oldValue != OPTION_SELECT(PROC_CONFIRM_MOVE_MOVE_e) && oldValue != OPTION_SELECT(PROC_CONFIRM_SELECT_MOVE_e) && oldValue != OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e)) { dpdMenuMove(); } @@ -545,10 +567,10 @@ skip: field_0x3f0 = 0xff; } - (this->*process[field_0x3ef])(); + (this->*process[OPTION_PROC(field_0x3ef)])(); mpSelectScreen->animation(); if (oldValue != field_0x3ef) { - (this->*init[field_0x3ef])(); + (this->*init[OPTION_PROC(field_0x3ef)])(); } setHIO(false); @@ -610,8 +632,8 @@ void dMenu_Option_c::drawHaihai() { field_0x3f6 = 0; field_0x3f6 |= 1; field_0x3f6 |= 4; - if (selectType < PROC_CONFIRM_OPEN_MOVE_e && field_0x3f6 != 0 && field_0x3f3 == 5 && field_0x3ef != PROC_CONFIRM_OPEN_MOVE_e && - field_0x3ef != PROC_CONFIRM_MOVE_MOVE_e && field_0x3ef != PROC_CONFIRM_SELECT_MOVE_e && field_0x3ef != PROC_CONFIRM_CLOSE_MOVE_e) + if (selectType < OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e) && field_0x3f6 != 0 && field_0x3f3 == 5 && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e) && + field_0x3ef != OPTION_SELECT(PROC_CONFIRM_MOVE_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_SELECT_MOVE_e) && field_0x3ef != OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e)) { mpMeterHaihai->_execute(0); Vec haihaiPosL = @@ -752,13 +774,7 @@ void dMenu_Option_c::atten_move() { if (field_0x3f3 != 5) { (this->*tv_process[field_0x3f3])(); } else if (downTrigger) { -#if TARGET_PC - field_0x3ef = dusk::version::isRegionJpn() ? PROC_RUBY_e : PROC_VIB_e; -#elif VERSION == VERSION_GCN_JPN - field_0x3ef = PROC_RUBY_e; -#else - field_0x3ef = PROC_VIB_e; -#endif + field_0x3ef = 1; Z2GetAudioMgr()->seStart(Z2SE_SY_CURSOR_OPTION, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); } else if (leftTrigger) { if (field_0x3e4 == 0) { @@ -768,8 +784,8 @@ void dMenu_Option_c::atten_move() { field_0x3e4 = 0; field_0x3da = -5; } - field_0x3ef = PROC_CHANGE_MOVE_e; - field_0x3f5 = PROC_ATTEN_e; + field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e); + field_0x3f5 = OPTION_SELECT(PROC_ATTEN_e); Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); } else if (rightTrigger) { if (field_0x3e4 == 0) { @@ -779,8 +795,8 @@ void dMenu_Option_c::atten_move() { field_0x3e4 = 0; field_0x3da = 5; } - field_0x3ef = PROC_CHANGE_MOVE_e; - field_0x3f5 = PROC_ATTEN_e; + field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e); + field_0x3f5 = OPTION_SELECT(PROC_ATTEN_e); Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); } else { changeTVCheck(); @@ -818,10 +834,10 @@ void dMenu_Option_c::ruby_move() { if (field_0x3f3 != 5) { (this->*tv_process[field_0x3f3])(); } else if (upTrigger) { - field_0x3ef = PROC_ATTEN_e; + field_0x3ef = OPTION_SELECT(PROC_ATTEN_e); Z2GetAudioMgr()->seStart(Z2SE_SY_CURSOR_OPTION, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); } else if (downTrigger) { - field_0x3ef = PROC_VIB_e; + field_0x3ef = OPTION_SELECT(PROC_VIB_e); Z2GetAudioMgr()->seStart(Z2SE_SY_CURSOR_OPTION, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); } else if (leftTrigger) { if (field_0x3e5_JPN == 0) { @@ -831,8 +847,8 @@ void dMenu_Option_c::ruby_move() { field_0x3e5_JPN = 0; field_0x3da = -5; } - field_0x3ef = PROC_CHANGE_MOVE_e; - field_0x3f5 = PROC_RUBY_e; + field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e); + field_0x3f5 = OPTION_SELECT(PROC_RUBY_e); Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); } else if (rightTrigger) { if (field_0x3e5_JPN == 0) { @@ -842,8 +858,8 @@ void dMenu_Option_c::ruby_move() { field_0x3e5_JPN = 0; field_0x3da = 5; } - field_0x3ef = PROC_CHANGE_MOVE_e; - field_0x3f5 = PROC_RUBY_e; + field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e); + field_0x3f5 = OPTION_SELECT(PROC_RUBY_e); Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); } else { changeTVCheck(); @@ -853,7 +869,7 @@ void dMenu_Option_c::ruby_move() { void dMenu_Option_c::vib_init() { mpDrawCursor->setAlphaRate(1.0f); - setCursorPos(PROC_VIB_e); + setCursorPos(OPTION_SELECT(PROC_VIB_e)); setAButtonString(0x40C); setBButtonString(0x3F9); } @@ -868,7 +884,7 @@ void dMenu_Option_c::vib_move() { (this->*tv_process[field_0x3f3])(); } else if (upTrigger) { #if TARGET_PC - field_0x3ef = dusk::version::isRegionJpn() ? PROC_RUBY_e : PROC_ATTEN_e; + field_0x3ef = OPTION_SELECT(dusk::version::isRegionJpn() ? PROC_RUBY_e : PROC_ATTEN_e); #elif VERSION == VERSION_GCN_JPN field_0x3ef = PROC_RUBY_e; #else @@ -876,7 +892,7 @@ void dMenu_Option_c::vib_move() { #endif Z2GetAudioMgr()->seStart(Z2SE_SY_CURSOR_OPTION, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); } else if (downTrigger) { - field_0x3ef = PROC_SOUND_e; + field_0x3ef = OPTION_SELECT(PROC_SOUND_e); Z2GetAudioMgr()->seStart(Z2SE_SY_CURSOR_OPTION, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); } else if (leftTrigger) { if (isRumbleSupported()) { @@ -888,8 +904,8 @@ void dMenu_Option_c::vib_move() { field_0x3ea = 0; field_0x3da = -5; } - field_0x3ef = PROC_CHANGE_MOVE_e; - field_0x3f5 = PROC_VIB_e; + field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e); + field_0x3f5 = OPTION_SELECT(PROC_VIB_e); Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); } @@ -903,8 +919,8 @@ void dMenu_Option_c::vib_move() { field_0x3ea = 0; field_0x3da = 5; } - field_0x3ef = PROC_CHANGE_MOVE_e; - field_0x3f5 = PROC_VIB_e; + field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e); + field_0x3f5 = OPTION_SELECT(PROC_VIB_e); Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); } @@ -915,7 +931,7 @@ void dMenu_Option_c::vib_move() { void dMenu_Option_c::sound_init() { mpDrawCursor->setAlphaRate(1.0f); - setCursorPos(PROC_SOUND_e); + setCursorPos(OPTION_SELECT(PROC_SOUND_e)); setAButtonString(0x40C); setBButtonString(0x3F9); } @@ -929,7 +945,7 @@ void dMenu_Option_c::sound_move() { if (field_0x3f3 != 5) { (this->*tv_process[field_0x3f3])(); } else if (upTrigger) { - field_0x3ef = PROC_VIB_e; + field_0x3ef = OPTION_SELECT(PROC_VIB_e); Z2GetAudioMgr()->seStart(Z2SE_SY_CURSOR_OPTION, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); } else if (leftTrigger) { if (field_0x3e9 == 2) { @@ -954,8 +970,8 @@ void dMenu_Option_c::sound_move() { } mDoAud_setOutputMode(dMo_soundMode[field_0x3e9]); setSoundMode(dMo_soundMode[field_0x3e9]); - field_0x3ef = PROC_CHANGE_MOVE_e; - field_0x3f5 = PROC_SOUND_e; + field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e); + field_0x3f5 = OPTION_SELECT(PROC_SOUND_e); Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); } else if (rightTrigger) { if (field_0x3e9 == 0) { @@ -980,8 +996,8 @@ void dMenu_Option_c::sound_move() { } mDoAud_setOutputMode(dMo_soundMode[field_0x3e9]); setSoundMode(dMo_soundMode[field_0x3e9]); - field_0x3ef = PROC_CHANGE_MOVE_e; - field_0x3f5 = PROC_SOUND_e; + field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e); + field_0x3f5 = OPTION_SELECT(PROC_SOUND_e); Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); } else { changeTVCheck(); @@ -1002,15 +1018,15 @@ void dMenu_Option_c::change_move() { field_0x3da++; } u8 index; - switch (field_0x3f5) { + switch (OPTION_PROC(field_0x3f5)) { case PROC_ATTEN_e: - index = PROC_ATTEN_e; + index = field_0x3f5; if (field_0x3da == 0) { setAttenString(); } break; case PROC_RUBY_e: - index = PROC_RUBY_e; + index = field_0x3f5; if (field_0x3da == 0) { IF_DUSK_BLOCK(dusk::version::isRegionJpn()) setRubyString(); @@ -1018,13 +1034,13 @@ void dMenu_Option_c::change_move() { } break; case PROC_VIB_e: - index = DUSK_IF_ELSE(dusk::version::isRegionJpn() ? 2 : 1, PROC_VIB_e); + index = field_0x3f5; if (field_0x3da == 0) { setVibString(); } break; case PROC_SOUND_e: - index = DUSK_IF_ELSE(dusk::version::isRegionJpn() ? 3 : 2, PROC_SOUND_e); + index = field_0x3f5; if (field_0x3da == 0) { setSoundString(); } @@ -1090,7 +1106,7 @@ void dMenu_Option_c::confirm_open_move() { } if (status == 1 && yesNoMenuMove == 1 && field_0x374 == 1.0f) { yesnoCursorShow(); - field_0x3ef = PROC_CONFIRM_MOVE_MOVE_e; + field_0x3ef = OPTION_SELECT(PROC_CONFIRM_MOVE_MOVE_e); } mpWarning->_move(); setAnimation(); @@ -1120,21 +1136,21 @@ void dMenu_Option_c::confirm_move_move() { field_0x3f9 = i; if (clicked) { yesNoSelectStart(); - field_0x3ef = PROC_CONFIRM_CLOSE_MOVE_e; + field_0x3ef = OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e); dMeter2Info_set2DVibrationM(); mpWarning->_move(); setAnimation(); return; } yesnoSelectAnmSet(); - field_0x3ef = PROC_CONFIRM_SELECT_MOVE_e; + field_0x3ef = OPTION_SELECT(PROC_CONFIRM_SELECT_MOVE_e); mpWarning->_move(); setAnimation(); return; } if (clicked) { yesNoSelectStart(); - field_0x3ef = PROC_CONFIRM_CLOSE_MOVE_e; + field_0x3ef = OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e); dMeter2Info_set2DVibrationM(); mpWarning->_move(); setAnimation(); @@ -1145,12 +1161,12 @@ void dMenu_Option_c::confirm_move_move() { if (mDoCPd_c::getTrigA(PAD_1) != 0) { yesNoSelectStart(); - field_0x3ef = PROC_CONFIRM_CLOSE_MOVE_e; + field_0x3ef = OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e); dMeter2Info_set2DVibrationM(); } else if (mDoCPd_c::getTrigB(PAD_1) != 0) { field_0x3f9 = 0; yesnoCancelAnmSet(); - field_0x3ef = PROC_CONFIRM_CLOSE_MOVE_e; + field_0x3ef = OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e); dMeter2Info_set2DVibrationM(); } else if (rightTrigger != 0) { if (field_0x3f9 != 0) { @@ -1159,7 +1175,7 @@ void dMenu_Option_c::confirm_move_move() { field_0x3fa = field_0x3f9; field_0x3f9 = 0; yesnoSelectAnmSet(); - field_0x3ef = PROC_CONFIRM_SELECT_MOVE_e; + field_0x3ef = OPTION_SELECT(PROC_CONFIRM_SELECT_MOVE_e); } } else if (leftTrigger != 0) { if (field_0x3f9 != 1) { @@ -1168,7 +1184,7 @@ void dMenu_Option_c::confirm_move_move() { field_0x3fa = field_0x3f9; field_0x3f9 = 1; yesnoSelectAnmSet(); - field_0x3ef = PROC_CONFIRM_SELECT_MOVE_e; + field_0x3ef = OPTION_SELECT(PROC_CONFIRM_SELECT_MOVE_e); } } mpWarning->_move(); @@ -1202,14 +1218,14 @@ void dMenu_Option_c::confirm_select_move() { dusk::menu_pointer::Context::Options, option_yes_no_target(field_0x3f9))) { yesNoSelectStart(); - field_0x3ef = PROC_CONFIRM_CLOSE_MOVE_e; + field_0x3ef = OPTION_SELECT(PROC_CONFIRM_CLOSE_MOVE_e); dMeter2Info_set2DVibrationM(); mpWarning->_move(); setAnimation(); return; } #endif - field_0x3ef = PROC_CONFIRM_MOVE_MOVE_e; + field_0x3ef = OPTION_SELECT(PROC_CONFIRM_MOVE_MOVE_e); } mpWarning->_move(); setAnimation(); @@ -1353,13 +1369,7 @@ void dMenu_Option_c::calibration_close2_move() { void dMenu_Option_c::menuVisible() { for (int i = 0; i < 6; i++) { -#if TARGET_PC - if ((dusk::version::isRegionJpn() && i < 4) || i < 3) -#elif VERSION == VERSION_GCN_JPN - if (i < 4) -#else - if (i < 3) -#endif + if (i < OPTION_SELECT(PROC_CHANGE_MOVE_e)) { menuShow(i); } else { @@ -1710,9 +1720,11 @@ void dMenu_Option_c::screenSet() { mpString->getString(0x55C, field_0x270[2], NULL, NULL, NULL, 0); for (int i = 0; i < 5; i++) { #if TARGET_PC - if (dusk::version::isRegionJpn()) { + if (dusk::version::isJpnOrLessThanWiiJpn()) { field_0x25c[i] = (J2DTextBox*)mpTVScreen->search(tv_btnA[i]); - mpTVScreen->search(ftv_btnA[i])->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mpTVScreen->search(ftv_btnA[i])->hide(); + } } else { field_0x25c[i] = (J2DTextBox*)mpTVScreen->search(ftv_btnA[i]); mpTVScreen->search(tv_btnA[i])->hide(); @@ -2210,19 +2222,6 @@ void dMenu_Option_c::setSoundString() { } void dMenu_Option_c::setCursorPos(u8 i_index) { -#if TARGET_PC - if (!dusk::version::isRegionJpn()) { - switch (i_index) { - case PROC_VIB_e: - i_index = 1; - break; - case PROC_SOUND_e: - i_index = 2; - break; - } - } -#endif - #if TARGET_PC || VERSION != VERSION_GCN_JPN IF_DUSK_BLOCK(!dusk::version::isRegionJpn()) if (i_index == 4) { @@ -2279,33 +2278,13 @@ void dMenu_Option_c::setSelectColor(u8 param_0, bool param_1) { } u8 dMenu_Option_c::getSelectType() { -#if TARGET_PC - u8 proc = 0; - if (field_0x3ef < PROC_CHANGE_MOVE_e) { - proc = field_0x3ef; - } else if (field_0x3f5 < PROC_CHANGE_MOVE_e) { - proc = field_0x3f5; - } - - if (!dusk::version::isRegionJpn()) { - switch (proc) { - case PROC_VIB_e: - return 1; - case PROC_SOUND_e: - return 2; - } - } - - return proc; -#else - if (field_0x3ef < PROC_CHANGE_MOVE_e) { + if (field_0x3ef < OPTION_SELECT(PROC_CHANGE_MOVE_e)) { return field_0x3ef; } - if (field_0x3f5 < PROC_CHANGE_MOVE_e) { + if (field_0x3f5 < OPTION_SELECT(PROC_CHANGE_MOVE_e)) { return field_0x3f5; } return 0; -#endif } void dMenu_Option_c::changeBarColor(bool i_changeColor) { @@ -2513,9 +2492,9 @@ bool dMenu_Option_c::pointerConfirmSelect() { field_0x3f7 = 1; field_0x3f5 = field_0x3ef; - field_0x3ef = PROC_CONFIRM_OPEN_MOVE_e; + field_0x3ef = OPTION_SELECT(PROC_CONFIRM_OPEN_MOVE_e); dMeter2Info_set2DVibration(); - (this->*init[field_0x3ef])(); + (this->*init[OPTION_PROC(field_0x3ef)])(); return true; } #endif @@ -2560,8 +2539,8 @@ bool dMenu_Option_c::dpdMenuMove() { } if (getSelectType() != i) { - field_0x3ef = selectProc; - setCursorPos(field_0x3ef); + field_0x3ef = OPTION_SELECT(selectProc); + setCursorPos(i); Z2GetAudioMgr()->seStart(Z2SE_SY_CURSOR_OPTION, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); } @@ -2573,8 +2552,8 @@ bool dMenu_Option_c::dpdMenuMove() { case PROC_ATTEN_e: field_0x3e4 ^= 1; field_0x3da = 5; - field_0x3ef = PROC_CHANGE_MOVE_e; - field_0x3f5 = PROC_ATTEN_e; + field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e); + field_0x3f5 = OPTION_SELECT(PROC_ATTEN_e); Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); return true; @@ -2586,8 +2565,8 @@ bool dMenu_Option_c::dpdMenuMove() { field_0x3e5_JPN = 0; field_0x3da = 5; } - field_0x3ef = PROC_CHANGE_MOVE_e; - field_0x3f5 = PROC_RUBY_e; + field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e); + field_0x3f5 = OPTION_SELECT(PROC_RUBY_e); Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); return true; case PROC_VIB_e: @@ -2597,8 +2576,8 @@ bool dMenu_Option_c::dpdMenuMove() { mDoCPd_c::startMotorWave(0, &field_0x3e0, JUTGamePad::CRumble::VAL_0, 0x3c); } field_0x3da = 5; - field_0x3ef = PROC_CHANGE_MOVE_e; - field_0x3f5 = PROC_VIB_e; + field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e); + field_0x3f5 = OPTION_SELECT(PROC_VIB_e); Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); } @@ -2612,8 +2591,8 @@ bool dMenu_Option_c::dpdMenuMove() { field_0x3da = 5; mDoAud_setOutputMode(dMo_soundMode[field_0x3e9]); setSoundMode(dMo_soundMode[field_0x3e9]); - field_0x3ef = PROC_CHANGE_MOVE_e; - field_0x3f5 = PROC_SOUND_e; + field_0x3ef = OPTION_SELECT(PROC_CHANGE_MOVE_e); + field_0x3f5 = OPTION_SELECT(PROC_SOUND_e); Z2GetAudioMgr()->seStart(Z2SE_SY_OPTION_SWITCH, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); return true; diff --git a/src/d/d_menu_ring.cpp b/src/d/d_menu_ring.cpp index f0f44db166..ed79d40524 100644 --- a/src/d/d_menu_ring.cpp +++ b/src/d/d_menu_ring.cpp @@ -333,11 +333,13 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i mpScreen->search(MULTI_CHAR('yx_te_s3'))->hide(); mpScreen->search(MULTI_CHAR('yx_te_s4'))->hide(); mpScreen->search(MULTI_CHAR('yx_text'))->hide(); + IF_DUSK_BLOCK(dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) mpScreen->search(MULTI_CHAR('fyx_te_1'))->hide(); mpScreen->search(MULTI_CHAR('fyx_te_2'))->hide(); mpScreen->search(MULTI_CHAR('fyx_te_3'))->hide(); mpScreen->search(MULTI_CHAR('fyx_te_4'))->hide(); mpScreen->search(MULTI_CHAR('fyx_tex'))->hide(); + IF_DUSK_BLOCK_END mpScreen->search(MULTI_CHAR('x_btn_n'))->hide(); mpScreen->search(MULTI_CHAR('y_btn_n'))->hide(); } @@ -345,9 +347,11 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i for (i = 0; i < 5; i++) { #if TARGET_PC J2DTextBox* fxy_TextBox; - if (dusk::version::isRegionJpn()) { + if (dusk::version::isJpnOrLessThanWiiJpn()) { fxy_TextBox = (J2DTextBox*)mpScreen->search(xy_text[i]); - mpScreen->search(fxy_text[i])->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mpScreen->search(fxy_text[i])->hide(); + } } else { fxy_TextBox = (J2DTextBox*)mpScreen->search(fxy_text[i]); mpScreen->search(xy_text[i])->hide(); @@ -366,13 +370,17 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i for (i = 0; i < 5; i++) { #if TARGET_PC J2DTextBox* fc_TextBox; - if (dusk::version::isRegionJpn()) { + if (dusk::version::isJpnOrLessThanWiiJpn()) { if (dusk::getSettings().game.swapDirectSelect) { fc_TextBox = (J2DTextBox*)mpScreen->search(c_text1[i]); - mpScreen->search(fc_text1[i])->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mpScreen->search(fc_text1[i])->hide(); + } } else { fc_TextBox = (J2DTextBox*)mpScreen->search(c_text[i]); - mpScreen->search(fc_text[i])->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mpScreen->search(fc_text[i])->hide(); + } } } else { if (dusk::getSettings().game.swapDirectSelect) { @@ -397,13 +405,17 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i for (i = 0; i < 5; i++) { #if TARGET_PC J2DTextBox* fc1_TextBox; - if (dusk::version::isRegionJpn()) { + if (dusk::version::isJpnOrLessThanWiiJpn()) { if (dusk::getSettings().game.swapDirectSelect) { fc1_TextBox = (J2DTextBox*)mpScreen->search(c_text[i]); - mpScreen->search(fc_text[i])->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mpScreen->search(fc_text[i])->hide(); + } } else { fc1_TextBox = (J2DTextBox*)mpScreen->search(c_text1[i]); - mpScreen->search(fc_text1[i])->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mpScreen->search(fc_text1[i])->hide(); + } } } else { if (dusk::getSettings().game.swapDirectSelect) { @@ -427,9 +439,11 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i } for (int i = 0; i < 5; i++) { #if TARGET_PC - if (dusk::version::isRegionJpn()) { + if (dusk::version::isJpnOrLessThanWiiJpn()) { mpComboOffString[i] = (J2DTextBox*)mpScreen->search(t_on[i]); - mpScreen->search(ft_on[i])->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mpScreen->search(ft_on[i])->hide(); + } } else { mpComboOffString[i] = (J2DTextBox*)mpScreen->search(ft_on[i]); mpScreen->search(t_on[i])->hide(); @@ -447,9 +461,11 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i } for (int i = 0; i < 5; i++) { #if TARGET_PC - if (dusk::version::isRegionJpn()) { + if (dusk::version::isJpnOrLessThanWiiJpn()) { mpBowArrowComboString[i] = (J2DTextBox*)mpScreen->search(t_off[i]); - mpScreen->search(ft_off[i])->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mpScreen->search(ft_off[i])->hide(); + } } else { mpBowArrowComboString[i] = (J2DTextBox*)mpScreen->search(ft_off[i]); mpScreen->search(t_off[i])->hide(); @@ -486,19 +502,21 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i mpCircle = JKR_NEW CPaneMgr(mpCenterScreen, MULTI_CHAR('circle_n'), 2, NULL); J2DTextBox* textBox[4]; #if TARGET_PC - if (dusk::version::isRegionJpn()) { + if (dusk::version::isJpnOrLessThanWiiJpn()) { textBox[0] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n04')); textBox[1] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n05')); textBox[2] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n06')); textBox[3] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n07')); - J2DPane* pane = mpCenterScreen->search(MULTI_CHAR('fitem_n1')); - pane->mVisible = false; - pane = mpCenterScreen->search(MULTI_CHAR('fitem_n2')); - pane->mVisible = false; - pane = mpCenterScreen->search(MULTI_CHAR('fitem_n3')); - pane->mVisible = false; - pane = mpCenterScreen->search(MULTI_CHAR('fitem_n4')); - pane->mVisible = false; + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + J2DPane* pane = mpCenterScreen->search(MULTI_CHAR('fitem_n1')); + pane->mVisible = false; + pane = mpCenterScreen->search(MULTI_CHAR('fitem_n2')); + pane->mVisible = false; + pane = mpCenterScreen->search(MULTI_CHAR('fitem_n3')); + pane->mVisible = false; + pane = mpCenterScreen->search(MULTI_CHAR('fitem_n4')); + pane->mVisible = false; + } } else { textBox[0] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('fitem_n1')); textBox[1] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('fitem_n2')); @@ -1292,17 +1310,11 @@ void dMenu_Ring_c::setScale() { void dMenu_Ring_c::setNameString(u32 i_stringID) { J2DTextBox* textBox[4]; #if TARGET_PC - if (dusk::version::isRegionJpn()) { - textBox[0] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n04')); - textBox[1] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n05')); - textBox[2] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n06')); - textBox[3] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n07')); - } else { - textBox[0] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('fitem_n1')); - textBox[1] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('fitem_n2')); - textBox[2] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('fitem_n3')); - textBox[3] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('fitem_n4')); - } + const bool useDomestic = dusk::version::isJpnOrLessThanWiiJpn(); + textBox[0] = (J2DTextBox*)mpCenterScreen->search(useDomestic ? MULTI_CHAR('item_n04') : MULTI_CHAR('fitem_n1')); + textBox[1] = (J2DTextBox*)mpCenterScreen->search(useDomestic ? MULTI_CHAR('item_n05') : MULTI_CHAR('fitem_n2')); + textBox[2] = (J2DTextBox*)mpCenterScreen->search(useDomestic ? MULTI_CHAR('item_n06') : MULTI_CHAR('fitem_n3')); + textBox[3] = (J2DTextBox*)mpCenterScreen->search(useDomestic ? MULTI_CHAR('item_n07') : MULTI_CHAR('fitem_n4')); #elif VERSION == VERSION_GCN_JPN textBox[0] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n04')); textBox[1] = (J2DTextBox*)mpCenterScreen->search(MULTI_CHAR('item_n05')); diff --git a/src/d/d_meter2_draw.cpp b/src/d/d_meter2_draw.cpp index 09963e8cc7..3e5f55916e 100644 --- a/src/d/d_meter2_draw.cpp +++ b/src/d/d_meter2_draw.cpp @@ -1386,6 +1386,22 @@ void dMeter2Draw_c::initButtonCross() { dMeter2Info_getString( 0x62, static_cast(mpScreen->search(MULTI_CHAR('cont_ju9')))->getStringPtr(), NULL); +#if TARGET_PC + // These panes are not wide enough for French text (and possibly other languages) + // on Wii PAL. Resize them to always match their counterparts in later releases. + static u64 const juTags[] = { + MULTI_CHAR('cont_ju0'), MULTI_CHAR('cont_ju1'), MULTI_CHAR('cont_ju2'), + MULTI_CHAR('cont_ju3'), MULTI_CHAR('cont_ju4'), MULTI_CHAR('cont_ju5'), + MULTI_CHAR('cont_ju6'), MULTI_CHAR('cont_ju7'), MULTI_CHAR('cont_ju8'), + MULTI_CHAR('cont_ju9'), + }; + + for (u64 tag : juTags) { + J2DPane* pane = mpScreen->search(tag); + pane->resize(120.0f, pane->getHeight()); + } +#endif + mpButtonCrossParent->setAlphaRate(0.0f); drawButtonCross(g_drawHIO.mButtonCrossOFFPosX, g_drawHIO.mButtonCrossOFFPosY); } diff --git a/src/d/d_meter_button.cpp b/src/d/d_meter_button.cpp index 573147f888..56d756ef44 100644 --- a/src/d/d_meter_button.cpp +++ b/src/d/d_meter_button.cpp @@ -1208,9 +1208,11 @@ void dMeterButton_c::screenInitButton() { for (int i = 0; i < 10; i++) { #if TARGET_PC - if (dusk::version::isRegionJpn()) { + if (dusk::version::isJpnOrLessThanWiiJpn()) { mpTextBox[i] = (J2DTextBox*)mpButtonScreen->search(text_tag[i]); - mpButtonScreen->search(ftext_tag[i])->hide(); + if (dusk::version::getGameVersion() >= dusk::version::GameVersion::WiiJpn) { + mpButtonScreen->search(ftext_tag[i])->hide(); + } } else { mpTextBox[i] = (J2DTextBox*)mpButtonScreen->search(ftext_tag[i]); mpButtonScreen->search(text_tag[i])->hide(); diff --git a/src/d/d_msg_object.cpp b/src/d/d_msg_object.cpp index fc6b03d6df..f39467222f 100644 --- a/src/d/d_msg_object.cpp +++ b/src/d/d_msg_object.cpp @@ -30,6 +30,7 @@ #include "m_Do/m_Do_lib.h" #if TARGET_PC +#include "dusk/language.hpp" #include "dusk/menu_pointer.h" #include "dusk/settings.h" #include "dusk/version.hpp" @@ -1731,7 +1732,9 @@ void dMsgObject_c::readMessageGroupLocal(mDoDvdThd_mountXArchive_c** p_arcMount) #endif int msgGroup = dStage_stagInfo_GetMsgGroup(dComIfGp_getStage()->getStagInfo()); - #if REGION_PAL +#if TARGET_PC + snprintf(arcName, sizeof(arcName), "/res/%s/bmgres%d.arc", dusk::language::msg_folder(), msgGroup); +#elif REGION_PAL switch (dComIfGs_getPalLanguage()) { case dSv_player_config_c::LANGUAGE_GERMAN: sprintf(arcName, "/res/Msgde/bmgres%d.arc", msgGroup); @@ -1748,39 +1751,11 @@ void dMsgObject_c::readMessageGroupLocal(mDoDvdThd_mountXArchive_c** p_arcMount) default: sprintf(arcName, "/res/Msguk/bmgres%d.arc", msgGroup); } - #elif REGION_JPN +#elif REGION_JPN sprintf(arcName, "/res/Msgjp/bmgres%d.arc", msgGroup); - #else -#if TARGET_PC - // Original game UB - - if (dusk::version::isRegionPal()) { - switch (dComIfGs_getPalLanguage()) { - case dSv_player_config_c::LANGUAGE_GERMAN: - snprintf(arcName, sizeof(arcName), "/res/Msgde/bmgres%d.arc", msgGroup); - break; - case dSv_player_config_c::LANGUAGE_FRENCH: - snprintf(arcName, sizeof(arcName), "/res/Msgfr/bmgres%d.arc", msgGroup); - break; - case dSv_player_config_c::LANGUAGE_SPANISH: - snprintf(arcName, sizeof(arcName), "/res/Msgsp/bmgres%d.arc", msgGroup); - break; - case dSv_player_config_c::LANGUAGE_ITALIAN: - snprintf(arcName, sizeof(arcName), "/res/Msgit/bmgres%d.arc", msgGroup); - break; - default: - snprintf(arcName, sizeof(arcName), "/res/Msguk/bmgres%d.arc", msgGroup); - } - } else if (dusk::version::isRegionJpn()) { - snprintf(arcName, sizeof(arcName), "/res/Msgjp/bmgres%d.arc", msgGroup); - } else { - snprintf(arcName, sizeof(arcName), "/res/Msgus/bmgres%d.arc", msgGroup); - } - #else sprintf(arcName, "/res/Msgus/bmgres%d.arc", msgGroup); #endif - #endif *p_arcMount = mDoDvdThd_mountXArchive_c::create(arcName, 0, JKRArchive::MOUNT_MEM, NULL); diff --git a/src/d/d_s_logo.cpp b/src/d/d_s_logo.cpp index 366d87c02b..bd5b1f7783 100644 --- a/src/d/d_s_logo.cpp +++ b/src/d/d_s_logo.cpp @@ -24,6 +24,7 @@ #include "JSystem/JUtility/JUTConsole.h" #ifdef TARGET_PC +#include "dusk/language.hpp" #include "dusk/logging.h" #include "dusk/main.h" #include "dusk/mods/svc/save.hpp" @@ -53,8 +54,8 @@ struct homeBtnData { #if TARGET_PC using namespace dusk::version; -#define LOGO_ARC versionSelect({{GameVersion::GcnJpn, "Logo"}, {GameVersion::GcnPal, "LogoPal"}}, "LogoUs") -#define MSG_PATH versionSelect({{GameVersion::GcnJpn, "/res/Msgjp/bmgres.arc"}}, "/res/Msgus/bmgres.arc") +#define LOGO_ARC regionSelect("LogoUs", "LogoPal", "Logo") +#define MSG_PATH regionSelect("/res/Msgus/bmgres.arc", "/res/Msgus/bmgres.arc", "/res/Msgjp/bmgres.arc") #elif VERSION == VERSION_SHIELD #define LOGO_ARC "LogoUs" #define MSG_PATH "/res/Msgcn/bmgres.arc" @@ -77,7 +78,20 @@ using namespace dusk::version; #define PROGRESSIVE_MODE_ON OS_PROGRESSIVE_MODE_ON #endif -#if PLATFORM_WII || VERSION == VERSION_SHIELD_DEBUG +// TODO: Probably shouldn't actually load LayoutRevo, so I disabled it for now +#if TARGET_PC && 0 +using namespace dusk::version; + +#define FMAP_RES_PATH platformSelect("/res/Layout/fmapres.arc", "/res/LayoutRevo/fmapresR.arc") +#define DMAP_RES_PATH platformSelect("/res/Layout/dmapres.arc", "/res/LayoutRevo/dmapresR.arc") +#define COLLECT_RES_PATH platformSelect("/res/Layout/clctres.arc", "/res/LayoutRevo/clctresR.arc") + +#define MSG_COM_PATH platformSelect("/res/Layout/msgcom.arc", "/res/LayoutRevo/msgcomR.arc") +#define MSG_RES0_PATH platformSelect("/res/Layout/msgres00.arc", "/res/LayoutRevo/msgres00R.arc") +#define MSG_RES1_PATH platformSelect("/res/Layout/msgres01.arc", "/res/LayoutRevo/msgres01R.arc") +#define MSG_RES2_PATH platformSelect("/res/Layout/msgres02.arc", "/res/LayoutRevo/msgres02R.arc") +#define MSG_RES3_PATH platformSelect("/res/Layout/msgres03.arc", "/res/LayoutRevo/msgres03R.arc") +#elif PLATFORM_WII || VERSION == VERSION_SHIELD_DEBUG #define FMAP_RES_PATH "/res/LayoutRevo/fmapresR.arc" #define DMAP_RES_PATH "/res/LayoutRevo/dmapresR.arc" #define COLLECT_RES_PATH "/res/LayoutRevo/clctresR.arc" @@ -99,7 +113,10 @@ using namespace dusk::version; #define MSG_RES3_PATH "/res/Layout/msgres03.arc" #endif -#if PLATFORM_WII || PLATFORM_SHIELD +#if TARGET_PC +#define ICON_RES_PATH "/res/CardIcon/cardicon.arc" +#define PARTICLE_COM_PATH platformSelect("/res/Particle/common.jpc", "/res/Particle/common-r.jpc") +#elif PLATFORM_WII || PLATFORM_SHIELD #define ICON_RES_PATH "/res/WiiBannerIcon/bannerIcon.arc" #define PARTICLE_COM_PATH "/res/Particle/common-r.jpc" #else @@ -107,7 +124,13 @@ using namespace dusk::version; #define PARTICLE_COM_PATH "/res/Particle/common.jpc" #endif -#if PLATFORM_WII +// TODO: Probably shouldn't actually load LayoutRevo, so I disabled it for now +#if TARGET_PC && 0 +#define RING_RES_PATH platformSelect("/res/Layout/ringres.arc", "/res/LayoutRevo/ringresR.arc") +#define ITEM_INF_RES_PATH platformSelect("/res/Layout/itmInfRes.arc", "/res/LayoutRevo/itmInfResR.arc") +#define BUTTON_RES_PATH platformSelect("/res/Layout/button.arc", "/res/LayoutRevo/buttonR.arc") +#define MAIN2D_PATH platformSelect("/res/Layout/main2D.arc", "/res/LayoutRevo/main2DR.arc") +#elif PLATFORM_WII #define RING_RES_PATH "/res/LayoutRevo/ringresR.arc" #define ITEM_INF_RES_PATH "/res/LayoutRevo/itmInfResR.arc" #define BUTTON_RES_PATH "/res/LayoutRevo/buttonR.arc" @@ -862,7 +885,7 @@ dScnLogo_c::~dScnLogo_c() { JKR_DELETE(mProgressiveSel); #if TARGET_PC - if (getGameVersion() == GameVersion::GcnPal) { + if (isRegionPal()) { mpPalLogoResCommand->getArchive()->removeResourceAll(); mpPalLogoResCommand->getArchive()->unmount(); mpPalLogoResCommand->destroy(); @@ -974,7 +997,7 @@ dScnLogo_c::~dScnLogo_c() { mDoExt_setAraCacheSize(free_size - aram_heap->getTotalFreeSize()); #if TARGET_PC - if (getGameVersion() == GameVersion::GcnJpn) { + if (isRegionJpn()) { if (dComIfGp_getFontArchive() != NULL) { dComIfGp_getFontArchive()->unmount(); dComIfGp_setFontArchive(NULL); @@ -1037,7 +1060,7 @@ static int phase_0(dScnLogo_c* i_this) { JKRHEAP_NAME(i_this->mLogo01Heap, "Logo01"); #if TARGET_PC || VERSION == VERSION_GCN_PAL - IF_DUSK_BLOCK(getGameVersion() == GameVersion::GcnPal) + IF_DUSK_BLOCK(isRegionPal()) switch (i_this->getPalLanguage()) { case 1: i_this->mpPalLogoResCommand = mDoDvdThd_mountArchive_c::create("/res/Layout/LogoPalGm.arc", 0, NULL); @@ -1078,7 +1101,7 @@ static int phase_1(dScnLogo_c* i_this) { #endif #if TARGET_PC || VERSION == VERSION_GCN_PAL - IF_DUSK_BLOCK(getGameVersion() == GameVersion::GcnPal) + IF_DUSK_BLOCK(isRegionPal()) if (!mDoDvdThd::SyncWidthSound) { return cPhs_INIT_e; } @@ -1313,7 +1336,7 @@ void dScnLogo_c::logoInitGC() { mDolbyLogo = JKR_NEW dDlst_2D_c(dolbyImg, 189, 150, 232, 112, 255); #if TARGET_PC - if (getGameVersion() == GameVersion::GcnPal) { + if (isRegionPal()) { u8 language = getPalLanguage(); if (language >= 5) { language = 0; @@ -1576,30 +1599,15 @@ void dScnLogo_c::dvdDataLoad() { mpButtonCommand = aramMount(BUTTON_RES_PATH, mDoExt_getJ2dHeap()); mpCardIconCommand = aramMount(ICON_RES_PATH, mDoExt_getJ2dHeap()); - #if TARGET_PC - if (getGameVersion() == GameVersion::GcnPal) { - switch (getPalLanguage()) { - case 1: - mpBmgResCommand = onMemMount("/res/Msgde/bmgres.arc"); - break; - case 2: - mpBmgResCommand = onMemMount("/res/Msgfr/bmgres.arc"); - break; - case 3: - mpBmgResCommand = onMemMount("/res/Msgsp/bmgres.arc"); - break; - case 4: - mpBmgResCommand = onMemMount("/res/Msgit/bmgres.arc"); - break; - case 0: - default: - mpBmgResCommand = onMemMount("/res/Msguk/bmgres.arc"); - break; - } - } else { - mpBmgResCommand = onMemMount(MSG_PATH); - } - #elif VERSION == VERSION_GCN_PAL +#if TARGET_PC +#if AVOID_UB + static char bmgPath[32]; +#else + static char bmgPath[22]; +#endif + snprintf(bmgPath, sizeof(bmgPath), "/res/%s/bmgres.arc", dusk::language::msg_folder()); + mpBmgResCommand = onMemMount(bmgPath); +#elif VERSION == VERSION_GCN_PAL switch (getPalLanguage()) { case 1: mpBmgResCommand = onMemMount("/res/Msgde/bmgres.arc"); @@ -1618,7 +1626,7 @@ void dScnLogo_c::dvdDataLoad() { mpBmgResCommand = onMemMount("/res/Msguk/bmgres.arc"); break; } - #elif VERSION == VERSION_SHIELD_DEBUG +#elif VERSION == VERSION_SHIELD_DEBUG switch (getPalLanguage()) { case 2: mpBmgResCommand = onMemMount("/res/Msgfr/bmgres.arc"); @@ -1630,9 +1638,9 @@ void dScnLogo_c::dvdDataLoad() { mpBmgResCommand = onMemMount("/res/Msgus/bmgres.arc"); break; } - #else +#else mpBmgResCommand = onMemMount(MSG_PATH); - #endif +#endif mpMsgComCommand = aramMount(MSG_COM_PATH, mDoExt_getJ2dHeap()); mpMsgResCommand[0] = aramMount(MSG_RES0_PATH, mDoExt_getJ2dHeap()); @@ -1640,8 +1648,10 @@ void dScnLogo_c::dvdDataLoad() { mpMsgResCommand[2] = aramMount(MSG_RES2_PATH, mDoExt_getJ2dHeap()); mpMsgResCommand[3] = aramMount(MSG_RES3_PATH, mDoExt_getJ2dHeap()); #if TARGET_PC - const auto res4Path = versionSelect({{GameVersion::GcnJpn, "/res/Layout/msgres04.arc"}}, "/res/Layout/msgres04F.arc"); - mpMsgResCommand[4] = aramMount( res4Path, mDoExt_getJ2dHeap()); + const auto res4Path = regionSelect("/res/Layout/msgres04F.arc", + "/res/Layout/msgres04F.arc", + "/res/Layout/msgres04.arc"); + mpMsgResCommand[4] = aramMount(res4Path, mDoExt_getJ2dHeap()); #elif VERSION == VERSION_GCN_JPN mpMsgResCommand[4] = aramMount("/res/Layout/msgres04.arc", mDoExt_getJ2dHeap()); #else @@ -1653,16 +1663,12 @@ void dScnLogo_c::dvdDataLoad() { mpMain2DCommand = onMemMount(MAIN2D_PATH); #if TARGET_PC - const auto fontResPath = versionSelect( - { - {GameVersion::GcnJpn, "/res/Fontjp/fontres.arc"}, - {GameVersion::GcnPal, "/res/Fonteu/fontres.arc"}, - }, "/res/Fontus/fontres.arc"); - const auto fontRubyPath = versionSelect( - { - {GameVersion::GcnJpn, "/res/Fontjp/rubyres.arc"}, - {GameVersion::GcnPal, "/res/Fonteu/rubyres.arc"}, - }, "/res/Fontus/rubyres.arc"); + const auto fontResPath = regionSelect("/res/Fontus/fontres.arc", + "/res/Fonteu/fontres.arc", + "/res/Fontjp/fontres.arc"); + const auto fontRubyPath = regionSelect("/res/Fontus/rubyres.arc", + "/res/Fonteu/rubyres.arc", + "/res/Fontjp/rubyres.arc"); // Note: GCN_JPN mounts this archive as tail instead of head. // I'm guessing this is fine since we have more RAM. diff --git a/src/d/d_save.cpp b/src/d/d_save.cpp index d634c7b21d..e638d23ab1 100644 --- a/src/d/d_save.cpp +++ b/src/d/d_save.cpp @@ -1086,7 +1086,7 @@ void dSv_player_config_c::setVibration(u8 i_status) { u8 dSv_player_config_c::getPalLanguage() const { #if TARGET_PC || VERSION == VERSION_GCN_PAL - IF_DUSK_BLOCK(dusk::version::getGameVersion() == dusk::version::GameVersion::GcnPal) + IF_DUSK_BLOCK(dusk::version::isRegionPal()) switch (OSGetLanguage()) { case 0: return LANGUAGE_ENGLISH; diff --git a/src/dusk/dvd_asset.hpp b/src/dusk/dvd_asset.hpp index 8594d4631c..d1ce5f3e39 100644 --- a/src/dusk/dvd_asset.hpp +++ b/src/dusk/dvd_asset.hpp @@ -23,9 +23,20 @@ bool LoadDolAsset(void* dst, std::initializer_list virtualAddress */ bool LoadRelAsset(void* dst, const char* dvdPath, std::initializer_list offset, s32 size); +template +bool LoadRelAsset(T (&dst)[N], const char* dvdPath, std::initializer_list offset) { + return LoadRelAsset(static_cast(dst), dvdPath, offset, static_cast(sizeof(dst))); +} + /** * Load bytes from a REL inside RELS.arc */ bool LoadArchivedRelAsset(void* dst, u32 memType, const char* relFileName, std::initializer_list offset, s32 size); +template +bool LoadArchivedRelAsset(T (&dst)[N], u32 memType, const char* relFileName, + std::initializer_list offset) { + return LoadArchivedRelAsset(static_cast(dst), memType, relFileName, offset, static_cast(sizeof(dst))); +} + } // namespace dusk diff --git a/src/dusk/iso_validate.cpp b/src/dusk/iso_validate.cpp index 380c1860a1..26fdef11e9 100644 --- a/src/dusk/iso_validate.cpp +++ b/src/dusk/iso_validate.cpp @@ -40,10 +40,25 @@ constexpr auto AcceptedDiscs = std::to_array({ .gameId = "GZ2P01", .expectedHash = borealis::disc::parse_xxh3_128("9ef597588b0035ca9e91b333fa9a8a7e"), }, + { + .gameId = "RZDE01", .revision = 0, + .expectedHash = borealis::disc::parse_xxh3_128("b3d91fbea59e5c66934d04c01566728e"), + }, + { + .gameId = "RZDE01", .revision = 2, + .expectedHash = borealis::disc::parse_xxh3_128("c3ec420921a1b36d6ae43f576491d25c"), + }, + { + .gameId = "RZDJ01", + .expectedHash = borealis::disc::parse_xxh3_128("d3866821c7fc6999e6e8bbef8b6875aa"), + }, + { + .gameId = "RZDP01", + .expectedHash = borealis::disc::parse_xxh3_128("6095a924a57e5fb4294ac96fb85a09a1"), + }, }); -constexpr auto RecognizedGameIds = - std::to_array({"RZDE01", "RZDJ01", "RZDK01", "RZDP01"}); +constexpr auto RecognizedGameIds = std::to_array({"RZDK01"}); constexpr borealis::disc::Catalog DiscCatalog{ .acceptedDiscs = AcceptedDiscs, @@ -92,6 +107,7 @@ void update_info(const borealis::disc::Result& result, DiscInfo& info) noexcept if (!result.metadata.gameId.empty()) { info.platform = result.metadata.platform; info.region = region_from_game_id(result.metadata.gameId); + info.revision = result.metadata.revision; } } diff --git a/src/dusk/iso_validate.hpp b/src/dusk/iso_validate.hpp index b9267a6a64..7b376815bd 100644 --- a/src/dusk/iso_validate.hpp +++ b/src/dusk/iso_validate.hpp @@ -37,6 +37,7 @@ using VerificationStatus = borealis::disc::Progress; struct DiscInfo { Platform platform = Platform::Unknown; Region region = Region::NorthAmerica; + std::uint8_t revision = 0; }; ValidationError inspect(const char* path, DiscInfo& info); diff --git a/src/dusk/language.cpp b/src/dusk/language.cpp new file mode 100644 index 0000000000..62d30df816 --- /dev/null +++ b/src/dusk/language.cpp @@ -0,0 +1,79 @@ +#include "dusk/language.hpp" + +#include "dusk/version.hpp" + +namespace dusk::language { +namespace { + +constexpr GameLanguage kEnglishOnly[] = {GameLanguage::English}; +constexpr GameLanguage kJapaneseOnly[] = {GameLanguage::Japanese}; +constexpr GameLanguage kPalLanguages[] = { + GameLanguage::English, + GameLanguage::German, + GameLanguage::French, + GameLanguage::Spanish, + GameLanguage::Italian, +}; +constexpr GameLanguage kWiiUsaLanguages[] = { + GameLanguage::English, + GameLanguage::French, + GameLanguage::Spanish, +}; + +} // namespace + +std::span available_languages(const iso::DiscInfo& info) noexcept { + switch (info.region) { + case iso::Region::Japan: + return kJapaneseOnly; + case iso::Region::Europe: + return kPalLanguages; + case iso::Region::NorthAmerica: + if (info.platform == iso::Platform::Wii && info.revision == 2) { + return kWiiUsaLanguages; + } + return kEnglishOnly; + default: + return kEnglishOnly; + } +} + +const char* language_name(GameLanguage language) noexcept { + switch (language) { + case GameLanguage::English: + return "English"; + case GameLanguage::German: + return "German"; + case GameLanguage::French: + return "French"; + case GameLanguage::Spanish: + return "Spanish"; + case GameLanguage::Italian: + return "Italian"; + case GameLanguage::Japanese: + return "Japanese"; + } + return "English"; +} + +const char* msg_folder() noexcept { + using namespace version; + + switch (getSettings().game.language.getValue()) { + case GameLanguage::German: + return "Msgde"; + case GameLanguage::French: + return "Msgfr"; + case GameLanguage::Spanish: + return "Msgsp"; + case GameLanguage::Italian: + return "Msgit"; + case GameLanguage::Japanese: + return "Msgjp"; + case GameLanguage::English: + default: + return isRegionPal() ? "Msguk" : "Msgus"; + } +} + +} // namespace dusk::language diff --git a/src/dusk/language.hpp b/src/dusk/language.hpp new file mode 100644 index 0000000000..3da488b538 --- /dev/null +++ b/src/dusk/language.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "dusk/iso_validate.hpp" +#include "dusk/settings.h" + +#include + +namespace dusk::language { + +std::span available_languages(const iso::DiscInfo& info) noexcept; + +const char* language_name(GameLanguage language) noexcept; +const char* msg_folder() noexcept; + +} // namespace dusk::language diff --git a/src/dusk/mods/loader/loader.cpp b/src/dusk/mods/loader/loader.cpp index 6c3a01bd7a..83c7660410 100644 --- a/src/dusk/mods/loader/loader.cpp +++ b/src/dusk/mods/loader/loader.cpp @@ -899,6 +899,7 @@ bool ModLoader::activate_mod(LoadedMod& mod) { } void ModLoader::deactivate_mod(LoadedMod& mod) { + svc::modules_mod_deactivating(mod); if (mod.initialized && mod.native && mod.native->fn_shutdown) { log::write(mod.metadata.id, LOG_LEVEL_TRACE, "calling mod_shutdown"); try { diff --git a/src/dusk/mods/svc/gfx.cpp b/src/dusk/mods/svc/gfx.cpp index 900640d4fb..098894007a 100644 --- a/src/dusk/mods/svc/gfx.cpp +++ b/src/dusk/mods/svc/gfx.cpp @@ -9,8 +9,10 @@ #include #include +#include #include +#include #include #include #include @@ -126,23 +128,34 @@ GfxSlot* resolve_owned_slot_locked(LoadedMod& mod, uint64_t handle, GfxSlotKind return &entry->value; } -void collect_mod_types_locked(LoadedMod& owner, std::vector& drawIds, +void take_mod_types_locked(LoadedMod& owner, std::vector& drawIds, std::vector& taskIds) { - s_slots.for_each([&](uint64_t, const auto& entry) { + std::vector drawHandles; + std::vector taskHandles; + s_slots.for_each([&](uint64_t handle, const auto& entry) { if (entry.owner != &owner) { return; } const auto& slot = entry.value; if (slot.kind == GfxSlotKind::DrawType && slot.auroraDrawId != aurora::gfx::InvalidDrawType) { - drawIds.push_back(slot.auroraDrawId); + drawHandles.push_back(handle); } else if ((slot.kind == GfxSlotKind::ComputeType || slot.kind == GfxSlotKind::PresentTarget) && slot.auroraTaskId != aurora::gfx::InvalidEncoderTask) { - taskIds.push_back(slot.auroraTaskId); + taskHandles.push_back(handle); } }); + for (const auto handle : drawHandles) { + auto* entry = s_slots.find(handle); + drawIds.push_back(std::exchange(entry->value.auroraDrawId, aurora::gfx::InvalidDrawType)); + } + for (const auto handle : taskHandles) { + auto* entry = s_slots.find(handle); + taskIds.push_back( + std::exchange(entry->value.auroraTaskId, aurora::gfx::InvalidEncoderTask)); + } } void unregister_aurora_types(const std::vector& drawIds, @@ -155,6 +168,49 @@ void unregister_aurora_types(const std::vector& drawIds } } +void gfx_mod_deactivating(LoadedMod& mod) { + std::vector drawIds; + std::vector taskIds; + { + std::lock_guard lock{s_mutex}; + take_mod_types_locked(mod, drawIds, taskIds); + } + unregister_aurora_types(drawIds, taskIds); + if (!drawIds.empty() || !taskIds.empty()) { + aurora::gfx::synchronize(); + } +} + +GfxAttachmentSemantic gfx_attachment_semantic(aurora::gfx::ColorAttachmentSemantic semantic) { + switch (semantic) { + case aurora::gfx::ColorAttachmentSemantic::SceneColor: + return GFX_ATTACHMENT_SCENE_COLOR; + case aurora::gfx::ColorAttachmentSemantic::Normal: + return GFX_ATTACHMENT_NORMAL; + case aurora::gfx::ColorAttachmentSemantic::Auxiliary: + return GFX_ATTACHMENT_AUXILIARY; + } + return GFX_ATTACHMENT_AUXILIARY; +} + +GfxRenderTargetLayout gfx_render_target_layout(const aurora::gfx::RenderTargetLayout& layout) { + GfxRenderTargetLayout result = GFX_RENDER_TARGET_LAYOUT_INIT; + result.key = layout.key; + result.color_attachment_count = + std::min(layout.colorAttachmentCount, GFX_MAX_COLOR_ATTACHMENTS); + for (uint32_t i = 0; i < result.color_attachment_count; ++i) { + result.color_attachments[i] = { + .semantic = gfx_attachment_semantic(layout.colorAttachments[i].semantic), + .format = static_cast(layout.colorAttachments[i].format), + .width = layout.colorAttachments[i].width, + .height = layout.colorAttachments[i].height, + }; + } + result.depth_stencil_format = static_cast(layout.depthStencilFormat); + result.sample_count = layout.sampleCount; + return result; +} + void draw_trampoline(const aurora::gfx::DrawContext& ctx, const wgpu::RenderPassEncoder& pass, const void* payload, size_t payloadSize, void* userdata) { const auto handle = static_cast(reinterpret_cast(userdata)); @@ -184,12 +240,12 @@ void draw_trampoline(const aurora::gfx::DrawContext& ctx, const wgpu::RenderPass .index_buffer = ctx.indexBuffer.Get(), .uniform_buffer = ctx.uniformBuffer.Get(), .storage_buffer = ctx.storageBuffer.Get(), - .color_format = static_cast(ctx.colorFormat), - .depth_format = static_cast(ctx.depthFormat), - .sample_count = ctx.sampleCount, - .target_width = ctx.targetWidth, - .target_height = ctx.targetHeight, + .color_format = static_cast( + ctx.layout.colorAttachments[GFX_SCENE_COLOR_ATTACHMENT_INDEX].format), + .depth_format = static_cast(ctx.layout.depthStencilFormat), + .sample_count = ctx.layout.sampleCount, .uses_reversed_z = aurora::gfx::uses_reversed_z(), + .layout = gfx_render_target_layout(ctx.layout), }; std::string failure; @@ -778,8 +834,10 @@ ModResult gfx_unregister_present_target(LoadedMod& mod, uint64_t handle) { auroraId = slot->auroraTaskId; } - aurora::gfx::unregister_encoder_task_type(auroraId); - aurora::gfx::synchronize(); + if (auroraId != aurora::gfx::InvalidEncoderTask) { + aurora::gfx::unregister_encoder_task_type(auroraId); + aurora::gfx::synchronize(); + } std::optional removed; { @@ -903,6 +961,7 @@ void gfx_run_stage( .game_viewport = gameViewport, }; + AuroraGXSync(); for (const auto& entry : entries) { { std::lock_guard lock{s_mutex}; @@ -924,6 +983,7 @@ void gfx_run_stage( fail_mod(*entry.owner, MOD_ERROR, "unknown exception in gfx stage callback"); } + AuroraGXSync(); if (aurora::gfx::is_offscreen() != wasOffscreen) { aurora::gfx::ResolvedTargets discarded; aurora::gfx::resolve_pass( @@ -935,17 +995,8 @@ void gfx_run_stage( } } -void gfx_remove_mod(LoadedMod& mod) { - std::vector drawIds; - std::vector taskIds; - { - std::lock_guard lock{s_mutex}; - collect_mod_types_locked(mod, drawIds, taskIds); - } - unregister_aurora_types(drawIds, taskIds); - if (!drawIds.empty() || !taskIds.empty()) { - aurora::gfx::synchronize(); - } +void gfx_mod_detached(LoadedMod& mod) { + gfx_mod_deactivating(mod); std::vector entries; { @@ -966,7 +1017,7 @@ void gfx_remove_mod(LoadedMod& mod) { } } -void gfx_drain_worker_failures() { +void gfx_frame_begin() { std::vector failures; { std::lock_guard lock{s_mutex}; @@ -979,7 +1030,7 @@ void gfx_drain_worker_failures() { for (const auto& failure : failures) { for (auto& mod : ModLoader::instance().mods()) { if (mod.metadata.id == failure.modId && mod.active) { - gfx_remove_mod(mod); + gfx_mod_detached(mod); fail_mod(mod, MOD_ERROR, failure.message); break; } @@ -1030,6 +1081,19 @@ ModResult gfx_get_device_info(ModContext* context, GfxDeviceInfo* outInfo) { return MOD_OK; } +ModResult gfx_get_scene_target_layout(ModContext* context, GfxRenderTargetLayout* outLayout) { + if (outLayout == nullptr || outLayout->struct_size < sizeof(GfxRenderTargetLayout) || + mod_from_context(context) == nullptr) + { + return MOD_INVALID_ARGUMENT; + } + + const uint32_t structSize = outLayout->struct_size; + *outLayout = gfx_render_target_layout(aurora::gfx::scene_render_target_layout()); + outLayout->struct_size = structSize; + return MOD_OK; +} + void* gfx_get_proc_address(ModContext* context, const char* name) { if (mod_from_context(context) == nullptr || name == nullptr) { return nullptr; @@ -1327,6 +1391,7 @@ constexpr GfxService s_gfxService{ .resize_present_target = gfx_resize_present_target_impl, .unregister_present_target = gfx_unregister_present_target_impl, .push_present = gfx_push_present_impl, + .get_scene_target_layout = gfx_get_scene_target_layout, }; } // namespace @@ -1336,8 +1401,9 @@ constinit const ServiceModule g_gfxModule{ .majorVersion = GFX_SERVICE_MAJOR, .minorVersion = GFX_SERVICE_MINOR, .service = &s_gfxService, - .modDetached = gfx_remove_mod, - .frameBegin = gfx_drain_worker_failures, + .modDeactivating = gfx_mod_deactivating, + .modDetached = gfx_mod_detached, + .frameBegin = gfx_frame_begin, }; } // namespace dusk::mods::svc diff --git a/src/dusk/mods/svc/registry.cpp b/src/dusk/mods/svc/registry.cpp index 1c8368720f..051d7ad977 100644 --- a/src/dusk/mods/svc/registry.cpp +++ b/src/dusk/mods/svc/registry.cpp @@ -150,6 +150,14 @@ ModResult register_module(const ServiceModule& module) { return MOD_OK; } +void modules_mod_deactivating(LoadedMod& mod) { + for (const auto* module : s_modules | std::views::reverse) { + if (module->modDeactivating != nullptr) { + module->modDeactivating(mod); + } + } +} + void modules_mod_detached(LoadedMod& mod) { for (const auto* module : s_modules | std::views::reverse) { if (module->modDetached != nullptr) { diff --git a/src/dusk/mods/svc/registry.hpp b/src/dusk/mods/svc/registry.hpp index d3df44ccc3..c88ef5509c 100644 --- a/src/dusk/mods/svc/registry.hpp +++ b/src/dusk/mods/svc/registry.hpp @@ -19,7 +19,7 @@ struct ServiceRecord { }; // A host service and its lifecycle hooks. Every hook is optional. Frame and lifecycle hooks run in -// registration order, modDetached in reverse registration order. +// registration order, teardown hooks in reverse registration order. struct ServiceModule { const char* id = nullptr; uint16_t majorVersion = 0; @@ -28,6 +28,9 @@ struct ServiceModule { // One-time setup, at registration (ModLoader::init_services). void (*initialize)() = nullptr; + // A mod is beginning deactivation: stop callbacks that may execute concurrently. Service state + // remains registered so mod_shutdown may release it normally. + void (*modDeactivating)(LoadedMod& mod) = nullptr; // A mod is going away (deactivation or failed activation): drop all state held for it. // Runs after the mod's mod_shutdown and before its library unloads, so pointers into // the mod are still valid but must not be called. @@ -55,6 +58,7 @@ const ServiceRecord* find_service( const ServiceRecord* find_service_record(const char* serviceId, uint16_t majorVersion); ModResult register_module(const ServiceModule& module); +void modules_mod_deactivating(LoadedMod& mod); void modules_mod_detached(LoadedMod& mod); void modules_lifecycle_applied(); void modules_frame_begin(); diff --git a/src/dusk/mods/svc/save.cpp b/src/dusk/mods/svc/save.cpp index 360cdf6dca..209c0037fa 100644 --- a/src/dusk/mods/svc/save.cpp +++ b/src/dusk/mods/svc/save.cpp @@ -200,6 +200,7 @@ void save_slot_written(uint32_t slot, const void* slotData) { store.snapshotCrc = utils::crc32(slotData, kQuestLogSize); } flush_sidecar(); + s_currentSlot = static_cast(slot); notify(slot, &SaveObserverRecord::onWritten, "save-written"); } diff --git a/src/dusk/settings.h b/src/dusk/settings.h index 914ef37efc..3d29c0ec02 100644 --- a/src/dusk/settings.h +++ b/src/dusk/settings.h @@ -33,6 +33,7 @@ enum class GameLanguage : u8 { French = OS_LANGUAGE_FRENCH, Spanish = OS_LANGUAGE_SPANISH, Italian = OS_LANGUAGE_ITALIAN, + Japanese = 6, }; enum class DiscVerificationState : u8 { @@ -89,7 +90,7 @@ struct ConfigEnumRange { template <> struct ConfigEnumRange { static constexpr auto min = GameLanguage::English; - static constexpr auto max = GameLanguage::Italian; + static constexpr auto max = GameLanguage::Japanese; }; template <> diff --git a/src/dusk/ui/prelaunch.cpp b/src/dusk/ui/prelaunch.cpp index 487e40ab48..d392242140 100644 --- a/src/dusk/ui/prelaunch.cpp +++ b/src/dusk/ui/prelaunch.cpp @@ -4,6 +4,7 @@ #include "dusk/config.hpp" #include "dusk/data.hpp" #include "dusk/iso_validate.hpp" +#include "dusk/language.hpp" #include "dusk/main.h" #include "dusk/settings.h" #include "modal.hpp" @@ -291,7 +292,7 @@ std::string get_error_msg(iso::ValidationError error) { case iso::ValidationError::WrongGame: return "The selected game is not supported by Dusklight."; case iso::ValidationError::WrongVersion: - return "Dusklight currently supports GameCube USA and PAL disc images only."; + return "Dusklight does not currently support the Wii's Korean version."; case iso::ValidationError::Canceled: return "Disc verification was canceled. Dusklight cannot guarantee the selected disc " "image is compatible."; @@ -317,6 +318,24 @@ void persist_disc_choice(const std::string& path, iso::ValidationError validatio } } +void apply_language_for_disc(const iso::DiscInfo& info) { + const auto langs = language::available_languages(info); + auto& language = getSettings().game.language; + const GameLanguage previous = language.getValue(); + if (std::ranges::find(langs, previous) != langs.end()) { + return; + } + + const GameLanguage fallback = langs.front(); + language.setValue(fallback); + config::save(); + + auto& state = prelaunch_state(); + state.initialLanguage = fallback; + state.unavailableLanguage = previous; + state.pendingLanguageUnavailableNotice = true; +} + void apply_valid_disc_result( const std::string& path, const iso::DiscInfo& info, iso::ValidationError validation) { auto& state = prelaunch_state(); @@ -329,6 +348,7 @@ void apply_valid_disc_result( state.activeDiscInfo = info; } persist_disc_choice(path, validation); + apply_language_for_disc(info); } void apply_disc_verification_result(const DiscVerificationResult& result) { @@ -548,6 +568,7 @@ void refresh_configured_disc_state() noexcept { if (state.configuredDiscPath == state.activeDiscPath) { state.activeDiscInfo = info; } + apply_language_for_disc(info); return; } @@ -632,6 +653,36 @@ void try_push_verification_modal(Document& host) { })); } +void try_push_language_unavailable_modal(Document& host) { + auto& state = prelaunch_state(); + + if (!state.pendingLanguageUnavailableNotice) { + return; + } + state.pendingLanguageUnavailableNotice = false; + + const Rml::String bodyRml = fmt::format( + "{} is not available on this disc. Language has been reset to {}.", + language::language_name(state.unavailableLanguage), + language::language_name(getSettings().game.language.getValue())); + + auto dismiss = [](Modal& modal) { modal.pop(); }; + + host.push(std::make_unique(Modal::Props{ + .title = "Language unavailable", + .bodyRml = bodyRml, + .actions = + { + ModalAction{ + .label = "OK", + .onPressed = dismiss, + }, + }, + .onDismiss = dismiss, + .icon = "warning", + })); +} + void ensure_initialized() noexcept { auto& state = prelaunch_state(); if (state.initialized) { @@ -844,6 +895,7 @@ void Prelaunch::update() { if (top_document() == this) { try_push_verification_modal(*this); + try_push_language_unavailable_modal(*this); } const auto& state = prelaunch_state(); @@ -917,6 +969,9 @@ void Prelaunch::update() { break; case iso::Region::NorthAmerica: innerRML += "USA"; + if (state.activeDiscInfo.platform == iso::Platform::Wii) { + innerRML += fmt::format(" Rev. {}", state.activeDiscInfo.revision); + } break; case iso::Region::Korea: innerRML += "KOR"; diff --git a/src/dusk/ui/prelaunch.hpp b/src/dusk/ui/prelaunch.hpp index a5be868f36..45d158912a 100644 --- a/src/dusk/ui/prelaunch.hpp +++ b/src/dusk/ui/prelaunch.hpp @@ -49,6 +49,8 @@ struct PrelaunchState { std::string activeDiscPath; iso::DiscInfo activeDiscInfo{}; GameLanguage initialLanguage = GameLanguage::English; + GameLanguage unavailableLanguage = GameLanguage::English; + bool pendingLanguageUnavailableNotice = false; std::string initialGraphicsBackend; int initialCardFileType = 0; std::string errorString; @@ -63,5 +65,6 @@ void refresh_configured_disc_state() noexcept; void open_iso_picker() noexcept; bool is_restart_pending() noexcept; void try_push_verification_modal(Document& host); +void try_push_language_unavailable_modal(Document& host); } // namespace dusk::ui diff --git a/src/dusk/ui/settings.cpp b/src/dusk/ui/settings.cpp index f425fb5425..423909f821 100644 --- a/src/dusk/ui/settings.cpp +++ b/src/dusk/ui/settings.cpp @@ -11,6 +11,7 @@ #include "dusk/data.hpp" #include "dusk/imgui/ImGuiEngine.hpp" #include "dusk/io.hpp" +#include "dusk/language.hpp" #include "dusk/presentation.hpp" #include #include @@ -53,14 +54,6 @@ namespace dusk::ui { namespace { -constexpr std::array kLanguageNames = { - "English", - "German", - "French", - "Spanish", - "Italian", -}; - constexpr std::array kCardFileTypes = { "Card Image", "GCI Folder", @@ -220,6 +213,18 @@ AuroraBackend configured_backend() { return configuredBackend; } +bool is_graphics_backend_restart_pending() { + return getSettings().backend.graphicsBackend.getValue() != + prelaunch_state().initialGraphicsBackend; +} + +Rml::String graphics_backend_display_name() { + if (is_graphics_backend_restart_pending()) { + return Rml::String{backend_name(configured_backend())}; + } + return Rml::String{backend_name(aurora_get_backend())}; +} + Rml::String configured_data_path_display_name() { const auto path = data::abbreviated_path_string(data::configured_data_path()); if (path.empty()) { @@ -562,18 +567,15 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) { .key = "Language", .getValue = [] { - const auto& state = prelaunch_state(); - if (!state.configuredDiscCanLaunch || state.configuredDiscInfo.region != iso::Region::Europe) { - return kLanguageNames[0]; - } - const u8 idx = static_cast(getSettings().game.language.getValue()); - return kLanguageNames[idx]; + return language::language_name(getSettings().game.language.getValue()); }, .isDisabled = [] { const auto& state = prelaunch_state(); - return !state.configuredDiscCanLaunch || - state.configuredDiscInfo.region != iso::Region::Europe; + if (!state.configuredDiscCanLaunch) { + return true; + } + return language::available_languages(state.configuredDiscInfo).size() <= 1; }, .isModified = [] { @@ -582,18 +584,22 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) { }, }), rightPane, [](Pane& pane) { - for (int i = 0; i < kLanguageNames.size(); i++) { + const auto& state = prelaunch_state(); + const auto languages = state.configuredDiscCanLaunch + ? language::available_languages(state.configuredDiscInfo) + : language::available_languages({}); + for (const GameLanguage language : languages) { pane.add_button({ - .text = kLanguageNames[i], + .text = language::language_name(language), .isSelected = - [i] { + [language] { return getSettings().game.language.getValue() == - static_cast(i); + language; }, }) - .on_pressed([i] { + .on_pressed([language] { mDoAud_seStartMenu(kSoundItemChange); - getSettings().game.language.setValue(static_cast(i)); + getSettings().game.language.setValue(language); config::save(); }); } @@ -602,12 +608,8 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) { leftPane.register_control( leftPane.add_select_button({ .key = "Graphics Backend", - .getValue = [] { return Rml::String{backend_name(aurora_get_backend())}; }, - .isModified = - [] { - return getSettings().backend.graphicsBackend.getValue() != - prelaunch_state().initialGraphicsBackend; - }, + .getValue = [] { return graphics_backend_display_name(); }, + .isModified = [] { return is_graphics_backend_restart_pending(); }, }), rightPane, [](Pane& pane) { const auto availableBackends = available_backends(); @@ -1543,6 +1545,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) { void SettingsWindow::update() { if (mPrelaunch && top_document() == this) { try_push_verification_modal(*this); + try_push_language_unavailable_modal(*this); } Window::update(); diff --git a/src/dusk/version.cpp b/src/dusk/version.cpp index 1655031cdb..5d0856aed1 100644 --- a/src/dusk/version.cpp +++ b/src/dusk/version.cpp @@ -26,10 +26,18 @@ void init() { if (game == "GZ2E"sv) { gameVersion = GameVersion::GcnUsa; - } else if (game == "GZ2P") { + } else if (game == "GZ2P"sv) { gameVersion = GameVersion::GcnPal; - } else if (game == "GZ2J") { + } else if (game == "GZ2J"sv) { gameVersion = GameVersion::GcnJpn; + } else if (game == "RZDE"sv && diskId.gameVersion == 0) { + gameVersion = GameVersion::WiiUsaRev0; + } else if (game == "RZDE"sv && diskId.gameVersion == 2) { + gameVersion = GameVersion::WiiUsa; + } else if (game == "RZDP"sv) { + gameVersion = GameVersion::WiiPal; + } else if (game == "RZDJ"sv) { + gameVersion = GameVersion::WiiJpn; } else { // TODO: Handle remaining valid versions. DuskLog.fatal("Unknown/unsupported game version in disc: {}", game); @@ -52,8 +60,12 @@ bool isWii() { || getGameVersion() == GameVersion::WiiKor; } +bool isJpnOrLessThanWiiJpn() { + return isRegionJpn() || getGameVersion() < GameVersion::WiiJpn; +} + bool isPalOrAtLeastWiiR2() { - return getGameVersion() == GameVersion::GcnPal || getGameVersion() >= GameVersion::WiiUsa; + return isRegionPal() || (isWii() && getGameVersion() != GameVersion::WiiUsaRev0); } bool isRegionJpn() { diff --git a/src/dusk/version.hpp b/src/dusk/version.hpp index 4fd6395059..59e2895f77 100644 --- a/src/dusk/version.hpp +++ b/src/dusk/version.hpp @@ -5,18 +5,19 @@ */ namespace dusk::version { enum class GameVersion : u8 { - GcnUsa = VERSION_GCN_USA, - GcnPal = VERSION_GCN_PAL, - GcnJpn = VERSION_GCN_JPN, - WiiUsaRev0 = VERSION_WII_USA_R0, - WiiUsa = VERSION_WII_USA_R2, - WiiPal = VERSION_WII_PAL, - WiiJpn = VERSION_WII_JPN, - WiiKor = VERSION_WII_KOR, + WiiUsaRev0, + WiiPal, + WiiJpn, + GcnUsa, + GcnPal, + GcnJpn, + WiiUsa, + WiiKor, }; bool isGcn(); bool isWii(); + bool isJpnOrLessThanWiiJpn(); bool isPalOrAtLeastWiiR2(); bool isRegionPal(); @@ -61,4 +62,14 @@ namespace dusk::version { return defaultValue; } + + template + T platformSelect(const T& gcn, const T& wii) { + return isGcn() ? gcn : wii; + } + + template + T regionSelect(const T& usa, const T& pal, const T& jpn) { + return isRegionUsa() ? usa : isRegionPal() ? pal : jpn; + } } // namespace dusk::version diff --git a/src/m_Do/m_Do_ext.cpp b/src/m_Do/m_Do_ext.cpp index 381061e079..2d7cc86bbd 100644 --- a/src/m_Do/m_Do_ext.cpp +++ b/src/m_Do/m_Do_ext.cpp @@ -3713,7 +3713,7 @@ static ResFONT* mDoExt_resfont0; static void mDoExt_initFont0() { static char const fontdata[] = "rodan_b_24_22.bfn"; #if TARGET_PC - if (dusk::version::getGameVersion() == dusk::version::GameVersion::GcnJpn) { + if (dusk::version::isRegionJpn()) { mDoExt_initFontCommon(&mDoExt_font0, &mDoExt_resfont0, mDoExt_getZeldaHeap(), fontdata, dComIfGp_getFontArchive(), 0, 200, 512); } else { @@ -3748,7 +3748,7 @@ void mDoExt_removeMesgFont() { mDoExt_font0 = NULL; if (mDoExt_resfont0 != NULL) { #if TARGET_PC - if (dusk::version::getGameVersion() == dusk::version::GameVersion::GcnJpn) { + if (dusk::version::isRegionJpn()) { JKRFileLoader::removeResource(mDoExt_resfont0, NULL); } else { JKRFree(mDoExt_resfont0);