Implemented UI for controlling autosaving, fixed general config defaults not being applied correctly

This commit is contained in:
Mr-Wiseguy 2024-05-04 13:08:14 -04:00
parent 7034243ff6
commit 54b862599c
9 changed files with 98 additions and 23 deletions

View File

@ -93,7 +93,7 @@
</div> </div>
</div> </div>
<!-- targeting mode --> <!-- background input -->
<div class="config-option" data-event-mouseover="set_cur_config_index(4)" id="conf-general__Background-Input"> <div class="config-option" data-event-mouseover="set_cur_config_index(4)" id="conf-general__Background-Input">
<label class="config-option__title">Background Input</label> <label class="config-option__title">Background Input</label>
<div class="config-option__list"> <div class="config-option__list">
@ -105,7 +105,7 @@
data-checked="background_input_mode" data-checked="background_input_mode"
value="On" value="On"
id="bg_input_enabled" id="bg_input_enabled"
style="nav-up: #mouse_sensitivity_input" style="nav-up: #mouse_sensitivity_input; nav-down: #autosave_enabled"
/> />
<label class="config-option__tab-label" for="bg_input_enabled">On</label> <label class="config-option__tab-label" for="bg_input_enabled">On</label>
@ -117,11 +117,41 @@
data-checked="background_input_mode" data-checked="background_input_mode"
value="Off" value="Off"
id="bg_input_disabled" id="bg_input_disabled"
style="nav-up: #mouse_sensitivity_input" style="nav-up: #mouse_sensitivity_input; nav-down: #autosave_disabled"
/> />
<label class="config-option__tab-label" for="bg_input_disabled">Off</label> <label class="config-option__tab-label" for="bg_input_disabled">Off</label>
</div> </div>
</div> </div>
<!-- autosave -->
<div class="config-option" data-event-mouseover="set_cur_config_index(5)">
<label class="config-option__title">Autosaving</label>
<div class="config-option__list">
<input
type="radio"
data-event-blur="set_cur_config_index(-1)"
data-event-focus="set_cur_config_index(5)"
name="autosave_mode"
data-checked="autosave_mode"
value="On"
id="autosave_enabled"
style="nav-up: #bg_input_enabled"
/>
<label class="config-option__tab-label" for="autosave_enabled">On</label>
<input
type="radio"
data-event-blur="set_cur_config_index(-1)"
data-event-focus="set_cur_config_index(5)"
name="autosave_mode"
data-checked="autosave_mode"
value="Off"
id="autosave_disabled"
style="nav-up: #bg_input_disabled"
/>
<label class="config-option__tab-label" for="autosave_disabled">Off</label>
</div>
</div>
</div> </div>
<!-- Descriptions --> <!-- Descriptions -->
<div class="config__wrapper"> <div class="config__wrapper">
@ -138,7 +168,7 @@
<b>Note: To recalibrate controller gyro, set the controller down on a still, flat surface for 5 seconds.</b> <b>Note: To recalibrate controller gyro, set the controller down on a still, flat surface for 5 seconds.</b>
</p> </p>
<p data-if="cur_config_index == 3"> <p data-if="cur_config_index == 3">
Controls the sensitivity of mouse aiming. <b>Setting this to zero will disable mouse aiming.</b> Controls the sensitivity of mouse aiming when using items in first person. <b>Setting this to zero will disable mouse aiming.</b>
<br /> <br />
<br /> <br />
<b>Note: This option does not allow mouse buttons to activate items. Mouse aiming is is intended to be used with inputs that are mapped to mouse movement, such as gyro on Steam Deck.</b> <b>Note: This option does not allow mouse buttons to activate items. Mouse aiming is is intended to be used with inputs that are mapped to mouse movement, such as gyro on Steam Deck.</b>
@ -148,6 +178,11 @@
<br/> <br/>
<b>This setting does not affect keyboard input.</b> <b>This setting does not affect keyboard input.</b>
</p> </p>
<p data-if="cur_config_index == 5">
Enables or disables the autosave feature.
<br/>
<b>If any owl save exists when an autosave is made, the owl save will get replaced.</b>
</p>
</div> </div>
</div> </div>
</form> </form>

