Qt/Core: Refactor GBA Core accessors

This commit is contained in:
Bonta 2021-07-22 23:22:47 +02:00
parent f380c23fda
commit ee64e217f4
5 changed files with 78 additions and 99 deletions

View File

@ -292,6 +292,25 @@ bool Core::IsStarted() const
return m_started;
}
CoreInfo Core::GetCoreInfo() const
{
CoreInfo info{};
info.device_number = m_device_number;
info.width = GBA_VIDEO_HORIZONTAL_PIXELS;
info.height = GBA_VIDEO_VERTICAL_PIXELS;
if (!IsStarted())
return info;
info.is_gba = m_core->platform(m_core) == mPlatform::mPLATFORM_GBA;
info.has_rom = !m_rom_path.empty();
info.has_ereader =
info.is_gba && static_cast<::GBA*>(m_core->board)->memory.hw.devices & HW_EREADER;
m_core->desiredVideoDimensions(m_core, &info.width, &info.height);
info.game_title = m_game_title;
return info;
}
void Core::SetHost(std::weak_ptr<GBAHostInterface> host)
{
m_host = std::move(host);
@ -305,7 +324,7 @@ void Core::SetForceDisconnect(bool force_disconnect)
void Core::EReaderQueueCard(std::string_view card_path)
{
Flush();
if (!IsStarted() || m_core->platform(m_core) != mPlatform::mPLATFORM_GBA)
if (!GetCoreInfo().has_ereader)
return;
File::IOFile file(std::string(card_path), "rb");
@ -438,28 +457,6 @@ void Core::SetupEvent()
m_event.priority = 0x80;
}
int Core::GetDeviceNumber() const
{
return m_device_number;
}
void Core::GetVideoDimensions(u32* width, u32* height) const
{
if (!IsStarted())
{
*width = GBA_VIDEO_HORIZONTAL_PIXELS;
*height = GBA_VIDEO_VERTICAL_PIXELS;
return;
}
m_core->desiredVideoDimensions(m_core, width, height);
}
std::string Core::GetGameTitle() const
{
return m_game_title;
}
void Core::SendJoybusCommand(u64 gc_ticks, int transfer_time, u8* buffer, u16 keys)
{
if (!IsStarted())

View File

@ -36,6 +36,17 @@ struct AVStream : mAVStream
Core* core;
};
struct CoreInfo
{
int device_number;
bool is_gba;
bool has_rom;
bool has_ereader;
u32 width;
u32 height;
std::string game_title;
};
class Core final
{
public:
@ -46,15 +57,12 @@ public:
void Stop();
void Reset();
bool IsStarted() const;
CoreInfo GetCoreInfo() const;
void SetHost(std::weak_ptr<GBAHostInterface> host);
void SetForceDisconnect(bool force_disconnect);
void EReaderQueueCard(std::string_view card_path);
int GetDeviceNumber() const;
void GetVideoDimensions(u32* width, u32* height) const;
std::string GetGameTitle() const;
void SendJoybusCommand(u64 gc_ticks, int transfer_time, u8* buffer, u16 keys);
std::vector<u8> GetJoybusResponse();

View File

@ -15,16 +15,9 @@ GBAHost::GBAHost(std::weak_ptr<HW::GBA::Core> core)
m_widget_controller->moveToThread(qApp->thread());
m_core = std::move(core);
auto core_ptr = m_core.lock();
int device_number = core_ptr->GetDeviceNumber();
std::string game_title = core_ptr->GetGameTitle();
u32 width, height;
core_ptr->GetVideoDimensions(&width, &height);
HW::GBA::CoreInfo info = core_ptr->GetCoreInfo();
QueueOnObject(m_widget_controller, [widget_controller = m_widget_controller, core = m_core,
device_number, game_title, width, height] {
widget_controller->Create(core, device_number, game_title, width, height);
});
info] { widget_controller->Create(core, info); });
}
GBAHost::~GBAHost()
@ -37,15 +30,10 @@ void GBAHost::GameChanged()
auto core_ptr = m_core.lock();
if (!core_ptr || !core_ptr->IsStarted())
return;
std::string game_title = core_ptr->GetGameTitle();
u32 width, height;
core_ptr->GetVideoDimensions(&width, &height);
QueueOnObject(m_widget_controller,
[widget_controller = m_widget_controller, game_title, width, height] {
widget_controller->GameChanged(game_title, width, height);
});
HW::GBA::CoreInfo info = core_ptr->GetCoreInfo();
QueueOnObject(m_widget_controller, [widget_controller = m_widget_controller, info] {
widget_controller->GameChanged(info);
});
}
void GBAHost::FrameEnded(const std::vector<u32>& video_buffer)

View File

