Compare commits

...

26 Commits

Author SHA1 Message Date
Ty Lamontagne
7e5016fdab linux/cmake: Allow libbacktrace to be disabled 2024-07-18 16:46:24 -04:00
PCSX2 Bot
47606400fa Qt: Update Base Translation 2024-07-18 19:11:09 +02:00
TheLastRar
d6076a6107 DEV9: Use const in ICMP session 2024-07-18 19:10:40 +02:00
TheLastRar
95c57462cc DEV9: FreeBSD/Mac Fixes for ICMP session 2024-07-18 19:10:40 +02:00
TheLastRar
48a1ec3531 DEV9: Use std::unique_ptr for tracking active pings 2024-07-18 19:10:40 +02:00
TheLastRar
9da3bccca2 DEV9: Use vector for ICMP temp buffer 2024-07-18 19:10:40 +02:00
TheLastRar
a1a92920b2 DEV9: Fix handling of ICMP timeout 2024-07-18 19:10:40 +02:00
TheLastRar
b6b775e44e DEV9: Fix IP_PayloadPtr::WriteBytes() 2024-07-18 19:10:40 +02:00
TheLastRar
5ea46ac076 DEV9: Use non-blocking sockets for ICMP Sessions on Unix 2024-07-18 19:10:40 +02:00
TheLastRar
ab008bf5d0 DEV9: Correct ICMP log messages 2024-07-18 19:10:40 +02:00
TheLastRar
54782cbf70 DEV9: Amend ICMP_Session comments 2024-07-18 19:10:40 +02:00
TheLastRar
3c7cff99f4 DEV9: Eliminate c-style casts from ICMP_Session 2024-07-18 19:10:40 +02:00
TheLastRar
f326e8775f DEV9: Correct spelling in ICMP session 2024-07-18 19:10:40 +02:00
AKuHAK
a2a711b1b3 Bios: add support for Rom2 up to 4Mb 2024-07-18 11:50:57 -04:00
PCSX2 Bot
dfb857b68f Qt: Update Base Translation 2024-07-17 22:20:21 +02:00
TheLastRar
ad64d88e7b Common: Fix FreeBSD build 2024-07-17 22:15:09 +02:00
TheTechnician27
cbd207d3f4 Qt: Add Emerald theme and fix palette var names 2024-07-17 21:56:46 +02:00
gooosedev
4bf8b23204 Debugger: change how the nullbyte (0x00) are displayed in the memoryview widget. 2024-07-17 21:55:04 +02:00
Ty Lamontagne
951780b43d Debugger: Implement little endian memory view support 2024-07-17 21:55:04 +02:00
TheTechnician27
84fe413635 GameDB: Ensure NativeScaling doesn't nag users at native res 2024-07-17 15:01:07 -04:00
Mrlinkwii
17aaa31362 github: mention to verify games if making an issue
[ci skip]
2024-07-17 14:58:37 -04:00
TheTechnician27
f943bdad98 Covers: Use serial for cover image names when selected individually 2024-07-17 14:58:04 -04:00
JordanTheToaster
09b2b6f949 GameDB: Fix up ATV ORF 3 fixes 2024-07-17 20:57:56 +02:00
L1Q
c46902c0f5 ReadMe: Fix BIOS dump link. (#11552) 2024-07-17 20:57:07 +02:00
PCSX2 Bot
c0dce9f64b PAD: Update to latest controller database. 2024-07-17 20:55:31 +02:00
Silent
cd3e11bff7 InputManager: Release settings lock before shutting down the input source 2024-07-13 07:29:26 -04:00
24 changed files with 834 additions and 604 deletions

View File

@@ -18,6 +18,8 @@ body:
Please make an effort to make sure your issue isn't already reported.
Please make sure your game is verified using the built-in game verifier.
Do not create issues involving software piracy of BIOS or ISO files, our rules specifically prohibit this and your issue will be closed.
### Please Avoid Issues Pertaining to the Following:

View File

@@ -18,7 +18,7 @@ Installers and binaries for both stable and nightly builds are available from [o
PCSX2 supports Windows, Linux, and Mac platforms. Our [setup documentation page](https://pcsx2.net/docs/setup/requirements) contains additional details on software and hardware requirements.
Please note that a BIOS dump from a legitimately-owned PS2 console is required to use the emulator. For more information, visit [this page](https://pcsx2.net/docs/setup/gather/#how-to-dump-your-ps2-bios).
Please note that a BIOS dump from a legitimately-owned PS2 console is required to use the emulator. For more information, visit [this page](https://pcsx2.net/docs/setup/bios/).
## Contributing / Building

View File

@@ -11186,8 +11186,6 @@ SCUS-97436:
SCUS-97437:
name: "ATV Offroad Fury 3 [Demo]"
region: "NTSC-U"
speedHacks:
mtvu: 0 # Increases FPS drastically.
SCUS-97438:
name: "EyeToy - Antigrav [Demo]"
region: "NTSC-U"
@@ -11583,8 +11581,6 @@ SCUS-97513:
SCUS-97514:
name: "ATV Offroad Fury 3 [Greatest Hits]"
region: "NTSC-U"
speedHacks:
mtvu: 0 # Increases FPS drastically.
SCUS-97515:
name: "Hot Shots Golf FORE! [Greatest Hits]"
region: "NTSC-U"
@@ -22926,8 +22922,6 @@ SLES-53753:
SLES-53754:
name: "ATV Offroad Fury 3"
region: "PAL-M6"
speedHacks:
mtvu: 0 # Increases FPS drastically.
SLES-53755:
name: "Castlevania - Curse of Darkness"
region: "PAL-M5"
@@ -69617,8 +69611,6 @@ SLUS-90009:
SLUS-97405:
name: "ATV Offroad Fury 3"
region: "NTSC-U"
speedHacks:
mtvu: 0 # Increases FPS drastically.
SRPM-70201:
name: "Space Venus Starring Morning Musume."
region: "NTSC-J"

View File

@@ -1690,6 +1690,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000005e040000220b000013050000,Xbox One Elite 2 Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000005e040000ea02000011050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
050082795e040000e002000003090000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
060000005e040000ea0200000b050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
060000005e040000ea0200000d050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,

View File

@@ -23,6 +23,7 @@ if(UNIX AND NOT APPLE)
option(ENABLE_SETCAP "Enable networking capability for DEV9" OFF)
option(X11_API "Enable X11 support" ON)
option(WAYLAND_API "Enable Wayland support" ON)
option(USE_BACKTRACE "Enable libbacktrace support" ON)
endif()
if(UNIX)

View File

@@ -65,7 +65,10 @@ else()
find_package(Wayland REQUIRED Egl)
endif()
find_package(Libbacktrace REQUIRED)
if(USE_BACKTRACE)
find_package(Libbacktrace REQUIRED)
endif()
find_package(PkgConfig REQUIRED)
pkg_check_modules(DBUS REQUIRED dbus-1)
endif()

View File

@@ -167,10 +167,16 @@ else()
)
target_link_libraries(common PRIVATE
${DBUS_LINK_LIBRARIES}
libbacktrace::libbacktrace
X11::X11
X11::Xrandr
)
if(USE_BACKTRACE)
target_compile_definitions(common PRIVATE "HAS_LIBBACKTRACE=1")
target_link_libraries(common PRIVATE libbacktrace::libbacktrace)
endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
target_link_libraries(common PRIVATE cpuinfo)
endif()
endif()
set_source_files_properties(PrecompiledHeader.cpp PROPERTIES HEADER_FILE_ONLY TRUE)

View File

@@ -176,7 +176,7 @@ void CrashHandler::WriteDumpForCaller()
WriteMinidumpAndCallstack(nullptr);
}
#elif !defined(__APPLE__)
#elif !defined(__APPLE__) && defined(HAS_LIBBACKTRACE)
#include "FileSystem.h"
@@ -377,4 +377,4 @@ void CrashHandler::CrashSignalHandler(int signal, siginfo_t* siginfo, void* ctx)
std::abort();
}
#endif
#endif

View File

@@ -19,6 +19,10 @@
#include "fmt/core.h"
#if defined(__FreeBSD__)
#include "cpuinfo.h"
#endif
// FreeBSD does not have MAP_FIXED_NOREPLACE, but does have MAP_EXCL.
// MAP_FIXED combined with MAP_EXCL behaves like MAP_FIXED_NOREPLACE.
#if defined(__FreeBSD__) && !defined(MAP_FIXED_NOREPLACE)
@@ -142,6 +146,22 @@ size_t HostSys::GetRuntimePageSize()
size_t HostSys::GetRuntimeCacheLineSize()
{
#if defined(__FreeBSD__)
if (!cpuinfo_initialize())
return 0;
u32 max_line_size = 0;
for (u32 i = 0; i < cpuinfo_get_processors_count(); i++)
{
const u32 l1i = cpuinfo_get_processor(i)->cache.l1i->line_size;
const u32 l1d = cpuinfo_get_processor(i)->cache.l1d->line_size;
const u32 res = std::max<u32>(l1i, l1d);
max_line_size = std::max<u32>(max_line_size, res);
}
return static_cast<size_t>(max_line_size);
#else
int l1i = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
int l1d = sysconf(_SC_LEVEL1_ICACHE_LINESIZE);
int res = (l1i > l1d) ? l1i : l1d;
@@ -160,6 +180,7 @@ size_t HostSys::GetRuntimeCacheLineSize()
}
return (res > 0) ? static_cast<size_t>(res) : 0;
#endif
}
SharedMemoryMappingArea::SharedMemoryMappingArea(u8* base_ptr, size_t size, size_t num_pages)

View File

@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LGPL-3.0+
#include "MemoryViewWidget.h"
#include "common/Console.h"
#include "QtHost.h"
#include "QtUtils.h"
@@ -10,7 +11,6 @@
#include <QtWidgets/QInputDialog>
#include <QtWidgets/QMessageBox>
#include <QtGui/QClipboard>
#include <QtCore/QtEndian>
using namespace QtUtils;
@@ -67,47 +67,78 @@ void MemoryViewTable::DrawTable(QPainter& painter, const QPalette& palette, s32
s32 valX = valuexAxis;
segmentXAxis[0] = valX;
u32 currentSegmentAddress = currentRowAddress;
for (int j = 0; j < 16; j++)
for (int j = 0; j < 16 / (s32)displayType; j++)
{
const u32 currentByteAddress = currentRowAddress + j;
valX += charWidth;
const u32 thisSegmentsStart = currentRowAddress + (j * (s32)displayType);
if (!(j % (s32)displayType))
{
valX += charWidth;
currentSegmentAddress = currentByteAddress;
}
segmentXAxis[j] = valX;
bool penDefault = false;
if ((selectedAddress & ~0xF) == currentRowAddress)
{
if (selectedAddress == currentByteAddress)
if (selectedAddress >= thisSegmentsStart && selectedAddress < (thisSegmentsStart + (s32)displayType))
{ // If the current byte and row we are drawing is selected
if (!selectedText)
{
s32 charsIntoSegment = ((selectedAddress - thisSegmentsStart) * 2) + ((selectedNibbleHI ? 0 : 1) ^ littleEndian);
if (littleEndian)
charsIntoSegment = ((s32)displayType * 2) - charsIntoSegment - 1;
painter.setPen(QColor::fromRgb(205, 165, 0)); // SELECTED NIBBLE LINE COLOUR
const QPoint lineStart(valX + (selectedNibbleHI ? 0 : charWidth) + 1, y + (rowHeight * i));
const QPoint lineStart(valX + (charsIntoSegment * charWidth) + 1, y + (rowHeight * i));
painter.drawLine(lineStart, lineStart + QPoint(charWidth - 3, 0));
}
painter.setPen(QColor::fromRgb(0xaa, 0x22, 0x22)); // SELECTED BYTE COLOUR
}
// If the current selected byte is in our current segment, highlight the entire segment
else if (displayType != MemoryViewType::BYTE &&
currentSegmentAddress <= selectedAddress && (selectedAddress <= (currentSegmentAddress + (s32)displayType - 1)))
{
painter.setPen(palette.highlight().color()); // SELECTED SEGMENT COLOUR
}
else
{
penDefault = true;
painter.setPen(palette.text().color()); // Default colour
}
}
else
{
penDefault = true;
painter.setPen(palette.text().color()); // Default colour
}
bool valid;
const u8 val = static_cast<u8>(m_cpu->read8(currentByteAddress, valid));
painter.drawText(valX, y + (rowHeight * i), valid ? FilledQStringFromValue(val, 16) : "??");
valX += charWidth * 2;
switch (displayType)
{
case MemoryViewType::BYTE:
{
const u8 val = static_cast<u8>(m_cpu->read8(thisSegmentsStart, valid));
if (penDefault && val == 0)
painter.setPen(QColor::fromRgb(145, 145, 155)); // ZERO BYTE COLOUR
painter.drawText(valX, y + (rowHeight * i), valid ? FilledQStringFromValue(val, 16) : "??");
break;
}
case MemoryViewType::BYTEHW:
{
const u16 val = convertEndian<u16>(static_cast<u16>(m_cpu->read16(thisSegmentsStart, valid)));
if (penDefault && val == 0)
painter.setPen(QColor::fromRgb(145, 145, 155)); // ZERO BYTE COLOUR
painter.drawText(valX, y + (rowHeight * i), valid ? FilledQStringFromValue(val, 16) : "????");
break;
}
case MemoryViewType::WORD:
{
const u32 val = convertEndian<u32>(m_cpu->read32(thisSegmentsStart, valid));
if (penDefault && val == 0)
painter.setPen(QColor::fromRgb(145, 145, 155)); // ZERO BYTE COLOUR
painter.drawText(valX, y + (rowHeight * i), valid ? FilledQStringFromValue(val, 16) : "????????");
break;
}
case MemoryViewType::DWORD:
{
const u64 val = convertEndian<u64>(m_cpu->read64(thisSegmentsStart, valid));
if (penDefault && val == 0)
painter.setPen(QColor::fromRgb(145, 145, 155)); // ZERO BYTE COLOUR
painter.drawText(valX, y + (rowHeight * i), valid ? FilledQStringFromValue(val, 16) : "????????????????");
break;
}
}
valX += charWidth * 2 * (s32)displayType;
}
// valX is our new X position after the hex values
@@ -146,12 +177,15 @@ void MemoryViewTable::SelectAt(QPoint pos)
const u32 selectedRow = (pos.y() - 2) / (rowHeight);
const s32 x = pos.x();
const s32 avgSegmentWidth = segmentXAxis[1] - segmentXAxis[0];
const u32 nibbleWidth = (avgSegmentWidth / (2 * (s32)displayType));
selectedAddress = (selectedRow * 0x10) + startAddress;
if (x <= segmentXAxis[0])
{
selectedText = false;
// The user clicked before the first segment
selectedText = false;
if (littleEndian)
selectedAddress += (s32)displayType - 1;
selectedNibbleHI = true;
}
else if (x > valuexAxis && x < textXAxis)
@@ -160,10 +194,13 @@ void MemoryViewTable::SelectAt(QPoint pos)
// The user clicked inside of the hexadecimal area
for (s32 i = 0; i < 16; i++)
{
if (i == 15 || (x >= segmentXAxis[i] && x < (segmentXAxis[i + 1])))
if (i == ((16 / (s32)displayType) - 1) || (x >= segmentXAxis[i] && x < (segmentXAxis[i + 1])))
{
selectedAddress = selectedAddress + i;
selectedNibbleHI = ((x - segmentXAxis[i]) < ((avgSegmentWidth / 2) - 2)); // Subtract 2 units, makes selecting nibbles feel more natural
u32 indexInSegment = (x - segmentXAxis[i]) / nibbleWidth;
if (littleEndian)
indexInSegment = ((s32)displayType * 2) - indexInSegment - 1;
selectedAddress = selectedAddress + i * (s32)displayType + (indexInSegment / 2);
selectedNibbleHI = littleEndian ? indexInSegment & 1 : !(indexInSegment & 1);
break;
}
}
@@ -185,13 +222,13 @@ u128 MemoryViewTable::GetSelectedSegment()
val.lo = m_cpu->read8(selectedAddress);
break;
case MemoryViewType::BYTEHW:
val.lo = qToBigEndian((u16)m_cpu->read16(selectedAddress & ~1));
val.lo = convertEndian((u16)m_cpu->read16(selectedAddress & ~1));
break;
case MemoryViewType::WORD:
val.lo = qToBigEndian(m_cpu->read32(selectedAddress & ~3));
val.lo = convertEndian(m_cpu->read32(selectedAddress & ~3));
break;
case MemoryViewType::DWORD:
val._u64[0] = qToBigEndian(m_cpu->read64(selectedAddress & ~7));
val._u64[0] = convertEndian(m_cpu->read64(selectedAddress & ~7));
break;
}
return val;
@@ -210,7 +247,8 @@ void MemoryViewTable::InsertIntoSelectedHexView(u8 value)
});
}
void MemoryViewTable::InsertAtCurrentSelection(const QString& text) {
void MemoryViewTable::InsertAtCurrentSelection(const QString& text)
{
if (!m_cpu->isValidAddress(selectedAddress))
return;
@@ -218,16 +256,89 @@ void MemoryViewTable::InsertAtCurrentSelection(const QString& text) {
// This approach prevents one from pasting on a nibble boundary, but that is almost always
// user error, and we don't have an undo function in this view, so best to stay conservative.
QByteArray input = selectedText ? text.toUtf8() : QByteArray::fromHex(text.toUtf8());
Host::RunOnCPUThread([this, address = selectedAddress, cpu = m_cpu, inBytes = input] {
u32 currAddr = address;
for (int i = 0; i < inBytes.size(); i++)
{
cpu->write8(address + i, inBytes[i]);
cpu->write8(currAddr, inBytes[i]);
currAddr = nextAddress(currAddr);
QtHost::RunOnUIThread([this] { parent->update(); });
}
QtHost::RunOnUIThread([this, inBytes] { UpdateSelectedAddress(selectedAddress + inBytes.size()); parent->update(); });
});
}
u32 MemoryViewTable::nextAddress(u32 addr)
{
if (!littleEndian)
{
return addr + 1;
}
else
{
if (selectedAddress % (s32)displayType == 0)
return addr + ((s32)displayType * 2 - 1);
else
return addr - 1;
}
}
u32 MemoryViewTable::prevAddress(u32 addr)
{
if (!littleEndian)
{
return addr - 1;
}
else
{
// It works
if ((addr & ((s32)displayType - 1)) == ((s32)displayType - 1))
return addr - ((s32)displayType * 2 - 1);
else
return selectedAddress + 1;
}
}
void MemoryViewTable::ForwardSelection()
{
if (!littleEndian)
{
if ((selectedNibbleHI = !selectedNibbleHI))
UpdateSelectedAddress(selectedAddress + 1);
}
else
{
if ((selectedNibbleHI = !selectedNibbleHI))
{
if (selectedAddress % (s32)displayType == 0)
UpdateSelectedAddress(selectedAddress + ((s32)displayType * 2 - 1));
else
UpdateSelectedAddress(selectedAddress - 1);
}
}
}
void MemoryViewTable::BackwardSelection()
{
if (!littleEndian)
{
if (!(selectedNibbleHI = !selectedNibbleHI))
UpdateSelectedAddress(selectedAddress - 1);
}
else
{
if (!(selectedNibbleHI = !selectedNibbleHI))
{
// It works
if ((selectedAddress & ((s32)displayType - 1)) == ((s32)displayType - 1))
UpdateSelectedAddress(selectedAddress - ((s32)displayType * 2 - 1));
else
UpdateSelectedAddress(selectedAddress + 1);
}
}
}
// We need both key and keychar because `key` is easy to use, but is case insensitive
bool MemoryViewTable::KeyPress(int key, QChar keychar)
{
@@ -255,16 +366,16 @@ bool MemoryViewTable::KeyPress(int key, QChar keychar)
case Qt::Key::Key_Escape:
Host::RunOnCPUThread([this, address = selectedAddress, cpu = m_cpu] {
cpu->write8(address, 0);
QtHost::RunOnUIThread([this] { UpdateSelectedAddress(selectedAddress - 1); parent->update(); });
QtHost::RunOnUIThread([this] {BackwardSelection(); parent->update(); });
});
pressHandled = true;
break;
case Qt::Key::Key_Right:
UpdateSelectedAddress(selectedAddress + 1);
ForwardSelection();
pressHandled = true;
break;
case Qt::Key::Key_Left:
UpdateSelectedAddress(selectedAddress - 1);
BackwardSelection();
pressHandled = true;
break;
default:
@@ -282,9 +393,7 @@ bool MemoryViewTable::KeyPress(int key, QChar keychar)
if (pressHandled)
{
InsertIntoSelectedHexView(keyPressed);
// Increment to the next nibble or byte
if ((selectedNibbleHI = !selectedNibbleHI))
UpdateSelectedAddress(selectedAddress + 1);
ForwardSelection();
}
}
@@ -293,19 +402,15 @@ bool MemoryViewTable::KeyPress(int key, QChar keychar)
case Qt::Key::Key_Backspace:
case Qt::Key::Key_Escape:
InsertIntoSelectedHexView(0);
// Move back a byte or nibble if it's backspace being pressed
if (!(selectedNibbleHI = !selectedNibbleHI))
UpdateSelectedAddress(selectedAddress - 1);
BackwardSelection();
pressHandled = true;
break;
case Qt::Key::Key_Right:
if ((selectedNibbleHI = !selectedNibbleHI))
UpdateSelectedAddress(selectedAddress + 1);
ForwardSelection();
pressHandled = true;
break;
case Qt::Key::Key_Left:
if (!(selectedNibbleHI = !selectedNibbleHI))
UpdateSelectedAddress(selectedAddress - 1);
BackwardSelection();
pressHandled = true;
break;
default:
@@ -403,6 +508,11 @@ void MemoryViewWidget::customMenuRequested(QPoint pos)
m_contextMenu->addSeparator();
m_actionLittleEndian = new QAction(tr("Show as Little Endian"));
m_actionLittleEndian->setCheckable(true);
m_contextMenu->addAction(m_actionLittleEndian);
connect(m_actionLittleEndian, &QAction::triggered, this, [this]() { m_table.SetLittleEndian(m_actionLittleEndian->isChecked()); });
// View Types
m_actionBYTE = new QAction(tr("Show as 1 byte"));
m_actionBYTE->setCheckable(true);
@@ -446,6 +556,8 @@ void MemoryViewWidget::customMenuRequested(QPoint pos)
m_contextMenu->addAction(action);
connect(action, &QAction::triggered, this, [this]() { contextPaste(); });
}
m_actionLittleEndian->setChecked(m_table.GetLittleEndian());
const MemoryViewType currentViewType = m_table.GetViewType();
m_actionBYTE->setChecked(currentViewType == MemoryViewType::BYTE);

View File

@@ -12,6 +12,7 @@
#include <QtWidgets/QMenu>
#include <QtWidgets/QTabBar>
#include <QtGui/QPainter>
#include <QtCore/QtEndian>
#include <vector>
@@ -28,22 +29,39 @@ class MemoryViewTable
QWidget* parent;
DebugInterface* m_cpu;
MemoryViewType displayType = MemoryViewType::BYTE;
bool littleEndian = true;
u32 rowCount;
u32 rowVisible;
s32 rowHeight;
// Stuff used for selection handling
// This gets set every paint and depends on the window size / current display mode (1byte,2byte,etc)
s32 valuexAxis; // Where the hexadecimal view begins
s32 textXAxis; // Where the text view begins
s32 row1YAxis; // Where the first row starts
s32 segmentXAxis[16]; // Where the segments begin
s32 valuexAxis; // Where the hexadecimal view begins
s32 textXAxis; // Where the text view begins
s32 row1YAxis; // Where the first row starts
s32 segmentXAxis[16]; // Where the segments begin
bool selectedText = false; // Whether the user has clicked on text or hex
bool selectedNibbleHI = false;
void InsertIntoSelectedHexView(u8 value);
template <class T>
T convertEndian(T in)
{
if (littleEndian)
{
return in;
}
else
{
return qToBigEndian(in);
}
}
u32 nextAddress(u32 addr);
u32 prevAddress(u32 addr);
public:
MemoryViewTable(QWidget* parent)
: parent(parent){};
@@ -60,6 +78,8 @@ public:
void SelectAt(QPoint pos);
u128 GetSelectedSegment();
void InsertAtCurrentSelection(const QString& text);
void ForwardSelection();
void BackwardSelection();
// Returns true if the keypress was handled
bool KeyPress(int key, QChar keychar);
@@ -72,6 +92,16 @@ public:
{
displayType = viewType;
}
bool GetLittleEndian()
{
return littleEndian;
}
void SetLittleEndian(bool le)
{
littleEndian = le;
}
};
@@ -111,6 +141,7 @@ private:
Ui::RegisterWidget ui;
QMenu* m_contextMenu = 0x0;
QAction* m_actionLittleEndian;
QAction* m_actionBYTE;
QAction* m_actionBYTEHW;
QAction* m_actionWORD;

