Fixed formattingFixed formatting

Special DI Config bit is now only set when loading a Triforce game
Made logtype names unique
Removed GetPointer function and updated code to use GetSpanForAddress instead
Removed incorrect value from GBAPadGroup struct
Optimized the code in GetGameID that retrieves the Triforce game ID
This commit is contained in:
crediar 2025-08-03 13:00:58 +02:00
commit 05c2f5d09f
29 changed files with 303 additions and 330 deletions

View file

@ -28,7 +28,7 @@ enum
{ {
D_USER_IDX, D_USER_IDX,
D_GCUSER_IDX, D_GCUSER_IDX,
D_WIIROOT_IDX, // always points to User/Wii or global user-configured directory D_WIIROOT_IDX, // always points to User/Wii or global user-configured directory
D_TRIUSER_IDX, D_TRIUSER_IDX,
D_SESSION_WIIROOT_IDX, // may point to minimal temporary directory for determinism D_SESSION_WIIROOT_IDX, // may point to minimal temporary directory for determinism
D_CONFIG_IDX, // global settings D_CONFIG_IDX, // global settings

View file

@ -113,7 +113,7 @@ LogManager::LogManager()
m_log[LogType::DSP_MAIL] = {"DSPMails", "DSP Mails"}; m_log[LogType::DSP_MAIL] = {"DSPMails", "DSP Mails"};
m_log[LogType::DSPINTERFACE] = {"DSP", "DSP Interface"}; m_log[LogType::DSPINTERFACE] = {"DSP", "DSP Interface"};
m_log[LogType::DVDINTERFACE] = {"DVD", "DVD Interface"}; m_log[LogType::DVDINTERFACE] = {"DVD", "DVD Interface"};
m_log[LogType::DVDINTERFACE_AMMB] = { "DVD", "AMMB Interface" }; m_log[LogType::DVDINTERFACE_AMMB] = {"DVD_AMMB", "AMMB Interface"};
m_log[LogType::DYNA_REC] = {"JIT", "JIT Dynamic Recompiler"}; m_log[LogType::DYNA_REC] = {"JIT", "JIT Dynamic Recompiler"};
m_log[LogType::EXPANSIONINTERFACE] = {"EXI", "Expansion Interface"}; m_log[LogType::EXPANSIONINTERFACE] = {"EXI", "Expansion Interface"};
m_log[LogType::FILEMON] = {"FileMon", "File Monitor"}; m_log[LogType::FILEMON] = {"FileMon", "File Monitor"};
@ -145,9 +145,9 @@ LogManager::LogManager()
m_log[LogType::PROCESSORINTERFACE] = {"PI", "Processor Interface"}; m_log[LogType::PROCESSORINTERFACE] = {"PI", "Processor Interface"};
m_log[LogType::POWERPC] = {"PowerPC", "PowerPC IBM CPU"}; m_log[LogType::POWERPC] = {"PowerPC", "PowerPC IBM CPU"};
m_log[LogType::SERIALINTERFACE] = {"SI", "Serial Interface"}; m_log[LogType::SERIALINTERFACE] = {"SI", "Serial Interface"};
m_log[LogType::SERIALINTERFACE_AMBB] = { "SI", "AMBB Interface" }; m_log[LogType::SERIALINTERFACE_AMBB] = {"SI_AMBB", "AMBB Interface"};
m_log[LogType::SERIALINTERFACE_CARD] = { "SI", "CARD Interface" }; m_log[LogType::SERIALINTERFACE_CARD] = {"SI_CARD", "CARD Interface"};
m_log[LogType::SERIALINTERFACE_JVSIO] = { "SI", "JVS-I/O" }; m_log[LogType::SERIALINTERFACE_JVSIO] = {"SI_JVS", "JVS-I/O"};
m_log[LogType::SP1] = {"SP1", "Serial Port 1"}; m_log[LogType::SP1] = {"SP1", "Serial Port 1"};
m_log[LogType::SYMBOLS] = {"SYMBOLS", "Symbols"}; m_log[LogType::SYMBOLS] = {"SYMBOLS", "Symbols"};
m_log[LogType::VIDEO] = {"Video", "Video Backend"}; m_log[LogType::VIDEO] = {"Video", "Video Backend"};

View file

@ -37,8 +37,8 @@
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
#include "Core/FifoPlayer/FifoPlayer.h" #include "Core/FifoPlayer/FifoPlayer.h"
#include "Core/HLE/HLE.h" #include "Core/HLE/HLE.h"
#include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/DVD/AMMediaboard.h" #include "Core/HW/DVD/AMMediaboard.h"
#include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/EXI/EXI_DeviceIPL.h" #include "Core/HW/EXI/EXI_DeviceIPL.h"
#include "Core/HW/Memmap.h" #include "Core/HW/Memmap.h"
#include "Core/HW/VideoInterface.h" #include "Core/HW/VideoInterface.h"

View file

@ -21,8 +21,8 @@
#include "Core/Core.h" #include "Core/Core.h"
#include "Core/Debugger/BranchWatch.h" #include "Core/Debugger/BranchWatch.h"
#include "Core/HLE/HLE.h" #include "Core/HLE/HLE.h"
#include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/DVD/AMMediaboard.h" #include "Core/HW/DVD/AMMediaboard.h"
#include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/EXI/EXI_DeviceIPL.h" #include "Core/HW/EXI/EXI_DeviceIPL.h"
#include "Core/HW/Memmap.h" #include "Core/HW/Memmap.h"
#include "Core/IOS/DI/DI.h" #include "Core/IOS/DI/DI.h"

View file

@ -303,9 +303,9 @@ void Stop(Core::System& system) // - Hammertime!
system.GetFifo().ExitGpuLoop(); system.GetFifo().ExitGpuLoop();
} }
const ExpansionInterface::EXIDeviceType Type = Config::Get(Config::MAIN_SERIAL_PORT_1); const ExpansionInterface::EXIDeviceType type = Config::Get(Config::MAIN_SERIAL_PORT_1);
if ((Type == ExpansionInterface::EXIDeviceType::Baseboard)) if ((type == ExpansionInterface::EXIDeviceType::Baseboard))
{ {
AMMediaboard::Shutdown(); AMMediaboard::Shutdown();
} }

View file

