Initial Review Changes

This commit is contained in:
Joshua de Reeper 2026-05-20 12:12:49 +02:00 committed by deReeperJosh
parent 29ffab52f7
commit dc1ef5d844
9 changed files with 111 additions and 86 deletions

View File

@ -630,7 +630,7 @@ bool sky_portal::remove_skylander(u8 sky_num)
thesky.queued_status.push(2);
thesky.queued_status.push(0);
thesky.sky_file.close();
ui_skylanders[thesky.ui_slot] = std::nullopt;
::at32(ui_skylanders, thesky.ui_slot) = std::nullopt;
thesky.ui_slot = 0xFF;
return true;
}
@ -646,7 +646,7 @@ u8 sky_portal::load_skylander(u8 ui_slot, u8* buf, fs::file in_file)
u8 found_slot = 0xFF;
// mimics spot retaining on the portal
for (u8 i = 0; i < 8; i++)
for (u8 i = 0; i < MAX_SKYLANDERS; i++)
{
if ((skylanders[i].status & 1) == 0)
{
@ -665,7 +665,7 @@ u8 sky_portal::load_skylander(u8 ui_slot, u8* buf, fs::file in_file)
ensure(found_slot != 0xFF);
ui_skylanders[ui_slot] = std::make_tuple(found_slot, reinterpret_cast<le_t<u16>&>(buf[0x10]), reinterpret_cast<le_t<u16>&>(buf[0x1C]));
::at32(ui_skylanders, ui_slot) = std::make_tuple(found_slot, reinterpret_cast<le_t<u16>&>(buf[0x10]), reinterpret_cast<le_t<u16>&>(buf[0x1C]));
skylander& thesky = skylanders[found_slot];
memcpy(thesky.data.data(), buf, thesky.data.size());
thesky.sky_file = std::move(in_file);
@ -678,9 +678,10 @@ u8 sky_portal::load_skylander(u8 ui_slot, u8* buf, fs::file in_file)
return found_slot;
}
std::optional<std::tuple<u8, u16, u16>> sky_portal::get_skylander(u8 ui_slot)
std::optional<std::tuple<u8, u16, u16>> sky_portal::get_skylander(u8 ui_slot) const
{
return ui_skylanders[ui_slot];
//std::lock_guard lock(sky_mutex);
return ::at32(ui_skylanders, ui_slot);
}
usb_device_skylander::usb_device_skylander(const std::array<u8, 7>& location)
@ -777,7 +778,7 @@ void usb_device_skylander::control_transfer(u8 bmRequestType, u8 bRequest, u16 w
ensure(buf_size == 3 || buf_size == 32);
const u8 sky_num = buf[1] & 0xF;
ensure(sky_num < 8);
ensure(sky_num < MAX_SKYLANDERS);
const u8 block = buf[2];
ensure(block < 0x40);
@ -813,7 +814,7 @@ void usb_device_skylander::control_transfer(u8 bmRequestType, u8 bRequest, u16 w
ensure(buf_size == 19 || buf_size == 32);
const u8 sky_num = buf[1] & 0xF;
ensure(sky_num < 8);
ensure(sky_num < MAX_SKYLANDERS);
const u8 block = buf[2];
ensure(block < 0x40);

View File

@ -5,6 +5,8 @@
#include <optional>
#include <queue>
constexpr auto MAX_SKYLANDERS = 8;
struct skylander
{
fs::file sky_file;
@ -31,17 +33,19 @@ public:
bool remove_skylander(u8 sky_num);
u8 load_skylander(u8 ui_slot, u8* buf, fs::file in_file);
std::optional<std::tuple<u8, u16, u16>> get_skylander(u8 ui_slot);
std::optional<std::tuple<u8, u16, u16>> get_skylander(u8 ui_slot) const;
bool is_active() const { return activated; }
protected:
shared_mutex sky_mutex;
bool activated = true;
bool activated = false;
u8 interrupt_counter = 0;
u8 r = 0, g = 0, b = 0;
skylander skylanders[8];
std::optional<std::tuple<u8, u16, u16>> ui_skylanders[8];
std::array<skylander, MAX_SKYLANDERS> skylanders {};
std::array<std::optional<std::tuple<u8, u16, u16>>, MAX_SKYLANDERS> ui_skylanders {};
};
extern sky_portal g_skyportal;

View File

@ -10,6 +10,7 @@
#include "Emu/System.h"
#include "Emu/system_config.h"
#include "Emu/Cell/Modules/sceNpTrophy.h"
#include "Emu/Io/Skylander.h"
extern atomic_t<bool> g_user_asked_for_recording;
@ -97,20 +98,23 @@ namespace rsx
});
}
add_item(home_menu::fa_icon::usb, get_localized_string(localized_string_id::HOME_MENU_SETTINGS_USB_DEVICES), [](pad_button btn) -> page_navigation
if (g_skyportal.is_active())
{
if (btn != pad_button::cross) return page_navigation::stay;
rsx_log.notice("User selected devices in home menu");
Emu.CallFromMainThread([]()
add_item(home_menu::fa_icon::usb, get_localized_string(localized_string_id::HOME_MENU_SETTINGS_SKYLANDER_MANAGER), [](pad_button btn) -> page_navigation
{
if (auto manager = g_fxo->try_get<rsx::overlays::display_manager>())
if (btn != pad_button::cross) return page_navigation::stay;
rsx_log.notice("User selected devices in home menu");
Emu.CallFromMainThread([]()
{
manager->create<rsx::overlays::skylander_dialog>()->show();
}
if (auto manager = g_fxo->try_get<rsx::overlays::display_manager>())
{
manager->create<rsx::overlays::skylander_dialog>()->show();
}
});
return page_navigation::stay;
});
return page_navigation::stay;
});
}
add_item(home_menu::fa_icon::screenshot, get_localized_string(localized_string_id::HOME_MENU_SCREENSHOT), [](pad_button btn) -> page_navigation
{

View File

@ -15,48 +15,17 @@ namespace rsx
static std::string last_skylander_path = "";
skylander_dialog::skylander_list_entry::skylander_list_entry(std::string name)
skylander_dialog::skylander_list_entry::skylander_list_entry(std::string_view name)
{
std::unique_ptr<overlay_element> label_text = std::make_unique<label>(name);
std::unique_ptr<overlay_element> label_load = std::make_unique<label>("Load");
std::unique_ptr<overlay_element> load_image = std::make_unique<image_view>(30, 30);
std::unique_ptr<overlay_element> label_clear = std::make_unique<label>("Clear");
std::unique_ptr<overlay_element> clear_image = std::make_unique<image_view>(30, 30);
std::unique_ptr<overlay_element> label_create = std::make_unique<label>("Create");
std::unique_ptr<overlay_element> create_image = std::make_unique<image_view>(30, 30);
label_text->set_size(130, 30);
label_text->set_font("Arial", 16);
label_text->set_wrap_text(true);
label_text->back_color.a = 0.f;
label_load->set_size(100, 30);
label_load->set_font("Arial", 16);
label_load->set_wrap_text(true);
label_load->back_color.a = 0.f;
label_clear->set_size(100, 30);
label_clear->set_font("Arial", 16);
label_clear->set_wrap_text(true);
label_clear->back_color.a = 0.f;
label_create->set_size(100, 30);
label_create->set_font("Arial", 16);
label_create->set_wrap_text(true);
label_create->back_color.a = 0.f;
static_cast<image_view*>(load_image.get())->set_image_resource(resource_config::standard_image_resource::cross);
static_cast<image_view*>(clear_image.get())->set_image_resource(resource_config::standard_image_resource::square);
static_cast<image_view*>(create_image.get())->set_image_resource(resource_config::standard_image_resource::triangle);
this->pack_padding = 15;
add_element(label_text);
add_element(load_image);
add_element(label_load);
add_element(clear_image);
add_element(label_clear);
add_element(create_image);
add_element(label_create);
}
skylander_dialog::skylander_dialog()
@ -70,10 +39,31 @@ namespace rsx
m_description = std::make_unique<label>();
m_description->set_font("Arial", 20);
m_description->set_pos(20, 37);
m_description->set_text("Emulated Skylander Portal");
m_description->set_text(get_localized_string(localized_string_id::HOME_MENU_SETTINGS_SKYLANDER_MANAGER));
m_description->auto_resize();
m_description->back_color.a = 0.f;
m_load_button = std::make_unique<image_button>();
m_load_button->set_text(localized_string_id::HOME_MENU_SETTINGS_SKYLANDER_LOAD);
m_load_button->set_image_resource(resource_config::standard_image_resource::cross);
m_load_button->set_size(120, 30);
m_load_button->set_pos(180, sky_list_y + sky_list_h + 20);
m_load_button->set_font("Arial", 16);
m_clear_button = std::make_unique<image_button>();
m_clear_button->set_text(localized_string_id::HOME_MENU_SETTINGS_SKYLANDER_CLEAR);
m_clear_button->set_image_resource(resource_config::standard_image_resource::square);
m_clear_button->set_size(120, 30);
m_clear_button->set_pos(360, sky_list_y + sky_list_h + 20);
m_clear_button->set_font("Arial", 16);
m_create_button = std::make_unique<image_button>();
m_create_button->set_text(localized_string_id::HOME_MENU_SETTINGS_SKYLANDER_CREATE);
m_create_button->set_image_resource(resource_config::standard_image_resource::triangle);
m_create_button->set_size(120, 30);
m_create_button->set_pos(540, sky_list_y + sky_list_h + 20);
m_create_button->set_font("Arial", 16);
fade_animation.duration_sec = 0.15f;
return_code = selection_code::canceled;
@ -160,6 +150,9 @@ namespace rsx
result.add(m_list->get_compiled());
}
result.add(m_description->get_compiled());
result.add(m_load_button->get_compiled());
result.add(m_clear_button->get_compiled());
result.add(m_create_button->get_compiled());
fade_animation.apply(result);
@ -195,10 +188,10 @@ namespace rsx
void skylander_dialog::reload()
{
s32 selected_index = m_list ? m_list->get_selected_index() : 0;
const s32 selected_index = m_list ? m_list->get_selected_index() : 0;
std::vector<std::unique_ptr<overlay_element>> entries;
for (u8 sky_slot = 0; sky_slot < 8; ++sky_slot)
for (u8 sky_slot = 0; sky_slot < MAX_SKYLANDERS; ++sky_slot)
{
if (const auto& slot_infos = g_skyportal.get_skylander(sky_slot))
{
@ -239,13 +232,13 @@ namespace rsx
m_list->select_entry(selected_index);
}
m_description->set_text("Emulated Skylander Portal");
m_description->set_text(get_localized_string(localized_string_id::HOME_MENU_SETTINGS_SKYLANDER_MANAGER));
m_description->auto_resize();
}
void skylander_dialog::clear_skylander(u8 sky_slot)
{
ensure(sky_slot < 8);
ensure(sky_slot < MAX_SKYLANDERS);
if (const auto& slot_infos = g_skyportal.get_skylander(sky_slot))
{
@ -259,7 +252,7 @@ namespace rsx
void skylander_dialog::load_skylander(u8 slot)
{
ensure(slot < 8);
ensure(slot < MAX_SKYLANDERS);
Emu.CallFromMainThread([this, slot]()
{
@ -274,7 +267,7 @@ namespace rsx
});
}
skylander_load_dialog::skylander_file_list_entry::skylander_file_list_entry(skylander_file_type type, std::string file_name)
skylander_load_dialog::skylander_file_list_entry::skylander_file_list_entry(skylander_file_type type, const std::string& file_name)
: file_name(file_name), type(type)
{
if (type == skylander_file_type::folder)
@ -285,9 +278,11 @@ namespace rsx
{
icon_data = rsx::overlays::resource_config::load_icon("home/32/file-solid.png");
}
std::unique_ptr<overlay_element> image = std::make_unique<image_view>(30, 30);
static_cast<image_view*>(image.get())->set_raw_image(icon_data.get());
std::unique_ptr<overlay_element> label_text = std::make_unique<label>(file_name);
auto image = std::make_unique<image_view>(30, 30);
image->set_raw_image(icon_data.get());
image->set_padding(4, 4, 4, 4);
auto label_text = std::make_unique<label>(file_name);
label_text->set_size(400, 30);
label_text->set_font("Arial", 16);
label_text->set_wrap_text(true);
@ -309,7 +304,7 @@ namespace rsx
m_description = std::make_unique<label>();
m_description->set_font("Arial", 20);
m_description->set_pos(20, 37);
m_description->set_text("Emulated Skylander Portal");
m_description->set_text(get_localized_string(localized_string_id::HOME_MENU_SETTINGS_SKYLANDER_LOAD));
m_description->auto_resize();
m_description->back_color.a = 0.f;
@ -344,13 +339,13 @@ namespace rsx
play_sound(sound_effect::accept);
if (m_list && !m_list->m_items.empty())
{
auto selected_entry = static_cast<const skylander_file_list_entry*>(m_list->get_selected_entry());
const auto selected_entry = static_cast<const skylander_file_list_entry*>(m_list->get_selected_entry());
rsx_log.notice("Selected skylander file entry: %s (type: %d)", selected_entry->get_file_name(), static_cast<u8>(selected_entry->get_type()));
if (selected_entry->get_type() == skylander_file_type::folder)
{
if (selected_entry->get_file_name() == "..")
{
auto last_slash_pos = last_skylander_path.find_last_of('/', last_skylander_path.length() - 2);
const auto last_slash_pos = last_skylander_path.find_last_of('/', last_skylander_path.length() - 2);
if (last_slash_pos != std::string::npos)
{
last_skylander_path = last_skylander_path.substr(0, last_slash_pos + 1);
@ -364,16 +359,17 @@ namespace rsx
}
else if (selected_entry->get_type() == skylander_file_type::file)
{
rsx_log.notice("Loading skylander from file: %s", last_skylander_path + selected_entry->get_file_name());
fs::file sky_file(last_skylander_path + selected_entry->get_file_name(), fs::read + fs::write + fs::lock);
std::string full_path = last_skylander_path + selected_entry->get_file_name();
rsx_log.notice("Loading skylander from file: %s", full_path);
fs::file sky_file(full_path, fs::read + fs::write + fs::lock);
if (!sky_file)
{
rsx_log.error("Failed to open skylander file: %s", last_skylander_path + selected_entry->get_file_name());
rsx_log.error("Failed to open skylander file: %s", full_path);
}
std::array<u8, 0x40 * 0x10> data;
if (sky_file.read(data.data(), data.size()) != data.size())
{
rsx_log.error("Failed to read skylander file: %s", last_skylander_path + selected_entry->get_file_name());
rsx_log.error("Failed to read skylander file: %s", full_path);
}
if (const auto skylander = g_skyportal.get_skylander(slot))
{
@ -478,7 +474,7 @@ namespace rsx
void skylander_load_dialog::reload()
{
s32 selected_index = 0;
const s32 selected_index = 0;
std::vector<std::unique_ptr<overlay_element>> entries;
@ -525,7 +521,7 @@ namespace rsx
m_list->select_entry(selected_index);
}
m_description->set_text("Select Skylander File");
m_description->set_text(get_localized_string(localized_string_id::HOME_MENU_SETTINGS_SKYLANDER_LOAD));
m_description->auto_resize();
}
} // namespace overlays

View File

@ -7,14 +7,13 @@ namespace rsx
{
namespace overlays
{
struct skylander_dialog : public user_interface
{
private:
struct skylander_list_entry : horizontal_layout
{
public:
skylander_list_entry(std::string name);
skylander_list_entry(std::string_view name);
};
void reload();
@ -24,6 +23,9 @@ namespace rsx
std::unique_ptr<overlay_element> m_dim_background;
std::unique_ptr<list_view> m_list;
std::unique_ptr<label> m_description;
std::unique_ptr<image_button> m_load_button;
std::unique_ptr<image_button> m_clear_button;
std::unique_ptr<image_button> m_create_button;
animation_color_interpolate fade_animation;
@ -39,6 +41,7 @@ namespace rsx
void show();
};
enum class skylander_file_type
{
folder,
@ -56,10 +59,17 @@ namespace rsx
skylander_file_type type;
public:
skylander_file_list_entry(skylander_file_type type, std::string file_name);
std::string get_file_name() const { return file_name; }
skylander_file_type get_type() const { return type; }
skylander_file_list_entry(skylander_file_type type, const std::string& file_name);
const std::string get_file_name() const
{
return file_name;
}
skylander_file_type get_type() const
{
return type;
}
};
void reload();
u8 slot = 0xff;

View File

@ -276,6 +276,11 @@ enum class localized_string_id
HOME_MENU_SETTINGS_PERFORMANCE_OVERLAY_OPACITY,
HOME_MENU_SETTINGS_PERFORMANCE_OVERLAY_USE_WINDOW_SPACE,
HOME_MENU_SETTINGS_USB_DEVICES,
HOME_MENU_SETTINGS_SKYLANDER_CLEAR,
HOME_MENU_SETTINGS_SKYLANDER_CREATE,
HOME_MENU_SETTINGS_SKYLANDER_LOAD,
HOME_MENU_SETTINGS_SKYLANDER_LOAD_FILE,
HOME_MENU_SETTINGS_SKYLANDER_MANAGER,
HOME_MENU_SETTINGS_DEBUG,
HOME_MENU_SETTINGS_DEBUG_OVERLAY,
HOME_MENU_SETTINGS_DEBUG_INPUT_OVERLAY,

View File

@ -295,7 +295,11 @@ private:
case localized_string_id::HOME_MENU_SETTINGS_PERFORMANCE_OVERLAY_FONT_SIZE: return tr("Font Size", "Performance Overlay");
case localized_string_id::HOME_MENU_SETTINGS_PERFORMANCE_OVERLAY_OPACITY: return tr("Opacity", "Performance Overlay");
case localized_string_id::HOME_MENU_SETTINGS_PERFORMANCE_OVERLAY_USE_WINDOW_SPACE: return tr("Use Window Space", "Performance Overlay");
case localized_string_id::HOME_MENU_SETTINGS_USB_DEVICES: return tr("USB Devices");
case localized_string_id::HOME_MENU_SETTINGS_SKYLANDER_CLEAR: return tr("Clear Skylander");
case localized_string_id::HOME_MENU_SETTINGS_SKYLANDER_CREATE: return tr("Create Skylander");
case localized_string_id::HOME_MENU_SETTINGS_SKYLANDER_LOAD: return tr("Load Skylander");
case localized_string_id::HOME_MENU_SETTINGS_SKYLANDER_LOAD_FILE: return tr("Select Skylander File");
case localized_string_id::HOME_MENU_SETTINGS_SKYLANDER_MANAGER: return tr("Skylander Manager");
case localized_string_id::HOME_MENU_SETTINGS_DEBUG: return tr("Debug");
case localized_string_id::HOME_MENU_SETTINGS_DEBUG_OVERLAY: return tr("Debug Overlay", "Debug");
case localized_string_id::HOME_MENU_SETTINGS_DEBUG_INPUT_OVERLAY: return tr("Input Debug Overlay", "Debug");

View File

@ -1,7 +1,6 @@
#include "stdafx.h"
#include "Utilities/File.h"
#include "skylander_dialog.h"
#include "Emu/Io/Skylander.h"
#include <QLabel>
#include <QGroupBox>
@ -212,7 +211,7 @@ skylander_dialog::skylander_dialog(QWidget* parent)
QGroupBox* group_skylanders = new QGroupBox(tr("Active Portal Skylanders:"));
QVBoxLayout* vbox_group = new QVBoxLayout();
for (auto i = 0; i < UI_SKY_NUM; i++)
for (auto i = 0; i < MAX_SKYLANDERS; i++)
{
if (i != 0)
{
@ -255,9 +254,12 @@ skylander_dialog::~skylander_dialog()
skylander_dialog* skylander_dialog::get_dlg(QWidget* parent)
{
if (inst == nullptr) {
if (inst == nullptr)
{
inst = new skylander_dialog(parent);
} else {
}
else
{
inst->update_edits();
}
@ -321,7 +323,7 @@ void skylander_dialog::load_skylander_path(u8 slot, const QString& path)
void skylander_dialog::update_edits()
{
for (auto i = 0; i < UI_SKY_NUM; i++)
for (auto i = 0; i < MAX_SKYLANDERS; i++)
{
QString display_string;
if (const auto& sd = g_skyportal.get_skylander(i))

View File

@ -1,12 +1,11 @@
#pragma once
#include "util/types.hpp"
#include "Emu/Io/Skylander.h"
#include <QDialog>
#include <QLineEdit>
constexpr auto UI_SKY_NUM = 8;
class skylander_creator_dialog : public QDialog
{
Q_OBJECT
@ -40,7 +39,7 @@ protected:
void update_edits();
protected:
QLineEdit* edit_skylanders[UI_SKY_NUM]{};
QLineEdit* edit_skylanders[MAX_SKYLANDERS]{};
private:
static skylander_dialog* inst;