View File

@@ -2664,7 +2664,7 @@ void MainWindow::setGameListEntryCoverImage(const GameList::Entry* entry)
return;
const QString old_filename = QString::fromStdString(GameList::GetCoverImagePathForEntry(entry));
const QString new_filename = QString::fromStdString(GameList::GetNewCoverImagePathForEntry(entry, filename.toUtf8().constData()));
const QString new_filename = QString::fromStdString(GameList::GetNewCoverImagePathForEntry(entry, filename.toUtf8().constData(), true));
if (new_filename.isEmpty())
return;

View File

@@ -779,7 +779,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
dialog->registerWidgetHelp(m_ui.skipPresentingDuplicateFrames, tr("Skip Presenting Duplicate Frames"), tr("Unchecked"),
tr("Detects when idle frames are being presented in 25/30fps games, and skips presenting those frames. The frame is still "
"rendered, it just means the GPU has more time to complete it (this is NOT frame skipping). Can smooth our frame time "
"rendered, it just means the GPU has more time to complete it (this is NOT frame skipping). Can smooth out frame time "
"fluctuations when the CPU/GPU are near maximum utilization, but makes frame pacing more inconsistent and can increase "
"input lag."));

View File

@@ -39,6 +39,8 @@ const char* InterfaceSettingsWidget::THEME_NAMES[] = {
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Ruby (Black/Red) [Dark]"),
//: Ignore what Crowdin says in this string about "[Light]/[Dark]" being untouchable here, these are not variables in this case and must be translated.
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Sapphire (Black/Blue) [Dark]"),
//: Ignore what Crowdin says in this string about "[Light]/[Dark]" being untouchable here, these are not variables in this case and must be translated.
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Emerald (Black/Green) [Dark]"),
//: "Custom.qss" must be kept as-is.
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Custom.qss [Drop in PCSX2 Folder]"),
nullptr};
@@ -61,6 +63,7 @@ const char* InterfaceSettingsWidget::THEME_VALUES[] = {
"CobaltSky",
"Ruby",
"Sapphire",
"Emerald",
"Custom",
nullptr};

View File