View File

@ -20,6 +20,20 @@ namespace recomp {
bool get_debug_mode_enabled(); bool get_debug_mode_enabled();
void set_debug_mode_enabled(bool enabled); void set_debug_mode_enabled(bool enabled);
enum class AutosaveMode {
On,
Off,
OptionCount
};
NLOHMANN_JSON_SERIALIZE_ENUM(recomp::AutosaveMode, {
{recomp::AutosaveMode::On, "On"},
{recomp::AutosaveMode::Off, "Off"}
});
AutosaveMode get_autosave_mode();
void set_autosave_mode(AutosaveMode mode);
}; };
#endif #endif

View File

@ -3,6 +3,7 @@
#include "z64save.h" #include "z64save.h"
#include "overlays/gamestates/ovl_file_choose/z_file_select.h" #include "overlays/gamestates/ovl_file_choose/z_file_select.h"
#include "overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h" #include "overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h"
#include "misc_funcs.h"
#define SAVE_TYPE_AUTOSAVE 2 #define SAVE_TYPE_AUTOSAVE 2
@ -268,10 +269,6 @@ void show_autosave_icon() {
autosave_icon_counter = AUTOSAVE_ICON_TOTAL_FRAMES; autosave_icon_counter = AUTOSAVE_ICON_TOTAL_FRAMES;
} }
s32 recomp_autosave_enabled() {
return 1;
}
u32 recomp_autosave_interval() { u32 recomp_autosave_interval() {
return 2 * 60 * 1000; return 2 * 60 * 1000;
} }

View File

