From 6497ef3d86e13d7e20e5a2f95c1fb172b457807f Mon Sep 17 00:00:00 2001 From: John Baumann Date: Sat, 27 Jan 2024 22:23:30 -0600 Subject: [PATCH 01/29] Add getCPUCycles function to Lua --- src/core/pcsxffi.lua | 2 ++ src/core/pcsxlua.cc | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/core/pcsxffi.lua b/src/core/pcsxffi.lua index e7739c923..5b6145e1e 100644 --- a/src/core/pcsxffi.lua +++ b/src/core/pcsxffi.lua @@ -50,6 +50,7 @@ typedef struct { enum BreakpointType { Exec, Read, Write }; typedef struct { uint8_t opaque[?]; } Breakpoint; +uint32_t getCPUCycles(); uint8_t* getMemPtr(); uint8_t* getParPtr(); uint8_t* getRomPtr(); @@ -172,6 +173,7 @@ local function jumpToMemory(address, width) end PCSX = { + getCPUCycles = function() return C.getCPUCycles() end, getMemPtr = function() return C.getMemPtr() end, getParPtr = function() return C.getParPtr() end, getRomPtr = function() return C.getRomPtr() end, diff --git a/src/core/pcsxlua.cc b/src/core/pcsxlua.cc index c2c0777af..e5024d3a6 100644 --- a/src/core/pcsxlua.cc +++ b/src/core/pcsxlua.cc @@ -34,6 +34,7 @@ struct LuaBreakpoint { PCSX::Debug::BreakpointUserListType wrapper; }; +uint32_t getCPUCycles() { return PCSX::g_emulator->m_cpu->m_regs.cycle; } void* getMemPtr() { return PCSX::g_emulator->m_mem->m_wram; } void* getParPtr() { return PCSX::g_emulator->m_mem->m_exp1; } void* getRomPtr() { return PCSX::g_emulator->m_mem->m_bios; } @@ -137,6 +138,7 @@ static void registerAllSymbols(PCSX::Lua L) { L.getfieldtable("_CLIBS", LUA_REGISTRYINDEX); L.push("PCSX"); L.newtable(); + REGISTER(L, getCPUCycles); REGISTER(L, getMemPtr); REGISTER(L, getParPtr); REGISTER(L, getRomPtr); From 8b77052974270a2dc0f9187e21d205782e23cfc9 Mon Sep 17 00:00:00 2001 From: John Baumann Date: Sun, 28 Jan 2024 09:59:31 -0600 Subject: [PATCH 02/29] Expose cpu clockspeed constant to lua --- src/core/psxemulator.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/core/psxemulator.cc b/src/core/psxemulator.cc index e158ea553..12fe4ac76 100644 --- a/src/core/psxemulator.cc +++ b/src/core/psxemulator.cc @@ -116,6 +116,15 @@ void PCSX::Emulator::setLua() { L.pop(); L.pop(); + L.getfieldtable("PCSX", LUA_GLOBALSINDEX); + L.getfieldtable("CONSTS"); + L.getfieldtable("CPU"); + L.push(lua_Number(m_psxClockSpeed)); + L.setfield("CLOCKSPEED"); + L.pop(); + L.pop(); + L.pop(); + m_pads->setLua(L); assert(L.gettop() == 0); From 45c505c85d051160e9b99067e3e40e627643b7b8 Mon Sep 17 00:00:00 2001 From: spicyjpeg Date: Mon, 14 Oct 2024 10:45:39 +0200 Subject: [PATCH 03/29] Update VS Code extension bare metal templates --- .../bare-metal/cmake-cube/CMakeLists.txt | 7 +- .../templates/bare-metal/cmake-cube/src/gpu.h | 6 +- .../bare-metal/cmake-cube/src/main.c | 82 ++++++++++++------- .../bare-metal/empty-cmake/CMakeLists.txt | 7 +- 4 files changed, 65 insertions(+), 37 deletions(-) diff --git a/tools/vscode-extension/templates/bare-metal/cmake-cube/CMakeLists.txt b/tools/vscode-extension/templates/bare-metal/cmake-cube/CMakeLists.txt index 9c0be9d6a..13e8b16b0 100644 --- a/tools/vscode-extension/templates/bare-metal/cmake-cube/CMakeLists.txt +++ b/tools/vscode-extension/templates/bare-metal/cmake-cube/CMakeLists.txt @@ -16,9 +16,10 @@ project( HOMEPAGE_URL "https://github.com/grumpycoders/pcsx-redux" ) -# Locate a working Python installation in order to run the scripts in the tools -# directory. -find_package(Python3 3.10 REQUIRED COMPONENTS Interpreter) +# Set up compiler flags and initialize the Python environment used to run the +# scripts in the tools directory. +include(ps1-bare-metal/cmake/setup.cmake) +include(ps1-bare-metal/cmake/virtualenv.cmake) # Build a "common" library containing basic support code. We are going to link # this library into our executable. diff --git a/tools/vscode-extension/templates/bare-metal/cmake-cube/src/gpu.h b/tools/vscode-extension/templates/bare-metal/cmake-cube/src/gpu.h index 47cf3fce8..14b95636d 100644 --- a/tools/vscode-extension/templates/bare-metal/cmake-cube/src/gpu.h +++ b/tools/vscode-extension/templates/bare-metal/cmake-cube/src/gpu.h @@ -4,9 +4,13 @@ #include #include "ps1/gpucmd.h" +// In order for Z averaging to work properly, ORDERING_TABLE_SIZE should be set +// to either a relatively high value (1024 or more) or a multiple of 12; see +// setupGTE() for more details. Higher values will take up more memory but are +// required to render more complex scenes with wide depth ranges correctly. #define DMA_MAX_CHUNK_SIZE 16 #define CHAIN_BUFFER_SIZE 1024 -#define ORDERING_TABLE_SIZE 32 +#define ORDERING_TABLE_SIZE 240 typedef struct { uint32_t data[CHAIN_BUFFER_SIZE]; diff --git a/tools/vscode-extension/templates/bare-metal/cmake-cube/src/main.c b/tools/vscode-extension/templates/bare-metal/cmake-cube/src/main.c index 1782973b7..b01fdada7 100644 --- a/tools/vscode-extension/templates/bare-metal/cmake-cube/src/main.c +++ b/tools/vscode-extension/templates/bare-metal/cmake-cube/src/main.c @@ -12,34 +12,47 @@ #include #include +#include #include "font.h" #include "gpu.h" -#include "ps1/cop0gte.h" +#include "ps1/cop0.h" #include "ps1/gpucmd.h" +#include "ps1/gte.h" #include "ps1/registers.h" #include "trig.h" -// The GTE uses a 4.12 fixed-point format for most values. What this means is -// that most fractional values will be stored as integers by multiplying them by -// a fixed unit, in this case 4096 or 1 << 12 (hence making the fractional part -// 12 bits long). We'll define this unit value to make their handling easier. +// The GTE uses a 20.12 fixed-point format for most values. What this means is +// that fractional values will be stored as integers by multiplying them by a +// fixed unit, in this case 4096 or 1 << 12 (hence making the fractional part 12 +// bits long). We'll define this unit value to make their handling easier. #define ONE (1 << 12) static void setupGTE(int width, int height) { // Ensure the GTE, which is coprocessor 2, is enabled. MIPS coprocessors are - // enabled through a register in coprocessor 0, which is always accessible. - cop0_setSR(cop0_getSR() | COP0_SR_CU2); + // enabled through the status register in coprocessor 0, which is always + // accessible. + cop0_setReg(COP0_SR, cop0_getReg(COP0_SR) | COP0_SR_CU2); - // Set the offset to be added to all calculated coordinates (we want our - // cube to appear at the center of the screen) as well as the field of view. - gte_setXYOrigin(width / 2, height / 2); - gte_setFieldOfView(width); + // Set the offset to be added to all calculated screen space coordinates (we + // want our cube to appear at the center of the screen) Note that OFX and + // OFY are 16.16 fixed-point rather than 20.12. + gte_setControlReg(GTE_OFX, (width << 16) / 2); + gte_setControlReg(GTE_OFY, (height << 16) / 2); + + // Set the distance of the perspective projection plane (i.e. the camera's + // focal length), which affects the field of view. + int focalLength = (width < height) ? width : height; + + gte_setControlReg(GTE_H, focalLength / 2); // Set the scaling factor for Z averaging. For each polygon drawn, the GTE // will sum the transformed Z coordinates of its vertices multiplied by this // value in order to derive the ordering table bucket index the polygon will - // be sorted into. - gte_setZScaleFactor(ONE / ORDERING_TABLE_SIZE); + // be sorted into. This will work best if the ordering table length is a + // multiple of 12 (i.e. both 3 and 4) or high enough to make any rounding + // error negligible. + gte_setControlReg(GTE_ZSF3, ORDERING_TABLE_SIZE / 3); + gte_setControlReg(GTE_ZSF4, ORDERING_TABLE_SIZE / 4); } // When transforming vertices, the GTE will multiply their vectors by a 3x3 @@ -52,19 +65,19 @@ static void multiplyCurrentMatrixByVectors(GTEMatrix *output) { // done one column at a time, as the GTE only supports multiplying a matrix // by a vector using the MVMVA command. gte_command(GTE_CMD_MVMVA | GTE_SF | GTE_MX_RT | GTE_V_V0 | GTE_CV_NONE); - output->values[0][0] = gte_getIR1(); - output->values[1][0] = gte_getIR2(); - output->values[2][0] = gte_getIR3(); + output->values[0][0] = gte_getDataReg(GTE_IR1); + output->values[1][0] = gte_getDataReg(GTE_IR2); + output->values[2][0] = gte_getDataReg(GTE_IR3); gte_command(GTE_CMD_MVMVA | GTE_SF | GTE_MX_RT | GTE_V_V1 | GTE_CV_NONE); - output->values[0][1] = gte_getIR1(); - output->values[1][1] = gte_getIR2(); - output->values[2][1] = gte_getIR3(); + output->values[0][1] = gte_getDataReg(GTE_IR1); + output->values[1][1] = gte_getDataReg(GTE_IR2); + output->values[2][1] = gte_getDataReg(GTE_IR3); gte_command(GTE_CMD_MVMVA | GTE_SF | GTE_MX_RT | GTE_V_V2 | GTE_CV_NONE); - output->values[0][2] = gte_getIR1(); - output->values[1][2] = gte_getIR2(); - output->values[2][2] = gte_getIR3(); + output->values[0][2] = gte_getDataReg(GTE_IR1); + output->values[1][2] = gte_getDataReg(GTE_IR2); + output->values[2][2] = gte_getDataReg(GTE_IR3); } static void rotateCurrentMatrix(int yaw, int pitch, int roll) { @@ -168,10 +181,15 @@ static const Face cubeFaces[NUM_CUBE_FACES] = { extern const uint8_t fontTexture[], fontPalette[]; int main(int argc, const char **argv) { - if ((GPU_GP1 & GP1_STAT_MODE_BITMASK) == GP1_STAT_MODE_PAL) + initSerialIO(115200); + + if ((GPU_GP1 & GP1_STAT_FB_MODE_BITMASK) == GP1_STAT_FB_MODE_PAL) { + puts("Using PAL mode"); setupGPU(GP1_MODE_PAL, SCREEN_WIDTH, SCREEN_HEIGHT); - else + } else { + puts("Using NTSC mode"); setupGPU(GP1_MODE_NTSC, SCREEN_WIDTH, SCREEN_HEIGHT); + } setupGTE(SCREEN_WIDTH, SCREEN_HEIGHT); @@ -181,7 +199,7 @@ int main(int argc, const char **argv) { GPU_GP1 = gp1_dmaRequestMode(GP1_DREQ_GP0_WRITE); GPU_GP1 = gp1_dispBlank(false); - // Upload the font texture into VRAM. + // Upload the font texture to VRAM. TextureInfo font; uploadIndexedTexture( @@ -211,7 +229,9 @@ int main(int argc, const char **argv) { // transformation matrix, then modify the matrix to rotate the cube. The // translation vector is used here to move the cube away from the camera // so it can be seen. - gte_setTranslationVector(0, 0, 256); + gte_setControlReg(GTE_TRX, 0); + gte_setControlReg(GTE_TRY, 0); + gte_setControlReg(GTE_TRZ, 128); gte_setRotationMatrix( ONE, 0, 0, 0, ONE, 0, @@ -238,14 +258,14 @@ int main(int argc, const char **argv) { // be skipped as it is not facing the camera. gte_command(GTE_CMD_NCLIP); - if (gte_getMAC0() <= 0) + if (gte_getDataReg(GTE_MAC0) <= 0) continue; // Save the first transformed vertex (the GTE only keeps the X/Y // coordinates of the last 3 vertices processed and Z coordinates of // the last 4 vertices processed) and apply projection to the last // vertex. - uint32_t xy0 = gte_getSXY0(); + uint32_t xy0 = gte_getDataReg(GTE_SXY0); gte_loadV0(&cubeVertices[face->vertices[3]]); gte_command(GTE_CMD_RTPS | GTE_SF); @@ -253,7 +273,7 @@ int main(int argc, const char **argv) { // Calculate the average Z coordinate of all vertices and use it to // determine the ordering table bucket index for this face. gte_command(GTE_CMD_AVSZ4 | GTE_SF); - int zIndex = gte_getOTZ(); + int zIndex = gte_getDataReg(GTE_OTZ); if ((zIndex < 0) || (zIndex >= ORDERING_TABLE_SIZE)) continue; @@ -263,7 +283,9 @@ int main(int argc, const char **argv) { ptr = allocatePacket(chain, zIndex, 5); ptr[0] = face->color | gp0_shadedQuad(false, false, false); ptr[1] = xy0; - gte_storeSXY012(&ptr[2]); + gte_storeDataReg(GTE_SXY0, 2 * 4, ptr); + gte_storeDataReg(GTE_SXY1, 3 * 4, ptr); + gte_storeDataReg(GTE_SXY2, 4 * 4, ptr); } ptr = allocatePacket(chain, ORDERING_TABLE_SIZE - 1, 3); diff --git a/tools/vscode-extension/templates/bare-metal/empty-cmake/CMakeLists.txt b/tools/vscode-extension/templates/bare-metal/empty-cmake/CMakeLists.txt index ab362d3f2..7e9e4a340 100644 --- a/tools/vscode-extension/templates/bare-metal/empty-cmake/CMakeLists.txt +++ b/tools/vscode-extension/templates/bare-metal/empty-cmake/CMakeLists.txt @@ -16,9 +16,10 @@ project( HOMEPAGE_URL "https://github.com/grumpycoders/pcsx-redux" ) -# Locate a working Python installation in order to run the scripts in the tools -# directory. -find_package(Python3 3.10 REQUIRED COMPONENTS Interpreter) +# Set up compiler flags and initialize the Python environment used to run the +# scripts in the tools directory. +include(ps1-bare-metal/cmake/setup.cmake) +include(ps1-bare-metal/cmake/virtualenv.cmake) # Build a "common" library containing basic support code. We are going to link # this library into our executable. From ba5c080ba21f83b6448048f92625b2026578e1f3 Mon Sep 17 00:00:00 2001 From: spicyjpeg Date: Mon, 14 Oct 2024 10:45:53 +0200 Subject: [PATCH 04/29] Add Python venv support to VS Code extension, bump to 0.3.8 --- tools/vscode-extension/README.md | 2 + tools/vscode-extension/extension.js | 36 +++++++++++++++- tools/vscode-extension/media/main.js | 6 +++ tools/vscode-extension/package.json | 7 +++- tools/vscode-extension/templates.js | 62 +++++++++++++++++++++++++++- 5 files changed, 108 insertions(+), 5 deletions(-) diff --git a/tools/vscode-extension/README.md b/tools/vscode-extension/README.md index ea4e6aaed..643f20173 100644 --- a/tools/vscode-extension/README.md +++ b/tools/vscode-extension/README.md @@ -19,6 +19,8 @@ The panel will have the ability to install the tools on the most popular platfor ### Changelog +- 0.3.8 + - Added automatic setup of Python virtual environments in order to reflect the changes in ps1-bare-metal. - 0.3.7 - Bumping gcc to 14.2.0 - Bumping binutils to 2.43 diff --git a/tools/vscode-extension/extension.js b/tools/vscode-extension/extension.js index 583150f18..50bacb802 100644 --- a/tools/vscode-extension/extension.js +++ b/tools/vscode-extension/extension.js @@ -110,6 +110,9 @@ class PSXDevPanel { case 'restorePsyq': restorePsyq() break + case 'restorePythonEnv': + restorePythonEnv() + break case 'updateModules': updateModules() break @@ -219,8 +222,8 @@ class PSXDevPanel {

Before debugging a PlayStation 1 application, you'll need to have a target able to run PlayStation 1 code accessible through the gdb protocol. You can connect to a real PlayStation 1, or you can run an emulator with a gdb server. You can click the button below to launch the PCSX-Redux PlayStation 1 emulator in debugger mode.


Open Settings folder Launch PCSX-Redux

-

After cloning a project that uses the Psy-Q library, it'll be necessary to restore it. You can press the button below in order to restore the library into the current workspace.


- Restore Psy-Q
+

After cloning a project that uses Psy-Q libraries or a Python virtual environment, it'll be necessary to restore them. Use the buttons below in order to restore the appropriate dependencies into the current workspace.


+ Restore Psy-Q Restore Python environment

The templates will create git repositories with submodules. These submodules may update frequently with bug fixes and new features. The updates should not break backward compatibility in general, and should be safe to do. Press the button below to update the submodules in the current workspace.


Update modules
@@ -287,6 +290,12 @@ exports.activate = (context) => { }) ) + context.subscriptions.push( + vscode.commands.registerCommand('psxDev.restorePythonEnv', () => { + restorePythonEnv() + }) + ) + context.subscriptions.push( vscode.commands.registerCommand('psxDev.updateModules', () => { updateModules() @@ -363,6 +372,29 @@ function restorePsyq () { } } +function restorePythonEnv () { + if (vscode.workspace.workspaceFolders) { + templates + .createPythonEnv({ + path: vscode.workspace.workspaceFolders[0].uri.fsPath, + name: 'env', + requirementsFiles: [ + vscode.Uri.joinPath( + vscode.workspace.workspaceFolders[0].uri, + 'ps1-bare-metal', + 'tools', + 'requirements.txt' + ).fsPath + ] + }) + .catch((err) => { + vscode.window.showErrorMessage(err.message) + }) + } else { + vscode.window.showErrorMessage('Please open a project first.') + } +} + function showReduxSettings () { const pathToOpen = vscode.Uri.joinPath( globalStorageUri, diff --git a/tools/vscode-extension/media/main.js b/tools/vscode-extension/media/main.js index 2b682ed3f..8d7d6756a 100644 --- a/tools/vscode-extension/media/main.js +++ b/tools/vscode-extension/media/main.js @@ -87,6 +87,7 @@ import { const panelTab = document.createElement('vscode-panel-tab') panelTab.textContent = category panels.appendChild(panelTab) + templateKeys // Suppress unused variable warning } for (const [category, templateKeys] of Object.entries(categories)) { const panel = document.createElement('vscode-panel-view') @@ -295,6 +296,11 @@ import { document.getElementById('restore-psyq').addEventListener('click', () => { vscode.postMessage({ command: 'restorePsyq' }) }) + document + .getElementById('restore-python-env') + .addEventListener('click', () => { + vscode.postMessage({ command: 'restorePythonEnv' }) + }) document.getElementById('update-modules').addEventListener('click', () => { vscode.postMessage({ command: 'updateModules' }) }) diff --git a/tools/vscode-extension/package.json b/tools/vscode-extension/package.json index b1cd63f03..3487419e1 100644 --- a/tools/vscode-extension/package.json +++ b/tools/vscode-extension/package.json @@ -2,7 +2,7 @@ "name": "psx-dev", "displayName": "PSX.Dev", "description": "PlayStation 1 development made easy", - "version": "0.3.7", + "version": "0.3.8", "engines": { "vscode": "^1.75.0" }, @@ -72,6 +72,11 @@ "title": "Restore Psy-Q", "category": "PSX.Dev" }, + { + "command": "psxDev.restorePythonEnv", + "title": "Restore Python environment", + "category": "PSX.Dev" + }, { "command": "psxDev.showReduxSettings", "title": "Show PCSX-Redux Settings", diff --git a/tools/vscode-extension/templates.js b/tools/vscode-extension/templates.js index f131362e9..fd505e085 100644 --- a/tools/vscode-extension/templates.js +++ b/tools/vscode-extension/templates.js @@ -4,6 +4,7 @@ const path = require('node:path') const fs = require('fs-extra') const Mustache = require('mustache') const { simpleGit } = require('simple-git') +const terminal = require('./terminal.js') const progressNotification = require('./progressnotification.js') let extensionUri @@ -365,6 +366,7 @@ const baseCMakeTemplate = combine(baseTemplate, { name: '.gitignore', content: [ 'build/', + 'env/', '.cache/', '__pycache__/', '*.pyc', @@ -521,6 +523,27 @@ async function createGitRepository (fullPath, template, progressReporter) { return git } +async function createPythonEnv (fullPath, name, packages, requirementsFiles) { + // On Windows "python" and "python3" are aliased to a script that opens the + // Microsoft Store by default, so the "py" launcher is invoked instead. + const pythonCommand = (process.platform === 'win32') ? 'py' : 'python3' + await terminal.run(pythonCommand, ['-m', 'venv', name], { + cwd: fullPath + }) + const pipCommand = path.join(fullPath, name, 'bin', 'pip') + if (packages && packages.length) { + await terminal.run(pipCommand, ['install', ...packages], { + cwd: fullPath + }) + } + if (requirementsFiles && requirementsFiles.length) { + const options = requirementsFiles.flatMap((file) => ['-r', file]) + await terminal.run(pipCommand, ['install', ...options], { + cwd: fullPath + }) + } +} + async function copyTemplateDirectory (git, fullPath, name, templates, data) { const binaryExtensions = ['.bin', '.dat', '.png', '.tim'] const ignoredFiles = ['PSX.Dev-README.md'] @@ -620,6 +643,20 @@ const templates = { ], { projectName: name, isCMake: true } ) + progressReporter.report({ message: 'Setting up Python environment...' }) + await createPythonEnv( + fullPath, + 'env', + [], + [ + path.join( + fullPath, + 'ps1-bare-metal', + 'tools', + 'requirements.txt' + ) + ] + ) } }, cmake_cube: { @@ -659,6 +696,20 @@ const templates = { ], { projectName: name, isCMake: true } ) + progressReporter.report({ message: 'Setting up Python environment...' }) + await createPythonEnv( + fullPath, + 'env', + [], + [ + path.join( + fullPath, + 'ps1-bare-metal', + 'tools', + 'requirements.txt' + ) + ] + ) } }, psyq_cube: { @@ -731,7 +782,6 @@ const templates = { netyarozeTemplate, progressReporter ) - await copyTemplateDirectory( git, fullPath, @@ -787,7 +837,7 @@ exports.createProjectFromTemplate = async function (tools, options) { let rejecter const { progressReporter, progressResolver } = await progressNotification.notify( - 'Creating project...', + 'Creating project', 'Creating directories...' ) const ret = new Promise((resolve, reject) => { @@ -806,6 +856,14 @@ exports.createProjectFromTemplate = async function (tools, options) { }) return ret } +exports.createPythonEnv = async function (options) { + await createPythonEnv( + options.path, + options.name, + options.packages, + options.requirementsFiles + ) +} exports.setExtensionUri = (uri) => { extensionUri = uri From 065c7a118b8fc07e4699f81fadb6a0c523857e53 Mon Sep 17 00:00:00 2001 From: spicyjpeg Date: Mon, 14 Oct 2024 11:11:30 +0200 Subject: [PATCH 05/29] More updates to CMake bare metal templates --- .../bare-metal/cmake-cube/CMakeLists.txt | 63 ++++++++---------- .../cmake-cube/assets/fontPalette.dat | Bin 32 -> 0 bytes .../cmake-cube/assets/fontTexture.dat | Bin 2688 -> 0 bytes .../bare-metal/cmake-cube/src/main.c | 11 ++- .../bare-metal/empty-cmake/src/main.c | 7 +- 5 files changed, 36 insertions(+), 45 deletions(-) delete mode 100644 tools/vscode-extension/templates/bare-metal/cmake-cube/assets/fontPalette.dat delete mode 100644 tools/vscode-extension/templates/bare-metal/cmake-cube/assets/fontTexture.dat diff --git a/tools/vscode-extension/templates/bare-metal/cmake-cube/CMakeLists.txt b/tools/vscode-extension/templates/bare-metal/cmake-cube/CMakeLists.txt index 13e8b16b0..05bef1ee0 100644 --- a/tools/vscode-extension/templates/bare-metal/cmake-cube/CMakeLists.txt +++ b/tools/vscode-extension/templates/bare-metal/cmake-cube/CMakeLists.txt @@ -40,40 +40,8 @@ target_include_directories( ps1-bare-metal/src/libc ) -# Define a helper function to embed the contents of a file into the executable. -function(addBinaryFile target name path) - set(_file "${PROJECT_BINARY_DIR}/includes/${target}_${name}.s") - cmake_path(ABSOLUTE_PATH path OUTPUT_VARIABLE _path) - - # Generate an assembly listing that uses the .incbin directive to embed the - # file and add it to the executable's list of source files. This may look - # hacky, but it works and lets us easily customize the symbol name (i.e. the - # name of the "array" that will contain the file's data). - file( - CONFIGURE - OUTPUT "${_file}" - CONTENT [[ -.section .data.${name}, "aw" -.balign 8 - -.global ${name} -.type ${name}, @object -.size ${name}, (${name}_end - ${name}) - -${name}: - .incbin "${_path}" -${name}_end: -]] - ESCAPE_QUOTES - NEWLINE_STYLE LF - ) - - target_sources(${target} PRIVATE "${_file}") - set_source_files_properties("${_file}" PROPERTIES OBJECT_DEPENDS "${_path}") -endfunction() - -# Create the main executable. You may add more source files by listing them -# here, or other images or files by adding calls to addBinaryFile(). +# Compile the main executable. You may add more source files by listing them +# here. add_executable( {{projectName}} src/font.c @@ -83,8 +51,28 @@ add_executable( ) target_link_libraries({{projectName}} PRIVATE common) -addBinaryFile({{projectName}} fontTexture assets/fontTexture.dat) -addBinaryFile({{projectName}} fontPalette assets/fontPalette.dat) +# Define a CMake macro that invokes convertImage.py in order to generate VRAM +# texture data from an image file. +function(convertImage input bpp) + add_custom_command( + OUTPUT ${ARGN} + DEPENDS "${PROJECT_SOURCE_DIR}/${input}" + COMMAND + "${Python3_EXECUTABLE}" + "${PROJECT_SOURCE_DIR}/ps1-bare-metal/tools/convertImage.py" + -b ${bpp} + "${PROJECT_SOURCE_DIR}/${input}" + ${ARGN} + VERBATIM + ) +endfunction() + +# Convert the font spritesheet to a 4bpp texture and palette, then embed them +# into the executable. The addBinaryFile() macro is defined in setup.cmake; you +# may call it multiple times to embed other data into the binary. +convertImage(assets/font.png 4 fontTexture.dat fontPalette.dat) +addBinaryFile({{projectName}} fontTexture "${PROJECT_BINARY_DIR}/fontTexture.dat") +addBinaryFile({{projectName}} fontPalette "${PROJECT_BINARY_DIR}/fontPalette.dat") # Add a step to run convertExecutable.py after the executable is compiled in # order to convert it into a PS1 executable. By default all custom commands run @@ -96,6 +84,7 @@ add_custom_command( COMMAND "${Python3_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/ps1-bare-metal/tools/convertExecutable.py" - "$" {{projectName}}.psexe + "$" + {{projectName}}.psexe VERBATIM ) diff --git a/tools/vscode-extension/templates/bare-metal/cmake-cube/assets/fontPalette.dat b/tools/vscode-extension/templates/bare-metal/cmake-cube/assets/fontPalette.dat deleted file mode 100644 index aeefa9ad7e24bc17d3d3e0fee1d5797327ca59fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32 QcmZQz_+Q^LfdMA~07?Y{lK=n! diff --git a/tools/vscode-extension/templates/bare-metal/cmake-cube/assets/fontTexture.dat b/tools/vscode-extension/templates/bare-metal/cmake-cube/assets/fontTexture.dat deleted file mode 100644 index 48f9cfc28da80d5f835b14759ce4439296b00664..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2688 zcmchZQF0|A2t~maXs-a=|03sHXuI>0sZ`C+5Fd?jMFg>8X3pUEg_zC1=}Tv6mi(Yv z1(KN$EtzpE%iMEWBWzBaixuu}pis`iq@){Ns-sxTJx5IbWNv(fp=a7$yB_?!HvZ9Q zgM&wi+~QkYUXaDgLpsj0Ho!tWqQaC^$2kWo|AG7Y=^u9-9P;BKYHDK`@nhanD4*^B z2xuQouK@efcxR6qq0T5SVd@kJ&82CofD{i2-#$~EVQb{x2)XmtG``|cgqT1lTc;8; zM=Bpd4bU>=lhIXh!P12Oz9b3&b2`&pZOlFRd}273~>goO5j_$ zQRR^9$LBYSAI8o}^AnqKJdQ{t2z-mHl#r@W^@3BcyJVDOgCAViBtJ8ksfa8g9W~G+ zFl9*AeFjes(RgZL*(4{I%D^Ovfq{&&@hddVNNxgv$*Rrp#?wq1X!qm4@Y-4fcnfJP zL4K|3cg6o|08kV-@l@edJC@u^x2fP&&Gw0&x`ah^b-H$>>{cRJS!uaosEGeat2*m& zcl#JBpP7>`l}_|jidqCo(UIQ~q^=)E&dxIMuQfC|)5$}}4X)ynCG;cIBx_Aa135-pI=jr}}pYGsQ3;e)+ zumlZ%T|UqcK3KjvN~ji0nvZ%I(eB+>ewBZg1OJ^u$SAJmz2GdX@5|(g*|BPRS4|?6 z{FIrJ1k<5QD_s$_pvCG|aO;uh&?}d2ft?)GeO^4pRG|)|77OP-_?2+<;G_oPMk%6C;-jg}L}vs^vje;nQIsc&y!D2o*n7xbbq) z{aF50O-S!yzl8NF%727WGQGns1Z0KLf*L~Oj zq&%+t;;kTBr%PF@%q#8w3|Z?+w=3S2q)a8VG2q>g#Q70F k)-BJL0qf3cUj3!2F?IPTDv{nvsF;LL0t|)BjQ>M_0NNI3Y5)KL diff --git a/tools/vscode-extension/templates/bare-metal/cmake-cube/src/main.c b/tools/vscode-extension/templates/bare-metal/cmake-cube/src/main.c index b01fdada7..673864427 100644 --- a/tools/vscode-extension/templates/bare-metal/cmake-cube/src/main.c +++ b/tools/vscode-extension/templates/bare-metal/cmake-cube/src/main.c @@ -1,13 +1,12 @@ /* - * This template is based on the following examples: + * This program is a simple demo that displays a 3D cube and some text (using + * the font spritesheet in the assets directory), based on the following + * examples: * https://github.com/spicyjpeg/ps1-bare-metal/blob/main/src/06_fonts/main.c * https://github.com/spicyjpeg/ps1-bare-metal/blob/main/src/08_spinningCube/main.c * - * If you wish to modify the font image in the assets directory or add more - * images, you may use the ps1-bare-metal/tools/convertImage.py script to - * generate the texture and palette files to embed into the executable. Note - * that the script requires additional dependencies to run; see - * ps1-bare-metal/tools/requirements.txt for information on how to install them. + * For further information on the contents of the ps1-bare-metal submodule, see: + * https://github.com/spicyjpeg/ps1-bare-metal */ #include diff --git a/tools/vscode-extension/templates/bare-metal/empty-cmake/src/main.c b/tools/vscode-extension/templates/bare-metal/empty-cmake/src/main.c index f956df06e..9de349546 100644 --- a/tools/vscode-extension/templates/bare-metal/empty-cmake/src/main.c +++ b/tools/vscode-extension/templates/bare-metal/empty-cmake/src/main.c @@ -6,9 +6,12 @@ * back of the console or to another interface. Additionally, most emulators can * log calls to printf() and display the output in their log window. * - * For a variant of this project that prints directly to the PS1's serial port - * instead of using the kernel, see: + * A variant of this project that prints directly to the PS1's serial port + * instead of using the kernel is available here: * https://github.com/spicyjpeg/ps1-bare-metal/blob/main/src/00_helloWorld/main.c + * + * For further information on the contents of the ps1-bare-metal submodule, see: + * https://github.com/spicyjpeg/ps1-bare-metal */ #define BIOS_API_TABLE ((void **) 0x80000200) From 5c167be68e755b42f1a9cc38e39bcf3524a6a810 Mon Sep 17 00:00:00 2001 From: spicyjpeg Date: Fri, 18 Oct 2024 20:58:43 +0200 Subject: [PATCH 06/29] Use execFile(), add Python detection workaround --- tools/vscode-extension/package.json | 2 +- tools/vscode-extension/pcsx-redux.js | 6 +- tools/vscode-extension/tools.js | 108 ++++++++++++++------------- 3 files changed, 62 insertions(+), 54 deletions(-) diff --git a/tools/vscode-extension/package.json b/tools/vscode-extension/package.json index 3487419e1..ab96b49c3 100644 --- a/tools/vscode-extension/package.json +++ b/tools/vscode-extension/package.json @@ -116,6 +116,6 @@ "open-file-explorer": "^1.0.2", "simple-git": "^3.16.1", "unzipper": "^0.10.11", - "which": "^3.0.0" + "which": "^5.0.0" } } diff --git a/tools/vscode-extension/pcsx-redux.js b/tools/vscode-extension/pcsx-redux.js index 36882f0de..318ebd09f 100644 --- a/tools/vscode-extension/pcsx-redux.js +++ b/tools/vscode-extension/pcsx-redux.js @@ -13,8 +13,8 @@ const dmg = require('dmg') const dmgMount = util.promisify(dmg.mount) const dmgUnmount = util.promisify(dmg.unmount) const terminal = require('./terminal.js') -const execAsync = require('node:child_process').exec -const exec = util.promisify(execAsync) +const execFileAsync = require('node:child_process').execFile +const execFile = util.promisify(execFileAsync) const os = require('node:os') const updateInfo = { @@ -97,7 +97,7 @@ exports.install = async () => { 'https://aka.ms/vs/17/release/vc_redist.x64.exe', fullPath ) - await exec(fullPath) + await execFile(fullPath) } } diff --git a/tools/vscode-extension/tools.js b/tools/vscode-extension/tools.js index f69a671b2..a72e0b911 100644 --- a/tools/vscode-extension/tools.js +++ b/tools/vscode-extension/tools.js @@ -2,11 +2,12 @@ const vscode = require('vscode') const util = require('node:util') -const execAsync = require('node:child_process').exec -const exec = util.promisify(execAsync) +const execFileAsync = require('node:child_process').execFile +const execFile = util.promisify(execFileAsync) const terminal = require('./terminal.js') const pcsxRedux = require('./pcsx-redux.js') const fs = require('fs-extra') +const which = require('which') const downloader = require('./downloader.js') const unzipper = require('unzipper') const path = require('node:path') @@ -26,16 +27,16 @@ async function checkInstalled (name) { return tools[name].installed } -function checkSimpleCommand (command) { - return new Promise((resolve) => { - execAsync(command, (error) => { - if (error) { - resolve(false) - } else { - resolve(true) - } - }) - }) +async function checkCommands (commands, args) { + for (const command of commands) { + try { + await execFile(command, args) + } catch (error) { + continue + } + return true + } + return false } let mipsInstalling = false @@ -166,13 +167,6 @@ async function installToolchain () { } } -function checkToolchain () { - return Promise.any([ - exec('mipsel-linux-gnu-g++ --version'), - exec('mipsel-none-elf-g++ --version') - ]) -} - async function installGDB () { switch (process.platform) { case 'win32': @@ -309,7 +303,7 @@ async function installCMake () { asset.browser_download_url.split('/').pop() ) await downloader.downloadFile(asset.browser_download_url, filename) - await exec(`start ${filename}`) + await execFile('start', [filename]) requiresReboot = true break case 'linux': @@ -385,7 +379,7 @@ async function installGit () { asset.browser_download_url.split('/').pop() ) await downloader.downloadFile(asset.browser_download_url, filename) - await exec(filename) + await execFile(filename) requiresReboot = true break } @@ -428,7 +422,7 @@ async function installPython () { url.split('/').pop() ) await downloader.downloadFile(url, filename) - await exec(filename) + await execFile(filename) requiresReboot = true break case 'linux': @@ -460,21 +454,34 @@ async function installPython () { } } -function checkPython () { - switch (process.platform) { - case 'win32': - // On Windows "python" and "python3" are aliased to a script that opens - // the Microsoft Store by default, so we must check for the "py" launcher - // provided by the official installers instead. - // TODO: try to detect other Python installations that do not come with - // the py launcher (e.g. ones from MSys2) - return checkSimpleCommand('py -3 --version') - default: - return Promise.any([ - exec('python --version'), - exec('python3 --version') - ]) +async function checkPython () { + /* + * Windows ships by default with fake (zero-byte) 'python' and 'python3' + * executables that launch the Microsoft Store when invoked, so a manual PATH + * scan before running 'python --version' is needed to avoid executing them. + * + * IMPORTANT: this assumes that, if Python is installed but the dummy files + * are still listed in PATH before the real installation, the project's build + * system will also be able to detect and ignore them (rather than blindly + * executing 'python'). This is currently the case for the CMake-based + * templates. + */ + for (const command of ['python3', 'python', 'py']) { + const matches = await which(command, { all: true }) + for (const fullPath of matches) { + const stats = await fs.stat(fullPath) + if (!stats.size && !stats.isSymbolicLink()) { + continue + } + try { + await execFile(fullPath, ['--version']) + } catch (error) { + continue + } + return true + } } + return false } function unpackPsyq (destination) { @@ -504,20 +511,20 @@ const tools = { mips: { type: 'internal', install: installMips, - check: () => checkSimpleCommand('mips --version') + check: () => checkCommands(['mips'], ['--version']) }, apt: { type: 'internal', - check: () => checkSimpleCommand('apt-get --version') + check: () => checkCommands(['apt-get'], ['--version']) }, trizen: { type: 'internal', - check: () => checkSimpleCommand('trizen --version') + check: () => checkCommands(['trizen'], ['--version']) }, brew: { type: 'internal', install: 'https://brew.sh/', - check: () => checkSimpleCommand('brew --version') + check: () => checkCommands(['brew'], ['--version']) }, toolchain: { type: 'package', @@ -525,7 +532,10 @@ const tools = { description: 'The toolchain used to compile code for the PlayStation 1', homepage: 'https://gcc.gnu.org/', install: installToolchain, - check: checkToolchain + check: () => checkCommands( + ['mipsel-none-elf-g++', 'mipsel-linux-gnu-g++'], + ['--version'] + ) }, gdb: { type: 'package', @@ -533,7 +543,10 @@ const tools = { description: 'The tool to debug code for the PlayStation 1', homepage: 'https://www.sourceware.org/gdb/', install: installGDB, - check: () => checkGDB() + check: () => checkCommands( + [(process.platform === 'darwin') ? 'gdb' : 'gdb-multiarch'], + ['--version'] + ) }, make: { type: 'package', @@ -541,7 +554,7 @@ const tools = { description: 'Build code and various targets with this tool', homepage: 'https://www.gnu.org/software/make/', install: installMake, - check: () => checkSimpleCommand('make --version') + check: () => checkCommands(['make'], ['--version']) }, cmake: { type: 'package', @@ -549,7 +562,7 @@ const tools = { description: 'A more advanced building tool for projects that require it', homepage: 'https://cmake.org/', install: installCMake, - check: () => checkSimpleCommand('cmake --version') + check: () => checkCommands(['cmake'], ['--version']) }, git: { type: 'package', @@ -558,7 +571,7 @@ const tools = { 'Tool to maintain your code, and initialize your project templates', homepage: 'https://git-scm.com/', install: installGit, - check: () => checkSimpleCommand('git --version') + check: () => checkCommands(['git'], ['--version']) }, python: { type: 'package', @@ -636,11 +649,6 @@ function checkLocalFile (filename) { }) } -function checkGDB () { - if (process.platform === 'darwin') return checkSimpleCommand('gdb --version') - return checkSimpleCommand('gdb-multiarch --version') -} - exports.refreshAll = async () => { for (const [, tool] of Object.entries(tools)) { if (tool.check) { From c08ef0588b75e2330bee84016f6f2cc57f519785 Mon Sep 17 00:00:00 2001 From: spicyjpeg Date: Sat, 19 Oct 2024 23:04:03 +0200 Subject: [PATCH 07/29] Actually fix Python install detection on Windows --- tools/vscode-extension/tools.js | 72 ++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/tools/vscode-extension/tools.js b/tools/vscode-extension/tools.js index a72e0b911..58f6fd11b 100644 --- a/tools/vscode-extension/tools.js +++ b/tools/vscode-extension/tools.js @@ -47,7 +47,8 @@ async function installMips () { mipsInstalling = true try { await terminal.run('powershell', [ - '-c "& { iwr -UseBasicParsing https://bit.ly/mips-ps1 | iex }"' + '-c', + '& { iwr -UseBasicParsing https://raw.githubusercontent.com/grumpycoders/pcsx-redux/main/mips.ps1 | iex }' ]) requiresReboot = true vscode.window.showInformationMessage( @@ -455,33 +456,56 @@ async function installPython () { } async function checkPython () { - /* - * Windows ships by default with fake (zero-byte) 'python' and 'python3' - * executables that launch the Microsoft Store when invoked, so a manual PATH - * scan before running 'python --version' is needed to avoid executing them. - * - * IMPORTANT: this assumes that, if Python is installed but the dummy files - * are still listed in PATH before the real installation, the project's build - * system will also be able to detect and ignore them (rather than blindly - * executing 'python'). This is currently the case for the CMake-based - * templates. - */ - for (const command of ['python3', 'python', 'py']) { - const matches = await which(command, { all: true }) - for (const fullPath of matches) { - const stats = await fs.stat(fullPath) - if (!stats.size && !stats.isSymbolicLink()) { - continue - } + switch (process.platform) { + case 'win32': + /* + * We cannot simply run 'python --version' here as Windows ships by + * default with fake (zero-byte) 'python' and 'python3' executables in its + * PATH. These files are actually links to UWP apps, implemented using a + * specific NTFS reparse tag. If Python is installed from the Microsoft + * Store they behave as if they were symlinks to the actual executables; + * if not, however, attempting to run them will result in the store + * popping up and prompting the user to install Python. + * + * A kludge is thus needed here in order to prevent this from happening. + * We'll first check for any UWP Python installations, then search PATH + * manually and skip the fake binaries if none was found. This ensures + * both UWP and non-UWP installs will be detected somewhat reliably. + * + * IMPORTANT: this assumes that the project's build system will also be + * able to detect and ignore the fake executables (rather than e.g. + * blindly executing 'python'). This is currently the case for the + * CMake-based templates. + */ + let hasUWPPython try { - await execFile(fullPath, ['--version']) + const result = await execFile('powershell', [ + '-c', + 'Get-AppxPackage -Name PythonSoftwareFoundation.Python.*' + ]) + hasUWPPython = (result.stdout.trim() !== '') } catch (error) { - continue + hasUWPPython = false } - return true - } + for (const command of ['python3', 'python', 'py']) { + const matches = await which(command, { all: true }) + for (const fullPath of matches) { + const stats = await fs.stat(fullPath) + if (!stats.size && !hasUWPPython) { + continue + } + try { + await execFile(fullPath, ['--version']) + } catch (error) { + continue + } + return true + } + } + return false + default: + return checkCommands(['python3', 'python'], ['--version']) } - return false } function unpackPsyq (destination) { From 3ada28e39bf8bd92582a6a5a68e4fab99ff7aa4f Mon Sep 17 00:00:00 2001 From: nicolasnoble Date: Sun, 20 Oct 2024 05:58:52 +0000 Subject: [PATCH 08/29] [Chores] Format code --- src/cdrom/cdriso.cc | 10 +- src/core/DynaRec_aa64/gte_aa64.cc | 4 +- src/core/DynaRec_aa64/recompiler.h | 14 +- src/core/DynaRec_x64/gte_x64.cc | 4 +- src/core/DynaRec_x64/recompiler.h | 14 +- src/core/decode_xa.cc | 4 +- src/core/disr3000a.cc | 2 +- src/core/gte.h | 2 +- src/core/logger.h | 2 +- src/core/mdec.cc | 2 +- src/core/patchmanager.cc | 3 +- src/core/patchmanager.h | 1 + src/core/pgxp_cpu.cc | 14 +- src/core/pgxp_debug.cc | 2 +- src/core/pgxp_debug.h | 8 +- src/core/pgxp_gte.cc | 2 +- src/core/pgxp_value.h | 2 +- src/core/psxcounters.cc | 2 +- src/core/psxemulator.cc | 2 +- src/core/psxinterpreter.cc | 6 +- src/core/r3000a.h | 8 +- src/core/web-server.cc | 14 +- src/gui/gui.h | 18 +-- src/gui/widgets/assembly.cc | 3 +- src/gui/widgets/memory_observer.cc | 6 +- src/gui/widgets/patches.cc | 19 ++- src/gui/widgets/sio1.cc | 3 +- src/lua/luafile.cc | 4 +- src/mips/common/crt0/cxxglue.c | 3 +- src/mips/common/hardware/gpu.h | 5 +- src/mips/common/hardware/sio1.c | 3 +- src/mips/common/syscalls/syscalls.h | 4 +- src/mips/cxxhello/main.cpp | 3 +- src/mips/helloworld/main/main.c | 3 +- src/mips/openbios/cdrom/cdrom.c | 6 +- src/mips/openbios/cdrom/filesystem.c | 6 +- src/mips/openbios/cdrom/helpers.c | 6 +- src/mips/openbios/fileio/filesystem.c | 4 +- src/mips/openbios/gpu/gpu.c | 3 +- src/mips/openbios/kernel/globals.h | 4 +- src/mips/openbios/kernel/handlers.c | 3 +- src/mips/openbios/kernel/psxexe.c | 6 +- src/mips/openbios/patches/patches.c | 3 +- src/mips/openbios/sio0/card.c | 6 +- src/mips/openbios/sio0/driver.c | 22 ++- src/mips/openbios/uC-sdk-glue/BoardInit.c | 5 +- .../examples/cdrom-loader/cdrom-loader.cpp | 9 +- src/mips/psyqo-paths/src/cdrom-loader.cpp | 6 +- src/mips/psyqo/cdrom-device.hh | 4 +- src/mips/psyqo/examples/bezier/bezier.cpp | 5 +- src/mips/psyqo/examples/cube/cube.cpp | 111 ++++++--------- src/mips/psyqo/examples/hello/hello.cpp | 1 - src/mips/psyqo/examples/tetris/gameover.cpp | 3 +- src/mips/psyqo/examples/tetris/pieces.cpp | 1 - src/mips/psyqo/examples/tetris/sound.cpp | 8 +- src/mips/psyqo/gte-registers.hh | 126 +++++++++--------- src/mips/psyqo/kernel.hh | 4 +- src/mips/psyqo/primitive-concept.hh | 4 +- src/mips/psyqo/src/cdrom-device-cdda.cpp | 9 +- .../psyqo/src/cdrom-device-muteunmute.cpp | 6 +- src/mips/psyqo/src/cdrom-device-reset.cpp | 3 +- src/mips/psyqo/src/cdrom-device-toc.cpp | 6 +- src/mips/psyqo/src/ordering-table.cpp | 3 +- src/mips/psyqo/src/xprintf.c | 14 +- src/mips/tests/cop0/exceptions.cpp | 4 +- src/mips/ucl-demo/ucl-demo.cpp | 2 +- src/support/opengl.h | 2 +- src/support/protobuf.h | 8 +- src/support/settings.h | 3 +- src/support/uvfile.cc | 15 +-- src/support/uvfile.h | 5 +- src/support/version-windows.cc | 3 +- 72 files changed, 275 insertions(+), 360 deletions(-) diff --git a/src/cdrom/cdriso.cc b/src/cdrom/cdriso.cc index cf6e7550f..46ff24dbf 100644 --- a/src/cdrom/cdriso.cc +++ b/src/cdrom/cdriso.cc @@ -248,10 +248,12 @@ uint8_t *PCSX::CDRIso::getBuffer() { void PCSX::CDRIso::printTracks() { for (int i = 1; i <= m_numtracks; i++) { - PCSX::g_system->printf( - _("Track %.2d (%s) - Start %.2d:%.2d:%.2d, Length %.2d:%.2d:%.2d\n"), i, - (m_ti[i].type == TrackType::DATA ? "DATA" : m_ti[i].cddatype == trackinfo::CCDDA ? "CZDA" : "CDDA"), - m_ti[i].start.m, m_ti[i].start.s, m_ti[i].start.f, m_ti[i].length.m, m_ti[i].length.s, m_ti[i].length.f); + PCSX::g_system->printf(_("Track %.2d (%s) - Start %.2d:%.2d:%.2d, Length %.2d:%.2d:%.2d\n"), i, + (m_ti[i].type == TrackType::DATA ? "DATA" + : m_ti[i].cddatype == trackinfo::CCDDA ? "CZDA" + : "CDDA"), + m_ti[i].start.m, m_ti[i].start.s, m_ti[i].start.f, m_ti[i].length.m, m_ti[i].length.s, + m_ti[i].length.f); } } diff --git a/src/core/DynaRec_aa64/gte_aa64.cc b/src/core/DynaRec_aa64/gte_aa64.cc index c6a1bdac8..af325923b 100644 --- a/src/core/DynaRec_aa64/gte_aa64.cc +++ b/src/core/DynaRec_aa64/gte_aa64.cc @@ -21,8 +21,8 @@ #if defined(DYNAREC_AA64) #include "core/gte.h" -#define COP2_CONTROL_OFFSET(reg) ((uintptr_t)&m_regs.CP2C.r[(reg)] - (uintptr_t)this) -#define COP2_DATA_OFFSET(reg) ((uintptr_t)&m_regs.CP2D.r[(reg)] - (uintptr_t)this) +#define COP2_CONTROL_OFFSET(reg) ((uintptr_t) & m_regs.CP2C.r[(reg)] - (uintptr_t)this) +#define COP2_DATA_OFFSET(reg) ((uintptr_t) & m_regs.CP2D.r[(reg)] - (uintptr_t)this) void DynaRecCPU::recCOP2(uint32_t code) { const auto func = m_recGTE[code & 0x3f]; // Look up the opcode in our decoding LUT diff --git a/src/core/DynaRec_aa64/recompiler.h b/src/core/DynaRec_aa64/recompiler.h index cf7d184a0..8cef44117 100644 --- a/src/core/DynaRec_aa64/recompiler.h +++ b/src/core/DynaRec_aa64/recompiler.h @@ -33,13 +33,13 @@ #include "spu/interface.h" #include "tracy/public/tracy/Tracy.hpp" -#define HOST_REG_CACHE_OFFSET(x) ((uintptr_t)&m_hostRegisterCache[(x)] - (uintptr_t)this) -#define GPR_OFFSET(x) ((uintptr_t)&m_regs.GPR.r[(x)] - (uintptr_t)this) -#define COP0_OFFSET(x) ((uintptr_t)&m_regs.CP0.r[(x)] - (uintptr_t)this) -#define PC_OFFSET ((uintptr_t)&m_regs.pc - (uintptr_t)this) -#define LO_OFFSET ((uintptr_t)&m_regs.GPR.n.lo - (uintptr_t)this) -#define HI_OFFSET ((uintptr_t)&m_regs.GPR.n.hi - (uintptr_t)this) -#define CYCLE_OFFSET ((uintptr_t)&m_regs.cycle - (uintptr_t)this) +#define HOST_REG_CACHE_OFFSET(x) ((uintptr_t) & m_hostRegisterCache[(x)] - (uintptr_t)this) +#define GPR_OFFSET(x) ((uintptr_t) & m_regs.GPR.r[(x)] - (uintptr_t)this) +#define COP0_OFFSET(x) ((uintptr_t) & m_regs.CP0.r[(x)] - (uintptr_t)this) +#define PC_OFFSET ((uintptr_t) & m_regs.pc - (uintptr_t)this) +#define LO_OFFSET ((uintptr_t) & m_regs.GPR.n.lo - (uintptr_t)this) +#define HI_OFFSET ((uintptr_t) & m_regs.GPR.n.hi - (uintptr_t)this) +#define CYCLE_OFFSET ((uintptr_t) & m_regs.cycle - (uintptr_t)this) #undef _PC_ #undef _Op_ diff --git a/src/core/DynaRec_x64/gte_x64.cc b/src/core/DynaRec_x64/gte_x64.cc index 70865339c..a61d3920c 100644 --- a/src/core/DynaRec_x64/gte_x64.cc +++ b/src/core/DynaRec_x64/gte_x64.cc @@ -21,8 +21,8 @@ #if defined(DYNAREC_X86_64) #include "core/gte.h" -#define COP2_CONTROL_OFFSET(reg) ((uintptr_t)&m_regs.CP2C.r[(reg)] - (uintptr_t)this) -#define COP2_DATA_OFFSET(reg) ((uintptr_t)&m_regs.CP2D.r[(reg)] - (uintptr_t)this) +#define COP2_CONTROL_OFFSET(reg) ((uintptr_t) & m_regs.CP2C.r[(reg)] - (uintptr_t)this) +#define COP2_DATA_OFFSET(reg) ((uintptr_t) & m_regs.CP2D.r[(reg)] - (uintptr_t)this) void DynaRecCPU::recCOP2(uint32_t code) { const auto func = m_recGTE[m_regs.code & 0x3F]; // Look up the opcode in our decoding LUT diff --git a/src/core/DynaRec_x64/recompiler.h b/src/core/DynaRec_x64/recompiler.h index 407659686..6ae789702 100644 --- a/src/core/DynaRec_x64/recompiler.h +++ b/src/core/DynaRec_x64/recompiler.h @@ -36,13 +36,13 @@ #include "spu/interface.h" #include "tracy/public/tracy/Tracy.hpp" -#define HOST_REG_CACHE_OFFSET(x) ((uintptr_t)&m_hostRegisterCache[(x)] - (uintptr_t)this) -#define GPR_OFFSET(x) ((uintptr_t)&m_regs.GPR.r[(x)] - (uintptr_t)this) -#define COP0_OFFSET(x) ((uintptr_t)&m_regs.CP0.r[(x)] - (uintptr_t)this) -#define PC_OFFSET ((uintptr_t)&m_regs.pc - (uintptr_t)this) -#define LO_OFFSET ((uintptr_t)&m_regs.GPR.n.lo - (uintptr_t)this) -#define HI_OFFSET ((uintptr_t)&m_regs.GPR.n.hi - (uintptr_t)this) -#define CYCLE_OFFSET ((uintptr_t)&m_regs.cycle - (uintptr_t)this) +#define HOST_REG_CACHE_OFFSET(x) ((uintptr_t) & m_hostRegisterCache[(x)] - (uintptr_t)this) +#define GPR_OFFSET(x) ((uintptr_t) & m_regs.GPR.r[(x)] - (uintptr_t)this) +#define COP0_OFFSET(x) ((uintptr_t) & m_regs.CP0.r[(x)] - (uintptr_t)this) +#define PC_OFFSET ((uintptr_t) & m_regs.pc - (uintptr_t)this) +#define LO_OFFSET ((uintptr_t) & m_regs.GPR.n.lo - (uintptr_t)this) +#define HI_OFFSET ((uintptr_t) & m_regs.GPR.n.hi - (uintptr_t)this) +#define CYCLE_OFFSET ((uintptr_t) & m_regs.cycle - (uintptr_t)this) #undef _PC_ #undef _Op_ diff --git a/src/core/decode_xa.cc b/src/core/decode_xa.cc index ebde9554e..a7bcbf145 100644 --- a/src/core/decode_xa.cc +++ b/src/core/decode_xa.cc @@ -23,7 +23,7 @@ #include "core/decode_xa.h" -//#define FIXED +// #define FIXED #define NOT(_X_) (!(_X_)) #define XACLAMP(_X_, _MI_, _MA_) \ @@ -274,7 +274,7 @@ typedef struct { #define SUB_SUB_VIDEO (1 << 1) // contains video #define SUB_SUB_EOR (1 << 0) // end of record -#define AUDIO_CODING_GET_STEREO(_X_) ((_X_)&3) +#define AUDIO_CODING_GET_STEREO(_X_) ((_X_) & 3) #define AUDIO_CODING_GET_FREQ(_X_) (((_X_) >> 2) & 3) #define AUDIO_CODING_GET_BPS(_X_) (((_X_) >> 4) & 3) #define AUDIO_CODING_GET_EMPHASIS(_X_) (((_X_) >> 6) & 1) diff --git a/src/core/disr3000a.cc b/src/core/disr3000a.cc index 2d1db7c99..05b886ccd 100644 --- a/src/core/disr3000a.cc +++ b/src/core/disr3000a.cc @@ -68,7 +68,7 @@ const char *PCSX::Disasm::s_disRNameCP0[] = { #define declare(n) \ void PCSX::Disasm::n(uint32_t code, uint32_t nextCode, uint32_t pc, bool *skipNext, bool *delaySlotNext) -#define _Funct_ ((code)&0x3F) // The funct part of the instruction register +#define _Funct_ ((code) & 0x3F) // The funct part of the instruction register #define _Rd_ ((code >> 11) & 0x1F) // The rd part of the instruction register #define _Rt_ ((code >> 16) & 0x1F) // The rt part of the instruction register #define _Rs_ ((code >> 21) & 0x1F) // The rs part of the instruction register diff --git a/src/core/gte.h b/src/core/gte.h index 887640a88..d367d095e 100644 --- a/src/core/gte.h +++ b/src/core/gte.h @@ -27,7 +27,7 @@ #undef NCCS #define gteoB (PCSX::g_emulator->m_cpu->m_regs.GPR.r[_Rs_] + _Imm_) -#define gteop(instruction) ((instruction)&0x1ffffff) +#define gteop(instruction) ((instruction) & 0x1ffffff) namespace PCSX { diff --git a/src/core/logger.h b/src/core/logger.h index b725c5275..66817b100 100644 --- a/src/core/logger.h +++ b/src/core/logger.h @@ -54,7 +54,7 @@ enum class LogClass : unsigned { template struct Logger { template - static void Log(const char *format, const Args &... args) { + static void Log(const char *format, const Args &...args) { if (!enabled) return; std::string s = fmt::sprintf(format, args...); g_system->log(logClass, std::move(s)); diff --git a/src/core/mdec.cc b/src/core/mdec.cc index 9e3916997..fffd09b26 100644 --- a/src/core/mdec.cc +++ b/src/core/mdec.cc @@ -248,7 +248,7 @@ unsigned short *PCSX::MDEC::rl2blk(int *blk, unsigned short *mdec_rl) { // B = 1.000 * (Y) + 1.765 * (Cb - 128) #define MULR(a) ((1434 * (a))) #define MULB(a) ((1807 * (a))) -#define MULG2(a, b) ((-351 * (a)-728 * (b))) +#define MULG2(a, b) ((-351 * (a) - 728 * (b))) #define MULY(a) ((a) << 10) #define MAKERGB15(r, g, b, a) (SWAP_LE16(a | ((b) << 10) | ((g) << 5) | (r))) diff --git a/src/core/patchmanager.cc b/src/core/patchmanager.cc index 10edf4cf8..bbd36c504 100644 --- a/src/core/patchmanager.cc +++ b/src/core/patchmanager.cc @@ -18,8 +18,9 @@ ***************************************************************************/ #include "core/patchmanager.h" -#include "core/psxmem.h" + #include "core/psxemulator.h" +#include "core/psxmem.h" #include "core/r3000a.h" int PCSX::PatchManager::registerPatch(uint32_t address, Patch::Type type) { diff --git a/src/core/patchmanager.h b/src/core/patchmanager.h index a397a8e67..ed884223d 100644 --- a/src/core/patchmanager.h +++ b/src/core/patchmanager.h @@ -20,6 +20,7 @@ #pragma once #include + #include namespace PCSX { diff --git a/src/core/pgxp_cpu.cc b/src/core/pgxp_cpu.cc index 6bdd90710..bf6aab798 100644 --- a/src/core/pgxp_cpu.cc +++ b/src/core/pgxp_cpu.cc @@ -15,7 +15,7 @@ PGXP_value* const g_CP0_reg = s_CP0_reg_mem; // Instruction register decoding #define op(_instr) (_instr >> 26) // The op part of the instruction register -#define func(_instr) ((_instr)&0x3F) // The funct part of the instruction register +#define func(_instr) ((_instr) & 0x3F) // The funct part of the instruction register #define sa(_instr) ((_instr >> 6) & 0x1F) // The sa part of the instruction register #define rd(_instr) ((_instr >> 11) & 0x1F) // The rd part of the instruction register #define rt(_instr) ((_instr >> 16) & 0x1F) // The rt part of the instruction register @@ -427,9 +427,9 @@ void PGXP_CPU_SLT(uint32_t instr, uint32_t rdVal, uint32_t rsVal, uint32_t rtVal ret.y = 0.f; ret.compFlags[1] = VALID; - ret.x = (g_CPU_reg[rs(instr)].y < g_CPU_reg[rt(instr)].y) - ? 1.f - : (f16Unsign(g_CPU_reg[rs(instr)].x) < f16Unsign(g_CPU_reg[rt(instr)].x)) ? 1.f : 0.f; + ret.x = (g_CPU_reg[rs(instr)].y < g_CPU_reg[rt(instr)].y) ? 1.f + : (f16Unsign(g_CPU_reg[rs(instr)].x) < f16Unsign(g_CPU_reg[rt(instr)].x)) ? 1.f + : 0.f; ret.value = rdVal; g_CPU_reg[rd(instr)] = ret; @@ -452,9 +452,9 @@ void PGXP_CPU_SLTU(uint32_t instr, uint32_t rdVal, uint32_t rsVal, uint32_t rtVa ret.y = 0.f; ret.compFlags[1] = VALID; - ret.x = (f16Unsign(g_CPU_reg[rs(instr)].y) < f16Unsign(g_CPU_reg[rt(instr)].y)) - ? 1.f - : (f16Unsign(g_CPU_reg[rs(instr)].x) < f16Unsign(g_CPU_reg[rt(instr)].x)) ? 1.f : 0.f; + ret.x = (f16Unsign(g_CPU_reg[rs(instr)].y) < f16Unsign(g_CPU_reg[rt(instr)].y)) ? 1.f + : (f16Unsign(g_CPU_reg[rs(instr)].x) < f16Unsign(g_CPU_reg[rt(instr)].x)) ? 1.f + : 0.f; ret.value = rdVal; g_CPU_reg[rd(instr)] = ret; diff --git a/src/core/pgxp_debug.cc b/src/core/pgxp_debug.cc index 623be30b9..de6743ac9 100644 --- a/src/core/pgxp_debug.cc +++ b/src/core/pgxp_debug.cc @@ -9,7 +9,7 @@ unsigned int g_pgxp_debug = 0; // Instruction register decoding #define op(_instr) (_instr >> 26) // The op part of the instruction register -#define func(_instr) ((_instr)&0x3F) // The funct part of the instruction register +#define func(_instr) ((_instr) & 0x3F) // The funct part of the instruction register #define sa(_instr) ((_instr >> 6) & 0x1F) // The sa part of the instruction register #define rd(_instr) ((_instr >> 11) & 0x1F) // The rd part of the instruction register #define rt(_instr) ((_instr >> 16) & 0x1F) // The rt part of the instruction register diff --git a/src/core/pgxp_debug.h b/src/core/pgxp_debug.h index 2a7805d29..9a21a0cfe 100644 --- a/src/core/pgxp_debug.h +++ b/src/core/pgxp_debug.h @@ -30,10 +30,10 @@ #include "psxemulator.h" -//#define PGXP_CPU_DEBUG -//#define PGXP_OUTPUT_ALL -//#define PGXP_FORCE_INPUT_VALUES -//#define PGXP_TEST_OUTPUT_VALUES +// #define PGXP_CPU_DEBUG +// #define PGXP_OUTPUT_ALL +// #define PGXP_FORCE_INPUT_VALUES +// #define PGXP_TEST_OUTPUT_VALUES #define PGXP_DEBUG_TOLERANCE 2.f diff --git a/src/core/pgxp_gte.cc b/src/core/pgxp_gte.cc index 9fef57d09..210d78420 100644 --- a/src/core/pgxp_gte.cc +++ b/src/core/pgxp_gte.cc @@ -57,7 +57,7 @@ void PGXP_InitGTE() { // Instruction register decoding #define op(_instr) (_instr >> 26) // The op part of the instruction register -#define func(_instr) ((_instr)&0x3F) // The funct part of the instruction register +#define func(_instr) ((_instr) & 0x3F) // The funct part of the instruction register #define sa(_instr) ((_instr >> 6) & 0x1F) // The sa part of the instruction register #define rd(_instr) ((_instr >> 11) & 0x1F) // The rd part of the instruction register #define rt(_instr) ((_instr >> 16) & 0x1F) // The rt part of the instruction register diff --git a/src/core/pgxp_value.h b/src/core/pgxp_value.h index 4a8b30df6..2c7d9b8ed 100644 --- a/src/core/pgxp_value.h +++ b/src/core/pgxp_value.h @@ -93,7 +93,7 @@ typedef enum { VALID_HALF = (1 << 0) } PGXP_half_flags; // typedef enum //{ -//#define NONE 0 +// #define NONE 0 #define ALL 0xFFFFFFFF #define VALID 1 #define VALID_0 (VALID << 0) diff --git a/src/core/psxcounters.cc b/src/core/psxcounters.cc index ae4f20934..3e73d36b8 100644 --- a/src/core/psxcounters.cc +++ b/src/core/psxcounters.cc @@ -30,7 +30,7 @@ #include "spu/interface.h" template -void verboseLog(int32_t level, const char *str, const Args &... args) { +void verboseLog(int32_t level, const char *str, const Args &...args) { PSXHW_LOG(str, args...); } diff --git a/src/core/psxemulator.cc b/src/core/psxemulator.cc index 10e30db20..f732583bf 100644 --- a/src/core/psxemulator.cc +++ b/src/core/psxemulator.cc @@ -30,6 +30,7 @@ #include "core/luaiso.h" #include "core/mdec.h" #include "core/pad.h" +#include "core/patchmanager.h" #include "core/pcsxlua.h" #include "core/pio-cart.h" #include "core/r3000a.h" @@ -37,7 +38,6 @@ #include "core/sio1-server.h" #include "core/sio1.h" #include "core/web-server.h" -#include "core/patchmanager.h" #include "gpu/soft/interface.h" #include "lua/extra.h" #include "lua/luafile.h" diff --git a/src/core/psxinterpreter.cc b/src/core/psxinterpreter.cc index 55182dd11..ac3931c75 100644 --- a/src/core/psxinterpreter.cc +++ b/src/core/psxinterpreter.cc @@ -1584,10 +1584,8 @@ void InterpretedCPU::Execute() { } } -void InterpretedCPU::Clear(uint32_t Addr, uint32_t Size) -{ - for (auto i = 0; i < Size ; i+=4) - { +void InterpretedCPU::Clear(uint32_t Addr, uint32_t Size) { + for (auto i = 0; i < Size; i += 4) { flushICacheLine(Addr); Addr += 16; } diff --git a/src/core/r3000a.h b/src/core/r3000a.h index d9aafd1d7..018bcaea7 100644 --- a/src/core/r3000a.h +++ b/src/core/r3000a.h @@ -229,7 +229,7 @@ struct psxRegisters { #define _PC_ PCSX::g_emulator->m_cpu->m_regs.pc // The next PC to be executed #define _fOp_(code) ((code >> 26)) // The opcode part of the instruction register -#define _fFunct_(code) ((code)&0x3F) // The funct part of the instruction register +#define _fFunct_(code) ((code) & 0x3F) // The funct part of the instruction register #define _fRd_(code) ((code >> 11) & 0x1F) // The rd part of the instruction register #define _fRt_(code) ((code >> 16) & 0x1F) // The rt part of the instruction register #define _fRs_(code) ((code >> 21) & 0x1F) // The rs part of the instruction register @@ -461,11 +461,9 @@ Formula One 2001 memset(m_regs.iCacheCode, 0xff, sizeof(m_regs.iCacheCode)); } - inline void flushICacheLine(uint32_t pc) - { + inline void flushICacheLine(uint32_t pc) { uint32_t pcBank = pc >> 24; - if (pcBank == 0x00 || pcBank == 0x80) - { + if (pcBank == 0x00 || pcBank == 0x80) { uint32_t pcCache = pc & 0xfff; pcCache &= ~0xf; diff --git a/src/core/web-server.cc b/src/core/web-server.cc index b047b1c55..d928cb03c 100644 --- a/src/core/web-server.cc +++ b/src/core/web-server.cc @@ -595,8 +595,8 @@ class StateExecutor : public PCSX::WebExecutor { message = fmt::format("HTTP/1.1 200 OK\r\n\r\nState slot index {} {} successful.", slot, path); } else { - message = fmt::format("HTTP/1.1 500 Internal Server Error\r\n\r\nState slot index {} {} failed.", - slot, path); + message = fmt::format( + "HTTP/1.1 500 Internal Server Error\r\n\r\nState slot index {} {} failed.", slot, path); } } client->write(std::move(message)); @@ -634,8 +634,9 @@ class StateExecutor : public PCSX::WebExecutor { message = fmt::format("HTTP/1.1 200 OK\r\n\r\nState slot name \"{}\" {} successful.", name, path); } else { - message = fmt::format("HTTP/1.1 500 Internal Server Error\r\n\r\nState slot name \"{}\" {} failed.", - name, path); + message = fmt::format( + "HTTP/1.1 500 Internal Server Error\r\n\r\nState slot name \"{}\" {} failed.", name, + path); } } client->write(std::move(message)); @@ -683,8 +684,9 @@ class ScreenExecutor : public PCSX::WebExecutor { message = fmt::format("HTTP/1.1 200 OK\r\n\r\nScreenshot saved successfully to \"{}\".", path.string()); } else { - message = fmt::format("HTTP/1.1 500 Internal Server Error\r\n\r\nFailed to save screenshot to \"{}\".", - path.string()); + message = + fmt::format("HTTP/1.1 500 Internal Server Error\r\n\r\nFailed to save screenshot to \"{}\".", + path.string()); } client->write(std::move(message)); return true; diff --git a/src/gui/gui.h b/src/gui/gui.h index 77fc60ee0..4c91c749d 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -153,15 +153,15 @@ class GUI final : public UI { Settings + ShowPatches, ShowMemcardManager, ShowRegisters, ShowAssembly, ShowDisassembly, ShowBreakpoints, + ShowNamedSaveStates, ShowEvents, ShowHandlers, ShowKernelLog, ShowCallstacks, ShowSIO1, ShowIsoBrowser, + ShowGPULogger, MainFontSize, MonoFontSize, GUITheme, AllowMouseCaptureToggle, EnableRawMouseMotion, + WidescreenRatio, ShowPIOCartConfig, ShowMemoryEditor1, ShowMemoryEditor2, ShowMemoryEditor3, + ShowMemoryEditor4, ShowMemoryEditor5, ShowMemoryEditor6, ShowMemoryEditor7, ShowMemoryEditor8, + ShowParallelPortEditor, ShowScratchpadEditor, ShowHWRegsEditor, ShowBiosEditor, ShowVRAMEditor, + MemoryEditor1Addr, MemoryEditor2Addr, MemoryEditor3Addr, MemoryEditor4Addr, MemoryEditor5Addr, + MemoryEditor6Addr, MemoryEditor7Addr, MemoryEditor8Addr, ParallelPortEditorAddr, ScratchpadEditorAddr, + HWRegsEditorAddr, BiosEditorAddr, VRAMEditorAddr> settings; // imgui can't handle more than one "instance", so... diff --git a/src/gui/widgets/assembly.cc b/src/gui/widgets/assembly.cc index 59718a122..257622fd0 100644 --- a/src/gui/widgets/assembly.cc +++ b/src/gui/widgets/assembly.cc @@ -638,8 +638,7 @@ settings, otherwise debugging features may not work.)"); }; if (clipper.DisplayStart != 0) { uint32_t addr = clipper.DisplayStart * 4 - 4; - process( - addr, [](uint32_t, const char*, uint32_t, uint32_t, uint32_t) {}, &dummy); + process(addr, [](uint32_t, const char*, uint32_t, uint32_t, uint32_t) {}, &dummy); } auto& tree = g_emulator->m_debug->getTree(); for (int x = clipper.DisplayStart; x < clipper.DisplayEnd; x++) { diff --git a/src/gui/widgets/memory_observer.cc b/src/gui/widgets/memory_observer.cc index 946215887..31fc694fd 100644 --- a/src/gui/widgets/memory_observer.cc +++ b/src/gui/widgets/memory_observer.cc @@ -334,9 +334,9 @@ void PCSX::Widgets::MemoryObserver::draw(const char* title) { ImGui::TableHeadersRow(); bool as_uint = (m_scanValueType == ScanValueType::Uint); - const auto valueDisplayFormat = - m_hex ? "%x" - : (m_fixedPoint && stride > 1) ? (as_uint ? "%u.%u" : "%i.%i") : (as_uint ? "%u" : "%i"); + const auto valueDisplayFormat = m_hex ? "%x" + : (m_fixedPoint && stride > 1) ? (as_uint ? "%u.%u" : "%i.%i") + : (as_uint ? "%u" : "%i"); ImGuiListClipper clipper; clipper.Begin(m_addressValuePairs.size()); diff --git a/src/gui/widgets/patches.cc b/src/gui/widgets/patches.cc index b561fec86..57f5442c0 100644 --- a/src/gui/widgets/patches.cc +++ b/src/gui/widgets/patches.cc @@ -17,9 +17,10 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ +#include "gui/widgets/patches.h" + #include "core/patchmanager.h" #include "core/r3000a.h" -#include "gui/widgets/patches.h" #include "imgui.h" void PCSX::Widgets::Patches::draw(const char* title) { @@ -37,8 +38,8 @@ void PCSX::Widgets::Patches::draw(const char* title) { } static ImGuiTableFlags flags = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | - ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | - ImGuiTableFlags_ContextMenuInBody; + ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | + ImGuiTableFlags_ContextMenuInBody; if (ImGui::BeginTable("Patches", 4, flags)) { ImGui::TableSetupColumn("#"); @@ -74,14 +75,10 @@ void PCSX::Widgets::Patches::draw(const char* title) { ImGui::TableSetColumnIndex(2); ImGui::PushID(row); - if (ImGui::Checkbox("", &patch.active)) - { - if (patch.active) - { + if (ImGui::Checkbox("", &patch.active)) { + if (patch.active) { patchManager.doPatch(row); - } - else - { + } else { patchManager.undoPatch(row); } } @@ -110,6 +107,6 @@ void PCSX::Widgets::Patches::draw(const char* title) { patchManager.deleteAllPatches(); } } - + ImGui::End(); } diff --git a/src/gui/widgets/sio1.cc b/src/gui/widgets/sio1.cc index ac8261625..77a1e6c00 100644 --- a/src/gui/widgets/sio1.cc +++ b/src/gui/widgets/sio1.cc @@ -132,8 +132,7 @@ void PCSX::Widgets::SIO1::DrawRegisterEditor(T* reg, const char* regname, SIO1Re } else if constexpr (sizeof(T) == 4) { displayFormat = "%08x"; } else { - []() { static_assert(f, "No known formatter"); } - (); + []() { static_assert(f, "No known formatter"); }(); } snprintf(currentValue, 11, displayFormat, *reg); diff --git a/src/lua/luafile.cc b/src/lua/luafile.cc index d51c5bf12..69dc287c9 100644 --- a/src/lua/luafile.cc +++ b/src/lua/luafile.cc @@ -59,8 +59,8 @@ LuaFile* openFile(const char* filename, FileOps type) { } LuaFile* openFileWithCallback(const char* url, void (*callback)()) { - return new LuaFile(new PCSX::UvFile( - url, [callback]() { callback(); }, PCSX::g_system->getLoop(), PCSX::UvFile::DOWNLOAD_URL)); + return new LuaFile( + new PCSX::UvFile(url, [callback]() { callback(); }, PCSX::g_system->getLoop(), PCSX::UvFile::DOWNLOAD_URL)); } LuaFile* bufferFileReadOnly(void* data, uint64_t size) { return new LuaFile(new PCSX::BufferFile(data, size)); } diff --git a/src/mips/common/crt0/cxxglue.c b/src/mips/common/crt0/cxxglue.c index d3124eba0..c6f6a2c44 100644 --- a/src/mips/common/crt0/cxxglue.c +++ b/src/mips/common/crt0/cxxglue.c @@ -70,8 +70,7 @@ void cxxmain() { __attribute__((weak)) void abort() { pcsx_debugbreak(); // TODO: make this better - while (1) - ; + while (1); } // This will be called if a pure virtual function is called, usually mistakenly calling diff --git a/src/mips/common/hardware/gpu.h b/src/mips/common/hardware/gpu.h index 46d2e7bbb..309b81c88 100644 --- a/src/mips/common/hardware/gpu.h +++ b/src/mips/common/hardware/gpu.h @@ -72,10 +72,7 @@ struct DisplayModeConfig { enum HResolutionExtended hResolutionExtended; }; -static inline void waitGPU() { - while ((GPU_STATUS & 0x04000000) == 0) - ; -} +static inline void waitGPU() { while ((GPU_STATUS & 0x04000000) == 0); } static inline void sendGPUData(uint32_t data) { waitGPU(); diff --git a/src/mips/common/hardware/sio1.c b/src/mips/common/hardware/sio1.c index c09409bc0..cfb3e8ca8 100644 --- a/src/mips/common/hardware/sio1.c +++ b/src/mips/common/hardware/sio1.c @@ -44,7 +44,6 @@ void sio1_init() { } void sio1_putc(uint8_t byte) { - while ((SIO1_STAT & 1) == 0) - ; + while ((SIO1_STAT & 1) == 0); SIO1_DATA = byte; } diff --git a/src/mips/common/syscalls/syscalls.h b/src/mips/common/syscalls/syscalls.h index 22fab25d0..f2dc1ebc8 100644 --- a/src/mips/common/syscalls/syscalls.h +++ b/src/mips/common/syscalls/syscalls.h @@ -60,13 +60,13 @@ static __attribute__((always_inline)) int changeThreadSubFunction(uint32_t addre static __attribute__((always_inline)) size_t syscall_write(int fd, const void *buf, size_t size) { register int n asm("t1") = 0x03; __asm__ volatile("" : "=r"(n) : "r"(n)); - return ((size_t (*)(int, const void *, size_t))0xa0)(fd, buf, size); + return ((size_t(*)(int, const void *, size_t))0xa0)(fd, buf, size); } static __attribute__((always_inline, returns_twice)) int syscall_setjmp(struct JmpBuf *buf) { register int n asm("t1") = 0x13; __asm__ volatile("" : "=r"(n) : "r"(n)); - return ((int (*)(struct JmpBuf * buf))0xa0)(buf); + return ((int (*)(struct JmpBuf *buf))0xa0)(buf); } static __attribute__((always_inline, noreturn)) void syscall_longjmp(struct JmpBuf *buf, int ret) { diff --git a/src/mips/cxxhello/main.cpp b/src/mips/cxxhello/main.cpp index 842e11c4d..adfe29393 100644 --- a/src/mips/cxxhello/main.cpp +++ b/src/mips/cxxhello/main.cpp @@ -57,6 +57,5 @@ std::string_view HelloWorld::getName() { return "World"; } int main() { HelloWorld hw; hw.print(); - while (1) - ; + while (1); } diff --git a/src/mips/helloworld/main/main.c b/src/mips/helloworld/main/main.c index 3170a00c6..1f5c214e7 100644 --- a/src/mips/helloworld/main/main.c +++ b/src/mips/helloworld/main/main.c @@ -28,6 +28,5 @@ SOFTWARE. int main() { ramsyscall_printf("Hello world\n"); - while (1) - ; + while (1); } diff --git a/src/mips/openbios/cdrom/cdrom.c b/src/mips/openbios/cdrom/cdrom.c index 4d39a8a7b..2f3698dfa 100644 --- a/src/mips/openbios/cdrom/cdrom.c +++ b/src/mips/openbios/cdrom/cdrom.c @@ -53,8 +53,7 @@ void initializeCDRomHandlersAndEvents() { static void initializeSoftwareAndHardware() { initializeCDRomHandlersAndEvents(); - while (!syscall_cdromInnerInit()) - ; + while (!syscall_cdromInnerInit()); } void initCDRom() { @@ -78,8 +77,7 @@ int cdromBlockGetStatus() { uint8_t status; int cyclesToWait = 9; - while (!syscall_cdromGetStatus(&status) && (--cyclesToWait > 0)) - ; + while (!syscall_cdromGetStatus(&status) && (--cyclesToWait > 0)); if (cyclesToWait < 1) { syscall_exception(0x44, 0x1f); return -1; diff --git a/src/mips/openbios/cdrom/filesystem.c b/src/mips/openbios/cdrom/filesystem.c index 6db415e98..c5260db6a 100644 --- a/src/mips/openbios/cdrom/filesystem.c +++ b/src/mips/openbios/cdrom/filesystem.c @@ -238,13 +238,11 @@ int dev_cd_open(struct File *file, const char *filename, int mode) { char canonicalFilename[32]; char *ptr = canonicalFilename; - while ((*ptr++ = toupper(*filename++))) - ; + while ((*ptr++ = toupper(*filename++))); ptr = canonicalFilename; char c; - while (((c = *ptr++) != 0) && (c != ';')) - ; + while (((c = *ptr++) != 0) && (c != ';')); if (c == 0) strcat(canonicalFilename, ";1"); int id; diff --git a/src/mips/openbios/cdrom/helpers.c b/src/mips/openbios/cdrom/helpers.c index 4bc9cd692..53343c910 100644 --- a/src/mips/openbios/cdrom/helpers.c +++ b/src/mips/openbios/cdrom/helpers.c @@ -47,8 +47,7 @@ int cdromBlockReading(int count, int sector, char* buffer) { for (retries = 0; retries < 10; retries++) { int cyclesToWait = 99999; - while (!syscall_cdromSeekL(msf) && (--cyclesToWait > 0)) - ; + while (!syscall_cdromSeekL(msf) && (--cyclesToWait > 0)); if (cyclesToWait < 1) { syscall_exception(0x44, 0x0b); @@ -63,8 +62,7 @@ int cdromBlockReading(int count, int sector, char* buffer) { } cyclesToWait = 99999; - while (!syscall_cdromRead(count, buffer, 0x80) && (--cyclesToWait > 0)) - ; + while (!syscall_cdromRead(count, buffer, 0x80) && (--cyclesToWait > 0)); if (cyclesToWait < 1) { syscall_exception(0x44, 0x0c); return -1; diff --git a/src/mips/openbios/fileio/filesystem.c b/src/mips/openbios/fileio/filesystem.c index c43625895..a5b51ba01 100644 --- a/src/mips/openbios/fileio/filesystem.c +++ b/src/mips/openbios/fileio/filesystem.c @@ -55,9 +55,7 @@ struct DirEntry *firstFile(const char *filepath, struct DirEntry *entry) { } } -struct DirEntry *nextFile(struct DirEntry *entry) { - return g_firstFile->device->nextFile(g_firstFile, entry); -} +struct DirEntry *nextFile(struct DirEntry *entry) { return g_firstFile->device->nextFile(g_firstFile, entry); } int format(const char *deviceName) { struct File *file = findEmptyFile(); diff --git a/src/mips/openbios/gpu/gpu.c b/src/mips/openbios/gpu/gpu.c index 7f112e3a9..01aacd6eb 100644 --- a/src/mips/openbios/gpu/gpu.c +++ b/src/mips/openbios/gpu/gpu.c @@ -113,8 +113,7 @@ int GPU_sync() { return -1; } } - while ((GPU_STATUS & 0x4000000) == 0) - ; + while ((GPU_STATUS & 0x4000000) == 0); GPU_STATUS = 0x4000000; } return 0; diff --git a/src/mips/openbios/kernel/globals.h b/src/mips/openbios/kernel/globals.h index 66d06a14c..b37724ae8 100644 --- a/src/mips/openbios/kernel/globals.h +++ b/src/mips/openbios/kernel/globals.h @@ -33,7 +33,9 @@ SOFTWARE. #include "openbios/kernel/events.h" #include "openbios/kernel/threads.h" -extern struct { uint32_t ramsize, unk1, unk2; } __globals60; +extern struct { + uint32_t ramsize, unk1, unk2; +} __globals60; extern struct { /* 100 */ struct HandlersStorage* handlersArray; diff --git a/src/mips/openbios/kernel/handlers.c b/src/mips/openbios/kernel/handlers.c index 2dc941cb3..f9ef6daf3 100644 --- a/src/mips/openbios/kernel/handlers.c +++ b/src/mips/openbios/kernel/handlers.c @@ -107,8 +107,7 @@ void unimplemented(uint32_t table, uint32_t call, uint32_t ra) { osDbgPrintf("hi = %p - lo = %p\r\n", regs->GPR.r[32], regs->GPR.r[33]); osDbgPrintf("=== halting ===\r\n"); pcsx_debugbreak(); - while (1) - ; + while (1); } static void installExceptionHandler() { installHandler((uint32_t *)exceptionVector, (uint32_t *)0x80); } diff --git a/src/mips/openbios/kernel/psxexe.c b/src/mips/openbios/kernel/psxexe.c index 1a94ced56..7f28b03ba 100644 --- a/src/mips/openbios/kernel/psxexe.c +++ b/src/mips/openbios/kernel/psxexe.c @@ -80,8 +80,7 @@ void loadAndExec(const char *filename, uint32_t stackStart, uint32_t stackSize) filename++; } - while ((*ptr++ = toupper(*filename++)) != 0) - ; + while ((*ptr++ = toupper(*filename++)) != 0); ptr = localFilename; while (((c = *ptr) != 0) && (c != ';')) ptr++; @@ -107,6 +106,5 @@ void loadAndExec(const char *filename, uint32_t stackStart, uint32_t stackSize) exec(&binaryHeader, 1, NULL); } psxprintf("No boot file !\n"); - while (1) - ; + while (1); } diff --git a/src/mips/openbios/patches/patches.c b/src/mips/openbios/patches/patches.c index 8f3cd57cc..0582aab52 100644 --- a/src/mips/openbios/patches/patches.c +++ b/src/mips/openbios/patches/patches.c @@ -213,7 +213,6 @@ void patch_hook(uint32_t* ra, enum patch_table table) { romsyscall_printf("Stopping.\n", t, h); enterCriticalSection(); pcsx_debugbreak(); - while (1) - ; + while (1); } } diff --git a/src/mips/openbios/sio0/card.c b/src/mips/openbios/sio0/card.c index 295746005..a08ea55b6 100644 --- a/src/mips/openbios/sio0/card.c +++ b/src/mips/openbios/sio0/card.c @@ -195,8 +195,7 @@ int __attribute__((section(".ramtext"))) mcReadHandler() { SIOS[0].ctrl |= 0x0010; IREG = ~IRQ_CONTROLLER; if (b != g_mcChecksum[port]) return -1; - while ((SIOS[0].stat & 2) == 0) - ; + while ((SIOS[0].stat & 2) == 0); return SIOS[0].fifo == 0x47 ? 1 : -1; default: return -1; @@ -292,8 +291,7 @@ int __attribute__((section(".ramtext"))) mcWriteHandler() { SIOS[0].ctrl |= 0x0010; IREG = ~IRQ_CONTROLLER; if (b != 0x5d) return -1; - while ((SIOS[0].stat & 2) == 0) - ; + while ((SIOS[0].stat & 2) == 0); if (!g_skipErrorOnNewCard && ((s_mcFlagByte[port] & 4) != 0)) { g_mcLastPort = g_mcPortFlipping; g_skipErrorOnNewCard = 0; // whyyyy diff --git a/src/mips/openbios/sio0/driver.c b/src/mips/openbios/sio0/driver.c index 1bbe28987..e33dba5f3 100644 --- a/src/mips/openbios/sio0/driver.c +++ b/src/mips/openbios/sio0/driver.c @@ -113,15 +113,13 @@ static uint32_t __attribute__((section(".ramtext"))) readPad(int pad) { SIOS[0].fifo; // throw away busyloop(40); SIOS[0].ctrl = mask | 0x1003; - while (!(SIOS[0].stat & 1)) - ; + while (!(SIOS[0].stat & 1)); g_sio0Mask = mask; SIOS[0].fifo = 1; busyloop(20); SIOS[0].ctrl |= 0x10; IREG = ~IRQ_CONTROLLER; - while (!(SIOS[0].stat & 2)) - ; + while (!(SIOS[0].stat & 2)); SIOS[0].fifo; // throw away busyloop(40); @@ -138,8 +136,7 @@ static uint32_t __attribute__((section(".ramtext"))) readPad(int pad) { SIOS[0].ctrl |= 0x10; IREG = ~IRQ_CONTROLLER; - while (!(SIOS[0].stat & 2)) - ; + while (!(SIOS[0].stat & 2)); uint32_t fifoBytes = SIOS[0].fifo; padBuffer[1] = fifoBytes & 0xff; fifoBytes &= 0x0f; @@ -159,8 +156,7 @@ static uint32_t __attribute__((section(".ramtext"))) readPad(int pad) { SIOS[0].ctrl |= 0x10; IREG = ~IRQ_CONTROLLER; - while (!(SIOS[0].stat & 2)) - ; + while (!(SIOS[0].stat & 2)); if (SIOS[0].fifo != 0x5a) { padAbort(pad); @@ -186,8 +182,7 @@ static uint32_t __attribute__((section(".ramtext"))) readPad(int pad) { cyclesWaited = 0; while (!(SIOS[0].stat & 2)) { if (!(IREG & IRQ_CONTROLLER)) continue; - while (!(SIOS[0].stat & 2)) - ; + while (!(SIOS[0].stat & 2)); padAbort(pad); return 0xffff; } @@ -209,8 +204,7 @@ static uint32_t __attribute__((section(".ramtext"))) readPad(int pad) { SIOS[0].ctrl |= 0x10; IREG = ~IRQ_CONTROLLER; - while (!(SIOS[0].stat & 2)) - ; + while (!(SIOS[0].stat & 2)); padBuffer[3] = SIOS[0].fifo; padBuffer += 2; @@ -364,8 +358,8 @@ static void __attribute__((section(".ramtext"))) setupBasicSio0Handler() { g_sio0HandlerInfo.padding = 0; } -int __attribute__((section(".ramtext"))) -initPad(uint8_t* pad1Buffer, size_t pad1BufferSize, uint8_t* pad2Buffer, size_t pad2BufferSize) { +int __attribute__((section(".ramtext"))) initPad(uint8_t* pad1Buffer, size_t pad1BufferSize, uint8_t* pad2Buffer, + size_t pad2BufferSize) { // *sigh* ramsyscall_printf("%s\n", "PS-X Control PAD Driver"); g_userPadBuffer = NULL; diff --git a/src/mips/openbios/uC-sdk-glue/BoardInit.c b/src/mips/openbios/uC-sdk-glue/BoardInit.c index 4eba268ef..37a1820ba 100644 --- a/src/mips/openbios/uC-sdk-glue/BoardInit.c +++ b/src/mips/openbios/uC-sdk-glue/BoardInit.c @@ -32,7 +32,4 @@ void BoardLateInit() {} void BoardShutdown() {} -void BoardExceptionHandler(int code) { - while (1) - ; -} +void BoardExceptionHandler(int code) { while (1); } diff --git a/src/mips/psyqo-paths/examples/cdrom-loader/cdrom-loader.cpp b/src/mips/psyqo-paths/examples/cdrom-loader/cdrom-loader.cpp index a2e4568f8..9367dee53 100644 --- a/src/mips/psyqo-paths/examples/cdrom-loader/cdrom-loader.cpp +++ b/src/mips/psyqo-paths/examples/cdrom-loader/cdrom-loader.cpp @@ -24,13 +24,14 @@ SOFTWARE. */ +#include "psyqo-paths/cdrom-loader.hh" + #include "psyqo/application.hh" #include "psyqo/cdrom-device.hh" #include "psyqo/font.hh" #include "psyqo/gpu.hh" #include "psyqo/iso9660-parser.hh" #include "psyqo/scene.hh" -#include "psyqo-paths/cdrom-loader.hh" namespace { @@ -71,9 +72,9 @@ void CDRomLoaderExample::createScene() { pushScene(&cdromLoaderExampleScene); m_cdromLoader.readFile("SYSTEM.CNF;1", cdromLoaderExample.gpu(), cdromLoaderExample.m_isoParser, [this](eastl::vector&& buffer) { - m_buffer = eastl::move(buffer); - m_callbackCalled = true; - }); + m_buffer = eastl::move(buffer); + m_callbackCalled = true; + }); } void CDRomLoaderExampleScene::frame() { diff --git a/src/mips/psyqo-paths/src/cdrom-loader.cpp b/src/mips/psyqo-paths/src/cdrom-loader.cpp index 764b775cb..7831b73ac 100644 --- a/src/mips/psyqo-paths/src/cdrom-loader.cpp +++ b/src/mips/psyqo-paths/src/cdrom-loader.cpp @@ -29,7 +29,7 @@ SOFTWARE. #include "psyqo/kernel.hh" void psyqo::paths::CDRomLoader::setupQueue(eastl::string_view path, GPU& gpu, psyqo::ISO9660Parser& parser, - eastl::function&&)>&& callback) { + eastl::function&&)>&& callback) { Kernel::assert(!m_pending, "Only one file can be read at a time"); m_queue.reset(); m_pending = true; @@ -46,9 +46,7 @@ void psyqo::paths::CDRomLoader::setupQueue(eastl::string_view path, GPU& gpu, ps task->resolve(); }) .then(parser.scheduleReadRequest(&m_request)) - .butCatch([this](auto task) { - m_request.entry.size = 0; - }) + .butCatch([this](auto task) { m_request.entry.size = 0; }) .finally([this](auto task) { m_pending = false; m_data.resize(m_request.entry.size); diff --git a/src/mips/psyqo/cdrom-device.hh b/src/mips/psyqo/cdrom-device.hh index c38fbccae..c3027c742 100644 --- a/src/mips/psyqo/cdrom-device.hh +++ b/src/mips/psyqo/cdrom-device.hh @@ -325,9 +325,7 @@ class CDRomDevice final : public CDRom { * @brief Checks if the CDROM device is in idle state. * */ - [[nodiscard]] bool isIdle() const { - return m_state == 0; - } + [[nodiscard]] bool isIdle() const { return m_state == 0; } private: void switchAction(ActionBase *action); diff --git a/src/mips/psyqo/examples/bezier/bezier.cpp b/src/mips/psyqo/examples/bezier/bezier.cpp index 33fc5306e..0b682f089 100644 --- a/src/mips/psyqo/examples/bezier/bezier.cpp +++ b/src/mips/psyqo/examples/bezier/bezier.cpp @@ -73,8 +73,8 @@ class BezierScene final : public psyqo::Scene { // point, which is always the end point of the curve. for (unsigned i = 0; i < 20; i++) { m_quads[i].setColor({.r = 0xff, .g = 0x80, .b = 0x33}); - m_quads[i].pointC = psyqo::Vertex{{ .x = int16_t(i * 32), .y = 480}}; - m_quads[i].pointD = psyqo::Vertex{{ .x = int16_t(i * 32 + 32), .y = 480}}; + m_quads[i].pointC = psyqo::Vertex{{.x = int16_t(i * 32), .y = 480}}; + m_quads[i].pointD = psyqo::Vertex{{.x = int16_t(i * 32 + 32), .y = 480}}; } m_quads[19].pointB = b; } @@ -148,7 +148,6 @@ void BezierScene::frame() { // Draw the Quad fan. gpu().sendPrimitive(m_quads); - #ifdef DEBUG_BEZIER // Draw the control points. psyqo::Prim::Line line; diff --git a/src/mips/psyqo/examples/cube/cube.cpp b/src/mips/psyqo/examples/cube/cube.cpp index 9f42e6515..ab348333e 100644 --- a/src/mips/psyqo/examples/cube/cube.cpp +++ b/src/mips/psyqo/examples/cube/cube.cpp @@ -25,17 +25,17 @@ SOFTWARE. */ #include "psyqo/application.hh" -#include "psyqo/gpu.hh" -#include "psyqo/trigonometry.hh" -#include "psyqo/gte-registers.hh" -#include "psyqo/gte-kernels.hh" #include "psyqo/fixed-point.hh" #include "psyqo/fragments.hh" +#include "psyqo/gpu.hh" +#include "psyqo/gte-kernels.hh" +#include "psyqo/gte-registers.hh" #include "psyqo/primitives/common.hh" #include "psyqo/primitives/quads.hh" -#include "psyqo/vector.hh" -#include "psyqo/soft-math.hh" #include "psyqo/scene.hh" +#include "psyqo/soft-math.hh" +#include "psyqo/trigonometry.hh" +#include "psyqo/vector.hh" using namespace psyqo::fixed_point_literals; using namespace psyqo::trig_literals; @@ -45,27 +45,25 @@ static constexpr unsigned NUM_CUBE_FACES = 6; static constexpr unsigned ORDERING_TABLE_SIZE = 240; typedef struct { - uint8_t vertices[4]; - psyqo::Color color; + uint8_t vertices[4]; + psyqo::Color color; } Face; - static constexpr psyqo::Matrix33 identity = {{ - {1.0_fp, 0.0_fp, 0.0_fp}, - {0.0_fp, 1.0_fp, 0.0_fp}, - {0.0_fp, 0.0_fp, 1.0_fp}, + {1.0_fp, 0.0_fp, 0.0_fp}, + {0.0_fp, 1.0_fp, 0.0_fp}, + {0.0_fp, 0.0_fp, 1.0_fp}, }}; class Cube final : public psyqo::Application { void prepare() override; void createScene() override; - public: - psyqo::Trig<> m_trig; + public: + psyqo::Trig<> m_trig; }; class CubeScene final : public psyqo::Scene { - void start(StartReason reason) override; void frame() override; @@ -74,8 +72,8 @@ class CubeScene final : public psyqo::Scene { // We need to create 2 OrderingTable objects since we can't reuse a single one for both // framebuffers, as the previous one may not finish transfering in time. psyqo::OrderingTable m_ots[2]; - - // Since we're using an ordering table, we need to sort fill commands as well, + + // Since we're using an ordering table, we need to sort fill commands as well, // otherwise they'll draw over our beautiful cube. psyqo::Fragments::SimpleFragment m_clear[2]; @@ -83,71 +81,51 @@ class CubeScene final : public psyqo::Scene { static constexpr psyqo::Color c_bg = {.r = 63, .g = 63, .b = 63}; - static constexpr psyqo::Vec3 c_cubeVertices[NUM_CUBE_VERTICES] = { - { .x = -0.05, .y = -0.05, .z = -0.05 }, - { .x = 0.05, .y = -0.05, .z = -0.05 }, - { .x = -0.05, .y = 0.05, .z = -0.05 }, - { .x = 0.05, .y = 0.05, .z = -0.05 }, - { .x = -0.05, .y = -0.05, .z = 0.05 }, - { .x = 0.05, .y = -0.05, .z = 0.05 }, - { .x = -0.05, .y = 0.05, .z = 0.05 }, - { .x = 0.05, .y = 0.05, .z = 0.05 } - }; - + {.x = -0.05, .y = -0.05, .z = -0.05}, {.x = 0.05, .y = -0.05, .z = -0.05}, {.x = -0.05, .y = 0.05, .z = -0.05}, + {.x = 0.05, .y = 0.05, .z = -0.05}, {.x = -0.05, .y = -0.05, .z = 0.05}, {.x = 0.05, .y = -0.05, .z = 0.05}, + {.x = -0.05, .y = 0.05, .z = 0.05}, {.x = 0.05, .y = 0.05, .z = 0.05}}; static constexpr Face c_cubeFaces[NUM_CUBE_FACES] = { - { .vertices = { 0, 1, 2, 3 }, .color = {0,0,255} }, - { .vertices = { 6, 7, 4, 5 }, .color = {0,255,0} }, - { .vertices = { 4, 5, 0, 1 }, .color = {0,255,255} }, - { .vertices = { 7, 6, 3, 2 }, .color = {255,0,0} }, - { .vertices = { 6, 4, 2, 0 }, .color = {255,0,255}}, - { .vertices = { 5, 7, 1, 3 }, .color = {255,255,0} } - }; + {.vertices = {0, 1, 2, 3}, .color = {0, 0, 255}}, {.vertices = {6, 7, 4, 5}, .color = {0, 255, 0}}, + {.vertices = {4, 5, 0, 1}, .color = {0, 255, 255}}, {.vertices = {7, 6, 3, 2}, .color = {255, 0, 0}}, + {.vertices = {6, 4, 2, 0}, .color = {255, 0, 255}}, {.vertices = {5, 7, 1, 3}, .color = {255, 255, 0}}}; }; static Cube cube; static CubeScene cubeScene; void Cube::prepare() { - psyqo::GPU::Configuration config; - config.set(psyqo::GPU::Resolution::W320) - .set(psyqo::GPU::VideoMode::AUTO) - .set(psyqo::GPU::ColorMode::C15BITS) - .set(psyqo::GPU::Interlace::PROGRESSIVE); + psyqo::GPU::Configuration config; + config.set(psyqo::GPU::Resolution::W320) + .set(psyqo::GPU::VideoMode::AUTO) + .set(psyqo::GPU::ColorMode::C15BITS) + .set(psyqo::GPU::Interlace::PROGRESSIVE); - gpu().initialize(config); + gpu().initialize(config); } -void Cube::createScene() { - pushScene(&cubeScene); -} +void Cube::createScene() { pushScene(&cubeScene); } void CubeScene::start(StartReason reason) { - // Clear the translation registers psyqo::GTE::clear(); psyqo::GTE::clear(); psyqo::GTE::clear(); - // Set the screen offset in the GTE. (this is half the X and Y resolutions as standard) psyqo::GTE::write(psyqo::FixedPoint<16>(160.0).raw()); psyqo::GTE::write(psyqo::FixedPoint<16>(120.0).raw()); - // Write the projection plane distance. psyqo::GTE::write(120); - // Set the scaling for Z averaging. psyqo::GTE::write(ORDERING_TABLE_SIZE / 3); psyqo::GTE::write(ORDERING_TABLE_SIZE / 4); - } void CubeScene::frame() { - eastl::array projected; // Get which frame we're currently drawing @@ -160,11 +138,10 @@ void CubeScene::frame() { // Chain the fill command accordingly to clear the buffer gpu().getNextClear(clear.primitive, c_bg); gpu().chain(clear); - // We want the cube to appear slightly further away, so we translate it by 512 on the Z-axis. psyqo::GTE::write(512); - + // Here we're setting up the rotation for the spinning cube // First, generate a rotation matrix for the X-axis and Y-axis auto transform = psyqo::SoftMath::generateRotationMatrix33(m_rot, psyqo::SoftMath::Axis::X, cube.m_trig); @@ -179,19 +156,16 @@ void CubeScene::frame() { // Apply the combined rotation and write it to the pseudo register for the cube's rotation psyqo::SoftMath::multiplyMatrix33(transform, rot, &transform); psyqo::GTE::writeUnsafe(transform); - - int faceNum = 0; - for(auto face : c_cubeFaces) { - - // We load the first 3 vertices into the GTE. We can't do all 4 at once because the GTE + for (auto face : c_cubeFaces) { + // We load the first 3 vertices into the GTE. We can't do all 4 at once because the GTE // handles only 3 at a time... psyqo::GTE::writeUnsafe(c_cubeVertices[face.vertices[0]]); psyqo::GTE::writeUnsafe(c_cubeVertices[face.vertices[1]]); psyqo::GTE::writeUnsafe(c_cubeVertices[face.vertices[2]]); - + // We perform rtpt (Perspective transformation) to the three verticies. psyqo::GTE::Kernels::rtpt(); @@ -202,10 +176,9 @@ void CubeScene::frame() { // Read the result of nclip and skip rendering this face if it's not facing us uint32_t mac0 = 0; psyqo::GTE::read(&mac0); - if(mac0 <= 0) - continue; + if (mac0 <= 0) continue; - // Since the GTE can only handle 3 vertices at a time, we need to store our first vertex + // Since the GTE can only handle 3 vertices at a time, we need to store our first vertex // so we can write our last one. psyqo::GTE::read(&projected[0].packed); @@ -214,17 +187,15 @@ void CubeScene::frame() { // Perform rtps (Perspective transformation) to the last vertice (rtpS - single, rtpT - triple). psyqo::GTE::Kernels::rtps(); - + // Calculate the average Z for the z-Index to be put in the ordering table psyqo::GTE::Kernels::avsz4(); uint32_t zIndex = 0; psyqo::GTE::read(&zIndex); - // If the Z-index is out of bounds for our ordering table, we skip rendering this face. - if(zIndex < 0 || zIndex >= ORDERING_TABLE_SIZE) - continue; - + if (zIndex < 0 || zIndex >= ORDERING_TABLE_SIZE) continue; + // Read the 3 remaining vertices from the GTE psyqo::GTE::read(&projected[1].packed); psyqo::GTE::read(&projected[2].packed); @@ -243,12 +214,10 @@ void CubeScene::frame() { ot.insert(quad, zIndex); faceNum++; } - - // Send the entire ordering table as a DMA chain to the GPU. + + // Send the entire ordering table as a DMA chain to the GPU. gpu().chain(ot); m_rot += 0.005_pi; } - -int main() {return cube.run();} - +int main() { return cube.run(); } diff --git a/src/mips/psyqo/examples/hello/hello.cpp b/src/mips/psyqo/examples/hello/hello.cpp index a63289981..4bb86eb3f 100644 --- a/src/mips/psyqo/examples/hello/hello.cpp +++ b/src/mips/psyqo/examples/hello/hello.cpp @@ -34,7 +34,6 @@ namespace { // A PSYQo software needs to declare one `Application` object. // This is the one we're going to do for our hello world. class Hello final : public psyqo::Application { - void prepare() override; void createScene() override; diff --git a/src/mips/psyqo/examples/tetris/gameover.cpp b/src/mips/psyqo/examples/tetris/gameover.cpp index 51c2c8e32..e9c6c5971 100644 --- a/src/mips/psyqo/examples/tetris/gameover.cpp +++ b/src/mips/psyqo/examples/tetris/gameover.cpp @@ -48,8 +48,7 @@ void GameOver::frame() { // The main difference with the Pause scene is we pop all the scenes, // not just the current one. This will force the application to // re-create the root scene. - while (popScene()) - ; + while (popScene()); } } diff --git a/src/mips/psyqo/examples/tetris/pieces.cpp b/src/mips/psyqo/examples/tetris/pieces.cpp index 3dbcee0fe..0e3c771ea 100644 --- a/src/mips/psyqo/examples/tetris/pieces.cpp +++ b/src/mips/psyqo/examples/tetris/pieces.cpp @@ -212,4 +212,3 @@ const uint8_t PIECES[7][4][4][4] = { }, }, }; - diff --git a/src/mips/psyqo/examples/tetris/sound.cpp b/src/mips/psyqo/examples/tetris/sound.cpp index 22bbc0c82..02fc47b88 100644 --- a/src/mips/psyqo/examples/tetris/sound.cpp +++ b/src/mips/psyqo/examples/tetris/sound.cpp @@ -30,13 +30,9 @@ extern "C" { #include "modplayer/modplayer.h" } -void Sound::playClick() { - MOD_PlaySoundEffect(4, 28, 30, m_volume); -} +void Sound::playClick() { MOD_PlaySoundEffect(4, 28, 30, m_volume); } -void Sound::playFlip(int pitch) { - MOD_PlaySoundEffect(5, 27, 30 + pitch, m_volume); -} +void Sound::playFlip(int pitch) { MOD_PlaySoundEffect(5, 27, 30 + pitch, m_volume); } void Sound::playDrop(unsigned int volume) { auto vol = m_volume; diff --git a/src/mips/psyqo/gte-registers.hh b/src/mips/psyqo/gte-registers.hh index 35376a959..ba33cc971 100644 --- a/src/mips/psyqo/gte-registers.hh +++ b/src/mips/psyqo/gte-registers.hh @@ -69,72 +69,72 @@ struct PackedVec3 { /** * @brief The list of available GTE registers. - */ + */ enum class Register { - VXY0, /* Vector 0 (X,Y) */ - VZ0, /* Vector 0 (Z) */ - VXY1, /* Vector 1 (X,Y) */ - VZ1, /* Vector 1 (Z) */ - VXY2, /* Vector 2 (X,Y) */ - VZ2, /* Vector 2 (Z) */ - RGB, /* Color/code value */ - OTZ, /* Average Z value (for Ordering Table) */ - IR0, /* 16bit Accumulator 0 (Interpolate) */ - IR1, /* 16bit Accumulator 1 (Vector) */ - IR2, /* 16bit Accumulator 2 (Vector) */ - IR3, /* 16bit Accumulator 3 (Vector) */ - SXY0, /* Screen XY-coordinate 0 FIFO */ - SXY1, /* Screen XY-coordinate 1 FIFO */ - SXY2, /* Screen XY-coordinate 2 FIFO */ - SXYP, /* Screen XY-coordinate P FIFO */ - SZ0, /* Screen Z-coordinate 0 FIFO */ - SZ1, /* Screen Z-coordinate 1 FIFO */ - SZ2, /* Screen Z-coordinate 2 FIFO */ - SZ3, /* Screen Z-coordinate 3 FIFO */ - RGB0, /* Color CRGB-code/color 0 FIFO */ - RGB1, /* Color CRGB-code/color 1 FIFO */ - RGB2, /* Color CRGB-code/color 2 FIFO */ - RES1, /* Prohibited */ - MAC0, /* 32bit Maths Accumulators 0 (Value) */ - MAC1, /* 32bit Maths Accumulators 1 (Vector) */ - MAC2, /* 32bit Maths Accumulators 2 (Vector) */ - MAC3, /* 32bit Maths Accumulators 3 (Vector) */ - IRGB, /* Convert RGB Color (48bit vs 15bit) */ - ORGB, /* Convert RGB Color (48bit vs 15bit) */ - LZCS, /* Count Leading-Zeroes/Ones (sign bits) */ - LZCR, /* Count Leading-Zeroes/Ones (sign bits) */ + VXY0, /* Vector 0 (X,Y) */ + VZ0, /* Vector 0 (Z) */ + VXY1, /* Vector 1 (X,Y) */ + VZ1, /* Vector 1 (Z) */ + VXY2, /* Vector 2 (X,Y) */ + VZ2, /* Vector 2 (Z) */ + RGB, /* Color/code value */ + OTZ, /* Average Z value (for Ordering Table) */ + IR0, /* 16bit Accumulator 0 (Interpolate) */ + IR1, /* 16bit Accumulator 1 (Vector) */ + IR2, /* 16bit Accumulator 2 (Vector) */ + IR3, /* 16bit Accumulator 3 (Vector) */ + SXY0, /* Screen XY-coordinate 0 FIFO */ + SXY1, /* Screen XY-coordinate 1 FIFO */ + SXY2, /* Screen XY-coordinate 2 FIFO */ + SXYP, /* Screen XY-coordinate P FIFO */ + SZ0, /* Screen Z-coordinate 0 FIFO */ + SZ1, /* Screen Z-coordinate 1 FIFO */ + SZ2, /* Screen Z-coordinate 2 FIFO */ + SZ3, /* Screen Z-coordinate 3 FIFO */ + RGB0, /* Color CRGB-code/color 0 FIFO */ + RGB1, /* Color CRGB-code/color 1 FIFO */ + RGB2, /* Color CRGB-code/color 2 FIFO */ + RES1, /* Prohibited */ + MAC0, /* 32bit Maths Accumulators 0 (Value) */ + MAC1, /* 32bit Maths Accumulators 1 (Vector) */ + MAC2, /* 32bit Maths Accumulators 2 (Vector) */ + MAC3, /* 32bit Maths Accumulators 3 (Vector) */ + IRGB, /* Convert RGB Color (48bit vs 15bit) */ + ORGB, /* Convert RGB Color (48bit vs 15bit) */ + LZCS, /* Count Leading-Zeroes/Ones (sign bits) */ + LZCR, /* Count Leading-Zeroes/Ones (sign bits) */ R11R12, /* Rotation matrix (3x3) */ R13R21, /* Rotation matrix (3x3) */ R22R23, /* Rotation matrix (3x3) */ R31R32, /* Rotation matrix (3x3) */ - R33, /* Rotation matrix (3x3) */ - TRX, /* Translation vector (X) */ - TRY, /* Translation vector (Y) */ - TRZ, /* Translation vector (Z) */ + R33, /* Rotation matrix (3x3) */ + TRX, /* Translation vector (X) */ + TRY, /* Translation vector (Y) */ + TRZ, /* Translation vector (Z) */ L11L12, /* Light source matrix (3x3) */ L13L21, /* Light source matrix (3x3) */ L22L23, /* Light source matrix (3x3) */ L31L32, /* Light source matrix (3x3) */ - L33, /* Light source matrix (3x3) */ - RBK, /* Background color(R) */ - GBK, /* Background color(G) */ - BBK, /* Background color(B) */ + L33, /* Light source matrix (3x3) */ + RBK, /* Background color(R) */ + GBK, /* Background color(G) */ + BBK, /* Background color(B) */ LR1LR2, /* Light color matrix source (3x3) */ LR3LG1, /* Light color matrix source (3x3) */ LG2LG3, /* Light color matrix source (3x3) */ LB1LB2, /* Light color matrix source (3x3) */ - LB3, /* Light color matrix source (3x3) */ - RFC, /* Far color (R) */ - GFC, /* Far color (G) */ - BFC, /* Far color (B) */ - OFX, /* Screen offset (X) */ - OFY, /* Screen offset (Y) */ - H, /* Projection plane distance. */ - DQA, /* Depth queing parameter A (coeff) */ - DQB, /* Depth queing parameter B (offset) */ - ZSF3, /* Average Z scale factors */ - ZSF4, /* Average Z scale factors */ - FLAG, /* Returns any calculation errors */ + LB3, /* Light color matrix source (3x3) */ + RFC, /* Far color (R) */ + GFC, /* Far color (G) */ + BFC, /* Far color (B) */ + OFX, /* Screen offset (X) */ + OFY, /* Screen offset (Y) */ + H, /* Projection plane distance. */ + DQA, /* Depth queing parameter A (coeff) */ + DQB, /* Depth queing parameter B (offset) */ + ZSF3, /* Average Z scale factors */ + ZSF4, /* Average Z scale factors */ + FLAG, /* Returns any calculation errors */ }; /** @@ -150,7 +150,7 @@ enum class Register { */ enum Safety { Unsafe, /* avoid nops */ - Safe, /* insert nops */ + Safe, /* insert nops */ }; /** @@ -247,15 +247,15 @@ static inline void writeUnsafe(Short low, Short hi) { * @brief The list of available GTE pseudo registers. */ enum class PseudoRegister { - Rotation, /* pseudo register for full rotation matrix, mapped to registers R11R12-R33 */ - Light, /* pseudo register for full light matrix, mapped to registers L11L12-L33 */ - Color, /* pseudo register for full light color matrix, mapped to registers LR1LR2-LB3 */ - V0, /* pseudo register for full Vector 0, mapped to registers VXY0 and VZ0 */ - V1, /* pseudo register for full Vector 1, mapped to registers VXY1 and VZ1 */ - V2, /* pseudo register for full Vector 2, mapped to registers VXY2 and VZ2 */ - SV, /* pseudo register for full 16bit Accumulator Vector, mapped to registers IR1-IR3 */ - LV, /* pseudo register for full 32bit Maths Accumulator Vector, mapped to registers MAC1-MAC3 */ - Translation, /* pseudo register for full Translation vector, mapped to registers TRX-TRZ */ + Rotation, /* pseudo register for full rotation matrix, mapped to registers R11R12-R33 */ + Light, /* pseudo register for full light matrix, mapped to registers L11L12-L33 */ + Color, /* pseudo register for full light color matrix, mapped to registers LR1LR2-LB3 */ + V0, /* pseudo register for full Vector 0, mapped to registers VXY0 and VZ0 */ + V1, /* pseudo register for full Vector 1, mapped to registers VXY1 and VZ1 */ + V2, /* pseudo register for full Vector 2, mapped to registers VXY2 and VZ2 */ + SV, /* pseudo register for full 16bit Accumulator Vector, mapped to registers IR1-IR3 */ + LV, /* pseudo register for full 32bit Maths Accumulator Vector, mapped to registers MAC1-MAC3 */ + Translation, /* pseudo register for full Translation vector, mapped to registers TRX-TRZ */ ScreenOffset, /* pseudo register for full Screen offset, mapped to registers OFX and OFY */ }; diff --git a/src/mips/psyqo/kernel.hh b/src/mips/psyqo/kernel.hh index bec3b5166..b91377754 100644 --- a/src/mips/psyqo/kernel.hh +++ b/src/mips/psyqo/kernel.hh @@ -262,10 +262,10 @@ void setBreakHandler(unsigned category, eastl::function&& handle /** * @brief Queues a break handler for psyqo's reserved category. - * + * * @param handler The handler to call when a break occurs. */ -void queuePsyqoBreakHandler(eastl::function && handler); +void queuePsyqoBreakHandler(eastl::function&& handler); namespace Internal { void pumpCallbacks(); diff --git a/src/mips/psyqo/primitive-concept.hh b/src/mips/psyqo/primitive-concept.hh index 883b7d7f7..730a03bdf 100644 --- a/src/mips/psyqo/primitive-concept.hh +++ b/src/mips/psyqo/primitive-concept.hh @@ -41,7 +41,9 @@ template concept Primitive = requires { { (alignof(Prim) & 3) == 0 }; { (sizeof(Prim) & 3) == 0 }; - { !requires { typename Prim::head; } }; + { + !requires { typename Prim::head; } + }; }; } // namespace psyqo diff --git a/src/mips/psyqo/src/cdrom-device-cdda.cpp b/src/mips/psyqo/src/cdrom-device-cdda.cpp index 4d9d2abdd..f4f1434e2 100644 --- a/src/mips/psyqo/src/cdrom-device-cdda.cpp +++ b/src/mips/psyqo/src/cdrom-device-cdda.cpp @@ -53,8 +53,7 @@ class PlayCDDAAction : public psyqo::CDRomDevice::Action { PlayCDDAAction() : Action("PlayCDDAAction") {} void start(psyqo::CDRomDevice *device, unsigned track, bool stopAtEndOfTrack, eastl::function &&callback) { - psyqo::Kernel::assert(device->isIdle(), - "CDRomDevice::playCDDA() called while another action is in progress"); + psyqo::Kernel::assert(device->isIdle(), "CDRomDevice::playCDDA() called while another action is in progress"); registerMe(device); setCallback(eastl::move(callback)); setState(PlayCDDAActionState::GETTD); @@ -64,8 +63,7 @@ class PlayCDDAAction : public psyqo::CDRomDevice::Action { } void start(psyqo::CDRomDevice *device, psyqo::MSF msf, bool stopAtEndOfTrack, eastl::function &&callback) { - psyqo::Kernel::assert(device->isIdle(), - "CDRomDevice::playCDDA() called while another action is in progress"); + psyqo::Kernel::assert(device->isIdle(), "CDRomDevice::playCDDA() called while another action is in progress"); registerMe(device); setCallback(eastl::move(callback)); setState(PlayCDDAActionState::SEEK); @@ -74,8 +72,7 @@ class PlayCDDAAction : public psyqo::CDRomDevice::Action { psyqo::Hardware::CDRom::Command.send(psyqo::Hardware::CDRom::CDL::SETMODE, stopAtEndOfTrack ? 3 : 1); } void start(psyqo::CDRomDevice *device, eastl::function &&callback) { - psyqo::Kernel::assert(device->isIdle(), - "CDRomDevice::playCDDA() called while another action is in progress"); + psyqo::Kernel::assert(device->isIdle(), "CDRomDevice::playCDDA() called while another action is in progress"); registerMe(device); setCallback(eastl::move(callback)); setState(PlayCDDAActionState::PLAY); diff --git a/src/mips/psyqo/src/cdrom-device-muteunmute.cpp b/src/mips/psyqo/src/cdrom-device-muteunmute.cpp index bbdf2a351..91b1df6bd 100644 --- a/src/mips/psyqo/src/cdrom-device-muteunmute.cpp +++ b/src/mips/psyqo/src/cdrom-device-muteunmute.cpp @@ -41,8 +41,7 @@ class MuteAction : public psyqo::CDRomDevice::Action { public: MuteAction() : Action("MuteAction") {} void start(psyqo::CDRomDevice *device, eastl::function &&callback) { - psyqo::Kernel::assert(device->isIdle(), - "CDRomDevice::mute() called while another action is in progress"); + psyqo::Kernel::assert(device->isIdle(), "CDRomDevice::mute() called while another action is in progress"); registerMe(device); setCallback(eastl::move(callback)); setState(MuteActionState::MUTE); @@ -79,8 +78,7 @@ class UnmuteAction : public psyqo::CDRomDevice::Action { public: UnmuteAction() : Action("UnmuteAction") {} void start(psyqo::CDRomDevice *device, eastl::function &&callback) { - psyqo::Kernel::assert(device->isIdle(), - "CDRomDevice::unmute() called while another action is in progress"); + psyqo::Kernel::assert(device->isIdle(), "CDRomDevice::unmute() called while another action is in progress"); registerMe(device); setCallback(eastl::move(callback)); setState(UnmuteActionState::UNMUTE); diff --git a/src/mips/psyqo/src/cdrom-device-reset.cpp b/src/mips/psyqo/src/cdrom-device-reset.cpp index a5f935687..c03ff341d 100644 --- a/src/mips/psyqo/src/cdrom-device-reset.cpp +++ b/src/mips/psyqo/src/cdrom-device-reset.cpp @@ -42,8 +42,7 @@ class ResetAction : public psyqo::CDRomDevice::Action { public: ResetAction() : Action("ResetAction") {} void start(psyqo::CDRomDevice *device, eastl::function &&callback) { - psyqo::Kernel::assert(device->isIdle(), - "CDRomDevice::reset() called while another action is in progress"); + psyqo::Kernel::assert(device->isIdle(), "CDRomDevice::reset() called while another action is in progress"); registerMe(device); setCallback(eastl::move(callback)); setState(ResetActionState::RESET); diff --git a/src/mips/psyqo/src/cdrom-device-toc.cpp b/src/mips/psyqo/src/cdrom-device-toc.cpp index 6dd04caa0..f6725f9c5 100644 --- a/src/mips/psyqo/src/cdrom-device-toc.cpp +++ b/src/mips/psyqo/src/cdrom-device-toc.cpp @@ -43,8 +43,7 @@ class GetTNAction : public psyqo::CDRomDevice::Action { public: GetTNAction() : Action("GetTNAction") {} void start(psyqo::CDRomDevice *device, unsigned *size, eastl::function &&callback) { - psyqo::Kernel::assert(device->isIdle(), - "CDRomDevice::getTOCSize() called while another action is in progress"); + psyqo::Kernel::assert(device->isIdle(), "CDRomDevice::getTOCSize() called while another action is in progress"); registerMe(device); setCallback(eastl::move(callback)); setState(GetTNActionEnum::GETTN); @@ -100,8 +99,7 @@ class ReadTOCAction : public psyqo::CDRomDevice::Action { public: ReadTOCAction() : Action("ReadTOCAction") {} void start(psyqo::CDRomDevice *device, psyqo::MSF *toc, unsigned size, eastl::function &&callback) { - psyqo::Kernel::assert(device->isIdle(), - "CDRomDevice::readTOC() called while another action is in progress"); + psyqo::Kernel::assert(device->isIdle(), "CDRomDevice::readTOC() called while another action is in progress"); registerMe(device); setCallback(eastl::move(callback)); setState(ReadTOCActionState::GETTN); diff --git a/src/mips/psyqo/src/ordering-table.cpp b/src/mips/psyqo/src/ordering-table.cpp index e4457eecc..dfb0d9632 100644 --- a/src/mips/psyqo/src/ordering-table.cpp +++ b/src/mips/psyqo/src/ordering-table.cpp @@ -35,7 +35,8 @@ void psyqo::OrderingTableBase::clear(uint32_t* table, size_t size) { } } -void psyqo::OrderingTableBase::insert(uint32_t* table, int32_t size, uint32_t* head, uint32_t shiftedFragmentSize, int32_t z) { +void psyqo::OrderingTableBase::insert(uint32_t* table, int32_t size, uint32_t* head, uint32_t shiftedFragmentSize, + int32_t z) { z = eastl::clamp(z, int32_t(0), size) + 1; *head = shiftedFragmentSize | table[z]; table[z] = reinterpret_cast(head) & 0xffffff; diff --git a/src/mips/psyqo/src/xprintf.c b/src/mips/psyqo/src/xprintf.c index b3ce6c687..8fbed5443 100644 --- a/src/mips/psyqo/src/xprintf.c +++ b/src/mips/psyqo/src/xprintf.c @@ -109,13 +109,13 @@ enum e_type { /* The type of the format field */ ** Each builtin conversion character (ex: the 'd' in "%d") is described ** by an instance of the following structure */ -typedef struct s_info { /* Information about each format field */ - int fmttype; /* The format field code letter */ - int base; /* The base for radix conversion, or the scale in fixed-point mode */ - const char *charset; /* The character set for conversion */ - int flag_signed; /* Is the quantity signed? */ - const char *prefix; /* Prefix on non-zero values in alt format */ - enum e_type type; /* Conversion paradigm */ +typedef struct s_info { /* Information about each format field */ + int fmttype; /* The format field code letter */ + int base; /* The base for radix conversion, or the scale in fixed-point mode */ + const char *charset; /* The character set for conversion */ + int flag_signed; /* Is the quantity signed? */ + const char *prefix; /* Prefix on non-zero values in alt format */ + enum e_type type; /* Conversion paradigm */ } info; /* diff --git a/src/mips/tests/cop0/exceptions.cpp b/src/mips/tests/cop0/exceptions.cpp index 803eb8af1..0fac532c5 100644 --- a/src/mips/tests/cop0/exceptions.cpp +++ b/src/mips/tests/cop0/exceptions.cpp @@ -68,8 +68,8 @@ static Handler<0x40> s_handler40; static Handler<0x80> s_handler80; extern "C" void installExceptionHandlers(uint32_t (*handler)(uint32_t *regs, uint32_t from)) { - uint32_t (*wrapper)(uint32_t * regs, uint32_t from, uint32_t(*handler)(uint32_t * regs, uint32_t from)) = - [](uint32_t *regs, uint32_t from, uint32_t (*handler)(uint32_t * regs, uint32_t from)) -> uint32_t { + uint32_t (*wrapper)(uint32_t *regs, uint32_t from, uint32_t (*handler)(uint32_t *regs, uint32_t from)) = + [](uint32_t *regs, uint32_t from, uint32_t (*handler)(uint32_t *regs, uint32_t from)) -> uint32_t { return handler(regs, from); }; __asm__ volatile( diff --git a/src/mips/ucl-demo/ucl-demo.cpp b/src/mips/ucl-demo/ucl-demo.cpp index afc9e9449..dc77c4237 100644 --- a/src/mips/ucl-demo/ucl-demo.cpp +++ b/src/mips/ucl-demo/ucl-demo.cpp @@ -97,7 +97,7 @@ int main() { // to overlap the decompressed data by 16 bytes, in order to be able to safely decompress // in-place. In practice, it only requires about 4 bytes, but we will use 16 bytes here // as documented in the UCL library. - uint8_t * compressed = buffer + header.decompsize - header.compsize + 16; + uint8_t* compressed = buffer + header.decompsize - header.compsize + 16; r = PCread(fd, compressed, header.compsize); if (r != header.compsize) { diff --git a/src/support/opengl.h b/src/support/opengl.h index 4797eb4ee..14a01a5b6 100644 --- a/src/support/opengl.h +++ b/src/support/opengl.h @@ -43,7 +43,7 @@ namespace OpenGL { class [[nodiscard]] Status : private std::optional { public: Status(const Status&) = default; - Status(Status &&) = default; + Status(Status&&) = default; Status& operator=(const Status&) = default; Status& operator=(Status&&) = default; bool isOk() const { return !has_value(); } diff --git a/src/support/protobuf.h b/src/support/protobuf.h index b6dccd902..a14069b6f 100644 --- a/src/support/protobuf.h +++ b/src/support/protobuf.h @@ -701,9 +701,9 @@ struct MessageField, fieldNumberValue> : pu MessageField(const MessageType &value) : MessageType(value) {} MessageField(MessageType &value) : MessageType(value) {} template - MessageField(const fields &... values) : MessageType(values...) {} + MessageField(const fields &...values) : MessageType(values...) {} template - MessageField(fields &&... values) : MessageType(std::move(values)...) {} + MessageField(fields &&...values) : MessageType(std::move(values)...) {} static constexpr bool matches(unsigned wireType) { return wireType == 2; } static constexpr unsigned wireType = 2; static constexpr uint64_t fieldNumber = fieldNumberValue; @@ -739,8 +739,8 @@ class Message, fields...> : private std::tuple(); } - Message(const fields &... values) : base(values...) { verifyIntegrity<0, fields...>(); } - Message(fields &&... values) : base(std::move(values)...) { verifyIntegrity<0, fields...>(); } + Message(const fields &...values) : base(values...) { verifyIntegrity<0, fields...>(); } + Message(fields &&...values) : base(std::move(values)...) { verifyIntegrity<0, fields...>(); } using name = irqus::typestring; static constexpr char const typeName[sizeof...(C) + 1] = {C..., '\0'}; static constexpr void dumpSchema(std::ostream &stream) { diff --git a/src/support/settings.h b/src/support/settings.h index a954267c0..4f65c5e58 100644 --- a/src/support/settings.h +++ b/src/support/settings.h @@ -294,8 +294,7 @@ struct SettingNested, nestedSettings> : public nestedSet return 1; }, -1); - L.declareFunc( - "newindex", [](Lua L) -> int { return 0; }, -1); + L.declareFunc("newindex", [](Lua L) -> int { return 0; }, -1); L.declareFunc( "reset", [this](Lua L) -> int { diff --git a/src/support/uvfile.cc b/src/support/uvfile.cc index 867e7ebbe..2a14a6e97 100644 --- a/src/support/uvfile.cc +++ b/src/support/uvfile.cc @@ -481,8 +481,7 @@ ssize_t PCSX::UvFile::read(void *dest, size_t size) { ssize_t PCSX::UvFile::write(const void *src, size_t size) { if (!writable()) return -1; if (m_cache) { - while (m_cacheProgress.load(std::memory_order_relaxed) != 1.0) - ; + while (m_cacheProgress.load(std::memory_order_relaxed) != 1.0); size_t newSize = m_ptrW + size; if (newSize > m_size) { m_cache = reinterpret_cast(realloc(m_cache, newSize)); @@ -529,8 +528,7 @@ ssize_t PCSX::UvFile::write(const void *src, size_t size) { void PCSX::UvFile::write(Slice &&slice) { if (!writable()) return; if (m_cache) { - while (m_cacheProgress.load(std::memory_order_relaxed) != 1.0) - ; + while (m_cacheProgress.load(std::memory_order_relaxed) != 1.0); size_t newSize = m_ptrW + slice.size(); if (newSize > m_size) { m_cache = reinterpret_cast(realloc(m_cache, newSize)); @@ -629,8 +627,7 @@ ssize_t PCSX::UvFile::readAt(void *dest, size_t size, size_t ptr) { ssize_t PCSX::UvFile::writeAt(const void *src, size_t size, size_t ptr) { if (!writable()) return -1; if (m_cache) { - while (m_cacheProgress.load(std::memory_order_acquire) != 1.0) - ; + while (m_cacheProgress.load(std::memory_order_acquire) != 1.0); size_t newSize = ptr + size; if (newSize > m_size) { m_cache = reinterpret_cast(realloc(m_cache, newSize)); @@ -673,8 +670,7 @@ ssize_t PCSX::UvFile::writeAt(const void *src, size_t size, size_t ptr) { void PCSX::UvFile::writeAt(Slice &&slice, size_t ptr) { if (!writable()) return; if (m_cache) { - while (m_cacheProgress.load(std::memory_order_acquire) != 1.0) - ; + while (m_cacheProgress.load(std::memory_order_acquire) != 1.0); size_t newSize = ptr + slice.size(); if (newSize > m_size) { m_cache = reinterpret_cast(realloc(m_cache, newSize)); @@ -874,8 +870,7 @@ ssize_t PCSX::UvFifo::read(void *dest_, size_t size) { if (m_size.load() == 0) { return ret == 0 ? -1 : ret; } - while (!m_queue.Dequeue(m_slice)) - ; + while (!m_queue.Dequeue(m_slice)); } auto toRead = std::min(size, static_cast(m_slice.size()) - m_currentPtr); memcpy(dest, m_slice.data() + m_currentPtr, toRead); diff --git a/src/support/uvfile.h b/src/support/uvfile.h index 609b1ba6c..a2b8e871a 100644 --- a/src/support/uvfile.h +++ b/src/support/uvfile.h @@ -152,8 +152,9 @@ class UvFile : public File, public UvThreadOp { virtual bool eof() final override; virtual std::filesystem::path filename() final override { return m_filename; } virtual File* dup() final override { - return m_download ? new UvFile(m_filename.string(), DOWNLOAD_URL) - : writable() ? new UvFile(m_filename, FileOps::READWRITE) : new UvFile(m_filename); + return m_download ? new UvFile(m_filename.string(), DOWNLOAD_URL) + : writable() ? new UvFile(m_filename, FileOps::READWRITE) + : new UvFile(m_filename); } // Open the file in read-only mode. diff --git a/src/support/version-windows.cc b/src/support/version-windows.cc index 3427c5f19..87e1765df 100644 --- a/src/support/version-windows.cc +++ b/src/support/version-windows.cc @@ -150,8 +150,7 @@ bool PCSX::Update::applyUpdate(const std::filesystem::path& binDir) { _freea(str); #endif - while (!std::filesystem::exists(tmp / "pcsx-redux-update.started")) - ; + while (!std::filesystem::exists(tmp / "pcsx-redux-update.started")); return true; } From f20f438b2794d9f238177573b490f76c91710482 Mon Sep 17 00:00:00 2001 From: Elias Daler Date: Mon, 21 Oct 2024 17:22:06 +0200 Subject: [PATCH 09/29] Fix bug in writeSafe --- src/mips/psyqo/gte-registers.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mips/psyqo/gte-registers.hh b/src/mips/psyqo/gte-registers.hh index ba33cc971..c9abc588b 100644 --- a/src/mips/psyqo/gte-registers.hh +++ b/src/mips/psyqo/gte-registers.hh @@ -843,7 +843,7 @@ inline void writeSafe(const Vec3& in) { template <> inline void writeSafe(const Vec3& in) { write(in.x.raw()); - write(in.y.raw()); + write(in.y.raw()); write(in.z.raw()); } From a06067ddf52cdd358b6bbd333735c8bae511ee1c Mon Sep 17 00:00:00 2001 From: Jan Racek Date: Tue, 22 Oct 2024 20:38:24 +0200 Subject: [PATCH 10/29] Fixed mac0 value casting in psyqo cube example and implemented Nicolas' inline assembly fix --- src/mips/psyqo/examples/cube/cube.cpp | 8 ++++---- src/mips/psyqo/gte-registers.hh | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mips/psyqo/examples/cube/cube.cpp b/src/mips/psyqo/examples/cube/cube.cpp index ab348333e..395f9fe04 100644 --- a/src/mips/psyqo/examples/cube/cube.cpp +++ b/src/mips/psyqo/examples/cube/cube.cpp @@ -174,8 +174,8 @@ void CubeScene::frame() { psyqo::GTE::Kernels::nclip(); // Read the result of nclip and skip rendering this face if it's not facing us - uint32_t mac0 = 0; - psyqo::GTE::read(&mac0); + int32_t mac0 = 0; + psyqo::GTE::read(reinterpret_cast(&mac0)); if (mac0 <= 0) continue; // Since the GTE can only handle 3 vertices at a time, we need to store our first vertex @@ -190,8 +190,8 @@ void CubeScene::frame() { // Calculate the average Z for the z-Index to be put in the ordering table psyqo::GTE::Kernels::avsz4(); - uint32_t zIndex = 0; - psyqo::GTE::read(&zIndex); + int32_t zIndex = 0; + psyqo::GTE::read(reinterpret_cast(&zIndex)); // If the Z-index is out of bounds for our ordering table, we skip rendering this face. if (zIndex < 0 || zIndex >= ORDERING_TABLE_SIZE) continue; diff --git a/src/mips/psyqo/gte-registers.hh b/src/mips/psyqo/gte-registers.hh index c9abc588b..b210559e1 100644 --- a/src/mips/psyqo/gte-registers.hh +++ b/src/mips/psyqo/gte-registers.hh @@ -386,7 +386,7 @@ template static inline void read(uint32_t* ptr) { static_assert(reg < Register::R11R12, "Unable to read from register to memory directly"); if constexpr (reg < Register::R11R12) { - asm volatile("swc2 $%1, 0(%0)" ::"r"(ptr), "i"(static_cast(reg))); + asm volatile("swc2 $%2, 0(%1)" : "=m"(*ptr) : "r"(ptr), "i"(static_cast(reg))); } } From d4f7ad6fad9f282679ddd40dfbcf3d6cf775e429 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Tue, 22 Oct 2024 20:02:22 -0700 Subject: [PATCH 11/29] Adding interpolateColors to gouraud primitives. This needs to be used with the GTE pre-loaded with IR0 and the far color registers. --- src/mips/psyqo/primitives/common.hh | 4 ++ src/mips/psyqo/primitives/quads.hh | 86 ++++++++++++++++++++++++++ src/mips/psyqo/primitives/triangles.hh | 70 +++++++++++++++++++++ 3 files changed, 160 insertions(+) diff --git a/src/mips/psyqo/primitives/common.hh b/src/mips/psyqo/primitives/common.hh index cc79bc558..993ff1fbd 100644 --- a/src/mips/psyqo/primitives/common.hh +++ b/src/mips/psyqo/primitives/common.hh @@ -101,6 +101,10 @@ enum SemiTrans { HalfBackAndHalfFront, FullBackAndFullFront, FullBackSubFullFron enum ColorMode { Tex4Bits, Tex8Bits, Tex16Bits }; } // namespace Prim::TPageAttr +namespace Prim { + enum class Transparency { Auto, Opaque, SemiTransparent }; +} + namespace PrimPieces { /** diff --git a/src/mips/psyqo/primitives/quads.hh b/src/mips/psyqo/primitives/quads.hh index ecef146fb..440dbf404 100644 --- a/src/mips/psyqo/primitives/quads.hh +++ b/src/mips/psyqo/primitives/quads.hh @@ -28,6 +28,8 @@ SOFTWARE. #include +#include "psyqo/gte-kernels.hh" +#include "psyqo/gte-registers.hh" #include "psyqo/primitives/common.hh" namespace psyqo { @@ -188,6 +190,48 @@ struct GouraudQuad { pointD = v; return *this; } + template + void interpolateColors(const Color* a, const Color* b, const Color* c, const Color* d) { + uint32_t rgb; + if constexpr (transparency == Transparency::Auto) { + rgb = (a->packed & 0xffffff) | (command & 0xff000000); + } else if constexpr (transparency == Transparency::Opaque) { + rgb = (a->packed & 0xffffff) | 0x38000000; + } else if constexpr (transparency == Transparency::SemiTransparent) { + rgb = (a->packed & 0xffffff) | 0x3a000000; + } + GTE::write(rgb); + GTE::Kernels::dpcs(); + GTE::read(&command); + GTE::write(&b->packed); + GTE::write(&c->packed); + GTE::write(&d->packed); + GTE::Kernels::dpct(); + GTE::read(&colorB.packed); + GTE::read(&colorC.packed); + GTE::read(&colorD.packed); + } + template + void interpolateColors(Color a, Color b, Color c, Color d) { + uint32_t rgb; + if constexpr (transparency == Transparency::Auto) { + rgb = (a.packed & 0xffffff) | (command & 0xff000000); + } else if constexpr (transparency == Transparency::Opaque) { + rgb = (a.packed & 0xffffff) | 0x38000000; + } else if constexpr (transparency == Transparency::SemiTransparent) { + rgb = (a.packed & 0xffffff) | 0x3a000000; + } + GTE::write(rgb); + GTE::Kernels::dpcs(); + GTE::read(&command); + GTE::write(b.packed); + GTE::write(c.packed); + GTE::write(d.packed); + GTE::Kernels::dpct(); + GTE::read(&colorB.packed); + GTE::read(&colorC.packed); + GTE::read(&colorD.packed); + } private: uint32_t command; @@ -246,6 +290,48 @@ struct GouraudTexturedQuad { command |= 0x02000000; return *this; } + template + void interpolateColors(const Color* a, const Color* b, const Color* c, const Color* d) { + uint32_t rgb; + if constexpr (transparency == Transparency::Auto) { + rgb = (a->packed & 0xffffff) | (command & 0xff000000); + } else if constexpr (transparency == Transparency::Opaque) { + rgb = (a->packed & 0xffffff) | 0x3c000000; + } else if constexpr (transparency == Transparency::SemiTransparent) { + rgb = (a->packed & 0xffffff) | 0x3e000000; + } + GTE::write(rgb); + GTE::Kernels::dpcs(); + GTE::read(&command); + GTE::write(&b->packed); + GTE::write(&c->packed); + GTE::write(&d->packed); + GTE::Kernels::dpct(); + GTE::read(&colorB.packed); + GTE::read(&colorC.packed); + GTE::read(&colorD.packed); + } + template + void interpolateColors(Color a, Color b, Color c, Color d) { + uint32_t rgb; + if constexpr (transparency == Transparency::Auto) { + rgb = (a.packed & 0xffffff) | (command & 0xff000000); + } else if constexpr (transparency == Transparency::Opaque) { + rgb = (a.packed & 0xffffff) | 0x3c000000; + } else if constexpr (transparency == Transparency::SemiTransparent) { + rgb = (a.packed & 0xffffff) | 0x3e000000; + } + GTE::write(rgb); + GTE::Kernels::dpcs(); + GTE::read(&command); + GTE::write(b.packed); + GTE::write(c.packed); + GTE::write(d.packed); + GTE::Kernels::dpct(); + GTE::read(&colorB.packed); + GTE::read(&colorC.packed); + GTE::read(&colorD.packed); + } private: uint32_t command; diff --git a/src/mips/psyqo/primitives/triangles.hh b/src/mips/psyqo/primitives/triangles.hh index fe2266cc1..d5753c7c4 100644 --- a/src/mips/psyqo/primitives/triangles.hh +++ b/src/mips/psyqo/primitives/triangles.hh @@ -28,6 +28,8 @@ SOFTWARE. #include +#include "psyqo/gte-kernels.hh" +#include "psyqo/gte-registers.hh" #include "psyqo/primitives/common.hh" namespace psyqo { @@ -167,6 +169,40 @@ struct GouraudTriangle { pointC = v; return *this; } + template + void interpolateColors(const Color* a, const Color* b, const Color* c) { + GTE::write(&a->packed); + GTE::write(&b->packed); + GTE::write(&c->packed); + if constexpr (transparency == Transparency::Auto) { + GTE::write(&command); + } else if constexpr (transparency == Transparency::Opaque) { + GTE::write(0x30000000); + } else if constexpr (transparency == Transparency::SemiTransparent) { + GTE::write(0x32000000); + } + GTE::Kernels::dpct(); + GTE::read(&command); + GTE::read(&colorB.packed); + GTE::read(&colorC.packed); + } + template + void interpolateColors(Color a, Color b, Color c) { + GTE::write(a.packed); + GTE::write(b.packed); + GTE::write(c.packed); + if constexpr (transparency == Transparency::Auto) { + GTE::write(&command); + } else if constexpr (transparency == Transparency::Opaque) { + GTE::write(0x30000000); + } else if constexpr (transparency == Transparency::SemiTransparent) { + GTE::write(0x32000000); + } + GTE::Kernels::dpct(); + GTE::read(&command); + GTE::read(&colorB.packed); + GTE::read(&colorC.packed); + } private: uint32_t command; @@ -218,6 +254,40 @@ struct GouraudTexturedTriangle { command |= 0x02000000; return *this; } + template + void interpolateColors(const Color* a, const Color* b, const Color* c) { + GTE::write(&a->packed); + GTE::write(&b->packed); + GTE::write(&c->packed); + if constexpr (transparency == Transparency::Auto) { + GTE::write(&command); + } else if constexpr (transparency == Transparency::Opaque) { + GTE::write(0x34000000); + } else if constexpr (transparency == Transparency::SemiTransparent) { + GTE::write(0x36000000); + } + GTE::Kernels::dpct(); + GTE::read(&command); + GTE::read(&colorB.packed); + GTE::read(&colorC.packed); + } + template + void interpolateColors(Color a, Color b, Color c) { + GTE::write(a.packed); + GTE::write(b.packed); + GTE::write(c.packed); + if constexpr (transparency == Transparency::Auto) { + GTE::write(&command); + } else if constexpr (transparency == Transparency::Opaque) { + GTE::write(0x34000000); + } else if constexpr (transparency == Transparency::SemiTransparent) { + GTE::write(0x36000000); + } + GTE::Kernels::dpct(); + GTE::read(&command); + GTE::read(&colorB.packed); + GTE::read(&colorC.packed); + } private: uint32_t command; From 63459798c4fbb62e6ebb760375e99829fa9f7467 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Tue, 22 Oct 2024 21:22:06 -0700 Subject: [PATCH 12/29] Making the bump allocator more generic. Also, breaks established API, unfortunately. --- src/mips/psyqo/advancedpad.hh | 2 -- src/mips/psyqo/bump-allocator.h | 27 ++++++++++++++++----------- src/mips/psyqo/fragment-concept.hh | 3 ++- src/mips/psyqo/primitive-concept.hh | 3 --- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/mips/psyqo/advancedpad.hh b/src/mips/psyqo/advancedpad.hh index 0095ee530..0488eb41f 100644 --- a/src/mips/psyqo/advancedpad.hh +++ b/src/mips/psyqo/advancedpad.hh @@ -29,8 +29,6 @@ SOFTWARE. #include #include -#include "psyqo/application.hh" - namespace psyqo { /** diff --git a/src/mips/psyqo/bump-allocator.h b/src/mips/psyqo/bump-allocator.h index 7fb6eb8e6..074c9fa93 100644 --- a/src/mips/psyqo/bump-allocator.h +++ b/src/mips/psyqo/bump-allocator.h @@ -28,7 +28,6 @@ SOFTWARE. #include -#include "psyqo/fragment-concept.hh" #include "psyqo/fragments.hh" #include "psyqo/primitive-concept.hh" @@ -53,19 +52,25 @@ namespace psyqo { template class BumpAllocator { public: - template - Fragments::SimpleFragment

&allocate() { - constexpr size_t size = sizeof(Fragments::SimpleFragment

); - auto *ptr = m_current; + template + Fragments::SimpleFragment

&allocateFragment(Args ...args) { + static constexpr size_t size = sizeof(Fragments::SimpleFragment

); + uint8_t *ptr = m_current; m_current += size; - return *new (ptr) Fragments::SimpleFragment

(); + return *new (ptr) Fragments::SimpleFragment

(args...); } - template - F &allocate() { - constexpr size_t size = sizeof(F); - auto *ptr = m_current; + template + T &allocate(Args ...args) { + size_t size = sizeof(T); + uint8_t *ptr = m_current; + if constexpr (alignof(T) > 1) { + static constexpr size_t a = alignof(T) - 1; + auto alignedptr = reinterpret_cast((reinterpret_cast(ptr) + a) & ~a); + size += alignedptr - ptr; + ptr = alignedptr; + } m_current += size; - return *new (ptr) F(); + return *new (ptr) T(args...); } void reset() { m_current = m_memory; } diff --git a/src/mips/psyqo/fragment-concept.hh b/src/mips/psyqo/fragment-concept.hh index 9c125baca..f025dd5ee 100644 --- a/src/mips/psyqo/fragment-concept.hh +++ b/src/mips/psyqo/fragment-concept.hh @@ -26,8 +26,9 @@ SOFTWARE. #pragma once +#include + #include -#include #include namespace psyqo { diff --git a/src/mips/psyqo/primitive-concept.hh b/src/mips/psyqo/primitive-concept.hh index 730a03bdf..ee16beb8c 100644 --- a/src/mips/psyqo/primitive-concept.hh +++ b/src/mips/psyqo/primitive-concept.hh @@ -26,9 +26,6 @@ SOFTWARE. #pragma once -#include -#include - namespace psyqo { /** From 6ac48420d91f5ced68bb9f3b6ab90a3d9766db05 Mon Sep 17 00:00:00 2001 From: Nicolas 'Pixel' Noble Date: Wed, 23 Oct 2024 18:16:57 -0700 Subject: [PATCH 13/29] Having a crt0 for C++ which: - passes the arguments throught - uses pcsx_exit - implements strlen and memchr as weak symbols - implements std::terminate - calls pcsx_exit on abort --- src/mips/common/crt0/cxxglue.c | 37 ++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/mips/common/crt0/cxxglue.c b/src/mips/common/crt0/cxxglue.c index c6f6a2c44..80610b742 100644 --- a/src/mips/common/crt0/cxxglue.c +++ b/src/mips/common/crt0/cxxglue.c @@ -43,9 +43,9 @@ extern fptr __preinit_array_end[] __attribute__((weak)); extern fptr __init_array_start[] __attribute__((weak)); extern fptr __init_array_end[] __attribute__((weak)); -void main(); +int main(int argc, char ** argv); -void cxxmain() { +void cxxmain(int argc, char ** argv) { size_t count, i; count = __preinit_array_end - __preinit_array_start; @@ -64,13 +64,42 @@ void cxxmain() { } } - main(); + pcsx_exit(main(argc, argv)); +} + +// These two technically aren't part of the standard library requirements, but can +// be invoked by the freestanding libstdc++, so might as well. +__attribute__((weak)) size_t strlen(const char * s) { + size_t r = 0; + + while (*s++) r++; + + return r; +} + +__attribute__((weak)) const void * memchr(const void * _s, int c, size_t n) { + const uint8_t * s = (uint8_t *) _s; + size_t i; + + for (i = 0; i < n; i++, s++) { + if (*s == c) return s; + } + + return NULL; +} + +// std::terminate(), called by the freestanding libstdc++ instead of +// throwing exceptions, when they are disabled. +__attribute__((weak)) void _ZSt9terminatev() { + pcsx_exit(-1); + while (1) asm(""); } __attribute__((weak)) void abort() { pcsx_debugbreak(); + pcsx_exit(-1); // TODO: make this better - while (1); + while (1) asm(""); } // This will be called if a pure virtual function is called, usually mistakenly calling From e120a3dc0f42b204a24b54a6704418d75b780681 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 23 Oct 2024 20:28:16 -0700 Subject: [PATCH 14/29] VSCode extension work - Adding psyqo cube example - Adding darwin arm support for pcsx-redux --- tools/vscode-extension/README.md | 4 +- tools/vscode-extension/pcsx-redux.js | 10 +- tools/vscode-extension/templates.js | 27 +++ .../templates/psyqo/cube/Makefile | 7 + .../templates/psyqo/cube/compile_flags.txt | 7 + .../templates/psyqo/cube/main.cpp | 197 ++++++++++++++++++ 6 files changed, 249 insertions(+), 3 deletions(-) create mode 100644 tools/vscode-extension/templates/psyqo/cube/Makefile create mode 100644 tools/vscode-extension/templates/psyqo/cube/compile_flags.txt create mode 100644 tools/vscode-extension/templates/psyqo/cube/main.cpp diff --git a/tools/vscode-extension/README.md b/tools/vscode-extension/README.md index 643f20173..242b1b72c 100644 --- a/tools/vscode-extension/README.md +++ b/tools/vscode-extension/README.md @@ -13,7 +13,6 @@ The panel will have the ability to install the tools on the most popular platfor - The extension is currently only targeting Windows, Linux Ubuntu, Arch Linux, and MacOS. It may work on more platforms, but it's not guaranteed, and won't be as automated as it is on the supported platforms. - Only Windows and Linux Ubuntu have been thoroughly tested for now. - The extension will not work from the browser as it requires running external tools. It may work in a remote SSH session, but it's not been tested. -- The PCSX-Redux dependency is currently only available on x86_64 platforms, and may possibly work on M1/M2 Macs. - Linux requires libfuse2 to be installed, for AppImages like the PCSX-Redux dependency to work. - The PCSX-Redux workflow won't check for system-wide installations, and will always install the dependency locally. @@ -21,6 +20,9 @@ The panel will have the ability to install the tools on the most popular platfor - 0.3.8 - Added automatic setup of Python virtual environments in order to reflect the changes in ps1-bare-metal. + - Fixed compile_flags.txt in template file. + - Added psyqo cube example. + - Added download support for Darwin ARM64 (M1/M2/etc) for PCSX-Redux. - 0.3.7 - Bumping gcc to 14.2.0 - Bumping binutils to 2.43 diff --git a/tools/vscode-extension/pcsx-redux.js b/tools/vscode-extension/pcsx-redux.js index 318ebd09f..5018713da 100644 --- a/tools/vscode-extension/pcsx-redux.js +++ b/tools/vscode-extension/pcsx-redux.js @@ -27,9 +27,13 @@ const updateInfo = { infoBase: 'https://distrib.app/storage/manifests/pcsx-redux/dev-linux-x64/', fileType: 'zip' }, - darwin: { + darwin_Intel: { infoBase: 'https://distrib.app/storage/manifests/pcsx-redux/dev-macos-x64/', fileType: 'dmg' + }, + darwin_Arm: { + infoBase: 'https://distrib.app/storage/manifests/pcsx-redux/dev-macos-arm/', + fileType: 'dmg' } } @@ -101,7 +105,9 @@ exports.install = async () => { } } - const updateInfoForPlatform = updateInfo[process.platform] + const darwinArch = process.arch === 'arm64' ? 'Arm' : 'Intel' + const platform = process.platform === 'darwin' ? 'darwin_' + darwinArch : process.platform + const updateInfoForPlatform = updateInfo[platform] const outputDir = process.platform === 'win32' ? vscode.Uri.joinPath(globalStorageUri, 'pcsx-redux').fsPath diff --git a/tools/vscode-extension/templates.js b/tools/vscode-extension/templates.js index fd505e085..f9e6436d6 100644 --- a/tools/vscode-extension/templates.js +++ b/tools/vscode-extension/templates.js @@ -767,6 +767,33 @@ const templates = { ) } }, + psyqo_cube: { + name: 'PSYQo Cube', + category: 'PSYQo SDK', + description: 'A project featuring a rotating cube using the PSYQo SDK.', + url: 'https://github.com/pcsx-redux/nugget/tree/main/psyqo#how', + examples: + 'https://github.com/grumpycoders/pcsx-redux/tree/main/src/mips/psyqo/examples', + requiredTools: ['git', 'make', 'toolchain'], + recommendedTools: ['gdb', 'debugger', 'redux'], + create: async function (fullPath, name, progressReporter) { + const git = await createGitRepository( + fullPath, + psyqoTemplate, + progressReporter + ) + await copyTemplateDirectory( + git, + fullPath, + name, + [ + path.join(extensionUri.fsPath, 'templates', 'common'), + path.join(extensionUri.fsPath, 'templates', 'psyqo', 'cube') + ], + { projectName: name, isCMake: false } + ) + } + }, psyq_netyaroze: { name: 'Net Yaroze Sprite', category: 'Psy-Q SDK', diff --git a/tools/vscode-extension/templates/psyqo/cube/Makefile b/tools/vscode-extension/templates/psyqo/cube/Makefile new file mode 100644 index 000000000..7936fcd0c --- /dev/null +++ b/tools/vscode-extension/templates/psyqo/cube/Makefile @@ -0,0 +1,7 @@ +TARGET = {{projectName}} +TYPE = ps-exe + +SRCS = \ +main.cpp + +include third_party/nugget/psyqo/psyqo.mk diff --git a/tools/vscode-extension/templates/psyqo/cube/compile_flags.txt b/tools/vscode-extension/templates/psyqo/cube/compile_flags.txt new file mode 100644 index 000000000..a0d792fec --- /dev/null +++ b/tools/vscode-extension/templates/psyqo/cube/compile_flags.txt @@ -0,0 +1,7 @@ +-m32 +-std=c++20 +-fcoroutines-ts +-I. +-Ithird_party/nugget +-Ithird_party/nugget/third_party/EASTL/include +-Ithird_party/nugget/third_party/EABase/include/Common diff --git a/tools/vscode-extension/templates/psyqo/cube/main.cpp b/tools/vscode-extension/templates/psyqo/cube/main.cpp new file mode 100644 index 000000000..2a439c2f4 --- /dev/null +++ b/tools/vscode-extension/templates/psyqo/cube/main.cpp @@ -0,0 +1,197 @@ +{{=<% %>=}}#include "psyqo/application.hh" +#include "psyqo/fixed-point.hh" +#include "psyqo/fragments.hh" +#include "psyqo/gpu.hh" +#include "psyqo/gte-kernels.hh" +#include "psyqo/gte-registers.hh" +#include "psyqo/primitives/common.hh" +#include "psyqo/primitives/quads.hh" +#include "psyqo/scene.hh" +#include "psyqo/soft-math.hh" +#include "psyqo/trigonometry.hh" +#include "psyqo/vector.hh" + +using namespace psyqo::fixed_point_literals; +using namespace psyqo::trig_literals; + +static constexpr unsigned NUM_CUBE_VERTICES = 8; +static constexpr unsigned NUM_CUBE_FACES = 6; +static constexpr unsigned ORDERING_TABLE_SIZE = 240; + +typedef struct { + uint8_t vertices[4]; + psyqo::Color color; +} Face; + +static constexpr psyqo::Matrix33 identity = {{ + {1.0_fp, 0.0_fp, 0.0_fp}, + {0.0_fp, 1.0_fp, 0.0_fp}, + {0.0_fp, 0.0_fp, 1.0_fp}, +}}; + +class Cube final : public psyqo::Application { + void prepare() override; + void createScene() override; + + public: + psyqo::Trig<> m_trig; +}; + +class CubeScene final : public psyqo::Scene { + void start(StartReason reason) override; + void frame() override; + + psyqo::Angle m_rot = 0; + + // We need to create 2 OrderingTable objects since we can't reuse a single one for both + // framebuffers, as the previous one may not finish transfering in time. + psyqo::OrderingTable m_ots[2]; + + // Since we're using an ordering table, we need to sort fill commands as well, + // otherwise they'll draw over our beautiful cube. + psyqo::Fragments::SimpleFragment m_clear[2]; + + eastl::array, 6> m_quads; + + static constexpr psyqo::Color c_bg = {.r = 63, .g = 63, .b = 63}; + + static constexpr psyqo::Vec3 c_cubeVertices[NUM_CUBE_VERTICES] = { + {.x = -0.05, .y = -0.05, .z = -0.05}, {.x = 0.05, .y = -0.05, .z = -0.05}, {.x = -0.05, .y = 0.05, .z = -0.05}, + {.x = 0.05, .y = 0.05, .z = -0.05}, {.x = -0.05, .y = -0.05, .z = 0.05}, {.x = 0.05, .y = -0.05, .z = 0.05}, + {.x = -0.05, .y = 0.05, .z = 0.05}, {.x = 0.05, .y = 0.05, .z = 0.05}}; + + static constexpr Face c_cubeFaces[NUM_CUBE_FACES] = { + {.vertices = {0, 1, 2, 3}, .color = {0, 0, 255}}, {.vertices = {6, 7, 4, 5}, .color = {0, 255, 0}}, + {.vertices = {4, 5, 0, 1}, .color = {0, 255, 255}}, {.vertices = {7, 6, 3, 2}, .color = {255, 0, 0}}, + {.vertices = {6, 4, 2, 0}, .color = {255, 0, 255}}, {.vertices = {5, 7, 1, 3}, .color = {255, 255, 0}}}; +}; + +static Cube cube; +static CubeScene cubeScene; + +void Cube::prepare() { + psyqo::GPU::Configuration config; + config.set(psyqo::GPU::Resolution::W320) + .set(psyqo::GPU::VideoMode::AUTO) + .set(psyqo::GPU::ColorMode::C15BITS) + .set(psyqo::GPU::Interlace::PROGRESSIVE); + + gpu().initialize(config); +} + +void Cube::createScene() { pushScene(&cubeScene); } + +void CubeScene::start(StartReason reason) { + // Clear the translation registers + psyqo::GTE::clear(); + psyqo::GTE::clear(); + psyqo::GTE::clear(); + + // Set the screen offset in the GTE. (this is half the X and Y resolutions as standard) + psyqo::GTE::write(psyqo::FixedPoint<16>(160.0).raw()); + psyqo::GTE::write(psyqo::FixedPoint<16>(120.0).raw()); + + // Write the projection plane distance. + psyqo::GTE::write(120); + + // Set the scaling for Z averaging. + psyqo::GTE::write(ORDERING_TABLE_SIZE / 3); + psyqo::GTE::write(ORDERING_TABLE_SIZE / 4); +} + +void CubeScene::frame() { + eastl::array projected; + + // Get which frame we're currently drawing + int parity = gpu().getParity(); + + // Get our current ordering table and fill command + auto& ot = m_ots[parity]; + auto& clear = m_clear[parity]; + + // Chain the fill command accordingly to clear the buffer + gpu().getNextClear(clear.primitive, c_bg); + gpu().chain(clear); + + // We want the cube to appear slightly further away, so we translate it by 512 on the Z-axis. + psyqo::GTE::write(512); + + // Here we're setting up the rotation for the spinning cube + // First, generate a rotation matrix for the X-axis and Y-axis + auto transform = psyqo::SoftMath::generateRotationMatrix33(m_rot, psyqo::SoftMath::Axis::X, cube.m_trig); + auto rot = psyqo::SoftMath::generateRotationMatrix33(m_rot, psyqo::SoftMath::Axis::Y, cube.m_trig); + + // Multiply the X and Y rotation matrices together + psyqo::SoftMath::multiplyMatrix33(transform, rot, &transform); + + // Generate a Z-axis rotation matrix (Empty, but it's here for your use) + psyqo::SoftMath::generateRotationMatrix33(0, 0, psyqo::SoftMath::Axis::Z, cube.m_trig); + + // Apply the combined rotation and write it to the pseudo register for the cube's rotation + psyqo::SoftMath::multiplyMatrix33(transform, rot, &transform); + psyqo::GTE::writeUnsafe(transform); + + int faceNum = 0; + + for (auto face : c_cubeFaces) { + // We load the first 3 vertices into the GTE. We can't do all 4 at once because the GTE + // handles only 3 at a time... + psyqo::GTE::writeUnsafe(c_cubeVertices[face.vertices[0]]); + psyqo::GTE::writeUnsafe(c_cubeVertices[face.vertices[1]]); + psyqo::GTE::writeUnsafe(c_cubeVertices[face.vertices[2]]); + + // We perform rtpt (Perspective transformation) to the three verticies. + psyqo::GTE::Kernels::rtpt(); + + // Nclip determines the winding of the vertices, used to check which direction the face is pointing. + // Clockwise winding means the face is oriented towards us. + psyqo::GTE::Kernels::nclip(); + + // Read the result of nclip and skip rendering this face if it's not facing us + int32_t mac0 = 0; + psyqo::GTE::read(reinterpret_cast(&mac0)); + if (mac0 <= 0) continue; + + // Since the GTE can only handle 3 vertices at a time, we need to store our first vertex + // so we can write our last one. + psyqo::GTE::read(&projected[0].packed); + + // Write the last vertex + psyqo::GTE::writeSafe(c_cubeVertices[face.vertices[3]]); + + // Perform rtps (Perspective transformation) to the last vertice (rtpS - single, rtpT - triple). + psyqo::GTE::Kernels::rtps(); + + // Calculate the average Z for the z-Index to be put in the ordering table + psyqo::GTE::Kernels::avsz4(); + int32_t zIndex = 0; + psyqo::GTE::read(reinterpret_cast(&zIndex)); + + // If the Z-index is out of bounds for our ordering table, we skip rendering this face. + if (zIndex < 0 || zIndex >= ORDERING_TABLE_SIZE) continue; + + // Read the 3 remaining vertices from the GTE + psyqo::GTE::read(&projected[1].packed); + psyqo::GTE::read(&projected[2].packed); + psyqo::GTE::read(&projected[3].packed); + + // Take a Quad fragment from our array, set its vertices, color and make it opaque + auto& quad = m_quads[faceNum]; + quad.primitive.setPointA(projected[0]); + quad.primitive.setPointB(projected[1]); + quad.primitive.setPointC(projected[2]); + quad.primitive.setPointD(projected[3]); + quad.primitive.setColor(face.color); + quad.primitive.setOpaque(); + + // Insert the Quad fragment into the ordering table at the calculated Z-index. + ot.insert(quad, zIndex); + faceNum++; + } + + // Send the entire ordering table as a DMA chain to the GPU. + gpu().chain(ot); + m_rot += 0.005_pi; +} + +int main() { return cube.run(); } From c7838864496bbe580e45d77dad9ef5850dd10b10 Mon Sep 17 00:00:00 2001 From: Romain Clement Date: Mon, 4 Nov 2024 23:57:34 +0100 Subject: [PATCH 15/29] Fix install of MIPS Toolchain using Homebrew --- tools/vscode-extension/tools.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/vscode-extension/tools.js b/tools/vscode-extension/tools.js index 58f6fd11b..bcba5305a 100644 --- a/tools/vscode-extension/tools.js +++ b/tools/vscode-extension/tools.js @@ -105,7 +105,7 @@ async function installToolchain () { const gccScriptPath = vscode.Uri.joinPath( extensionUri, 'scripts', - 'mipsel-none-elf-binutils.rb' + 'mipsel-none-elf-gcc.rb' ).fsPath await terminal.run('brew', [ 'install', @@ -136,7 +136,7 @@ async function installToolchain () { const gccScriptPath = vscode.Uri.joinPath( extensionUri, 'scripts', - 'mipsel-none-elf-binutils.rb' + 'mipsel-none-elf-gcc.rb' ).fsPath await terminal.run('brew', [ 'install', From b89e2aa01331eda33ddc3307557f97d469f8ef1f Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Mon, 4 Nov 2024 18:46:07 -0800 Subject: [PATCH 16/29] Some more 8mb fixes. --- src/core/DynaRec_x64/recompiler.cc | 2 +- src/core/gpu.cc | 6 ++---- src/core/psxemulator.h | 15 ++++++++++++++- src/core/r3000a.h | 2 +- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/core/DynaRec_x64/recompiler.cc b/src/core/DynaRec_x64/recompiler.cc index a630df200..9bfc2adf5 100644 --- a/src/core/DynaRec_x64/recompiler.cc +++ b/src/core/DynaRec_x64/recompiler.cc @@ -476,7 +476,7 @@ void DynaRecCPU::handleKernelCall() { return; } - const uint32_t pc = m_pc & 0x1fffff; + const uint32_t pc = m_pc & PCSX::g_emulator->getRamMask(); const uint32_t base = (m_pc >> 20) & 0xffc; if ((base != 0x000) && (base != 0x800) && (base != 0xa00)) return; // Mask out the segment, return if not a kernel call vector diff --git a/src/core/gpu.cc b/src/core/gpu.cc index 01ffeaa5e..dc283fc21 100644 --- a/src/core/gpu.cc +++ b/src/core/gpu.cc @@ -533,7 +533,7 @@ void PCSX::GPU::dma(uint32_t madr, uint32_t bcr, uint32_t chcr) { // GPU PSXDMA_LOG("*** DMA 2 - GPU dma chain *** %8.8lx addr = %lx size = %lx\n", chcr, madr, bcr); size = gpuDmaChainSize(madr); - chainedDMAWrite((uint32_t *)PCSX::g_emulator->m_mem->m_wram, madr & 0x1fffff); + chainedDMAWrite((uint32_t *)PCSX::g_emulator->m_mem->m_wram, madr); // Tekken 3 = use 1.0 only (not 1.5x) @@ -685,10 +685,8 @@ void PCSX::GPU::chainedDMAWrite(const uint32_t *memory, uint32_t hwAddr) { s_usedAddr[0] = s_usedAddr[1] = s_usedAddr[2] = 0xffffff; - const bool ramExpansion = PCSX::g_emulator->settings.get(); - do { - addr &= ramExpansion ? 0x7ffffc : 0x1ffffc; + addr &= g_emulator->getRamMask<4>(); if (DMACommandCounter++ > 2000000) break; if (CheckForEndlessLoop(addr)) break; diff --git a/src/core/psxemulator.h b/src/core/psxemulator.h index 30d0b74bc..8f68cd245 100644 --- a/src/core/psxemulator.h +++ b/src/core/psxemulator.h @@ -24,6 +24,10 @@ #pragma once +// Windows include on top +#include "support/windowswrapper.h" + +// Normal includes #include #include #include @@ -45,7 +49,6 @@ #include "support/strings-helpers.h" #ifndef MAXPATHLEN -#include "support/windowswrapper.h" #if defined(MAX_PATH) #define MAXPATHLEN MAX_PATH #elif defined(PATH_MAX) @@ -227,6 +230,16 @@ class Emulator { uint32_t m_psxClockSpeed = 33868800 /* 33.8688 MHz */; enum { BIAS = 2 }; + template + requires((alignment == 1) || (alignment == 4)) + constexpr uint32_t getRamMask() { + if constexpr (alignment == 1) { + return settings.get() ? 0x7fffff : 0x1fffff; + } else if constexpr (alignment == 4) { + return settings.get() ? 0x7ffffc : 0x1ffffc; + } + } + int init(); void reset(); void shutdown(); diff --git a/src/core/r3000a.h b/src/core/r3000a.h index 018bcaea7..08601270d 100644 --- a/src/core/r3000a.h +++ b/src/core/r3000a.h @@ -409,7 +409,7 @@ class R3000Acpu { public: template inline void InterceptBIOS(uint32_t currentPC) { - const uint32_t pc = currentPC & 0x1fffff; + const uint32_t pc = currentPC & g_emulator->getRamMask(); if constexpr (checkPC) { const uint32_t base = (currentPC >> 20) & 0xffc; From 2bf44413cbac0953f450ef8fcef41b4ec85ce97d Mon Sep 17 00:00:00 2001 From: Romain Clement Date: Tue, 5 Nov 2024 08:30:42 +0100 Subject: [PATCH 17/29] Fix VSCode Extension installing MIPS Toolchain as Homebrew formulae instead of casks --- tools/vscode-extension/tools.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/vscode-extension/tools.js b/tools/vscode-extension/tools.js index bcba5305a..d2149de5c 100644 --- a/tools/vscode-extension/tools.js +++ b/tools/vscode-extension/tools.js @@ -109,6 +109,7 @@ async function installToolchain () { ).fsPath await terminal.run('brew', [ 'install', + '--formula', binutilsScriptPath, gccScriptPath ]) @@ -140,6 +141,7 @@ async function installToolchain () { ).fsPath await terminal.run('brew', [ 'install', + '--formula', binutilsScriptPath, gccScriptPath ]) From 9bcedcbaaff3a04f0f8f2b94452c0fe9340a54f5 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Tue, 5 Nov 2024 18:38:44 -0800 Subject: [PATCH 18/29] Making symbol map load dialog persisting its path. --- src/core/psxemulator.h | 3 ++- src/gui/gui.cc | 2 +- src/gui/widgets/assembly.cc | 17 ++++++++++++++--- src/gui/widgets/assembly.h | 2 +- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/core/psxemulator.h b/src/core/psxemulator.h index 8f68cd245..1056b281e 100644 --- a/src/core/psxemulator.h +++ b/src/core/psxemulator.h @@ -189,6 +189,7 @@ class Emulator { typedef SettingPath SettingEXP1Filepath; typedef SettingPath SettingEXP1BrowsePath; typedef Setting SettingPIOConnected; + typedef SettingPath SettingMapBrowsePath; Settings + SettingPIOConnected, SettingMapBrowsePath> settings; class PcsxConfig { public: diff --git a/src/gui/gui.cc b/src/gui/gui.cc index e034d7bef..2123099a1 100644 --- a/src/gui/gui.cc +++ b/src/gui/gui.cc @@ -1557,7 +1557,7 @@ in Configuration->Emulation, restart PCSX-Redux, then try again.)")); } if (m_assembly.m_show) { - m_assembly.draw(this, &g_emulator->m_cpu->m_regs, g_emulator->m_mem.get(), _("Assembly")); + changed |= m_assembly.draw(this, &g_emulator->m_cpu->m_regs, g_emulator->m_mem.get(), _("Assembly")); } if (m_disassembly.m_show && g_emulator->m_cpu->isDynarec()) { diff --git a/src/gui/widgets/assembly.cc b/src/gui/widgets/assembly.cc index 257622fd0..f02cee83d 100644 --- a/src/gui/widgets/assembly.cc +++ b/src/gui/widgets/assembly.cc @@ -459,7 +459,8 @@ void PCSX::Widgets::Assembly::Offset(uint32_t addr, int size) { } } -void PCSX::Widgets::Assembly::draw(GUI* gui, psxRegisters* registers, Memory* memory, const char* title) { +bool PCSX::Widgets::Assembly::draw(GUI* gui, psxRegisters* registers, Memory* memory, const char* title) { + bool changed = false; auto& cpu = g_emulator->m_cpu; m_registers = registers; m_memory = memory; @@ -467,7 +468,7 @@ void PCSX::Widgets::Assembly::draw(GUI* gui, psxRegisters* registers, Memory* me ImGui::SetNextWindowSize(ImVec2(500, 500), ImGuiCond_FirstUseEver); if (!ImGui::Begin(title, &m_show, ImGuiWindowFlags_MenuBar)) { ImGui::End(); - return; + return changed; } float glyphWidth = ImGui::GetFontSize(); @@ -1044,8 +1045,17 @@ if not success then return msg else return nil end } ImGui::End(); - if (openSymbolsDialog) m_symbolsFileDialog.openDialog(); + auto& mapPath = g_emulator->settings.get(); + + if (openSymbolsDialog) { + if (!mapPath.empty()) { + m_symbolsFileDialog.m_currentPath = mapPath.value; + } + m_symbolsFileDialog.openDialog(); + } if (m_symbolsFileDialog.draw()) { + mapPath.value = m_symbolsFileDialog.m_currentPath; + changed = true; std::vector filesToOpen = m_symbolsFileDialog.selected(); for (auto fileName : filesToOpen) { std::ifstream file; @@ -1100,6 +1110,7 @@ if not success then return msg else return nil end } ImGui::End(); } + return changed; } std::list PCSX::Widgets::Assembly::findSymbol(uint32_t addr) { diff --git a/src/gui/widgets/assembly.h b/src/gui/widgets/assembly.h index b2e3c91a9..2fbff4f4f 100644 --- a/src/gui/widgets/assembly.h +++ b/src/gui/widgets/assembly.h @@ -46,7 +46,7 @@ class Assembly : private Disasm { m_listener.listen([this](const auto& event) { m_jumpToPC = event.pc; }); memset(m_jumpAddressString, 0, sizeof(m_jumpAddressString)); } - void draw(GUI* gui, psxRegisters* registers, Memory* memory, const char* title); + bool draw(GUI* gui, psxRegisters* registers, Memory* memory, const char* title); bool& m_show; From d04076cf6bd30ef4d56336225dcf150dae447d23 Mon Sep 17 00:00:00 2001 From: acemno33 Date: Fri, 15 Nov 2024 19:31:16 +0300 Subject: [PATCH 19/29] Add OverlayReduxSymbols ghidra script --- tools/ghidra_scripts/OverlayReduxSymbols.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 tools/ghidra_scripts/OverlayReduxSymbols.java diff --git a/tools/ghidra_scripts/OverlayReduxSymbols.java b/tools/ghidra_scripts/OverlayReduxSymbols.java new file mode 100644 index 000000000..b6958e959 --- /dev/null +++ b/tools/ghidra_scripts/OverlayReduxSymbols.java @@ -0,0 +1,55 @@ +// Exports symbols to PCSX-Redux's symbols map including Overlays filtering +//@author acemon33 +//@category PSX + +import ghidra.app.script.GhidraScript; +import ghidra.program.model.symbol.*; +import ghidra.program.model.address.*; +import ghidra.program.model.mem.*; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.*; + +public class OverlayReduxSymbols extends GhidraScript { + + public void run() throws Exception { + MemoryBlock[] MemoryBlockList = state.getCurrentProgram().getMemory().getBlocks(); + List choices = new ArrayList(); + for (int i = 0; i < MemoryBlockList.length; i++) { if (MemoryBlockList[i].isOverlay()) choices.add(MemoryBlockList[i].getName()); } + List filterList = askChoices("Title", "Message", choices); + List choiceList = new ArrayList(); + for (String e : choices) { choiceList.add(e + "::"); choiceList.add(e + "__"); } + + List symbols = new ArrayList(); + SymbolTable st = state.getCurrentProgram().getSymbolTable(); + SymbolIterator iter = st.getSymbolIterator(true); + while (iter.hasNext() && !monitor.isCancelled()) { + Symbol sym = iter.next(); + Address add = sym.getAddress(); + String name = sym.getName(true); + + boolean hasFilter = true; + for (String s : filterList) { if (add.toString().contains(s)) { hasFilter = false; break; } } + if (hasFilter) + { + boolean isNext = false; + for (String s : choiceList) { if (add.toString().contains(s)) { isNext = true; break; } } + if (isNext) continue; + } + + symbols.add(String.format("%08x %s", add.getOffset(), name)); + } + + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create("http://localhost:8080/api/v1/assembly/symbols?function=upload")) + .POST(HttpRequest.BodyPublishers.ofString(String.join("\n", symbols))) + .build(); + + client.send(request, HttpResponse.BodyHandlers.ofString()); + + println("size: " + symbols.size()); + } +} From 3f7a6c01e5e0ddf43099b5581f9198ed7b8c7810 Mon Sep 17 00:00:00 2001 From: rocketz Date: Sat, 16 Nov 2024 12:34:11 +0100 Subject: [PATCH 20/29] - Fixed crash when deleting patches from Assembly view - Added "are you sure?" popup when clicking "delete all" --- src/core/patchmanager.cc | 7 +++--- src/core/patchmanager.h | 2 +- src/gui/widgets/assembly.cc | 43 +++++++++++++++++++------------------ src/gui/widgets/patches.cc | 15 ++++++++++--- 4 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/core/patchmanager.cc b/src/core/patchmanager.cc index 10edf4cf8..7f9f83c32 100644 --- a/src/core/patchmanager.cc +++ b/src/core/patchmanager.cc @@ -71,13 +71,14 @@ void PCSX::PatchManager::undoPatch(Patch& patch) { patch.active = false; } -PCSX::PatchManager::Patch::Type PCSX::PatchManager::findPatch(uint32_t address) const { +int PCSX::PatchManager::findPatch(uint32_t address) const { + int idx = 0; for (const Patch& patch : m_patches) { if (patch.addr == address) { - return patch.type; + return idx; } } - return PCSX::PatchManager::Patch::Type::None; + return -1; } void PCSX::PatchManager::deletePatch(uint32_t index) { diff --git a/src/core/patchmanager.h b/src/core/patchmanager.h index a397a8e67..0db8bbc9f 100644 --- a/src/core/patchmanager.h +++ b/src/core/patchmanager.h @@ -47,7 +47,7 @@ class PatchManager { Patch& getPatch(int index) { return m_patches[index]; } int registerPatch(uint32_t address, Patch::Type type); - PatchManager::Patch::Type findPatch(uint32_t address) const; + int findPatch(uint32_t address) const; void deletePatch(uint32_t index); void deleteAllPatches(); void deactivateAll(); diff --git a/src/gui/widgets/assembly.cc b/src/gui/widgets/assembly.cc index 59718a122..46a1fab42 100644 --- a/src/gui/widgets/assembly.cc +++ b/src/gui/widgets/assembly.cc @@ -789,28 +789,29 @@ settings, otherwise debugging features may not work.)"); } if (absAddr < 0x00800000) { PatchManager& pm = *g_emulator->m_patchManager; - PatchManager::Patch::Type patchType = pm.findPatch(dispAddr); - switch (patchType) { - case PatchManager::Patch::Type::None: - if (ImGui::MenuItem(_("Patch in Return"))) { - pm.registerPatch(dispAddr, PatchManager::Patch::Type::Return); - } - if (ImGui::MenuItem(_("Patch in NOP"))) { - pm.registerPatch(dispAddr, PatchManager::Patch::Type::NOP); - } - break; - - case PatchManager::Patch::Type::Return: - if (ImGui::MenuItem(_("Remove Return Patch"))) { - pm.undoPatch(dispAddr); - } - break; + int patchIdx = pm.findPatch(dispAddr); + if (patchIdx == -1) { + if (ImGui::MenuItem(_("Patch in Return"))) { + pm.registerPatch(dispAddr, PatchManager::Patch::Type::Return); + } + if (ImGui::MenuItem(_("Patch in NOP"))) { + pm.registerPatch(dispAddr, PatchManager::Patch::Type::NOP); + } + } else { + PatchManager::Patch& patch = pm.getPatch(patchIdx); + switch (patch.type) { + case PatchManager::Patch::Type::Return: + if (ImGui::MenuItem(_("Delete Return Patch"))) { + pm.deletePatch(patchIdx); + } + break; - case PatchManager::Patch::Type::NOP: - if (ImGui::MenuItem(_("Remove NOP Patch"))) { - pm.undoPatch(dispAddr); - } - break; + case PatchManager::Patch::Type::NOP: + if (ImGui::MenuItem(_("Delete NOP Patch"))) { + pm.deletePatch(patchIdx); + } + break; + } } if (ImGui::MenuItem(_("Assemble"))) { diff --git a/src/gui/widgets/patches.cc b/src/gui/widgets/patches.cc index b561fec86..29cbc2cf4 100644 --- a/src/gui/widgets/patches.cc +++ b/src/gui/widgets/patches.cc @@ -105,9 +105,18 @@ void PCSX::Widgets::Patches::draw(const char* title) { patchManager.deactivateAll(); } - ImGui::SameLine(); - if (ImGui::Button(_("Delete All"))) { - patchManager.deleteAllPatches(); + if (patchManager.getNumPatches() > 0) { + ImGui::SameLine(); + if (ImGui::Button(_("Delete All"))) { + ImGui::OpenPopup("delpatches_popup"); + } + if (ImGui::BeginPopup("delpatches_popup")) { + ImGui::TextUnformatted(_("Delete all Patches?")); + if (ImGui::Button(_("Delete##patches"))) { + patchManager.deleteAllPatches(); + } + ImGui::EndPopup(); + } } } From 10a33e1b832d991dba5bc2e8bbec6fbd62910f79 Mon Sep 17 00:00:00 2001 From: Elias Daler Date: Sun, 17 Nov 2024 23:50:40 +0100 Subject: [PATCH 21/29] Fix interpolation issues on HW Also safeguard against bad psyqo::Color being passed into the primitives when it can potentially affect the command (e.g. in setColor/setColorA). --- src/mips/psyqo/primitives/lines.hh | 8 ++++---- src/mips/psyqo/primitives/quads.hh | 16 ++++++++-------- src/mips/psyqo/primitives/rectangles.hh | 8 ++++---- src/mips/psyqo/primitives/sprites.hh | 8 ++++---- src/mips/psyqo/primitives/triangles.hh | 8 ++++---- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/mips/psyqo/primitives/lines.hh b/src/mips/psyqo/primitives/lines.hh index 29e8cef2c..9cd63cfbe 100644 --- a/src/mips/psyqo/primitives/lines.hh +++ b/src/mips/psyqo/primitives/lines.hh @@ -46,7 +46,7 @@ struct Line { Line(Color c) : command(0x40000000 | c.packed) {} Line& setColor(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = 0x40000000 | c.packed | wasSemiTrans; + command = 0x40000000 | (c.packed & 0xffffff) | wasSemiTrans; return *this; } Line& setOpaque() { @@ -81,7 +81,7 @@ struct GouraudLine { GouraudLine(Color c) : command(0x50000000 | c.packed) {} GouraudLine& setColorA(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = 0x50000000 | c.packed | wasSemiTrans; + command = 0x50000000 | (c.packed & 0xffffff) | wasSemiTrans; return *this; } GouraudLine& setColorB(Color c) { @@ -125,7 +125,7 @@ struct PolyLineBegin { PolyLineBegin(Color c) : command(0x48000000 | c.packed) {} PolyLineBegin& setColor(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = 0x48000000 | c.packed | wasSemiTrans; + command = 0x48000000 | (c.packed & 0xffffff) | wasSemiTrans; return *this; } PolyLineBegin& setOpaque() { @@ -166,7 +166,7 @@ struct PolyLine { PolyLine(Color c) : command(0x48000000 | c.packed) {} PolyLine& setColor(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = 0x48000000 | c.packed | wasSemiTrans; + command = 0x48000000 | (c.packed & 0xffffff) | wasSemiTrans; return *this; } PolyLine& setOpaque() { diff --git a/src/mips/psyqo/primitives/quads.hh b/src/mips/psyqo/primitives/quads.hh index 440dbf404..cb7e552c7 100644 --- a/src/mips/psyqo/primitives/quads.hh +++ b/src/mips/psyqo/primitives/quads.hh @@ -54,7 +54,7 @@ struct Quad { Quad(Color c) : command(0x28000000 | c.packed) {} Quad& setColor(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = 0x28000000 | c.packed | wasSemiTrans; + command = 0x28000000 | (c.packed & 0xffffff) | wasSemiTrans; return *this; } Quad& setOpaque() { @@ -109,7 +109,7 @@ struct TexturedQuad { TexturedQuad(Color c) : command(0x2c000000 | c.packed) {} TexturedQuad& setColor(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = 0x2c000000 | c.packed | wasSemiTrans; + command = 0x2c000000 | (c.packed & 0xffffff) | wasSemiTrans; return *this; } TexturedQuad& setOpaque() { @@ -151,7 +151,7 @@ struct GouraudQuad { GouraudQuad(Color c) : command(0x38000000 | c.packed) {} GouraudQuad& setColorA(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = 0x38000000 | c.packed | wasSemiTrans; + command = 0x38000000 | (c.packed & 0xffffff) | wasSemiTrans; return *this; } GouraudQuad& setColorB(Color c) { @@ -205,7 +205,7 @@ struct GouraudQuad { GTE::read(&command); GTE::write(&b->packed); GTE::write(&c->packed); - GTE::write(&d->packed); + GTE::write(&d->packed); GTE::Kernels::dpct(); GTE::read(&colorB.packed); GTE::read(&colorC.packed); @@ -226,7 +226,7 @@ struct GouraudQuad { GTE::read(&command); GTE::write(b.packed); GTE::write(c.packed); - GTE::write(d.packed); + GTE::write(d.packed); GTE::Kernels::dpct(); GTE::read(&colorB.packed); GTE::read(&colorC.packed); @@ -267,7 +267,7 @@ struct GouraudTexturedQuad { GouraudTexturedQuad(Color c) : command(0x3c000000 | c.packed) {} GouraudTexturedQuad& setColorA(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = 0x3c000000 | c.packed | wasSemiTrans; + command = 0x3c000000 | (c.packed & 0xffffff) | wasSemiTrans; return *this; } GouraudTexturedQuad& setColorB(Color c) { @@ -305,7 +305,7 @@ struct GouraudTexturedQuad { GTE::read(&command); GTE::write(&b->packed); GTE::write(&c->packed); - GTE::write(&d->packed); + GTE::write(&d->packed); GTE::Kernels::dpct(); GTE::read(&colorB.packed); GTE::read(&colorC.packed); @@ -326,7 +326,7 @@ struct GouraudTexturedQuad { GTE::read(&command); GTE::write(b.packed); GTE::write(c.packed); - GTE::write(d.packed); + GTE::write(d.packed); GTE::Kernels::dpct(); GTE::read(&colorB.packed); GTE::read(&colorC.packed); diff --git a/src/mips/psyqo/primitives/rectangles.hh b/src/mips/psyqo/primitives/rectangles.hh index bb28f9e77..aaae9d50f 100644 --- a/src/mips/psyqo/primitives/rectangles.hh +++ b/src/mips/psyqo/primitives/rectangles.hh @@ -49,7 +49,7 @@ struct Rectangle { Rectangle(Color c) : command(BASE | c.packed) {} Rectangle& setColor(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = BASE | c.packed | wasSemiTrans; + command = BASE | (c.packed & 0xffffff) | wasSemiTrans; return *this; } Rectangle& setOpaque() { @@ -84,7 +84,7 @@ struct Pixel { Pixel(Color c) : command(BASE | c.packed) {} Pixel& setColor(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = BASE | c.packed | wasSemiTrans; + command = BASE | (c.packed & 0xffffff) | wasSemiTrans; return *this; } Pixel& setOpaque() { @@ -118,7 +118,7 @@ struct Rectangle8x8 { Rectangle8x8(Color c) : command(BASE | c.packed) {} Rectangle8x8& setColor(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = BASE | c.packed | wasSemiTrans; + command = BASE | (c.packed & 0xffffff) | wasSemiTrans; return *this; } Rectangle8x8& setOpaque() { @@ -152,7 +152,7 @@ struct Rectangle16x16 { Rectangle16x16(Color c) : command(BASE | c.packed) {} Rectangle16x16& setColor(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = BASE | c.packed | wasSemiTrans; + command = BASE | (c.packed & 0xffffff) | wasSemiTrans; return *this; } Rectangle16x16& setOpaque() { diff --git a/src/mips/psyqo/primitives/sprites.hh b/src/mips/psyqo/primitives/sprites.hh index 02fe1674d..22dac4a17 100644 --- a/src/mips/psyqo/primitives/sprites.hh +++ b/src/mips/psyqo/primitives/sprites.hh @@ -50,7 +50,7 @@ struct Sprite { Sprite(Color c) : command(BASE | c.packed) {} Sprite& setColor(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = BASE | c.packed | wasSemiTrans; + command = BASE | (c.packed & 0xffffff) | wasSemiTrans; return *this; } Sprite& setOpaque() { @@ -87,7 +87,7 @@ struct Sprite1x1 { Sprite1x1(Color c) : command(BASE | c.packed) {} Sprite1x1& setColor(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = BASE | c.packed | wasSemiTrans; + command = BASE | (c.packed & 0xffffff) | wasSemiTrans; return *this; } Sprite1x1& setOpaque() { @@ -123,7 +123,7 @@ struct Sprite8x8 { Sprite8x8(Color c) : command(BASE | c.packed) {} Sprite8x8& setColor(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = BASE | c.packed | wasSemiTrans; + command = BASE | (c.packed & 0xffffff) | wasSemiTrans; return *this; } Sprite8x8& setOpaque() { @@ -159,7 +159,7 @@ struct Sprite16x16 { Sprite16x16(Color c) : command(BASE | c.packed) {} Sprite16x16& setColor(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = BASE | c.packed | wasSemiTrans; + command = BASE | (c.packed & 0xffffff) | wasSemiTrans; return *this; } Sprite16x16& setOpaque() { diff --git a/src/mips/psyqo/primitives/triangles.hh b/src/mips/psyqo/primitives/triangles.hh index d5753c7c4..c0fa73a71 100644 --- a/src/mips/psyqo/primitives/triangles.hh +++ b/src/mips/psyqo/primitives/triangles.hh @@ -47,7 +47,7 @@ struct Triangle { Triangle(Color c) : command(0x20000000 | c.packed) {} Triangle& setColor(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = 0x20000000 | c.packed | wasSemiTrans; + command = 0x20000000 | (c.packed & 0xffffff) | wasSemiTrans; return *this; } Triangle& setOpaque() { @@ -98,7 +98,7 @@ struct TexturedTriangle { TexturedTriangle(Color c) : command(0x24000000 | c.packed) {} TexturedTriangle& setColor(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = 0x24000000 | c.packed | wasSemiTrans; + command = 0x24000000 | (c.packed & 0xffffff) | wasSemiTrans; return *this; } TexturedTriangle& setOpaque() { @@ -138,7 +138,7 @@ struct GouraudTriangle { GouraudTriangle(Color c) : command(0x30000000 | c.packed) {} GouraudTriangle& setColorA(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = 0x30000000 | c.packed | wasSemiTrans; + command = 0x30000000 | (c.packed & 0xffffff) | wasSemiTrans; return *this; } GouraudTriangle& setColorB(Color c) { @@ -235,7 +235,7 @@ struct GouraudTexturedTriangle { GouraudTexturedTriangle(Color c) : command(0x34000000 | c.packed) {} GouraudTexturedTriangle& setColorA(Color c) { uint32_t wasSemiTrans = command & 0x02000000; - command = 0x34000000 | c.packed | wasSemiTrans; + command = 0x34000000 | (c.packed & 0xffffff) | wasSemiTrans; return *this; } GouraudTexturedTriangle& setColorB(Color c) { From b5751bd577710e6e3b129e7409f2fbfe00aa5b33 Mon Sep 17 00:00:00 2001 From: Nicolas Pixel Noble Date: Sun, 17 Nov 2024 15:35:40 -0800 Subject: [PATCH 22/29] Updating imgui to fix compilation issue. --- src/gui/gui.cc | 4 ++-- src/gui/widgets/memcard_manager.cc | 2 +- src/gui/widgets/vram-viewer.cc | 2 +- third_party/ImFileDialog/ImFileDialog.cpp | 2 +- third_party/imgui | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gui/gui.cc b/src/gui/gui.cc index 2123099a1..571ad71bc 100644 --- a/src/gui/gui.cc +++ b/src/gui/gui.cc @@ -1052,7 +1052,7 @@ void PCSX::GUI::endFrame() { m_outputShaderEditor.configure(this); if (m_fullWindowRender) { - ImTextureID texture = reinterpret_cast(m_offscreenTextures[m_currentTexture]); + ImTextureID texture = m_offscreenTextures[m_currentTexture]; const auto basePos = ImGui::GetMainViewport()->Pos; const auto displayFramebufferScale = ImGui::GetIO().DisplayFramebufferScale; const auto logicalRenderSize = @@ -1086,7 +1086,7 @@ void PCSX::GUI::endFrame() { m_setupScreenSize = true; } ImGuiHelpers::normalizeDimensions(textureSize, renderRatio); - ImTextureID texture = reinterpret_cast(m_offscreenTextures[m_currentTexture]); + ImTextureID texture = m_offscreenTextures[m_currentTexture]; if (g_system->getArgs().isShadersDisabled()) { ImGui::Image(texture, textureSize, ImVec2(0, 0), ImVec2(1, 1)); } else { diff --git a/src/gui/widgets/memcard_manager.cc b/src/gui/widgets/memcard_manager.cc index 9db4264a3..1cac21a9c 100644 --- a/src/gui/widgets/memcard_manager.cc +++ b/src/gui/widgets/memcard_manager.cc @@ -352,7 +352,7 @@ void PCSX::Widgets::MemcardManager::drawIcon(const PCSX::SIO::McdBlock& block) { glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 32, 32, GL_RGBA, GL_UNSIGNED_BYTE, pixels); } - ImGui::Image(reinterpret_cast(texture), ImVec2(m_iconSize, m_iconSize)); + ImGui::Image(texture, ImVec2(m_iconSize, m_iconSize)); } // Extract the pocketstation icon from the block indicated by blockNumber into the pixels array (In RGBA8888) diff --git a/src/gui/widgets/vram-viewer.cc b/src/gui/widgets/vram-viewer.cc index f14503a57..e3611f14d 100644 --- a/src/gui/widgets/vram-viewer.cc +++ b/src/gui/widgets/vram-viewer.cc @@ -422,7 +422,7 @@ void PCSX::Widgets::VRAMViewer::drawVRAM(GUI *gui, GLuint textureID) { ImVec2 texTL = ImVec2(0.0f, 0.0f) - m_cornerTL / dimensions; ImVec2 texBR = ImVec2(1.0f, 1.0f) - (m_cornerBR - m_resolution) / dimensions; ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); - ImGui::ImageButton("vram", reinterpret_cast(textureID), m_resolution, texTL, texBR); + ImGui::ImageButton("vram", textureID, m_resolution, texTL, texBR); ImGui::PopStyleVar(); if (m_clutDestination && m_selectingClut) { m_clutDestination->m_clut = m_mouseUV; diff --git a/third_party/ImFileDialog/ImFileDialog.cpp b/third_party/ImFileDialog/ImFileDialog.cpp index e6143bfa1..5d0255969 100644 --- a/third_party/ImFileDialog/ImFileDialog.cpp +++ b/third_party/ImFileDialog/ImFileDialog.cpp @@ -1187,7 +1187,7 @@ namespace ifd { bool isSelected = std::count(m_selections.begin(), m_selections.end(), entry.Path); - if (FileIcon(filename.c_str(), isSelected, entry.HasIconPreview ? entry.IconPreview : (ImTextureID)m_getIcon(entry.Path), ImVec2(32 + 16 * m_zoom, 32 + 16 * m_zoom), entry.HasIconPreview, entry.IconPreviewWidth, entry.IconPreviewHeight)) { + if (FileIcon(filename.c_str(), isSelected, entry.HasIconPreview ? (ImTextureID)entry.IconPreview : (ImTextureID)m_getIcon(entry.Path), ImVec2(32 + 16 * m_zoom, 32 + 16 * m_zoom), entry.HasIconPreview, entry.IconPreviewWidth, entry.IconPreviewHeight)) { std::error_code ec; bool isDir = std::filesystem::is_directory(entry.Path, ec); diff --git a/third_party/imgui b/third_party/imgui index f63c95a07..368123ab0 160000 --- a/third_party/imgui +++ b/third_party/imgui @@ -1 +1 @@ -Subproject commit f63c95a076a401721ceaf21f30d4f12e8c40cb2c +Subproject commit 368123ab06b2b573d585e52f84cd782c5c006697 From 7c0363731cc43ca43a906aa790e42f722f38a7a2 Mon Sep 17 00:00:00 2001 From: Nicolas Pixel Noble Date: Sun, 17 Nov 2024 15:54:23 -0800 Subject: [PATCH 23/29] Probably fixing Linux build. --- src/gui/widgets/shader-editor.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/shader-editor.cc b/src/gui/widgets/shader-editor.cc index 349822711..9ef9e2fe1 100644 --- a/src/gui/widgets/shader-editor.cc +++ b/src/gui/widgets/shader-editor.cc @@ -711,7 +711,7 @@ void PCSX::Widgets::ShaderEditor::renderWithImgui(GUI *gui, ImTextureID textureI if (L.isfunction()) { L.copy(-2); L.setfenv(); - L.push(static_cast(reinterpret_cast(textureID))); + L.push(static_cast(textureID)); L.push(srcSize.x); L.push(srcSize.y); L.push(dstSize.x); @@ -752,7 +752,7 @@ void PCSX::Widgets::ShaderEditor::renderWithImgui(GUI *gui, ImTextureID textureI } void PCSX::Widgets::ShaderEditor::imguiCB(const ImDrawList *parentList, const ImDrawCmd *cmd) { - GLuint textureID = static_cast(reinterpret_cast(cmd->TextureId)); + GLuint textureID = static_cast(cmd->TextureId); GLfloat projMtx[4][4]; if (m_imguiProjMtxLoc == -1) { From 39f7549e7a24b4a0369220a5e44fecc81f82617c Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Mon, 18 Nov 2024 22:27:17 -0800 Subject: [PATCH 24/29] Save/Restore file dialogs favorites. --- src/core/psxemulator.h | 3 +- src/gui/gui.cc | 16 +++++++++++ src/gui/gui.h | 25 +++++++--------- src/gui/widgets/assembly.h | 6 ++-- src/gui/widgets/filedialog.cc | 13 +++++++++ src/gui/widgets/filedialog.h | 11 ++++++- src/gui/widgets/isobrowser.h | 7 +++-- src/gui/widgets/memcard_manager.h | 9 ++++-- src/gui/widgets/pio-cart.h | 8 ++++-- src/gui/widgets/typed_debugger.cc | 6 +++- src/gui/widgets/typed_debugger.h | 6 ++-- src/main/main.cc | 3 +- src/support/settings.h | 48 +++++++++++++++++++++++++------ 13 files changed, 122 insertions(+), 39 deletions(-) diff --git a/src/core/psxemulator.h b/src/core/psxemulator.h index 1056b281e..8a4d0eb17 100644 --- a/src/core/psxemulator.h +++ b/src/core/psxemulator.h @@ -190,6 +190,7 @@ class Emulator { typedef SettingPath SettingEXP1BrowsePath; typedef Setting SettingPIOConnected; typedef SettingPath SettingMapBrowsePath; + typedef SettingVector SettingOpenDialogFavorites; Settings + SettingPIOConnected, SettingMapBrowsePath, SettingOpenDialogFavorites> settings; class PcsxConfig { public: diff --git a/src/gui/gui.cc b/src/gui/gui.cc index 571ad71bc..472e309e9 100644 --- a/src/gui/gui.cc +++ b/src/gui/gui.cc @@ -96,6 +96,22 @@ __declspec(dllexport) DWORD NvOptimusEnablement = 1; __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 1; } +PCSX::GUI::GUI(std::vector& favorites) + : m_listener(g_system->m_eventBus), + m_typedDebugger(settings.get().value, favorites), + m_memcardManager(settings.get().value, favorites), + m_assembly(settings.get().value, favorites), + m_openIsoFileDialog(l_("Open Disk Image"), favorites), + m_openBinaryDialog(l_("Open Binary"), favorites), + m_openArchiveDialog(l_("Open Archive"), favorites), + m_selectBiosDialog(l_("Select BIOS"), favorites), + m_selectEXP1Dialog(l_("Select EXP1"), favorites), + m_isoBrowser(settings.get().value, favorites), + m_pioCart(settings.get().value, favorites) { + assert(g_gui == nullptr); + g_gui = this; +} + void PCSX::GUI::openUrl(std::string_view url) { std::string storage = std::string(url); ShellExecuteA(0, 0, storage.c_str(), 0, 0, SW_SHOW); diff --git a/src/gui/gui.h b/src/gui/gui.h index 4c91c749d..41c0d99b0 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -213,10 +213,7 @@ class GUI final : public UI { GUI *m_gui = nullptr; }; std::vector getGLerrors() { return std::move(m_glErrors); } - GUI() : m_listener(g_system->m_eventBus) { - assert(g_gui == nullptr); - g_gui = this; - } + GUI(std::vector &favorites); ~GUI() { assert(g_gui == this); g_gui = nullptr; @@ -374,20 +371,20 @@ class GUI final : public UI { MemoryEditorWrapper m_vramEditor = {this, settings.get().value, settings.get().value}; Widgets::MemoryObserver m_memoryObserver = {settings.get().value}; - Widgets::TypedDebugger m_typedDebugger = {settings.get().value}; + Widgets::TypedDebugger m_typedDebugger; Widgets::Patches m_patches = {settings.get().value}; - Widgets::MemcardManager m_memcardManager = {settings.get().value}; + Widgets::MemcardManager m_memcardManager; Widgets::Registers m_registers = {settings.get().value}; - Widgets::Assembly m_assembly = {settings.get().value}; + Widgets::Assembly m_assembly; Widgets::Disassembly m_disassembly = {settings.get().value}; - Widgets::FileDialog<> m_openIsoFileDialog = {l_("Open Disk Image")}; - Widgets::FileDialog<> m_openBinaryDialog = {l_("Open Binary")}; - Widgets::FileDialog<> m_openArchiveDialog = {l_("Open Archive")}; - Widgets::FileDialog<> m_selectBiosDialog = {l_("Select BIOS")}; - Widgets::FileDialog<> m_selectEXP1Dialog = {l_("Select EXP1")}; + Widgets::FileDialog<> m_openIsoFileDialog; + Widgets::FileDialog<> m_openBinaryDialog; + Widgets::FileDialog<> m_openArchiveDialog; + Widgets::FileDialog<> m_selectBiosDialog; + Widgets::FileDialog<> m_selectEXP1Dialog; Widgets::NamedSaveStates m_namedSaveStates = {settings.get().value}; Widgets::Breakpoints m_breakpoints = {settings.get().value}; - Widgets::IsoBrowser m_isoBrowser = {settings.get().value}; + Widgets::IsoBrowser m_isoBrowser; bool m_showCfg = false; bool m_showUiCfg = false; @@ -408,7 +405,7 @@ class GUI final : public UI { Widgets::CallStacks m_callstacks = {settings.get().value}; - Widgets::PIOCart m_pioCart = {settings.get().value}; + Widgets::PIOCart m_pioCart; Widgets::SIO1 m_sio1 = {settings.get().value}; Widgets::GPULogger m_gpuLogger{settings.get().value}; diff --git a/src/gui/widgets/assembly.h b/src/gui/widgets/assembly.h index 2fbff4f4f..edd2bd849 100644 --- a/src/gui/widgets/assembly.h +++ b/src/gui/widgets/assembly.h @@ -26,6 +26,7 @@ #include #include #include +#include #include "core/disr3000a.h" #include "core/r3000a.h" @@ -42,7 +43,8 @@ namespace Widgets { class Assembly : private Disasm { public: - Assembly(bool& show) : m_show(show), m_listener(g_system->m_eventBus) { + Assembly(bool& show, std::vector& favorites) + : m_show(show), m_listener(g_system->m_eventBus), m_symbolsFileDialog(l_("Load Symbols"), favorites) { m_listener.listen([this](const auto& event) { m_jumpToPC = event.pc; }); memset(m_jumpAddressString, 0, sizeof(m_jumpAddressString)); } @@ -60,7 +62,7 @@ class Assembly : private Disasm { int m_numColumns = 4; char m_jumpAddressString[20]; uint32_t m_previousPC = 0; - FileDialog<> m_symbolsFileDialog = {l_("Load Symbols")}; + FileDialog<> m_symbolsFileDialog; std::vector> m_arrows; // Disasm section diff --git a/src/gui/widgets/filedialog.cc b/src/gui/widgets/filedialog.cc index d35d76933..fe826336d 100644 --- a/src/gui/widgets/filedialog.cc +++ b/src/gui/widgets/filedialog.cc @@ -43,3 +43,16 @@ void PCSX::Widgets::FileDialogBase::setDeleteTexture() { glDeleteTextures(1, &texID); }; } + +void PCSX::Widgets::FileDialogBase::restoreFavorites() { + for (const auto& fav : m_favorites) { + AddFavorite(fav); + } +} + +void PCSX::Widgets::FileDialogBase::saveFavorites() { + m_favorites.clear(); + for (const auto& fav : GetFavorites()) { + m_favorites.push_back(fav); + } +} diff --git a/src/gui/widgets/filedialog.h b/src/gui/widgets/filedialog.h index 8e86431fe..6558160ee 100644 --- a/src/gui/widgets/filedialog.h +++ b/src/gui/widgets/filedialog.h @@ -33,9 +33,15 @@ namespace Widgets { class FileDialogBase : protected ifd::FileDialog { public: virtual void* CreateTexture(uint8_t* data, int w, int h, char fmt) override; + FileDialogBase(std::vector& favorites) : ifd::FileDialog(), m_favorites(favorites) {} protected: void setDeleteTexture(); + void restoreFavorites(); + void saveFavorites(); + + private: + std::vector& m_favorites; }; enum class FileDialogMode { Open, MultiSelect, Save }; @@ -43,13 +49,15 @@ enum class FileDialogMode { Open, MultiSelect, Save }; template class FileDialog : public FileDialogBase { public: - FileDialog(std::function title) : m_title(title) { + FileDialog(std::function title, std::vector& favorites) + : FileDialogBase(favorites), m_title(title) { setToCurrentPath(); setDeleteTexture(); } virtual ~FileDialog() = default; void setToCurrentPath() { m_currentPath = std::filesystem::current_path(); } void openDialog() { + restoreFavorites(); if constexpr (mode == FileDialogMode::Open) { Open(m_title(), m_title(), "*.*", mode == FileDialogMode::MultiSelect, reinterpret_cast(m_currentPath.u8string().c_str())); @@ -67,6 +75,7 @@ class FileDialog : public FileDialogBase { m_results.reserve(results.size()); for (auto& result : results) m_results.push_back(result.u8string()); Close(); + saveFavorites(); } return done; } diff --git a/src/gui/widgets/isobrowser.h b/src/gui/widgets/isobrowser.h index 42dc99110..cff66374c 100644 --- a/src/gui/widgets/isobrowser.h +++ b/src/gui/widgets/isobrowser.h @@ -22,6 +22,8 @@ #include #include +#include +#include #include "gui/widgets/filedialog.h" #include "support/coroutine.h" @@ -35,7 +37,8 @@ namespace Widgets { class IsoBrowser { public: - IsoBrowser(bool& show) : m_show(show) {} + IsoBrowser(bool& show, std::vector& favorites) + : m_show(show), m_openIsoFileDialog(l_("Open Disk Image"), favorites) {} void draw(CDRom* cdrom, const char* title); bool& m_show; @@ -47,7 +50,7 @@ class IsoBrowser { float m_crcProgress = 0.0f; Coroutine<> computeCRC(CDRIso*); - FileDialog<> m_openIsoFileDialog = {l_("Open Disk Image")}; + FileDialog<> m_openIsoFileDialog; }; } // namespace Widgets diff --git a/src/gui/widgets/memcard_manager.h b/src/gui/widgets/memcard_manager.h index dff8f4f60..db74f0740 100644 --- a/src/gui/widgets/memcard_manager.h +++ b/src/gui/widgets/memcard_manager.h @@ -38,7 +38,10 @@ namespace Widgets { class MemcardManager { public: - MemcardManager(bool& show) : m_show(show) {} + MemcardManager(bool& show, std::vector& favorites) + : m_show(show), + m_importMemoryCardDialog(l_("Import Memory Card file"), favorites), + m_exportMemoryCardDialog(l_("Export Memory Card file"), favorites) {} bool draw(GUI* gui, const char* title); bool& m_show; // The framecount from 0 to 59 inclusive. We need it to know which frame of multi-animation @@ -73,8 +76,8 @@ class MemcardManager { int m_undoIndex = 0; std::unique_ptr m_latest; - Widgets::FileDialog<> m_importMemoryCardDialog = {l_("Import Memory Card file")}; - Widgets::FileDialog m_exportMemoryCardDialog = {l_("Export Memory Card file")}; + Widgets::FileDialog<> m_importMemoryCardDialog; + Widgets::FileDialog m_exportMemoryCardDialog; unsigned m_memoryCardImportExportIndex = 0; void clearUndoBuffer() { diff --git a/src/gui/widgets/pio-cart.h b/src/gui/widgets/pio-cart.h index 1e7a15055..85ec84e5e 100644 --- a/src/gui/widgets/pio-cart.h +++ b/src/gui/widgets/pio-cart.h @@ -19,7 +19,8 @@ #pragma once -#include +#include +#include #include "gui/widgets/filedialog.h" @@ -28,12 +29,13 @@ namespace PCSX { namespace Widgets { class PIOCart { public: - PIOCart(bool& show) : m_show(show) {} + PIOCart(bool& show, std::vector& favorites) + : m_show(show), m_selectEXP1Dialog(l_("Select EXP1"), favorites) {} bool draw(const char* title); bool& m_show; private: - Widgets::FileDialog<> m_selectEXP1Dialog = {l_("Select EXP1")}; + Widgets::FileDialog<> m_selectEXP1Dialog; int m_flashSizeIndex; bool m_switchOn = 1; }; diff --git a/src/gui/widgets/typed_debugger.cc b/src/gui/widgets/typed_debugger.cc index 1281d5afc..55e68357e 100644 --- a/src/gui/widgets/typed_debugger.cc +++ b/src/gui/widgets/typed_debugger.cc @@ -138,7 +138,11 @@ void PCSX::Widgets::TypedDebugger::import(std::string_view fileContents, ImportT } } -PCSX::Widgets::TypedDebugger::TypedDebugger(bool& show) : m_show(show), m_listener(g_system->m_eventBus) { +PCSX::Widgets::TypedDebugger::TypedDebugger(bool& show, std::vector& favorites) + : m_show(show), + m_listener(g_system->m_eventBus), + m_importDataTypesFileDialog(l_("Import data types"), favorites), + m_importFunctionsFileDialog(l_("Import functions"), favorites) { m_listener.listen([this](const auto& event) { m_displayedWatchData.clear(); for (const auto* bp : m_watchBreakpoints) { diff --git a/src/gui/widgets/typed_debugger.h b/src/gui/widgets/typed_debugger.h index 4b20e302e..7de667393 100644 --- a/src/gui/widgets/typed_debugger.h +++ b/src/gui/widgets/typed_debugger.h @@ -38,16 +38,16 @@ class TypedDebugger { public: void draw(const char* title, GUI* gui); bool& m_show; - TypedDebugger(bool& show); + TypedDebugger(bool& show, std::vector& favorites); private: /** * Data importation. */ std::vector m_dataTypesFile; - Widgets::FileDialog<> m_importDataTypesFileDialog = {l_("Import data types")}; + Widgets::FileDialog<> m_importDataTypesFileDialog; std::vector m_functionsFile; - Widgets::FileDialog<> m_importFunctionsFileDialog = {l_("Import functions")}; + Widgets::FileDialog<> m_importFunctionsFileDialog; enum class ImportType { DataTypes, Functions }; void import(std::string_view filename, ImportType importType); diff --git a/src/main/main.cc b/src/main/main.cc index 110ab8bf4..36591940d 100644 --- a/src/main/main.cc +++ b/src/main/main.cc @@ -220,9 +220,10 @@ int pcsxMain(int argc, char **argv) { // At this point, we're committed to run the emulator, so we first create it, and the UI next. PCSX::Emulator *emulator = new PCSX::Emulator(); PCSX::g_emulator = emulator; + auto &favorites = emulator->settings.get().value; s_ui = args.get("no-ui") || args.get("cli") ? reinterpret_cast(new PCSX::TUI()) - : reinterpret_cast(new PCSX::GUI()); + : reinterpret_cast(new PCSX::GUI(favorites)); // Settings will be loaded after this initialization. s_ui->init([&emulator, &args, &system]() { // Start tweaking / sanitizing settings a bit, while continuing to parse the command line diff --git a/src/support/settings.h b/src/support/settings.h index 4f65c5e58..9e3e964b2 100644 --- a/src/support/settings.h +++ b/src/support/settings.h @@ -37,6 +37,7 @@ SOFTWARE. #include #include #include +#include #include "core/system.h" #include "json.hpp" @@ -47,6 +48,36 @@ SOFTWARE. namespace PCSX { +namespace concepts { +template +concept Setting = requires(S s) { + { s.serialize() } -> std::same_as; + { s.deserialize(std::declval()) } -> std::same_as; + { s.reset() } -> std::same_as; + { s.pushLuaClosures(std::declval()) } -> std::same_as; +}; +template +concept Settings = requires(S s) { + { s.reset() } -> std::same_as; + { s.serialize() } -> std::same_as; + { s.deserialize(std::declval()) } -> std::same_as; + { s.pushValue(std::declval()) } -> std::same_as; +}; +} // namespace concepts + +template +struct SettingVector; +template +struct SettingVector> { + using json = nlohmann::json; + typedef irqus::typestring name; + json serialize() const { return value; } + void deserialize(const json &j) { value = j.template get>(); } + void reset() { value.clear(); } + std::vector value; + void pushLuaClosures(Lua L) {} +}; + template struct Setting; template @@ -275,9 +306,9 @@ struct SettingFloat, defaultValue, divisor> { float value = (float)defaultValue / (float)divisor; }; -template +template struct SettingNested; -template +template struct SettingNested, nestedSettings> : public nestedSettings { typedef irqus::typestring name; @@ -306,7 +337,7 @@ struct SettingNested, nestedSettings> : public nestedSet } }; -template +template struct Settings : private std::tuple { using json = nlohmann::json; template @@ -336,6 +367,8 @@ struct Settings : private std::tuple { L.declareFunc("__pairs", lua_pairswrapper, -1); L.setmetatable(); } + + private: static int lua_index(lua_State *L_) { Lua L(L_); int r = L.getmetatable(-2); @@ -384,10 +417,9 @@ struct Settings : private std::tuple { return 3; } - private: template constexpr void reset() {} - template + template constexpr void reset() { settingType &setting = std::get(*this); setting.reset(); @@ -395,7 +427,7 @@ struct Settings : private std::tuple { } template constexpr void serialize(json &j) const {} - template + template constexpr void serialize(json &j) const { const settingType &setting = std::get(*this); j[settingType::name::data()] = setting.serialize(); @@ -403,7 +435,7 @@ struct Settings : private std::tuple { } template constexpr void deserialize(const json &j, bool doReset = true) {} - template + template constexpr void deserialize(const json &j, bool doReset = true) { settingType &setting = std::get(*this); try { @@ -419,7 +451,7 @@ struct Settings : private std::tuple { } template void pushValue(Lua L) {} - template + template void pushValue(Lua L) { settingType &setting = std::get(*this); setting.pushLuaClosures(L); From f06ba3caf9455adfa71fa51b91a639d426534b07 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Mon, 18 Nov 2024 23:00:05 -0800 Subject: [PATCH 25/29] Fixing Linux build. --- src/gui/gui.cc | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/gui/gui.cc b/src/gui/gui.cc index 472e309e9..3f313671f 100644 --- a/src/gui/gui.cc +++ b/src/gui/gui.cc @@ -96,22 +96,6 @@ __declspec(dllexport) DWORD NvOptimusEnablement = 1; __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 1; } -PCSX::GUI::GUI(std::vector& favorites) - : m_listener(g_system->m_eventBus), - m_typedDebugger(settings.get().value, favorites), - m_memcardManager(settings.get().value, favorites), - m_assembly(settings.get().value, favorites), - m_openIsoFileDialog(l_("Open Disk Image"), favorites), - m_openBinaryDialog(l_("Open Binary"), favorites), - m_openArchiveDialog(l_("Open Archive"), favorites), - m_selectBiosDialog(l_("Select BIOS"), favorites), - m_selectEXP1Dialog(l_("Select EXP1"), favorites), - m_isoBrowser(settings.get().value, favorites), - m_pioCart(settings.get().value, favorites) { - assert(g_gui == nullptr); - g_gui = this; -} - void PCSX::GUI::openUrl(std::string_view url) { std::string storage = std::string(url); ShellExecuteA(0, 0, storage.c_str(), 0, 0, SW_SHOW); @@ -130,6 +114,22 @@ void PCSX::GUI::openUrl(std::string_view url) { } #endif +PCSX::GUI::GUI(std::vector& favorites) + : m_listener(g_system->m_eventBus), + m_typedDebugger(settings.get().value, favorites), + m_memcardManager(settings.get().value, favorites), + m_assembly(settings.get().value, favorites), + m_openIsoFileDialog(l_("Open Disk Image"), favorites), + m_openBinaryDialog(l_("Open Binary"), favorites), + m_openArchiveDialog(l_("Open Archive"), favorites), + m_selectBiosDialog(l_("Select BIOS"), favorites), + m_selectEXP1Dialog(l_("Select EXP1"), favorites), + m_isoBrowser(settings.get().value, favorites), + m_pioCart(settings.get().value, favorites) { + assert(g_gui == nullptr); + g_gui = this; +} + using json = nlohmann::json; static std::function s_imguiUserErrorFunctor = nullptr; From c82fbc43892f045e56f9574f9a31e16b7de28d2e Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Tue, 19 Nov 2024 21:25:56 -0800 Subject: [PATCH 26/29] Moving cycle counters to 64-bits. They'll no longer roll over, simplifying a lot of things. --- src/core/psxcounters.cc | 26 +++++++++----------------- src/core/psxcounters.h | 4 ++-- src/core/r3000a.cc | 14 +++++++------- src/core/r3000a.h | 8 ++++---- src/core/sstate.cc | 6 +++--- src/core/sstate.h | 10 +++++----- 6 files changed, 30 insertions(+), 38 deletions(-) diff --git a/src/core/psxcounters.cc b/src/core/psxcounters.cc index 3e73d36b8..2e5b69602 100644 --- a/src/core/psxcounters.cc +++ b/src/core/psxcounters.cc @@ -55,7 +55,7 @@ inline void PCSX::Counters::writeCounterInternal(uint32_t index, uint32_t value) } inline uint32_t PCSX::Counters::readCounterInternal(uint32_t index) { - uint32_t count; + uint64_t count; count = PCSX::g_emulator->m_cpu->m_regs.cycle; count -= m_rcnts[index].cycleStart; @@ -71,17 +71,17 @@ inline uint32_t PCSX::Counters::readCounterInternal(uint32_t index) { void PCSX::Counters::set() { m_psxNextCounter = PCSX::g_emulator->m_cpu->m_regs.cycle; - uint32_t next = 0x7fffffff; + uint64_t next = 0x7fffffffffffffff; for (int i = 0; i < CounterQuantity; ++i) { - int32_t countToUpdate = m_rcnts[i].cycle - (m_psxNextCounter - m_rcnts[i].cycleStart); + int64_t countToUpdate = m_rcnts[i].cycle - (m_psxNextCounter - m_rcnts[i].cycleStart); if (countToUpdate < 0) { next = 0; break; } - if (countToUpdate < (int32_t)next) { + if (countToUpdate < (int64_t)next) { next = countToUpdate; } } @@ -138,19 +138,11 @@ void PCSX::Counters::reset(uint32_t index) { } void PCSX::Counters::update() { - const uint32_t cycle = PCSX::g_emulator->m_cpu->m_regs.cycle; + const uint64_t cycle = PCSX::g_emulator->m_cpu->m_regs.cycle; { - uint32_t prev = g_emulator->m_cpu->m_regs.previousCycles; - uint64_t diff; - if (cycle > prev) { - diff = cycle - prev; - } else { - diff = std::numeric_limits::max(); - diff += cycle + 1; - diff -= prev; - diff &= 0xffffffff; - } + uint64_t prev = g_emulator->m_cpu->m_regs.previousCycles; + uint64_t diff = cycle - prev; diff *= 4410000; diff /= g_emulator->settings.get(); diff /= g_emulator->m_psxClockSpeed; @@ -297,8 +289,8 @@ uint32_t PCSX::Counters::readCounter(uint32_t index) { *affected). */ static uint32_t clast = 0xffff; - static uint32_t cylast = 0; - uint32_t count1 = count; + static uint64_t cylast = 0; + uint64_t count1 = count; count /= PCSX::Emulator::BIAS; verboseLog(4, "[RCNT %i] rcountpe2: %x %x %x (%u)\n", index, count, count1, clast, (PCSX::g_emulator->m_cpu->m_regs.cycle - cylast)); diff --git a/src/core/psxcounters.h b/src/core/psxcounters.h index 6ac986afc..b8c1b3b3f 100644 --- a/src/core/psxcounters.h +++ b/src/core/psxcounters.h @@ -40,7 +40,7 @@ class Counters { struct Rcnt { uint16_t mode, target; uint32_t rate, irq, counterState, irqState; - uint32_t cycle, cycleStart; + uint64_t cycle, cycleStart; }; enum { @@ -86,7 +86,7 @@ class Counters { uint32_t m_HSyncTotal[PCSX::Emulator::PSX_TYPE_PAL + 1]; // 2 public: - uint32_t m_psxNextCounter; + uint64_t m_psxNextCounter; bool m_pollSIO1 = false; void init(); void update(); diff --git a/src/core/r3000a.cc b/src/core/r3000a.cc index 9e6ea7e9f..416f7b3a2 100644 --- a/src/core/r3000a.cc +++ b/src/core/r3000a.cc @@ -350,7 +350,7 @@ void PCSX::R3000Acpu::branchTest() { } #endif - const uint32_t cycle = m_regs.cycle; + const uint64_t cycle = m_regs.cycle; if (cycle >= g_emulator->m_counters->m_psxNextCounter) g_emulator->m_counters->update(); @@ -358,17 +358,17 @@ void PCSX::R3000Acpu::branchTest() { const uint32_t interrupts = m_regs.interrupt; - int32_t lowestDistance = std::numeric_limits::max(); - uint32_t lowestTarget = cycle; - uint32_t* targets = m_regs.intTargets; + int32_t lowestDistance = std::numeric_limits::max(); + uint64_t lowestTarget = cycle; + uint64_t* targets = m_regs.intTargets; - if ((interrupts != 0) && (((int32_t)(m_regs.lowestTarget - cycle)) <= 0)) { + if ((interrupts != 0) && (m_regs.lowestTarget < cycle)) { #define checkAndUpdate(irq, act) \ { \ constexpr uint32_t mask = 1 << irq; \ if ((interrupts & mask) != 0) { \ - uint32_t target = targets[irq]; \ - int32_t dist = target - cycle; \ + uint64_t target = targets[irq]; \ + int64_t dist = target - cycle; \ if (dist > 0) { \ if (lowestDistance > dist) { \ lowestDistance = dist; \ diff --git a/src/core/r3000a.h b/src/core/r3000a.h index 08601270d..e8528bbb8 100644 --- a/src/core/r3000a.h +++ b/src/core/r3000a.h @@ -199,12 +199,12 @@ struct psxRegisters { psxCP2Ctrl CP2C; // COP2 control registers uint32_t pc; // Program counter uint32_t code; // The current instruction - uint32_t cycle; - uint32_t previousCycles; + uint64_t cycle; + uint64_t previousCycles; uint32_t interrupt; std::atomic spuInterrupt; - uint32_t intTargets[32]; - uint32_t lowestTarget; + uint64_t intTargets[32]; + uint64_t lowestTarget; uint8_t iCacheAddr[0x1000]; uint8_t iCacheCode[0x1000]; }; diff --git a/src/core/sstate.cc b/src/core/sstate.cc index 6aef5dfb1..27107c2a8 100644 --- a/src/core/sstate.cc +++ b/src/core/sstate.cc @@ -182,8 +182,8 @@ std::string PCSX::SaveStates::save() { SaveState state = constructSaveState(); SaveStateWrapper wrapper(state); - state.get().get().value = "PCSX-Redux SaveState v3"; - state.get().get().value = 3; + state.get().get().value = "PCSX-Redux SaveState v4"; + state.get().get().value = 4; g_emulator->m_gpu->serialize(&wrapper); g_emulator->m_spu->save(state.get()); @@ -288,7 +288,7 @@ bool PCSX::SaveStates::load(std::string_view data) { return false; } - if (state.get().get().value != 3) { + if (state.get().get().value != 4) { return false; } diff --git a/src/core/sstate.h b/src/core/sstate.h index 910f2e1b3..317b51685 100644 --- a/src/core/sstate.h +++ b/src/core/sstate.h @@ -55,7 +55,7 @@ typedef Protobuf::RepeatedFieldRef typedef Protobuf::RepeatedFieldRef CP2C; typedef Protobuf::FieldRef PC; typedef Protobuf::FieldRef Code; -typedef Protobuf::FieldRef Cycle; +typedef Protobuf::FieldRef Cycle; typedef Protobuf::FieldRef Interrupt; // skip id 9 typedef Protobuf::FieldPtr, TYPESTRING("icache_addr"), 10> ICacheAddr; @@ -75,7 +75,7 @@ typedef Protobuf::Message DelaySlotInfo1; typedef Protobuf::MessageField DelaySlotInfo2; typedef Protobuf::FieldRef CurrentDelayedLoad; -typedef Protobuf::RepeatedFieldRef IntTargetsField; +typedef Protobuf::RepeatedFieldRef IntTargetsField; typedef Protobuf::FieldRef InISR; typedef Protobuf::Message RcntRate; typedef Protobuf::Field RcntIRQ; typedef Protobuf::Field RcntCounterState; typedef Protobuf::Field RcntIRQState; -typedef Protobuf::Field RcntCycle; -typedef Protobuf::Field RcntCycleStart; +typedef Protobuf::Field RcntCycle; +typedef Protobuf::Field RcntCycleStart; typedef Protobuf::Message Rcnt; typedef Protobuf::RepeatedField Rcnts; typedef Protobuf::Field HSyncCount; typedef Protobuf::Field SPUSyncCountdown; -typedef Protobuf::Field PSXNextCounter; +typedef Protobuf::Field PSXNextCounter; typedef Protobuf::Message Counters; typedef Protobuf::MessageField CountersField; From d4003a0a922fa1286af266d009031991a78e31b0 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 20 Nov 2024 19:54:27 -0800 Subject: [PATCH 27/29] Few more uint32 -> uint64 upgrades. --- src/core/DynaRec_aa64/recompiler.cc | 6 +++--- src/core/DynaRec_x64/recompiler.cc | 2 +- src/core/DynaRec_x64/symbols.cc | 2 +- src/core/cdrom.cc | 4 +++- src/core/r3000a.h | 8 ++++---- src/core/sio.h | 2 +- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/core/DynaRec_aa64/recompiler.cc b/src/core/DynaRec_aa64/recompiler.cc index 2814d2e0f..0402b8b88 100644 --- a/src/core/DynaRec_aa64/recompiler.cc +++ b/src/core/DynaRec_aa64/recompiler.cc @@ -304,9 +304,9 @@ DynarecCallback DynaRecCPU::recompile(DynarecCallback* callback, uint32_t pc, bo m_linkedPC = std::nullopt; } - gen.Ldr(w0, MemOperand(contextPointer, CYCLE_OFFSET)); // Fetch cycle count from memory - gen.Add(w0, w0, count * PCSX::Emulator::BIAS); // Add block cycles - gen.Str(w0, MemOperand(contextPointer, CYCLE_OFFSET)); // Store cycles back to memory + gen.Ldr(x0, MemOperand(contextPointer, CYCLE_OFFSET)); // Fetch cycle count from memory + gen.Add(x0, x0, count * PCSX::Emulator::BIAS); // Add block cycles + gen.Str(x0, MemOperand(contextPointer, CYCLE_OFFSET)); // Store cycles back to memory // Link block else return to dispatcher if (m_linkedPC && ENABLE_BLOCK_LINKING && m_linkedPC.value() != startingPC) { diff --git a/src/core/DynaRec_x64/recompiler.cc b/src/core/DynaRec_x64/recompiler.cc index 9bfc2adf5..4e2bff32d 100644 --- a/src/core/DynaRec_x64/recompiler.cc +++ b/src/core/DynaRec_x64/recompiler.cc @@ -450,7 +450,7 @@ DynarecCallback DynaRecCPU::recompile(uint32_t pc, bool fullLoadDelayEmulation, endProfiling(); } - gen.add(dword[contextPointer + CYCLE_OFFSET], count * PCSX::Emulator::BIAS); // Add block cycles; + gen.add(qword[contextPointer + CYCLE_OFFSET], count * PCSX::Emulator::BIAS); // Add block cycles; if (m_linkedPC && ENABLE_BLOCK_LINKING && m_linkedPC.value() != startingPC) { handleLinking(); } else { diff --git a/src/core/DynaRec_x64/symbols.cc b/src/core/DynaRec_x64/symbols.cc index cace05b6f..3897ff67a 100644 --- a/src/core/DynaRec_x64/symbols.cc +++ b/src/core/DynaRec_x64/symbols.cc @@ -85,7 +85,7 @@ void DynaRecCPU::makeSymbols() { REGISTER_VARIABLE(m_regs.CP2C.r[i], COP2_controlRegs[i], 4); } - REGISTER_VARIABLE(m_regs.cycle, "m_cycles", 4); + REGISTER_VARIABLE(m_regs.cycle, "m_cycles", 8); REGISTER_VARIABLE(m_regs.pc, "m_pc", 4); for (int i = 0; i < 16; i++) { // Register host register cache diff --git a/src/core/cdrom.cc b/src/core/cdrom.cc index 456475557..eaac186fc 100644 --- a/src/core/cdrom.cc +++ b/src/core/cdrom.cc @@ -580,7 +580,9 @@ class CDRomImpl : public PCSX::CDRom { if (m_irqRepeated) { m_irqRepeated = 0; - if (m_eCycle > PCSX::g_emulator->m_cpu->m_regs.cycle) { + auto ®s = PCSX::g_emulator->m_cpu->m_regs; + auto diff = regs.intTargets[PCSX::PSXINT_CDR] - regs.cycle; + if (m_eCycle > diff) { scheduleCDIRQ(m_eCycle); goto finish; } diff --git a/src/core/r3000a.h b/src/core/r3000a.h index e8528bbb8..3bb1cef15 100644 --- a/src/core/r3000a.h +++ b/src/core/r3000a.h @@ -317,12 +317,12 @@ class R3000Acpu { void scheduleInterrupt(unsigned interrupt, uint32_t eCycle) { PSXIRQ_LOG("Scheduling interrupt %08x at %08x\n", interrupt, eCycle); - const uint32_t cycle = m_regs.cycle; - uint32_t target = uint32_t(cycle + eCycle * m_interruptScales[interrupt]); + const uint64_t cycle = m_regs.cycle; + uint64_t target = uint64_t(cycle + eCycle * m_interruptScales[interrupt]); m_regs.interrupt |= (1 << interrupt); m_regs.intTargets[interrupt] = target; - int32_t lowest = m_regs.lowestTarget - cycle; - int32_t maybeNewLowest = target - cycle; + int64_t lowest = m_regs.lowestTarget - cycle; + int64_t maybeNewLowest = target - cycle; if (maybeNewLowest < lowest) m_regs.lowestTarget = target; } diff --git a/src/core/sio.h b/src/core/sio.h index 586e2b43b..8071c4730 100644 --- a/src/core/sio.h +++ b/src/core/sio.h @@ -233,7 +233,7 @@ class SIO { bool isReceiveIRQReady(); bool isTransmitReady(); - static inline void scheduleInterrupt(uint32_t eCycle) { + static inline void scheduleInterrupt(uint64_t eCycle) { g_emulator->m_cpu->scheduleInterrupt(PSXINT_SIO, eCycle); #if 0 // Breaks Twisted Metal 2 intro From fb4eb9e44a840d09f5b4a894011c850ab44faf6b Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 20 Nov 2024 20:54:19 -0800 Subject: [PATCH 28/29] Missed a spot. --- src/core/psxcounters.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/psxcounters.cc b/src/core/psxcounters.cc index 2e5b69602..1c4ba9bae 100644 --- a/src/core/psxcounters.cc +++ b/src/core/psxcounters.cc @@ -90,7 +90,7 @@ void PCSX::Counters::set() { } void PCSX::Counters::reset(uint32_t index) { - uint32_t count; + uint64_t count; if (m_rcnts[index].counterState == CountToTarget) { if (m_rcnts[index].mode & RcCountToTarget) { From 47e67e081bb872be3f712448c33d60b4654cc352 Mon Sep 17 00:00:00 2001 From: John Baumann Date: Thu, 21 Nov 2024 21:17:54 -0600 Subject: [PATCH 29/29] Update cpu cycles to 64-bits --- src/core/pcsxffi.lua | 2 +- src/core/pcsxlua.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/pcsxffi.lua b/src/core/pcsxffi.lua index 5b6145e1e..79ebee5bb 100644 --- a/src/core/pcsxffi.lua +++ b/src/core/pcsxffi.lua @@ -50,7 +50,7 @@ typedef struct { enum BreakpointType { Exec, Read, Write }; typedef struct { uint8_t opaque[?]; } Breakpoint; -uint32_t getCPUCycles(); +uint64_t getCPUCycles(); uint8_t* getMemPtr(); uint8_t* getParPtr(); uint8_t* getRomPtr(); diff --git a/src/core/pcsxlua.cc b/src/core/pcsxlua.cc index e5024d3a6..1c9b50a37 100644 --- a/src/core/pcsxlua.cc +++ b/src/core/pcsxlua.cc @@ -34,7 +34,7 @@ struct LuaBreakpoint { PCSX::Debug::BreakpointUserListType wrapper; }; -uint32_t getCPUCycles() { return PCSX::g_emulator->m_cpu->m_regs.cycle; } +uint64_t getCPUCycles() { return PCSX::g_emulator->m_cpu->m_regs.cycle; } void* getMemPtr() { return PCSX::g_emulator->m_mem->m_wram; } void* getParPtr() { return PCSX::g_emulator->m_mem->m_exp1; } void* getRomPtr() { return PCSX::g_emulator->m_mem->m_bios; }