@@ -108,28 +108,28 @@ void QtHost::SetStyleFromSettings()
const QColor blue(198, 238, 255);
const QColor blue2(0, 88, 208);
QPalette darkPalette;
darkPalette.setColor(QPalette::Window, darkGray);
darkPalette.setColor(QPalette::WindowText, Qt::white);
darkPalette.setColor(QPalette::Base, black);
darkPalette.setColor(QPalette::AlternateBase, darkGray);
darkPalette.setColor(QPalette::ToolTipBase, blue2);
darkPalette.setColor(QPalette::ToolTipText, Qt::white);
darkPalette.setColor(QPalette::Text, Qt::white);
darkPalette.setColor(QPalette::Button, darkGray);
darkPalette.setColor(QPalette::ButtonText, Qt::white);
darkPalette.setColor(QPalette::Link, blue);
darkPalette.setColor(QPalette::Highlight, blue2);
darkPalette.setColor(QPalette::HighlightedText, Qt::white);
darkPalette.setColor(QPalette::PlaceholderText, QColor(Qt::white).darker());
QPalette darkBluePalette;
darkBluePalette.setColor(QPalette::Window, darkGray);
darkBluePalette.setColor(QPalette::WindowText, Qt::white);
darkBluePalette.setColor(QPalette::Base, black);
darkBluePalette.setColor(QPalette::AlternateBase, darkGray);
darkBluePalette.setColor(QPalette::ToolTipBase, blue2);
darkBluePalette.setColor(QPalette::ToolTipText, Qt::white);
darkBluePalette.setColor(QPalette::Text, Qt::white);
darkBluePalette.setColor(QPalette::Button, darkGray);
darkBluePalette.setColor(QPalette::ButtonText, Qt::white);
darkBluePalette.setColor(QPalette::Link, blue);
darkBluePalette.setColor(QPalette::Highlight, blue2);
darkBluePalette.setColor(QPalette::HighlightedText, Qt::white);
darkBluePalette.setColor(QPalette::PlaceholderText, QColor(Qt::white).darker());
darkPalette.setColor(QPalette::Active, QPalette::Button, darkGray);
darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray);
darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, gray);
darkPalette.setColor(QPalette::Disabled, QPalette::Text, gray);
darkPalette.setColor(QPalette::Disabled, QPalette::Light, darkGray);
darkBluePalette.setColor(QPalette::Active, QPalette::Button, darkGray);
darkBluePalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray);
darkBluePalette.setColor(QPalette::Disabled, QPalette::WindowText, gray);
darkBluePalette.setColor(QPalette::Disabled, QPalette::Text, gray);
darkBluePalette.setColor(QPalette::Disabled, QPalette::Light, darkGray);
qApp->setPalette(darkPalette);
qApp->setPalette(darkBluePalette);
}
else if (theme == "GreyMatter")
{
@@ -143,28 +143,28 @@ void QtHost::SetStyleFromSettings()
const QColor gray(111, 111, 111);
const QColor blue(198, 238, 255);
QPalette darkPalette;
darkPalette.setColor(QPalette::Window, darkGray);
darkPalette.setColor(QPalette::WindowText, Qt::white);
darkPalette.setColor(QPalette::Base, lighterGray);
darkPalette.setColor(QPalette::AlternateBase, darkGray);
darkPalette.setColor(QPalette::ToolTipBase, darkGray);
darkPalette.setColor(QPalette::ToolTipText, Qt::white);
darkPalette.setColor(QPalette::Text, Qt::white);
darkPalette.setColor(QPalette::Button, lighterGray);
darkPalette.setColor(QPalette::ButtonText, Qt::white);
darkPalette.setColor(QPalette::Link, blue);
darkPalette.setColor(QPalette::Highlight, lighterGray.lighter());
darkPalette.setColor(QPalette::HighlightedText, Qt::white);
darkPalette.setColor(QPalette::PlaceholderText, QColor(Qt::white).darker());
QPalette greyMatterPalette;
greyMatterPalette.setColor(QPalette::Window, darkGray);
greyMatterPalette.setColor(QPalette::WindowText, Qt::white);
greyMatterPalette.setColor(QPalette::Base, lighterGray);
greyMatterPalette.setColor(QPalette::AlternateBase, darkGray);
greyMatterPalette.setColor(QPalette::ToolTipBase, darkGray);
greyMatterPalette.setColor(QPalette::ToolTipText, Qt::white);
greyMatterPalette.setColor(QPalette::Text, Qt::white);
greyMatterPalette.setColor(QPalette::Button, lighterGray);
greyMatterPalette.setColor(QPalette::ButtonText, Qt::white);
greyMatterPalette.setColor(QPalette::Link, blue);
greyMatterPalette.setColor(QPalette::Highlight, lighterGray.lighter());
greyMatterPalette.setColor(QPalette::HighlightedText, Qt::white);
greyMatterPalette.setColor(QPalette::PlaceholderText, QColor(Qt::white).darker());
darkPalette.setColor(QPalette::Active, QPalette::Button, lighterGray);
darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray.lighter());
darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, gray.lighter());
darkPalette.setColor(QPalette::Disabled, QPalette::Text, gray.lighter());
darkPalette.setColor(QPalette::Disabled, QPalette::Light, darkGray);
greyMatterPalette.setColor(QPalette::Active, QPalette::Button, lighterGray);
greyMatterPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray.lighter());
greyMatterPalette.setColor(QPalette::Disabled, QPalette::WindowText, gray.lighter());
greyMatterPalette.setColor(QPalette::Disabled, QPalette::Text, gray.lighter());
greyMatterPalette.setColor(QPalette::Disabled, QPalette::Light, darkGray);
qApp->setPalette(darkPalette);
qApp->setPalette(greyMatterPalette);
}
else if (theme == "UntouchedLagoon")
{
@@ -178,27 +178,27 @@ void QtHost::SetStyleFromSettings()
const QColor tameTeal(160, 190, 185);
const QColor grayBlue(160, 180, 190);
QPalette standardPalette;
standardPalette.setColor(QPalette::Window, tameTeal);
standardPalette.setColor(QPalette::WindowText, black.lighter());
standardPalette.setColor(QPalette::Base, grayBlue);
standardPalette.setColor(QPalette::AlternateBase, tameTeal);
standardPalette.setColor(QPalette::ToolTipBase, tameTeal);
standardPalette.setColor(QPalette::ToolTipText, grayBlue);
standardPalette.setColor(QPalette::Text, black);
standardPalette.setColor(QPalette::Button, tameTeal);
standardPalette.setColor(QPalette::ButtonText, black);
standardPalette.setColor(QPalette::Link, black.lighter());
standardPalette.setColor(QPalette::Highlight, teal);
standardPalette.setColor(QPalette::HighlightedText, grayBlue.lighter());
QPalette untouchedLagoonPalette;
untouchedLagoonPalette.setColor(QPalette::Window, tameTeal);
untouchedLagoonPalette.setColor(QPalette::WindowText, black.lighter());
untouchedLagoonPalette.setColor(QPalette::Base, grayBlue);
untouchedLagoonPalette.setColor(QPalette::AlternateBase, tameTeal);
untouchedLagoonPalette.setColor(QPalette::ToolTipBase, tameTeal);
untouchedLagoonPalette.setColor(QPalette::ToolTipText, grayBlue);
untouchedLagoonPalette.setColor(QPalette::Text, black);
untouchedLagoonPalette.setColor(QPalette::Button, tameTeal);
untouchedLagoonPalette.setColor(QPalette::ButtonText, black);
untouchedLagoonPalette.setColor(QPalette::Link, black.lighter());
untouchedLagoonPalette.setColor(QPalette::Highlight, teal);
untouchedLagoonPalette.setColor(QPalette::HighlightedText, grayBlue.lighter());
standardPalette.setColor(QPalette::Active, QPalette::Button, tameTeal);
standardPalette.setColor(QPalette::Disabled, QPalette::ButtonText, darkteal);
standardPalette.setColor(QPalette::Disabled, QPalette::WindowText, darkteal.lighter());
standardPalette.setColor(QPalette::Disabled, QPalette::Text, darkteal.lighter());
standardPalette.setColor(QPalette::Disabled, QPalette::Light, tameTeal);
untouchedLagoonPalette.setColor(QPalette::Active, QPalette::Button, tameTeal);
untouchedLagoonPalette.setColor(QPalette::Disabled, QPalette::ButtonText, darkteal);
untouchedLagoonPalette.setColor(QPalette::Disabled, QPalette::WindowText, darkteal.lighter());
untouchedLagoonPalette.setColor(QPalette::Disabled, QPalette::Text, darkteal.lighter());
untouchedLagoonPalette.setColor(QPalette::Disabled, QPalette::Light, tameTeal);
qApp->setPalette(standardPalette);
qApp->setPalette(untouchedLagoonPalette);
}
else if (theme == "BabyPastel")
{
@@ -214,27 +214,27 @@ void QtHost::SetStyleFromSettings()
const QColor congoPink(255, 127, 121);
const QColor blue(221, 225, 239);
QPalette standardPalette;
standardPalette.setColor(QPalette::Window, pink);
standardPalette.setColor(QPalette::WindowText, black);
standardPalette.setColor(QPalette::Base, brightPink);
standardPalette.setColor(QPalette::AlternateBase, blue);
standardPalette.setColor(QPalette::ToolTipBase, pink);
standardPalette.setColor(QPalette::ToolTipText, brightPink);
standardPalette.setColor(QPalette::Text, black);
standardPalette.setColor(QPalette::Button, pink);
standardPalette.setColor(QPalette::ButtonText, black);
standardPalette.setColor(QPalette::Link, black);
standardPalette.setColor(QPalette::Highlight, congoPink);
standardPalette.setColor(QPalette::HighlightedText, black);
QPalette babyPastelPalette;
babyPastelPalette.setColor(QPalette::Window, pink);
babyPastelPalette.setColor(QPalette::WindowText, black);
babyPastelPalette.setColor(QPalette::Base, brightPink);
babyPastelPalette.setColor(QPalette::AlternateBase, blue);
babyPastelPalette.setColor(QPalette::ToolTipBase, pink);
babyPastelPalette.setColor(QPalette::ToolTipText, brightPink);
babyPastelPalette.setColor(QPalette::Text, black);
babyPastelPalette.setColor(QPalette::Button, pink);
babyPastelPalette.setColor(QPalette::ButtonText, black);
babyPastelPalette.setColor(QPalette::Link, black);
babyPastelPalette.setColor(QPalette::Highlight, congoPink);
babyPastelPalette.setColor(QPalette::HighlightedText, black);
standardPalette.setColor(QPalette::Active, QPalette::Button, pink);
standardPalette.setColor(QPalette::Disabled, QPalette::ButtonText, redpinkish);
standardPalette.setColor(QPalette::Disabled, QPalette::WindowText, redpinkish);
standardPalette.setColor(QPalette::Disabled, QPalette::Text, redpinkish);
standardPalette.setColor(QPalette::Disabled, QPalette::Light, gray);
babyPastelPalette.setColor(QPalette::Active, QPalette::Button, pink);
babyPastelPalette.setColor(QPalette::Disabled, QPalette::ButtonText, redpinkish);
babyPastelPalette.setColor(QPalette::Disabled, QPalette::WindowText, redpinkish);
babyPastelPalette.setColor(QPalette::Disabled, QPalette::Text, redpinkish);
babyPastelPalette.setColor(QPalette::Disabled, QPalette::Light, gray);
qApp->setPalette(standardPalette);
qApp->setPalette(babyPastelPalette);
}
else if (theme == "PizzaBrown")
{
@@ -250,26 +250,27 @@ void QtHost::SetStyleFromSettings()
const QColor comp(248, 230, 213);
const QColor highlight(188, 100, 60);
QPalette standardPalette;
standardPalette.setColor(QPalette::Window, main);
standardPalette.setColor(QPalette::WindowText, Qt::black);
standardPalette.setColor(QPalette::Base, comp);
standardPalette.setColor(QPalette::AlternateBase, extr);
standardPalette.setColor(QPalette::ToolTipBase, comp);
standardPalette.setColor(QPalette::ToolTipText, Qt::black);
standardPalette.setColor(QPalette::Text, Qt::black);
standardPalette.setColor(QPalette::Button, extr);
standardPalette.setColor(QPalette::ButtonText, Qt::black);
standardPalette.setColor(QPalette::Link, highlight.darker());
standardPalette.setColor(QPalette::Highlight, highlight);
standardPalette.setColor(QPalette::HighlightedText, Qt::white);
standardPalette.setColor(QPalette::Active, QPalette::Button, extr);
standardPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray.darker());
standardPalette.setColor(QPalette::Disabled, QPalette::WindowText, gray.darker());
standardPalette.setColor(QPalette::Disabled, QPalette::Text, Qt::gray);
standardPalette.setColor(QPalette::Disabled, QPalette::Light, gray.lighter());
QPalette pizzaPalette;
pizzaPalette.setColor(QPalette::Window, main);
pizzaPalette.setColor(QPalette::WindowText, Qt::black);
pizzaPalette.setColor(QPalette::Base, comp);
pizzaPalette.setColor(QPalette::AlternateBase, extr);
pizzaPalette.setColor(QPalette::ToolTipBase, comp);
pizzaPalette.setColor(QPalette::ToolTipText, Qt::black);
pizzaPalette.setColor(QPalette::Text, Qt::black);
pizzaPalette.setColor(QPalette::Button, extr);
pizzaPalette.setColor(QPalette::ButtonText, Qt::black);
pizzaPalette.setColor(QPalette::Link, highlight.darker());
pizzaPalette.setColor(QPalette::Highlight, highlight);
pizzaPalette.setColor(QPalette::HighlightedText, Qt::white);
pizzaPalette.setColor(QPalette::Active, QPalette::Button, extr);
pizzaPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray.darker());
pizzaPalette.setColor(QPalette::Disabled, QPalette::WindowText, gray.darker());
pizzaPalette.setColor(QPalette::Disabled, QPalette::Text, Qt::gray);
pizzaPalette.setColor(QPalette::Disabled, QPalette::Light, gray.lighter());
qApp->setPalette(standardPalette);
qApp->setPalette(pizzaPalette);
}
else if (theme == "PCSX2Blue")
{
@@ -283,27 +284,27 @@ void QtHost::SetStyleFromSettings()
const QColor blue(106, 156, 255);
const QColor lightBlue(130, 155, 241);
QPalette standardPalette;
standardPalette.setColor(QPalette::Window, blue2.lighter());
standardPalette.setColor(QPalette::WindowText, blackish);
standardPalette.setColor(QPalette::Base, lightBlue);
standardPalette.setColor(QPalette::AlternateBase, blue2.lighter());
standardPalette.setColor(QPalette::ToolTipBase, blue2);
standardPalette.setColor(QPalette::ToolTipText, Qt::white);
standardPalette.setColor(QPalette::Text, blackish);
standardPalette.setColor(QPalette::Button, blue);
standardPalette.setColor(QPalette::ButtonText, blackish);
standardPalette.setColor(QPalette::Link, darkBlue);
standardPalette.setColor(QPalette::Highlight, Qt::white);
standardPalette.setColor(QPalette::HighlightedText, blackish);
QPalette pcsx2BluePalette;
pcsx2BluePalette.setColor(QPalette::Window, blue2.lighter());
pcsx2BluePalette.setColor(QPalette::WindowText, blackish);
pcsx2BluePalette.setColor(QPalette::Base, lightBlue);
pcsx2BluePalette.setColor(QPalette::AlternateBase, blue2.lighter());
pcsx2BluePalette.setColor(QPalette::ToolTipBase, blue2);
pcsx2BluePalette.setColor(QPalette::ToolTipText, Qt::white);
pcsx2BluePalette.setColor(QPalette::Text, blackish);
pcsx2BluePalette.setColor(QPalette::Button, blue);
pcsx2BluePalette.setColor(QPalette::ButtonText, blackish);
pcsx2BluePalette.setColor(QPalette::Link, darkBlue);
pcsx2BluePalette.setColor(QPalette::Highlight, Qt::white);
pcsx2BluePalette.setColor(QPalette::HighlightedText, blackish);
standardPalette.setColor(QPalette::Active, QPalette::Button, blue);
standardPalette.setColor(QPalette::Disabled, QPalette::ButtonText, darkBlue);
standardPalette.setColor(QPalette::Disabled, QPalette::WindowText, darkBlue);
standardPalette.setColor(QPalette::Disabled, QPalette::Text, darkBlue);
standardPalette.setColor(QPalette::Disabled, QPalette::Light, darkBlue);
pcsx2BluePalette.setColor(QPalette::Active, QPalette::Button, blue);
pcsx2BluePalette.setColor(QPalette::Disabled, QPalette::ButtonText, darkBlue);
pcsx2BluePalette.setColor(QPalette::Disabled, QPalette::WindowText, darkBlue);
pcsx2BluePalette.setColor(QPalette::Disabled, QPalette::Text, darkBlue);
pcsx2BluePalette.setColor(QPalette::Disabled, QPalette::Light, darkBlue);
qApp->setPalette(standardPalette);
qApp->setPalette(pcsx2BluePalette);
}
else if (theme == "ScarletDevilRed")
{
@@ -315,27 +316,27 @@ void QtHost::SetStyleFromSettings()
const QColor purplishRed(120, 45, 69);
const QColor brightRed(200, 45, 69);
QPalette darkPalette;
darkPalette.setColor(QPalette::Window, darkRed);
darkPalette.setColor(QPalette::WindowText, Qt::white);
darkPalette.setColor(QPalette::Base, purplishRed);
darkPalette.setColor(QPalette::AlternateBase, darkRed);
darkPalette.setColor(QPalette::ToolTipBase, darkRed);
darkPalette.setColor(QPalette::ToolTipText, Qt::white);
darkPalette.setColor(QPalette::Text, Qt::white);
darkPalette.setColor(QPalette::Button, purplishRed.darker());
darkPalette.setColor(QPalette::ButtonText, Qt::white);
darkPalette.setColor(QPalette::Link, brightRed);
darkPalette.setColor(QPalette::Highlight, brightRed);
darkPalette.setColor(QPalette::HighlightedText, Qt::white);
QPalette scarletDevilPalette;
scarletDevilPalette.setColor(QPalette::Window, darkRed);
scarletDevilPalette.setColor(QPalette::WindowText, Qt::white);
scarletDevilPalette.setColor(QPalette::Base, purplishRed);
scarletDevilPalette.setColor(QPalette::AlternateBase, darkRed);
scarletDevilPalette.setColor(QPalette::ToolTipBase, darkRed);
scarletDevilPalette.setColor(QPalette::ToolTipText, Qt::white);
scarletDevilPalette.setColor(QPalette::Text, Qt::white);
scarletDevilPalette.setColor(QPalette::Button, purplishRed.darker());
scarletDevilPalette.setColor(QPalette::ButtonText, Qt::white);
scarletDevilPalette.setColor(QPalette::Link, brightRed);
scarletDevilPalette.setColor(QPalette::Highlight, brightRed);
scarletDevilPalette.setColor(QPalette::HighlightedText, Qt::white);
darkPalette.setColor(QPalette::Active, QPalette::Button, purplishRed.darker());
darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, brightRed);
darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, brightRed);
darkPalette.setColor(QPalette::Disabled, QPalette::Text, brightRed);
darkPalette.setColor(QPalette::Disabled, QPalette::Light, darkRed);
scarletDevilPalette.setColor(QPalette::Active, QPalette::Button, purplishRed.darker());
scarletDevilPalette.setColor(QPalette::Disabled, QPalette::ButtonText, brightRed);
scarletDevilPalette.setColor(QPalette::Disabled, QPalette::WindowText, brightRed);
scarletDevilPalette.setColor(QPalette::Disabled, QPalette::Text, brightRed);
scarletDevilPalette.setColor(QPalette::Disabled, QPalette::Light, darkRed);
qApp->setPalette(darkPalette);
qApp->setPalette(scarletDevilPalette);
}
else if (theme == "VioletAngelPurple")
{
@@ -347,27 +348,27 @@ void QtHost::SetStyleFromSettings()
const QColor darkerPurple(90, 30, 105);
const QColor nauticalPurple(110, 30, 125);
QPalette darkPalette;
darkPalette.setColor(QPalette::Window, blackishblue);
darkPalette.setColor(QPalette::WindowText, Qt::white);
darkPalette.setColor(QPalette::Base, nauticalPurple);
darkPalette.setColor(QPalette::AlternateBase, blackishblue);
darkPalette.setColor(QPalette::ToolTipBase, nauticalPurple);
darkPalette.setColor(QPalette::ToolTipText, Qt::white);
darkPalette.setColor(QPalette::Text, Qt::white);
darkPalette.setColor(QPalette::Button, nauticalPurple.darker());
darkPalette.setColor(QPalette::ButtonText, Qt::white);
darkPalette.setColor(QPalette::Link, darkerPurple.lighter());
darkPalette.setColor(QPalette::Highlight, darkerPurple.lighter());
darkPalette.setColor(QPalette::HighlightedText, Qt::white);
QPalette violetAngelPalette;
violetAngelPalette.setColor(QPalette::Window, blackishblue);
violetAngelPalette.setColor(QPalette::WindowText, Qt::white);
violetAngelPalette.setColor(QPalette::Base, nauticalPurple);
violetAngelPalette.setColor(QPalette::AlternateBase, blackishblue);
violetAngelPalette.setColor(QPalette::ToolTipBase, nauticalPurple);
violetAngelPalette.setColor(QPalette::ToolTipText, Qt::white);
violetAngelPalette.setColor(QPalette::Text, Qt::white);
violetAngelPalette.setColor(QPalette::Button, nauticalPurple.darker());
violetAngelPalette.setColor(QPalette::ButtonText, Qt::white);
violetAngelPalette.setColor(QPalette::Link, darkerPurple.lighter());
violetAngelPalette.setColor(QPalette::Highlight, darkerPurple.lighter());
violetAngelPalette.setColor(QPalette::HighlightedText, Qt::white);
darkPalette.setColor(QPalette::Active, QPalette::Button, nauticalPurple.darker());
darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, darkerPurple.lighter());
darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, darkerPurple.lighter());
darkPalette.setColor(QPalette::Disabled, QPalette::Text, darkerPurple.darker());
darkPalette.setColor(QPalette::Disabled, QPalette::Light, nauticalPurple);
violetAngelPalette.setColor(QPalette::Active, QPalette::Button, nauticalPurple.darker());
violetAngelPalette.setColor(QPalette::Disabled, QPalette::ButtonText, darkerPurple.lighter());
violetAngelPalette.setColor(QPalette::Disabled, QPalette::WindowText, darkerPurple.lighter());
violetAngelPalette.setColor(QPalette::Disabled, QPalette::Text, darkerPurple.darker());
violetAngelPalette.setColor(QPalette::Disabled, QPalette::Light, nauticalPurple);
qApp->setPalette(darkPalette);
qApp->setPalette(violetAngelPalette);
}
else if (theme == "CobaltSky")
{
@@ -383,27 +384,27 @@ void QtHost::SetStyleFromSettings()
const QColor highlight(36, 93, 218);
const QColor link(0, 202, 255);
QPalette darkPalette;
darkPalette.setColor(QPalette::Window, royalBlue);
darkPalette.setColor(QPalette::WindowText, Qt::white);
darkPalette.setColor(QPalette::Base, royalBlue.lighter());
darkPalette.setColor(QPalette::AlternateBase, darkishBlue);
darkPalette.setColor(QPalette::ToolTipBase, darkishBlue);
darkPalette.setColor(QPalette::ToolTipText, Qt::white);
darkPalette.setColor(QPalette::Text, Qt::white);
darkPalette.setColor(QPalette::Button, lighterBlue);
darkPalette.setColor(QPalette::ButtonText, Qt::white);
darkPalette.setColor(QPalette::Link, link);
darkPalette.setColor(QPalette::Highlight, highlight);
darkPalette.setColor(QPalette::HighlightedText, Qt::white);
QPalette cobaltSkyPalette;
cobaltSkyPalette.setColor(QPalette::Window, royalBlue);
cobaltSkyPalette.setColor(QPalette::WindowText, Qt::white);
cobaltSkyPalette.setColor(QPalette::Base, royalBlue.lighter());
cobaltSkyPalette.setColor(QPalette::AlternateBase, darkishBlue);
cobaltSkyPalette.setColor(QPalette::ToolTipBase, darkishBlue);
cobaltSkyPalette.setColor(QPalette::ToolTipText, Qt::white);
cobaltSkyPalette.setColor(QPalette::Text, Qt::white);
cobaltSkyPalette.setColor(QPalette::Button, lighterBlue);
cobaltSkyPalette.setColor(QPalette::ButtonText, Qt::white);
cobaltSkyPalette.setColor(QPalette::Link, link);
cobaltSkyPalette.setColor(QPalette::Highlight, highlight);
cobaltSkyPalette.setColor(QPalette::HighlightedText, Qt::white);
darkPalette.setColor(QPalette::Active, QPalette::Button, lighterBlue);
darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray);
darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, gray);
darkPalette.setColor(QPalette::Disabled, QPalette::Text, gray);
darkPalette.setColor(QPalette::Disabled, QPalette::Light, gray);
cobaltSkyPalette.setColor(QPalette::Active, QPalette::Button, lighterBlue);
cobaltSkyPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray);
cobaltSkyPalette.setColor(QPalette::Disabled, QPalette::WindowText, gray);
cobaltSkyPalette.setColor(QPalette::Disabled, QPalette::Text, gray);
cobaltSkyPalette.setColor(QPalette::Disabled, QPalette::Light, gray);
qApp->setPalette(darkPalette);
qApp->setPalette(cobaltSkyPalette);
}
else if (theme == "Ruby")
{
@@ -415,27 +416,27 @@ void QtHost::SetStyleFromSettings()
const QColor slate(18, 18, 18);
const QColor rubyish(172, 21, 31);
QPalette darkPalette;
darkPalette.setColor(QPalette::Window, slate);
darkPalette.setColor(QPalette::WindowText, Qt::white);
darkPalette.setColor(QPalette::Base, slate.lighter());
darkPalette.setColor(QPalette::AlternateBase, slate.lighter());
darkPalette.setColor(QPalette::ToolTipBase, slate);
darkPalette.setColor(QPalette::ToolTipText, Qt::white);
darkPalette.setColor(QPalette::Text, Qt::white);
darkPalette.setColor(QPalette::Button, slate);
darkPalette.setColor(QPalette::ButtonText, Qt::white);
darkPalette.setColor(QPalette::Link, Qt::white);
darkPalette.setColor(QPalette::Highlight, rubyish);
darkPalette.setColor(QPalette::HighlightedText, Qt::white);
QPalette rubyPalette;
rubyPalette.setColor(QPalette::Window, slate);
rubyPalette.setColor(QPalette::WindowText, Qt::white);
rubyPalette.setColor(QPalette::Base, slate.lighter());
rubyPalette.setColor(QPalette::AlternateBase, slate.lighter());
rubyPalette.setColor(QPalette::ToolTipBase, slate);
rubyPalette.setColor(QPalette::ToolTipText, Qt::white);
rubyPalette.setColor(QPalette::Text, Qt::white);
rubyPalette.setColor(QPalette::Button, slate);
rubyPalette.setColor(QPalette::ButtonText, Qt::white);
rubyPalette.setColor(QPalette::Link, Qt::white);
rubyPalette.setColor(QPalette::Highlight, rubyish);
rubyPalette.setColor(QPalette::HighlightedText, Qt::white);
darkPalette.setColor(QPalette::Active, QPalette::Button, slate);
darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray);
darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, gray);
darkPalette.setColor(QPalette::Disabled, QPalette::Text, gray);
darkPalette.setColor(QPalette::Disabled, QPalette::Light, slate.lighter());
rubyPalette.setColor(QPalette::Active, QPalette::Button, slate);
rubyPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray);
rubyPalette.setColor(QPalette::Disabled, QPalette::WindowText, gray);
rubyPalette.setColor(QPalette::Disabled, QPalette::Text, gray);
rubyPalette.setColor(QPalette::Disabled, QPalette::Light, slate.lighter());
qApp->setPalette(darkPalette);
qApp->setPalette(rubyPalette);
}
else if (theme == "Sapphire")
{
@@ -447,27 +448,59 @@ void QtHost::SetStyleFromSettings()
const QColor slate(18, 18, 18);
const QColor persianBlue(32, 35, 204);
QPalette darkPalette;
darkPalette.setColor(QPalette::Window, slate);
darkPalette.setColor(QPalette::WindowText, Qt::white);
darkPalette.setColor(QPalette::Base, slate.lighter());
darkPalette.setColor(QPalette::AlternateBase, slate.lighter());
darkPalette.setColor(QPalette::ToolTipBase, slate);
darkPalette.setColor(QPalette::ToolTipText, Qt::white);
darkPalette.setColor(QPalette::Text, Qt::white);
darkPalette.setColor(QPalette::Button, slate);
darkPalette.setColor(QPalette::ButtonText, Qt::white);
darkPalette.setColor(QPalette::Link, Qt::white);
darkPalette.setColor(QPalette::Highlight, persianBlue);
darkPalette.setColor(QPalette::HighlightedText, Qt::white);
QPalette sapphirePalette;
sapphirePalette.setColor(QPalette::Window, slate);
sapphirePalette.setColor(QPalette::WindowText, Qt::white);
sapphirePalette.setColor(QPalette::Base, slate.lighter());
sapphirePalette.setColor(QPalette::AlternateBase, slate.lighter());
sapphirePalette.setColor(QPalette::ToolTipBase, slate);
sapphirePalette.setColor(QPalette::ToolTipText, Qt::white);
sapphirePalette.setColor(QPalette::Text, Qt::white);
sapphirePalette.setColor(QPalette::Button, slate);
sapphirePalette.setColor(QPalette::ButtonText, Qt::white);
sapphirePalette.setColor(QPalette::Link, Qt::white);
sapphirePalette.setColor(QPalette::Highlight, persianBlue);
sapphirePalette.setColor(QPalette::HighlightedText, Qt::white);
darkPalette.setColor(QPalette::Active, QPalette::Button, slate);
darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray);
darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, gray);
darkPalette.setColor(QPalette::Disabled, QPalette::Text, gray);
darkPalette.setColor(QPalette::Disabled, QPalette::Light, slate.lighter());
sapphirePalette.setColor(QPalette::Active, QPalette::Button, slate);
sapphirePalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray);
sapphirePalette.setColor(QPalette::Disabled, QPalette::WindowText, gray);
sapphirePalette.setColor(QPalette::Disabled, QPalette::Text, gray);
sapphirePalette.setColor(QPalette::Disabled, QPalette::Light, slate.lighter());
qApp->setPalette(darkPalette);
qApp->setPalette(sapphirePalette);
}
else if (theme == "Emerald")
{
// Custom palette by RedDevilus, Black as main color and Blue as complimentary.
// Alternative dark (black) theme.
qApp->setStyle(QStyleFactory::create("Fusion"));
const QColor gray(128, 128, 128);
const QColor slate(18, 18, 18);
const QColor evergreenEmerald(15, 81, 59);
QPalette emeraldPalette;
emeraldPalette.setColor(QPalette::Window, slate);
emeraldPalette.setColor(QPalette::WindowText, Qt::white);
emeraldPalette.setColor(QPalette::Base, slate.lighter());
emeraldPalette.setColor(QPalette::AlternateBase, slate.lighter());
emeraldPalette.setColor(QPalette::ToolTipBase, slate);
emeraldPalette.setColor(QPalette::ToolTipText, Qt::white);
emeraldPalette.setColor(QPalette::Text, Qt::white);
emeraldPalette.setColor(QPalette::Button, slate);
emeraldPalette.setColor(QPalette::ButtonText, Qt::white);
emeraldPalette.setColor(QPalette::Link, Qt::white);
emeraldPalette.setColor(QPalette::Highlight, evergreenEmerald);
emeraldPalette.setColor(QPalette::HighlightedText, Qt::white);
emeraldPalette.setColor(QPalette::Active, QPalette::Button, slate);
emeraldPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray);
emeraldPalette.setColor(QPalette::Disabled, QPalette::WindowText, gray);
emeraldPalette.setColor(QPalette::Disabled, QPalette::Text, gray);
emeraldPalette.setColor(QPalette::Disabled, QPalette::Light, slate.lighter());
qApp->setPalette(emeraldPalette);
}
else if (theme == "Custom")
{

View File

@@ -1708,8 +1708,8 @@ Leaderboard Position: {1} of {2}</source>
<name>AutoUpdaterDialog</name>
<message>
<location filename="../AutoUpdaterDialog.ui" line="17"/>
<location filename="../AutoUpdaterDialog.cpp" line="477"/>
<location filename="../AutoUpdaterDialog.cpp" line="542"/>
<location filename="../AutoUpdaterDialog.cpp" line="489"/>
<location filename="../AutoUpdaterDialog.cpp" line="554"/>
<source>Automatic Updater</source>
<translation type="unfinished"></translation>
</message>
@@ -1750,67 +1750,67 @@ Leaderboard Position: {1} of {2}</source>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="178"/>
<location filename="../AutoUpdaterDialog.cpp" line="671"/>
<location filename="../AutoUpdaterDialog.cpp" line="683"/>
<source>Updater Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="389"/>
<location filename="../AutoUpdaterDialog.cpp" line="401"/>
<source>&lt;h2&gt;Changes:&lt;/h2&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="423"/>
<location filename="../AutoUpdaterDialog.cpp" line="435"/>
<source>&lt;h2&gt;Save State Warning&lt;/h2&gt;&lt;p&gt;Installing this update will make your save states &lt;b&gt;incompatible&lt;/b&gt;. Please ensure you have saved your games to a Memory Card before installing this update or you will lose progress.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="433"/>
<location filename="../AutoUpdaterDialog.cpp" line="445"/>
<source>&lt;h2&gt;Settings Warning&lt;/h2&gt;&lt;p&gt;Installing this update will reset your program configuration. Please note that you will have to reconfigure your settings after this update.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="460"/>
<location filename="../AutoUpdaterDialog.cpp" line="472"/>
<source>Savestate Warning</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="461"/>
<location filename="../AutoUpdaterDialog.cpp" line="473"/>
<source>&lt;h1&gt;WARNING&lt;/h1&gt;&lt;p style=&apos;font-size:12pt;&apos;&gt;Installing this update will make your &lt;b&gt;save states incompatible&lt;/b&gt;, &lt;i&gt;be sure to save any progress to your memory cards before proceeding&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;Do you wish to continue?&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="478"/>
<location filename="../AutoUpdaterDialog.cpp" line="490"/>
<source>Downloading %1...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="543"/>
<location filename="../AutoUpdaterDialog.cpp" line="555"/>
<source>No updates are currently available. Please try again later.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="561"/>
<location filename="../AutoUpdaterDialog.cpp" line="573"/>
<source>Current Version: %1 (%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="562"/>
<location filename="../AutoUpdaterDialog.cpp" line="574"/>
<source>New Version: %1 (%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="563"/>
<location filename="../AutoUpdaterDialog.cpp" line="575"/>
<source>Download Size: %1 MB</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="564"/>
<location filename="../AutoUpdaterDialog.cpp" line="576"/>
<source>Loading...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="671"/>
<location filename="../AutoUpdaterDialog.cpp" line="683"/>
<source>Failed to remove updater exe after update.</source>
<translation type="unfinished"></translation>
</message>
@@ -11871,6 +11871,11 @@ Swap chain: see Microsoft&apos;s Terminology Portal.</extracomment>
<source>Overrides the driver&apos;s heuristics for enabling exclusive fullscreen, or direct flip/scanout.&lt;br&gt;Disallowing exclusive fullscreen may enable smoother task switching and overlays, but increase input latency.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/GraphicsSettingsWidget.cpp" line="781"/>
<source>Detects when idle frames are being presented in 25/30fps games, and skips presenting those frames. The frame is still rendered, it just means the GPU has more time to complete it (this is NOT frame skipping). Can smooth out frame time fluctuations when the CPU/GPU are near maximum utilization, but makes frame pacing more inconsistent and can increase input lag.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/GraphicsSettingsWidget.cpp" line="1118"/>
<source>1.25x Native (~450px)</source>
@@ -12528,11 +12533,6 @@ Swap chain: see Microsoft&apos;s Terminology Portal.</extracomment>
<extracomment>Blit = a data operation. You might want to write it as-is, but fully uppercased. More information: https://en.wikipedia.org/wiki/Bit_blit</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/GraphicsSettingsWidget.cpp" line="781"/>
<source>Detects when idle frames are being presented in 25/30fps games, and skips presenting those frames. The frame is still rendered, it just means the GPU has more time to complete it (this is NOT frame skipping). Can smooth our frame time fluctuations when the CPU/GPU are near maximum utilization, but makes frame pacing more inconsistent and can increase input lag.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/GraphicsSettingsWidget.cpp" line="791"/>
<source>Displays additional, very high upscaling multipliers dependent on GPU capability.</source>
@@ -13352,49 +13352,49 @@ Right click to clear binding</source>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.ui" line="63"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="148"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="151"/>
<source>Pause On Focus Loss</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.ui" line="42"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="137"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="140"/>
<source>Inhibit Screensaver</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.ui" line="35"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="143"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="146"/>
<source>Save State On Shutdown</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.ui" line="56"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="146"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="149"/>
<source>Pause On Start</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.ui" line="49"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="140"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="143"/>
<source>Confirm Shutdown</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.ui" line="84"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="153"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="156"/>
<source>Create Save State Backups</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.ui" line="77"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="167"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="170"/>
<source>Enable Discord Presence</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.ui" line="70"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="151"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="154"/>
<source>Pause On Controller Disconnection</source>
<translation type="unfinished"></translation>
</message>
@@ -13405,37 +13405,37 @@ Right click to clear binding</source>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.ui" line="100"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="156"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="159"/>
<source>Start Fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.ui" line="107"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="170"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="173"/>
<source>Double-Click Toggles Fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.ui" line="114"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="161"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="164"/>
<source>Render To Separate Window</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.ui" line="121"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="164"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="167"/>
<source>Hide Main Window When Running</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.ui" line="128"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="173"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="176"/>
<source>Disable Window Resizing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.ui" line="135"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="158"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="161"/>
<source>Hide Cursor In Fullscreen</source>
<translation type="unfinished"></translation>
</message>
@@ -13471,7 +13471,7 @@ Right click to clear binding</source>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.ui" line="206"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="108"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="111"/>
<source>Enable Automatic Update Check</source>
<translation type="unfinished"></translation>
</message>
@@ -13565,71 +13565,77 @@ Right click to clear binding</source>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="43"/>
<source>Emerald (Black/Green) [Dark]</source>
<extracomment>Ignore what Crowdin says in this string about &quot;[Light]/[Dark]&quot; being untouchable here, these are not variables in this case and must be translated.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="45"/>
<source>Custom.qss [Drop in PCSX2 Folder]</source>
<extracomment>&quot;Custom.qss&quot; must be kept as-is.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="108"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="137"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="111"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="140"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="153"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="170"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="143"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="156"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="173"/>
<source>Checked</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="109"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="112"/>
<source>Automatically checks for updates to the program on startup. Updates can be deferred until later or skipped entirely.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="117"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="120"/>
<source>%1 (%2)</source>
<extracomment>Variable %1 shows the version number and variable %2 shows a timestamp.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="138"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="141"/>
<source>Prevents the screen saver from activating and the host from sleeping while emulation is running.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="141"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="144"/>
<source>Determines whether a prompt will be displayed to confirm shutting down the virtual machine when the hotkey is pressed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="144"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="147"/>
<source>Automatically saves the emulator state when powering down or exiting. You can then resume directly from where you left off next time.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="152"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="155"/>
<source>Pauses the emulator when a controller with bindings is disconnected.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="171"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="174"/>
<source>Allows switching in and out of fullscreen mode by double-clicking the game window.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="174"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="177"/>
<source>Prevents the main window from being resized.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="143"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="146"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="148"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="152"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="156"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="158"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="149"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="151"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="155"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="159"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="161"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="164"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="167"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="173"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="170"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="176"/>
<source>Unchecked</source>
<translation type="unfinished"></translation>
</message>
@@ -13639,43 +13645,43 @@ Right click to clear binding</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="147"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="150"/>
<source>Pauses the emulator when a game is started.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="149"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="152"/>
<source>Pauses the emulator when you minimize the window or switch to another application, and unpauses when you switch back.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="155"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="158"/>
<source>Creates a backup copy of a save state if it already exists when the save is created. The backup copy has a .backup suffix.</source>
<extracomment>Do not translate the &quot;.backup&quot; extension.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="157"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="160"/>
<source>Automatically switches to fullscreen mode when a game is started.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="159"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="162"/>
<source>Hides the mouse pointer/cursor when the emulator is in fullscreen mode.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="162"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="165"/>
<source>Renders the game to a separate window, instead of the main window. If unchecked, the game will display over the top of the game list.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="165"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="168"/>
<source>Hides the main window (with the game list) when a game is running, requires Render To Separate Window to be enabled.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="168"/>
<location filename="../Settings/InterfaceSettingsWidget.cpp" line="171"/>
<source>Shows the game you are currently playing as part of your profile in Discord.</source>
<translation type="unfinished"></translation>
</message>
@@ -15621,63 +15627,68 @@ This action cannot be reversed, and you will lose any saves on the card.</source
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/MemoryViewWidget.cpp" line="392"/>
<location filename="../Debugger/MemoryViewWidget.cpp" line="497"/>
<source>Copy Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/MemoryViewWidget.cpp" line="396"/>
<location filename="../Debugger/MemoryViewWidget.cpp" line="501"/>
<source>Go to in Disassembly</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/MemoryViewWidget.cpp" line="400"/>
<location filename="../Debugger/MemoryViewWidget.cpp" line="484"/>
<location filename="../Debugger/MemoryViewWidget.cpp" line="505"/>
<location filename="../Debugger/MemoryViewWidget.cpp" line="596"/>
<source>Go to address</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/MemoryViewWidget.cpp" line="407"/>
<location filename="../Debugger/MemoryViewWidget.cpp" line="511"/>
<source>Show as Little Endian</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/MemoryViewWidget.cpp" line="517"/>
<source>Show as 1 byte</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/MemoryViewWidget.cpp" line="412"/>
<location filename="../Debugger/MemoryViewWidget.cpp" line="522"/>
<source>Show as 2 bytes</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/MemoryViewWidget.cpp" line="417"/>
<location filename="../Debugger/MemoryViewWidget.cpp" line="527"/>
<source>Show as 4 bytes</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/MemoryViewWidget.cpp" line="422"/>
<location filename="../Debugger/MemoryViewWidget.cpp" line="532"/>
<source>Show as 8 bytes</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/MemoryViewWidget.cpp" line="429"/>
<location filename="../Debugger/MemoryViewWidget.cpp" line="539"/>
<source>Add to Saved Memory Addresses</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/MemoryViewWidget.cpp" line="433"/>
<location filename="../Debugger/MemoryViewWidget.cpp" line="543"/>
<source>Copy Byte</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/MemoryViewWidget.cpp" line="437"/>
<location filename="../Debugger/MemoryViewWidget.cpp" line="547"/>
<source>Copy Segment</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/MemoryViewWidget.cpp" line="441"/>
<location filename="../Debugger/MemoryViewWidget.cpp" line="551"/>
<source>Copy Character</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/MemoryViewWidget.cpp" line="445"/>
<location filename="../Debugger/MemoryViewWidget.cpp" line="555"/>
<source>Paste</source>
<translation type="unfinished"></translation>
</message>

View File

@@ -96,10 +96,10 @@ namespace PacketReader::IP
{
//If buffer & data point to the same location
//Then no copy is needed
if (data == buffer)
if (data == &buffer[*offset])
return;
memcpy(buffer, data, length);
memcpy(&buffer[*offset], data, length);
*offset += length;
}
virtual IP_Payload* Clone() const

View File

@@ -15,8 +15,11 @@
#endif
#include <algorithm>
#include <bit>
#include <thread>
#include <errno.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
@@ -35,36 +38,38 @@ using namespace PacketReader::IP::ICMP;
using namespace std::chrono_literals;
/* Ping is kindof annoying to do crossplatform
All platforms restrict raw sockets
Windows provides an api for ICMP
ICMP_ECHO_REPLY should always be used, ignore ICMP_ECHO_REPLY32
IP_OPTION_INFORMATION should always be used, ignore IP_OPTION_INFORMATION32
Linux
We have access to raw sockets via CAP_NET_RAW (for pcap)
However we may be missing that cap on some builds
Linux has socket(PF_INET, SOCK_DGRAM, IPPROTO_ICMP), used similar to raw sockets but for ICMP only
Auto filters responses
Requires net.ipv4.ping_group_range sysctl, default off on alot of distros
Timeouts reported via sock_extended_err control messages (with IP_RECVERR socket option set)
Mac
Raw sockets restricted
Mac has socket(PF_INET, SOCK_DGRAM, IPPROTO_ICMP)
No restriction to using it
Implementation differs, is more versatile than linux
Does not auto filter responses
Timeouts reported as a normal packet
FreeBSD
Raw sockets restricted
No unprivilaged ICMP sockets
Timeouts reported as a normal packet??
Ping cli
Present for all platforms, but command args differ
/*
* Ping is kindof annoying to do crossplatform
* All platforms restrict raw sockets
*
* Windows provides an api for ICMP
* ICMP_ECHO_REPLY should always be used, ignore ICMP_ECHO_REPLY32
* IP_OPTION_INFORMATION should always be used, ignore IP_OPTION_INFORMATION32
*
* Linux
* We have access to raw sockets via CAP_NET_RAW (for pcap)
* However we may be missing that cap on some builds
* Also hava socket(PF_INET, SOCK_DGRAM, IPPROTO_ICMP), used similarly to raw sockets, but for ICMP only
* Auto filters responses
* Requires net.ipv4.ping_group_range sysctl, default off on a lot of distros
* Timeouts reported via sock_extended_err control messages (with IP_RECVERR socket option set)
*
* Mac
* Raw sockets restricted
* Mac has socket(PF_INET, SOCK_DGRAM, IPPROTO_ICMP)
* No restriction to using it with ICMP_ECHO
* Implementation differs, is more versatile than linux
* Does not auto filter responses
* Timeouts reported as a normal packet
*
* FreeBSD
* Raw sockets restricted
* No unprivilaged ICMP sockets
* Timeouts reported as a normal packet??
*
* Ping cli
* Present for all platforms, but command args differ
* Not used here
*/
namespace Sessions
@@ -95,29 +100,36 @@ namespace Sessions
return;
}
//Allocate return buffer
//Documentation says + 8 to allow for an ICMP error message
//In testing, ICMP_ECHO_REPLY structure itself was returned with data set to null
/*
* Allocate response buffer
* Documentation says + 8 to allow for an ICMP error message
* In testing, ICMP_ECHO_REPLY structure itself was returned with data set to null
*/
icmpResponseBufferLen = sizeof(ICMP_ECHO_REPLY) + requestSize + 8;
icmpResponseBuffer = std::make_unique<u8[]>(icmpResponseBufferLen);
icmpResponseBuffer = std::make_unique<std::byte[]>(icmpResponseBufferLen);
#elif defined(__POSIX__)
{
/*
* Allocate response buffer
* Size needed depends on which socket protocol (ICMP or raw) we use aswell as os
*/
switch (icmpConnectionKind)
{
//Two different methods for raw/icmp sockets bettween the unix OSes
//Play it safe and only enable when we know which of the two methods we use
// Two different methods for raw/icmp sockets between the Unix OSes
// Play it safe and only enable when we know which of the two methods we use
#if defined(ICMP_SOCKETS_LINUX) || defined(ICMP_SOCKETS_BSD)
case (PingType::ICMP):
icmpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
if (icmpSocket != -1)
{
#if defined(ICMP_SOCKETS_LINUX)
//Space for ICMP header, as MSG_ERRQUEUE returns what we sent
//An extra +8 required sometimes, for some reason?
// Only need space for ICMP header, as MSG_ERRQUEUE returns data we sent
// Testing found an extra + 8 was required sometimes, for some reason?
icmpResponseBufferLen = 8 + requestSize + 8;
#elif defined(ICMP_SOCKETS_BSD)
//Returned IP Header, ICMP Header & either data or failed ICMP packet
icmpResponseBufferLen = 20 + 8 + std::max(20 + 8, requestSize);
// Returned IP Header, ICMP Header & either data or failed ICMP packet
// Sometimes get full packet in ICMP error response
icmpResponseBufferLen = 20 + 8 + (20 + 8 + requestSize);
#endif
break;
}
@@ -132,16 +144,17 @@ namespace Sessions
if (icmpSocket != -1)
{
#if defined(ICMP_SOCKETS_LINUX)
//We get packet + header
// We get IP packet + ICMP header
icmpResponseBufferLen = 20 + 8 + requestSize;
#elif defined(ICMP_SOCKETS_BSD)
//As above, but we will also directly recive error ICMP messages
// As above, but we will also directly receive error ICMP messages
icmpResponseBufferLen = 20 + 8 + std::max(20 + 8, requestSize);
#endif
break;
}
DevCon.WriteLn("DEV9: ICMP: Failed To Open RAW Socket");
[[fallthrough]];
#endif
default:
@@ -149,11 +162,11 @@ namespace Sessions
return;
}
icmpResponseBuffer = std::make_unique<u8[]>(icmpResponseBufferLen);
icmpResponseBuffer = std::make_unique<std::byte[]>(icmpResponseBufferLen);
#endif
}
bool ICMP_Session::Ping::IsInitialised()
bool ICMP_Session::Ping::IsInitialised() const
{
#ifdef _WIN32
return icmpFile != INVALID_HANDLE_VALUE;
@@ -169,19 +182,29 @@ namespace Sessions
#endif
}
//Note, we can finish reading but have no data
// Returned PingResult.data is only valid when PingResult.type is 0
ICMP_Session::PingResult* ICMP_Session::Ping::Recv()
{
#ifdef _WIN32
if (WaitForSingleObject(icmpEvent, 0) == WAIT_OBJECT_0)
{
ResetEvent(icmpEvent);
//Prep buffer for reasing
[[maybe_unused]] int count = IcmpParseReplies(icmpResponseBuffer.get(), icmpResponseBufferLen);
pxAssert(count == 1);
ICMP_ECHO_REPLY* pingRet = (ICMP_ECHO_REPLY*)icmpResponseBuffer.get();
//Map status to ICMP type/code
const int count = IcmpParseReplies(icmpResponseBuffer.get(), icmpResponseBufferLen);
pxAssert(count <= 1);
// Timeout
if (count == 0)
{
result.type = -2;
result.code = 0;
return &result;
}
// Rely on implicit object creation
const ICMP_ECHO_REPLY* pingRet = reinterpret_cast<ICMP_ECHO_REPLY*>(icmpResponseBuffer.get());
// Map status to ICMP type/code
switch (pingRet->Status)
{
case (IP_SUCCESS):
@@ -208,21 +231,23 @@ namespace Sessions
result.type = 3;
result.code = 4;
break;
case (IP_BAD_ROUTE): //Bad source route
case (IP_BAD_ROUTE): // Bad source route
result.type = 3;
result.code = 5;
break;
case (IP_BAD_DESTINATION):
//I think this could be either
//Destination network unknown
//or
//Destination host unknown
//Use host unkown
/*
* I think this could be mapped to either
* Destination network unknown
* or
* Destination host unknown
* Lets map to host unknown
*/
result.type = 3;
result.code = 7;
break;
case (IP_REQ_TIMED_OUT):
//Return nothing
// Return nothing
result.type = -2;
result.code = 0;
break;
@@ -239,7 +264,7 @@ namespace Sessions
result.code = 0;
break;
//Unexpected Errors
// Unexpected errors
case (IP_BUF_TOO_SMALL):
case (IP_NO_RESOURCES):
case (IP_BAD_OPTION):
@@ -255,7 +280,7 @@ namespace Sessions
}
result.dataLength = pingRet->DataSize;
result.data = (u8*)pingRet->Data;
result.data = static_cast<u8*>(pingRet->Data);
result.address.integer = pingRet->Address;
return &result;
@@ -268,82 +293,30 @@ namespace Sessions
case (PingType::ICMP):
case (PingType::RAW):
{
int ret;
#if defined(ICMP_SOCKETS_BSD)
fd_set sReady;
fd_set sExcept;
timeval nowait{0};
FD_ZERO(&sReady);
FD_ZERO(&sExcept);
FD_SET(icmpSocket, &sReady);
FD_SET(icmpSocket, &sExcept);
ret = select(icmpSocket + 1, &sReady, nullptr, &sExcept, &nowait);
bool hasData;
if (ret == -1)
{
hasData = false;
Console.WriteLn("DEV9: ICMP: select failed. Error Code: %d", errno);
}
else if (FD_ISSET(icmpSocket, &sExcept))
{
hasData = false;
int error = 0;
socklen_t len = sizeof(error);
if (getsockopt(icmpSocket, SOL_SOCKET, SO_ERROR, (char*)&error, &len) < 0)
Console.Error("DEV9: ICMP: Unkown ICMP Connection Error (getsockopt Error: %d)", errno);
else
Console.Error("DEV9: ICMP: Recv Error: %d", error);
}
else
hasData = FD_ISSET(icmpSocket, &sReady);
if (hasData == false)
{
if (std::chrono::steady_clock::now() - icmpDeathClockStart > ICMP_TIMEOUT)
{
result.type = -2;
result.code = 0;
return &result;
}
else
return nullptr;
}
#endif
sockaddr endpoint{0};
sockaddr_in endpoint{};
iovec iov;
iov.iov_base = icmpResponseBuffer.get();
iov.iov_len = icmpResponseBufferLen;
#if defined(ICMP_SOCKETS_LINUX)
//Needs to hold cmsghdr + sock_extended_err + sockaddr_in
//for ICMP error responses (total 44 bytes)
//Unkown for other types of error
u8 cbuff[64];
// Needs to hold cmsghdr + sock_extended_err + sockaddr_in
// for ICMP error responses, this is a total of 44 bytes
// Unknown size needed for other error types
std::byte cbuff[64]{};
#endif
msghdr msg{0};
msghdr msg{};
msg.msg_name = &endpoint;
msg.msg_namelen = sizeof(endpoint);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
#if defined(ICMP_SOCKETS_LINUX)
ret = recvmsg(icmpSocket, &msg, MSG_DONTWAIT);
#elif defined(ICMP_SOCKETS_BSD)
ret = recvmsg(icmpSocket, &msg, 0);
#endif
int ret = recvmsg(icmpSocket, &msg, 0);
if (ret == -1)
{
int err = errno;
#if defined(ICMP_SOCKETS_LINUX)
if (err == EAGAIN || err == EWOULDBLOCK)
{
if (std::chrono::steady_clock::now() - icmpDeathClockStart > ICMP_TIMEOUT)
@@ -355,14 +328,16 @@ namespace Sessions
else
return nullptr;
}
#if defined(ICMP_SOCKETS_LINUX)
else
{
msg.msg_control = &cbuff;
msg.msg_controllen = sizeof(cbuff);
ret = recvmsg(icmpSocket, &msg, MSG_ERRQUEUE | MSG_DONTWAIT);
ret = recvmsg(icmpSocket, &msg, MSG_ERRQUEUE);
}
#endif
if (ret == -1)
#endif
{
Console.Error("DEV9: ICMP: RecvMsg Error: %d", err);
result.type = -1;
@@ -373,40 +348,59 @@ namespace Sessions
if (msg.msg_flags & MSG_TRUNC)
Console.Error("DEV9: ICMP: RecvMsg Truncated");
#if defined(ICMP_SOCKETS_LINUX)
if (msg.msg_flags & MSG_CTRUNC)
Console.Error("DEV9: ICMP: RecvMsg Control Truncated");
sock_extended_err* ex_err = nullptr;
// On Linux, ICMP errors are stored in control messages retrieved using MSG_ERRQUEUE
sock_extended_err* exErrorPtr = nullptr;
cmsghdr* cmsg;
/* Receive auxiliary data in msgh */
// Search though control messages, taking the latest mesage
// We should only have at most 1 message
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg))
{
if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR)
{
ex_err = (sock_extended_err*)CMSG_DATA(cmsg);
pxAssert(!exErrorPtr);
exErrorPtr = reinterpret_cast<sock_extended_err*>(CMSG_DATA(cmsg));
continue;
}
pxAssert(false);
}
if (ex_err != nullptr)
if (exErrorPtr != nullptr)
{
if (ex_err->ee_origin == SO_EE_ORIGIN_ICMP)
{
result.type = ex_err->ee_type;
result.code = ex_err->ee_code;
/*
* The pointer returned cannot be assumed to be suitably aligned for accessing arbitrary payload data types
* So we would need to memcpy sock_extended_err
*/
sock_extended_err exError;
std::memcpy(&exError, exErrorPtr, sizeof(exError));
sockaddr_in* sockaddr = (sockaddr_in*)SO_EE_OFFENDER(ex_err);
result.address = *(IP_Address*)&sockaddr->sin_addr;
// Process the error
if (exError.ee_origin == SO_EE_ORIGIN_ICMP)
{
result.type = exError.ee_type;
result.code = exError.ee_code;
/*
* SO_EE_OFFENDER reads data relative to, but not necessarily included in struct sock_extended_err
* So we need to pass the original pointer provided to us from CMSG_DATA()
* However, the input pointer needs to be of type sock_extended_err*, hence the reinterpret_cast
* The pointer returned may not be suitably aligned (see CMSG_DATA), so we need to memcpy
*/
sockaddr_in errorEndpoint;
std::memcpy(&errorEndpoint, SO_EE_OFFENDER(exErrorPtr), sizeof(errorEndpoint));
result.address = std::bit_cast<IP_Address>(errorEndpoint.sin_addr);
return &result;
}
else
{
Console.Error("DEV9: ICMP: Recv Error %d", ex_err->ee_errno);
Console.Error("DEV9: ICMP: Recv error %d", exError.ee_errno);
result.type = -1;
result.code = ex_err->ee_errno;
result.code = exError.ee_errno;
return &result;
}
}
@@ -424,60 +418,66 @@ namespace Sessions
else
#endif
{
ip* ipHeader = (ip*)icmpResponseBuffer.get();
int headerLength = ipHeader->ip_hl << 2;
// Rely on implicit object creation
const ip* ipHeader = reinterpret_cast<ip*>(icmpResponseBuffer.get());
const int headerLength = ipHeader->ip_hl << 2;
pxAssert(headerLength == 20);
offset = headerLength;
#ifdef __APPLE__
//Apple (old BSD)'s raw IP sockets implementation converts the ip_len field to host byte order
//and additionally subtracts the header length.
//https://www.unix.com/man-page/mojave/4/ip/
// Apple (old BSD)'s raw IP sockets implementation converts the ip_len field to host byte order
// and additionally subtracts the header length.
// https://www.unix.com/man-page/mojave/4/ip/
length = ipHeader->ip_len;
#else
length = ntohs(ipHeader->ip_len) - headerLength;
#endif
}
ICMP_Packet icmp(&icmpResponseBuffer[offset], length);
// Rely on implicit object creation for u8
ICMP_Packet icmp(reinterpret_cast<u8*>(&icmpResponseBuffer[offset]), length);
PayloadPtr* icmpPayload = static_cast<PayloadPtr*>(icmp.GetPayload());
result.type = icmp.type;
result.code = icmp.code;
sockaddr_in* sockaddr = (sockaddr_in*)&endpoint;
result.address = *(IP_Address*)&sockaddr->sin_addr;
result.address = std::bit_cast<IP_Address>(endpoint.sin_addr);
if (icmp.type == 0)
{
//Check if response is to us
// Check if response is for us
if (icmpConnectionKind == PingType::RAW)
{
ICMP_HeaderDataIdentifier headerData(icmp.headerData);
const ICMP_HeaderDataIdentifier headerData(icmp.headerData);
if (headerData.identifier != icmpId)
return nullptr;
}
//While icmp (and its PayloadPtr) will be destroyed when leaving this function
//the data pointed to it persist in icmpResponseBuffer
// While icmp (and its PayloadPtr) will be destroyed when leaving this function
// the data it points to persists in icmpResponseBuffer
result.dataLength = icmpPayload->GetLength();
result.data = icmpPayload->data;
return &result;
}
#if defined(ICMP_SOCKETS_BSD)
// On BSD/Mac, ICMP errors are returned as normal packets
else if (icmp.type == 3 || icmp.type == 4 || icmp.type == 5 || icmp.type == 11)
{
//Check if response is to us
//We need to extract the sent header
// Extract the packet the ICMP message is responding to
IP_Packet ipPacket(icmpPayload->data, icmpPayload->GetLength(), true);
IP_PayloadPtr* ipPayload = static_cast<IP_PayloadPtr*>(ipPacket.GetPayload());
ICMP_Packet retIcmp(ipPayload->data, ipPayload->GetLength());
ICMP_HeaderDataIdentifier headerData(icmp.headerData);
if (ipPacket.protocol != static_cast<u8>(IP_Type::ICMP))
return nullptr;
IP_PayloadPtr* ipPayload = static_cast<IP_PayloadPtr*>(ipPacket.GetPayload());
ICMP_Packet icmpInner(ipPayload->data, ipPayload->GetLength());
// Check if response is for us
const ICMP_HeaderDataIdentifier headerData(icmpInner.headerData);
if (headerData.identifier != icmpId)
return nullptr;
//This response is for us
// This response is for us
return &result;
}
#endif
@@ -487,7 +487,7 @@ namespace Sessions
Console.Error("DEV9: ICMP: Unexpected packet");
pxAssert(false);
#endif
//Assume not for us
// Assume not for us
return nullptr;
}
}
@@ -503,25 +503,25 @@ namespace Sessions
bool ICMP_Session::Ping::Send(IP_Address parAdapterIP, IP_Address parDestIP, int parTimeToLive, PayloadPtr* parPayload)
{
#ifdef _WIN32
//Documentation is incorrect, IP_OPTION_INFORMATION is to be used regardless of platform
IP_OPTION_INFORMATION ipInfo{0};
// Documentation is incorrect, IP_OPTION_INFORMATION is to be used regardless of platform
IP_OPTION_INFORMATION ipInfo{};
ipInfo.Ttl = parTimeToLive;
DWORD ret;
if (parAdapterIP.integer != 0)
ret = IcmpSendEcho2Ex(icmpFile, icmpEvent, nullptr, nullptr, parAdapterIP.integer, parDestIP.integer, parPayload->data, parPayload->GetLength(), &ipInfo, icmpResponseBuffer.get(), icmpResponseBufferLen,
(DWORD)std::chrono::duration_cast<std::chrono::milliseconds>(ICMP_TIMEOUT).count());
static_cast<DWORD>(std::chrono::duration_cast<std::chrono::milliseconds>(ICMP_TIMEOUT).count()));
else
ret = IcmpSendEcho2(icmpFile, icmpEvent, nullptr, nullptr, parDestIP.integer, parPayload->data, parPayload->GetLength(), &ipInfo, icmpResponseBuffer.get(), icmpResponseBufferLen,
(DWORD)std::chrono::duration_cast<std::chrono::milliseconds>(ICMP_TIMEOUT).count());
static_cast<DWORD>(std::chrono::duration_cast<std::chrono::milliseconds>(ICMP_TIMEOUT).count()));
//Documentation states that IcmpSendEcho2 returns ERROR_IO_PENDING
//However, it actully returns zero, with the error set to ERROR_IO_PENDING
// Documentation states that IcmpSendEcho2 returns ERROR_IO_PENDING
// However, it actually returns zero, with the error set to ERROR_IO_PENDING
if (ret == 0)
ret = GetLastError();
if (ret != ERROR_IO_PENDING)
{
Console.Error("DEV9: ICMP: Failed to Send Echo, %d", GetLastError());
Console.Error("DEV9: ICMP: Failed to send echo, %d", GetLastError());
return false;
}
@@ -534,16 +534,16 @@ namespace Sessions
{
icmpDeathClockStart = std::chrono::steady_clock::now();
//broadcast and multicast mignt need extra setsockopts
//I don't think any game will broadcast/multicast ping
// Broadcast and multicast might need extra setsockopts calls
// I don't think any game will do a broadcast/multicast ping
if (parAdapterIP.integer != 0)
{
sockaddr_in endpoint{0};
sockaddr_in endpoint{};
endpoint.sin_family = AF_INET;
*(IP_Address*)&endpoint.sin_addr = parAdapterIP;
endpoint.sin_addr = std::bit_cast<in_addr>(parAdapterIP);
if (bind(icmpSocket, (const sockaddr*)&endpoint, sizeof(endpoint)) == -1)
if (bind(icmpSocket, reinterpret_cast<const sockaddr*>(&endpoint), sizeof(endpoint)) == -1)
{
Console.Error("DEV9: ICMP: Failed to bind socket. Error: %d", errno);
::close(icmpSocket);
@@ -553,8 +553,8 @@ namespace Sessions
}
#if defined(ICMP_SOCKETS_LINUX)
int value = 1;
if (setsockopt(icmpSocket, SOL_IP, IP_RECVERR, (char*)&value, sizeof(value)))
const int value = 1;
if (setsockopt(icmpSocket, SOL_IP, IP_RECVERR, reinterpret_cast<const char*>(&value), sizeof(value)))
{
Console.Error("DEV9: ICMP: Failed to setsockopt IP_RECVERR. Error: %d", errno);
::close(icmpSocket);
@@ -563,8 +563,8 @@ namespace Sessions
}
#endif
// TTL (Note multicast & regular ttl are seperate)
if (setsockopt(icmpSocket, IPPROTO_IP, IP_TTL, (const char*)&parTimeToLive, sizeof(parTimeToLive)) == -1)
// TTL (Note multicast & regular ttl are separate)
if (setsockopt(icmpSocket, IPPROTO_IP, IP_TTL, reinterpret_cast<const char*>(&parTimeToLive), sizeof(parTimeToLive)) == -1)
{
Console.Error("DEV9: ICMP: Failed to set TTL. Error: %d", errno);
::close(icmpSocket);
@@ -572,13 +572,23 @@ namespace Sessions
return false;
}
// Non-blocking
int blocking = 1;
if (ioctl(icmpSocket, FIONBIO, &blocking) == -1)
{
Console.Error("DEV9: ICMP: Failed to set non-blocking. Error: %d", errno);
::close(icmpSocket);
icmpSocket = -1;
return false;
}
#if defined(ICMP_SOCKETS_LINUX)
if (icmpConnectionKind == PingType::ICMP)
{
//We get assigned a port
sockaddr_in endpoint{0};
// We get assigned a port/Id
sockaddr_in endpoint{};
socklen_t endpointsize = sizeof(endpoint);
if (getsockname(icmpSocket, (sockaddr*)&endpoint, &endpointsize) == -1)
if (getsockname(icmpSocket, reinterpret_cast<sockaddr*>(&endpoint), &endpointsize) == -1)
{
Console.Error("DEV9: ICMP: Failed to get id. Error: %d", errno);
::close(icmpSocket);
@@ -591,15 +601,15 @@ namespace Sessions
else
#endif
{
//Use time, in ms, as id
icmpId = (u16)std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
// Use time, in ms, as id
icmpId = static_cast<u16>(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
}
ICMP_Packet icmp(parPayload->Clone());
icmp.type = 8;
icmp.code = 0;
//We only send one icmp packet per identifier
// We only send one icmp packet per identifier
ICMP_HeaderDataIdentifier headerData(icmpId, 1);
headerData.WriteHeaderData(icmp.headerData);
@@ -609,17 +619,27 @@ namespace Sessions
int offset = 0;
icmp.WriteBytes(buffer.get(), &offset);
sockaddr_in endpoint{0};
sockaddr_in endpoint{};
endpoint.sin_family = AF_INET;
*(IP_Address*)&endpoint.sin_addr.s_addr = parDestIP;
endpoint.sin_addr = std::bit_cast<in_addr>(parDestIP);
const int ret = sendto(icmpSocket, buffer.get(), icmp.GetLength(), 0, (const sockaddr*)&endpoint, sizeof(endpoint));
if (ret == -1)
int ret = -1;
while (ret == -1)
{
Console.Error("DEV9: ICMP: Send Error %d", errno);
::close(icmpSocket);
icmpSocket = -1;
return false;
ret = sendto(icmpSocket, buffer.get(), icmp.GetLength(), 0, reinterpret_cast<const sockaddr*>(&endpoint), sizeof(endpoint));
if (ret == -1)
{
const int err = errno;
if (err == EAGAIN || err == EWOULDBLOCK)
std::this_thread::yield();
else
{
Console.Error("DEV9: ICMP: Send error %d", errno);
::close(icmpSocket);
icmpSocket = -1;
return false;
}
}
}
return true;
@@ -665,16 +685,15 @@ namespace Sessions
for (size_t i = 0; i < pings.size(); i++)
{
ICMP_Session::PingResult* pingRet = nullptr;
pingRet = pings[i]->Recv();
const ICMP_Session::PingResult* pingRet = pings[i]->Recv();
if (pingRet != nullptr)
{
Ping* ping = pings[i];
//Remove ping from list and unlock
std::unique_ptr<Ping> ping = std::move(pings[i]);
// Remove ping from list and unlock mutex
pings.erase(pings.begin() + i);
lock.unlock();
//Create return ICMP packet
// Create return ICMP packet
std::optional<ReceivedPayload> ret;
if (pingRet->type >= 0)
{
@@ -686,22 +705,19 @@ namespace Sessions
}
else
{
//We will copy the original packet back here
//Allocate fullsize buffer
u8* temp = new u8[ping->originalPacket->GetLength()];
//Allocate data
int responseSize = ping->originalPacket->GetHeaderLength() + 8;
// Copy the original packet into the returned ICMP packet
// Allocate fullsize buffer
std::vector<u8> temp = std::vector<u8>(ping->originalPacket->GetLength());
// Allocate returned ICMP payload
const int responseSize = ping->originalPacket->GetHeaderLength() + 8;
data = new PayloadData(responseSize);
//Write packet back into bytes
// Write packet into buffer
int offset = 0;
ping->originalPacket->WriteBytes(temp, &offset);
ping->originalPacket->WriteBytes(temp.data(), &offset);
//Copy only needed bytes
memcpy(data->data.get(), temp, responseSize);
//cleanup
delete[] temp;
// Copy only needed bytes
memcpy(data->data.get(), temp.data(), responseSize);
}
std::unique_ptr<ICMP_Packet> pRet = std::make_unique<ICMP_Packet>(data);
@@ -716,16 +732,13 @@ namespace Sessions
else
DevCon.WriteLn("DEV9: ICMP: ICMP timeout");
//free ping
delete ping;
if (ret.has_value())
DevCon.WriteLn("DEV9: ICMP: Return Ping");
if (--open == 0)
RaiseEventConnectionClosed();
if (ret.has_value())
DevCon.WriteLn("DEV9: ICMP: Return Ping");
//Return packet
// Return packet
return ret;
}
}
@@ -741,7 +754,7 @@ namespace Sessions
return false;
}
//Note, expects caller to set ipTimeToLive before calling
// Expects caller to set ipTimeToLive before calling
bool ICMP_Session::Send(PacketReader::IP::IP_Payload* payload, IP_Packet* packet)
{
IP_PayloadPtr* ipPayload = static_cast<IP_PayloadPtr*>(payload);
@@ -751,16 +764,19 @@ namespace Sessions
switch (icmp.type)
{
case 3: //Port Closed
case 3: // Port Closed
switch (icmp.code)
{
case 3:
{
Console.Error("DEV9: ICMP: Recived Packet Rejected, Port Closed");
//RE:Outbreak Hackfix
//TODO, check if still needed
Console.Error("DEV9: ICMP: Received Packet Rejected, Port Closed");
/*
* RE:Outbreak Hackfix
* ICMP port closed messages has an extra 4 bytes of padding before the packet copy
* this can be tested by trying to connect without using the resurrection server DNS
* turbo mode may be needed to trigger the bug, depending on the DNS server's latency
*/
std::unique_ptr<IP_Packet> retPkt;
if ((icmpPayload->data[0] & 0xF0) == (4 << 4))
retPkt = std::make_unique<IP_Packet>(icmpPayload->data, icmpPayload->GetLength(), true);
@@ -776,20 +792,20 @@ namespace Sessions
retPkt = std::make_unique<IP_Packet>(&icmpPayload->data[off], icmpPayload->GetLength(), true);
}
IP_Address srvIP = retPkt->sourceIP;
u8 prot = retPkt->protocol;
const IP_Address srvIP = retPkt->sourceIP;
const u8 prot = retPkt->protocol;
u16 srvPort = 0;
u16 ps2Port = 0;
switch (prot)
{
case (u8)IP_Type::TCP:
case (u8)IP_Type::UDP:
//Read ports directly from the payload
//both UDP and TCP have the same locations for ports
case static_cast<u8>(IP_Type::TCP):
case static_cast<u8>(IP_Type::UDP):
// Read ports directly from the payload
// both UDP and TCP have the same locations for ports
IP_PayloadPtr* payload = static_cast<IP_PayloadPtr*>(retPkt->GetPayload());
int offset = 0;
NetLib::ReadUInt16(payload->data, &offset, &srvPort); //src
NetLib::ReadUInt16(payload->data, &offset, &ps2Port); //dst
NetLib::ReadUInt16(payload->data, &offset, &srvPort); // src
NetLib::ReadUInt16(payload->data, &offset, &ps2Port); // dst
}
ConnectionKey Key{};
@@ -798,7 +814,7 @@ namespace Sessions
Key.ps2Port = ps2Port;
Key.srvPort = srvPort;
//is from Normal Port?
// Is from Normal Port?
BaseSession* s = nullptr;
connections->TryGetValue(Key, &s);
@@ -809,7 +825,7 @@ namespace Sessions
break;
}
//Is from Fixed Port?
// Is from Fixed Port?
Key.ip = {};
Key.srvPort = 0;
connections->TryGetValue(Key, &s);
@@ -827,18 +843,17 @@ namespace Sessions
Console.Error("DEV9: ICMP: Unsupported ICMP Code For Destination Unreachable %d", icmp.code);
}
break;
case 8: //Echo
case 8: // Echo
{
DevCon.WriteLn("DEV9: ICMP: Send Ping");
open++;
Ping* ping = new Ping(icmpPayload->GetLength());
std::unique_ptr<Ping> ping = std::make_unique<Ping>(icmpPayload->GetLength());
if (!ping->IsInitialised())
{
if (--open == 0)
RaiseEventConnectionClosed();
delete ping;
return false;
}
@@ -846,18 +861,17 @@ namespace Sessions
{
if (--open == 0)
RaiseEventConnectionClosed();
delete ping;
return false;
}
memcpy(ping->headerData, icmp.headerData, 4);
//Need to copy IP_Packet, original is stack allocated
// Need to copy IP_Packet, original is stack allocated
ping->originalPacket = std::make_unique<IP_Packet>(*packet);
{
std::scoped_lock lock(ping_mutex);
pings.push_back(ping);
pings.push_back(std::move(ping));
}
break;
@@ -876,10 +890,8 @@ namespace Sessions
ICMP_Session::~ICMP_Session()
{
// Cleanup
std::scoped_lock lock(ping_mutex);
//Cleanup
for (size_t i = 0; i < pings.size(); i++)
delete pings[i];
pings.clear();
}
} // namespace Sessions

View File

@@ -47,30 +47,29 @@ namespace Sessions
static PingType icmpConnectionKind;
//Sockets
// Sockets
int icmpSocket{-1};
std::chrono::steady_clock::time_point icmpDeathClockStart;
u16 icmpId;
#endif
//Return buffers
// Return buffers
PingResult result{};
int icmpResponseBufferLen{0};
std::unique_ptr<u8[]> icmpResponseBuffer;
std::unique_ptr<std::byte[]> icmpResponseBuffer;
public:
Ping(int requestSize);
bool IsInitialised();
bool IsInitialised() const;
PingResult* Recv();
bool Send(PacketReader::IP::IP_Address parAdapterIP, PacketReader::IP::IP_Address parDestIP, int parTimeToLive, PacketReader::PayloadPtr* parPayload);
~Ping();
};
SimpleQueue<PacketReader::IP::ICMP::ICMP_Packet*> _recvBuff;
std::mutex ping_mutex;
std::vector<Ping*> pings;
std::vector<std::unique_ptr<Ping>> pings;
ThreadSafeMap<Sessions::ConnectionKey, Sessions::BaseSession*>* connections;
std::atomic<int> open{0};

View File

@@ -640,7 +640,7 @@ bool GameDatabaseSchema::GameEntry::configMatchesHWFix(const Pcsx2Config::GSOpti
return (config.UpscaleMultiplier <= 1.0f || config.UserHacks_RoundSprite == value);
case GSHWFixId::NativeScaling:
return (static_cast<int>(config.UserHacks_NativeScaling) == value);
return (config.UpscaleMultiplier <= 1.0f || static_cast<int>(config.UserHacks_NativeScaling) == value);
case GSHWFixId::TexturePreloading:
return (static_cast<int>(config.TexturePreloading) <= value);

View File

@@ -1605,7 +1605,10 @@ void InputManager::UpdateInputSourceState(SettingsInterface& si, std::unique_loc
{
if (s_input_sources[static_cast<u32>(type)])
{
settings_lock.unlock();
s_input_sources[static_cast<u32>(type)]->Shutdown();
settings_lock.lock();
s_input_sources[static_cast<u32>(type)].reset();
}
}

View File

@@ -39,18 +39,18 @@ void iopMemRelease()
// which is performed by MemInit and PsxMemInit()
void iopMemReset()
{
pxAssert( iopMem );
pxAssert(iopMem);
DbgCon.WriteLn("IOP resetting main memory...");
memset(psxMemWLUT, 0, 0x2000 * sizeof(uptr) * 2); // clears both allocations, RLUT and WLUT
memset(psxMemWLUT, 0, 0x2000 * sizeof(uptr) * 2); // clears both allocations, RLUT and WLUT
// Trick! We're accessing RLUT here through WLUT, since it's the non-const pointer.
// So the ones with a 0x2000 prefixed are RLUT tables.
// Map IOP main memory, which is Read/Write, and mirrored three times
// at 0x0, 0x8000, and 0xa000:
for (int i=0; i<0x0080; i++)
for (int i = 0; i < 0x0080; i++)
{
psxMemWLUT[i + 0x0000] = (uptr)&iopMem->Main[(i & 0x1f) << 16];
@@ -78,7 +78,7 @@ void iopMemReset()
psxMemWLUT[i + 0x2000 + 0x1e00] = (uptr)&eeMem->ROM1[i << 16];
}
for (int i = 0; i < 0x0008; i++)
for (int i = 0; i < 0x0040; i++)
{
psxMemWLUT[i + 0x2000 + 0x1e40] = (uptr)&eeMem->ROM2[i << 16];
}
@@ -318,7 +318,7 @@ void iopMemWrite16(u32 mem, u16 value)
default:
psxHu16(mem) = value;
break;
break;
}
} else
{
@@ -443,7 +443,7 @@ void iopMemWrite32(u32 mem, u32 value)
case 0x60:
psHu32(SBUS_F260) = 0;
return;
return;
}
#if PSX_EXTRALOGS
@@ -529,11 +529,11 @@ bool iopMemSafeWriteBytes(u32 mem, const void* src, u32 size)
std::string iopMemReadString(u32 mem, int maxlen)
{
std::string ret;
char c;
std::string ret;
char c;
while ((c = iopMemRead8(mem++)) && maxlen--)
ret.push_back(c);
while ((c = iopMemRead8(mem++)) && maxlen--)
ret.push_back(c);
return ret;
return ret;
}

View File

@@ -11,7 +11,7 @@ namespace Ps2MemSize
static constexpr u32 TotalRam = _1mb * 128;// 128 MB total memory.
static constexpr u32 Rom = _1mb * 4; // 4 MB main rom
static constexpr u32 Rom1 = _1mb * 4; // DVD player
static constexpr u32 Rom2 = 0x00080000; // Chinese rom extension
static constexpr u32 Rom2 = _1mb * 4; // Chinese rom extension
static constexpr u32 Hardware = _64kb;
static constexpr u32 Scratch = _16kb;

View File

@@ -548,7 +548,7 @@ static void recReserveRAM()
recLUT_SetPage(recLUT, hwLUT, recROM1, 0xa000, i, i - 0x1e00);
}
for (int i = 0x1e40; i < 0x1e48; i++)
for (int i = 0x1e40; i < 0x1e80; i++)
{
recLUT_SetPage(recLUT, hwLUT, recROM2, 0x0000, i, i - 0x1e40);
recLUT_SetPage(recLUT, hwLUT, recROM2, 0x8000, i, i - 0x1e40);
@@ -691,7 +691,7 @@ static void recExecute()
if (!fastjmp_set(&m_SetJmp_StateCheck))
{
eeCpuExecuting = true;
((void(*)())EnterRecompiledCode)();
((void (*)())EnterRecompiledCode)();
// Generally unreachable code here ...
}
@@ -1544,7 +1544,7 @@ void dynarecMemcheck(size_t i)
auto mc = CBreakPoints::GetMemChecks(BREAKPOINT_EE)[i];
if(mc.hasCond)
if (mc.hasCond)
{
if (!mc.cond.Evaluate())
return;
@@ -1557,7 +1557,7 @@ void dynarecMemcheck(size_t i)
else
DevCon.WriteLn("Hit load breakpoint @0x%x", cpuRegs.pc);
}
CBreakPoints::SetBreakpointTriggered(true, BREAKPOINT_EE);
VMManager::SetPaused(true);
recExitExecution();