@ -9,5 +9,6 @@ DECLARE_FUNC(void, recomp_handle_quicksave_actions, OSMesgQueue* enter_mq, OSMes
DECLARE_FUNC(void, recomp_handle_quicksave_actions_main, OSMesgQueue* enter_mq, OSMesgQueue* exit_mq); DECLARE_FUNC(void, recomp_handle_quicksave_actions_main, OSMesgQueue* enter_mq, OSMesgQueue* exit_mq);
DECLARE_FUNC(u16, recomp_get_pending_warp); DECLARE_FUNC(u16, recomp_get_pending_warp);
DECLARE_FUNC(u32, recomp_get_pending_set_time); DECLARE_FUNC(u32, recomp_get_pending_set_time);
DECLARE_FUNC(s32, recomp_autosave_enabled);
#endif #endif

View File

@ -49,3 +49,4 @@ osContGetQuery_recomp = 0x8F00007C;
recomp_get_mouse_deltas = 0x8F000080; recomp_get_mouse_deltas = 0x8F000080;
bcmp_recomp = 0x8F000084; bcmp_recomp = 0x8F000084;
osGetTime_recomp = 0x8F000088; osGetTime_recomp = 0x8F000088;
recomp_autosave_enabled = 0x8F00008C;

View File

@ -160,22 +160,28 @@ void save_general_config(const std::filesystem::path& path) {
config_json["rumble_strength"] = recomp::get_rumble_strength(); config_json["rumble_strength"] = recomp::get_rumble_strength();
config_json["gyro_sensitivity"] = recomp::get_gyro_sensitivity(); config_json["gyro_sensitivity"] = recomp::get_gyro_sensitivity();
config_json["mouse_sensitivity"] = recomp::get_mouse_sensitivity(); config_json["mouse_sensitivity"] = recomp::get_mouse_sensitivity();
config_json["autosave_mode"] = recomp::get_autosave_mode();
config_json["debug_mode"] = recomp::get_debug_mode_enabled(); config_json["debug_mode"] = recomp::get_debug_mode_enabled();
config_file << std::setw(4) << config_json; config_file << std::setw(4) << config_json;
} }
void set_general_settings_from_json(const nlohmann::json& config_json) {
recomp::set_targeting_mode(from_or_default(config_json, "targeting_mode", recomp::TargetingMode::Switch));
recomp::set_background_input_mode(from_or_default(config_json, "background_input_mode", recomp::BackgroundInputMode::On));
recomp::set_rumble_strength(from_or_default(config_json, "rumble_strength", 25));
recomp::set_gyro_sensitivity(from_or_default(config_json, "gyro_sensitivity", 50));
recomp::set_mouse_sensitivity(from_or_default(config_json, "mouse_sensitivity", is_steam_deck ? 50 : 0));
recomp::set_autosave_mode(from_or_default(config_json, "autosave_mode", recomp::AutosaveMode::On));
recomp::set_debug_mode_enabled(from_or_default(config_json, "debug_mode", false));
}
void load_general_config(const std::filesystem::path& path) { void load_general_config(const std::filesystem::path& path) {
std::ifstream config_file{path}; std::ifstream config_file{path};
nlohmann::json config_json{}; nlohmann::json config_json{};
config_file >> config_json; config_file >> config_json;
recomp::set_targeting_mode(from_or_default(config_json, "targeting_mode", recomp::TargetingMode::Switch)); set_general_settings_from_json(config_json);
recomp::set_background_input_mode(from_or_default(config_json, "background_input_mode", recomp::BackgroundInputMode::On));
recomp::set_rumble_strength(from_or_default(config_json, "rumble_strength", 25));
recomp::set_gyro_sensitivity(from_or_default(config_json, "gyro_sensitivity", 50));
recomp::set_mouse_sensitivity(from_or_default(config_json, "mouse_sensitivity", is_steam_deck ? 50 : 0));
recomp::set_debug_mode_enabled(from_or_default(config_json, "debug_mode", false));
} }
void assign_mapping(recomp::InputDevice device, recomp::GameInput input, const std::vector<recomp::InputField>& value) { void assign_mapping(recomp::InputDevice device, recomp::GameInput input, const std::vector<recomp::InputField>& value) {
@ -374,6 +380,8 @@ void recomp::load_config() {
load_general_config(general_path); load_general_config(general_path);
} }
else { else {
// Set the general settings from an empty json to use defaults.
set_general_settings_from_json({});
save_general_config(general_path); save_general_config(general_path);
} }

View File

@ -1,6 +1,7 @@
#include <cmath> #include <cmath>
#include "recomp.h" #include "recomp.h"
#include "recomp_config.h"
#include "recomp_input.h" #include "recomp_input.h"
#include "recomp_ui.h" #include "recomp_ui.h"
#include "recomp_sound.h" #include "recomp_sound.h"
@ -88,3 +89,7 @@ extern "C" void recomp_get_low_health_beeps_enabled(uint8_t* rdram, recomp_conte
extern "C" void recomp_time_us(uint8_t* rdram, recomp_context* ctx) { extern "C" void recomp_time_us(uint8_t* rdram, recomp_context* ctx) {
_return(ctx, static_cast<u32>(std::chrono::duration_cast<std::chrono::microseconds>(ultramodern::time_since_start()).count())); _return(ctx, static_cast<u32>(std::chrono::duration_cast<std::chrono::microseconds>(ultramodern::time_since_start()).count()));
} }
extern "C" void recomp_autosave_enabled(uint8_t* rdram, recomp_context* ctx) {
_return(ctx, static_cast<s32>(recomp::get_autosave_mode() == recomp::AutosaveMode::On));
}

View File

@ -269,12 +269,14 @@ void recomp::open_quit_game_prompt() {
); );
} }
// These defaults values don't matter, as the config file handling overrides them.
struct ControlOptionsContext { struct ControlOptionsContext {
int rumble_strength = 50; // 0 to 100 int rumble_strength; // 0 to 100
int gyro_sensitivity = 50; // 0 to 100 int gyro_sensitivity; // 0 to 100
int mouse_sensitivity = 50; // 0 to 100 int mouse_sensitivity; // 0 to 100
recomp::TargetingMode targeting_mode = recomp::TargetingMode::Switch; recomp::TargetingMode targeting_mode;
recomp::BackgroundInputMode background_input_mode = recomp::BackgroundInputMode::On; recomp::BackgroundInputMode background_input_mode;
recomp::AutosaveMode autosave_mode;
}; };
ControlOptionsContext control_options_context; ControlOptionsContext control_options_context;
@ -340,6 +342,17 @@ void recomp::set_background_input_mode(recomp::BackgroundInputMode mode) {
); );
} }
recomp::AutosaveMode recomp::get_autosave_mode() {
return control_options_context.autosave_mode;
}
void recomp::set_autosave_mode(recomp::AutosaveMode mode) {
control_options_context.autosave_mode = mode;
if (general_model_handle) {
general_model_handle.DirtyVariable("autosave_mode");
}
}
struct SoundOptionsContext { struct SoundOptionsContext {
std::atomic<int> bgm_volume; std::atomic<int> bgm_volume;
std::atomic<int> low_health_beeps_enabled; // RmlUi doesn't seem to like "true"/"false" strings for setting variants so an int is used here instead. std::atomic<int> low_health_beeps_enabled; // RmlUi doesn't seem to like "true"/"false" strings for setting variants so an int is used here instead.
@ -824,6 +837,7 @@ public:
constructor.Bind("mouse_sensitivity", &control_options_context.mouse_sensitivity); constructor.Bind("mouse_sensitivity", &control_options_context.mouse_sensitivity);
bind_option(constructor, "targeting_mode", &control_options_context.targeting_mode); bind_option(constructor, "targeting_mode", &control_options_context.targeting_mode);
bind_option(constructor, "background_input_mode", &control_options_context.background_input_mode); bind_option(constructor, "background_input_mode", &control_options_context.background_input_mode);
bind_option(constructor, "autosave_mode", &control_options_context.autosave_mode);
general_model_handle = constructor.GetModelHandle(); general_model_handle = constructor.GetModelHandle();
} }