@ -21,7 +21,6 @@
#include "Core/Config/MainSettings.h"
#include "Core/Core.h"
#include "Core/CoreTiming.h"
#include "Core/HW/GBACore.h"
#include "Core/HW/GBAPad.h"
#include "Core/HW/SI/SI.h"
#include "Core/HW/SI/SI_Device.h"
@ -38,7 +37,7 @@ static void RestartCore(const std::weak_ptr<HW::GBA::Core>& core, std::string_vi
[core, rom_path = std::string(rom_path)] {
if (auto core_ptr = core.lock())
{
auto& info = Config::MAIN_GBA_ROM_PATHS[core_ptr->GetDeviceNumber()];
auto& info = Config::MAIN_GBA_ROM_PATHS[core_ptr->GetCoreInfo().device_number];
core_ptr->Stop();
Config::SetCurrent(info, rom_path);
if (core_ptr->Start(CoreTiming::GetTicks()))
@ -60,17 +59,16 @@ static void QueueEReaderCard(const std::weak_ptr<HW::GBA::Core>& core, std::stri
false);
}
GBAWidget::GBAWidget(std::weak_ptr<HW::GBA::Core> core, int device_number,
std::string_view game_title, int width, int height, QWidget* parent,
Qt::WindowFlags flags)
: QWidget(parent, flags), m_core(std::move(core)), m_device_number(device_number),
m_local_pad(device_number), m_game_title(game_title), m_width(width), m_height(height),
m_is_local_pad(true), m_volume(0), m_muted(false), m_force_disconnect(false)
GBAWidget::GBAWidget(std::weak_ptr<HW::GBA::Core> core, const HW::GBA::CoreInfo& info,
QWidget* parent, Qt::WindowFlags flags)
: QWidget(parent, flags), m_core(std::move(core)), m_core_info(info),
m_local_pad(info.device_number), m_is_local_pad(true), m_volume(0), m_muted(false),
m_force_disconnect(false)
{
bool visible = true;
if (NetPlay::IsNetPlayRunning())
{
NetPlay::PadDetails details = NetPlay::GetPadDetails(m_device_number);
NetPlay::PadDetails details = NetPlay::GetPadDetails(m_core_info.device_number);
if (details.local_pad < 4)
{
m_netplayer_name = details.player_name;
@ -82,7 +80,7 @@ GBAWidget::GBAWidget(std::weak_ptr<HW::GBA::Core> core, int device_number,
setWindowIcon(Resources::GetAppIcon());
setAcceptDrops(true);
resize(m_width, m_height);
resize(m_core_info.width, m_core_info.height);
setVisible(visible);
SetVolume(100);
@ -98,11 +96,9 @@ GBAWidget::~GBAWidget()
SaveGeometry();
}
void GBAWidget::GameChanged(std::string_view game_title, int width, int height)
void GBAWidget::GameChanged(const HW::GBA::CoreInfo& info)
{
m_game_title = game_title;
m_width = width;
m_height = height;
m_core_info = info;
UpdateTitle();
update();
}
@ -170,7 +166,7 @@ void GBAWidget::LoadROM()
void GBAWidget::UnloadROM()
{
if (!CanControlCore() || m_game_title.empty())
if (!CanControlCore() || !m_core_info.has_rom)
return;
RestartCore(m_core);
@ -224,17 +220,17 @@ void GBAWidget::DoState(bool export_state)
void GBAWidget::Resize(int scale)
{
resize(m_width * scale, m_height * scale);
resize(m_core_info.width * scale, m_core_info.height * scale);
}
void GBAWidget::UpdateTitle()
{
std::string title = fmt::format("GBA{}", m_device_number + 1);
std::string title = fmt::format("GBA{}", m_core_info.device_number + 1);
if (!m_netplayer_name.empty())
title += " " + m_netplayer_name;
if (!m_game_title.empty())
title += " | " + m_game_title;
if (!m_core_info.game_title.empty())
title += " | " + m_core_info.game_title;
if (m_muted)
title += " | Muted";
@ -247,7 +243,7 @@ void GBAWidget::UpdateTitle()
void GBAWidget::UpdateVolume()
{
int volume = m_muted ? 0 : m_volume * 256 / 100;
g_sound_stream->GetMixer()->SetGBAVolume(m_device_number, volume, volume);
g_sound_stream->GetMixer()->SetGBAVolume(m_core_info.device_number, volume, volume);
UpdateTitle();
}
@ -298,11 +294,11 @@ void GBAWidget::contextMenuEvent(QContextMenuEvent* event)
connect(load_action, &QAction::triggered, this, &GBAWidget::LoadROM);
auto* unload_action = new QAction(tr("&Unload ROM"), menu);
unload_action->setEnabled(CanControlCore() && !m_game_title.empty());
unload_action->setEnabled(CanControlCore() && m_core_info.has_rom);
connect(unload_action, &QAction::triggered, this, &GBAWidget::UnloadROM);
auto* card_action = new QAction(tr("&Scan e-Reader Card(s)"), menu);
card_action->setEnabled(CanControlCore() && !m_game_title.empty());
card_action->setEnabled(CanControlCore() && m_core_info.has_ereader);
connect(card_action, &QAction::triggered, this, &GBAWidget::PromptForEReaderCards);
auto* reset_action = new QAction(tr("&Reset"), menu);
@ -364,32 +360,32 @@ void GBAWidget::paintEvent(QPaintEvent* event)
QPainter painter(this);
painter.fillRect(QRect(QPoint(), size()), Qt::black);
if (m_video_buffer.size() == static_cast<size_t>(m_width * m_height))
if (m_video_buffer.size() == static_cast<size_t>(m_core_info.width * m_core_info.height))
{
QImage image(reinterpret_cast<const uchar*>(m_video_buffer.data()), m_width, m_height,
QImage::Format_ARGB32);
QImage image(reinterpret_cast<const uchar*>(m_video_buffer.data()), m_core_info.width,
m_core_info.height, QImage::Format_ARGB32);
image = image.convertToFormat(QImage::Format_RGB32);
image = image.rgbSwapped();
QSize widget_size = size();
if (widget_size == QSize(m_width, m_height))
if (widget_size == QSize(m_core_info.width, m_core_info.height))
{
painter.drawImage(QPoint(), image, QRect(0, 0, m_width, m_height));
painter.drawImage(QPoint(), image, QRect(0, 0, m_core_info.width, m_core_info.height));
}
else if (static_cast<float>(m_width) / m_height >
else if (static_cast<float>(m_core_info.width) / m_core_info.height >
static_cast<float>(widget_size.width()) / widget_size.height())
{
int new_height = widget_size.width() * m_height / m_width;
int new_height = widget_size.width() * m_core_info.height / m_core_info.width;
painter.drawImage(
QRect(0, (widget_size.height() - new_height) / 2, widget_size.width(), new_height), image,
QRect(0, 0, m_width, m_height));
QRect(0, 0, m_core_info.width, m_core_info.height));
}
else
{
int new_width = widget_size.height() * m_width / m_height;
int new_width = widget_size.height() * m_core_info.width / m_core_info.height;
painter.drawImage(
QRect((widget_size.width() - new_width) / 2, 0, new_width, widget_size.height()), image,
QRect(0, 0, m_width, m_height));
QRect(0, 0, m_core_info.width, m_core_info.height));
}
}
}
@ -431,15 +427,14 @@ GBAWidgetController::~GBAWidgetController()
m_widget->deleteLater();
}
void GBAWidgetController::Create(std::weak_ptr<HW::GBA::Core> core, int device_number,
std::string_view game_title, int width, int height)
void GBAWidgetController::Create(std::weak_ptr<HW::GBA::Core> core, const HW::GBA::CoreInfo& info)
{
m_widget = new GBAWidget(std::move(core), device_number, game_title, width, height);
m_widget = new GBAWidget(std::move(core), info);
}
void GBAWidgetController::GameChanged(std::string_view game_title, int width, int height)
void GBAWidgetController::GameChanged(const HW::GBA::CoreInfo& info)
{
m_widget->GameChanged(game_title, width, height);
m_widget->GameChanged(info);
}
void GBAWidgetController::FrameEnded(std::vector<u32> video_buffer)

View File

@ -11,11 +11,7 @@
#include <QWidget>
#include "Common/CommonTypes.h"
namespace HW::GBA
{
class Core;
} // namespace HW::GBA
#include "Core/HW/GBACore.h"
class QCloseEvent;
class QContextMenuEvent;
@ -27,12 +23,11 @@ class GBAWidget : public QWidget
{
Q_OBJECT
public:
explicit GBAWidget(std::weak_ptr<HW::GBA::Core> core, int device_number,
std::string_view game_title, int width, int height, QWidget* parent = nullptr,
Qt::WindowFlags flags = {});
explicit GBAWidget(std::weak_ptr<HW::GBA::Core> core, const HW::GBA::CoreInfo& info,
QWidget* parent = nullptr, Qt::WindowFlags flags = {});
~GBAWidget();
void GameChanged(std::string_view game_title, int width, int height);
void GameChanged(const HW::GBA::CoreInfo& info);
void SetVideoBuffer(std::vector<u32> video_buffer);
void SetVolume(int volume);
@ -67,14 +62,11 @@ private:
void dropEvent(QDropEvent* event) override;
std::weak_ptr<HW::GBA::Core> m_core;
HW::GBA::CoreInfo m_core_info;
std::vector<u32> m_video_buffer;
int m_device_number;
int m_local_pad;
std::string m_game_title;
int m_width;
int m_height;
std::string m_netplayer_name;
bool m_is_local_pad;
std::string m_netplayer_name;
int m_volume;
bool m_muted;
bool m_force_disconnect;
@ -87,9 +79,8 @@ public:
explicit GBAWidgetController() = default;
~GBAWidgetController();
void Create(std::weak_ptr<HW::GBA::Core> core, int device_number, std::string_view game_title,
int width, int height);
void GameChanged(std::string_view game_title, int width, int height);
void Create(std::weak_ptr<HW::GBA::Core> core, const HW::GBA::CoreInfo& info);
void GameChanged(const HW::GBA::CoreInfo& info);
void FrameEnded(std::vector<u32> video_buffer);
private: