Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overlays: Add a selection of dynamic settings to the home menu #13368

Merged
merged 7 commits into from
Feb 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions Utilities/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,8 @@ namespace cfg
int_type def;

// Expose range
static const s64 max = Max;
static const s64 min = Min;
static constexpr s64 max = Max;
static constexpr s64 min = Min;

_int(node* owner, const std::string& name, int_type def = std::min<int_type>(Max, std::max<int_type>(Min, 0)), bool dynamic = false)
: _base(type::_int, owner, name, dynamic)
Expand Down Expand Up @@ -334,6 +334,7 @@ namespace cfg

void set(const s64& value)
{
ensure(value >= Min && value <= Max);
m_value = static_cast<int_type>(value);
}

Expand Down Expand Up @@ -405,6 +406,7 @@ namespace cfg

void set(const f64& value)
{
ensure(value >= Min && value <= Max);
m_value = static_cast<float_type>(value);
}

Expand Down Expand Up @@ -435,8 +437,8 @@ namespace cfg
int_type def;

// Expose range
static const u64 max = Max;
static const u64 min = Min;
static constexpr u64 max = Max;
static constexpr u64 min = Min;

uint(node* owner, const std::string& name, int_type def = std::max<int_type>(Min, 0), bool dynamic = false)
: _base(type::uint, owner, name, dynamic)
Expand Down Expand Up @@ -484,6 +486,7 @@ namespace cfg

void set(const u64& value)
{
ensure(value >= Min && value <= Max);
m_value = static_cast<int_type>(value);
}