View File

@ -521,7 +521,7 @@ public:
if (row_byte_padding == 0) { if (row_byte_padding == 0) {
// Copy row-by-row if the image is flipped. // Copy row-by-row if the image is flipped.
if (flip_y) { if (flip_y) {
for (uint32_t row = 0; row < source_dimensions.y; row++) { for (int row = 0; row < source_dimensions.y; row++) {
memcpy(dst_data + row_byte_width * (source_dimensions.y - row - 1), source + row_byte_width * row, row_byte_width); memcpy(dst_data + row_byte_width * (source_dimensions.y - row - 1), source + row_byte_width * row, row_byte_width);
} }
} }
@ -536,7 +536,7 @@ public:
uint32_t src_stride = flip_y ? -row_pitch : row_pitch; uint32_t src_stride = flip_y ? -row_pitch : row_pitch;
size_t offset = 0; size_t offset = 0;
for (uint32_t row = 0; row < source_dimensions.y; row++) { //(offset + increment) <= image_size_bytes) { for (int row = 0; row < source_dimensions.y; row++) { //(offset + increment) <= image_size_bytes) {
memcpy(dst_data, src_data, row_pitch); memcpy(dst_data, src_data, row_pitch);
src_data += src_stride; src_data += src_stride;
offset += row_pitch; offset += row_pitch;
@ -581,7 +581,7 @@ public:
mvp_ = projection_mtx_ * transform_; mvp_ = projection_mtx_ * transform_;
} }
void start(RT64::RenderCommandList* list, uint32_t image_width, uint32_t image_height) { void start(RT64::RenderCommandList* list, int image_width, int image_height) {
list_ = list; list_ = list;
if (multisampling_.sampleCount > 1) { if (multisampling_.sampleCount > 1) {