mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7e5016fdab | ||
|
|
47606400fa | ||
|
|
d6076a6107 | ||
|
|
95c57462cc | ||
|
|
48a1ec3531 | ||
|
|
9da3bccca2 | ||
|
|
a1a92920b2 | ||
|
|
b6b775e44e | ||
|
|
5ea46ac076 | ||
|
|
ab008bf5d0 | ||
|
|
54782cbf70 | ||
|
|
3c7cff99f4 | ||
|
|
f326e8775f | ||
|
|
a2a711b1b3 | ||
|
|
dfb857b68f | ||
|
|
ad64d88e7b | ||
|
|
cbd207d3f4 | ||
|
|
4bf8b23204 | ||
|
|
951780b43d | ||
|
|
84fe413635 | ||
|
|
17aaa31362 | ||
|
|
f943bdad98 | ||
|
|
09b2b6f949 | ||
|
|
c46902c0f5 | ||
|
|
c0dce9f64b | ||
|
|
cd3e11bff7 |
2
.github/ISSUE_TEMPLATE/emu_bug_report.yaml
vendored
2
.github/ISSUE_TEMPLATE/emu_bug_report.yaml
vendored
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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."));
|
||||
|
||||
|
||||
@@ -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};
|
||||
|
||||
|
||||
@@ -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")
|
||||
{
|
||||
|
||||
@@ -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><h2>Changes:</h2></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../AutoUpdaterDialog.cpp" line="423"/>
|
||||
<location filename="../AutoUpdaterDialog.cpp" line="435"/>
|
||||
<source><h2>Save State Warning</h2><p>Installing this update will make your save states <b>incompatible</b>. Please ensure you have saved your games to a Memory Card before installing this update or you will lose progress.</p></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../AutoUpdaterDialog.cpp" line="433"/>
|
||||
<location filename="../AutoUpdaterDialog.cpp" line="445"/>
|
||||
<source><h2>Settings Warning</h2><p>Installing this update will reset your program configuration. Please note that you will have to reconfigure your settings after this update.</p></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><h1>WARNING</h1><p style='font-size:12pt;'>Installing this update will make your <b>save states incompatible</b>, <i>be sure to save any progress to your memory cards before proceeding</i>.</p><p>Do you wish to continue?</p></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's Terminology Portal.</extracomment>
|
||||
<source>Overrides the driver's heuristics for enabling exclusive fullscreen, or direct flip/scanout.<br>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'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 "[Light]/[Dark]" 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>"Custom.qss" 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 ".backup" 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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user