@ -61,7 +61,7 @@
typedef int SOCKET; typedef int SOCKET;
#define INVALID_SOCKET (SOCKET)(~0) #define INVALID_SOCKET (SOCKET)(~0)
static int WSAGetLastError(void) static int WSAGetLastError(void)
{ {
@ -219,7 +219,8 @@ void Init(void)
if (!File::Exists(sega_boot_filename)) if (!File::Exists(sega_boot_filename))
{ {
PanicAlertFmt("Failed to open segaboot.gcm({}), which is required for test menus.", sega_boot_filename.c_str()); PanicAlertFmt("Failed to open segaboot.gcm({}), which is required for test menus.",
sega_boot_filename.c_str());
return; return;
} }
@ -487,10 +488,10 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
memory.Write_U16(Common::swap16(0x0100), address); memory.Write_U16(Common::swap16(0x0100), address);
break; break;
case MediaBoardStatus2: case MediaBoardStatus2:
memset(memory.GetPointer(address), 0, length); memset(memory.GetSpanForAddress(address).data(), 0, length);
break; break;
case MediaBoardStatus3: case MediaBoardStatus3:
memset(memory.GetPointer(address), 0xFF, length); memset(memory.GetSpanForAddress(address).data(), 0xFF, length);
// DIMM size (512MB) // DIMM size (512MB)
memory.Write_U32(Common::swap32(0x20000000), address); memory.Write_U32(Common::swap32(0x20000000), address);
// GCAM signature // GCAM signature
@ -526,7 +527,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
if (offset == 0x00000000 && length == 0x80) if (offset == 0x00000000 && length == 0x80)
{ {
s_netcfg->Seek(0, File::SeekOrigin::Begin); s_netcfg->Seek(0, File::SeekOrigin::Begin);
s_netcfg->ReadBytes(memory.GetPointer(address), length); s_netcfg->ReadBytes(memory.GetSpanForAddress(address).data(), length);
return 0; return 0;
} }
@ -534,7 +535,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
if (offset == DIMMExtraSettings && length == 0x20) if (offset == DIMMExtraSettings && length == 0x20)
{ {
s_extra->Seek(0, File::SeekOrigin::Begin); s_extra->Seek(0, File::SeekOrigin::Begin);
s_extra->ReadBytes(memory.GetPointer(address), length); s_extra->ReadBytes(memory.GetSpanForAddress(address).data(), length);
return 0; return 0;
} }
@ -543,14 +544,14 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
{ {
u32 dimmoffset = offset - DIMMMemory; u32 dimmoffset = offset - DIMMMemory;
s_dimm->Seek(dimmoffset, File::SeekOrigin::Begin); s_dimm->Seek(dimmoffset, File::SeekOrigin::Begin);
s_dimm->ReadBytes(memory.GetPointer(address), length); s_dimm->ReadBytes(memory.GetSpanForAddress(address).data(), length);
return 0; return 0;
} }
if (offset >= DIMMCommandVersion1 && offset < 0x1F900040) if (offset >= DIMMCommandVersion1 && offset < 0x1F900040)
{ {
u32 dimmoffset = offset - DIMMCommandVersion1; u32 dimmoffset = offset - DIMMCommandVersion1;
memcpy(memory.GetPointer(address), s_media_buffer + dimmoffset, length); memcpy(memory.GetSpanForAddress(address).data(), s_media_buffer + dimmoffset, length);
INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read MEDIA BOARD COMM AREA (1) ({:08x},{})", offset, INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read MEDIA BOARD COMM AREA (1) ({:08x},{})", offset,
length); length);
@ -562,7 +563,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
{ {
u32 dimmoffset = offset - NetworkBufferAddress4; u32 dimmoffset = offset - NetworkBufferAddress4;
INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read NETWORK BUFFER (4) ({:08x},{})", offset, length); INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read NETWORK BUFFER (4) ({:08x},{})", offset, length);
memcpy(memory.GetPointer(address), s_network_buffer + dimmoffset, length); memcpy(memory.GetSpanForAddress(address).data(), s_network_buffer + dimmoffset, length);
return 0; return 0;
} }
@ -570,7 +571,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
{ {
u32 dimmoffset = offset - NetworkBufferAddress5; u32 dimmoffset = offset - NetworkBufferAddress5;
INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read NETWORK BUFFER (5) ({:08x},{})", offset, length); INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read NETWORK BUFFER (5) ({:08x},{})", offset, length);
memcpy(memory.GetPointer(address), s_network_buffer + dimmoffset, length); memcpy(memory.GetSpanForAddress(address).data(), s_network_buffer + dimmoffset, length);
return 0; return 0;
} }
@ -579,7 +580,8 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
u32 dimmoffset = offset - NetworkCommandAddress; u32 dimmoffset = offset - NetworkCommandAddress;
INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read NETWORK COMMAND BUFFER ({:08x},{})", offset, INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read NETWORK COMMAND BUFFER ({:08x},{})", offset,
length); length);
memcpy(memory.GetPointer(address), s_network_command_buffer + dimmoffset, length); memcpy(memory.GetSpanForAddress(address).data(), s_network_command_buffer + dimmoffset,
length);
return 0; return 0;
} }
@ -588,7 +590,8 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
u32 dimmoffset = offset - NetworkCommandAddress2; u32 dimmoffset = offset - NetworkCommandAddress2;
INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read NETWORK COMMAND BUFFER (2) ({:08x},{})", offset, INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read NETWORK COMMAND BUFFER (2) ({:08x},{})", offset,
length); length);
memcpy(memory.GetPointer(address), s_network_command_buffer + dimmoffset, length); memcpy(memory.GetSpanForAddress(address).data(), s_network_command_buffer + dimmoffset,
length);
return 0; return 0;
} }
@ -596,7 +599,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
{ {
u32 dimmoffset = offset - NetworkBufferAddress1; u32 dimmoffset = offset - NetworkBufferAddress1;
INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read NETWORK BUFFER (1) ({:08x},{})", offset, length); INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read NETWORK BUFFER (1) ({:08x},{})", offset, length);
memcpy(memory.GetPointer(address), s_network_buffer + dimmoffset, length); memcpy(memory.GetSpanForAddress(address).data(), s_network_buffer + dimmoffset, length);
return 0; return 0;
} }
@ -604,7 +607,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
{ {
u32 dimmoffset = offset - NetworkBufferAddress2; u32 dimmoffset = offset - NetworkBufferAddress2;
INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read NETWORK BUFFER (2) ({:08x},{})", offset, length); INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read NETWORK BUFFER (2) ({:08x},{})", offset, length);
memcpy(memory.GetPointer(address), s_network_buffer + dimmoffset, length); memcpy(memory.GetSpanForAddress(address).data(), s_network_buffer + dimmoffset, length);
return 0; return 0;
} }
@ -612,14 +615,14 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
{ {
u32 dimmoffset = offset - NetworkBufferAddress3; u32 dimmoffset = offset - NetworkBufferAddress3;
INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read NETWORK BUFFER (3) ({:08x},{})", offset, length); INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read NETWORK BUFFER (3) ({:08x},{})", offset, length);
memcpy(memory.GetPointer(address), s_network_buffer + dimmoffset, length); memcpy(memory.GetSpanForAddress(address).data(), s_network_buffer + dimmoffset, length);
return 0; return 0;
} }
if (offset >= DIMMCommandVersion2 && offset < 0x84000060) if (offset >= DIMMCommandVersion2 && offset < 0x84000060)
{ {
u32 dimmoffset = offset - DIMMCommandVersion2; u32 dimmoffset = offset - DIMMCommandVersion2;
memcpy(memory.GetPointer(address), s_media_buffer + dimmoffset, length); memcpy(memory.GetSpanForAddress(address).data(), s_media_buffer + dimmoffset, length);
INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read MEDIA BOARD COMM AREA (2) ({:08x},{})", offset, INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read MEDIA BOARD COMM AREA (2) ({:08x},{})", offset,
length); length);
@ -1024,7 +1027,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
s_media_buffer[3] |= 0x80; // Command complete flag s_media_buffer[3] |= 0x80; // Command complete flag
memset(memory.GetPointer(address), 0, length); memset(memory.GetSpanForAddress(address).data(), 0, length);
ExpansionInterface::GenerateInterrupt(0x10); ExpansionInterface::GenerateInterrupt(0x10);
return 0; return 0;
@ -1033,7 +1036,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
if (offset >= DIMMCommandVersion2_2 && offset <= 0x89000200) if (offset >= DIMMCommandVersion2_2 && offset <= 0x89000200)
{ {
u32 dimmoffset = offset - DIMMCommandVersion2_2; u32 dimmoffset = offset - DIMMCommandVersion2_2;
memcpy(memory.GetPointer(address), s_media_buffer + dimmoffset, length); memcpy(memory.GetSpanForAddress(address).data(), s_media_buffer + dimmoffset, length);
INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read MEDIA BOARD COMM AREA (3) ({:08x})", dimmoffset); INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Read MEDIA BOARD COMM AREA (3) ({:08x})", dimmoffset);
PrintMBBuffer(address, length); PrintMBBuffer(address, length);
@ -1045,14 +1048,14 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
{ {
u32 dimmoffset = offset - DIMMMemory2; u32 dimmoffset = offset - DIMMMemory2;
s_dimm->Seek(dimmoffset, File::SeekOrigin::Begin); s_dimm->Seek(dimmoffset, File::SeekOrigin::Begin);
s_dimm->ReadBytes(memory.GetPointer(address), length); s_dimm->ReadBytes(memory.GetSpanForAddress(address).data(), length);
return 0; return 0;
} }
if (offset == NetworkControl && length == 0x20) if (offset == NetworkControl && length == 0x20)
{ {
s_netctrl->Seek(0, File::SeekOrigin::Begin); s_netctrl->Seek(0, File::SeekOrigin::Begin);
s_netctrl->ReadBytes(memory.GetPointer(address), length); s_netctrl->ReadBytes(memory.GetSpanForAddress(address).data(), length);
return 0; return 0;
} }
@ -1070,13 +1073,13 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
DICMDBUF[1] &= ~0x00100000; DICMDBUF[1] &= ~0x00100000;
DICMDBUF[1] -= 0x20; DICMDBUF[1] -= 0x20;
} }
memcpy(memory.GetPointer(address), s_firmware + offset, length); memcpy(memory.GetSpanForAddress(address).data(), s_firmware + offset, length);
return 0; return 0;
} }
if (s_dimm_disc) if (s_dimm_disc)
{ {
memcpy(memory.GetPointer(address), s_dimm_disc + offset, length); memcpy(memory.GetSpanForAddress(address).data(), s_dimm_disc + offset, length);
return 0; return 0;
} }
@ -1104,7 +1107,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
if ((offset >= 0x00400000) && (offset <= 0x600000)) if ((offset >= 0x00400000) && (offset <= 0x600000))
{ {
u32 fwoffset = offset - 0x00400000; u32 fwoffset = offset - 0x00400000;
memcpy(s_firmware + fwoffset, memory.GetPointer(address), length); memcpy(s_firmware + fwoffset, memory.GetSpanForAddress(address).data(), length);
return 0; return 0;
} }
} }
@ -1112,21 +1115,21 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
// Network configuration // Network configuration
if ((offset == 0x00000000) && (length == 0x80)) if ((offset == 0x00000000) && (length == 0x80))
{ {
FileWriteData(s_netcfg, 0, memory.GetPointer(address), length); FileWriteData(s_netcfg, 0, memory.GetSpanForAddress(address).data(), length);
return 0; return 0;
} }
// media crc check on/off // media crc check on/off
if ((offset == DIMMExtraSettings) && (length == 0x20)) if ((offset == DIMMExtraSettings) && (length == 0x20))
{ {
FileWriteData(s_extra, 0, memory.GetPointer(address), length); FileWriteData(s_extra, 0, memory.GetSpanForAddress(address).data(), length);
return 0; return 0;
} }
// Backup memory (8MB) // Backup memory (8MB)
if ((offset >= BackupMemory) && (offset <= 0x00800000)) if ((offset >= BackupMemory) && (offset <= 0x00800000))
{ {
FileWriteData(s_backup, 0, memory.GetPointer(address), length); FileWriteData(s_backup, 0, memory.GetSpanForAddress(address).data(), length);
return 0; return 0;
} }
@ -1134,7 +1137,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
if ((offset >= DIMMMemory) && (offset <= 0x1F800000)) if ((offset >= DIMMMemory) && (offset <= 0x1F800000))
{ {
u32 dimmoffset = offset - DIMMMemory; u32 dimmoffset = offset - DIMMMemory;
FileWriteData(s_dimm, dimmoffset, memory.GetPointer(address), length); FileWriteData(s_dimm, dimmoffset, memory.GetSpanForAddress(address).data(), length);
return 0; return 0;
} }
@ -1142,7 +1145,8 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
{ {
u32 dimmoffset = offset - NetworkCommandAddress; u32 dimmoffset = offset - NetworkCommandAddress;
memcpy(s_network_command_buffer + dimmoffset, memory.GetPointer(address), length); memcpy(s_network_command_buffer + dimmoffset, memory.GetSpanForAddress(address).data(),
length);
INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Write NETWORK COMMAND BUFFER ({:08x},{})", dimmoffset, INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Write NETWORK COMMAND BUFFER ({:08x},{})", dimmoffset,
length); length);
@ -1154,7 +1158,8 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
{ {
u32 dimmoffset = offset - NetworkCommandAddress2; u32 dimmoffset = offset - NetworkCommandAddress2;
memcpy(s_network_command_buffer + dimmoffset, memory.GetPointer(address), length); memcpy(s_network_command_buffer + dimmoffset, memory.GetSpanForAddress(address).data(),
length);
INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Write NETWORK COMMAND BUFFER (2) ({:08x},{})", INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Write NETWORK COMMAND BUFFER (2) ({:08x},{})",
dimmoffset, length); dimmoffset, length);
@ -1166,7 +1171,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
{ {
u32 dimmoffset = offset - 0x1FA00000; u32 dimmoffset = offset - 0x1FA00000;
memcpy(s_network_buffer + dimmoffset, memory.GetPointer(address), length); memcpy(s_network_buffer + dimmoffset, memory.GetSpanForAddress(address).data(), length);
INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Write NETWORK BUFFER (1) ({:08x},{})", dimmoffset, INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Write NETWORK BUFFER (1) ({:08x},{})", dimmoffset,
length); length);
@ -1178,7 +1183,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
{ {
u32 dimmoffset = offset - 0x1FD00000; u32 dimmoffset = offset - 0x1FD00000;
memcpy(s_network_buffer + dimmoffset, memory.GetPointer(address), length); memcpy(s_network_buffer + dimmoffset, memory.GetSpanForAddress(address).data(), length);
INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Write NETWORK BUFFER (2) ({:08x},{})", dimmoffset, INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Write NETWORK BUFFER (2) ({:08x},{})", dimmoffset,
length); length);
@ -1190,7 +1195,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
{ {
u32 dimmoffset = offset - 0x89100000; u32 dimmoffset = offset - 0x89100000;
memcpy(s_network_buffer + dimmoffset, memory.GetPointer(address), length); memcpy(s_network_buffer + dimmoffset, memory.GetSpanForAddress(address).data(), length);
INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Write NETWORK BUFFER (3) ({:08x},{})", dimmoffset, INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Write NETWORK BUFFER (3) ({:08x},{})", dimmoffset,
length); length);
@ -1201,7 +1206,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
if ((offset >= DIMMCommandVersion1) && (offset <= 0x1F90003F)) if ((offset >= DIMMCommandVersion1) && (offset <= 0x1F90003F))
{ {
u32 dimmoffset = offset - 0x1F900000; u32 dimmoffset = offset - 0x1F900000;
memcpy(s_media_buffer + dimmoffset, memory.GetPointer(address), length); memcpy(s_media_buffer + dimmoffset, memory.GetSpanForAddress(address).data(), length);
INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Write MEDIA BOARD COMM AREA (1) ({:08x},{})", offset, INFO_LOG_FMT(DVDINTERFACE_AMMB, "GC-AM: Write MEDIA BOARD COMM AREA (1) ({:08x},{})", offset,
length); length);
@ -1278,7 +1283,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
break; break;
} }
memcpy(memory.GetPointer(address), s_media_buffer, length); memcpy(memory.GetSpanForAddress(address).data(), s_media_buffer, length);
memset(s_media_buffer + 0x20, 0, 0x20); memset(s_media_buffer + 0x20, 0, 0x20);
@ -1287,7 +1292,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
} }
else else
{ {
memcpy(s_media_buffer + dimmoffset, memory.GetPointer(address), length); memcpy(s_media_buffer + dimmoffset, memory.GetSpanForAddress(address).data(), length);
} }
return 0; return 0;
} }
@ -1299,7 +1304,7 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
dimmoffset); dimmoffset);
PrintMBBuffer(address, length); PrintMBBuffer(address, length);
memcpy(s_media_buffer + dimmoffset, memory.GetPointer(address), length); memcpy(s_media_buffer + dimmoffset, memory.GetSpanForAddress(address).data(), length);
return 0; return 0;
} }
@ -1318,13 +1323,13 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
if ((offset >= DIMMMemory2) && (offset <= 0xFF800000)) if ((offset >= DIMMMemory2) && (offset <= 0xFF800000))
{ {
u32 dimmoffset = offset - 0xFF000000; u32 dimmoffset = offset - 0xFF000000;
FileWriteData(s_dimm, dimmoffset, memory.GetPointer(address), length); FileWriteData(s_dimm, dimmoffset, memory.GetSpanForAddress(address).data(), length);
return 0; return 0;
} }
if ((offset == NetworkControl) && (length == 0x20)) if ((offset == NetworkControl) && (length == 0x20))
{ {
FileWriteData(s_netctrl, 0, memory.GetPointer(address), length); FileWriteData(s_netctrl, 0, memory.GetSpanForAddress(address).data(), length);
return 0; return 0;
} }
@ -1711,8 +1716,8 @@ u32 ExecuteCommand(std::array<u32, 3>& DICMDBUF, u32 address, u32 length)
PanicAlertFmtT("Unhandled Media Board Execute:{0:08x}", *(u16*)(s_media_buffer + 0x22)); PanicAlertFmtT("Unhandled Media Board Execute:{0:08x}", *(u16*)(s_media_buffer + 0x22));
break; break;
default: default:
PanicAlertFmtT("Unhandled Media Board Command:{0:02x}", command ); PanicAlertFmtT("Unhandled Media Board Command:{0:02x}", command);
break; break;
} }

View file

@ -27,8 +27,8 @@
#include "Core/CoreTiming.h" #include "Core/CoreTiming.h"
#include "Core/DolphinAnalytics.h" #include "Core/DolphinAnalytics.h"
#include "Core/HW/AudioInterface.h" #include "Core/HW/AudioInterface.h"
#include "Core/HW/DVD/DVDMath.h"
#include "Core/HW/DVD/AMMediaboard.h" #include "Core/HW/DVD/AMMediaboard.h"
#include "Core/HW/DVD/DVDMath.h"
#include "Core/HW/DVD/DVDThread.h" #include "Core/HW/DVD/DVDThread.h"
#include "Core/HW/EXI/EXI_DeviceIPL.h" #include "Core/HW/EXI/EXI_DeviceIPL.h"
#include "Core/HW/MMIO.h" #include "Core/HW/MMIO.h"
@ -270,8 +270,6 @@ void DVDInterface::Init()
m_DIIMMBUF = 0; m_DIIMMBUF = 0;
m_DICFG.Hex = 0; m_DICFG.Hex = 0;
m_DICFG.CONFIG = 1; // Disable bootrom descrambler m_DICFG.CONFIG = 1; // Disable bootrom descrambler
m_DICFG.Hex |= 8; /* The Triforce IPL checks this bit
to set the physical memory to either 50MB(unset) or 24MB(set) */
ResetDrive(false); ResetDrive(false);
@ -292,6 +290,8 @@ void DVDInterface::Init()
// The Triforce IPL expects the cover to be closed // The Triforce IPL expects the cover to be closed
m_DICVR.Hex = 0; m_DICVR.Hex = 0;
m_DICFG.Hex |= 8; /* The Triforce IPL checks this bit
to set the physical memory to either 50MB(unset) or 24MB(set) */
} }
} }

View file

@ -154,11 +154,9 @@ void ExpansionInterfaceManager::Init(const Sram* override_sram)
} }
m_channels[SlotToEXIChannel(Slot::SP1)]->AddDevice(sp1_device, SlotToEXIDevice(Slot::SP1)); m_channels[SlotToEXIChannel(Slot::SP1)]->AddDevice(sp1_device, SlotToEXIDevice(Slot::SP1));
m_channels[SlotToEXIChannel(Slot::SP2)]->AddDevice(Config::Get(Config::MAIN_SERIAL_PORT_2), m_channels[SlotToEXIChannel(Slot::SP2)]->AddDevice(Config::Get(Config::MAIN_SERIAL_PORT_2),
SlotToEXIDevice(Slot::SP2)); SlotToEXIDevice(Slot::SP2));
m_event_type_change_device = core_timing.RegisterEvent("ChangeEXIDevice", ChangeDeviceCallback); m_event_type_change_device = core_timing.RegisterEvent("ChangeEXIDevice", ChangeDeviceCallback);
m_event_type_update_interrupts = m_event_type_update_interrupts =
core_timing.RegisterEvent("EXIUpdateInterrupts", UpdateInterruptsCallback); core_timing.RegisterEvent("EXIUpdateInterrupts", UpdateInterruptsCallback);