Expand Down
7 changes: 6 additions & 1 deletion rpcs3/Emu/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -437,13 +437,18 @@ target_sources(rpcs3_emu PRIVATE
RSX/Common/TextureUtils.cpp
RSX/Common/texture_cache.cpp
RSX/Null/NullGSRender.cpp
RSX/Overlays/HomeMenu/overlay_home_menu.cpp
RSX/Overlays/HomeMenu/overlay_home_menu_components.cpp
RSX/Overlays/HomeMenu/overlay_home_menu_main_menu.cpp
RSX/Overlays/HomeMenu/overlay_home_menu_message_box.cpp
RSX/Overlays/HomeMenu/overlay_home_menu_page.cpp
RSX/Overlays/HomeMenu/overlay_home_menu_settings.cpp
RSX/Overlays/overlay_animated_icon.cpp
RSX/Overlays/overlay_animation.cpp
RSX/Overlays/overlay_controls.cpp
RSX/Overlays/overlay_cursor.cpp
RSX/Overlays/overlay_edit_text.cpp
RSX/Overlays/overlay_fonts.cpp
RSX/Overlays/overlay_home_menu.cpp
RSX/Overlays/overlay_list_view.cpp
RSX/Overlays/overlay_media_list_dialog.cpp
RSX/Overlays/overlay_message.cpp
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/Modules/cellAudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -427,5 +427,5 @@ using cell_audio = named_thread<cell_audio_thread>;
namespace audio
{
cell_audio_config::raw_config get_raw_config();
void configure_audio(bool force_reset = false);
extern void configure_audio(bool force_reset = false);
}
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1268,7 +1268,7 @@ bool rsxaudio_data_thread::enqueue_data(RsxaudioPort dst, bool silence, const vo

namespace audio
{
void configure_rsxaudio()
extern void configure_rsxaudio()
{
if (g_cfg.audio.provider == audio_provider::rsxaudio && g_fxo->is_init<rsx_audio_backend>())
{
Expand Down
216 changes: 216 additions & 0 deletions rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
#include "stdafx.h"
#include "overlay_home_menu.h"
#include "Emu/RSX/RSXThread.h"

#include <sstream>
#include <iomanip>

namespace rsx
{
namespace overlays
{
std::string get_time_string()
{
std::ostringstream ost;
const std::time_t dateTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
const std::tm tm = *std::localtime(&dateTime);
ost << std::put_time(&tm, "%Y/%m/%d %H:%M:%S");
return ost.str();
}

home_menu_dialog::home_menu_dialog()
: m_main_menu(20, 85, virtual_width - 2 * 20, 540, false, nullptr)
{
m_allow_input_on_pause = true;

m_dim_background.set_size(virtual_width, virtual_height);
m_dim_background.back_color.a = 0.5f;

m_description.set_font("Arial", 20);
m_description.set_pos(20, 37);
m_description.set_text(m_main_menu.title);
m_description.auto_resize();
m_description.back_color.a = 0.f;

m_time_display.set_font("Arial", 14);
m_time_display.set_text(get_time_string());
m_time_display.auto_resize();
m_time_display.set_pos(virtual_width - (20 + m_time_display.w), (m_description.y + m_description.h) - m_time_display.h);
m_time_display.back_color.a = 0.f;

fade_animation.duration = 0.15f;

return_code = selection_code::canceled;
}

void home_menu_dialog::update()
{
static u64 frame = 0;

if (Emu.IsPaused())
{
// Let's keep updating the animation anyway
frame++;
}
else
{
frame = rsx::get_current_renderer()->vblank_count;
}

if (fade_animation.active)
{
fade_animation.update(frame);
}

static std::string last_time;
std::string new_time = get_time_string();

if (last_time != new_time)
{
m_time_display.set_text(new_time);
m_time_display.auto_resize();
last_time = std::move(new_time);
}
}

void home_menu_dialog::on_button_pressed(pad_button button_press)
{
if (fade_animation.active) return;

// Increase auto repeat interval for some buttons
switch (button_press)
{
case pad_button::dpad_left:
case pad_button::dpad_right:
case pad_button::ls_left:
case pad_button::ls_right:
m_auto_repeat_ms_interval = 10;
break;
default:
m_auto_repeat_ms_interval = m_auto_repeat_ms_interval_default;
break;
}

const page_navigation navigation = m_main_menu.handle_button_press(button_press);

switch (navigation)
{
case page_navigation::back:
case page_navigation::next:
{
if (home_menu_page* page = m_main_menu.get_current_page(true))
{
std::string path = page->title;
for (home_menu_page* parent = page->parent; parent; parent = parent->parent)
{
path = parent->title + " > " + path;
}
m_description.set_text(path);
m_description.auto_resize();
}
break;
}
case page_navigation::exit:
{
fade_animation.current = color4f(1.f);
fade_animation.end = color4f(0.f);
fade_animation.active = true;

fade_animation.on_finish = [this]
{
close(true, true);

if (g_cfg.misc.pause_during_home_menu)
{
Emu.BlockingCallFromMainThread([]()
{
Emu.Resume();
});
}
};
break;
}
case page_navigation::stay:
{
break;
}
}
}

compiled_resource home_menu_dialog::get_compiled()
{
if (!visible)
{
return {};
}

compiled_resource result;
result.add(m_dim_background.get_compiled());
result.add(m_main_menu.get_compiled());
result.add(m_description.get_compiled());
result.add(m_time_display.get_compiled());

fade_animation.apply(result);

return result;
}

struct home_menu_dialog_thread
{
static constexpr auto thread_name = "Home Menu Thread"sv;
};

error_code home_menu_dialog::show(std::function<void(s32 status)> on_close)
{
visible = false;

fade_animation.current = color4f(0.f);
fade_animation.end = color4f(1.f);
fade_animation.active = true;

this->on_close = std::move(on_close);
visible = true;

auto& list_thread = g_fxo->get<named_thread<home_menu_dialog_thread>>();

const auto notify = std::make_shared<atomic_t<bool>>(false);

list_thread([&, notify]()
{
const u64 tbit = alloc_thread_bit();
g_thread_bit = tbit;

*notify = true;
notify->notify_one();

auto ref = g_fxo->get<display_manager>().get(uid);

if (const auto error = run_input_loop())
{
if (error != selection_code::canceled)
{
rsx_log.error("Home menu dialog input loop exited with error code=%d", error);
}
}

thread_bits &= ~tbit;
thread_bits.notify_all();
});

if (g_cfg.misc.pause_during_home_menu)
{
Emu.BlockingCallFromMainThread([]()
{
Emu.Pause(false, false);
});
}

while (list_thread < thread_state::errored && !*notify)
{
notify->wait(false, atomic_wait_timeout{1'000'000});
}

return CELL_OK;
}
} // namespace overlays
} // namespace RSX
32 changes: 32 additions & 0 deletions rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once

#include "Emu/RSX/Overlays/overlays.h"
#include "Emu/Cell/ErrorCodes.h"
#include "overlay_home_menu_main_menu.h"

namespace rsx
{
namespace overlays
{
struct home_menu_dialog : public user_interface
{
public:
home_menu_dialog();

void update() override;
void on_button_pressed(pad_button button_press) override;

compiled_resource get_compiled() override;

error_code show(std::function<void(s32 status)> on_close);

private:
home_menu_main_menu m_main_menu;
overlay_element m_dim_background{};
label m_description{};
label m_time_display{};

animation_color_interpolate fade_animation{};
};
}
}
65 changes: 65 additions & 0 deletions rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_components.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include "stdafx.h"
#include "overlay_home_menu_components.h"

namespace rsx
{
namespace overlays
{
home_menu_entry::home_menu_entry(const std::string& text)
{
std::unique_ptr<overlay_element> text_stack = std::make_unique<vertical_layout>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, these can be objects.

// In header file
vertical_layout m_text_stack;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add_element takes a unique_ptr and moves it

std::unique_ptr<overlay_element> padding = std::make_unique<spacer>();
std::unique_ptr<overlay_element> title = std::make_unique<label>(text);

padding->set_size(1, 1);
title->set_size(overlay::virtual_width - 2 * menu_entry_margin, menu_entry_height);
title->set_font("Arial", 16);
title->set_wrap_text(true);
title->align_text(text_align::center);

// Make back color transparent for text
title->back_color.a = 0.f;

static_cast<vertical_layout*>(text_stack.get())->pack_padding = 5;
static_cast<vertical_layout*>(text_stack.get())->add_element(padding);
static_cast<vertical_layout*>(text_stack.get())->add_element(title);

add_element(text_stack);
}

home_menu_checkbox::home_menu_checkbox(cfg::_bool* setting, const std::string& text) : home_menu_setting(setting, text)
{
m_background.set_size(menu_entry_margin, menu_entry_margin);
m_background.set_pos(overlay::virtual_width / 2 + menu_entry_margin, 0);

m_checkbox.set_size(m_background.w - 2, m_background.h - 2);
m_checkbox.set_pos(m_background.x, m_background.y);
}

compiled_resource& home_menu_checkbox::get_compiled()
{
update_value();

if (!is_compiled)
{
const f32 col = m_last_value ? 1.0f : 0.3f;
const f32 bkg = m_last_value ? 0.3f : 1.0f;
m_background.back_color.r = bkg;
m_background.back_color.g = bkg;
m_background.back_color.b = bkg;
m_checkbox.back_color.r = col;
m_checkbox.back_color.g = col;
m_checkbox.back_color.b = col;

m_background.set_pos(m_background.x, y + (h - m_background.h) / 2);
m_checkbox.set_pos(m_background.x + 1, m_background.y + 1);

compiled_resources = horizontal_layout::get_compiled();
compiled_resources.add(m_background.get_compiled());
compiled_resources.add(m_checkbox.get_compiled());
}

return compiled_resources;
}
}
}
Loading