mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 13:27:45 -07:00
Compare commits
31 Commits
fb71c32658
...
fe96bf4108
Author | SHA1 | Date | |
---|---|---|---|
|
fe96bf4108 | ||
|
deee3ee410 | ||
|
60a0efc69c | ||
|
4b0b9799a9 | ||
|
97ea64164b | ||
|
edb947df4f | ||
|
7e1074b140 | ||
|
29172fab9e | ||
|
0488ade1dc | ||
|
6dbffd1fee | ||
|
59530966f9 | ||
|
b8823457c1 | ||
|
6a59e83bbb | ||
|
346a9e0f97 | ||
|
2f1390e9f9 | ||
|
47a86d920f | ||
|
7b8610f4ea | ||
|
53ede795a2 | ||
|
2f38a00534 | ||
|
0fd5e86677 | ||
|
8da7a86b96 | ||
|
97931a718f | ||
|
466e8de62c | ||
|
d920064779 | ||
|
000e8fd83d | ||
|
54b37f6bc4 | ||
|
92608073ef | ||
|
d361d4ba6e | ||
|
149a3721ff | ||
|
12f8b11452 | ||
|
0aa8e0f477 |
@ -44,6 +44,18 @@
|
||||
"title": "Dead to Rights",
|
||||
"E23D98B2CE185C3993A40F2495D37E41B971BF91": "Fix audio issues"
|
||||
},
|
||||
"GEDE01": {
|
||||
"title": "Eternal Darkness",
|
||||
"21068C3CE905FB0CFFAA7408A93154AF8A5295A2": "Fix startup hang"
|
||||
},
|
||||
"GEDJ01": {
|
||||
"title": "Eternal Darkness",
|
||||
"7061F3CF11BF64D3BA7F32CCF2BAC42FF3614AB6": "Fix startup hang"
|
||||
},
|
||||
"GEDP01": {
|
||||
"title": "Eternal Darkness",
|
||||
"6F1B00517CBA30BEB738EAA90E71221378CD570D": "Fix startup hang"
|
||||
},
|
||||
"GEME7F": {
|
||||
"title": "Egg Mania: Eggstreme Madness",
|
||||
"CB04E00918C9C0F161715D21D046ED6620F7ADEF": "Force Progressive Scan"
|
||||
@ -236,6 +248,14 @@
|
||||
"title": "Ten Pin Alley 2",
|
||||
"793642AC6862C2F3412035A9E3D7172CC4A1D5C7": "Fix crash on main menu"
|
||||
},
|
||||
"RMHE08": {
|
||||
"title": "Monster Hunter Tri",
|
||||
"CCF233DA57B3E75221870DE502955114B0D4E7FA": "Bloom OFF"
|
||||
},
|
||||
"RMHJ08": {
|
||||
"title": "Monster Hunter Tri",
|
||||
"29D3625B7ED577587E56AA07CB0EB8C47C97E823": "Bloom OFF"
|
||||
},
|
||||
"RMHP08": {
|
||||
"title": "Monster Hunter Tri",
|
||||
"1720C1173D4698167080DBFC4232F21757C4DA08": "Bloom OFF"
|
||||
|
@ -6,3 +6,6 @@ $Fix startup hang
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$Fix startup hang
|
||||
|
||||
[Patches_RetroAchievements_Verified]
|
||||
$Fix startup hang
|
||||
|
@ -6,3 +6,6 @@ $Fix startup hang
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$Fix startup hang
|
||||
|
||||
[Patches_RetroAchievements_Verified]
|
||||
$Fix startup hang
|
||||
|
@ -6,3 +6,6 @@ $Fix startup hang
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$Fix startup hang
|
||||
|
||||
[Patches_RetroAchievements_Verified]
|
||||
$Fix startup hang
|
||||
|
@ -8,3 +8,6 @@ $Bloom OFF
|
||||
|
||||
[ActionReplay]
|
||||
# Add action replay cheats here.
|
||||
|
||||
[Patches_RetroAchievements_Verified]
|
||||
$Bloom OFF
|
||||
|
@ -12,3 +12,6 @@ SafeTextureCacheColorSamples = 0
|
||||
|
||||
[ActionReplay]
|
||||
# Add action replay cheats here.
|
||||
|
||||
[Patches_RetroAchievements_Verified]
|
||||
$Bloom OFF
|
||||
|
@ -11,3 +11,6 @@ $Bloom OFF
|
||||
|
||||
[ActionReplay]
|
||||
# Add action replay cheats here.
|
||||
|
||||
[Patches_RetroAchievements_Verified]
|
||||
$Bloom OFF
|
||||
|
@ -1,22 +0,0 @@
|
||||
{
|
||||
"name": "SDL2",
|
||||
"buildsystem": "autotools",
|
||||
"config-opts": ["--disable-static"],
|
||||
"sources": [
|
||||
{
|
||||
"type": "dir",
|
||||
"path": "../../Externals/SDL/SDL"
|
||||
}
|
||||
],
|
||||
"cleanup": [ "/bin/sdl2-config",
|
||||
"/include",
|
||||
"/lib/libSDL2.la",
|
||||
"/lib/libSDL2main.a",
|
||||
"/lib/libSDL2main.la",
|
||||
"/lib/libSDL2_test.a",
|
||||
"/lib/libSDL2_test.la",
|
||||
"/lib/cmake",
|
||||
"/share/aclocal",
|
||||
"/lib/pkgconfig"]
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
app-id: org.DolphinEmu.dolphin-emu
|
||||
runtime: org.kde.Platform
|
||||
runtime-version: '6.7'
|
||||
runtime-version: '6.8'
|
||||
sdk: org.kde.Sdk
|
||||
command: dolphin-emu-wrapper
|
||||
rename-desktop-file: dolphin-emu.desktop
|
||||
@ -47,9 +47,6 @@ modules:
|
||||
url: https://github.com/Unrud/xdg-screensaver-shim/archive/0.0.2.tar.gz
|
||||
sha256: 0ed2a69fe6ee6cbffd2fe16f85116db737f17fb1e79bfb812d893cf15c728399
|
||||
|
||||
# build the vendored SDL2 from Externals until the runtime gets 2.30.6
|
||||
- SDL2/SDL2.json
|
||||
|
||||
- name: dolphin-emu
|
||||
buildsystem: cmake-ninja
|
||||
config-opts:
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -302,7 +302,7 @@ public final class NativeLibrary
|
||||
|
||||
public static native int DefaultCPUCore();
|
||||
|
||||
public static native String GetDefaultGraphicsBackendName();
|
||||
public static native String GetDefaultGraphicsBackendConfigName();
|
||||
|
||||
public static native int GetMaxLogLevel();
|
||||
|
||||
|
@ -45,7 +45,7 @@ enum class StringSetting(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"GFXBackend",
|
||||
NativeLibrary.GetDefaultGraphicsBackendName()
|
||||
NativeLibrary.GetDefaultGraphicsBackendConfigName()
|
||||
),
|
||||
MAIN_DUMP_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "DumpPath", ""),
|
||||
MAIN_LOAD_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "LoadPath", ""),
|
||||
|
@ -408,9 +408,10 @@ JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_DefaultCPUCo
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_NativeLibrary_GetDefaultGraphicsBackendName(JNIEnv* env, jclass)
|
||||
Java_org_dolphinemu_dolphinemu_NativeLibrary_GetDefaultGraphicsBackendConfigName(JNIEnv* env,
|
||||
jclass)
|
||||
{
|
||||
return ToJString(env, VideoBackendBase::GetDefaultBackendName());
|
||||
return ToJString(env, VideoBackendBase::GetDefaultBackendConfigName());
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetMaxLogLevel(JNIEnv*, jclass)
|
||||
|
@ -70,8 +70,8 @@ public:
|
||||
static constexpr std::string_view BLUE = "#0B71C1";
|
||||
static constexpr std::string_view APPROVED_LIST_FILENAME = "ApprovedInis.json";
|
||||
static const inline Common::SHA1::Digest APPROVED_LIST_HASH = {
|
||||
0x50, 0x2F, 0x58, 0x02, 0x94, 0x60, 0x1B, 0x9F, 0x92, 0xC7,
|
||||
0x04, 0x17, 0x50, 0x2E, 0xF3, 0x09, 0x8C, 0x8C, 0xD6, 0xC0};
|
||||
0xCC, 0xB4, 0x05, 0x2D, 0x2B, 0xEE, 0xF4, 0x06, 0x4A, 0xC9,
|
||||
0x57, 0x5D, 0xA9, 0xE9, 0xDE, 0xB7, 0x98, 0xF8, 0x1A, 0x6D};
|
||||
|
||||
struct LeaderboardEntry
|
||||
{
|
||||
|
@ -212,7 +212,7 @@ const Info<bool> MAIN_RAM_OVERRIDE_ENABLE{{System::Main, "Core", "RAMOverrideEna
|
||||
const Info<u32> MAIN_MEM1_SIZE{{System::Main, "Core", "MEM1Size"}, Memory::MEM1_SIZE_RETAIL};
|
||||
const Info<u32> MAIN_MEM2_SIZE{{System::Main, "Core", "MEM2Size"}, Memory::MEM2_SIZE_RETAIL};
|
||||
const Info<std::string> MAIN_GFX_BACKEND{{System::Main, "Core", "GFXBackend"},
|
||||
VideoBackendBase::GetDefaultBackendName()};
|
||||
VideoBackendBase::GetDefaultBackendConfigName()};
|
||||
const Info<HSP::HSPDeviceType> MAIN_HSP_DEVICE{{System::Main, "Core", "HSPDevice"},
|
||||
HSP::HSPDeviceType::None};
|
||||
const Info<u32> MAIN_ARAM_EXPANSION_SIZE{{System::Main, "Core", "ARAMExpansionSize"}, 0x400000};
|
||||
|
@ -6,19 +6,14 @@
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
|
||||
#include "Common/Config/Config.h"
|
||||
#include "Core/Config/AchievementSettings.h"
|
||||
#include "Core/Config/GraphicsSettings.h"
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/Config/UISettings.h"
|
||||
#include "Core/Config/WiimoteSettings.h"
|
||||
|
||||
namespace ConfigLoaders
|
||||
{
|
||||
bool IsSettingSaveable(const Config::Location& config_location)
|
||||
{
|
||||
static constexpr std::array<Config::System, 3> systems_not_saveable = {
|
||||
Config::System::GCPad, Config::System::WiiPad, Config::System::GCKeyboard};
|
||||
static constexpr std::array systems_not_saveable = {Config::System::GCPad, Config::System::WiiPad,
|
||||
Config::System::GCKeyboard};
|
||||
|
||||
if (std::find(begin(systems_not_saveable), end(systems_not_saveable), config_location.system) ==
|
||||
end(systems_not_saveable))
|
||||
|
@ -418,7 +418,7 @@ void AXWiiUCode::WritePB(Memory::MemoryManager& memory, u32 addr, const AXPBWii&
|
||||
case 0xadbc06bd:
|
||||
memory.CopyToEmuSwapped<u16>(addr, (const u16*)src, updates_begin);
|
||||
memory.CopyToEmuSwapped<u16>(addr + updates_begin, (const u16*)(src + updates_end),
|
||||
sizeof(PBUpdatesWii));
|
||||
gap_begin - updates_end);
|
||||
memory.CopyToEmuSwapped<u16>(addr + gap_begin, (const u16*)(src + gap_end),
|
||||
sizeof(pb) - gap_end);
|
||||
break;
|
||||
|
@ -834,7 +834,7 @@ BbaTcpSocket::ConnectingState BbaTcpSocket::Connected(StackRef* ref)
|
||||
fd_set read_fds;
|
||||
fd_set write_fds;
|
||||
fd_set except_fds;
|
||||
struct timeval t = {0, 0};
|
||||
timeval t = {0, 0};
|
||||
FD_ZERO(&read_fds);
|
||||
FD_ZERO(&write_fds);
|
||||
FD_ZERO(&except_fds);
|
||||
@ -965,7 +965,7 @@ sf::Socket::Status BbaUdpSocket::Bind(u16 port, u32 net_ip)
|
||||
|
||||
// Subscribe to the SSDP multicast group
|
||||
// NB: Other groups aren't supported because of HLE
|
||||
struct ip_mreq mreq;
|
||||
ip_mreq mreq;
|
||||
mreq.imr_multiaddr.s_addr = std::bit_cast<u32>(Common::IP_ADDR_SSDP);
|
||||
mreq.imr_interface.s_addr = net_ip;
|
||||
if (setsockopt(getHandle(), IPPROTO_IP, IP_ADD_MEMBERSHIP, reinterpret_cast<const char*>(&mreq),
|
||||
|
@ -8,21 +8,12 @@
|
||||
#include "AudioCommon/AudioCommon.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/MathUtil.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/HW/WiimoteEmu/WiimoteEmu.h"
|
||||
#include "Core/System.h"
|
||||
#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h"
|
||||
#include "InputCommon/ControllerEmu/Setting/NumericSetting.h"
|
||||
|
||||
//#define WIIMOTE_SPEAKER_DUMP
|
||||
#ifdef WIIMOTE_SPEAKER_DUMP
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include "AudioCommon/WaveFile.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#endif
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
// Yamaha ADPCM decoder code based on The ffmpeg Project (Copyright (s) 2001-2003)
|
||||
@ -60,17 +51,6 @@ static s16 adpcm_yamaha_expand_nibble(ADPCMState& s, u8 nibble)
|
||||
return s.predictor;
|
||||
}
|
||||
|
||||
#ifdef WIIMOTE_SPEAKER_DUMP
|
||||
std::ofstream ofile;
|
||||
WaveFileWriter wav;
|
||||
|
||||
void stopdamnwav()
|
||||
{
|
||||
wav.Stop();
|
||||
ofile.close();
|
||||
}
|
||||
#endif
|
||||
|
||||
void SpeakerLogic::SpeakerData(const u8* data, int length, float speaker_pan)
|
||||
{
|
||||
// TODO: should we still process samples for the decoder state?
|
||||
@ -151,28 +131,6 @@ void SpeakerLogic::SpeakerData(const u8* data, int length, float speaker_pan)
|
||||
const unsigned int sample_rate = sample_rate_dividend / reg_data.sample_rate;
|
||||
sound_stream->GetMixer()->PushWiimoteSpeakerSamples(
|
||||
samples.get(), sample_length, Mixer::FIXED_SAMPLE_RATE_DIVIDEND / (sample_rate * 2));
|
||||
|
||||
#ifdef WIIMOTE_SPEAKER_DUMP
|
||||
static int num = 0;
|
||||
|
||||
if (num == 0)
|
||||
{
|
||||
File::Delete("rmtdump.wav");
|
||||
File::Delete("rmtdump.bin");
|
||||
atexit(stopdamnwav);
|
||||
File::OpenFStream(ofile, "rmtdump.bin", ofile.binary | ofile.out);
|
||||
wav.Start("rmtdump.wav", 6000);
|
||||
}
|
||||
wav.AddMonoSamples(samples.get(), length * 2);
|
||||
if (ofile.good())
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
ofile << data[i];
|
||||
}
|
||||
}
|
||||
num++;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SpeakerLogic::Reset()
|
||||
|
@ -197,8 +197,8 @@ void init_lib()
|
||||
|
||||
namespace WiimoteReal
|
||||
{
|
||||
int IOWrite(HANDLE& dev_handle, OVERLAPPED& hid_overlap_write, enum WinWriteMethod& stack,
|
||||
const u8* buf, size_t len, DWORD* written);
|
||||
int IOWrite(HANDLE& dev_handle, OVERLAPPED& hid_overlap_write, WinWriteMethod& stack, const u8* buf,
|
||||
size_t len, DWORD* written);
|
||||
int IORead(HANDLE& dev_handle, OVERLAPPED& hid_overlap_read, u8* buf, int index);
|
||||
|
||||
template <typename T>
|
||||
|
@ -798,7 +798,7 @@ IPCReply NetIPTopDevice::HandleInetAToNRequest(const IOCtlRequest& request)
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
const std::string hostname = memory.GetString(request.buffer_in);
|
||||
struct hostent* remoteHost = gethostbyname(hostname.c_str());
|
||||
hostent* remoteHost = gethostbyname(hostname.c_str());
|
||||
|
||||
if (remoteHost == nullptr || remoteHost->h_addr_list == nullptr ||
|
||||
remoteHost->h_addr_list[0] == nullptr)
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
static DRESULT read_vff_header(IOS::HLE::FS::FileHandle* vff, FATFS* fs)
|
||||
{
|
||||
struct IOS::HLE::NWC24::VFFHeader header;
|
||||
IOS::HLE::NWC24::VFFHeader header;
|
||||
if (!vff->Read(&header, 1))
|
||||
{
|
||||
ERROR_LOG_FMT(IOS_WC24, "Failed to read VFF header.");
|
||||
|
@ -770,7 +770,7 @@ WiiSocket::ConnectingState WiiSocket::GetConnectingState() const
|
||||
fd_set read_fds;
|
||||
fd_set write_fds;
|
||||
fd_set except_fds;
|
||||
struct timeval t = {0, 0};
|
||||
timeval t = {0, 0};
|
||||
FD_ZERO(&read_fds);
|
||||
FD_ZERO(&write_fds);
|
||||
FD_ZERO(&except_fds);
|
||||
@ -998,7 +998,7 @@ void WiiSockMan::Update()
|
||||
{
|
||||
s32 nfds = 0;
|
||||
fd_set read_fds, write_fds, except_fds;
|
||||
struct timeval t = {0, 0};
|
||||
timeval t = {0, 0};
|
||||
FD_ZERO(&read_fds);
|
||||
FD_ZERO(&write_fds);
|
||||
FD_ZERO(&except_fds);
|
||||
|
@ -2505,7 +2505,7 @@ struct hci_filter
|
||||
uint32_t mask[8]; /* 256 bits */
|
||||
};
|
||||
|
||||
static __inline void hci_filter_set(uint8_t bit, struct hci_filter* filter)
|
||||
static __inline void hci_filter_set(uint8_t bit, hci_filter* filter)
|
||||
{
|
||||
uint8_t off = bit - 1;
|
||||
|
||||
@ -2513,7 +2513,7 @@ static __inline void hci_filter_set(uint8_t bit, struct hci_filter* filter)
|
||||
filter->mask[off] |= (1 << ((bit - 1) & 0x1f));
|
||||
}
|
||||
|
||||
static __inline void hci_filter_clr(uint8_t bit, struct hci_filter* filter)
|
||||
static __inline void hci_filter_clr(uint8_t bit, hci_filter* filter)
|
||||
{
|
||||
uint8_t off = bit - 1;
|
||||
|
||||
@ -2581,7 +2581,7 @@ struct btreq
|
||||
uint16_t btri_link_policy; /* Link Policy */
|
||||
uint16_t btri_packet_type; /* Packet Type */
|
||||
} btri;
|
||||
struct bt_stats btrs; /* unit stats */
|
||||
bt_stats btrs; /* unit stats */
|
||||
} btru;
|
||||
};
|
||||
|
||||
|
@ -96,10 +96,11 @@ std::optional<IPCReply> USB_HIDv4::GetDeviceChange(const IOCtlRequest& request)
|
||||
m_devicechange_hook_request = std::make_unique<IOCtlRequest>(GetSystem(), request.address);
|
||||
// If there are pending changes, the reply is sent immediately (instead of on device
|
||||
// insertion/removal).
|
||||
if (m_has_pending_changes)
|
||||
if (m_has_pending_changes || m_is_shut_down)
|
||||
{
|
||||
TriggerDeviceChangeReply();
|
||||
m_has_pending_changes = false;
|
||||
m_is_shut_down = false;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
@ -114,6 +115,7 @@ IPCReply USB_HIDv4::Shutdown(const IOCtlRequest& request)
|
||||
memory.Write_U32(0xffffffff, m_devicechange_hook_request->buffer_out);
|
||||
GetEmulationKernel().EnqueueIPCReply(*m_devicechange_hook_request, -1);
|
||||
m_devicechange_hook_request.reset();
|
||||
m_is_shut_down = true;
|
||||
}
|
||||
return IPCReply(IPC_SUCCESS);
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ private:
|
||||
static constexpr u8 HID_CLASS = 0x03;
|
||||
|
||||
bool m_has_pending_changes = true;
|
||||
bool m_is_shut_down = false;
|
||||
std::mutex m_devicechange_hook_address_mutex;
|
||||
std::unique_ptr<IOCtlRequest> m_devicechange_hook_request;
|
||||
|
||||
|
@ -258,7 +258,7 @@ static void ReadCommand()
|
||||
|
||||
static bool IsDataAvailable()
|
||||
{
|
||||
struct timeval t;
|
||||
timeval t;
|
||||
fd_set _fds, *fds = &_fds;
|
||||
|
||||
FD_ZERO(fds);
|
||||
|
@ -318,6 +318,8 @@ add_executable(dolphin-emu
|
||||
QtUtils/ParallelProgressDialog.h
|
||||
QtUtils/PartiallyClosableTabWidget.cpp
|
||||
QtUtils/PartiallyClosableTabWidget.h
|
||||
QtUtils/QtUtils.cpp
|
||||
QtUtils/QtUtils.h
|
||||
QtUtils/SetWindowDecorations.cpp
|
||||
QtUtils/SetWindowDecorations.h
|
||||
QtUtils/SignalBlocking.h
|
||||
|
@ -239,7 +239,7 @@ void GeneralWidget::AddDescriptions()
|
||||
"recommended. Different games and different GPUs will behave differently on each "
|
||||
"backend, so for the best emulation experience it is recommended to try each and "
|
||||
"select the backend that is least problematic.<br><br><dolphin_emphasis>If unsure, "
|
||||
"select OpenGL.</dolphin_emphasis>");
|
||||
"select %1.</dolphin_emphasis>");
|
||||
static const char TR_FULLSCREEN_DESCRIPTION[] =
|
||||
QT_TR_NOOP("Uses the entire screen for rendering.<br><br>If disabled, a "
|
||||
"render window will be created instead.<br><br><dolphin_emphasis>If "
|
||||
@ -311,7 +311,9 @@ void GeneralWidget::AddDescriptions()
|
||||
"unsure, leave this unchecked.</dolphin_emphasis>");
|
||||
|
||||
m_backend_combo->SetTitle(tr("Backend"));
|
||||
m_backend_combo->SetDescription(tr(TR_BACKEND_DESCRIPTION));
|
||||
m_backend_combo->SetDescription(
|
||||
tr(TR_BACKEND_DESCRIPTION)
|
||||
.arg(QString::fromStdString(VideoBackendBase::GetDefaultBackendDisplayName())));
|
||||
|
||||
m_adapter_combo->SetTitle(tr("Adapter"));
|
||||
|
||||
|
@ -197,6 +197,7 @@
|
||||
<ClCompile Include="QtUtils\ModalMessageBox.cpp" />
|
||||
<ClCompile Include="QtUtils\NonDefaultQPushButton.cpp" />
|
||||
<ClCompile Include="QtUtils\PartiallyClosableTabWidget.cpp" />
|
||||
<ClCompile Include="QtUtils\QtUtils.cpp" />
|
||||
<ClCompile Include="QtUtils\SetWindowDecorations.cpp" />
|
||||
<ClCompile Include="QtUtils\UTF8CodePointCountValidator.cpp" />
|
||||
<ClCompile Include="QtUtils\WindowActivationEventFilter.cpp" />
|
||||
@ -404,6 +405,7 @@
|
||||
<ClInclude Include="QtUtils\FromStdString.h" />
|
||||
<QtMoc Include="QtUtils\ParallelProgressDialog.h" />
|
||||
<QtMoc Include="QtUtils\PartiallyClosableTabWidget.h" />
|
||||
<ClInclude Include="QtUtils\QtUtils.h" />
|
||||
<ClInclude Include="QtUtils\SetWindowDecorations.h" />
|
||||
<QtMoc Include="QtUtils\UTF8CodePointCountValidator.h" />
|
||||
<QtMoc Include="QtUtils\WindowActivationEventFilter.h" />
|
||||
|
@ -249,7 +249,8 @@ int main(int argc, char* argv[])
|
||||
Settings::Instance().InitDefaultPalette();
|
||||
Settings::Instance().ApplyStyle();
|
||||
|
||||
MainWindow win{std::move(boot), static_cast<const char*>(options.get("movie"))};
|
||||
MainWindow win{Core::System::GetInstance(), std::move(boot),
|
||||
static_cast<const char*>(options.get("movie"))};
|
||||
|
||||
#if defined(USE_ANALYTICS) && USE_ANALYTICS
|
||||
if (!Config::Get(Config::MAIN_ANALYTICS_PERMISSION_ASKED))
|
||||
|
@ -217,9 +217,9 @@ static std::vector<std::string> StringListToStdVector(QStringList list)
|
||||
return result;
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(std::unique_ptr<BootParameters> boot_parameters,
|
||||
MainWindow::MainWindow(Core::System& system, std::unique_ptr<BootParameters> boot_parameters,
|
||||
const std::string& movie_path)
|
||||
: QMainWindow(nullptr)
|
||||
: QMainWindow(nullptr), m_system(system)
|
||||
{
|
||||
setWindowTitle(QString::fromStdString(Common::GetScmRevStr()));
|
||||
setWindowIcon(Resources::GetAppIcon());
|
||||
@ -292,7 +292,7 @@ MainWindow::MainWindow(std::unique_ptr<BootParameters> boot_parameters,
|
||||
if (!movie_path.empty())
|
||||
{
|
||||
std::optional<std::string> savestate_path;
|
||||
if (Core::System::GetInstance().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),
|
||||
DeleteSavestateAfterBoot::No);
|
||||
@ -465,17 +465,17 @@ void MainWindow::CreateComponents()
|
||||
m_wii_tas_input_windows[i] = new WiiTASInputWindow(nullptr, i);
|
||||
}
|
||||
|
||||
m_jit_widget = new JITWidget(Core::System::GetInstance(), this);
|
||||
m_jit_widget = new JITWidget(m_system, this);
|
||||
m_log_widget = new LogWidget(this);
|
||||
m_log_config_widget = new LogConfigWidget(this);
|
||||
m_memory_widget = new MemoryWidget(Core::System::GetInstance(), this);
|
||||
m_memory_widget = new MemoryWidget(m_system, this);
|
||||
m_network_widget = new NetworkWidget(this);
|
||||
m_register_widget = new RegisterWidget(this);
|
||||
m_thread_widget = new ThreadWidget(this);
|
||||
m_watch_widget = new WatchWidget(this);
|
||||
m_breakpoint_widget = new BreakpointWidget(this);
|
||||
m_code_widget = new CodeWidget(this);
|
||||
m_cheats_manager = new CheatsManager(Core::System::GetInstance(), this);
|
||||
m_cheats_manager = new CheatsManager(m_system, this);
|
||||
m_assembler_widget = new AssemblerWidget(this);
|
||||
|
||||
const auto request_watch = [this](QString name, u32 addr) {
|
||||
@ -512,7 +512,7 @@ void MainWindow::CreateComponents()
|
||||
connect(m_memory_widget, &MemoryWidget::RequestWatch, request_watch);
|
||||
|
||||
connect(m_breakpoint_widget, &BreakpointWidget::ShowCode, [this](u32 address) {
|
||||
if (Core::GetState(Core::System::GetInstance()) == Core::State::Paused)
|
||||
if (Core::GetState(m_system) == Core::State::Paused)
|
||||
m_code_widget->SetAddress(address, CodeViewWidget::SetAddressUpdate::WithDetailedUpdate);
|
||||
});
|
||||
connect(m_breakpoint_widget, &BreakpointWidget::ShowMemory, m_memory_widget,
|
||||
@ -653,7 +653,7 @@ void MainWindow::ConnectHotkeys()
|
||||
connect(m_hotkey_scheduler, &HotkeyScheduler::ConnectWiiRemote, this,
|
||||
&MainWindow::OnConnectWiiRemote);
|
||||
connect(m_hotkey_scheduler, &HotkeyScheduler::ToggleReadOnlyMode, [this] {
|
||||
auto& movie = Core::System::GetInstance().GetMovie();
|
||||
auto& movie = m_system.GetMovie();
|
||||
bool read_only = !movie.IsReadOnly();
|
||||
movie.SetReadOnly(read_only);
|
||||
emit ReadOnlyModeChanged(read_only);
|
||||
@ -808,14 +808,12 @@ void MainWindow::ChangeDisc()
|
||||
if (paths.empty())
|
||||
return;
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
system.GetDVDInterface().ChangeDisc(Core::CPUThreadGuard{system}, paths);
|
||||
m_system.GetDVDInterface().ChangeDisc(Core::CPUThreadGuard{m_system}, paths);
|
||||
}
|
||||
|
||||
void MainWindow::EjectDisc()
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
system.GetDVDInterface().EjectDisc(Core::CPUThreadGuard{system}, DVD::EjectCause::User);
|
||||
m_system.GetDVDInterface().EjectDisc(Core::CPUThreadGuard{m_system}, DVD::EjectCause::User);
|
||||
}
|
||||
|
||||
void MainWindow::OpenUserFolder()
|
||||
@ -840,9 +838,9 @@ void MainWindow::Play(const std::optional<std::string>& savestate_path)
|
||||
// Otherwise, play the default game.
|
||||
// Otherwise, play the last played game, if there is one.
|
||||
// Otherwise, prompt for a new game.
|
||||
if (Core::GetState(Core::System::GetInstance()) == Core::State::Paused)
|
||||
if (Core::GetState(m_system) == Core::State::Paused)
|
||||
{
|
||||
Core::SetState(Core::System::GetInstance(), Core::State::Running);
|
||||
Core::SetState(m_system, Core::State::Running);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -870,12 +868,12 @@ void MainWindow::Play(const std::optional<std::string>& savestate_path)
|
||||
|
||||
void MainWindow::Pause()
|
||||
{
|
||||
Core::SetState(Core::System::GetInstance(), Core::State::Paused);
|
||||
Core::SetState(m_system, Core::State::Paused);
|
||||
}
|
||||
|
||||
void MainWindow::TogglePause()
|
||||
{
|
||||
if (Core::GetState(Core::System::GetInstance()) == Core::State::Paused)
|
||||
if (Core::GetState(m_system) == Core::State::Paused)
|
||||
{
|
||||
Play();
|
||||
}
|
||||
@ -918,7 +916,7 @@ void MainWindow::OnStopComplete()
|
||||
|
||||
bool MainWindow::RequestStop()
|
||||
{
|
||||
if (Core::IsUninitialized(Core::System::GetInstance()))
|
||||
if (Core::IsUninitialized(m_system))
|
||||
{
|
||||
Core::QueueHostJob([this](Core::System&) { OnStopComplete(); }, true);
|
||||
return true;
|
||||
@ -944,13 +942,13 @@ bool MainWindow::RequestStop()
|
||||
|
||||
Common::ScopeGuard confirm_lock([this] { m_stop_confirm_showing = false; });
|
||||
|
||||
const Core::State state = Core::GetState(Core::System::GetInstance());
|
||||
const Core::State state = Core::GetState(m_system);
|
||||
|
||||
// Only pause the game, if NetPlay is not running
|
||||
bool pause = !Settings::Instance().GetNetPlayClient();
|
||||
|
||||
if (pause)
|
||||
Core::SetState(Core::System::GetInstance(), Core::State::Paused);
|
||||
Core::SetState(m_system, Core::State::Paused);
|
||||
|
||||
if (rendered_widget_was_active)
|
||||
{
|
||||
@ -980,7 +978,7 @@ bool MainWindow::RequestStop()
|
||||
m_render_widget->SetWaitingForMessageBox(false);
|
||||
|
||||
if (pause)
|
||||
Core::SetState(Core::System::GetInstance(), state);
|
||||
Core::SetState(m_system, state);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -1001,8 +999,8 @@ bool MainWindow::RequestStop()
|
||||
|
||||
// Unpause because gracefully shutting down needs the game to actually request a shutdown.
|
||||
// TODO: Do not unpause in debug mode to allow debugging until the complete shutdown.
|
||||
if (Core::GetState(Core::System::GetInstance()) == Core::State::Paused)
|
||||
Core::SetState(Core::System::GetInstance(), Core::State::Running);
|
||||
if (Core::GetState(m_system) == Core::State::Paused)
|
||||
Core::SetState(m_system, Core::State::Running);
|
||||
|
||||
// Tell NetPlay about the power event
|
||||
if (NetPlay::IsNetPlayRunning())
|
||||
@ -1021,21 +1019,20 @@ bool MainWindow::RequestStop()
|
||||
|
||||
void MainWindow::ForceStop()
|
||||
{
|
||||
Core::Stop(Core::System::GetInstance());
|
||||
Core::Stop(m_system);
|
||||
}
|
||||
|
||||
void MainWindow::Reset()
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& movie = system.GetMovie();
|
||||
auto& movie = m_system.GetMovie();
|
||||
if (movie.IsRecordingInput())
|
||||
movie.SetReset(true);
|
||||
system.GetProcessorInterface().ResetButton_Tap();
|
||||
m_system.GetProcessorInterface().ResetButton_Tap();
|
||||
}
|
||||
|
||||
void MainWindow::FrameAdvance()
|
||||
{
|
||||
Core::DoFrameStep(Core::System::GetInstance());
|
||||
Core::DoFrameStep(m_system);
|
||||
}
|
||||
|
||||
void MainWindow::FullScreen()
|
||||
@ -1126,7 +1123,7 @@ void MainWindow::StartGame(std::unique_ptr<BootParameters>&& parameters)
|
||||
}
|
||||
|
||||
// If we're running, only start a new game once we've stopped the last.
|
||||
if (!Core::IsUninitialized(Core::System::GetInstance()))
|
||||
if (!Core::IsUninitialized(m_system))
|
||||
{
|
||||
if (!RequestStop())
|
||||
return;
|
||||
@ -1140,7 +1137,7 @@ void MainWindow::StartGame(std::unique_ptr<BootParameters>&& parameters)
|
||||
ShowRenderWidget();
|
||||
|
||||
// Boot up, show an error if it fails to load the game.
|
||||
if (!BootManager::BootCore(Core::System::GetInstance(), std::move(parameters),
|
||||
if (!BootManager::BootCore(m_system, std::move(parameters),
|
||||
::GetWindowSystemInfo(m_render_widget->windowHandle())))
|
||||
{
|
||||
ModalMessageBox::critical(this, tr("Error"), tr("Failed to init core"), QMessageBox::Ok);
|
||||
@ -1379,8 +1376,7 @@ void MainWindow::ShowFIFOPlayer()
|
||||
{
|
||||
if (!m_fifo_window)
|
||||
{
|
||||
m_fifo_window = new FIFOPlayerWindow(Core::System::GetInstance().GetFifoPlayer(),
|
||||
Core::System::GetInstance().GetFifoRecorder());
|
||||
m_fifo_window = new FIFOPlayerWindow(m_system.GetFifoPlayer(), m_system.GetFifoRecorder());
|
||||
connect(m_fifo_window, &FIFOPlayerWindow::LoadFIFORequested, this,
|
||||
[this](const QString& path) { StartGame(path, ScanForSecondDisc::No); });
|
||||
}
|
||||
@ -1426,7 +1422,7 @@ void MainWindow::StateLoad()
|
||||
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());
|
||||
if (!path.isEmpty())
|
||||
State::LoadAs(Core::System::GetInstance(), path.toStdString());
|
||||
State::LoadAs(m_system, path.toStdString());
|
||||
}
|
||||
|
||||
void MainWindow::StateSave()
|
||||
@ -1438,47 +1434,47 @@ void MainWindow::StateSave()
|
||||
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());
|
||||
if (!path.isEmpty())
|
||||
State::SaveAs(Core::System::GetInstance(), path.toStdString());
|
||||
State::SaveAs(m_system, path.toStdString());
|
||||
}
|
||||
|
||||
void MainWindow::StateLoadSlot()
|
||||
{
|
||||
State::Load(Core::System::GetInstance(), m_state_slot);
|
||||
State::Load(m_system, m_state_slot);
|
||||
}
|
||||
|
||||
void MainWindow::StateSaveSlot()
|
||||
{
|
||||
State::Save(Core::System::GetInstance(), m_state_slot);
|
||||
State::Save(m_system, m_state_slot);
|
||||
}
|
||||
|
||||
void MainWindow::StateLoadSlotAt(int slot)
|
||||
{
|
||||
State::Load(Core::System::GetInstance(), slot);
|
||||
State::Load(m_system, slot);
|
||||
}
|
||||
|
||||
void MainWindow::StateLoadLastSavedAt(int slot)
|
||||
{
|
||||
State::LoadLastSaved(Core::System::GetInstance(), slot);
|
||||
State::LoadLastSaved(m_system, slot);
|
||||
}
|
||||
|
||||
void MainWindow::StateSaveSlotAt(int slot)
|
||||
{
|
||||
State::Save(Core::System::GetInstance(), slot);
|
||||
State::Save(m_system, slot);
|
||||
}
|
||||
|
||||
void MainWindow::StateLoadUndo()
|
||||
{
|
||||
State::UndoLoadState(Core::System::GetInstance());
|
||||
State::UndoLoadState(m_system);
|
||||
}
|
||||
|
||||
void MainWindow::StateSaveUndo()
|
||||
{
|
||||
State::UndoSaveState(Core::System::GetInstance());
|
||||
State::UndoSaveState(m_system);
|
||||
}
|
||||
|
||||
void MainWindow::StateSaveOldest()
|
||||
{
|
||||
State::SaveFirstSaved(Core::System::GetInstance());
|
||||
State::SaveFirstSaved(m_system);
|
||||
}
|
||||
|
||||
void MainWindow::SetStateSlot(int slot)
|
||||
@ -1550,7 +1546,7 @@ void MainWindow::NetPlayInit()
|
||||
|
||||
bool MainWindow::NetPlayJoin()
|
||||
{
|
||||
if (!Core::IsUninitialized(Core::System::GetInstance()))
|
||||
if (!Core::IsUninitialized(m_system))
|
||||
{
|
||||
ModalMessageBox::critical(nullptr, tr("Error"),
|
||||
tr("Can't start a NetPlay Session while a game is still running!"));
|
||||
@ -1617,7 +1613,7 @@ bool MainWindow::NetPlayJoin()
|
||||
|
||||
bool MainWindow::NetPlayHost(const UICommon::GameFile& game)
|
||||
{
|
||||
if (!Core::IsUninitialized(Core::System::GetInstance()))
|
||||
if (!Core::IsUninitialized(m_system))
|
||||
{
|
||||
ModalMessageBox::critical(nullptr, tr("Error"),
|
||||
tr("Can't start a NetPlay Session while a game is still running!"));
|
||||
@ -1679,7 +1675,7 @@ void MainWindow::NetPlayQuit()
|
||||
void MainWindow::UpdateScreenSaverInhibition()
|
||||
{
|
||||
const bool inhibit = Config::Get(Config::MAIN_DISABLE_SCREENSAVER) &&
|
||||
(Core::GetState(Core::System::GetInstance()) == Core::State::Running);
|
||||
(Core::GetState(m_system) == Core::State::Running);
|
||||
|
||||
if (inhibit == m_is_screensaver_inhibited)
|
||||
return;
|
||||
@ -1840,7 +1836,7 @@ void MainWindow::OnPlayRecording()
|
||||
if (dtm_file.isEmpty())
|
||||
return;
|
||||
|
||||
auto& movie = Core::System::GetInstance().GetMovie();
|
||||
auto& movie = m_system.GetMovie();
|
||||
if (!movie.IsReadOnly())
|
||||
{
|
||||
// let's make the read-only flag consistent at the start of a movie.
|
||||
@ -1859,10 +1855,9 @@ void MainWindow::OnPlayRecording()
|
||||
|
||||
void MainWindow::OnStartRecording()
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& movie = system.GetMovie();
|
||||
if (Core::GetState(system) == Core::State::Starting ||
|
||||
Core::GetState(system) == Core::State::Stopping || movie.IsRecordingInput() ||
|
||||
auto& movie = m_system.GetMovie();
|
||||
if (Core::GetState(m_system) == Core::State::Starting ||
|
||||
Core::GetState(m_system) == Core::State::Stopping || movie.IsRecordingInput() ||
|
||||
movie.IsPlayingInput())
|
||||
{
|
||||
return;
|
||||
@ -1894,14 +1889,14 @@ void MainWindow::OnStartRecording()
|
||||
{
|
||||
emit RecordingStatusChanged(true);
|
||||
|
||||
if (Core::IsUninitialized(system))
|
||||
if (Core::IsUninitialized(m_system))
|
||||
Play();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::OnStopRecording()
|
||||
{
|
||||
auto& movie = Core::System::GetInstance().GetMovie();
|
||||
auto& movie = m_system.GetMovie();
|
||||
if (movie.IsRecordingInput())
|
||||
OnExportRecording();
|
||||
if (movie.IsMovieActive())
|
||||
@ -1911,13 +1906,12 @@ void MainWindow::OnStopRecording()
|
||||
|
||||
void MainWindow::OnExportRecording()
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
const Core::CPUThreadGuard guard(system);
|
||||
const Core::CPUThreadGuard guard(m_system);
|
||||
|
||||
QString dtm_file = DolphinFileDialog::getSaveFileName(
|
||||
this, tr("Save Recording File As"), QString(), tr("Dolphin TAS Movies (*.dtm)"));
|
||||
if (!dtm_file.isEmpty())
|
||||
system.GetMovie().SaveRecording(dtm_file.toStdString());
|
||||
m_system.GetMovie().SaveRecording(dtm_file.toStdString());
|
||||
}
|
||||
|
||||
void MainWindow::OnActivateChat()
|
||||
@ -1955,11 +1949,10 @@ void MainWindow::ShowTASInput()
|
||||
}
|
||||
}
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
for (int i = 0; i < num_wii_controllers; i++)
|
||||
{
|
||||
if (Config::Get(Config::GetInfoForWiimoteSource(i)) == WiimoteSource::Emulated &&
|
||||
(!Core::IsRunning(system) || system.IsWii()))
|
||||
(!Core::IsRunning(m_system) || m_system.IsWii()))
|
||||
{
|
||||
SetQWidgetWindowDecorations(m_wii_tas_input_windows[i]);
|
||||
m_wii_tas_input_windows[i]->show();
|
||||
@ -1971,7 +1964,7 @@ void MainWindow::ShowTASInput()
|
||||
|
||||
void MainWindow::OnConnectWiiRemote(int id)
|
||||
{
|
||||
const Core::CPUThreadGuard guard(Core::System::GetInstance());
|
||||
const Core::CPUThreadGuard guard(m_system);
|
||||
if (const auto bt = WiiUtils::GetBluetoothEmuDevice())
|
||||
{
|
||||
const auto wm = bt->AccessWiimoteByIndex(id);
|
||||
|
@ -54,6 +54,11 @@ class WatchWidget;
|
||||
class WiiTASInputWindow;
|
||||
struct WindowSystemInfo;
|
||||
|
||||
namespace Core
|
||||
{
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
enum class Region;
|
||||
@ -74,7 +79,7 @@ class MainWindow final : public QMainWindow
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(std::unique_ptr<BootParameters> boot_parameters,
|
||||
explicit MainWindow(Core::System& system, std::unique_ptr<BootParameters> boot_parameters,
|
||||
const std::string& movie_path);
|
||||
~MainWindow();
|
||||
|
||||
@ -213,6 +218,8 @@ private:
|
||||
void dropEvent(QDropEvent* event) override;
|
||||
QSize sizeHint() const override;
|
||||
|
||||
Core::System& m_system;
|
||||
|
||||
#ifdef HAVE_XRANDR
|
||||
std::unique_ptr<X11Utils::XRRConfiguration> m_xrr_config;
|
||||
#endif
|
||||
|
22
Source/Core/DolphinQt/QtUtils/QtUtils.cpp
Normal file
22
Source/Core/DolphinQt/QtUtils/QtUtils.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2024 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "DolphinQt/QtUtils/QtUtils.h"
|
||||
|
||||
#include <QDateTimeEdit>
|
||||
|
||||
namespace QtUtils
|
||||
{
|
||||
|
||||
void ShowFourDigitYear(QDateTimeEdit* widget)
|
||||
{
|
||||
if (!widget->displayFormat().contains(QStringLiteral("yyyy")))
|
||||
{
|
||||
// Always show the full year, no matter what the locale specifies. Otherwise, two-digit years
|
||||
// will always be interpreted as in the 21st century.
|
||||
widget->setDisplayFormat(
|
||||
widget->displayFormat().replace(QStringLiteral("yy"), QStringLiteral("yyyy")));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace QtUtils
|
13
Source/Core/DolphinQt/QtUtils/QtUtils.h
Normal file
13
Source/Core/DolphinQt/QtUtils/QtUtils.h
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2024 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
class QDateTimeEdit;
|
||||
|
||||
namespace QtUtils
|
||||
{
|
||||
|
||||
void ShowFourDigitYear(QDateTimeEdit* widget);
|
||||
|
||||
}
|
@ -24,6 +24,7 @@
|
||||
#include "Core/System.h"
|
||||
|
||||
#include "DolphinQt/Config/ConfigControls/ConfigBool.h"
|
||||
#include "DolphinQt/QtUtils/QtUtils.h"
|
||||
#include "DolphinQt/QtUtils/SignalBlocking.h"
|
||||
#include "DolphinQt/Settings.h"
|
||||
|
||||
@ -168,13 +169,7 @@ void AdvancedPane::CreateLayout()
|
||||
m_custom_rtc_datetime->setDisplayFormat(m_custom_rtc_datetime->displayFormat().replace(
|
||||
QStringLiteral("mm"), QStringLiteral("mm:ss")));
|
||||
|
||||
if (!m_custom_rtc_datetime->displayFormat().contains(QStringLiteral("yyyy")))
|
||||
{
|
||||
// Always show the full year, no matter what the locale specifies. Otherwise, two-digit years
|
||||
// will always be interpreted as in the 21st century.
|
||||
m_custom_rtc_datetime->setDisplayFormat(m_custom_rtc_datetime->displayFormat().replace(
|
||||
QStringLiteral("yy"), QStringLiteral("yyyy")));
|
||||
}
|
||||
QtUtils::ShowFourDigitYear(m_custom_rtc_datetime);
|
||||
m_custom_rtc_datetime->setDateTimeRange(QDateTime({2000, 1, 1}, {0, 0, 0}, Qt::UTC),
|
||||
QDateTime({2099, 12, 31}, {23, 59, 59}, Qt::UTC));
|
||||
m_custom_rtc_datetime->setTimeSpec(Qt::UTC);
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "Core/IOS/USB/Emulated/Skylanders/Skylander.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
#include "DolphinQt/QtUtils/QtUtils.h"
|
||||
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
|
||||
|
||||
SkylanderModifyDialog::SkylanderModifyDialog(QWidget* parent, u8 slot)
|
||||
@ -168,8 +169,9 @@ void SkylanderModifyDialog::PopulateSkylanderOptions(QVBoxLayout* layout)
|
||||
edit_nick->setValidator(
|
||||
new QRegularExpressionValidator(QRegularExpression(QStringLiteral("^\\p{L}{0,15}$")), this));
|
||||
edit_playtime->setValidator(new QIntValidator(0, INT_MAX, this));
|
||||
edit_last_reset->setDisplayFormat(QStringLiteral("dd/MM/yyyy hh:mm"));
|
||||
edit_last_placed->setDisplayFormat(QStringLiteral("dd/MM/yyyy hh:mm"));
|
||||
|
||||
QtUtils::ShowFourDigitYear(edit_last_reset);
|
||||
QtUtils::ShowFourDigitYear(edit_last_placed);
|
||||
|
||||
edit_toy_code->setToolTip(tr("The toy code for this figure. Only available for real figures."));
|
||||
edit_money->setToolTip(tr("The amount of money this Skylander has. Between 0 and 65000"));
|
||||
|
@ -693,7 +693,7 @@ private:
|
||||
negative = new AndroidAxis(source, axis, true);
|
||||
|
||||
if (positive && negative)
|
||||
AddAnalogInputs(positive, negative);
|
||||
AddFullAnalogSurfaceInputs(positive, negative);
|
||||
else if (positive || negative)
|
||||
AddInput(positive ? positive : negative);
|
||||
}
|
||||
|
@ -130,38 +130,50 @@ bool Device::Control::IsHidden() const
|
||||
return false;
|
||||
}
|
||||
|
||||
ControlState Device::FullAnalogSurface::GetState() const
|
||||
class FullAnalogSurface final : public Device::Input
|
||||
{
|
||||
return (1 + std::max(0.0, m_high.GetState()) - std::max(0.0, m_low.GetState())) / 2;
|
||||
}
|
||||
public:
|
||||
FullAnalogSurface(Input* low, Input* high) : m_low(*low), m_high(*high) {}
|
||||
|
||||
std::string Device::FullAnalogSurface::GetName() const
|
||||
ControlState GetState() const override
|
||||
{
|
||||
return (1 + std::max(0.0, m_high.GetState()) - std::max(0.0, m_low.GetState())) / 2;
|
||||
}
|
||||
|
||||
std::string GetName() const override
|
||||
{
|
||||
// E.g. "Full Axis X+"
|
||||
return "Full " + m_high.GetName();
|
||||
}
|
||||
|
||||
bool IsDetectable() const override { return m_low.IsDetectable() && m_high.IsDetectable(); }
|
||||
|
||||
bool IsHidden() const override { return m_low.IsHidden() && m_high.IsHidden(); }
|
||||
|
||||
bool IsMatchingName(std::string_view name) const override
|
||||
{
|
||||
if (Control::IsMatchingName(name))
|
||||
return true;
|
||||
|
||||
// Old naming scheme was "Axis X-+" which is too visually similar to "Axis X+".
|
||||
// This has caused countless problems for users with mysterious misconfigurations.
|
||||
// We match this old name to support old configurations.
|
||||
const auto old_name = m_low.GetName() + *m_high.GetName().rbegin();
|
||||
|
||||
return old_name == name;
|
||||
}
|
||||
|
||||
private:
|
||||
Input& m_low;
|
||||
Input& m_high;
|
||||
};
|
||||
|
||||
void Device::AddFullAnalogSurfaceInputs(Input* low, Input* high)
|
||||
{
|
||||
// E.g. "Full Axis X+"
|
||||
return "Full " + m_high.GetName();
|
||||
}
|
||||
|
||||
bool Device::FullAnalogSurface::IsDetectable() const
|
||||
{
|
||||
return m_low.IsDetectable() && m_high.IsDetectable();
|
||||
}
|
||||
|
||||
bool Device::FullAnalogSurface::IsHidden() const
|
||||
{
|
||||
return m_low.IsHidden() && m_high.IsHidden();
|
||||
}
|
||||
|
||||
bool Device::FullAnalogSurface::IsMatchingName(std::string_view name) const
|
||||
{
|
||||
if (Control::IsMatchingName(name))
|
||||
return true;
|
||||
|
||||
// Old naming scheme was "Axis X-+" which is too visually similar to "Axis X+".
|
||||
// This has caused countless problems for users with mysterious misconfigurations.
|
||||
// We match this old name to support old configurations.
|
||||
const auto old_name = m_low.GetName() + *m_high.GetName().rbegin();
|
||||
|
||||
return old_name == name;
|
||||
AddInput(low);
|
||||
AddInput(high);
|
||||
AddInput(new FullAnalogSurface(low, high));
|
||||
AddInput(new FullAnalogSurface(high, low));
|
||||
}
|
||||
|
||||
void Device::AddCombinedInput(std::string name, const std::pair<std::string, std::string>& inputs)
|
||||
|
@ -163,28 +163,14 @@ protected:
|
||||
void AddInput(Input* const i);
|
||||
void AddOutput(Output* const o);
|
||||
|
||||
class FullAnalogSurface final : public Input
|
||||
{
|
||||
public:
|
||||
FullAnalogSurface(Input* low, Input* high) : m_low(*low), m_high(*high) {}
|
||||
ControlState GetState() const override;
|
||||
std::string GetName() const override;
|
||||
bool IsDetectable() const override;
|
||||
bool IsHidden() const override;
|
||||
bool IsMatchingName(std::string_view name) const override;
|
||||
|
||||
private:
|
||||
Input& m_low;
|
||||
Input& m_high;
|
||||
};
|
||||
|
||||
void AddAnalogInputs(Input* low, Input* high)
|
||||
{
|
||||
AddInput(low);
|
||||
AddInput(high);
|
||||
AddInput(new FullAnalogSurface(low, high));
|
||||
AddInput(new FullAnalogSurface(high, low));
|
||||
}
|
||||
// Pass Inputs for center-neutral (- and +) directions of some axis.
|
||||
// This function adds those Inputs and also a FullAnalogSurface Input for each direction.
|
||||
// This is only needed when it's not known if the particular axis is neutral in the center
|
||||
// or neutral on one of the extremes.
|
||||
// Some e.g. DInput devices expose a trigger across the full analog surface
|
||||
// but we have no way of knowing this until the user actually maps the Input,
|
||||
// so both center-neutral and full-surface Inputs need to be created in that case.
|
||||
void AddFullAnalogSurfaceInputs(Input* low, Input* high);
|
||||
|
||||
void AddCombinedInput(std::string name, const std::pair<std::string, std::string>& inputs);
|
||||
|
||||
|
@ -167,8 +167,8 @@ Joystick::Joystick(const LPDIRECTINPUTDEVICE8 device) : m_device(device)
|
||||
const LONG& ax = (&m_state_in.lX)[offset];
|
||||
|
||||
// each axis gets a negative and a positive input instance associated with it
|
||||
AddAnalogInputs(new Axis(offset, ax, base, range.lMin - base),
|
||||
new Axis(offset, ax, base, range.lMax - base));
|
||||
AddFullAnalogSurfaceInputs(new Axis(offset, ax, base, range.lMin - base),
|
||||
new Axis(offset, ax, base, range.lMax - base));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ void PipeDevice::AddAxis(const std::string& name, double value)
|
||||
ax_lo->SetState(value);
|
||||
m_axes[name + " +"] = ax_hi;
|
||||
m_axes[name + " -"] = ax_lo;
|
||||
AddAnalogInputs(ax_lo, ax_hi);
|
||||
AddFullAnalogSurfaceInputs(ax_lo, ax_hi);
|
||||
}
|
||||
|
||||
void PipeDevice::SetAxis(const std::string& entry, double value)
|
||||
|
@ -263,18 +263,16 @@ private:
|
||||
};
|
||||
|
||||
public:
|
||||
GameController(SDL_GameController* const gamecontroller, SDL_Joystick* const joystick,
|
||||
const int sdl_index);
|
||||
GameController(SDL_GameController* const gamecontroller, SDL_Joystick* const joystick);
|
||||
~GameController();
|
||||
|
||||
std::string GetName() const override;
|
||||
std::string GetSource() const override;
|
||||
int GetSDLIndex() const;
|
||||
int GetSDLInstanceID() const;
|
||||
|
||||
private:
|
||||
SDL_GameController* const m_gamecontroller;
|
||||
std::string m_name;
|
||||
int m_sdl_index;
|
||||
SDL_Joystick* const m_joystick;
|
||||
SDL_Haptic* m_haptic = nullptr;
|
||||
};
|
||||
@ -318,7 +316,7 @@ void InputBackend::OpenAndAddDevice(int index)
|
||||
// SDL tries parsing these as Joysticks
|
||||
return;
|
||||
}
|
||||
auto gamecontroller = std::make_shared<GameController>(gc, js, index);
|
||||
auto gamecontroller = std::make_shared<GameController>(gc, js);
|
||||
if (!gamecontroller->Inputs().empty() || !gamecontroller->Outputs().empty())
|
||||
GetControllerInterface().AddDevice(std::move(gamecontroller));
|
||||
}
|
||||
@ -326,25 +324,20 @@ void InputBackend::OpenAndAddDevice(int index)
|
||||
|
||||
bool InputBackend::HandleEventAndContinue(const SDL_Event& e)
|
||||
{
|
||||
if (e.type == SDL_CONTROLLERDEVICEADDED || e.type == SDL_JOYDEVICEADDED)
|
||||
if (e.type == SDL_JOYDEVICEADDED)
|
||||
{
|
||||
// Avoid handling the event twice on a GameController
|
||||
if (e.type == SDL_JOYDEVICEADDED && SDL_IsGameController(e.jdevice.which))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// NOTE: SDL_JOYDEVICEADDED's `jdevice.which` is a device index in SDL2.
|
||||
// It will change to an "instance ID" in SDL3.
|
||||
// OpenAndAddDevice impl and calls will need refactoring when changing to SDL3.
|
||||
static_assert(!SDL_VERSION_ATLEAST(3, 0, 0), "Refactoring is needed for SDL3.");
|
||||
OpenAndAddDevice(e.jdevice.which);
|
||||
}
|
||||
else if (e.type == SDL_CONTROLLERDEVICEREMOVED || e.type == SDL_JOYDEVICEREMOVED)
|
||||
else if (e.type == SDL_JOYDEVICEREMOVED)
|
||||
{
|
||||
// Avoid handling the event twice on a GameController
|
||||
if (e.type == SDL_JOYDEVICEREMOVED && SDL_IsGameController(e.jdevice.which))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// NOTE: SDL_JOYDEVICEREMOVED's `jdevice.which` is an "instance ID".
|
||||
GetControllerInterface().RemoveDevice([&e](const auto* device) {
|
||||
return device->GetSource() == "SDL" &&
|
||||
static_cast<const GameController*>(device)->GetSDLIndex() == e.jdevice.which;
|
||||
static_cast<const GameController*>(device)->GetSDLInstanceID() == e.jdevice.which;
|
||||
});
|
||||
}
|
||||
else if (e.type == m_populate_event_type)
|
||||
@ -442,6 +435,9 @@ InputBackend::InputBackend(ControllerInterface* controller_interface)
|
||||
// We want buttons to come in as positions, not labels
|
||||
SDL_SetHint(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, "0");
|
||||
|
||||
// Disable DualSense Player LEDs; We already colorize the Primary LED
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED, "0");
|
||||
|
||||
m_hotplug_thread = std::thread([this] {
|
||||
Common::ScopeGuard quit_guard([] {
|
||||
// TODO: there seems to be some sort of memory leak with SDL, quit isn't freeing everything up
|
||||
@ -585,8 +581,8 @@ static constexpr SDLMotionAxisList SDL_AXES_GYRO = {{
|
||||
// clang-format on
|
||||
|
||||
GameController::GameController(SDL_GameController* const gamecontroller,
|
||||
SDL_Joystick* const joystick, const int sdl_index)
|
||||
: m_gamecontroller(gamecontroller), m_sdl_index(sdl_index), m_joystick(joystick)
|
||||
SDL_Joystick* const joystick)
|
||||
: m_gamecontroller(gamecontroller), m_joystick(joystick)
|
||||
{
|
||||
const char* name;
|
||||
if (gamecontroller)
|
||||
@ -714,8 +710,8 @@ GameController::GameController(SDL_GameController* const gamecontroller,
|
||||
const bool is_registered = registered_axes.contains(i);
|
||||
|
||||
// each axis gets a negative and a positive input instance associated with it
|
||||
AddAnalogInputs(new LegacyAxis(m_joystick, i, -32768, is_registered),
|
||||
new LegacyAxis(m_joystick, i, 32767, is_registered));
|
||||
AddFullAnalogSurfaceInputs(new LegacyAxis(m_joystick, i, -32768, is_registered),
|
||||
new LegacyAxis(m_joystick, i, 32767, is_registered));
|
||||
}
|
||||
|
||||
// Hats
|
||||
@ -809,9 +805,9 @@ std::string GameController::GetSource() const
|
||||
return "SDL";
|
||||
}
|
||||
|
||||
int GameController::GetSDLIndex() const
|
||||
int GameController::GetSDLInstanceID() const
|
||||
{
|
||||
return m_sdl_index;
|
||||
return SDL_JoystickInstanceID(m_joystick);
|
||||
}
|
||||
|
||||
std::string GameController::Button::GetName() const
|
||||
|
@ -125,9 +125,8 @@ public:
|
||||
u32 i = 0;
|
||||
for (auto& axis : m_axes)
|
||||
{
|
||||
// AddAnalogInputs adds additional "FullAnalogSurface" Inputs.
|
||||
AddAnalogInputs(new IndexedAxis(&axis, 0.5, +0.5, i),
|
||||
new IndexedAxis(&axis, 0.5, -0.5, i));
|
||||
AddFullAnalogSurfaceInputs(new IndexedAxis(&axis, 0.5, +0.5, i),
|
||||
new IndexedAxis(&axis, 0.5, -0.5, i));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
@ -572,7 +572,8 @@ bool evdevDevice::AddNode(std::string devnode, int fd, libevdev* dev)
|
||||
{
|
||||
if (libevdev_has_event_code(dev, EV_ABS, axis))
|
||||
{
|
||||
AddAnalogInputs(new Axis(num_axis, axis, false, dev), new Axis(num_axis, axis, true, dev));
|
||||
AddFullAnalogSurfaceInputs(new Axis(num_axis, axis, false, dev),
|
||||
new Axis(num_axis, axis, true, dev));
|
||||
++num_axis;
|
||||
}
|
||||
}
|
||||
|
@ -222,12 +222,18 @@ static VideoBackendBase* GetDefaultVideoBackend()
|
||||
return backends.front().get();
|
||||
}
|
||||
|
||||
std::string VideoBackendBase::GetDefaultBackendName()
|
||||
std::string VideoBackendBase::GetDefaultBackendConfigName()
|
||||
{
|
||||
auto* default_backend = GetDefaultVideoBackend();
|
||||
return default_backend ? default_backend->GetName() : "";
|
||||
}
|
||||
|
||||
std::string VideoBackendBase::GetDefaultBackendDisplayName()
|
||||
{
|
||||
auto* const default_backend = GetDefaultVideoBackend();
|
||||
return default_backend ? default_backend->GetDisplayName() : "";
|
||||
}
|
||||
|
||||
const std::vector<std::unique_ptr<VideoBackendBase>>& VideoBackendBase::GetAvailableBackends()
|
||||
{
|
||||
static auto s_available_backends = [] {
|
||||
|
@ -64,7 +64,8 @@ public:
|
||||
u32 Video_GetQueryResult(PerfQueryType type);
|
||||
u16 Video_GetBoundingBox(int index);
|
||||
|
||||
static std::string GetDefaultBackendName();
|
||||
static std::string GetDefaultBackendConfigName();
|
||||
static std::string GetDefaultBackendDisplayName();
|
||||
static const std::vector<std::unique_ptr<VideoBackendBase>>& GetAvailableBackends();
|
||||
static void ActivateBackend(const std::string& name);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user