View file

@ -16,7 +16,6 @@
#include "Core/HW/EXI/EXI_DeviceIPL.h" #include "Core/HW/EXI/EXI_DeviceIPL.h"
#include "Core/HW/EXI/EXI_DeviceMemoryCard.h" #include "Core/HW/EXI/EXI_DeviceMemoryCard.h"
#include "Core/HW/EXI/EXI_DeviceModem.h" #include "Core/HW/EXI/EXI_DeviceModem.h"
#include "Core/HW/EXI/EXI_DeviceBaseboard.h"
#include "Core/HW/Memmap.h" #include "Core/HW/Memmap.h"
#include "Core/System.h" #include "Core/System.h"

View file

@ -1,4 +1,4 @@
// Copyright 2017 Dolphin Emulator Project // Copyright 2013 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "Core/HW/EXI/EXI_DeviceBaseboard.h" #include "Core/HW/EXI/EXI_DeviceBaseboard.h"
@ -88,7 +88,7 @@ CEXIBaseboard::CEXIBaseboard(Core::System& system) : IEXIDevice(system), m_posit
// Some games share the same ID Client/Server // Some games share the same ID Client/Server
if (!m_backup->IsGood()) if (!m_backup->IsGood())
{ {
PanicAlertFmt("Failed to open {}\nFile might be in use.", backup_Filename.c_str() ); PanicAlertFmt("Failed to open {}\nFile might be in use.", backup_Filename.c_str());
std::srand(static_cast<u32>(std::time(nullptr))); std::srand(static_cast<u32>(std::time(nullptr)));
@ -167,7 +167,7 @@ void CEXIBaseboard::DMAWrite(u32 addr, u32 size)
m_backup->Seek(m_backoffset, File::SeekOrigin::Begin); m_backup->Seek(m_backoffset, File::SeekOrigin::Begin);
m_backup->WriteBytes(memory.GetPointer(addr), size); m_backup->WriteBytes(memory.GetSpanForAddress(addr).data(), size);
m_backup->Flush(); m_backup->Flush();
} }
@ -183,7 +183,7 @@ void CEXIBaseboard::DMARead(u32 addr, u32 size)
m_backup->Flush(); m_backup->Flush();
m_backup->ReadBytes(memory.GetPointer(addr), size); m_backup->ReadBytes(memory.GetSpanForAddress(addr).data(), size);
} }
void CEXIBaseboard::TransferByte(u8& _byte) void CEXIBaseboard::TransferByte(u8& _byte)
@ -241,8 +241,8 @@ void CEXIBaseboard::TransferByte(u8& _byte)
case DMAOffsetLengthSet: case DMAOffsetLengthSet:
m_backup_dma_offset = (m_command[1] << 8) | m_command[2]; m_backup_dma_offset = (m_command[1] << 8) | m_command[2];
m_backup_dma_length = m_command[3]; m_backup_dma_length = m_command[3];
NOTICE_LOG_FMT(SP1, "AM-BB: COMMAND: DMAOffsetLengthSet :{:04x} {:02x}", m_backup_dma_offset, NOTICE_LOG_FMT(SP1, "AM-BB: COMMAND: DMAOffsetLengthSet :{:04x} {:02x}",
m_backup_dma_length); m_backup_dma_offset, m_backup_dma_length);
_byte = 0x01; _byte = 0x01;
break; break;
case ReadISR: case ReadISR:

View file

