Recording Mode & Enable Autosave in Dusk preset (#685)

* branch for recording without a HUD

* no more black bars thanks maddie

* Backslash hotkey

* mute music

* dont check for null twice

* renamed option to recording mode, and added it to the rmlui menu

* Move recording mode to Interface

* re-added & renamed minimal hud option

* Mute all BGM if recording mode is on

* Update Interface section

* Un-experimentalize Autosave & enable in Dusk preset

---------

Co-authored-by: MelonSpeedruns <melonspeedruns@stratobox.net>
Co-authored-by: Irastris <irastris15@gmail.com>
Co-authored-by: Luke Street <luke@street.dev>
This commit is contained in:
MelonSpeedruns
2026-05-08 01:26:22 -04:00
committed by GitHub
parent 89d393e57a
commit 1c1a849095
16 changed files with 171 additions and 50 deletions
+2 -1
View File
@@ -99,7 +99,7 @@ struct UserSettings {
// Preferences
ConfigVar<bool> enableMirrorMode;
ConfigVar<bool> disableMainHUD;
ConfigVar<bool> minimalHUD;
ConfigVar<bool> pauseOnFocusLost;
ConfigVar<bool> enableLinkDollRotation;
ConfigVar<bool> enableAchievementNotifications;
@@ -161,6 +161,7 @@ struct UserSettings {
// Tools
ConfigVar<bool> speedrunMode;
ConfigVar<bool> liveSplitEnabled;
ConfigVar<bool> recordingMode;
} game;
struct {
+9
View File
@@ -12,6 +12,10 @@
#include "SSystem/SComponent/c_counter.h"
#include <cstring>
#if TARGET_PC
#include "dusk/settings.h"
#endif
#define DRAW_TYPE_YELLOW 0
#define DRAW_TYPE_RED 1
@@ -1422,6 +1426,11 @@ int dAttention_c::Run() {
}
void dAttention_c::Draw() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
if (mAttParam.CheckFlag(dAttParam_c::EFlag_ARROW_OFF)) {
draw[0].field_0x173 = 3;
draw[1].field_0x173 = 3;
+6 -3
View File
@@ -24,9 +24,10 @@
#include "d/actor/d_a_horse.h"
#include <cstring>
#if TARGET_PC
#include "dusk/memory.h"
#include "dusk/memory.h"
#include "dusk/settings.h"
#endif
int dMeter2_c::_create() {
stage_stag_info_class* stag_info = dComIfGp_getStageStagInfo();
@@ -317,7 +318,9 @@ int dMeter2_c::_execute() {
int dMeter2_c::_draw() {
#if TARGET_PC
if (dusk::getSettings().game.disableMainHUD || dusk::getSettings().game.debugFlyCam) {
if (dusk::getSettings().game.recordingMode || dusk::getSettings().game.minimalHUD ||
dusk::getSettings().game.debugFlyCam)
{
return 1;
}
#endif
+9
View File
@@ -6,6 +6,10 @@
#include "d/d_com_inf_game.h"
#include "d/d_pane_class.h"
#if TARGET_PC
#include "dusk/settings.h"
#endif
dMsgScrnArrow_c::dMsgScrnArrow_c() {
mpScreen = JKR_NEW J2DScreen();
JUT_ASSERT(0, mpScreen != NULL);
@@ -65,6 +69,11 @@ dMsgScrnArrow_c::~dMsgScrnArrow_c() {
}
void dMsgScrnArrow_c::draw() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
J2DGrafContext* graf_ctx = dComIfGp_getCurrentGrafPort();
mpScreen->draw(0.0f, 0.0f, graf_ctx);
}
+24
View File
@@ -8,6 +8,10 @@
#include "d/d_pane_class.h"
#include <cstring>
#if TARGET_PC
#include "dusk/settings.h"
#endif
dMsgScrnBase_c::dMsgScrnBase_c() {
init();
}
@@ -57,12 +61,22 @@ void dMsgScrnBase_c::init() {
}
void dMsgScrnBase_c::multiDraw() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
if (field_0x48 != NULL) {
dComIfGd_set2DOpa(field_0x48);
}
}
void dMsgScrnBase_c::draw() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
J2DGrafContext* ctx = dComIfGp_getCurrentGrafPort();
ctx->setup2D();
@@ -72,10 +86,20 @@ void dMsgScrnBase_c::draw() {
}
void dMsgScrnBase_c::drawSelf() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
drawOutFont(0.0f, 0.0f, 1.0f);
}
void dMsgScrnBase_c::drawOutFont(f32 param_0, f32 param_1, f32 param_2) {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
mpOutFont->draw(NULL, param_0, param_1, param_2);
}
+9
View File
@@ -6,6 +6,10 @@
#include "d/d_msg_object.h"
#include "d/d_pane_class.h"
#if TARGET_PC
#include "dusk/settings.h"
#endif
dMsgScrnBoss_c::dMsgScrnBoss_c() {
static u64 t_tag[7] = {
MULTI_CHAR('sfontb0'), MULTI_CHAR('sfontb1'), MULTI_CHAR('sfontb2'), MULTI_CHAR('sfontl0'), MULTI_CHAR('sfontl1'), MULTI_CHAR('sfontl2'), MULTI_CHAR('sfont00'),
@@ -91,6 +95,11 @@ void dMsgScrnBoss_c::exec() {
}
void dMsgScrnBoss_c::drawSelf() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
J2DGrafContext* ctx = dComIfGp_getCurrentGrafPort();
ctx->setup2D();
drawOutFont(0.0f, 0.0f, 1.0f);
+9
View File
@@ -13,6 +13,10 @@
#include "d/d_msg_out_font.h"
#include "d/d_pane_class.h"
#if TARGET_PC
#include "dusk/settings.h"
#endif
dMsgScrnKanban_c::dMsgScrnKanban_c(JKRExpHeap* param_0) {
if (param_0 != NULL) {
field_0xd4 = param_0;
@@ -176,6 +180,11 @@ void dMsgScrnKanban_c::exec() {
}
void dMsgScrnKanban_c::draw() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
J2DGrafContext* grafContext = dComIfGp_getCurrentGrafPort();
grafContext->setup2D();
mpScreen->draw(0.0f, 0.0f, grafContext);
+9
View File
@@ -12,6 +12,10 @@
#include "d/d_msg_object.h"
#include "d/d_pane_class.h"
#if TARGET_PC
#include "dusk/settings.h"
#endif
dMsgScrnPlace_c::dMsgScrnPlace_c() {
static u64 t_tag[7] = {
MULTI_CHAR('sfontb0'), MULTI_CHAR('sfontb1'), MULTI_CHAR('sfontb2'), MULTI_CHAR('sfontl0'), MULTI_CHAR('sfontl1'), MULTI_CHAR('sfontl2'), MULTI_CHAR('sfont00'),
@@ -127,6 +131,11 @@ void dMsgScrnPlace_c::exec() {
}
void dMsgScrnPlace_c::drawSelf() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
J2DGrafContext* grafContext = dComIfGp_getCurrentGrafPort();
grafContext->setup2D();
drawOutFont(0.0f, 0.0f, 1.0f);
+9
View File
@@ -20,6 +20,10 @@
#include "JSystem/J2DGraph/J2DScreen.h"
#include <cstring>
#if TARGET_PC
#include "dusk/settings.h"
#endif
dMsgScrnTalk_c::dMsgScrnTalk_c(u8 param_1, u8 param_2, JKRExpHeap* param_3) {
if (param_3 != NULL) {
field_0xe4 = param_3;
@@ -303,6 +307,11 @@ void dMsgScrnTalk_c::exec() {
}
void dMsgScrnTalk_c::drawSelf() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
J2DGrafContext* grafContext[1];
grafContext[0] = dComIfGp_getCurrentGrafPort();
grafContext[0]->setup2D();
+9
View File
@@ -9,6 +9,10 @@
#include "d/d_msg_out_font.h"
#include "d/d_pane_class.h"
#if TARGET_PC
#include "dusk/settings.h"
#endif
dMsgScrnTree_c::dMsgScrnTree_c(JUTFont* param_0, JKRExpHeap* param_1) {
if (param_1 != NULL) {
field_0xd8 = param_1;
@@ -187,6 +191,11 @@ void dMsgScrnTree_c::exec() {
}
void dMsgScrnTree_c::draw() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
J2DGrafContext* grafContext = dComIfGp_getCurrentGrafPort();
grafContext->setup2D();
mpScreen->draw(0.0f, 0.0f, grafContext);
+1
View File
@@ -273,6 +273,7 @@ namespace dusk {
m_isHidden = true;
}
}
bool showMenu = !m_isHidden;
// The menu bar renders with ImGuiCol_WindowBg behind it. We just want ImGuiCol_MenuBarBg,
+14 -12
View File
@@ -47,9 +47,9 @@ UserSettings g_userSettings = {
// Preferences
.enableMirrorMode {"game.enableMirrorMode", false},
.disableMainHUD {"game.disableMainHUD", false},
.minimalHUD {"game.minimalHUD", false},
.pauseOnFocusLost {"game.pauseOnFocusLost", false},
.enableLinkDollRotation = {"game.enableLinkDollRotation", false},
.enableLinkDollRotation {"game.enableLinkDollRotation", false},
.enableAchievementNotifications {"game.enableAchievementNotifications", true},
// Graphics
@@ -85,15 +85,15 @@ UserSettings g_userSettings = {
// Cheats
.infiniteHearts {"game.infiniteHearts", false},
.infiniteArrows{"game.infiniteArrows", false},
.infiniteBombs{"game.infiniteBombs", false},
.infiniteOil{"game.infiniteOil", false},
.infiniteOxygen{"game.infiniteOxygen", false},
.infiniteRupees{"game.infiniteRupees", false},
.infiniteArrows {"game.infiniteArrows", false},
.infiniteBombs {"game.infiniteBombs", false},
.infiniteOil {"game.infiniteOil", false},
.infiniteOxygen {"game.infiniteOxygen", false},
.infiniteRupees {"game.infiniteRupees", false},
.enableIndefiniteItemDrops {"game.enableIndefiniteItemDrops", false},
.moonJump{"game.moonJump", false},
.superClawshot{"game.superClawshot", false},
.alwaysGreatspin{"game.alwaysGreatspin", false},
.moonJump {"game.moonJump", false},
.superClawshot {"game.superClawshot", false},
.alwaysGreatspin {"game.alwaysGreatspin", false},
.enableFastIronBoots {"game.enableFastIronBoots", false},
.canTransformAnywhere {"game.canTransformAnywhere", false},
.fastSpinner {"game.fastSpinner", false},
@@ -107,7 +107,8 @@ UserSettings g_userSettings = {
// Tools
.speedrunMode {"game.speedrunMode", false},
.liveSplitEnabled {"game.liveSplitEnabled", false}
.liveSplitEnabled {"game.liveSplitEnabled", false},
.recordingMode {"game.recordingMode", false}
},
.backend = {
@@ -167,7 +168,7 @@ void registerSettings() {
Register(g_userSettings.game.invertCameraXAxis);
Register(g_userSettings.game.invertCameraYAxis);
Register(g_userSettings.game.freeCameraSensitivity);
Register(g_userSettings.game.disableMainHUD);
Register(g_userSettings.game.minimalHUD);
Register(g_userSettings.game.pauseOnFocusLost);
Register(g_userSettings.game.bloomMode);
Register(g_userSettings.game.bloomMultiplier);
@@ -188,6 +189,7 @@ void registerSettings() {
Register(g_userSettings.game.enableTurboKeybind);
Register(g_userSettings.game.speedrunMode);
Register(g_userSettings.game.liveSplitEnabled);
Register(g_userSettings.game.recordingMode);
Register(g_userSettings.game.fastSpinner);
Register(g_userSettings.game.infiniteHearts);
Register(g_userSettings.game.infiniteArrows);
+1
View File
@@ -43,6 +43,7 @@ void applyPresetDusk() {
s.game.internalResolutionScale.setValue(0);
s.game.shadowResolutionMultiplier.setValue(4);
s.game.enableGyroAim.setValue(true);
s.game.autoSave.setValue(true);
}
} // namespace
+50 -34
View File
@@ -10,11 +10,11 @@
#include "dusk/livesplit.h"
#include "graphics_tuner.hpp"
#include "m_Do/m_Do_main.h"
#include "menu_bar.hpp"
#include "number_button.hpp"
#include "pane.hpp"
#include "prelaunch.hpp"
#include "ui.hpp"
#include "menu_bar.hpp"
#include <algorithm>
@@ -340,9 +340,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
.getValue =
[] {
const auto& state = prelaunch_state();
if (!state.configuredDiscCanLaunch ||
!state.configuredDiscInfo.isPal)
{
if (!state.configuredDiscCanLaunch || !state.configuredDiscInfo.isPal) {
return kLanguageNames[0];
}
const u8 idx = static_cast<u8>(getSettings().game.language.getValue());
@@ -480,7 +478,8 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
.key = "Pause on Focus Lost",
.isDisabled = [] { return IsMobile; },
});
leftPane.register_control(leftPane.add_select_button({
leftPane.register_control(
leftPane.add_select_button({
.key = "Show FPS Counter",
.getValue =
[] {
@@ -499,25 +498,27 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
},
}),
rightPane, [](Pane& pane) {
pane.add_button({
.text = "Off",
.isSelected =
[] { return !getSettings().video.enableFpsOverlay.getValue(); },
})
pane.add_button(
{
.text = "Off",
.isSelected =
[] { return !getSettings().video.enableFpsOverlay.getValue(); },
})
.on_pressed([] {
mDoAud_seStartMenu(kSoundItemChange);
getSettings().video.enableFpsOverlay.setValue(false);
config::Save();
});
for (int i = 0; i < static_cast<int>(kFpsOverlayCornerNames.size()); ++i) {
pane.add_button({
.text = kFpsOverlayCornerNames[i],
.isSelected =
[i] {
return getSettings().video.enableFpsOverlay.getValue() &&
getSettings().video.fpsOverlayCorner.getValue() == i;
},
})
pane.add_button(
{
.text = kFpsOverlayCornerNames[i],
.isSelected =
[i] {
return getSettings().video.enableFpsOverlay.getValue() &&
getSettings().video.fpsOverlayCorner.getValue() == i;
},
})
.on_pressed([i] {
mDoAud_seStartMenu(kSoundItemChange);
getSettings().video.enableFpsOverlay.setValue(true);
@@ -743,8 +744,8 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
leftPane.add_section("General");
addOption("Mirror Mode", getSettings().game.enableMirrorMode,
"Mirrors the world horizontally, matching the Wii version of the game.");
addOption("Disable Main HUD", getSettings().game.disableMainHUD,
"Disables the main HUD of the game.<br/>Useful for recording or a more immersive "
addOption("Minimal HUD", getSettings().game.minimalHUD,
"Disables the elements of the main HUD of the game.<br/>Useful for a more immersive "
"experience.");
addOption("Restore Wii 1.0 Glitches", getSettings().game.restoreWiiGlitches,
"Restores patched glitches from Wii USA 1.0, the first released version.");
@@ -792,11 +793,8 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
config_bool_select(leftPane, rightPane, getSettings().game.autoSave,
{
.key = "Autosave",
.icon = "warning",
.helpText =
"Autosaves the game when going to a new area, opening a dungeon door, "
"or getting a new item.<br/><br/><icon class=\"warning\"/> Experimental "
"feature: Use at your own risk.",
.helpText = "Autosaves the game when going to a new area, opening a dungeon door, "
"or getting a new item.",
});
addOption("Instant Saves", getSettings().game.instantSaves,
"Skips the delay when writing to the Memory Card.");
@@ -884,11 +882,11 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
"Lets the magic armor work without consuming rupees.");
});
// TODO: Reorganize all of this?
add_tab("Interface", [this](Rml::Element* content) {
auto& leftPane = add_child<Pane>(content, Pane::Type::Controlled);
auto& rightPane = add_child<Pane>(content, Pane::Type::Uncontrolled);
leftPane.add_section("Dusk");
config_bool_select(leftPane, rightPane, getSettings().game.enableAchievementNotifications,
{
.key = "Achievement Notifications",
@@ -912,22 +910,40 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
.helpText = "When starting Dusk, skip the main menu and boot straight into the "
"game if a disc image is available.",
});
config_bool_select(leftPane, rightPane, getSettings().game.hideTvSettingsScreen,
{
.key = "Skip TV Settings Screen",
.helpText = "Skips the TV calibration screen shown when loading a save.",
});
config_bool_select(leftPane, rightPane, getSettings().backend.showPipelineCompilation,
{
.key = "Show Pipeline Compilation",
.helpText = "Show an overlay when shaders are being compiled for your hardware.",
});
config_bool_select(leftPane, rightPane, getSettings().backend.enableAdvancedSettings,
{
.key = "Enable Advanced Settings",
.helpText = "Show the advanced settings on the menu bar.<br/>Most users should have this disabled.",
.onChange = [](bool value) { get_document_stack()[0] = std::make_unique<MenuBar>(); },
.icon = "warning",
.helpText = "Show advanced settings and debugging tools with "
"Shift+F1.<br/><br/><icon class=\"warning\"/> WARNING: Debugging tools "
"can easily break your game. Do not use on a regular save!",
.onChange =
[](bool) {
for (auto& doc : get_document_stack()) {
if (dynamic_cast<MenuBar*>(doc.get())) {
doc = std::make_unique<MenuBar>();
break;
}
}
},
});
leftPane.add_section("Game");
config_bool_select(leftPane, rightPane, getSettings().game.hideTvSettingsScreen,
{
.key = "Skip TV Settings Screen",
.helpText = "Skips the TV calibration screen shown when loading a save.",
});
config_bool_select(leftPane, rightPane, getSettings().game.recordingMode,
{
.key = "Recording Mode",
.helpText = "Disables the game HUD and all background music.<br/><br/>Useful for "
"recording footage.",
});
});
}
+4
View File
@@ -743,6 +743,10 @@ static void duskExecute() {
handleGamepadColor();
updateAutoSave();
if (dusk::getSettings().game.recordingMode) {
Z2GetSeqMgr()->bgmAllMute(0, 0);
}
if (mDoCPd_c::getHoldR(PAD_1) && mDoCPd_c::getTrigX(PAD_1)) {
if (const auto link = g_dComIfG_gameInfo.play.getPlayer(0)) {
dynamic_cast<daAlink_c*>(link)->handleWolfHowl();
+6
View File
@@ -56,6 +56,7 @@
#include "dusk/gx_helper.h"
#include "dusk/imgui/ImGuiConsole.hpp"
#include "dusk/logging.h"
#include "dusk/settings.h"
#endif
class mDoGph_HIO_c : public JORReflexible {
@@ -1172,6 +1173,11 @@ static void drawDepth2(view_class* param_0, view_port_class* param_1, int param_
}
static void trimming(view_class* param_0, view_port_class* param_1) {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
ZoneScoped;
UNUSED(param_0);