Merge branch 'rando-mod' of https://github.com/TwilitRealm/dusk into rando-mod

This commit is contained in:
gymnast86
2026-08-16 17:58:06 -07:00
56 changed files with 2450 additions and 1478 deletions
+10 -5
View File
@@ -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
+4 -1
View File
@@ -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
+7 -1
View File
@@ -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
+1 -1
+2
View File
@@ -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
+1 -1
View File
@@ -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;
+5
View File
@@ -70,6 +70,11 @@ void JUTVideo::preRetraceProc(u32 retrace_count) {
OSTick tick = DUSK_IF_ELSE(static_cast<OSTick>(OSGetNativeTime()), OSGetTick());
sVideoInterval = tick - sVideoLastTick;
#if TARGET_PC
if (sVideoInterval <= 0) {
sVideoInterval = 1;
}
#endif
sVideoLastTick = tick;
JUTXfb* xfb = JUTXfb::getManager();
+12 -10
View File
@@ -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",
File diff suppressed because it is too large Load Diff
@@ -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
+5 -25
View File
@@ -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<std::string>();
if (stageIdString == "null") {
stageIdString = "-1";
ret = false;
}
int stageId = std::stoi(stageIdString);
if (stageId == -1) {
stageId = 0xFF;
}
SetStageId(static_cast<uint8_t>(stageId));
std::string roomNoString = node["Room"].as<std::string>();
if (roomNoString == "null") {
roomNoString = "-1";
ret = false;
}
SetRoomNo(static_cast<int8_t>(std::stoi(roomNoString)));
SetPointNo(static_cast<int16_t>(std::stoi("0x0"+node["Spawn"].as<std::string>(),nullptr,16)));
int layer = std::stoi("0x0"+node["State"].as<std::string>(),nullptr,16);
if (layer == 0xFF) {
layer = -1;
}
SetLayerNo(static_cast<int8_t>(layer));
return ret;
void Entrance::SetGameInfo(const YAML::Node& node) {
SetStageId(node["Stage"].as<uint8_t>());
SetRoomNo(node["Room"].as<int8_t>());
SetPointNo(node["Spawn"].as<int16_t>());
SetLayerNo(node["State"].as<int8_t>());
}
} // namespace randomizer::logic::entrance
+4 -4
View File
@@ -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<int16_t>& entrances) { _coupledEntrances = entrances; }
const std::vector<int16_t>& 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<int16_t> _coupledEntrances = {};
};
using EntrancePool = std::vector<Entrance*>;
@@ -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<std::string, std::list<entrance::Entrance*>> coupledDoors = {};
// Keep track of which entrances are together
std::unordered_map<std::string, std::list<entrance::Entrance*>> 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<std::string>();
auto roomString = forwardEntry["Stage"].as<std::string>();
if (stageString == "null" || stageString == "-1" || roomString == "null" || roomString == "-1") {
continue;
}
if (entranceDataNode["Return"]) {
stageString = entranceDataNode["Return"]["Stage"].as<std::string>();
roomString = entranceDataNode["Return"]["Stage"].as<std::string>();
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<std::string>() : "");
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<std::string>();
if (!coupledDoors.contains(tag))
auto tag = entranceDataNode["Entrance Couple Tag"].as<std::string>();
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<int16_t> 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();
}
}
}
+23 -80
View File
@@ -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<dFile_select_c*>(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<daObjMasterSword_c*>(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<u8>(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<daObjMasterSword_c*>(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<int*>(retval) = 1;
return HOOK_SKIP_ORIGINAL;
}
return HOOK_CONTINUE;
*static_cast<int*>(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<daE_MD_c__create>(svc_hook);
mods::hook::uninstall<daObjMasterSword_c__executeWait>(svc_hook);
mods::hook::uninstall<orderMapToolEvent>(svc_hook);
mods::hook::uninstall<daObjMasterSword_c__execute>(svc_hook);
mods::hook::uninstall<dScnName_c__changeGameScene>();
+299 -125
View File
@@ -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,
+6 -7
View File
@@ -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;
}
}
+10 -16
View File
@@ -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<std::string_view,9> 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) {
+4 -2
View File
@@ -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);
-2
View File
@@ -16,8 +16,6 @@ namespace randomizer::ui {
enum dialogSelectModeState : uint8_t {
SelectReady,
SelectWait,
SelectVanilla,
SelectRandomizer
};
extern dialogSelectModeState g_dialogSelectModeState;
+13 -11
View File
@@ -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))
{
-6
View File
@@ -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;
}
+71 -3
View File
@@ -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);
+4 -1
View File
@@ -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<Z2SeqMgr>(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();
}
+74 -18
View File
@@ -15,12 +15,50 @@
#include "dusk/dvd_asset.hpp"
#include "dusk/frame_interpolation.h"
using GameVersion = dusk::version::GameVersion;
#include <type_traits>
using namespace dusk::version;
#define MANT_REL_PATH platformSelect<const char*>("/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<type> 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] = {
+8 -4
View File
@@ -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
),
+1 -1
View File
@@ -52,7 +52,7 @@ static u8 const lit_3772[12] = {
#if TARGET_PC
using namespace dusk::version;
#define l_arcName versionSelect<const char*>({{GameVersion::GcnPal, "TitlePal"}}, "Title")
#define l_arcName regionSelect<const char*>("Title", "TitlePal", "Title")
#elif VERSION == VERSION_GCN_PAL
static char const l_arcName[] = "TitlePal";
#else
+108 -16
View File
@@ -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())
+92 -9
View File
@@ -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 <typename T, size_t N>
static bool LoadGrassAsset(T (&dst)[N], std::initializer_list<dusk::OffsetVersion> 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())
+9 -3
View File
@@ -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);
+16 -12
View File
@@ -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);
+2
View File
@@ -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);
+48 -56
View File
@@ -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<J2DTextBox*>(mpTitleScreen->search(area_name[i]))->setFont(mDoExt_getRubyFont());
static_cast<J2DTextBox*>(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<J2DTextBox*>(mpTitleScreen->search(farea_name[i]))->setFont(mDoExt_getRubyFont());
static_cast<J2DTextBox*>(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<J2DTextBox*>(mpTitleScreen->search(sfont_name[i]))->setFont(mDoExt_getRubyFont());
static_cast<J2DTextBox*>(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<J2DTextBox*>(mpTitleScreen->search(ffont_name[i]))->setFont(mDoExt_getRubyFont());
static_cast<J2DTextBox*>(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<J2DTextBox*>(mpTitleScreen->search(cont_zt[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(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<J2DTextBox*>(mpTitleScreen->search(font_zt[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(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<J2DTextBox*>(mpTitleScreen->search(cont_bt[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(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<J2DTextBox*>(mpTitleScreen->search(font_bt[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(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<J2DTextBox*>(mpTitleScreen->search(cont_at[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(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<J2DTextBox*>(mpTitleScreen->search(font_at[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(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<J2DTextBox*>(mpTitleScreen->search(juji_c[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(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<J2DTextBox*>(mpTitleScreen->search(fuji_c[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(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<J2DTextBox*>(mpTitleScreen->search(ast_c[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(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<J2DTextBox*>(mpTitleScreen->search(fst_c[i]))->setFont(mDoExt_getMesgFont());
static_cast<J2DTextBox*>(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<J2DTextBox*>(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? juji_c_jpn[i] : juji_c[i], juji_c[i])));
J2DTextBox* text_box = static_cast<J2DTextBox*>(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<J2DTextBox*>(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? juji_c_jpn[i] : juji_c[i], juji_c[i])));
J2DTextBox* text_box = static_cast<J2DTextBox*>(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<J2DTextBox*>(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? ast_c_jpn[i] : ast_c[i], ast_c[i])));
J2DTextBox* text_box = static_cast<J2DTextBox*>(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<J2DTextBox*>(mpTitleScreen->search(DUSK_IF_ELSE(dusk::version::isRegionJpn() ? ast_c_jpn[i] : ast_c[i], ast_c[i])));
J2DTextBox* text_box = static_cast<J2DTextBox*>(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();
+99 -120
View File
@@ -73,6 +73,26 @@ static calibrationFunc calibration_process[] = {
static dusk::menu_pointer::TargetId option_yes_no_target(u8 index) noexcept {
return static_cast<dusk::menu_pointer::TargetId>(0x100 + index);
}
static u8 option_to_proc(u8 select) noexcept {
if (!dusk::version::isRegionJpn() && select >= 1) {
return static_cast<u8>(select + 1);
}
return select;
}
static u8 option_to_select(u8 proc) noexcept {
if (!dusk::version::isRegionJpn() && proc >= 2) {
return static_cast<u8>(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;
+44 -32
View File
@@ -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'));
+16
View File
@@ -1386,6 +1386,22 @@ void dMeter2Draw_c::initButtonCross() {
dMeter2Info_getString(
0x62, static_cast<J2DTextBox*>(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);
}
+4 -2
View File
@@ -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();
+5 -30
View File
@@ -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);
+55 -49
View File
@@ -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<const char*>({{GameVersion::GcnJpn, "Logo"}, {GameVersion::GcnPal, "LogoPal"}}, "LogoUs")
#define MSG_PATH versionSelect<const char*>({{GameVersion::GcnJpn, "/res/Msgjp/bmgres.arc"}}, "/res/Msgus/bmgres.arc")
#define LOGO_ARC regionSelect<const char*>("LogoUs", "LogoPal", "Logo")
#define MSG_PATH regionSelect<const char*>("/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<const char*>("/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<const char*>({{GameVersion::GcnJpn, "/res/Layout/msgres04.arc"}}, "/res/Layout/msgres04F.arc");
mpMsgResCommand[4] = aramMount( res4Path, mDoExt_getJ2dHeap());
const auto res4Path = regionSelect<const char*>("/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<const char*>(
{
{GameVersion::GcnJpn, "/res/Fontjp/fontres.arc"},
{GameVersion::GcnPal, "/res/Fonteu/fontres.arc"},
}, "/res/Fontus/fontres.arc");
const auto fontRubyPath = versionSelect<const char*>(
{
{GameVersion::GcnJpn, "/res/Fontjp/rubyres.arc"},
{GameVersion::GcnPal, "/res/Fonteu/rubyres.arc"},
}, "/res/Fontus/rubyres.arc");
const auto fontResPath = regionSelect<const char*>("/res/Fontus/fontres.arc",
"/res/Fonteu/fontres.arc",
"/res/Fontjp/fontres.arc");
const auto fontRubyPath = regionSelect<const char*>("/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.
+1 -1
View File
@@ -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;
+11
View File
@@ -23,9 +23,20 @@ bool LoadDolAsset(void* dst, std::initializer_list<OffsetVersion> virtualAddress
*/
bool LoadRelAsset(void* dst, const char* dvdPath, std::initializer_list<OffsetVersion> offset, s32 size);
template <typename T, size_t N>
bool LoadRelAsset(T (&dst)[N], const char* dvdPath, std::initializer_list<OffsetVersion> offset) {
return LoadRelAsset(static_cast<void*>(dst), dvdPath, offset, static_cast<s32>(sizeof(dst)));
}
/**
* Load bytes from a REL inside RELS.arc
*/
bool LoadArchivedRelAsset(void* dst, u32 memType, const char* relFileName, std::initializer_list<OffsetVersion> offset, s32 size);
template <typename T, size_t N>
bool LoadArchivedRelAsset(T (&dst)[N], u32 memType, const char* relFileName,
std::initializer_list<OffsetVersion> offset) {
return LoadArchivedRelAsset(static_cast<void*>(dst), memType, relFileName, offset, static_cast<s32>(sizeof(dst)));
}
} // namespace dusk
+18 -2
View File
@@ -40,10 +40,25 @@ constexpr auto AcceptedDiscs = std::to_array<borealis::disc::AcceptedDisc>({
.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<std::string_view>({"RZDE01", "RZDJ01", "RZDK01", "RZDP01"});
constexpr auto RecognizedGameIds = std::to_array<std::string_view>({"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;
}
}
+1
View File
@@ -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);
+79
View File
@@ -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<const GameLanguage> 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
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include "dusk/iso_validate.hpp"
#include "dusk/settings.h"
#include <span>
namespace dusk::language {
std::span<const GameLanguage> available_languages(const iso::DiscInfo& info) noexcept;
const char* language_name(GameLanguage language) noexcept;
const char* msg_folder() noexcept;
} // namespace dusk::language
+1
View File
@@ -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 {
+92 -26
View File
@@ -9,8 +9,10 @@
#include <aurora/gfx.hpp>
#include <aurora/webgpu.hpp>
#include <dolphin/gx/GXAurora.h>
#include <fmt/format.h>
#include <algorithm>
#include <atomic>
#include <cstddef>
#include <cstdint>
@@ -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<aurora::gfx::DrawTypeId>& drawIds,
void take_mod_types_locked(LoadedMod& owner, std::vector<aurora::gfx::DrawTypeId>& drawIds,
std::vector<aurora::gfx::EncoderTaskId>& taskIds) {
s_slots.for_each([&](uint64_t, const auto& entry) {
std::vector<uint64_t> drawHandles;
std::vector<uint64_t> 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<aurora::gfx::DrawTypeId>& drawIds,
@@ -155,6 +168,49 @@ void unregister_aurora_types(const std::vector<aurora::gfx::DrawTypeId>& drawIds
}
}
void gfx_mod_deactivating(LoadedMod& mod) {
std::vector<aurora::gfx::DrawTypeId> drawIds;
std::vector<aurora::gfx::EncoderTaskId> 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<uint32_t>(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<WGPUTextureFormat>(layout.colorAttachments[i].format),
.width = layout.colorAttachments[i].width,
.height = layout.colorAttachments[i].height,
};
}
result.depth_stencil_format = static_cast<WGPUTextureFormat>(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<uint64_t>(reinterpret_cast<uintptr_t>(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<WGPUTextureFormat>(ctx.colorFormat),
.depth_format = static_cast<WGPUTextureFormat>(ctx.depthFormat),
.sample_count = ctx.sampleCount,
.target_width = ctx.targetWidth,
.target_height = ctx.targetHeight,
.color_format = static_cast<WGPUTextureFormat>(
ctx.layout.colorAttachments[GFX_SCENE_COLOR_ATTACHMENT_INDEX].format),
.depth_format = static_cast<WGPUTextureFormat>(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<GfxSlotMap::Entry> 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<aurora::gfx::DrawTypeId> drawIds;
std::vector<aurora::gfx::EncoderTaskId> 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<GfxSlotMap::Entry> entries;
{
@@ -966,7 +1017,7 @@ void gfx_remove_mod(LoadedMod& mod) {
}
}
void gfx_drain_worker_failures() {
void gfx_frame_begin() {
std::vector<WorkerFailure> 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
+8
View File
@@ -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) {
+5 -1
View File
@@ -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();
+1
View File
@@ -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<int32_t>(slot);
notify(slot, &SaveObserverRecord::onWritten, "save-written");
}
+2 -1
View File
@@ -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<Resampler> {
template <>
struct ConfigEnumRange<GameLanguage> {
static constexpr auto min = GameLanguage::English;
static constexpr auto max = GameLanguage::Italian;
static constexpr auto max = GameLanguage::Japanese;
};
template <>
+56 -1
View File
@@ -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(
"<b>{}</b> is not available on this disc. Language has been reset to <b>{}</b>.",
language::language_name(state.unavailableLanguage),
language::language_name(getSettings().game.language.getValue()));
auto dismiss = [](Modal& modal) { modal.pop(); };
host.push(std::make_unique<Modal>(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";
+3
View File
@@ -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
+31 -28
View File
@@ -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 <borealis/io.hpp>
#include <borealis/file_select.hpp>
@@ -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<u8>(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<GameLanguage>(i);
language;
},
})
.on_pressed([i] {
.on_pressed([language] {
mDoAud_seStartMenu(kSoundItemChange);
getSettings().game.language.setValue(static_cast<GameLanguage>(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();
+15 -3
View File
@@ -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() {
+19 -8
View File
@@ -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<typename T>
T platformSelect(const T& gcn, const T& wii) {
return isGcn() ? gcn : wii;
}
template<typename T>
T regionSelect(const T& usa, const T& pal, const T& jpn) {
return isRegionUsa() ? usa : isRegionPal() ? pal : jpn;
}
} // namespace dusk::version
+2 -2
View File
@@ -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);