@ -1,3 +1,5 @@
// Copyright 2013 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once #pragma once
@ -10,15 +12,14 @@
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/Flag.h" #include "Common/Flag.h"
#include "Core/HW/EXI/EXI_Device.h"
#include "Common/IOFile.h" #include "Common/IOFile.h"
#include "Core/HW/EXI/EXI_Device.h"
namespace Core namespace Core
{ {
class System; class System;
} }
namespace ExpansionInterface namespace ExpansionInterface
{ {
void GenerateInterrupt(int flag); void GenerateInterrupt(int flag);
@ -36,12 +37,10 @@ public:
void DMAWrite(u32 addr, u32 size) override; void DMAWrite(u32 addr, u32 size) override;
void DMARead(u32 addr, u32 size) override; void DMARead(u32 addr, u32 size) override;
private: private:
enum Command
enum Command {
{ BackupOffsetSet = 0x01,
BackupOffsetSet = 0x01,
BackupWrite = 0x02, BackupWrite = 0x02,
BackupRead = 0x03, BackupRead = 0x03,
@ -53,13 +52,13 @@ enum Command
WriteIMR = 0x87, WriteIMR = 0x87,
WriteLANCNT = 0xFF, WriteLANCNT = 0xFF,
}; };
u32 m_position; u32 m_position;
u32 m_backup_dma_offset; u32 m_backup_dma_offset;
u32 m_backup_dma_length; u32 m_backup_dma_length;
u8 m_command[4]; u8 m_command[4];
u16 m_backoffset; u16 m_backoffset;
File::IOFile* m_backup; File::IOFile* m_backup;
protected: protected:

View file

@ -17,8 +17,7 @@ class Buttons;
enum class GBAPadGroup enum class GBAPadGroup
{ {
DPad, DPad,
Buttons, Buttons
Triforce
}; };
class GBAPad : public ControllerEmu::EmulatedController class GBAPad : public ControllerEmu::EmulatedController

View file

@ -34,7 +34,7 @@ static const u16 trigger_bitmasks[] = {
static const u16 dpad_bitmasks[] = {PAD_BUTTON_UP, PAD_BUTTON_DOWN, PAD_BUTTON_LEFT, static const u16 dpad_bitmasks[] = {PAD_BUTTON_UP, PAD_BUTTON_DOWN, PAD_BUTTON_LEFT,
PAD_BUTTON_RIGHT}; PAD_BUTTON_RIGHT};
static const u8 triforce_bitmask[] = { PAD_SWITCH_TEST, PAD_SWITCH_SERVICE, PAD_SWITCH_COIN }; static const u8 triforce_bitmask[] = {PAD_SWITCH_TEST, PAD_SWITCH_SERVICE, PAD_SWITCH_COIN};
GCPad::GCPad(const unsigned int index) : m_index(index) GCPad::GCPad(const unsigned int index) : m_index(index)
{ {
@ -71,7 +71,7 @@ GCPad::GCPad(const unsigned int index) : m_index(index)
// triforce // triforce
groups.emplace_back(m_triforce = new ControllerEmu::Buttons(TRIFORCE_GROUP)); groups.emplace_back(m_triforce = new ControllerEmu::Buttons(TRIFORCE_GROUP));
for (const char* named_button : { TEST_BUTTON, SERVICE_BUTTON, COIN_BUTTON }) for (const char* named_button : {TEST_BUTTON, SERVICE_BUTTON, COIN_BUTTON})
{ {
m_triforce->AddInput(Translatability::DoNotTranslate, named_button); m_triforce->AddInput(Translatability::DoNotTranslate, named_button);
} }

View file

@ -526,25 +526,6 @@ std::span<u8> MemoryManager::GetSpanForAddress(u32 address) const
LR(ppc_state)); LR(ppc_state));
return {}; return {};
} }
u8* MemoryManager::GetPointer(u32 address) const
{
// TODO: Should we be masking off more bits here? Can all devices access
// EXRAM?
address &= 0x3FFFFFFF;
if (address < GetRamSizeReal())
return m_ram + address;
if (m_exram)
{
if ((address >> 28) == 0x1 && (address & 0x0fffffff) < GetExRamSizeReal())
return m_exram + (address & GetExRamMask());
}
auto& ppc_state = m_system.GetPPCState();
PanicAlertFmt("Unknown Pointer {:#010x} PC {:#010x} LR {:#010x}", address, ppc_state.pc,
LR(ppc_state));
return nullptr;
}
u8 MemoryManager::Read_U8(u32 address) const u8 MemoryManager::Read_U8(u32 address) const
{ {

View file

@ -115,7 +115,6 @@ public:
// If the specified range is within a single valid memory region, returns a pointer to the start // If the specified range is within a single valid memory region, returns a pointer to the start
// of the corresponding range in host memory. Otherwise, returns nullptr. // of the corresponding range in host memory. Otherwise, returns nullptr.
u8* GetPointerForRange(u32 address, size_t size) const; u8* GetPointerForRange(u32 address, size_t size) const;
u8* GetPointer(u32 address) const;
void CopyFromEmu(void* data, u32 address, size_t size) const; void CopyFromEmu(void* data, u32 address, size_t size) const;
void CopyToEmu(u32 address, const void* data, size_t size); void CopyToEmu(u32 address, const void* data, size_t size);
void Memset(u32 address, u8 value, size_t size); void Memset(u32 address, u8 value, size_t size);

View file

@ -16,11 +16,11 @@
#ifdef HAS_LIBMGBA #ifdef HAS_LIBMGBA
#include "Core/HW/SI/SI_DeviceGBAEmu.h" #include "Core/HW/SI/SI_DeviceGBAEmu.h"
#endif #endif
#include "Core/HW/SI/SI_DeviceAMBaseboard.h"
#include "Core/HW/SI/SI_DeviceGCAdapter.h" #include "Core/HW/SI/SI_DeviceGCAdapter.h"
#include "Core/HW/SI/SI_DeviceGCController.h" #include "Core/HW/SI/SI_DeviceGCController.h"
#include "Core/HW/SI/SI_DeviceGCSteeringWheel.h" #include "Core/HW/SI/SI_DeviceGCSteeringWheel.h"
#include "Core/HW/SI/SI_DeviceKeyboard.h" #include "Core/HW/SI/SI_DeviceKeyboard.h"
#include "Core/HW/SI/SI_DeviceAMBaseboard.h"
#include "Core/HW/SI/SI_DeviceNull.h" #include "Core/HW/SI/SI_DeviceNull.h"
#include "Core/HW/SystemTimers.h" #include "Core/HW/SystemTimers.h"
#include "Core/System.h" #include "Core/System.h"

View file

@ -1546,7 +1546,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
PadStatus = Pad::GetStatus(0); PadStatus = Pad::GetStatus(0);
// Test button // Test button
if (PadStatus.switches&PAD_SWITCH_TEST) if (PadStatus.switches & PAD_SWITCH_TEST)
{ {
// Trying to access the test menu without SegaBoot present will cause a crash // Trying to access the test menu without SegaBoot present will cause a crash
if (AMMediaboard::GetTestMenu()) if (AMMediaboard::GetTestMenu())
@ -1829,7 +1829,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
{ {
GCPadStatus PadStatus; GCPadStatus PadStatus;
PadStatus = Pad::GetStatus(i); PadStatus = Pad::GetStatus(i);
if ((PadStatus.switches&PAD_SWITCH_COIN) && !m_coin_pressed[i]) if ((PadStatus.switches & PAD_SWITCH_COIN) && !m_coin_pressed[i])
{ {
m_coin[i]++; m_coin[i]++;
} }

View file

@ -49,8 +49,8 @@ private:
SerialNumber = 0x11, SerialNumber = 0x11,
Unknown_12 = 0x12, Unknown_12 = 0x12,
Unknown_14 = 0x14, Unknown_14 = 0x14,
FirmVersion= 0x15, FirmVersion = 0x15,
FPGAVersion= 0x16, FPGAVersion = 0x16,
RegionSettings = 0x1F, RegionSettings = 0x1F,
Unknown_21 = 0x21, Unknown_21 = 0x21,
@ -151,7 +151,7 @@ private:
BootVersion = 0x62, BootVersion = 0x62,
SensLock = 0x63, SensLock = 0x63,
SensCard = 0x65, SensCard = 0x65,
FirmwareUpdate =0x66, FirmwareUpdate = 0x66,
ShutterGet = 0x67, ShutterGet = 0x67,
CameraCheck = 0x68, CameraCheck = 0x68,
ShutterCard = 0x69, ShutterCard = 0x69,

View file

@ -27,17 +27,10 @@ std::string VolumeDisc::GetGameID(const Partition& partition) const
std::unique_ptr<FileInfo> file_info = file_system->FindFileInfo("boot.id"); std::unique_ptr<FileInfo> file_info = file_system->FindFileInfo("boot.id");
if (file_info && !file_info->IsDirectory()) if (file_info && !file_info->IsDirectory())
{ {
u8* bootid_buffer = new u8[file_info->GetTotalSize()]; if (Read(file_info->GetOffset() + 0x30, sizeof(id), reinterpret_cast<u8*>(id), partition))
if (Read(file_info->GetOffset(), file_info->GetTotalSize(), bootid_buffer, partition))
{ {
memcpy(id, bootid_buffer + 0x30, sizeof(id));
delete[] bootid_buffer;
return DecodeString(id); return DecodeString(id);
} }
// Fall back to normal ID from header
delete[] bootid_buffer;
} }
} }

View file

@ -29,7 +29,7 @@
namespace DiscIO namespace DiscIO
{ {
Region g_triforce_region; Region g_triforce_region;
VolumeGC::VolumeGC(std::unique_ptr<BlobReader> reader) VolumeGC::VolumeGC(std::unique_ptr<BlobReader> reader)
: m_reader(std::move(reader)), m_is_triforce(false) : m_reader(std::move(reader)), m_is_triforce(false)
@ -61,15 +61,15 @@ VolumeGC::VolumeGC(std::unique_ptr<BlobReader> reader)
// Load region from the file // Load region from the file
switch (triforce_header.region) switch (triforce_header.region)
{ {
default: default:
case 0x02: // JAPAN case 0x02: // JAPAN
case 0x08: // ASIA case 0x08: // ASIA
g_triforce_region = Region::NTSC_J; g_triforce_region = Region::NTSC_J;
break; break;
case 0x0E: // USA case 0x0E: // USA
g_triforce_region = Region::NTSC_U; g_triforce_region = Region::NTSC_U;
break; break;
case 0x0C: // EXPORT case 0x0C: // EXPORT
g_triforce_region = Region::PAL; g_triforce_region = Region::PAL;
break; break;
} }

View file

@ -27,11 +27,13 @@ void GCPadEmu::CreateMainLayout()
layout->addWidget(CreateGroupBox(tr("Buttons"), Pad::GetGroup(GetPort(), PadGroup::Buttons)), 0, layout->addWidget(CreateGroupBox(tr("Buttons"), Pad::GetGroup(GetPort(), PadGroup::Buttons)), 0,
0); 0);
layout->addWidget(CreateGroupBox(tr("D-Pad"), Pad::GetGroup(GetPort(), PadGroup::DPad)), 1, 0 ); layout->addWidget(CreateGroupBox(tr("D-Pad"), Pad::GetGroup(GetPort(), PadGroup::DPad)), 1, 0);
if (Config::Get(Config::GetInfoForSIDevice(0)) == SerialInterface::SIDevices::SIDEVICE_AM_BASEBOARD) if (Config::Get(Config::GetInfoForSIDevice(0)) ==
SerialInterface::SIDevices::SIDEVICE_AM_BASEBOARD)
{ {
layout->addWidget(CreateGroupBox(tr("Triforce"), Pad::GetGroup(GetPort(), PadGroup::Triforce)), 2, 0); layout->addWidget(CreateGroupBox(tr("Triforce"), Pad::GetGroup(GetPort(), PadGroup::Triforce)),
2, 0);
} }
layout->addWidget( layout->addWidget(

View file

@ -440,7 +440,8 @@ void MappingWindow::SetMappingType(MappingWindow::Type type)
case Type::MAPPING_GC_DANCEMAT: case Type::MAPPING_GC_DANCEMAT:
case Type::MAPPING_GCPAD: case Type::MAPPING_GCPAD:
widget = new GCPadEmu(this); widget = new GCPadEmu(this);
if (Config::Get(Config::GetInfoForSIDevice(GetPort())) == SerialInterface::SIDevices::SIDEVICE_AM_BASEBOARD) if (Config::Get(Config::GetInfoForSIDevice(GetPort())) ==
SerialInterface::SIDevices::SIDEVICE_AM_BASEBOARD)
{ {
setWindowTitle(tr("Triforce Baseboard at Port %1").arg(GetPort() + 1)); setWindowTitle(tr("Triforce Baseboard at Port %1").arg(GetPort() + 1));
AddWidget(tr("Triforce Baseboard"), widget); AddWidget(tr("Triforce Baseboard"), widget);

View file

@ -178,8 +178,8 @@ static WindowSystemType GetWindowSystemType()
return WindowSystemType::Haiku; return WindowSystemType::Haiku;
ModalMessageBox::critical( ModalMessageBox::critical(
nullptr, QStringLiteral("Error"), nullptr, QStringLiteral("Error"),
QString::asprintf("Unknown Qt platform: %s", platform_name.toStdString().c_str())); QString::asprintf("Unknown Qt platform: %s", platform_name.toStdString().c_str()));
return WindowSystemType::Headless; return WindowSystemType::Headless;
} }
@ -218,8 +218,8 @@ static std::vector<std::string> StringListToStdVector(QStringList list)
} }
MainWindow::MainWindow(Core::System& system, std::unique_ptr<BootParameters> boot_parameters, MainWindow::MainWindow(Core::System& system, std::unique_ptr<BootParameters> boot_parameters,
const std::string& movie_path) const std::string& movie_path)
: QMainWindow(nullptr), m_system(system) : QMainWindow(nullptr), m_system(system)
{ {
setWindowTitle(QString::fromStdString(Common::GetScmRevStr())); setWindowTitle(QString::fromStdString(Common::GetScmRevStr()));
setWindowIcon(Resources::GetAppIcon()); setWindowIcon(Resources::GetAppIcon());
@ -249,21 +249,21 @@ MainWindow::MainWindow(Core::System& system, std::unique_ptr<BootParameters> boo
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, this,
[this](Qt::ColorScheme colorScheme) { [this](Qt::ColorScheme colorScheme) {
Settings::Instance().ApplyStyle(); Settings::Instance().ApplyStyle();
if (m_skylander_window) if (m_skylander_window)
m_skylander_window->RefreshList(); m_skylander_window->RefreshList();
}); });
#endif #endif
connect(m_cheats_manager, &CheatsManager::OpenGeneralSettings, this, connect(m_cheats_manager, &CheatsManager::OpenGeneralSettings, this,
&MainWindow::ShowGeneralWindow); &MainWindow::ShowGeneralWindow);
#ifdef USE_RETRO_ACHIEVEMENTS #ifdef USE_RETRO_ACHIEVEMENTS
connect(m_cheats_manager, &CheatsManager::OpenAchievementSettings, this, connect(m_cheats_manager, &CheatsManager::OpenAchievementSettings, this,
&MainWindow::ShowAchievementSettings); &MainWindow::ShowAchievementSettings);
connect(m_game_list, &GameList::OpenAchievementSettings, this, connect(m_game_list, &GameList::OpenAchievementSettings, this,
&MainWindow::ShowAchievementSettings); &MainWindow::ShowAchievementSettings);
#endif // USE_RETRO_ACHIEVEMENTS #endif // USE_RETRO_ACHIEVEMENTS
InitCoreCallbacks(); InitCoreCallbacks();
@ -276,7 +276,7 @@ MainWindow::MainWindow(Core::System& system, std::unique_ptr<BootParameters> boo
Settings::Instance().SetDebugModeEnabled(false); Settings::Instance().SetDebugModeEnabled(false);
// This needs to trigger on both RA_HARDCORE_ENABLED and RA_ENABLED // This needs to trigger on both RA_HARDCORE_ENABLED and RA_ENABLED
m_config_changed_callback_id = Config::AddConfigChangedCallback( m_config_changed_callback_id = Config::AddConfigChangedCallback(
[this] { QueueOnObject(this, [this] { this->OnHardcoreChanged(); }); }); [this] { QueueOnObject(this, [this] { this->OnHardcoreChanged(); }); });
// If hardcore is enabled when the emulator starts, make sure it turns off what it needs to // If hardcore is enabled when the emulator starts, make sure it turns off what it needs to
if (Config::Get(Config::RA_HARDCORE_ENABLED)) if (Config::Get(Config::RA_HARDCORE_ENABLED))
OnHardcoreChanged(); OnHardcoreChanged();
@ -300,14 +300,14 @@ MainWindow::MainWindow(Core::System& system, std::unique_ptr<BootParameters> boo
if (m_system.GetMovie().PlayInput(movie_path, &savestate_path)) if (m_system.GetMovie().PlayInput(movie_path, &savestate_path))
{ {
m_pending_boot->boot_session_data.SetSavestateData(std::move(savestate_path), m_pending_boot->boot_session_data.SetSavestateData(std::move(savestate_path),
DeleteSavestateAfterBoot::No); DeleteSavestateAfterBoot::No);
emit RecordingStatusChanged(true); emit RecordingStatusChanged(true);
} }
} }
} }
m_state_slot = m_state_slot =
std::clamp(Settings::Instance().GetStateSlot(), 1, static_cast<int>(State::NUM_STATES)); std::clamp(Settings::Instance().GetStateSlot(), 1, static_cast<int>(State::NUM_STATES));
m_render_widget_geometry = settings.value(QStringLiteral("renderwidget/geometry")).toByteArray(); m_render_widget_geometry = settings.value(QStringLiteral("renderwidget/geometry")).toByteArray();
@ -318,7 +318,7 @@ MainWindow::MainWindow(Core::System& system, std::unique_ptr<BootParameters> boo
if (!ResourcePack::Init()) if (!ResourcePack::Init())
{ {
ModalMessageBox::critical(this, tr("Error"), ModalMessageBox::critical(this, tr("Error"),
tr("Error occurred while loading some texture packs")); tr("Error occurred while loading some texture packs"));
} }
for (auto& pack : ResourcePack::GetPacks()) for (auto& pack : ResourcePack::GetPacks())
@ -326,9 +326,9 @@ MainWindow::MainWindow(Core::System& system, std::unique_ptr<BootParameters> boo
if (!pack.IsValid()) if (!pack.IsValid())
{ {
ModalMessageBox::critical(this, tr("Error"), ModalMessageBox::critical(this, tr("Error"),
tr("Invalid Pack %1 provided: %2") tr("Invalid Pack %1 provided: %2")
.arg(QString::fromStdString(pack.GetPath())) .arg(QString::fromStdString(pack.GetPath()))
.arg(QString::fromStdString(pack.GetError()))); .arg(QString::fromStdString(pack.GetError())));
return; return;
} }
} }
@ -433,7 +433,7 @@ void MainWindow::InitCoreCallbacks()
FullScreen(); FullScreen();
m_fullscreen_requested = false; m_fullscreen_requested = false;
} }
}); });
installEventFilter(this); installEventFilter(this);
m_render_widget->installEventFilter(this); m_render_widget->installEventFilter(this);
@ -441,7 +441,7 @@ void MainWindow::InitCoreCallbacks()
auto* filter = new FileOpenEventFilter(QGuiApplication::instance()); auto* filter = new FileOpenEventFilter(QGuiApplication::instance());
connect(filter, &FileOpenEventFilter::fileOpened, this, [this](const QString& file_name) { connect(filter, &FileOpenEventFilter::fileOpened, this, [this](const QString& file_name) {
StartGame(BootParameters::GenerateFromFile(file_name.toStdString())); StartGame(BootParameters::GenerateFromFile(file_name.toStdString()));
}); });
} }
static void InstallHotkeyFilter(QWidget* dialog) static void InstallHotkeyFilter(QWidget* dialog)
@ -450,9 +450,9 @@ static void InstallHotkeyFilter(QWidget* dialog)
dialog->installEventFilter(filter); dialog->installEventFilter(filter);
filter->connect(filter, &WindowActivationEventFilter::windowDeactivated, filter->connect(filter, &WindowActivationEventFilter::windowDeactivated,
[] { HotkeyManagerEmu::Enable(true); }); [] { HotkeyManagerEmu::Enable(true); });
filter->connect(filter, &WindowActivationEventFilter::windowActivated, filter->connect(filter, &WindowActivationEventFilter::windowActivated,
[] { HotkeyManagerEmu::Enable(false); }); [] { HotkeyManagerEmu::Enable(false); });
} }
void MainWindow::CreateComponents() void MainWindow::CreateComponents()
@ -486,15 +486,15 @@ void MainWindow::CreateComponents()
const auto request_watch = [this](QString name, u32 addr) { const auto request_watch = [this](QString name, u32 addr) {
m_watch_widget->AddWatch(name, addr); m_watch_widget->AddWatch(name, addr);
}; };
const auto request_breakpoint = [this](u32 addr) { m_breakpoint_widget->AddBP(addr); }; const auto request_breakpoint = [this](u32 addr) { m_breakpoint_widget->AddBP(addr); };
const auto request_memory_breakpoint = [this](u32 addr) { const auto request_memory_breakpoint = [this](u32 addr) {
m_breakpoint_widget->AddAddressMBP(addr); m_breakpoint_widget->AddAddressMBP(addr);
}; };
const auto request_view_in_memory = [this](u32 addr) { m_memory_widget->SetAddress(addr); }; const auto request_view_in_memory = [this](u32 addr) { m_memory_widget->SetAddress(addr); };
const auto request_view_in_code = [this](u32 addr) { const auto request_view_in_code = [this](u32 addr) {
m_code_widget->SetAddress(addr, CodeViewWidget::SetAddressUpdate::WithDetailedUpdate); m_code_widget->SetAddress(addr, CodeViewWidget::SetAddressUpdate::WithDetailedUpdate);
}; };
connect(m_jit_widget, &JITWidget::SetCodeAddress, m_code_widget, &CodeWidget::OnSetCodeAddress); connect(m_jit_widget, &JITWidget::SetCodeAddress, m_code_widget, &CodeWidget::OnSetCodeAddress);
connect(m_watch_widget, &WatchWidget::RequestMemoryBreakpoint, request_memory_breakpoint); connect(m_watch_widget, &WatchWidget::RequestMemoryBreakpoint, request_memory_breakpoint);
@ -510,19 +510,19 @@ void MainWindow::CreateComponents()
connect(m_thread_widget, &ThreadWidget::RequestViewInCode, request_view_in_code); connect(m_thread_widget, &ThreadWidget::RequestViewInCode, request_view_in_code);
connect(m_code_widget, &CodeWidget::RequestPPCComparison, m_jit_widget, connect(m_code_widget, &CodeWidget::RequestPPCComparison, m_jit_widget,
&JITWidget::OnRequestPPCComparison); &JITWidget::OnRequestPPCComparison);
connect(m_code_widget, &CodeWidget::ShowMemory, m_memory_widget, &MemoryWidget::SetAddress); connect(m_code_widget, &CodeWidget::ShowMemory, m_memory_widget, &MemoryWidget::SetAddress);
connect(m_memory_widget, &MemoryWidget::ShowCode, m_code_widget, [this](u32 address) { connect(m_memory_widget, &MemoryWidget::ShowCode, m_code_widget, [this](u32 address) {
m_code_widget->SetAddress(address, CodeViewWidget::SetAddressUpdate::WithDetailedUpdate); m_code_widget->SetAddress(address, CodeViewWidget::SetAddressUpdate::WithDetailedUpdate);
}); });
connect(m_memory_widget, &MemoryWidget::RequestWatch, request_watch); connect(m_memory_widget, &MemoryWidget::RequestWatch, request_watch);
connect(m_breakpoint_widget, &BreakpointWidget::ShowCode, [this](u32 address) { connect(m_breakpoint_widget, &BreakpointWidget::ShowCode, [this](u32 address) {
if (Core::GetState(m_system) == Core::State::Paused) if (Core::GetState(m_system) == Core::State::Paused)
m_code_widget->SetAddress(address, CodeViewWidget::SetAddressUpdate::WithDetailedUpdate); m_code_widget->SetAddress(address, CodeViewWidget::SetAddressUpdate::WithDetailedUpdate);
}); });
connect(m_breakpoint_widget, &BreakpointWidget::ShowMemory, m_memory_widget, connect(m_breakpoint_widget, &BreakpointWidget::ShowMemory, m_memory_widget,
&MemoryWidget::SetAddress); &MemoryWidget::SetAddress);
connect(m_cheats_manager, &CheatsManager::ShowMemory, m_memory_widget, &MemoryWidget::SetAddress); connect(m_cheats_manager, &CheatsManager::ShowMemory, m_memory_widget, &MemoryWidget::SetAddress);
connect(m_cheats_manager, &CheatsManager::RequestWatch, request_watch); connect(m_cheats_manager, &CheatsManager::RequestWatch, request_watch);
} }
@ -567,7 +567,7 @@ void MainWindow::ConnectMenuBar()
// Tools // Tools
connect(m_menu_bar, &MenuBar::ShowMemcardManager, this, &MainWindow::ShowMemcardManager); connect(m_menu_bar, &MenuBar::ShowMemcardManager, this, &MainWindow::ShowMemcardManager);
connect(m_menu_bar, &MenuBar::ShowResourcePackManager, this, connect(m_menu_bar, &MenuBar::ShowResourcePackManager, this,
&MainWindow::ShowResourcePackManager); &MainWindow::ShowResourcePackManager);
connect(m_menu_bar, &MenuBar::ShowCheatsManager, this, &MainWindow::ShowCheatsManager); connect(m_menu_bar, &MenuBar::ShowCheatsManager, this, &MainWindow::ShowCheatsManager);
connect(m_menu_bar, &MenuBar::BootGameCubeIPL, this, &MainWindow::OnBootGameCubeIPL); connect(m_menu_bar, &MenuBar::BootGameCubeIPL, this, &MainWindow::OnBootGameCubeIPL);
connect(m_menu_bar, &MenuBar::ImportNANDBackup, this, &MainWindow::OnImportNANDBackup); connect(m_menu_bar, &MenuBar::ImportNANDBackup, this, &MainWindow::OnImportNANDBackup);
@ -599,12 +599,12 @@ void MainWindow::ConnectMenuBar()
connect(m_menu_bar, &MenuBar::ShowSearch, m_search_bar, &SearchBar::Show); connect(m_menu_bar, &MenuBar::ShowSearch, m_search_bar, &SearchBar::Show);
connect(m_menu_bar, &MenuBar::ColumnVisibilityToggled, m_game_list, connect(m_menu_bar, &MenuBar::ColumnVisibilityToggled, m_game_list,
&GameList::OnColumnVisibilityToggled); &GameList::OnColumnVisibilityToggled);
connect(m_menu_bar, &MenuBar::GameListPlatformVisibilityToggled, m_game_list, connect(m_menu_bar, &MenuBar::GameListPlatformVisibilityToggled, m_game_list,
&GameList::OnGameListVisibilityChanged); &GameList::OnGameListVisibilityChanged);
connect(m_menu_bar, &MenuBar::GameListRegionVisibilityToggled, m_game_list, connect(m_menu_bar, &MenuBar::GameListRegionVisibilityToggled, m_game_list,
&GameList::OnGameListVisibilityChanged); &GameList::OnGameListVisibilityChanged);
connect(m_menu_bar, &MenuBar::ShowAboutDialog, this, &MainWindow::ShowAboutDialog); connect(m_menu_bar, &MenuBar::ShowAboutDialog, this, &MainWindow::ShowAboutDialog);
@ -623,9 +623,9 @@ void MainWindow::ConnectHotkeys()
connect(m_hotkey_scheduler, &HotkeyScheduler::TogglePauseHotkey, this, &MainWindow::TogglePause); connect(m_hotkey_scheduler, &HotkeyScheduler::TogglePauseHotkey, this, &MainWindow::TogglePause);
connect(m_hotkey_scheduler, &HotkeyScheduler::ActivateChat, this, &MainWindow::OnActivateChat); connect(m_hotkey_scheduler, &HotkeyScheduler::ActivateChat, this, &MainWindow::OnActivateChat);
connect(m_hotkey_scheduler, &HotkeyScheduler::RequestGolfControl, this, connect(m_hotkey_scheduler, &HotkeyScheduler::RequestGolfControl, this,
&MainWindow::OnRequestGolfControl); &MainWindow::OnRequestGolfControl);
connect(m_hotkey_scheduler, &HotkeyScheduler::RefreshGameListHotkey, this, connect(m_hotkey_scheduler, &HotkeyScheduler::RefreshGameListHotkey, this,
&MainWindow::RefreshGameList); &MainWindow::RefreshGameList);
connect(m_hotkey_scheduler, &HotkeyScheduler::StopHotkey, this, &MainWindow::RequestStop); connect(m_hotkey_scheduler, &HotkeyScheduler::StopHotkey, this, &MainWindow::RequestStop);
connect(m_hotkey_scheduler, &HotkeyScheduler::ResetHotkey, this, &MainWindow::Reset); connect(m_hotkey_scheduler, &HotkeyScheduler::ResetHotkey, this, &MainWindow::Reset);
connect(m_hotkey_scheduler, &HotkeyScheduler::ScreenShotHotkey, this, &MainWindow::ScreenShot); connect(m_hotkey_scheduler, &HotkeyScheduler::ScreenShotHotkey, this, &MainWindow::ScreenShot);
@ -634,40 +634,40 @@ void MainWindow::ConnectHotkeys()
connect(m_hotkey_scheduler, &HotkeyScheduler::StateLoadSlot, this, &MainWindow::StateLoadSlotAt); connect(m_hotkey_scheduler, &HotkeyScheduler::StateLoadSlot, this, &MainWindow::StateLoadSlotAt);
connect(m_hotkey_scheduler, &HotkeyScheduler::StateSaveSlot, this, &MainWindow::StateSaveSlotAt); connect(m_hotkey_scheduler, &HotkeyScheduler::StateSaveSlot, this, &MainWindow::StateSaveSlotAt);
connect(m_hotkey_scheduler, &HotkeyScheduler::StateLoadLastSaved, this, connect(m_hotkey_scheduler, &HotkeyScheduler::StateLoadLastSaved, this,
&MainWindow::StateLoadLastSavedAt); &MainWindow::StateLoadLastSavedAt);
connect(m_hotkey_scheduler, &HotkeyScheduler::StateLoadUndo, this, &MainWindow::StateLoadUndo); connect(m_hotkey_scheduler, &HotkeyScheduler::StateLoadUndo, this, &MainWindow::StateLoadUndo);
connect(m_hotkey_scheduler, &HotkeyScheduler::StateSaveUndo, this, &MainWindow::StateSaveUndo); connect(m_hotkey_scheduler, &HotkeyScheduler::StateSaveUndo, this, &MainWindow::StateSaveUndo);
connect(m_hotkey_scheduler, &HotkeyScheduler::StateSaveOldest, this, connect(m_hotkey_scheduler, &HotkeyScheduler::StateSaveOldest, this,
&MainWindow::StateSaveOldest); &MainWindow::StateSaveOldest);
connect(m_hotkey_scheduler, &HotkeyScheduler::StateSaveFile, this, &MainWindow::StateSave); connect(m_hotkey_scheduler, &HotkeyScheduler::StateSaveFile, this, &MainWindow::StateSave);
connect(m_hotkey_scheduler, &HotkeyScheduler::StateLoadFile, this, &MainWindow::StateLoad); connect(m_hotkey_scheduler, &HotkeyScheduler::StateLoadFile, this, &MainWindow::StateLoad);
connect(m_hotkey_scheduler, &HotkeyScheduler::StateLoadSlotHotkey, this, connect(m_hotkey_scheduler, &HotkeyScheduler::StateLoadSlotHotkey, this,
&MainWindow::StateLoadSlot); &MainWindow::StateLoadSlot);
connect(m_hotkey_scheduler, &HotkeyScheduler::StateSaveSlotHotkey, this, connect(m_hotkey_scheduler, &HotkeyScheduler::StateSaveSlotHotkey, this,
&MainWindow::StateSaveSlot); &MainWindow::StateSaveSlot);
connect(m_hotkey_scheduler, &HotkeyScheduler::SetStateSlotHotkey, this, connect(m_hotkey_scheduler, &HotkeyScheduler::SetStateSlotHotkey, this,
&MainWindow::SetStateSlot); &MainWindow::SetStateSlot);
connect(m_hotkey_scheduler, &HotkeyScheduler::IncrementSelectedStateSlotHotkey, this, connect(m_hotkey_scheduler, &HotkeyScheduler::IncrementSelectedStateSlotHotkey, this,
&MainWindow::IncrementSelectedStateSlot); &MainWindow::IncrementSelectedStateSlot);
connect(m_hotkey_scheduler, &HotkeyScheduler::DecrementSelectedStateSlotHotkey, this, connect(m_hotkey_scheduler, &HotkeyScheduler::DecrementSelectedStateSlotHotkey, this,
&MainWindow::DecrementSelectedStateSlot); &MainWindow::DecrementSelectedStateSlot);
connect(m_hotkey_scheduler, &HotkeyScheduler::StartRecording, this, connect(m_hotkey_scheduler, &HotkeyScheduler::StartRecording, this,
&MainWindow::OnStartRecording); &MainWindow::OnStartRecording);
connect(m_hotkey_scheduler, &HotkeyScheduler::PlayRecording, this, &MainWindow::OnPlayRecording); connect(m_hotkey_scheduler, &HotkeyScheduler::PlayRecording, this, &MainWindow::OnPlayRecording);
connect(m_hotkey_scheduler, &HotkeyScheduler::ExportRecording, this, connect(m_hotkey_scheduler, &HotkeyScheduler::ExportRecording, this,
&MainWindow::OnExportRecording); &MainWindow::OnExportRecording);
connect(m_hotkey_scheduler, &HotkeyScheduler::ConnectWiiRemote, this, connect(m_hotkey_scheduler, &HotkeyScheduler::ConnectWiiRemote, this,
&MainWindow::OnConnectWiiRemote); &MainWindow::OnConnectWiiRemote);
connect(m_hotkey_scheduler, &HotkeyScheduler::ToggleReadOnlyMode, [this] { connect(m_hotkey_scheduler, &HotkeyScheduler::ToggleReadOnlyMode, [this] {
auto& movie = m_system.GetMovie(); auto& movie = m_system.GetMovie();
bool read_only = !movie.IsReadOnly(); bool read_only = !movie.IsReadOnly();
movie.SetReadOnly(read_only); movie.SetReadOnly(read_only);
emit ReadOnlyModeChanged(read_only); emit ReadOnlyModeChanged(read_only);
}); });
#ifdef USE_RETRO_ACHIEVEMENTS #ifdef USE_RETRO_ACHIEVEMENTS
connect(m_hotkey_scheduler, &HotkeyScheduler::OpenAchievements, this, connect(m_hotkey_scheduler, &HotkeyScheduler::OpenAchievements, this,
&MainWindow::ShowAchievementsWindow, Qt::QueuedConnection); &MainWindow::ShowAchievementsWindow, Qt::QueuedConnection);
#endif // USE_RETRO_ACHIEVEMENTS #endif // USE_RETRO_ACHIEVEMENTS
connect(m_hotkey_scheduler, &HotkeyScheduler::Step, m_code_widget, &CodeWidget::Step); connect(m_hotkey_scheduler, &HotkeyScheduler::Step, m_code_widget, &CodeWidget::Step);
@ -679,14 +679,14 @@ void MainWindow::ConnectHotkeys()
connect(m_hotkey_scheduler, &HotkeyScheduler::SetPC, m_code_widget, &CodeWidget::SetPC); connect(m_hotkey_scheduler, &HotkeyScheduler::SetPC, m_code_widget, &CodeWidget::SetPC);
connect(m_hotkey_scheduler, &HotkeyScheduler::ToggleBreakpoint, m_code_widget, connect(m_hotkey_scheduler, &HotkeyScheduler::ToggleBreakpoint, m_code_widget,
&CodeWidget::ToggleBreakpoint); &CodeWidget::ToggleBreakpoint);
connect(m_hotkey_scheduler, &HotkeyScheduler::AddBreakpoint, m_code_widget, connect(m_hotkey_scheduler, &HotkeyScheduler::AddBreakpoint, m_code_widget,
&CodeWidget::AddBreakpoint); &CodeWidget::AddBreakpoint);
connect(m_hotkey_scheduler, &HotkeyScheduler::SkylandersPortalHotkey, this, connect(m_hotkey_scheduler, &HotkeyScheduler::SkylandersPortalHotkey, this,
&MainWindow::ShowSkylanderPortal); &MainWindow::ShowSkylanderPortal);
connect(m_hotkey_scheduler, &HotkeyScheduler::InfinityBaseHotkey, this, connect(m_hotkey_scheduler, &HotkeyScheduler::InfinityBaseHotkey, this,
&MainWindow::ShowInfinityBase); &MainWindow::ShowInfinityBase);
} }
void MainWindow::ConnectToolBar() void MainWindow::ConnectToolBar()
@ -718,7 +718,7 @@ void MainWindow::ConnectGameList()
connect(m_game_list, &GameList::GameSelected, this, [this] { Play(); }); connect(m_game_list, &GameList::GameSelected, this, [this] { Play(); });
connect(m_game_list, &GameList::NetPlayHost, this, &MainWindow::NetPlayHost); connect(m_game_list, &GameList::NetPlayHost, this, &MainWindow::NetPlayHost);
connect(m_game_list, &GameList::OnStartWithRiivolution, this, connect(m_game_list, &GameList::OnStartWithRiivolution, this,
&MainWindow::ShowRiivolutionBootWidget); &MainWindow::ShowRiivolutionBootWidget);
connect(m_game_list, &GameList::OpenGeneralSettings, this, &MainWindow::ShowGeneralWindow); connect(m_game_list, &GameList::OpenGeneralSettings, this, &MainWindow::ShowGeneralWindow);
connect(m_game_list, &GameList::OpenGraphicsSettings, this, &MainWindow::ShowGraphicsWindow); connect(m_game_list, &GameList::OpenGraphicsSettings, this, &MainWindow::ShowGraphicsWindow);
@ -732,7 +732,7 @@ void MainWindow::ConnectRenderWidget()
connect(m_render_widget, &RenderWidget::FocusChanged, this, [this](bool focus) { connect(m_render_widget, &RenderWidget::FocusChanged, this, [this](bool focus) {
if (m_render_widget->isFullScreen()) if (m_render_widget->isFullScreen())
SetFullScreenResolution(focus); SetFullScreenResolution(focus);
}); });
} }
void MainWindow::ConnectHost() void MainWindow::ConnectHost()
@ -792,17 +792,17 @@ QStringList MainWindow::PromptFileNames()
{ {
auto& settings = Settings::Instance().GetQSettings(); auto& settings = Settings::Instance().GetQSettings();
QStringList paths = DolphinFileDialog::getOpenFileNames( QStringList paths = DolphinFileDialog::getOpenFileNames(
this, tr("Select a File"), this, tr("Select a File"),
settings.value(QStringLiteral("mainwindow/lastdir"), QString{}).toString(), settings.value(QStringLiteral("mainwindow/lastdir"), QString{}).toString(),
QStringLiteral("%1 (*.elf *.dol *.gcm *.bin *.iso *.tgc *.wbfs *.ciso *.gcz *.wia *.rvz " QStringLiteral("%1 (*.elf *.dol *.gcm *.bin *.iso *.tgc *.wbfs *.ciso *.gcz *.wia *.rvz "
"hif_000000.nfs *.wad *.dff *.m3u *.json);;%2 (*)") "hif_000000.nfs *.wad *.dff *.m3u *.json);;%2 (*)")
.arg(tr("All GC/Wii files")) .arg(tr("All GC/Wii files"))
.arg(tr("All Files"))); .arg(tr("All Files")));
if (!paths.isEmpty()) if (!paths.isEmpty())
{ {
settings.setValue(QStringLiteral("mainwindow/lastdir"), settings.setValue(QStringLiteral("mainwindow/lastdir"),
QFileInfo(paths.front()).absoluteDir().absolutePath()); QFileInfo(paths.front()).absoluteDir().absolutePath());
} }
return paths; return paths;
@ -815,12 +815,12 @@ void MainWindow::ChangeDisc()
if (paths.empty()) if (paths.empty())
return; return;
m_system.GetDVDInterface().ChangeDisc(Core::CPUThreadGuard{ m_system }, paths); m_system.GetDVDInterface().ChangeDisc(Core::CPUThreadGuard{m_system}, paths);
} }
void MainWindow::EjectDisc() void MainWindow::EjectDisc()
{ {
m_system.GetDVDInterface().EjectDisc(Core::CPUThreadGuard{ m_system }, DVD::EjectCause::User); m_system.GetDVDInterface().EjectDisc(Core::CPUThreadGuard{m_system}, DVD::EjectCause::User);
} }
void MainWindow::OpenUserFolder() void MainWindow::OpenUserFolder()
@ -855,7 +855,7 @@ void MainWindow::Play(const std::optional<std::string>& savestate_path)
if (selection) if (selection)
{ {
StartGame(selection->GetFilePath(), ScanForSecondDisc::Yes, StartGame(selection->GetFilePath(), ScanForSecondDisc::Yes,
std::make_unique<BootSessionData>(savestate_path, DeleteSavestateAfterBoot::No)); std::make_unique<BootSessionData>(savestate_path, DeleteSavestateAfterBoot::No));
} }
else else
{ {
@ -863,7 +863,7 @@ void MainWindow::Play(const std::optional<std::string>& savestate_path)
if (!default_path.isEmpty() && QFile::exists(default_path)) if (!default_path.isEmpty() && QFile::exists(default_path))
{ {
StartGame(default_path, ScanForSecondDisc::Yes, StartGame(default_path, ScanForSecondDisc::Yes,
std::make_unique<BootSessionData>(savestate_path, DeleteSavestateAfterBoot::No)); std::make_unique<BootSessionData>(savestate_path, DeleteSavestateAfterBoot::No));
} }
else else
{ {
@ -930,11 +930,11 @@ bool MainWindow::RequestStop()
} }
const bool rendered_widget_was_active = const bool rendered_widget_was_active =
Settings::Instance().IsKeepWindowOnTopEnabled() || Settings::Instance().IsKeepWindowOnTopEnabled() ||
(m_render_widget->isActiveWindow() && !m_render_widget->isFullScreen()); (m_render_widget->isActiveWindow() && !m_render_widget->isFullScreen());
QWidget* confirm_parent = (!m_rendering_to_main && rendered_widget_was_active) ? QWidget* confirm_parent = (!m_rendering_to_main && rendered_widget_was_active) ?
m_render_widget : m_render_widget :
static_cast<QWidget*>(this); static_cast<QWidget*>(this);
const bool was_cursor_locked = m_render_widget->IsCursorLocked(); const bool was_cursor_locked = m_render_widget->IsCursorLocked();
if (!m_render_widget->isFullScreen()) if (!m_render_widget->isFullScreen())
@ -975,14 +975,14 @@ bool MainWindow::RequestStop()
if (m_stop_requested) if (m_stop_requested)
{ {
message = tr("A shutdown is already in progress. Unsaved data " message = tr("A shutdown is already in progress. Unsaved data "
"may be lost if you stop the current emulation " "may be lost if you stop the current emulation "
"before it completes. Force stop?"); "before it completes. Force stop?");
} }
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION #ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
else if (AchievementManager::GetInstance().CheckForModifications()) else if (AchievementManager::GetInstance().CheckForModifications())
{ {
message = tr( message = tr(
"Do you want to stop the current emulation? Unsaved achievement modifications detected."); "Do you want to stop the current emulation? Unsaved achievement modifications detected.");
} }
#endif // RC_CLIENT_SUPPORTS_RAINTEGRATION #endif // RC_CLIENT_SUPPORTS_RAINTEGRATION
else else
@ -990,8 +990,8 @@ bool MainWindow::RequestStop()
message = tr("Do you want to stop the current emulation?"); message = tr("Do you want to stop the current emulation?");
} }
auto confirm = ModalMessageBox::question(confirm_parent, tr("Confirm"), message, auto confirm = ModalMessageBox::question(confirm_parent, tr("Confirm"), message,
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes | QMessageBox::No,
QMessageBox::NoButton, Qt::ApplicationModal); QMessageBox::NoButton, Qt::ApplicationModal);
// If a user confirmed stopping the emulation, we do not capture the cursor again, // If a user confirmed stopping the emulation, we do not capture the cursor again,
// even if the render widget will stay alive for a while. // even if the render widget will stay alive for a while.
@ -1095,11 +1095,11 @@ void MainWindow::ScreenShot()
} }
void MainWindow::ScanForSecondDiscAndStartGame(const UICommon::GameFile& game, void MainWindow::ScanForSecondDiscAndStartGame(const UICommon::GameFile& game,
std::unique_ptr<BootSessionData> boot_session_data) std::unique_ptr<BootSessionData> boot_session_data)
{ {
auto second_game = m_game_list->FindSecondDisc(game); auto second_game = m_game_list->FindSecondDisc(game);
std::vector<std::string> paths = { game.GetFilePath() }; std::vector<std::string> paths = {game.GetFilePath()};
if (second_game != nullptr) if (second_game != nullptr)
paths.push_back(second_game->GetFilePath()); paths.push_back(second_game->GetFilePath());
@ -1107,13 +1107,13 @@ void MainWindow::ScanForSecondDiscAndStartGame(const UICommon::GameFile& game,
} }
void MainWindow::StartGame(const QString& path, ScanForSecondDisc scan, void MainWindow::StartGame(const QString& path, ScanForSecondDisc scan,
std::unique_ptr<BootSessionData> boot_session_data) std::unique_ptr<BootSessionData> boot_session_data)
{ {
StartGame(path.toStdString(), scan, std::move(boot_session_data)); StartGame(path.toStdString(), scan, std::move(boot_session_data));
} }
void MainWindow::StartGame(const std::string& path, ScanForSecondDisc scan, void MainWindow::StartGame(const std::string& path, ScanForSecondDisc scan,
std::unique_ptr<BootSessionData> boot_session_data) std::unique_ptr<BootSessionData> boot_session_data)
{ {
if (scan == ScanForSecondDisc::Yes) if (scan == ScanForSecondDisc::Yes)
{ {
@ -1126,14 +1126,14 @@ void MainWindow::StartGame(const std::string& path, ScanForSecondDisc scan,
} }
StartGame(BootParameters::GenerateFromFile( StartGame(BootParameters::GenerateFromFile(
path, boot_session_data ? std::move(*boot_session_data) : BootSessionData())); path, boot_session_data ? std::move(*boot_session_data) : BootSessionData()));
} }
void MainWindow::StartGame(const std::vector<std::string>& paths, void MainWindow::StartGame(const std::vector<std::string>& paths,
std::unique_ptr<BootSessionData> boot_session_data) std::unique_ptr<BootSessionData> boot_session_data)
{ {
StartGame(BootParameters::GenerateFromFile( StartGame(BootParameters::GenerateFromFile(
paths, boot_session_data ? std::move(*boot_session_data) : BootSessionData())); paths, boot_session_data ? std::move(*boot_session_data) : BootSessionData()));
} }
void MainWindow::StartGame(std::unique_ptr<BootParameters>&& parameters) void MainWindow::StartGame(std::unique_ptr<BootParameters>&& parameters)
@ -1150,18 +1150,21 @@ void MainWindow::StartGame(std::unique_ptr<BootParameters>&& parameters)
When booting Triforce games, we need to ensure that the hardware is set up correctly. When booting Triforce games, we need to ensure that the hardware is set up correctly.
*/ */
const auto volume_type = const auto volume_type =
std::get<BootParameters::Disc>(parameters->parameters).volume->GetVolumeType(); std::get<BootParameters::Disc>(parameters->parameters).volume->GetVolumeType();
const bool triforce_hardware_sp1 = Config::Get(Config::MAIN_SERIAL_PORT_1) == ExpansionInterface::EXIDeviceType::Baseboard; const bool triforce_hardware_sp1 =
const bool triforce_hardware_port_1 = Config::Get(Config::GetInfoForSIDevice(0)) == SerialInterface::SIDevices::SIDEVICE_AM_BASEBOARD; Config::Get(Config::MAIN_SERIAL_PORT_1) == ExpansionInterface::EXIDeviceType::Baseboard;
const bool triforce_hardware_port_1 = Config::Get(Config::GetInfoForSIDevice(0)) ==
SerialInterface::SIDevices::SIDEVICE_AM_BASEBOARD;
if (volume_type == DiscIO::Platform::Triforce) if (volume_type == DiscIO::Platform::Triforce)
{ {
if (!triforce_hardware_sp1 || !triforce_hardware_port_1) if (!triforce_hardware_sp1 || !triforce_hardware_port_1)
{ {
ModalMessageBox::critical( ModalMessageBox::critical(
this, tr("Error"), tr("To boot a Triforce game, SP1 and Port 1 must be set to Triforce Baseboard."), this, tr("Error"),
QMessageBox::Ok); tr("To boot a Triforce game, SP1 and Port 1 must be set to Triforce Baseboard."),
QMessageBox::Ok);
HideRenderWidget(); HideRenderWidget();
return; return;
} }
@ -1174,8 +1177,9 @@ void MainWindow::StartGame(std::unique_ptr<BootParameters>&& parameters)
if (triforce_hardware_sp1 || triforce_hardware_port_1) if (triforce_hardware_sp1 || triforce_hardware_port_1)
{ {
ModalMessageBox::warning( ModalMessageBox::warning(
this, tr("Warning"), tr("Non-Triforce games cannot be booted with Triforce hardware attached."), this, tr("Warning"),
QMessageBox::Ok); tr("Non-Triforce games cannot be booted with Triforce hardware attached."),
QMessageBox::Ok);
} }
} }
} }
@ -1196,7 +1200,7 @@ void MainWindow::StartGame(std::unique_ptr<BootParameters>&& parameters)
// Boot up, show an error if it fails to load the game. // Boot up, show an error if it fails to load the game.
if (!BootManager::BootCore(m_system, std::move(parameters), if (!BootManager::BootCore(m_system, std::move(parameters),
::GetWindowSystemInfo(m_render_widget->windowHandle()))) ::GetWindowSystemInfo(m_render_widget->windowHandle())))
{ {
ModalMessageBox::critical(this, tr("Error"), tr("Failed to init core"), QMessageBox::Ok); ModalMessageBox::critical(this, tr("Error"), tr("Failed to init core"), QMessageBox::Ok);
HideRenderWidget(); HideRenderWidget();
@ -1228,7 +1232,7 @@ void MainWindow::SetFullScreenResolution(bool fullscreen)
memset(&screen_settings, 0, sizeof(screen_settings)); memset(&screen_settings, 0, sizeof(screen_settings));
screen_settings.dmSize = sizeof(screen_settings); screen_settings.dmSize = sizeof(screen_settings);
sscanf(Config::Get(Config::MAIN_FULLSCREEN_DISPLAY_RES).c_str(), "%dx%d", sscanf(Config::Get(Config::MAIN_FULLSCREEN_DISPLAY_RES).c_str(), "%dx%d",
&screen_settings.dmPelsWidth, &screen_settings.dmPelsHeight); &screen_settings.dmPelsWidth, &screen_settings.dmPelsHeight);
screen_settings.dmBitsPerPel = 32; screen_settings.dmBitsPerPel = 32;
screen_settings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; screen_settings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
@ -1299,14 +1303,14 @@ void MainWindow::HideRenderWidget(bool reinit, bool is_exit)
connect(m_render_widget, &RenderWidget::FocusChanged, this, [this](bool focus) { connect(m_render_widget, &RenderWidget::FocusChanged, this, [this](bool focus) {
if (m_render_widget->isFullScreen()) if (m_render_widget->isFullScreen())
SetFullScreenResolution(focus); SetFullScreenResolution(focus);
}); });
// The controller interface will still be registered to the old render widget, if the core // The controller interface will still be registered to the old render widget, if the core
// has booted. Therefore, we should re-bind it to the main window for now. When the core // has booted. Therefore, we should re-bind it to the main window for now. When the core
// is next started, it will be swapped back to the new render widget. // is next started, it will be swapped back to the new render widget.
g_controller_interface.ChangeWindow(::GetWindowSystemInfo(windowHandle()).render_window, g_controller_interface.ChangeWindow(::GetWindowSystemInfo(windowHandle()).render_window,
is_exit ? ControllerInterface::WindowChangeReason::Exit : is_exit ? ControllerInterface::WindowChangeReason::Exit :
ControllerInterface::WindowChangeReason::Other); ControllerInterface::WindowChangeReason::Other);
} }
} }
@ -1325,7 +1329,7 @@ void MainWindow::ShowFreeLookWindow()
#ifdef USE_RETRO_ACHIEVEMENTS #ifdef USE_RETRO_ACHIEVEMENTS
connect(m_freelook_window, &FreeLookWindow::OpenAchievementSettings, this, connect(m_freelook_window, &FreeLookWindow::OpenAchievementSettings, this,
&MainWindow::ShowAchievementSettings); &MainWindow::ShowAchievementSettings);
#endif // USE_RETRO_ACHIEVEMENTS #endif // USE_RETRO_ACHIEVEMENTS
} }
@ -1342,9 +1346,9 @@ void MainWindow::ShowSettingsWindow()
if (GetWindowSystemType() == WindowSystemType::X11) if (GetWindowSystemType() == WindowSystemType::X11)
{ {
m_xrr_config = std::make_unique<X11Utils::XRRConfiguration>( m_xrr_config = std::make_unique<X11Utils::XRRConfiguration>(
static_cast<Display*>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow( static_cast<Display*>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow(
"display", windowHandle())), "display", windowHandle())),
winId()); winId());
} }
#endif #endif
m_settings_window = new SettingsWindow(this); m_settings_window = new SettingsWindow(this);
@ -1370,7 +1374,7 @@ void MainWindow::ShowGeneralWindow()
void MainWindow::ShowAboutDialog() void MainWindow::ShowAboutDialog()
{ {
AboutDialog about{ this }; AboutDialog about{this};
about.exec(); about.exec();
} }
@ -1414,7 +1418,7 @@ void MainWindow::ShowFIFOPlayer()
{ {
m_fifo_window = new FIFOPlayerWindow(m_system.GetFifoPlayer(), m_system.GetFifoRecorder()); m_fifo_window = new FIFOPlayerWindow(m_system.GetFifoPlayer(), m_system.GetFifoRecorder());
connect(m_fifo_window, &FIFOPlayerWindow::LoadFIFORequested, this, connect(m_fifo_window, &FIFOPlayerWindow::LoadFIFORequested, this,
[this](const QString& path) { StartGame(path, ScanForSecondDisc::No); }); [this](const QString& path) { StartGame(path, ScanForSecondDisc::No); });
} }
m_fifo_window->show(); m_fifo_window->show();
@ -1461,10 +1465,10 @@ void MainWindow::ShowWiiSpeakWindow()
void MainWindow::StateLoad() void MainWindow::StateLoad()
{ {
QString dialog_path = (Config::Get(Config::MAIN_CURRENT_STATE_PATH).empty()) ? QString dialog_path = (Config::Get(Config::MAIN_CURRENT_STATE_PATH).empty()) ?
QDir::currentPath() : QDir::currentPath() :
QString::fromStdString(Config::Get(Config::MAIN_CURRENT_STATE_PATH)); QString::fromStdString(Config::Get(Config::MAIN_CURRENT_STATE_PATH));
QString path = DolphinFileDialog::getOpenFileName( QString path = DolphinFileDialog::getOpenFileName(
this, tr("Select a File"), dialog_path, tr("All Save States (*.sav *.s##);; All Files (*)")); this, tr("Select a File"), dialog_path, tr("All Save States (*.sav *.s##);; All Files (*)"));
Config::SetBase(Config::MAIN_CURRENT_STATE_PATH, QFileInfo(path).dir().path().toStdString()); Config::SetBase(Config::MAIN_CURRENT_STATE_PATH, QFileInfo(path).dir().path().toStdString());
if (!path.isEmpty()) if (!path.isEmpty())
State::LoadAs(m_system, path.toStdString()); State::LoadAs(m_system, path.toStdString());
@ -1473,10 +1477,10 @@ void MainWindow::StateLoad()
void MainWindow::StateSave() void MainWindow::StateSave()
{ {
QString dialog_path = (Config::Get(Config::MAIN_CURRENT_STATE_PATH).empty()) ? QString dialog_path = (Config::Get(Config::MAIN_CURRENT_STATE_PATH).empty()) ?
QDir::currentPath() : QDir::currentPath() :
QString::fromStdString(Config::Get(Config::MAIN_CURRENT_STATE_PATH)); QString::fromStdString(Config::Get(Config::MAIN_CURRENT_STATE_PATH));
QString path = DolphinFileDialog::getSaveFileName( QString path = DolphinFileDialog::getSaveFileName(
this, tr("Select a File"), dialog_path, tr("All Save States (*.sav *.s##);; All Files (*)")); this, tr("Select a File"), dialog_path, tr("All Save States (*.sav *.s##);; All Files (*)"));
Config::SetBase(Config::MAIN_CURRENT_STATE_PATH, QFileInfo(path).dir().path().toStdString()); Config::SetBase(Config::MAIN_CURRENT_STATE_PATH, QFileInfo(path).dir().path().toStdString());
if (!path.isEmpty()) if (!path.isEmpty())
State::SaveAs(m_system, path.toStdString()); State::SaveAs(m_system, path.toStdString());
@ -1528,8 +1532,8 @@ void MainWindow::SetStateSlot(int slot)
m_state_slot = slot; m_state_slot = slot;
Core::DisplayMessage(fmt::format("Selected slot {} - {}", m_state_slot, Core::DisplayMessage(fmt::format("Selected slot {} - {}", m_state_slot,
State::GetInfoStringOfSlot(m_state_slot, false)), State::GetInfoStringOfSlot(m_state_slot, false)),
2500); 2500);
} }
void MainWindow::IncrementSelectedStateSlot() void MainWindow::IncrementSelectedStateSlot()
@ -1557,7 +1561,7 @@ void MainWindow::PerformOnlineUpdate(const std::string& region)
void MainWindow::BootWiiSystemMenu() void MainWindow::BootWiiSystemMenu()
{ {
StartGame(std::make_unique<BootParameters>(BootParameters::NANDTitle{ Titles::SYSTEM_MENU })); StartGame(std::make_unique<BootParameters>(BootParameters::NANDTitle{Titles::SYSTEM_MENU}));
} }
void MainWindow::NetPlayInit() void MainWindow::NetPlayInit()
@ -1565,10 +1569,10 @@ void MainWindow::NetPlayInit()
const auto& game_list_model = m_game_list->GetGameListModel(); const auto& game_list_model = m_game_list->GetGameListModel();
m_netplay_setup_dialog = new NetPlaySetupDialog(game_list_model, this); m_netplay_setup_dialog = new NetPlaySetupDialog(game_list_model, this);
m_netplay_dialog = new NetPlayDialog( m_netplay_dialog = new NetPlayDialog(
game_list_model, game_list_model,
[this](const std::string& path, std::unique_ptr<BootSessionData> boot_session_data) { [this](const std::string& path, std::unique_ptr<BootSessionData> boot_session_data) {
StartGame(path, ScanForSecondDisc::Yes, std::move(boot_session_data)); StartGame(path, ScanForSecondDisc::Yes, std::move(boot_session_data));
}); });
#ifdef USE_DISCORD_PRESENCE #ifdef USE_DISCORD_PRESENCE
m_netplay_discord = new DiscordHandler(this); m_netplay_discord = new DiscordHandler(this);
#endif #endif
@ -1584,9 +1588,9 @@ void MainWindow::NetPlayInit()
m_netplay_discord->Start(); m_netplay_discord->Start();
#endif #endif
connect(&Settings::Instance(), &Settings::ConfigChanged, this, connect(&Settings::Instance(), &Settings::ConfigChanged, this,
&MainWindow::UpdateScreenSaverInhibition); &MainWindow::UpdateScreenSaverInhibition);
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, connect(&Settings::Instance(), &Settings::EmulationStateChanged, this,
&MainWindow::UpdateScreenSaverInhibition); &MainWindow::UpdateScreenSaverInhibition);
} }
bool MainWindow::NetPlayJoin() bool MainWindow::NetPlayJoin()
@ -1594,14 +1598,14 @@ bool MainWindow::NetPlayJoin()
if (!Core::IsUninitialized(m_system)) if (!Core::IsUninitialized(m_system))
{ {
ModalMessageBox::critical(nullptr, tr("Error"), ModalMessageBox::critical(nullptr, tr("Error"),
tr("Can't start a NetPlay Session while a game is still running!")); tr("Can't start a NetPlay Session while a game is still running!"));
return false; return false;
} }
if (m_netplay_dialog->isVisible()) if (m_netplay_dialog->isVisible())
{ {
ModalMessageBox::critical(nullptr, tr("Error"), ModalMessageBox::critical(nullptr, tr("Error"),
tr("A NetPlay Session is already in progress!")); tr("A NetPlay Session is already in progress!"));
return false; return false;
} }
@ -1621,7 +1625,7 @@ bool MainWindow::NetPlayJoin()
else else
{ {
host_ip = is_traversal ? Config::Get(Config::NETPLAY_HOST_CODE) : host_ip = is_traversal ? Config::Get(Config::NETPLAY_HOST_CODE) :
Config::Get(Config::NETPLAY_ADDRESS); Config::Get(Config::NETPLAY_ADDRESS);
host_port = Config::Get(Config::NETPLAY_CONNECT_PORT); host_port = Config::Get(Config::NETPLAY_CONNECT_PORT);
} }
@ -1640,9 +1644,9 @@ bool MainWindow::NetPlayJoin()
// Create Client // Create Client
const bool is_hosting_netplay = server != nullptr; const bool is_hosting_netplay = server != nullptr;
Settings::Instance().ResetNetPlayClient(new NetPlay::NetPlayClient( Settings::Instance().ResetNetPlayClient(new NetPlay::NetPlayClient(
host_ip, host_port, m_netplay_dialog, nickname, host_ip, host_port, m_netplay_dialog, nickname,
NetPlay::NetTraversalConfig{ is_hosting_netplay ? false : is_traversal, traversal_host, NetPlay::NetTraversalConfig{is_hosting_netplay ? false : is_traversal, traversal_host,
traversal_port })); traversal_port}));
if (!Settings::Instance().GetNetPlayClient()->IsConnected()) if (!Settings::Instance().GetNetPlayClient()->IsConnected())
{ {
@ -1661,14 +1665,14 @@ bool MainWindow::NetPlayHost(const UICommon::GameFile& game)
if (!Core::IsUninitialized(m_system)) if (!Core::IsUninitialized(m_system))
{ {
ModalMessageBox::critical(nullptr, tr("Error"), ModalMessageBox::critical(nullptr, tr("Error"),
tr("Can't start a NetPlay Session while a game is still running!")); tr("Can't start a NetPlay Session while a game is still running!"));
return false; return false;
} }
if (m_netplay_dialog->isVisible()) if (m_netplay_dialog->isVisible())
{ {
ModalMessageBox::critical(nullptr, tr("Error"), ModalMessageBox::critical(nullptr, tr("Error"),
tr("A NetPlay Session is already in progress!")); tr("A NetPlay Session is already in progress!"));
return false; return false;
} }
@ -1687,22 +1691,22 @@ bool MainWindow::NetPlayHost(const UICommon::GameFile& game)
// Create Server // Create Server
Settings::Instance().ResetNetPlayServer( Settings::Instance().ResetNetPlayServer(
new NetPlay::NetPlayServer(host_port, use_upnp, m_netplay_dialog, new NetPlay::NetPlayServer(host_port, use_upnp, m_netplay_dialog,
NetPlay::NetTraversalConfig{ is_traversal, traversal_host, NetPlay::NetTraversalConfig{is_traversal, traversal_host,
traversal_port, traversal_port_alt })); traversal_port, traversal_port_alt}));
if (!Settings::Instance().GetNetPlayServer()->is_connected) if (!Settings::Instance().GetNetPlayServer()->is_connected)
{ {
ModalMessageBox::critical( ModalMessageBox::critical(
nullptr, tr("Failed to open server"), nullptr, tr("Failed to open server"),
tr("Failed to listen on port %1. Is another instance of the NetPlay server running?") tr("Failed to listen on port %1. Is another instance of the NetPlay server running?")
.arg(host_port)); .arg(host_port));
NetPlayQuit(); NetPlayQuit();
return false; return false;
} }
Settings::Instance().GetNetPlayServer()->ChangeGame(game.GetSyncIdentifier(), Settings::Instance().GetNetPlayServer()->ChangeGame(game.GetSyncIdentifier(),
m_game_list->GetNetPlayName(game)); m_game_list->GetNetPlayName(game));
// Join our local server // Join our local server
return NetPlayJoin(); return NetPlayJoin();
@ -1720,7 +1724,7 @@ void MainWindow::NetPlayQuit()
void MainWindow::UpdateScreenSaverInhibition() void MainWindow::UpdateScreenSaverInhibition()
{ {
const bool inhibit = Config::Get(Config::MAIN_DISABLE_SCREENSAVER) && const bool inhibit = Config::Get(Config::MAIN_DISABLE_SCREENSAVER) &&
(Core::GetState(m_system) == Core::State::Running); (Core::GetState(m_system) == Core::State::Running);
if (inhibit == m_is_screensaver_inhibited) if (inhibit == m_is_screensaver_inhibited)
return; return;
@ -1794,9 +1798,9 @@ void MainWindow::dropEvent(QDropEvent* event)
if (show_confirm) if (show_confirm)
{ {
if (ModalMessageBox::question( if (ModalMessageBox::question(
this, tr("Confirm"), this, tr("Confirm"),
tr("Do you want to add \"%1\" to the list of Game Paths?").arg(folder)) != tr("Do you want to add \"%1\" to the list of Game Paths?").arg(folder)) !=
QMessageBox::Yes) QMessageBox::Yes)
return; return;
} }
settings.AddPath(folder); settings.AddPath(folder);
@ -1811,25 +1815,25 @@ QSize MainWindow::sizeHint() const
void MainWindow::OnBootGameCubeIPL(DiscIO::Region region) void MainWindow::OnBootGameCubeIPL(DiscIO::Region region)
{ {
StartGame(std::make_unique<BootParameters>(BootParameters::IPL{ region })); StartGame(std::make_unique<BootParameters>(BootParameters::IPL{region}));
} }
void MainWindow::OnImportNANDBackup() void MainWindow::OnImportNANDBackup()
{ {
auto response = ModalMessageBox::question( auto response = ModalMessageBox::question(
this, tr("Question"), this, tr("Question"),
tr("Merging a new NAND over your currently selected NAND will overwrite any channels " tr("Merging a new NAND over your currently selected NAND will overwrite any channels "
"and savegames that already exist. This process is not reversible, so it is " "and savegames that already exist. This process is not reversible, so it is "
"recommended that you keep backups of both NANDs. Are you sure you want to " "recommended that you keep backups of both NANDs. Are you sure you want to "
"continue?")); "continue?"));
if (response == QMessageBox::No) if (response == QMessageBox::No)
return; return;
QString file = QString file =
DolphinFileDialog::getOpenFileName(this, tr("Select NAND Backup"), QDir::currentPath(), DolphinFileDialog::getOpenFileName(this, tr("Select NAND Backup"), QDir::currentPath(),
tr("BootMii NAND backup file (*.bin);;" tr("BootMii NAND backup file (*.bin);;"
"All Files (*)")); "All Files (*)"));
if (file.isEmpty()) if (file.isEmpty())
return; return;
@ -1844,26 +1848,26 @@ void MainWindow::OnImportNANDBackup()
std::future<void> result = std::async(std::launch::async, [&] { std::future<void> result = std::async(std::launch::async, [&] {
DiscIO::NANDImporter().ImportNANDBin( DiscIO::NANDImporter().ImportNANDBin(
file.toStdString(), file.toStdString(),
[&dialog, beginning] { [&dialog, beginning] {
dialog.SetLabelText( dialog.SetLabelText(
tr("Importing NAND backup\n Time elapsed: %1s") tr("Importing NAND backup\n Time elapsed: %1s")
.arg((QDateTime::currentDateTime().toMSecsSinceEpoch() - beginning) / 1000)); .arg((QDateTime::currentDateTime().toMSecsSinceEpoch() - beginning) / 1000));
}, },
[this] { [this] {
std::optional<std::string> keys_file = RunOnObject(this, [this] { std::optional<std::string> keys_file = RunOnObject(this, [this] {
return DolphinFileDialog::getOpenFileName( return DolphinFileDialog::getOpenFileName(
this, tr("Select Keys File (OTP/SEEPROM Dump)"), QDir::currentPath(), this, tr("Select Keys File (OTP/SEEPROM Dump)"), QDir::currentPath(),
tr("BootMii keys file (*.bin);;" tr("BootMii keys file (*.bin);;"
"All Files (*)")) "All Files (*)"))
.toStdString(); .toStdString();
}); });
if (keys_file) if (keys_file)
return *keys_file; return *keys_file;
return std::string(""); return std::string("");
}); });
dialog.Reset(); dialog.Reset();
}); });
dialog.GetRaw()->exec(); dialog.GetRaw()->exec();
@ -1877,13 +1881,13 @@ void MainWindow::OnPlayRecording()
if (AchievementManager::GetInstance().IsHardcoreModeActive()) if (AchievementManager::GetInstance().IsHardcoreModeActive())
{ {
ModalMessageBox::critical( ModalMessageBox::critical(
this, tr("Error"), this, tr("Error"),
tr("Playback of input recordings is disabled in RetroAchievements hardcore mode.")); tr("Playback of input recordings is disabled in RetroAchievements hardcore mode."));
return; return;
} }
QString dtm_file = DolphinFileDialog::getOpenFileName( QString dtm_file = DolphinFileDialog::getOpenFileName(
this, tr("Select the Recording File to Play"), QString(), tr("Dolphin TAS Movies (*.dtm)")); this, tr("Select the Recording File to Play"), QString(), tr("Dolphin TAS Movies (*.dtm)"));
if (dtm_file.isEmpty()) if (dtm_file.isEmpty())
return; return;
@ -1909,8 +1913,8 @@ void MainWindow::OnStartRecording()
{ {
auto& movie = m_system.GetMovie(); auto& movie = m_system.GetMovie();
if (Core::GetState(m_system) == Core::State::Starting || if (Core::GetState(m_system) == Core::State::Starting ||
Core::GetState(m_system) == Core::State::Stopping || movie.IsRecordingInput() || Core::GetState(m_system) == Core::State::Stopping || movie.IsRecordingInput() ||
movie.IsPlayingInput()) movie.IsPlayingInput())
{ {
return; return;
} }
@ -1961,7 +1965,7 @@ void MainWindow::OnExportRecording()
const Core::CPUThreadGuard guard(m_system); const Core::CPUThreadGuard guard(m_system);
QString dtm_file = DolphinFileDialog::getSaveFileName( QString dtm_file = DolphinFileDialog::getSaveFileName(
this, tr("Save Recording File As"), QString(), tr("Dolphin TAS Movies (*.dtm)")); this, tr("Save Recording File As"), QString(), tr("Dolphin TAS Movies (*.dtm)"));
if (!dtm_file.isEmpty()) if (!dtm_file.isEmpty())
m_system.GetMovie().SaveRecording(dtm_file.toStdString()); m_system.GetMovie().SaveRecording(dtm_file.toStdString());
} }
@ -1991,7 +1995,7 @@ void MainWindow::ShowTASInput()
m_gba_tas_input_windows[i]->activateWindow(); m_gba_tas_input_windows[i]->activateWindow();
} }
else if (si_device != SerialInterface::SIDEVICE_NONE && else if (si_device != SerialInterface::SIDEVICE_NONE &&
si_device != SerialInterface::SIDEVICE_GC_GBA) si_device != SerialInterface::SIDEVICE_GC_GBA)
{ {
m_gc_tas_input_windows[i]->show(); m_gc_tas_input_windows[i]->show();
m_gc_tas_input_windows[i]->raise(); m_gc_tas_input_windows[i]->raise();
@ -2002,7 +2006,7 @@ void MainWindow::ShowTASInput()
for (int i = 0; i < num_wii_controllers; i++) for (int i = 0; i < num_wii_controllers; i++)
{ {
if (Config::Get(Config::GetInfoForWiimoteSource(i)) == WiimoteSource::Emulated && if (Config::Get(Config::GetInfoForWiimoteSource(i)) == WiimoteSource::Emulated &&
(!Core::IsRunning(m_system) || m_system.IsWii())) (!Core::IsRunning(m_system) || m_system.IsWii()))
{ {
m_wii_tas_input_windows[i]->show(); m_wii_tas_input_windows[i]->show();
m_wii_tas_input_windows[i]->raise(); m_wii_tas_input_windows[i]->raise();
@ -2032,7 +2036,7 @@ void MainWindow::ShowAchievementsWindow()
m_achievements_window->show(); m_achievements_window->show();
m_achievements_window->raise(); m_achievements_window->raise();
m_achievements_window->activateWindow(); m_achievements_window->activateWindow();
m_achievements_window->UpdateData(AchievementManager::UpdatedItems{ .all = true }); m_achievements_window->UpdateData(AchievementManager::UpdatedItems{.all = true});
} }
void MainWindow::ShowAchievementSettings() void MainWindow::ShowAchievementSettings()
@ -2076,7 +2080,7 @@ void MainWindow::ShowCheatsManager()
void MainWindow::ShowRiivolutionBootWidget(const UICommon::GameFile& game) void MainWindow::ShowRiivolutionBootWidget(const UICommon::GameFile& game)
{ {
auto second_game = m_game_list->FindSecondDisc(game); auto second_game = m_game_list->FindSecondDisc(game);
std::vector<std::string> paths = { game.GetFilePath() }; std::vector<std::string> paths = {game.GetFilePath()};
if (second_game != nullptr) if (second_game != nullptr)
paths.push_back(second_game->GetFilePath()); paths.push_back(second_game->GetFilePath());
std::unique_ptr<BootParameters> boot_params = BootParameters::GenerateFromFile(paths); std::unique_ptr<BootParameters> boot_params = BootParameters::GenerateFromFile(paths);
@ -2087,11 +2091,11 @@ void MainWindow::ShowRiivolutionBootWidget(const UICommon::GameFile& game)
auto& disc = std::get<BootParameters::Disc>(boot_params->parameters); auto& disc = std::get<BootParameters::Disc>(boot_params->parameters);
RiivolutionBootWidget w(disc.volume->GetGameID(), disc.volume->GetRevision(), RiivolutionBootWidget w(disc.volume->GetGameID(), disc.volume->GetRevision(),
disc.volume->GetDiscNumber(), game.GetFilePath(), this); disc.volume->GetDiscNumber(), game.GetFilePath(), this);
#ifdef USE_RETRO_ACHIEVEMENTS #ifdef USE_RETRO_ACHIEVEMENTS
connect(&w, &RiivolutionBootWidget::OpenAchievementSettings, this, connect(&w, &RiivolutionBootWidget::OpenAchievementSettings, this,
&MainWindow::ShowAchievementSettings); &MainWindow::ShowAchievementSettings);
#endif // USE_RETRO_ACHIEVEMENTS #endif // USE_RETRO_ACHIEVEMENTS
w.exec(); w.exec();

View file

@ -310,8 +310,8 @@ void MenuBar::AddToolsMenu()
m_pal_ipl = m_pal_ipl =
gc_ipl->addAction(tr("PAL"), this, [this] { emit BootGameCubeIPL(DiscIO::Region::PAL); }); gc_ipl->addAction(tr("PAL"), this, [this] { emit BootGameCubeIPL(DiscIO::Region::PAL); });
m_dev_ipl = m_dev_ipl = gc_ipl->addAction(tr("Triforce"), this,
gc_ipl->addAction(tr("Triforce"), this, [this] { emit BootGameCubeIPL(DiscIO::Region::DEV); }); [this] { emit BootGameCubeIPL(DiscIO::Region::DEV); });
tools_menu->addAction(tr("Memory Card Manager"), this, [this] { emit ShowMemcardManager(); }); tools_menu->addAction(tr("Memory Card Manager"), this, [this] { emit ShowMemcardManager(); });

View file

@ -138,16 +138,10 @@ void GameCubePane::CreateWidgets()
} }
// Add SP1 devices // Add SP1 devices
for (const auto device : { for (const auto device :
EXIDeviceType::None, {EXIDeviceType::None, EXIDeviceType::Dummy, EXIDeviceType::Ethernet,
EXIDeviceType::Dummy, EXIDeviceType::EthernetXLink, EXIDeviceType::EthernetTapServer,
EXIDeviceType::Ethernet, EXIDeviceType::EthernetBuiltIn, EXIDeviceType::ModemTapServer, EXIDeviceType::Baseboard})
EXIDeviceType::EthernetXLink,
EXIDeviceType::EthernetTapServer,
EXIDeviceType::EthernetBuiltIn,
EXIDeviceType::ModemTapServer,
EXIDeviceType::Baseboard
})
{ {
m_slot_combos[ExpansionInterface::Slot::SP1]->addItem(tr(fmt::format("{:n}", device).c_str()), m_slot_combos[ExpansionInterface::Slot::SP1]->addItem(tr(fmt::format("{:n}", device).c_str()),
static_cast<int>(device)); static_cast<int>(device));

View file

@ -46,7 +46,7 @@ struct GCPadStatus
u8 triggerRight = 0; // 0 <= triggerRight <= 255 u8 triggerRight = 0; // 0 <= triggerRight <= 255
u8 analogA = 0; // 0 <= analogA <= 255 u8 analogA = 0; // 0 <= analogA <= 255
u8 analogB = 0; // 0 <= analogB <= 255 u8 analogB = 0; // 0 <= analogB <= 255
//Triforce // Triforce
u8 switches = 0; u8 switches = 0;
bool isConnected = true; bool isConnected = true;

View file

@ -499,8 +499,7 @@ const std::string& GameFile::GetName(const Core::TitleDatabase& title_database)
if (IsModDescriptor()) if (IsModDescriptor())
return GetName(Variant::LongAndPossiblyCustom); return GetName(Variant::LongAndPossiblyCustom);
const std::string& database_name = const std::string& database_name = title_database.GetTitleName(m_gametdb_id, GetConfigLanguage());
title_database.GetTitleName(m_gametdb_id, GetConfigLanguage());
return database_name.empty() ? GetName(Variant::LongAndPossiblyCustom) : database_name; return database_name.empty() ? GetName(Variant::LongAndPossiblyCustom) : database_name;
} }