From 7450b63167690d06d28f28798fec2fe4a9624822 Mon Sep 17 00:00:00 2001 From: luke01234 <95252713+luke01234@users.noreply.github.com> Date: Thu, 9 Jan 2025 23:04:58 -0600 Subject: [PATCH 1/9] Added support for PS2 Shadow Tower: Abyss --- README.md | 1 + games/ps2_stabyss.c | 59 ++++++++++++++++++++++++++++++--------------- makefile | 2 +- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 1a50682..e01775c 100644 --- a/README.md +++ b/README.md @@ -168,6 +168,7 @@ avoid clicking off the window. | Return to Castle Wolfenstein: Operation Resurrection (USA) | SLUS-20297 | Good | Not fully tested | Auto Center View: Off
Always Aim: Off | - | | Robotech: Invasion (USA) | SLUS-20823 | Fair | Turrets not supported
Not fully tested | - | - | | SOCOM U.S. Navy SEALs (USA) | SCUS-97134 | Fair | Not fully tested | Aim Assist: Off | - | +| Shadow Tower: Abyss (English Patch) | SLPS-25217 | Good | Strange vertex stretching across screen when turning too quickly. Not fully tested. | - | | - | | Serious Sam: Next Encounter (USA) | SLUS-20907 | Good | Vehicles not supported
Not fully tested | Auto Center: Off
Auto Aim: Off | - | | SWAT: Global Strike Team (USA) | SLUS-20433 | Good | Not fully tested | Auto Leveling: Off
Auto Aim: Off
Targeting Aid: Off | - | | Time Crisis II (USA) | SLUS-20219 | Good | Not fully tested | - | - | diff --git a/games/ps2_stabyss.c b/games/ps2_stabyss.c index 611d585..ec76cdb 100644 --- a/games/ps2_stabyss.c +++ b/games/ps2_stabyss.c @@ -26,9 +26,13 @@ #define PI 3.14159265f // 0x40490FDB #define TAU 6.2831853f // 0x40C90FDB +//CAM Y FROM -1.04719758 TO 0.6108651161 #define STA_CAMY 0xB7F820 -#define STA_CAMY2 0xB7F830 #define STA_CAMX 0xB7F824 +#define STA_IS_BUSY 0x201EB8 + +//no idea what all this is for +/*#define STA_CAMY2 0xB7F830 #define STA_CAMX2 0xB7F834 #define STA_CAMX_SIN 0xB7F860 @@ -38,7 +42,7 @@ #define STA_CAMX_COS 0xB7F868 #define STA_CAMX_COS2 0xB7F880 #define STA_CAMX_COS3 0xB7F9E8 -#define STA_CAMX_COS4 0xB7FA00 +#define STA_CAMX_COS4 0xB7FA00*/ static uint8_t PS2_STA_Status(void); static void PS2_STA_Inject(void); @@ -71,29 +75,37 @@ static void PS2_STA_Inject(void) if(xmouse == 0 && ymouse == 0) // if mouse is idle return; - float looksensitivity = (float)sensitivity / 40.f; + if(PS2_MEM_ReadUInt(STA_IS_BUSY)) + return; + float looksensitivity = (float)sensitivity; /// 40.f; float scale = 300.f; float camX = PS2_MEM_ReadFloat(STA_CAMX); - float camX2 = PS2_MEM_ReadFloat(STA_CAMX2); float camY = PS2_MEM_ReadFloat(STA_CAMY); - float camY2 = PS2_MEM_ReadFloat(STA_CAMY2); + /*float camX2 = PS2_MEM_ReadFloat(STA_CAMX2); + float camY2 = PS2_MEM_ReadFloat(STA_CAMY2);*/ // camX += (float)xmouse * looksensitivity / scale; float dx = (float)xmouse * looksensitivity / scale; camX += dx; - camX2 += dx; + //camX2 += dx; // camY -= (float)(invertpitch ? -ymouse : ymouse) * looksensitivity / scale; float dy = (float)(invertpitch ? -ymouse : ymouse) * looksensitivity / scale; camY -= dy; - camY2 -= dy; + //camY2 -= dy; while (camX > PI) camX -= TAU; while (camX < -PI) camX += TAU; - float nScale = 1.5f; + while (camY > 0.6108651161f) + camY = 0.6108651161f; + while (camY < -1.04719758f) + camY = -1.04719758f; + + + /*float nScale = 1.5f; float camXSin = PS2_MEM_ReadFloat(STA_CAMX_SIN) / nScale; float camXCos = PS2_MEM_ReadFloat(STA_CAMX_COS) / nScale; float angle = atan(camXSin / camXCos); @@ -101,17 +113,24 @@ static void PS2_STA_Inject(void) angle += TAU / 2.f; camXSin = sin(angle) * nScale; - camXCos = cos(angle) * nScale; + camXCos = cos(angle) * nScale;*/ - // PS2_MEM_WriteFloat(STA_CAMX_COS, camXCos); - // PS2_MEM_WriteFloat(STA_CAMX_COS2, -camXCos); - // PS2_MEM_WriteFloat(STA_CAMX_COS3, -camXCos); - // PS2_MEM_WriteFloat(STA_CAMX_COS4, camXCos); - // PS2_MEM_WriteFloat(STA_CAMX_SIN, camXSin); - // PS2_MEM_WriteFloat(STA_CAMX_SIN2, camXSin); - // PS2_MEM_WriteFloat(STA_CAMX_SIN3, camXSin); - // PS2_MEM_WriteFloat(STA_CAMX_SIN4, camXSin); - - // PS2_MEM_WriteFloat(STA_CAMX, (float)camX); - // PS2_MEM_WriteFloat(STA_CAMX2, (float)camX); + //I have no idea what the last guy was doing here, you dont need to be doing all this + /*PS2_MEM_WriteFloat(STA_CAMX_COS, camXCos); + PS2_MEM_WriteFloat(STA_CAMX_COS2, -camXCos); + PS2_MEM_WriteFloat(STA_CAMX_COS3, -camXCos); + PS2_MEM_WriteFloat(STA_CAMX_COS4, camXCos); + PS2_MEM_WriteFloat(STA_CAMX_SIN, camXSin); + PS2_MEM_WriteFloat(STA_CAMX_SIN2, camXSin); + PS2_MEM_WriteFloat(STA_CAMX_SIN3, camXSin); + PS2_MEM_WriteFloat(STA_CAMX_SIN4, camXSin); + PS2_MEM_WriteFloat(STA_CAMX2, (float)camX);*/ + //perhaps they were trying to rectify the visual glitches that appear as a result of turning too quickly? + //i dont know, i saw the different representations of the angles in the game memory but i dont see a good reason to edit them + + + + //you really only need these two + PS2_MEM_WriteFloat(STA_CAMX, (float)camX); + PS2_MEM_WriteFloat(STA_CAMY, camY); } \ No newline at end of file diff --git a/makefile b/makefile index ea4b15a..5af2ca9 100644 --- a/makefile +++ b/makefile @@ -5,7 +5,7 @@ #Compiler directories #MINGWDIR = C:/Dev/Dev-Cpp/MinGW64/bin/ -MINGWDIR = C:/Dev/TDM-GCC-64/bin/ +MINGWDIR = C:/TDM-GCC-64/bin/ CC = $(MINGWDIR)gcc WINDRES = $(MINGWDIR)windres From f210048313f4cf6a4921124f46dbfcb2ac695c01 Mon Sep 17 00:00:00 2001 From: luke01234 <95252713+luke01234@users.noreply.github.com> Date: Thu, 9 Jan 2025 23:10:25 -0600 Subject: [PATCH 2/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e01775c..4f44e73 100644 --- a/README.md +++ b/README.md @@ -168,7 +168,7 @@ avoid clicking off the window. | Return to Castle Wolfenstein: Operation Resurrection (USA) | SLUS-20297 | Good | Not fully tested | Auto Center View: Off
Always Aim: Off | - | | Robotech: Invasion (USA) | SLUS-20823 | Fair | Turrets not supported
Not fully tested | - | - | | SOCOM U.S. Navy SEALs (USA) | SCUS-97134 | Fair | Not fully tested | Aim Assist: Off | - | -| Shadow Tower: Abyss (English Patch) | SLPS-25217 | Good | Strange vertex stretching across screen when turning too quickly. Not fully tested. | - | | - | +| Shadow Tower: Abyss (English Patch) | SLPS-25217 | Good | Strange vertex stretching across screen when turning too quickly. Not fully tested. | - | | - | | Serious Sam: Next Encounter (USA) | SLUS-20907 | Good | Vehicles not supported
Not fully tested | Auto Center: Off
Auto Aim: Off | - | | SWAT: Global Strike Team (USA) | SLUS-20433 | Good | Not fully tested | Auto Leveling: Off
Auto Aim: Off
Targeting Aid: Off | - | | Time Crisis II (USA) | SLUS-20219 | Good | Not fully tested | - | - | From 28ed40823838a06f0967417da1773f656f11cf01 Mon Sep 17 00:00:00 2001 From: luke01234 <95252713+luke01234@users.noreply.github.com> Date: Fri, 10 Jan 2025 01:15:49 -0600 Subject: [PATCH 3/9] Added support for Fugitive Hunter - War on Terror --- games/game.c | 4 +- games/ps2_fugitivehunter.c | 90 ++++++++++++++++++++++++++++++++++++++ games/ps2_stabyss.c | 2 +- 3 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 games/ps2_fugitivehunter.c diff --git a/games/game.c b/games/game.c index 43ea4cf..0de563e 100644 --- a/games/game.c +++ b/games/game.c @@ -179,6 +179,7 @@ extern const GAMEDRIVER *GAME_PS2_DAEMONSUMMONER; extern const GAMEDRIVER *GAME_PS2_MACEGRIFFIN; extern const GAMEDRIVER *GAME_PS2_AREA51; extern const GAMEDRIVER *GAME_PS2_REDFACTION2; +extern const GAMEDRIVER *GAME_PS2_FUGITIVE_HUNTER; static const GAMEDRIVER **GAMELIST[] = { // UNF - Unfinished @@ -253,7 +254,7 @@ static const GAMEDRIVER **GAMELIST[] = &GAME_SNES_CYBERNATOR, // UNF &GAME_N64_TUROK3, // UNF &GAME_PS2_MICHIGAN, - &GAME_PS2_STABYSS, // UNF + &GAME_PS2_STABYSS, &GAME_PS2_AVPEXTINCTION, // UNF &GAME_N64_007WINE, &GAME_PS2_GEROGUEAGENT, // UNF @@ -339,6 +340,7 @@ static const GAMEDRIVER **GAMELIST[] = // &GAME_PS2_MACEGRIFFIN, // UNF // &GAME_PS2_AREA51, // UNF // &GAME_PS2_REDFACTION2 // UNF + &GAME_PS2_FUGITIVE_HUNTER }; static const GAMEDRIVER *CURRENT_GAME = NULL; diff --git a/games/ps2_fugitivehunter.c b/games/ps2_fugitivehunter.c new file mode 100644 index 0000000..afca42c --- /dev/null +++ b/games/ps2_fugitivehunter.c @@ -0,0 +1,90 @@ +//=========================================================== +// Mouse Injector for Dolphin +//========================================================================== +// Copyright (C) 2019-2020 Carnivorous +// All rights reserved. +// +// Mouse Injector is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, visit http://www.gnu.org/licenses/gpl-2.0.html +//========================================================================== +#include +#include "../main.h" +#include "../memory.h" +#include "../mouse.h" +#include "game.h" + +#define TAU 6.2831853f // 0x40C90FDB + +#define FUGITIVE_HUNTER_CAMX 0x371C74 +#define FUGITIVE_HUNTER_CAMY 0x371C70 +#define FUGITIVE_HUNTER_IS_BUSY 0x349A44 + +static uint8_t PS2_FUGITIVE_HUNTER_Status(void); +static void PS2_FUGITIVE_HUNTER_Inject(void); + +static const GAMEDRIVER GAMEDRIVER_INTERFACE = +{ + "Fugitive Hunter - War on Terror", + PS2_FUGITIVE_HUNTER_Status, + PS2_FUGITIVE_HUNTER_Inject, + 1, // 1000 Hz tickrate + 0 // crosshair sway not supported for driver +}; + +const GAMEDRIVER *GAME_PS2_FUGITIVE_HUNTER = &GAMEDRIVER_INTERFACE; + +//========================================================================== +// Purpose: return 1 if game is detected +//========================================================================== +static uint8_t PS2_FUGITIVE_HUNTER_Status(void) +{ + // 53 4C 55 53 5F 32 30 34 2E 36 34 3B + return (PS2_MEM_ReadWord(0x00093390) == 0x534C5553U && + PS2_MEM_ReadWord(0x00093394) == 0x5F323034U && + PS2_MEM_ReadWord(0x00093398) == 0x2E36343BU); +} + +//========================================================================== +// Purpose: calculate mouse look and inject into current game +//========================================================================== +static void PS2_FUGITIVE_HUNTER_Inject(void) +{ + if(xmouse == 0 && ymouse == 0) // if mouse is idle + return; + + if(PS2_MEM_ReadUInt(FUGITIVE_HUNTER_IS_BUSY)) + return; + + float looksensitivity = (float)sensitivity; /// 40.f; + float scale = 300.f; + + float camX = PS2_MEM_ReadFloat(FUGITIVE_HUNTER_CAMX); + float camY = PS2_MEM_ReadFloat(FUGITIVE_HUNTER_CAMY); + + camX += (float)xmouse * looksensitivity / scale; + + camY -= (float)(invertpitch ? -ymouse : ymouse) * looksensitivity / scale; + + while (camX > 360) + camX -= 360.f; + while (camX < -360) + camX += 360.f; + + while (camY > 85) + camY = 85.f; + while (camY < -83) + camY = -83.f; + + PS2_MEM_WriteFloat(FUGITIVE_HUNTER_CAMX, camX); + PS2_MEM_WriteFloat(FUGITIVE_HUNTER_CAMY, camY); +} \ No newline at end of file diff --git a/games/ps2_stabyss.c b/games/ps2_stabyss.c index ec76cdb..f497ba6 100644 --- a/games/ps2_stabyss.c +++ b/games/ps2_stabyss.c @@ -131,6 +131,6 @@ static void PS2_STA_Inject(void) //you really only need these two - PS2_MEM_WriteFloat(STA_CAMX, (float)camX); + PS2_MEM_WriteFloat(STA_CAMX, camX); PS2_MEM_WriteFloat(STA_CAMY, camY); } \ No newline at end of file From acfe74d4e8f053804dbefe1ad13cc2cb668faf65 Mon Sep 17 00:00:00 2001 From: luke01234 <95252713+luke01234@users.noreply.github.com> Date: Fri, 10 Jan 2025 01:21:33 -0600 Subject: [PATCH 4/9] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4f44e73..077caa2 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,7 @@ avoid clicking off the window. | Destroy All Humans! (USA) | SLUS-20945 | Good | **Requires supplied cheat file to disable aim-assist** | - | **67A29886.pnach** | | Destroy All Humans! 2 (USA) | SLUS-21439 | Good | **Requires supplied cheat file** | Not fully tested | **42DF8C8C.pnach** | | Dirge of Cerberus - Final Fantasy VII (USA) | SLUS-21419 | Good | **Requires supplied cheat file to disable auto-lookahead** | Not fully tested | **44A5FA15.pnach** | +| Fugitive hunter - War on Terror (USA) | SLUS-20464 | Good | Not fully tested | - | - | | Eternal Ring (USA) | SLUS-20015 | Good | Not fully tested | - | - | | Ghost in the Shell: Stand Alone Complex (USA) | SLUS-21006 | Fair | Horizontal camera while climbing not clamped | - | - | | Global Defence Force (PAL) / Chikyū Bōeigun 2 (Japan) | SLES-54464, SLPM-62652 | Good | Vehicle mouse control is experimental
Not fully tested | Control Type: Technical | - | @@ -168,7 +169,7 @@ avoid clicking off the window. | Return to Castle Wolfenstein: Operation Resurrection (USA) | SLUS-20297 | Good | Not fully tested | Auto Center View: Off
Always Aim: Off | - | | Robotech: Invasion (USA) | SLUS-20823 | Fair | Turrets not supported
Not fully tested | - | - | | SOCOM U.S. Navy SEALs (USA) | SCUS-97134 | Fair | Not fully tested | Aim Assist: Off | - | -| Shadow Tower: Abyss (English Patch) | SLPS-25217 | Good | Strange vertex stretching across screen when turning too quickly. Not fully tested. | - | | - | +| Shadow Tower: Abyss (English Patch) | SLPS-25217 | Good | Strange vertex stretching across screen when turning too quickly. Not fully tested. | - | | - | | Serious Sam: Next Encounter (USA) | SLUS-20907 | Good | Vehicles not supported
Not fully tested | Auto Center: Off
Auto Aim: Off | - | | SWAT: Global Strike Team (USA) | SLUS-20433 | Good | Not fully tested | Auto Leveling: Off
Auto Aim: Off
Targeting Aid: Off | - | | Time Crisis II (USA) | SLUS-20219 | Good | Not fully tested | - | - | From e17105cc3995c3dc5305a5418c03ef86c68c63e2 Mon Sep 17 00:00:00 2001 From: luke01234 <95252713+luke01234@users.noreply.github.com> Date: Fri, 10 Jan 2025 14:27:55 -0600 Subject: [PATCH 5/9] Incorporated the work of https://github.com/vl4sty/MouseInjectorDolphinDuck so that the program can hook to new versions of duckstation and pcsx2 --- README.md | 22 +- cheats/PS1/Tom Clancy's Rainbow Six (USA).cht | 11 + cheats/PS2/5A6A935D.pnach | 4 + games/game.c | 13 +- games/ps1_rs6.c | 121 +++++++++ games/ps2_007_qs.c | 108 ++++++++ games/ps2_mohf.c | 130 +++++++++ games/ps2_mohr.c | 125 +++++++++ games/ps2_stabyss.c | 4 +- games/ps2_syphonfilter_dm.c | 144 ++++++++++ main.h | 4 +- memory.c | 251 ++++++++++++++---- 12 files changed, 875 insertions(+), 62 deletions(-) create mode 100644 cheats/PS1/Tom Clancy's Rainbow Six (USA).cht create mode 100644 cheats/PS2/5A6A935D.pnach create mode 100644 games/ps1_rs6.c create mode 100644 games/ps2_007_qs.c create mode 100644 games/ps2_mohf.c create mode 100644 games/ps2_mohr.c create mode 100644 games/ps2_syphonfilter_dm.c diff --git a/README.md b/README.md index 4f44e73..801db1d 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,27 @@ # Mouse Injector for Dolphin 5.0, DuckStation, PCSX2, and other emulators -An external app that injects cursor input into game memory. +An external app that injects cursor input into game memory. + +### *This fork incorporates the work from https://github.com/vl4sty/MouseInjectorDolphinDuck in order to hook to newer versions of duckstation and pcsx2, however with support for some more games added by myself.* + +### !This fork is focused only on Duckstation and PCSX2 emulators! +## Additional games for PS2 - NTSC ONLY: +| Game Title | Issues | +| --------- | ------------------ | +| 007: Quantum of Solace | Needs a cheat file enabled to fix aiming in a cover: [5A6A935D.pnach](https://github.com/vl4sty/MouseInjectorDolphinDuck/blob/master/cheats/PS2/5A6A935D.pnach) | +| Medal of Honor: Frontline | None. | +| Medal of Honor: Rising Sun | X-axis while ADS is not working in the truck section in the mission "The Fall of the Philippines". | + ### *If you have a game request, please go to the 'Discussions' tab and post it!* ### _Scroll to bottom for_ *FREQUENTLY ASKED QUESTIONS* -## Supported Emulators +## This fork maintains only these emulators, thus they will work | Emulator/Frontend | Version | Executable name (case sensitive) | | --- | :---: | :---: | -| Dolphin | 5.0 and up | dolphin.exe | | DuckStation | 0.1-5943 | duckstation-qt-x64-ReleaseLTCG.exe | -| PCSX2 Nightly | latest | pcsx2-qt.exe
pcsx2-qtx64.exe
pcsx2-qtx64-avx2.exe | -| RetroArch (see cores below) | 1.14.0 | retroarch.exe | -| PPSSPP | 1.14.4 | PPSSPPWindows.exe / PPSSPPWindows64.exe | -| Project64 | >=3.0.1 | Project64.exe | +| PCSX2 | Stable 2.0.0, nightly| pcsx2-qt.exe
pcsx2-qtx64.exe
pcsx2-qtx64-avx2.exe | * NOTE: Versions given are the latest that have been tested working, may work with newer * NOTE: PCSX2 will only hook with **BIOS versions 5XXXX and up**. @@ -150,6 +157,7 @@ avoid clicking off the window. | Destroy All Humans! (USA) | SLUS-20945 | Good | **Requires supplied cheat file to disable aim-assist** | - | **67A29886.pnach** | | Destroy All Humans! 2 (USA) | SLUS-21439 | Good | **Requires supplied cheat file** | Not fully tested | **42DF8C8C.pnach** | | Dirge of Cerberus - Final Fantasy VII (USA) | SLUS-21419 | Good | **Requires supplied cheat file to disable auto-lookahead** | Not fully tested | **44A5FA15.pnach** | +| Fugitive Hunter - War on Terror (USA) | SLUS-20464 | Good | - | | - | - | | Eternal Ring (USA) | SLUS-20015 | Good | Not fully tested | - | - | | Ghost in the Shell: Stand Alone Complex (USA) | SLUS-21006 | Fair | Horizontal camera while climbing not clamped | - | - | | Global Defence Force (PAL) / Chikyū Bōeigun 2 (Japan) | SLES-54464, SLPM-62652 | Good | Vehicle mouse control is experimental
Not fully tested | Control Type: Technical | - | diff --git a/cheats/PS1/Tom Clancy's Rainbow Six (USA).cht b/cheats/PS1/Tom Clancy's Rainbow Six (USA).cht new file mode 100644 index 0000000..608480d --- /dev/null +++ b/cheats/PS1/Tom Clancy's Rainbow Six (USA).cht @@ -0,0 +1,11 @@ +#group=Ungrouped +#type=Gameshark +#activation=EndFrame +[*Disable Camera Centering] +9003E9CC 0000 +9003E988 0000 +9003E9B8 0000 +9003E974 0000 +9003E9A8 0000 +9003E960 0000 + diff --git a/cheats/PS2/5A6A935D.pnach b/cheats/PS2/5A6A935D.pnach new file mode 100644 index 0000000..06618b6 --- /dev/null +++ b/cheats/PS2/5A6A935D.pnach @@ -0,0 +1,4 @@ +gametitle=007 - Quantum of Solace SLUS-21813 0x5A6A935D + +// Disable wait on right stick input fuction while in cover +patch=1,EE,001DE778,word,00000000 \ No newline at end of file diff --git a/games/game.c b/games/game.c index 0de563e..fff4596 100644 --- a/games/game.c +++ b/games/game.c @@ -179,8 +179,14 @@ extern const GAMEDRIVER *GAME_PS2_DAEMONSUMMONER; extern const GAMEDRIVER *GAME_PS2_MACEGRIFFIN; extern const GAMEDRIVER *GAME_PS2_AREA51; extern const GAMEDRIVER *GAME_PS2_REDFACTION2; +extern const GAMEDRIVER *GAME_PS2_MOHFRONTLINE; +extern const GAMEDRIVER *GAME_PS2_MOHRISINGSUN; +extern const GAMEDRIVER *GAME_PS1_RS6; +extern const GAMEDRIVER *GAME_PS2_007QS; +extern const GAMEDRIVER *GAME_PS2_SFDM; extern const GAMEDRIVER *GAME_PS2_FUGITIVE_HUNTER; + static const GAMEDRIVER **GAMELIST[] = { // UNF - Unfinished &GAME_TS2, @@ -340,7 +346,12 @@ static const GAMEDRIVER **GAMELIST[] = // &GAME_PS2_MACEGRIFFIN, // UNF // &GAME_PS2_AREA51, // UNF // &GAME_PS2_REDFACTION2 // UNF - &GAME_PS2_FUGITIVE_HUNTER + &GAME_PS2_MOHFRONTLINE, + &GAME_PS2_MOHRISINGSUN, + &GAME_PS1_RS6, // UNF + &GAME_PS2_007QS, + &GAME_PS2_FUGITIVE_HUNTER, + // &GAME_PS2_SFDM // UNF }; static const GAMEDRIVER *CURRENT_GAME = NULL; diff --git a/games/ps1_rs6.c b/games/ps1_rs6.c new file mode 100644 index 0000000..ec9c519 --- /dev/null +++ b/games/ps1_rs6.c @@ -0,0 +1,121 @@ +//=========================================================== +// Mouse Injector for Dolphin +//========================================================================== +// Copyright (C) 2019-2020 Carnivorous +// All rights reserved. +// +// Mouse Injector is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, visit http://www.gnu.org/licenses/gpl-2.0.html +//========================================================================== +#include +#include "../main.h" +#include "../memory.h" +#include "../mouse.h" +#include "game.h" + +//Based on Delta Force: Urban Warfare patch. +#define TAU 6.2831853f +#define PI 3.1415926f +//#define PS1_RS6_CAMERABASE_X_POINTER - it is pointer to pointer to a pointer, + +//TODO: detect difficulty, it flips operatives offsets, needs to be detected, okay, detect current operative -> different offsets, same base at least, ??? does number of operatives affect offsets (NO!)? On easy C offset is green, on medium C offset is blue... +#define PS1_RS6_CAMERA_Y 0xAE8A4 +#define PS1_RS6_CAMERA_X_SIN 0xA0D24 //X-axis functions similiar to Delta Force, by Rebellion as well. +#define PS1_RS6_CAMERA_X_COS 0xA0D2C +#define PS1_RS6_CAMERA_X_COS_N 0xA0D3C +#define PS1_RS6_CAMERA_X_SIN_2 0xA0D44 +//#define PS1_RS6_FOV +//#define PS1_RS6_IS_PAUSED +//#define PS1_RS6_DIFFICULTY_FLAG +//#define PS1_RS6_SELECTED_OPERATIVE + + +static uint8_t PS1_RS6_Status(void); +static void PS1_RS6_Inject(void); +//static uint8_t PS1_RS6_DetectCamYBase(void); + +static const GAMEDRIVER GAMEDRIVER_INTERFACE = +{ + "Tom Clancy's Rainbow Six", + PS1_RS6_Status, + PS1_RS6_Inject, + 1, // 1000 Hz tickrate + 0 // crosshair sway not supported for driver +}; + +const GAMEDRIVER *GAME_PS1_RS6 = &GAMEDRIVER_INTERFACE; + +static float xAccumulator = 0.f; +static float yAccumulator = 0.f; +static uint32_t camYBase = 0; +static uint32_t camXBase = 0; +static uint32_t fovBase = 0; + +//========================================================================== +// Purpose: return 1 if game is detected +//========================================================================== + +static uint8_t PS1_RS6_Status(void) +{ + //53 4C 55 53 - 5F 30 30 39 - 2E 34 37 3B - SLUS_009.47 + return (PS1_MEM_ReadWord(0x92D4) == 0x534C5553U && PS1_MEM_ReadWord(0x92D8) == 0x5F303039U && PS1_MEM_ReadWord(0x92DC) == 0x2E34373BU); +} + +//========================================================================== +// Purpose: calculate mouse look and inject into current game +//========================================================================== +static void PS1_RS6_Inject(void) +{ + if(xmouse == 0 && ymouse == 0) // if mouse is idle + return; + + int32_t camXSin = PS1_MEM_ReadInt(PS1_RS6_CAMERA_X_SIN); + int32_t camXCos = PS1_MEM_ReadInt(PS1_RS6_CAMERA_X_COS); + float camXSinF = (float)(floor(camXSin)) / 65535.f; + float camXCosF = (float)(floor(camXCos)) / 65535.f; + + float angle = (float)atan((float)camXSinF / (float)camXCosF); + const float scale = 5.f; + const float looksensitivity = (float)sensitivity / 200.f; + + if (camXCos < 0) + angle += PI; + + angle += (float)xmouse * looksensitivity / 20.f / scale; + + while (angle > TAU) + angle -= TAU; + while (angle < 0) + angle += TAU; + + PS1_MEM_WriteInt(camXBase + PS1_RS6_CAMERA_X_SIN, (int32_t)((float)sin(angle) * 65535.f)); //From Delta Force patch, adjusted for R6. + PS1_MEM_WriteInt(camXBase + PS1_RS6_CAMERA_X_SIN_2, (int32_t)((float)sin(angle) * 65535.f)); + PS1_MEM_WriteInt(camXBase + PS1_RS6_CAMERA_X_COS, (int32_t)((float)cos(angle) * 65535.f)); + PS1_MEM_WriteInt(camXBase + PS1_RS6_CAMERA_X_COS_N, -(int32_t)((float)cos(angle) * 65535.f)); + + int32_t camY = PS1_MEM_ReadInt(camYBase + PS1_RS6_CAMERA_Y); + float camYF = (float)camY; + + float ym = (float)(invertpitch ? -ymouse : ymouse * -1); + float dy = -ym * looksensitivity * 20.f / scale; + AccumulateAddRemainder(&camYF, &yAccumulator, -ym, dy); + + // Y-axis clamping. Game uses ranges: UP 3328-4096 / DOWN 0-768; however, it allows exceding negative "DOWN" range, which moves the camera up. + if (camYF > 768) + camYF = 768; + if (camYF < -768) + camYF = -768; + + PS1_MEM_WriteInt(camYBase + PS1_RS6_CAMERA_Y, (int32_t)camYF); + +} diff --git a/games/ps2_007_qs.c b/games/ps2_007_qs.c new file mode 100644 index 0000000..c6ca21f --- /dev/null +++ b/games/ps2_007_qs.c @@ -0,0 +1,108 @@ +//=========================================================== +// Mouse Injector for Dolphin +//========================================================================== +// Copyright (C) 2019-2020 Carnivorous +// All rights reserved. +// +// Mouse Injector is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, visit http://www.gnu.org/licenses/gpl-2.0.html +//========================================================================== +#include +#include "../main.h" +#include "../memory.h" +#include "../mouse.h" +#include "game.h" + + +//variables +#define TAU 6.2831853f +//pointer to a pointer 4D87FC, AE4 offset to cam x, so many pointers, +//i ll need debugger for this, AE4 an offset, it shows addresses near the camera base... +//debugger points to register s4 (54DFF0), v0 calc will lead me to this +//debugged this base: pointer + offset -> pointer -> address +#define PS2_007QS_PTR_TO_CAMERA_PTR 0x3CA1C8 +#define PS2_007QS_PTR_TO_CAMERA_PTR_OFFSET 0xC14//set static by this instruction - lw s4,0x14C(v0) +#define PS2_007QS_CAMERA_BASE_OFFSET_X 0xAE4//X - axis +#define PS2_007QS_CAMERA_BASE_OFFSET_Y 0xAE0//Y - axis +#define PS2_007QS_FOV 0x4598B0 // value 64 + +static uint8_t PS2_007QS_Status(void); +static uint8_t PS2_007QS_DetectCamera(void); +static void PS2_007QS_Inject(void); + +static const GAMEDRIVER GAMEDRIVER_INTERFACE = +{ + "007 - Quantum of Solace", + PS2_007QS_Status, + PS2_007QS_Inject, + 1, // 1000 Hz tickrate + 0 // crosshair sway not supported for driver +}; + +const GAMEDRIVER *GAME_PS2_007QS = &GAMEDRIVER_INTERFACE; + +static uint32_t camBase = 0; +static uint32_t tempcambase = 0; + +//========================================================================== +// Purpose: return 1 if game is detected +//========================================================================== +static uint8_t PS2_007QS_Status(void) +{ + return (PS2_MEM_ReadWord(0x00093390) == 0x534C5553 && PS2_MEM_ReadWord(0x00093394) == 0x5F323138) && PS2_MEM_ReadWord(0x00093398) == 0x2E31333B; +} + +//========================================================================== +// Purpose: Camera object check. Don't write where you're not supposed to. +//========================================================================== +static uint8_t PS2_007QS_DetectCamera(void) +{ + uint32_t pointertocambase = PS2_MEM_ReadPointer(PS2_007QS_PTR_TO_CAMERA_PTR); + uint16_t offsettocambase = 0x14C; + tempcambase = PS2_MEM_ReadPointer(pointertocambase + offsettocambase); + if (tempcambase != 0) + { + camBase = tempcambase; + return 1; + } + + return 0; +} + +//========================================================================== +// Purpose: calculate mouse look and inject into current game +//========================================================================== +static void PS2_007QS_Inject(void) +{ + if (!PS2_007QS_DetectCamera()) + return; + + if(xmouse == 0 && ymouse == 0) // if mouse is idle + return; + + //sensitivity + float fov = PS2_MEM_ReadFloat(PS2_007QS_FOV); + float looksensitivity = (float)sensitivity; + float scale = 10000.f; + + //value of the read address is the address of the camera object + + float camX = PS2_MEM_ReadFloat(camBase + PS2_007QS_CAMERA_BASE_OFFSET_X); + float camY = PS2_MEM_ReadFloat(camBase + PS2_007QS_CAMERA_BASE_OFFSET_Y); + + camX += (float)xmouse * looksensitivity / scale * (fov / 64.f); + camY += (float)(invertpitch ? -ymouse : ymouse) * looksensitivity / scale * (fov / 64.f); + + PS2_MEM_WriteFloat(camBase + PS2_007QS_CAMERA_BASE_OFFSET_X, (float)camX); + PS2_MEM_WriteFloat(camBase + PS2_007QS_CAMERA_BASE_OFFSET_Y, (float)camY); +} \ No newline at end of file diff --git a/games/ps2_mohf.c b/games/ps2_mohf.c new file mode 100644 index 0000000..1e98cc8 --- /dev/null +++ b/games/ps2_mohf.c @@ -0,0 +1,130 @@ +//=========================================================== +// Mouse Injector for Dolphin +//========================================================================== +// Copyright (C) 2019-2020 Carnivorous +// All rights reserved. +// +// Mouse Injector is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, visit http://www.gnu.org/licenses/gpl-2.0.html +//========================================================================== +#include +#include "../main.h" +#include "../memory.h" +#include "../mouse.h" +#include "game.h" + + +//variables +#define TAU 6.2831853f +#define PS2_MOHF_CAMERA_BASE_POINTER 0x23F4A8 +#define PS2_MOHF_CAMERA_BASE_OFFSET_X 0x2A4 +#define PS2_MOHF_CAMERA_BASE_OFFSET_Y 0x2A8 +#define PS2_MOHF_CAMERA_BASE_OFFSET_FOV 0x43C//zoom sensitivity +#define PS2_MOHF_GLOBAL_FOV 0x1455C8//in the end not needed, but working leftover +#define PS2_MOHF_IS_MMG_FLAG 0x33C728//detect machine gun +#define PS2_MOHF_CAMERA_BASE_OFFSET_MMG_X 0x42C//offset for mg - X axis +#define PS2_MOHF_CAMERA_BASE_OFFSET_MMG_Y 0x430//offset for mg - Y axis + +static uint8_t PS2_MOHF_Status(void); +static uint8_t PS2_MOHF_DetectCamera(void); +static void PS2_MOHF_Inject(void); + +static const GAMEDRIVER GAMEDRIVER_INTERFACE = +{ + "Medal of Honor: Frontline", + PS2_MOHF_Status, + PS2_MOHF_Inject, + 1, // 1000 Hz tickrate + 0 // crosshair sway not supported for driver +}; + +const GAMEDRIVER *GAME_PS2_MOHFRONTLINE = &GAMEDRIVER_INTERFACE; + +static uint32_t camBase = 0; +static uint32_t tempcambase = 0; +static uint16_t T_Flag = 0; +static uint16_t fov16 = 0; +static uint32_t fov32 = 0; + +//========================================================================== +// Purpose: return 1 if game is detected +//========================================================================== +static uint8_t PS2_MOHF_Status(void) +{ + //SLUS_203.68 - 53 4C 55 53 5F 32 30 33 2E 36 38 + return (PS2_MEM_ReadWord(0x00093390) == 0x534C5553 && PS2_MEM_ReadWord(0x00093394) == 0x5F323033) && PS2_MEM_ReadWord(0x00093398) == 0x2E36383B; +} + + +//========================================================================== +// Purpose: Camera object check. Don't write where you're not supposed to. +//========================================================================== +static uint8_t PS2_MOHF_DetectCamera(void) +{ + uint32_t tempcambase = PS2_MEM_ReadPointer(PS2_MOHF_CAMERA_BASE_POINTER); + if (tempcambase != 0) + { + camBase = tempcambase; + return 1; + } + + return 0; +} + +//========================================================================== +// Purpose: calculate mouse look and inject into current game +//========================================================================== +static void PS2_MOHF_Inject(void) +{ + if (!PS2_MOHF_DetectCamera()) + return; + + if(xmouse == 0 && ymouse == 0) // if mouse is idle + return; + + //sensitivity + float looksensitivity = (float)sensitivity; + float scale = 10000.f; + + T_Flag = PS2_MEM_ReadUInt16(PS2_MOHF_IS_MMG_FLAG); + fov16 = PS2_MEM_ReadUInt16(PS2_MOHF_GLOBAL_FOV);//read the last 16 bit part of the fov op + fov32 = fov16 << 16;//move the 16 bits + float globalfov = *((float *)&fov32);//turn the hex value into a float + float fov = PS2_MEM_ReadFloat(camBase + PS2_MOHF_CAMERA_BASE_OFFSET_FOV); + + if (T_Flag == 0x0000) + { + float MMGX = PS2_MEM_ReadFloat(camBase + PS2_MOHF_CAMERA_BASE_OFFSET_MMG_X); + float MMGY = PS2_MEM_ReadFloat(camBase + PS2_MOHF_CAMERA_BASE_OFFSET_MMG_Y); + + MMGX += (float)xmouse * looksensitivity / scale * -1 * (fov / globalfov); + MMGY += (float)(invertpitch ? -ymouse : ymouse) * looksensitivity / scale * (fov / globalfov); + + PS2_MEM_WriteFloat(camBase + PS2_MOHF_CAMERA_BASE_OFFSET_MMG_X, (float)MMGX); + PS2_MEM_WriteFloat(camBase + PS2_MOHF_CAMERA_BASE_OFFSET_MMG_Y, (float)MMGY); + } + + else { + //value of the read address is the address of the camera object + + float camX = PS2_MEM_ReadFloat(camBase + PS2_MOHF_CAMERA_BASE_OFFSET_X); + float camY = PS2_MEM_ReadFloat(camBase + PS2_MOHF_CAMERA_BASE_OFFSET_Y); + + camX += (float)xmouse * looksensitivity / scale * -1 * (fov / globalfov); + camY += (float)(invertpitch ? -ymouse : ymouse) * looksensitivity / scale * (fov / globalfov); + camY = ClampFloat(camY, -1.450000048f, 1.450000048f); + + PS2_MEM_WriteFloat(camBase + PS2_MOHF_CAMERA_BASE_OFFSET_X, (float)camX); + PS2_MEM_WriteFloat(camBase + PS2_MOHF_CAMERA_BASE_OFFSET_Y, (float)camY); + } +} \ No newline at end of file diff --git a/games/ps2_mohr.c b/games/ps2_mohr.c new file mode 100644 index 0000000..b85fea4 --- /dev/null +++ b/games/ps2_mohr.c @@ -0,0 +1,125 @@ +//=========================================================== +// Mouse Injector for Dolphin +//========================================================================== +// Copyright (C) 2019-2020 Carnivorous +// All rights reserved. +// +// Mouse Injector is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, visit http://www.gnu.org/licenses/gpl-2.0.html +//========================================================================== +#include +#include "../main.h" +#include "../memory.h" +#include "../mouse.h" +#include "game.h" + + +//variables +#define TAU 6.2831853f +#define PS2_MOHR_CAMERA_BASE_POINTER 0x35E260 +#define PS2_MOHR_CAMERA_BASE_OFFSET_X 0x274 +#define PS2_MOHR_CAMERA_BASE_OFFSET_Y 0x278 +#define PS2_MOHR_CAMERA_BASE_OFFSET_FOV 0xE30//zoom sensitivity +#define PS2_MOHR_IS_MMG_FLAG_OFFSET 0xDB8//detect machine gun +#define PS2_MOHR_CAMERA_BASE_OFFSET_MMG_X 0xE1C//offset for mg - X axis +#define PS2_MOHR_CAMERA_BASE_OFFSET_MMG_Y 0xE20//offset for mg - Y axis + +static uint8_t PS2_MOHR_Status(void); +static uint8_t PS2_MOHR_DetectCamera(void); +static void PS2_MOHR_Inject(void); + +static const GAMEDRIVER GAMEDRIVER_INTERFACE = +{ + "Medal of Honor: Rising Sun", + PS2_MOHR_Status, + PS2_MOHR_Inject, + 1, // 1000 Hz tickrate + 0 // crosshair sway not supported for driver +}; + +const GAMEDRIVER *GAME_PS2_MOHRISINGSUN = &GAMEDRIVER_INTERFACE; + +static uint32_t camBase = 0; +static uint32_t tempcambase = 0; +static uint16_t MG_FLAG = 0; + +//========================================================================== +// Purpose: return 1 if game is detected +//========================================================================== +static uint8_t PS2_MOHR_Status(void) +{ + //SLUS_203.68 - 53 4C 55 53 5F 32 30 33 2E 36 38 + //SLUS_207.53 - 53 4C 55 53 5F 32 30 37 2E 35 33 + return (PS2_MEM_ReadWord(0x00093390) == 0x534C5553 && PS2_MEM_ReadWord(0x00093394) == 0x5F323037) && PS2_MEM_ReadWord(0x00093398) == 0x2E35333B; +} + + +//========================================================================== +// Purpose: Camera object check. Don't write where you're not supposed to. +//========================================================================== +static uint8_t PS2_MOHR_DetectCamera(void) +{ + uint32_t tempcambase = PS2_MEM_ReadPointer(PS2_MOHR_CAMERA_BASE_POINTER); + if (tempcambase != 0) + { + camBase = tempcambase; + return 1; + } + + return 0; +} + +//========================================================================== +// Purpose: calculate mouse look and inject into current game +//========================================================================== +static void PS2_MOHR_Inject(void) +{ + if (!PS2_MOHR_DetectCamera()) + return; + + if(xmouse == 0 && ymouse == 0) // if mouse is idle + return; + + //sensitivity + float looksensitivity = (float)sensitivity; + float scale = 10000.f; + + MG_FLAG = PS2_MEM_ReadUInt16(camBase + PS2_MOHR_IS_MMG_FLAG_OFFSET); + float fov = PS2_MEM_ReadFloat(camBase + PS2_MOHR_CAMERA_BASE_OFFSET_FOV); + + if (MG_FLAG == 0x0000) + { + float MMGX = PS2_MEM_ReadFloat(camBase + PS2_MOHR_CAMERA_BASE_OFFSET_MMG_X); + float MMGY = PS2_MEM_ReadFloat(camBase + PS2_MOHR_CAMERA_BASE_OFFSET_MMG_Y); + + MMGX += (float)xmouse * looksensitivity / scale * -1 * (fov / 43.f); + MMGY += (float)(invertpitch ? -ymouse : ymouse) * looksensitivity / scale * (fov / 43.f); + + PS2_MEM_WriteFloat(camBase + PS2_MOHR_CAMERA_BASE_OFFSET_MMG_X, (float)MMGX); + PS2_MEM_WriteFloat(camBase + PS2_MOHR_CAMERA_BASE_OFFSET_MMG_Y, (float)MMGY); + } + + else { + //value of the read address is the address of the camera object + + float camX = PS2_MEM_ReadFloat(camBase + PS2_MOHR_CAMERA_BASE_OFFSET_X); + float camY = PS2_MEM_ReadFloat(camBase + PS2_MOHR_CAMERA_BASE_OFFSET_Y); + + camX += (float)xmouse * looksensitivity / scale * -1 * (fov / 43.f); + camY += (float)(invertpitch ? -ymouse : ymouse) * looksensitivity / scale * (fov / 43.f); + camY = ClampFloat(camY, -1.450000048f, 1.450000048f); + + PS2_MEM_WriteFloat(camBase + PS2_MOHR_CAMERA_BASE_OFFSET_X, (float)camX); + PS2_MEM_WriteFloat(camBase + PS2_MOHR_CAMERA_BASE_OFFSET_Y, (float)camY); + } +} \ No newline at end of file diff --git a/games/ps2_stabyss.c b/games/ps2_stabyss.c index f497ba6..ecbe2d6 100644 --- a/games/ps2_stabyss.c +++ b/games/ps2_stabyss.c @@ -77,8 +77,8 @@ static void PS2_STA_Inject(void) if(PS2_MEM_ReadUInt(STA_IS_BUSY)) return; - float looksensitivity = (float)sensitivity; /// 40.f; - float scale = 300.f; + float looksensitivity = (float)sensitivity; + float scale = 12000.f; float camX = PS2_MEM_ReadFloat(STA_CAMX); float camY = PS2_MEM_ReadFloat(STA_CAMY); diff --git a/games/ps2_syphonfilter_dm.c b/games/ps2_syphonfilter_dm.c new file mode 100644 index 0000000..c41b866 --- /dev/null +++ b/games/ps2_syphonfilter_dm.c @@ -0,0 +1,144 @@ +//=========================================================== +// Mouse Injector for Dolphin +//========================================================================== +// Copyright (C) 2019-2020 Carnivorous +// All rights reserved. +// +// Mouse Injector is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, visit http://www.gnu.org/licenses/gpl-2.0.html +//========================================================================== +#include +#include "../main.h" +#include "../memory.h" +#include "../mouse.h" +#include "game.h" + + +//variables +#define PS2_SFDM_CAMERA_PTR 0x62CAD4 +#define PS2_SFDM_CAMERA_BASE_OFFSET_X 0x5D4//X - axis +#define PS2_SFDM_CAMERA_BASE_OFFSET_Y 0x5CC//Y - axis +//#define PS2_SFDN_PAUSE_FLAG +#define PS2_SFDN_PRECISE_T_FLAG 0xB98040 +#define PS2_SFDN_PRECISE_AIM_FLAG 0xA88830 +#define PS2_SFDM_PTR_TO_PB 0x5F4EC8 //5F4EC8 -> POINTER + 0x12E0 -> POINTER + 0x14 -> POINTER + 0x3F8 -> AIM X +//this pointer chain is still working the right way, but when you die one of offsets moves somewhere, prolly 12E0, yes it points to one 3F800000, I think -> only sometimes cant replicate 100%, debugging this is fun as it happens only sometimes, restarting mission works, not ideal +#define PS2_SFDM_OFFSET_TO_PRECISE_AIM_BASE_PTR_1 0x12E0 +#define PS2_SFDM_OFFSET_TO_PRECISE_AIM_BASE_PTR_2 0x14 +#define PS2_SFDM_PRECISE_AIM_OFFSET_X 0x3F8 +#define PS2_SFDM_PRECISE_AIM_OFFSET_Y 0x3F0 +#define PS2_SFDM_PRECISE_COVER_AIM_PTR 0x623BD4 // I dont believe in this simple pointer anymore, it is not, but the same i figured aim one +#define PS2_SFDM_PRECISE_AIM_COVER_OFFSET_X 0x3F8 //COVER IS ANOTHER POINTER TO POINTER TO POINTER +#define PS2_SFDM_PRECISE_AIM_COVER_OFFSET_Y 0x3F0 +#define PS2_SFDM_PRECISE_AIM_SAFETY_1 0x48C +#define PS2_SFDM_PRECISE_AIM_SAFETY_2 0x4C0 +#define PS2_SFDM_PRECISE_AIM_SAFETY_1_VALUE 0x3F800000 +#define PS2_SFDM_PRECISE_AIM_SAFETY_2_VALUE 0x00000000 //better value here +#define PS2_SFDM_FOV 0x4598B0 // value 64 + +static uint8_t PS2_SFDM_Status(void); +static uint8_t PS2_SFDM_DetectCamera(void); +static void PS2_SFDM_Inject(void); + +static const GAMEDRIVER GAMEDRIVER_INTERFACE = +{ + "Syphon Filter - Dark Mirror", + PS2_SFDM_Status, + PS2_SFDM_Inject, + 1, // 1000 Hz tickrate + 0 // crosshair sway not supported for driver +}; + +const GAMEDRIVER *GAME_PS2_SFDM = &GAMEDRIVER_INTERFACE; + +static uint32_t camBase = 0; +static uint32_t preciseaimbase = 0; +static uint32_t Aim_Flag = 0; +static uint32_t T_Flag = 0; + +//========================================================================== +// Purpose: return 1 if game is detected +//========================================================================== +static uint8_t PS2_SFDM_Status(void) +{ + //SCUS_973.62; + return (PS2_MEM_ReadWord(0x00093390) == 0x53435553 && PS2_MEM_ReadWord(0x00093394) == 0x5F393733) && PS2_MEM_ReadWord(0x00093398) == 0x2E36323B; +} + +//========================================================================== +// Purpose: Camera object check. Don't write where you're not supposed to. +//========================================================================== +static uint8_t PS2_SFDM_DetectCamera(void) +{ + uint32_t spielerbase = PS2_MEM_ReadPointer(PS2_SFDM_PTR_TO_PB); //read value of 0x5F4EC8 (0x1BFF490) + uint32_t pointeraimbase = PS2_MEM_ReadPointer(spielerbase + PS2_SFDM_OFFSET_TO_PRECISE_AIM_BASE_PTR_1); //read value of 0x1BFF490+0x12E0 (0xB370E0) + uint32_t tempaimbase = PS2_MEM_ReadPointer(pointeraimbase + PS2_SFDM_OFFSET_TO_PRECISE_AIM_BASE_PTR_2); //read value of 0xB370E0+0x14 (0xCA6910) + uint32_t tempcambase = PS2_MEM_ReadPointer(PS2_SFDM_CAMERA_PTR); + + if (tempaimbase && + PS2_MEM_ReadPointer(tempaimbase + PS2_SFDM_PRECISE_AIM_SAFETY_1) == PS2_SFDM_PRECISE_AIM_SAFETY_1_VALUE && + PS2_MEM_ReadPointer(tempaimbase + PS2_SFDM_PRECISE_AIM_SAFETY_2) == PS2_SFDM_PRECISE_AIM_SAFETY_2_VALUE) + { + preciseaimbase = tempaimbase; + } + + if (tempcambase != 0) + { + camBase = tempcambase; + return 1; + } + + return 0; +} + +//========================================================================== +// Purpose: calculate mouse look and inject into current game +//========================================================================== +static void PS2_SFDM_Inject(void) +{ + if (!PS2_SFDM_DetectCamera()) + return; + + if(xmouse == 0 && ymouse == 0) // if mouse is idle + return; + + float looksensitivity = (float)sensitivity; + float scale = 10000.f; + + Aim_Flag = PS2_MEM_ReadPointer(PS2_SFDN_PRECISE_AIM_FLAG); + T_Flag = PS2_MEM_ReadPointer(PS2_SFDN_PRECISE_T_FLAG); + + if (Aim_Flag == 0x3F800000 || T_Flag == 0x00000000 && + PS2_MEM_ReadPointer(preciseaimbase + PS2_SFDM_PRECISE_AIM_SAFETY_1) == PS2_SFDM_PRECISE_AIM_SAFETY_1_VALUE && + PS2_MEM_ReadPointer(preciseaimbase + PS2_SFDM_PRECISE_AIM_SAFETY_2) == PS2_SFDM_PRECISE_AIM_SAFETY_2_VALUE) //dont dont dont write there unless really these + + { + float camXa = PS2_MEM_ReadFloat(preciseaimbase + PS2_SFDM_PRECISE_AIM_OFFSET_X); + float camYa = PS2_MEM_ReadFloat(preciseaimbase + PS2_SFDM_PRECISE_AIM_OFFSET_Y); + + camXa -= (float)xmouse * looksensitivity / scale; + camYa -= (float)(invertpitch ? -ymouse : ymouse) * looksensitivity / scale; + + PS2_MEM_WriteFloat(preciseaimbase + PS2_SFDM_PRECISE_AIM_OFFSET_X, (float)camXa); + PS2_MEM_WriteFloat(preciseaimbase + PS2_SFDM_PRECISE_AIM_OFFSET_Y, (float)camYa); + } + + float camX = PS2_MEM_ReadFloat(camBase + PS2_SFDM_CAMERA_BASE_OFFSET_X); + float camY = PS2_MEM_ReadFloat(camBase + PS2_SFDM_CAMERA_BASE_OFFSET_Y); + + camX -= (float)xmouse * looksensitivity / scale; + camY -= (float)(invertpitch ? -ymouse : ymouse) * looksensitivity / scale; + + PS2_MEM_WriteFloat(camBase + PS2_SFDM_CAMERA_BASE_OFFSET_X, (float)camX); + PS2_MEM_WriteFloat(camBase + PS2_SFDM_CAMERA_BASE_OFFSET_Y, (float)camY); +} \ No newline at end of file diff --git a/main.h b/main.h index 338ddbf..7f942e4 100644 --- a/main.h +++ b/main.h @@ -19,8 +19,8 @@ //========================================================================== #include -#define DOLPHINVERSION "Dolphin" -#define BUILDINFO "(v0.31 - "__DATE__")" +#define DOLPHINVERSION "emulators" +#define BUILDINFO "(v0.31 - hotfix - "__DATE__")" #define LINE "__________________________________________________________________" // input for interface #define K_1 GetAsyncKeyState(0x31) // key '1' diff --git a/memory.c b/memory.c index 3826c03..19c610c 100644 --- a/memory.c +++ b/memory.c @@ -23,6 +23,7 @@ #include #include #include +#include // hex conversion for memory debug #include "main.h" #include "memory.h" @@ -110,6 +111,10 @@ void PS2_MEM_WriteUInt(const uint32_t addr, uint32_t value); void PS2_MEM_WriteUInt16(const uint32_t addr, uint16_t value); void PS2_MEM_WriteInt16(const uint32_t addr, int16_t value); void PS2_MEM_WriteFloat(const uint32_t addr, float value); +DWORD Process_ID = 0; +char PS2_EXE_Name[64]; +FARPROC RemoteAddress(HANDLE hProc, HMODULE hMod, const char* procName); +HMODULE RemoteHandle(DWORD ProcessPID, const TCHAR* modName); uint32_t SD_MEM_ReadWord(const uint32_t addr); float SD_MEM_ReadFloat(const uint32_t addr); @@ -128,7 +133,7 @@ float PSP_MEM_ReadFloat(const uint32_t addr); void PSP_MEM_WriteUInt16(const uint32_t addr, uint16_t value); void PSP_MEM_WriteFloat(const uint32_t addr, float value); -void printdebug(uint32_t val); +void printdebug(uint64_t val); //========================================================================== // Purpose: initialize dolphin handle and setup for memory injection @@ -155,6 +160,7 @@ uint8_t MEM_Init(void) strcpy(hookedEmulatorName, "DuckStation"); isPS1handle = 1; emuhandle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID); + Process_ID = pe32.th32ProcessID; break; } if(strcmp(pe32.szExeFile, "EmuHawk.exe") == 0) // if EmuHawk was found, 2.8 oldest tested working - 2.9 not supported @@ -198,28 +204,20 @@ uint8_t MEM_Init(void) emuhandle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID); break; } - //TODO: condense all pcsx2 checks down to one - if(strcmp(pe32.szExeFile, "pcsx2-qtx64-avx2.exe") == 0) // if pcsx2 was found - { - strcpy(hookedEmulatorName, "pcsx2-qtx64-avx2"); - isPcsx2handle = 1; - emuhandle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID); - break; - } - if(strcmp(pe32.szExeFile, "pcsx2-qtx64.exe") == 0) // if pcsx2 was found - { - strcpy(hookedEmulatorName, "pcsx2-qtx64"); - isPcsx2handle = 1; - emuhandle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID); - break; - } - if(strcmp(pe32.szExeFile, "pcsx2-qt.exe") == 0) // if pcsx2 was found - { - strcpy(hookedEmulatorName, "pcsx2-qt"); + const char* pcsx2Executables[] = {"pcsx2-qtx64-avx2.exe","pcsx2-qtx64.exe","pcsx2-qt.exe"}; + size_t numExecutables = sizeof(pcsx2Executables) / sizeof(pcsx2Executables[0]); + for (size_t i = 0; i < numExecutables; ++i) { + if (strcmp(pe32.szExeFile, pcsx2Executables[i]) == 0) { + strncpy(hookedEmulatorName, pcsx2Executables[i], strlen(pcsx2Executables[i]) - 4); + hookedEmulatorName[strlen(pcsx2Executables[i]) - 4] = '\0'; isPcsx2handle = 1; emuhandle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID); + Process_ID = pe32.th32ProcessID; + strncpy(PS2_EXE_Name, pe32.szExeFile, sizeof(PS2_EXE_Name) - 1); break; + } } + if(strcmp(pe32.szExeFile, "flycast.exe") == 0) { strcpy(hookedEmulatorName, "Flycast"); @@ -284,6 +282,98 @@ uint8_t MEM_FindRamOffset(void) uint32_t lastRegionSize = 0; uint32_t lastlastRegionSize = 0; + //--------------------Duckstation RAM export pointer----------------------- + if (isPS1handle == 1) { + const TCHAR* processName = "duckstation-qt-x64-ReleaseLTCG.exe"; + const TCHAR* moduleName = processName; + const char* symbol = "RAM"; + + printf("Scanning memory.\n"); + HANDLE snapshot = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, Process_ID); + HMODULE hMod = RemoteHandle(Process_ID, moduleName); + if (!hMod) { + return; + } + FARPROC addr = RemoteAddress(snapshot, hMod, symbol); + CloseHandle(snapshot); + + if (addr != 0) { + uint64_t pointerAddress = addr; + uint64_t foundValue; + ReadProcessMemory(emuhandle, (LPCVOID)pointerAddress, &foundValue, sizeof(foundValue), NULL); + emuoffset = foundValue; + printf(".\n"); + printf("..\n"); + printf("DEBUG - DUCKSTATION MEMORY BASE FOUND AT: 0x%p\n",foundValue); + } + } + //----------------------------------------------------------------------- + //--------------------PCSX2 RAM export pointer--------------------------- + //Using EEmem address causes some sort out of sync value updating in some games, seems like a PCSX2 thing or something with the injector?? -> use of a pointer to a different copy of PS2 virtual memory (hotfixed below) + if (isPcsx2handle == 1) { + const TCHAR* processName = PS2_EXE_Name; + const TCHAR* moduleName = processName; + const char* symbol = "EEmem"; + int chunk_size = 4096; + + HANDLE snapshot = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, Process_ID); + HMODULE hMod = RemoteHandle(Process_ID, moduleName); + if (!hMod) { + return; + } + FARPROC addr = RemoteAddress(snapshot, hMod, symbol); + CloseHandle(snapshot); + //search from EEmem SLUS string offset to different copy of virtual PS2 RAM + uint64_t PS2_Address = addr; + if (addr != 0) { + uint64_t pointerAddress = addr; + uint64_t EEmem; + uint64_t AddressCopy; + uint64_t OtherCopyBase; + BYTE* buffer; + SIZE_T bytesRead; + LPCVOID address = 0; + + ReadProcessMemory(emuhandle, (LPCVOID)pointerAddress, &EEmem, sizeof(EEmem), NULL); //EEmem is now set > offset this by 0x100000 > load up a chunk of data > loop to find ram copy that does not cause issues with injector, substract the 0x93390 and set emuoffset + + unsigned char* chunk = (unsigned char*)malloc(chunk_size); + DWORD_PTR offset = EEmem + 0x100000; //use an offset where the gamecode is, not 93390 that is determined by BIOS and not every games uses this offset + LPCVOID remotePtr = (LPCVOID)offset; + ReadProcessMemory(emuhandle, remotePtr, chunk, chunk_size, &bytesRead); // array gets loaded up correctly + + printf("Scanning memory.\n"); + while (VirtualQueryEx(emuhandle, address, &info, sizeof(info)) && info.RegionSize > 0) { //memory scan loop + if (info.State == MEM_COMMIT && (info.Protect == PAGE_READONLY || info.Protect == PAGE_READWRITE)) { + buffer = (BYTE*)malloc(info.RegionSize); + if (buffer && ReadProcessMemory(emuhandle, info.BaseAddress, buffer, info.RegionSize, &bytesRead)) { + for (SIZE_T i = 0; i <= bytesRead - chunk_size; i++) { + if (memcmp(buffer + i, chunk, chunk_size) == 0) { // if found match, exit, break out of the nested loop on the first match, will find EEmem if it wont find other memory + AddressCopy = (uint64_t*)((BYTE*)info.BaseAddress + i); + goto breakout; + } + } + } + } + address = (BYTE*)info.BaseAddress + info.RegionSize; + } + + breakout: + free(chunk);// free the memory + free(buffer); + + OtherCopyBase = AddressCopy - 0x100000; + printf(".\n"); + printf("..\n"); + printf("...\n"); + printf("DEBUG - PCSX2 EEMEM BASE FOUND AT: 0x%p\n",EEmem); + printf("DEBUG - PCSX2 MEMORY BASE FOUND AT: 0x%p\n",OtherCopyBase); + emuoffset = OtherCopyBase; + + // TODO: check the hotfix, clean up the code etc, remove the ridiculous printfs and code in normal debug page, and maybe some simple ui + } + } + //------------------------------------------------------------------------ + // if (strcmp(hookedEmulatorName, "DuckStation") == 0) // { // uint64_t output; // temp var @@ -413,22 +503,22 @@ uint8_t MEM_FindRamOffset(void) isBSNESMercuryHandle = 1; } } - else if (isPS1handle == 1) { + /*else if (isPS1handle == 1) { // emuRegionSize = 0x200000; // DuckStation emuRegionSize = 0x800000; // DuckStation, newer version 0.1-5943 (unsure which version changed region size) // TODO: check version and set region size // maybe look for a pointer to the right region and get size from that? - } else if (isN64handle == 1) { + }*/ else if (isN64handle == 1) { if (isMupenhandle) emuRegionSize = 0x20011000; // RetroArch(Mupen64Plus core)/simple64/RMG else emuRegionSize = 0x22D0000; // BizHawk 2.8 (Mupen64Plus) } else if (isBSNEShandle == 1) { emuRegionSize = 0x34000; - } else if (isPcsx2handle == 1) { + } /*else if (isPcsx2handle == 1) { // emuRegionSize = 0x80000; emuRegionSize = 0x1000; - } else if (isFlycastHandle == 1) { + }*/ else if (isFlycastHandle == 1) { emuRegionSize = 0x10000; } else if (isMesenHandle == 1) { emuRegionSize = 0x1BF000; @@ -559,7 +649,7 @@ uint8_t MEM_FindRamOffset(void) } } else if (isBSNEShandle == 1) { emuoffset += 0x2D7C; // WRAM always here? 0xB14000 + 0x2D7C, but region size is not fixed - } else if (isPcsx2handle == 1) { + } /*else if (isPcsx2handle == 1) { // check if region before 0x80000 has a size in a range, 0x1000 <= regionsize <= 0xF000 // if (lastRegionSize != 0x80000 || lastlastRegionSize != 0x1000) if (lastRegionSize != 0x80000 || lastlastRegionSize > 0xF000) @@ -567,7 +657,7 @@ uint8_t MEM_FindRamOffset(void) // } else if (isPPSSPPHandle) { // if (lastRegionSize != 0x3800000 && lastlastRegionSize != 0x200000) // continue; - } + }*/ // printdebug(lastRegionSize); // debug // printdebug(info.RegionSize); // debug @@ -955,13 +1045,15 @@ void SNES_MEM_WriteWord(const uint32_t addr, uint16_t value) // 16bit word return; WriteProcessMemory(emuhandle, (LPVOID)(emuoffset + addr), &value, sizeof(value), NULL); } - +//========================================================================== +//PS2 hooking via pointer. Use the base address of pcsx2.exe module -> point to static pointer/symbol "EEmem" -> Use its value as a "emuoffset". +//========================================================================== uint32_t PS2_MEM_ReadPointer(const uint32_t addr) { - if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) // if ps2 memory has not been init by emulator or reading from outside of memory range + if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) return 0; uint32_t output; // temp var used for output of function - ReadProcessMemory(emuhandle, (LPVOID)(emuoffset + (addr - 0x80000)), &output, sizeof(output), NULL); + ReadProcessMemory(emuhandle, (LPVOID)(emuoffset + addr), &output, sizeof(output), NULL); // printdebug(1); // debug // MEM_ByteSwap32(&output); // byteswap return output; @@ -969,10 +1061,10 @@ uint32_t PS2_MEM_ReadPointer(const uint32_t addr) uint32_t PS2_MEM_ReadWord(const uint32_t addr) { - if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) // if ps2 memory has not been init by emulator or reading from outside of memory range + if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) return 0; uint32_t output; // temp var used for output of function - ReadProcessMemory(emuhandle, (LPVOID)(emuoffset + (addr - 0x80000)), &output, sizeof(output), NULL); + ReadProcessMemory(emuhandle, (LPVOID)(emuoffset + addr), &output, sizeof(output), NULL); // printdebug(1); // debug MEM_ByteSwap32(&output); // byteswap return output; @@ -980,40 +1072,39 @@ uint32_t PS2_MEM_ReadWord(const uint32_t addr) uint32_t PS2_MEM_ReadUInt(const uint32_t addr) { - if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) // if ps2 memory has not been init by emulator or reading from outside of memory range + if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) return 0; uint32_t output; // temp var used for output of function - ReadProcessMemory(emuhandle, (LPVOID)(emuoffset + (addr - 0x80000)), &output, sizeof(output), NULL); + ReadProcessMemory(emuhandle, (LPVOID)(emuoffset + addr), &output, sizeof(output), NULL); // printdebug(1); // debug return output; } uint32_t PS2_MEM_ReadUInt16(const uint32_t addr) { - if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) // if ps2 memory has not been init by emulator or reading from outside of memory range + if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) return 0; uint16_t output; // temp var used for output of function - ReadProcessMemory(emuhandle, (LPVOID)(emuoffset + (addr - 0x80000)), &output, sizeof(output), NULL); + ReadProcessMemory(emuhandle, (LPVOID)(emuoffset + addr), &output, sizeof(output), NULL); // printdebug(1); // debug return output; } int16_t PS2_MEM_ReadInt16(const uint32_t addr) { - if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) // if ps2 memory has not been init by emulator or reading from outside of memory range + if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) return 0; int16_t output; // temp var used for output of function - ReadProcessMemory(emuhandle, (LPVOID)(emuoffset + (addr - 0x80000)), &output, sizeof(output), NULL); - // printdebug(1); // debug + ReadProcessMemory(emuhandle, (LPVOID)(emuoffset + addr), &output, sizeof(output), NULL); return output; } uint8_t PS2_MEM_ReadUInt8(const uint32_t addr) { - if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) // if ps2 memory has not been init by emulator or reading from outside of memory range + if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) return 0; uint8_t output; // temp var used for output of function - ReadProcessMemory(emuhandle, (LPVOID)(emuoffset + (addr - 0x80000)), &output, sizeof(output), NULL); + ReadProcessMemory(emuhandle, (LPVOID)(emuoffset + addr), &output, sizeof(output), NULL); // printdebug(1); // debug return output; } @@ -1023,7 +1114,7 @@ float PS2_MEM_ReadFloat(const uint32_t addr) if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) return 0; float output; // temp var used for output of function - ReadProcessMemory(emuhandle, (LPVOID)(emuoffset + (addr - 0x80000)), &output, sizeof(output), NULL); + ReadProcessMemory(emuhandle, (LPVOID)(emuoffset + addr), &output, sizeof(output), NULL); // MEM_ByteSwap32((uint32_t *)&output); // byteswap return output; } @@ -1033,28 +1124,28 @@ void PS2_MEM_WriteWord(const uint32_t addr, uint32_t value) if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) return; MEM_ByteSwap32(&value); // byteswap - WriteProcessMemory(emuhandle, (LPVOID)(emuoffset + (addr - 0x80000)), &value, sizeof(value), NULL); + WriteProcessMemory(emuhandle, (LPVOID)(emuoffset + addr), &value, sizeof(value), NULL); } void PS2_MEM_WriteUInt(const uint32_t addr, uint32_t value) { if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) return; - WriteProcessMemory(emuhandle, (LPVOID)(emuoffset + (addr - 0x80000)), &value, sizeof(value), NULL); + WriteProcessMemory(emuhandle, (LPVOID)(emuoffset + addr), &value, sizeof(value), NULL); } void PS2_MEM_WriteUInt16(const uint32_t addr, uint16_t value) { if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) return; - WriteProcessMemory(emuhandle, (LPVOID)(emuoffset + (addr - 0x80000)), &value, sizeof(value), NULL); + WriteProcessMemory(emuhandle, (LPVOID)(emuoffset + addr), &value, sizeof(value), NULL); } void PS2_MEM_WriteInt16(const uint32_t addr, int16_t value) { if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) return; - WriteProcessMemory(emuhandle, (LPVOID)(emuoffset + (addr - 0x80000)), &value, sizeof(value), NULL); + WriteProcessMemory(emuhandle, (LPVOID)(emuoffset + addr), &value, sizeof(value), NULL); } @@ -1063,7 +1154,7 @@ void PS2_MEM_WriteFloat(const uint32_t addr, float value) if(!emuoffset || PS2NOTWITHINMEMRANGE(addr)) return; // MEM_ByteSwap32((uint32_t *)&value); // byteswap - WriteProcessMemory(emuhandle, (LPVOID)(emuoffset + (addr - 0x80000)), &value, sizeof(value), NULL); + WriteProcessMemory(emuhandle, (LPVOID)(emuoffset + addr), &value, sizeof(value), NULL); } // TODO: give Dreamcast it's own within mem range @@ -1210,14 +1301,74 @@ void PSP_MEM_WriteFloat(const uint32_t addr, float value) WriteProcessMemory(emuhandle, (LPVOID)(emuoffset + addr), &value, sizeof(value), NULL); } -void printdebug(uint32_t val) +void printdebug(uint64_t val) //hexadecimal addresses debug { FILE *fp; fp = fopen("test.txt", "w"); - char output[255]; - sprintf(output, "%u", val); - fprintf(fp, output); + if (fp != NULL) { + char output[255]; + sprintf(output, "0x%" PRIx64, val); + fprintf(fp, "%s", output); + + fclose(fp); + } else { + perror("Failed to open file"); + } +} + +// ============================================================================================================================= +// Functions to look for specified symbol in the modules of a remote process, DLL injection would be much, much, much simpler +// ============================================================================================================================= +HMODULE RemoteHandle(DWORD Process_ID, const TCHAR* modName) { + HMODULE hMods[1024]; + DWORD cbNeeded; + + HANDLE snapshot = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, Process_ID); + if (!snapshot) return NULL; + if (EnumProcessModulesEx(snapshot, hMods, sizeof(hMods), &cbNeeded, LIST_MODULES_ALL)) { + for (unsigned int i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) { + TCHAR szModName[MAX_PATH]; + if (GetModuleBaseName(snapshot, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR))) { + if (_tcscmp(szModName, modName) == 0) { + CloseHandle(snapshot); + return hMods[i]; + } + } + } + } + CloseHandle(snapshot); + return NULL; +} +FARPROC RemoteAddress(HANDLE snapshot, HMODULE hMod, const char* procName) { + BYTE* base = (BYTE*)hMod; + IMAGE_DOS_HEADER dosHeader; + IMAGE_NT_HEADERS ntHeaders; + IMAGE_EXPORT_DIRECTORY expDir; + + if (!ReadProcessMemory(snapshot, base, &dosHeader, sizeof(dosHeader), NULL)) return NULL; // Reads DOS header of the module + if (!ReadProcessMemory(snapshot, base + dosHeader.e_lfanew, &ntHeaders, sizeof(ntHeaders), NULL)) return NULL; // Reads the PE header + if (!ReadProcessMemory(snapshot, base + ntHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, &expDir, sizeof(expDir), NULL)) return NULL; //Reads the exported directory + + DWORD* funcs = (DWORD*)malloc(expDir.NumberOfFunctions * sizeof(DWORD)); + DWORD* names = (DWORD*)malloc(expDir.NumberOfNames * sizeof(DWORD)); + WORD* ordinals = (WORD*)malloc(expDir.NumberOfNames * sizeof(WORD)); + if (!ReadProcessMemory(snapshot, base + expDir.AddressOfFunctions, funcs, expDir.NumberOfFunctions * sizeof(DWORD), NULL)) return NULL; + if (!ReadProcessMemory(snapshot, base + expDir.AddressOfNames, names, expDir.NumberOfNames * sizeof(DWORD), NULL)) return NULL; + if (!ReadProcessMemory(snapshot, base + expDir.AddressOfNameOrdinals, ordinals, expDir.NumberOfNames * sizeof(WORD), NULL)) return NULL; + + FARPROC addr = NULL; + for (DWORD i = 0; i < expDir.NumberOfNames; i++) { + char funcName[256]; + if (ReadProcessMemory(snapshot, base + names[i], funcName, sizeof(funcName), NULL) && strcmp(funcName, procName) == 0) { + addr = (FARPROC)(base + funcs[ordinals[i]]); + break; + } + } + + free(funcs); + free(names); + free(ordinals); - fclose(fp); + return addr; } \ No newline at end of file From 72f176abad74e9d5fc8e2d0dff487b42ecfd93f6 Mon Sep 17 00:00:00 2001 From: luke01234 <95252713+luke01234@users.noreply.github.com> Date: Fri, 10 Jan 2025 14:29:03 -0600 Subject: [PATCH 6/9] Incorporated the work of https://github.com/vl4sty/MouseInjectorDolphinDuck so that the program can hook to new versions of duckstation and pcsx2 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 801db1d..e654416 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ An external app that injects cursor input into game memory. ### *This fork incorporates the work from https://github.com/vl4sty/MouseInjectorDolphinDuck in order to hook to newer versions of duckstation and pcsx2, however with support for some more games added by myself.* +I would have liked to simply fork their repo but Github doesn't allow you to fork a repo if you have already forked its upstream. + ### !This fork is focused only on Duckstation and PCSX2 emulators! ## Additional games for PS2 - NTSC ONLY: | Game Title | Issues | From a3f06b6d29d239f19ed7d198ef178f36c95db8bb Mon Sep 17 00:00:00 2001 From: luke01234 <95252713+luke01234@users.noreply.github.com> Date: Fri, 10 Jan 2025 14:37:40 -0600 Subject: [PATCH 7/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 91dddbe..8b52991 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ An external app that injects cursor input into game memory. -### *This fork incorporates the work from https://github.com/vl4sty/MouseInjectorDolphinDuck in order to hook to newer versions of duckstation and pcsx2, however with support for some more games added by myself.* +### *This fork incorporates the work from https://github.com/vl4sty/MouseInjectorDolphinDuck in order to hook to newer versions of duckstation and pcsx2, however with support for some more games added by myself and vl4sty.* I would have liked to simply fork their repo but Github doesn't allow you to fork a repo if you have already forked its upstream. From ce62acf5463002b7c36119244eaac1cfd7708b45 Mon Sep 17 00:00:00 2001 From: luke01234 <95252713+luke01234@users.noreply.github.com> Date: Fri, 14 Mar 2025 18:17:12 -0500 Subject: [PATCH 8/9] Added support for "Germs : Nerawareta Machi" (PS1 JP) - Requires the use of the corresponding cheat file. Also added better PS3 hooking support, AC4A mouse injector still in progress. --- cheats/PS1/Germs Nerawareta Machi(JP).cht | 9 + games/game.c | 6 + games/ps1_germs.c | 153 ++++++++++++++++ games/ps3_AC4A.c | 193 +++++++++++++++++++++ games/ps3_demonssouls.c | 63 +++++++ memory.c | 40 ++++- memory.h | 2 +- 7 files changed, 457 insertions(+), 9 deletions(-) create mode 100644 cheats/PS1/Germs Nerawareta Machi(JP).cht create mode 100644 games/ps1_germs.c create mode 100644 games/ps3_AC4A.c create mode 100644 games/ps3_demonssouls.c diff --git a/cheats/PS1/Germs Nerawareta Machi(JP).cht b/cheats/PS1/Germs Nerawareta Machi(JP).cht new file mode 100644 index 0000000..f81c11b --- /dev/null +++ b/cheats/PS1/Germs Nerawareta Machi(JP).cht @@ -0,0 +1,9 @@ +#group=Ungrouped +#type=Gameshark +#activation=EndFrame +#Author = Unicorngoulash (Giovanni van den Heuvel) +#Description = Forces the camera to update even without controller input. Made by Unicorngoulash (Giovanni van den Heuvel) +[*Auto update camera read] +80197A26 1000 + + diff --git a/games/game.c b/games/game.c index fff4596..b2b35c6 100644 --- a/games/game.c +++ b/games/game.c @@ -185,6 +185,9 @@ extern const GAMEDRIVER *GAME_PS1_RS6; extern const GAMEDRIVER *GAME_PS2_007QS; extern const GAMEDRIVER *GAME_PS2_SFDM; extern const GAMEDRIVER *GAME_PS2_FUGITIVE_HUNTER; +extern const GAMEDRIVER *GAME_PS1_GERMS; +extern const GAMEDRIVER *GAME_PS3_DEMONSSOULS; +extern const GAMEDRIVER *GAME_PS3_AC4A; static const GAMEDRIVER **GAMELIST[] = @@ -291,6 +294,8 @@ static const GAMEDRIVER **GAMELIST[] = &GAME_PS2_JURASSICTHEHUNTED, &GAME_PS2_MONSTERHUNTER, // UNF &GAME_PS3_HAZE, // UNF + &GAME_PS3_DEMONSSOULS, + &GAME_PS3_AC4A, &GAME_PS2_NOONELIVESFOREVER, &GAME_SS_VIRTUALHYDLIDE, // UNF &GAME_PS2_EARTHDEFENSEFORCE, @@ -351,6 +356,7 @@ static const GAMEDRIVER **GAMELIST[] = &GAME_PS1_RS6, // UNF &GAME_PS2_007QS, &GAME_PS2_FUGITIVE_HUNTER, + &GAME_PS1_GERMS, // &GAME_PS2_SFDM // UNF }; diff --git a/games/ps1_germs.c b/games/ps1_germs.c new file mode 100644 index 0000000..59c17c8 --- /dev/null +++ b/games/ps1_germs.c @@ -0,0 +1,153 @@ +//=========================================================== +// Mouse Injector for Dolphin +//========================================================================== +// Copyright (C) 2019-2020 Carnivorous +// All rights reserved. +// +// Mouse Injector is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, visit http://www.gnu.org/licenses/gpl-2.0.html +//========================================================================== +#include +#include "../main.h" +#include "../memory.h" +#include "../mouse.h" +#include "game.h" + +#define TAU 6.2831853f // 0x40C90FDB + +#define GERMS_CAMY 0x1E068C +#define GERMS_CAMX 0x1E068E +#define GERMS_TRAIN_CAMY 0x1E114C +#define GERMS_TRAIN_CAMX 0x1E114E +#define GERMS_CAR_CAMY 0x1E117C +#define GERMS_CAR_CAMX 0x1E117E + +static uint8_t PS1_GERMS_Status(void); +static void PS1_GERMS_Inject(void); + +static const GAMEDRIVER GAMEDRIVER_INTERFACE = +{ + "Germs : Nerawareta Machi\n Make sure to use the required cheat file for this game.", + PS1_GERMS_Status, + PS1_GERMS_Inject, + 1, // 1000 Hz tickrate + 0 // crosshair sway not supported for driver +}; + +const GAMEDRIVER *GAME_PS1_GERMS = &GAMEDRIVER_INTERFACE; + +static float xAccumulator = 0.f; +static float yAccumulator = 0.f; + +//========================================================================== +// Purpose: return 1 if game is detected +//========================================================================== +static uint8_t PS1_GERMS_Status(void) +{ + //534C5053 + //5F303231 + //2E30373B + + return (PS1_MEM_ReadWord(0x92EC) == 0x534C5053U && PS1_MEM_ReadWord(0x92F0) == 0x5F303231U && PS1_MEM_ReadWord(0x92F4) == 0x2E30373BU); +} + +static void PS1_GERMS_Inject(void) +{ + if(xmouse == 0 && ymouse == 0) // if mouse is idle + return; + + uint16_t camX = PS1_MEM_ReadHalfword(GERMS_CAMX); + uint16_t camY = PS1_MEM_ReadHalfword(GERMS_CAMY); + + uint16_t trainCamX = PS1_MEM_ReadHalfword(GERMS_TRAIN_CAMX); + uint16_t trainCamY = PS1_MEM_ReadHalfword(GERMS_TRAIN_CAMY); + + uint16_t carCamX = PS1_MEM_ReadHalfword(GERMS_CAR_CAMX); + uint16_t carCamY = PS1_MEM_ReadHalfword(GERMS_CAR_CAMY); + + float camXF = (float)camX; + float camYF = (float)camY; + + float trainCamXF = (float)trainCamX; + float trainCamYF = (float)trainCamY; + + float carCamXF = (float)carCamX; + float carCamYF = (float)carCamY; + + const float Yscale = .1f; + const float Xscale = .1f; + const float looksensitivity = (float)sensitivity / 20.f; + + //NORMAL LOOK + float dx = (float)xmouse * looksensitivity * Xscale; + AccumulateAddRemainder(&camXF, &xAccumulator, xmouse, dx); + + float ym = -(float)(invertpitch ? -ymouse : ymouse); + float dy = ym * looksensitivity * Yscale; + AccumulateAddRemainder(&camYF, &yAccumulator, ym, dy); + + //TRAIN LOOK + float trainDX = (float)xmouse * looksensitivity * Xscale; + AccumulateAddRemainder(&trainCamXF, &xAccumulator, xmouse, trainDX); + + float trainDY = ym * looksensitivity * Yscale; + AccumulateAddRemainder(&trainCamYF, &yAccumulator, ym, trainDY); + + //CAR LOOK + float carDX = (float)xmouse * looksensitivity * Xscale; + AccumulateAddRemainder(&carCamXF, &xAccumulator, xmouse, carDX); + + float carDY = ym * looksensitivity * Yscale; + AccumulateAddRemainder(&carCamYF, &yAccumulator, ym, carDY); + + // clamp y-axis + // range is larger than game usually allows but feels better + if (camYF > 65 && camYF < 32000) + camYF = 65; + + + if (camYF < 65511 && camYF > 32000) + camYF = 65511; + + /*if (camXF < 0) + camXF = 360 - camXF; + if (camXF > 359) + camXF = 0 + camXF;*/ + + //clamp train view rotations + if (trainCamYF > 65 && trainCamYF < 32000) + trainCamYF = 65; + + + if (trainCamYF < 65511 && trainCamYF > 32000) + trainCamYF = 65511; + + //clamp car view rotations + if (carCamXF > 65 && carCamXF < 32000) + carCamXF = 65; + if (carCamXF < 65471 && carCamXF > 32000) + carCamXF = 65471; + + if (carCamYF > 20 && carCamYF < 32000) + carCamYF = 20; + if (carCamYF < 65516 && carCamYF > 32000) + carCamYF = 65516; + + + PS1_MEM_WriteHalfword(GERMS_CAMX, (uint16_t)camXF); + PS1_MEM_WriteHalfword(GERMS_CAMY, (uint16_t)camYF); + PS1_MEM_WriteHalfword(GERMS_TRAIN_CAMX, (uint16_t)trainCamXF); + PS1_MEM_WriteHalfword(GERMS_TRAIN_CAMY, (uint16_t)trainCamYF); + PS1_MEM_WriteHalfword(GERMS_CAR_CAMX, (uint16_t)carCamXF); + PS1_MEM_WriteHalfword(GERMS_CAR_CAMY, (uint16_t)carCamYF); +} \ No newline at end of file diff --git a/games/ps3_AC4A.c b/games/ps3_AC4A.c new file mode 100644 index 0000000..08ebd29 --- /dev/null +++ b/games/ps3_AC4A.c @@ -0,0 +1,193 @@ +//=========================================================== +// Mouse Injector for Dolphin +//========================================================================== +// Copyright (C) 2019-2020 Carnivorous +// All rights reserved. +// +// Mouse Injector is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, visit http://www.gnu.org/licenses/gpl-2.0.html +//========================================================================== +#include +#include "../main.h" +#include "../memory.h" +#include "../mouse.h" +#include "game.h" + +#define PI 3.14159265f // 0x40490FDB +#define TAU 6.2831853f // 0x40C90FDB + +#define AC4A_CAM_START_IDENTIFIER 0x0123A9B8 //i believe this hex identifies the start of the player cam, there are several copies of it in memory, but the only relevant one is the first one stored between 0x332000000 and 0x333000000 +#define AC4A_CAMY_STRING 0x3D567750U //you can always find the camy float at this string location + 0x4. (after the cam start identifier) string should read "=VwP" + +//FF FF FF FF +//FF FF FF FF +//00 00 00 00 +//00 00 00 05 +//00 00 00 00 +//00 00 00 05 this byte array is 0x68 behind the first sine value +//believe me i know how scuffed this is but until I find a real way of finding pointers in RPCS3 memory this is the best I got +#define AC4A_SIN_STRING1 0xFFFFFFFFU +#define AC4A_SIN_STRING2 0xFFFFFFFFU +#define AC4A_SIN_STRING3 0x00000000U +#define AC4A_SIN_STRING4 0x00000005U +#define AC4A_SIN_STRING5 0x00000000U +#define AC4A_SIN_STRING6 0x00000005U + +#define AC4A_CAM_SEARCH_MIN 0x2000000 //search values for finding the camera (I am very bad at finding pointers in the ps3) +#define AC4A_CAM_SEARCH_MAX 0x3000000 //if you have advice on finding them, please help + +#define AC4A_CAMY 0x2DA6090 //not static, fix later +#define AC4A_SINE1 0x2D9B1E0 //NOT STATIC FIX LATER THESE TWO SHOULD REMAIN IDENTICAL +#define AC4A_COS1 0x2D9B1E8 //NOT STATIC FIX LATER THIS COSINE IS INVERSE +#define AC4A_COS2 0x2D9B200 //NOT STATIC FIX LATER THIS COSINE IS CORRECT +#define AC4A_SINE2 0x2D9B208 //NOT STATIC FIX LATER THESE TWO SHOULD REMAIN IDENTICAL + +static uint8_t PS3_AC4A_Status(void); +static void PS3_AC4A_Inject(void); + +static const GAMEDRIVER GAMEDRIVER_INTERFACE = +{ + "Amored Core: For Answer", + PS3_AC4A_Status, + PS3_AC4A_Inject, + 1, // 1000 Hz tickrate + 0 // crosshair sway not supported for driver +}; + +const GAMEDRIVER *GAME_PS3_AC4A = &GAMEDRIVER_INTERFACE; + +//========================================================================== +// Purpose: return 1 if game is detected +//========================================================================== +static uint8_t PS3_AC4A_Status(void) +{ + //41 69 52 65 + //73 6F 75 00 + return (PS3_MEM_ReadUInt(0x1231) == 0x41695265U && + PS3_MEM_ReadUInt(0x1235) == 0x736F7500U); +} + +static void AC4A_Find_Camera(int *camStart, int *camY, int *sine1) +{ + int camSearchIndex = AC4A_CAM_SEARCH_MIN; + int camStartFound = 0; + int camYFound = 0; + int sine1Found = 0; + while (camSearchIndex <= AC4A_CAM_SEARCH_MAX) + { + if(PS3_MEM_ReadUInt(camSearchIndex) == AC4A_CAM_START_IDENTIFIER && !camStartFound) + { + camStartFound = camSearchIndex; + printf("Cam start found \n"); + } + else if(PS3_MEM_ReadUInt(camSearchIndex) == AC4A_CAMY_STRING && + !camYFound && camStartFound) + { + camYFound = camSearchIndex;// + 0x4; + printf("Camy found \n"); + } + else if(PS3_MEM_ReadUInt(camSearchIndex) == AC4A_SIN_STRING1 && + PS3_MEM_ReadUInt(camSearchIndex + 0x4) == AC4A_SIN_STRING2 && + PS3_MEM_ReadUInt(camSearchIndex + 0x8) == AC4A_SIN_STRING3 && + PS3_MEM_ReadUInt(camSearchIndex + 0xC) == AC4A_SIN_STRING4 && + PS3_MEM_ReadUInt(camSearchIndex + 0x10) == AC4A_SIN_STRING5 && + PS3_MEM_ReadUInt(camSearchIndex + 0x14) == AC4A_SIN_STRING6 && + !sine1Found && camStartFound) + { + sine1Found = camSearchIndex;// + 0x68; + printf("sine1Found found \n"); + } + + if (camStartFound && camYFound && sine1Found) + { + printf("Addresses found\n"); + *camY = camYFound; + *sine1 = sine1Found; + *camStart = camStartFound; + break; + } + + camSearchIndex += 0x4; + + } +} + +int camStartAddress; +int camYPrecursor; +int sine1Precursor; + +int camYAddress; +int sine1Address; +int sine2Address; +int cosine1Address; +int cosine2Address; +static void PS3_AC4A_Inject(void) +{ + if(xmouse == 0 && ymouse == 0) // if mouse is idle + return; + + float looksensitivity = (float)sensitivity; + float scale = 12000.f; + + + if (!(PS3_MEM_ReadUInt(camStartAddress) == AC4A_CAM_START_IDENTIFIER && //sanity check the memory locations + PS3_MEM_ReadUInt(camYPrecursor) == AC4A_CAMY_STRING && + (PS3_MEM_ReadUInt(sine1Precursor) == AC4A_SIN_STRING1 && + PS3_MEM_ReadUInt(sine1Precursor + 0x4) == AC4A_SIN_STRING2 && + PS3_MEM_ReadUInt(sine1Precursor + 0x8) == AC4A_SIN_STRING3 && + PS3_MEM_ReadUInt(sine1Precursor + 0xC) == AC4A_SIN_STRING4 && + PS3_MEM_ReadUInt(sine1Precursor + 0x10) == AC4A_SIN_STRING5 && + PS3_MEM_ReadUInt(sine1Precursor + 0x14) == AC4A_SIN_STRING6))) + { + printf("looking for camera\n"); + AC4A_Find_Camera(&camStartAddress, &camYPrecursor, &sine1Precursor); + camYAddress = camYPrecursor + 0x4; + sine1Address = sine1Precursor + 0x68; + cosine1Address = sine1Address + 0x8; + cosine2Address = sine1Address + 0x20; + sine2Address = cosine2Address + 0x8; + } + + + float camXSin = PS3_MEM_ReadFloat(sine1Address); + float camXCos = PS3_MEM_ReadFloat(cosine2Address); + float camY = PS3_MEM_ReadFloat(camYAddress); + + float CamXAngle = atan(camXSin / camXCos); + + CamXAngle -= (float)xmouse * looksensitivity / scale; + + if (camXCos < 0) + CamXAngle += PI; +/*while (camXCos < -PI) + CamXAngle += TAU;*/ + + + camY -= (float)(invertpitch ? -ymouse : ymouse) * looksensitivity / scale; + camXCos = cos(CamXAngle); + camXSin = sin(CamXAngle); + + + while (camY > 1.221730471f) + camY = 1.221730471f; + while (camY < -1.221730471f) + camY = -1.221730471f; + + + + PS3_MEM_WriteFloat(camYAddress, camY); + PS3_MEM_WriteFloat(sine1Address, camXSin); + PS3_MEM_WriteFloat(cosine1Address, -camXCos); + PS3_MEM_WriteFloat(cosine2Address, camXCos); + PS3_MEM_WriteFloat(sine2Address, camXSin); +} \ No newline at end of file diff --git a/games/ps3_demonssouls.c b/games/ps3_demonssouls.c new file mode 100644 index 0000000..5928da4 --- /dev/null +++ b/games/ps3_demonssouls.c @@ -0,0 +1,63 @@ +//=========================================================== +// Mouse Injector for Dolphin +//========================================================================== +// Copyright (C) 2019-2020 Carnivorous +// All rights reserved. +// +// Mouse Injector is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, visit http://www.gnu.org/licenses/gpl-2.0.html +//========================================================================== +#include +#include "../main.h" +#include "../memory.h" +#include "../mouse.h" +#include "game.h" + +#define TAU 6.2831853f // 0x40C90FDB + +static uint8_t PS3_DEMONSSOULS_Status(void); +static void PS3_DEMONSSOULS_Inject(void); + +static const GAMEDRIVER GAMEDRIVER_INTERFACE = +{ + "Demon's Souls", + PS3_DEMONSSOULS_Status, + PS3_DEMONSSOULS_Inject, + 1, // 1000 Hz tickrate + 0 // crosshair sway not supported for driver +}; + +const GAMEDRIVER *GAME_PS3_DEMONSSOULS = &GAMEDRIVER_INTERFACE; + +//========================================================================== +// Purpose: return 1 if game is detected +//========================================================================== +static uint8_t PS3_DEMONSSOULS_Status(void) +{ + //42 4C 55 53 + //33 30 34 34 + //33 44 45 4D + //4F 4E 53 53 + //printf("PS3 Read %d\n", PS3_MEM_ReadUInt(0x8A9FF00)); + return (PS3_MEM_ReadUInt(0x8A9FF00) == 0x424C5553U && + PS3_MEM_ReadUInt(0x8A9FF04) == 0x33303434U && + PS3_MEM_ReadUInt(0x8A9FF08) == 0x3344454DU && + PS3_MEM_ReadUInt(0x8A9FF0C) == 0x4F4E5353U); +} + +static void PS3_DEMONSSOULS_Inject(void) +{ + if(xmouse == 0 && ymouse == 0) // if mouse is idle + return; + +} \ No newline at end of file diff --git a/memory.c b/memory.c index 19c610c..eca6ce6 100644 --- a/memory.c +++ b/memory.c @@ -524,7 +524,9 @@ uint8_t MEM_FindRamOffset(void) emuRegionSize = 0x1BF000; } else if (isRPCS3Handle == 1) { // TODO: if rpcs3 just set offset to 0x330000000 since it seems to be static? - emuRegionSize = 0xCC00000; // Killzone HD + emuRegionSize = 0x0FFFFFFF; + emuoffset = 0x330000000ULL; + //emuRegionSize = 0xCC00000; // Killzone HD // emuRegionSize = 0x100000; // HAZE } else if (isPPSSPPHandle == 1) { emuRegionSize = 0x1F00000; @@ -537,7 +539,8 @@ uint8_t MEM_FindRamOffset(void) // PCSX2: MEM_MAPPED // PPSSPP: MEM_MAPPED - DWORD regionType = MEM_MAPPED; // Dolphin and DuckStation regions are type MEM_MAPPED + // RPCS3: MEM_MAPPED + DWORD regionType = MEM_MAPPED; // Dolphin, DuckStation and RPCS3 regions are type MEM_MAPPED if (isN64handle == 1 || isKronosHandle == 1) regionType = MEM_PRIVATE; // All N64 emulator regions are type MEM_PRIVATE if (isBSNEShandle == 1 || isBSNESMercuryHandle == 1) @@ -572,10 +575,15 @@ uint8_t MEM_FindRamOffset(void) // } // check if region is the size of region where console memory is located - uint8_t regionFound = 0; - if (info.RegionSize == emuRegionSize && ((info.Type == regionType) || isN64handle)) - regionFound = 1; - + uint8_t regionFound = 0; + if ((info.RegionSize == emuRegionSize && ((info.Type == regionType)) || isN64handle || isRPCS3Handle)) + { + regionFound = 1; + } + else + { + //while (1) printf("failed to find region %d\n", isRPCS3Handle); + } // if (isBizHawkSNESHandle && !regionFound) // { // if (info.Type == regionType) @@ -612,8 +620,11 @@ uint8_t MEM_FindRamOffset(void) continue; } else if (isRPCS3Handle == 1) { - if (lastRegionSize != 0xFF70000) - continue; + //printf("emuoffset ps3 set %11x\n", emuoffset); + emuoffset = 0x330000000ULL; + //while (1) printf("emuoffset ps3 set %11x\n", emuoffset); //this will print incorrectly, dont worry about it its being set properly + /*if (lastRegionSize != 0xFF70000) + continue;*/ } else if (isNOMONEYPSXHandle == 1) { emuoffset += 0x30100; @@ -1202,7 +1213,10 @@ void SD_MEM_WriteFloat(const uint32_t addr, float value) uint32_t PS3_MEM_ReadUInt(const uint32_t addr) { if(!emuoffset || PS3NOTWITHINMEMRANGE(addr)) + //while (1) printf("Out of range.\n%d %d\n",emuoffset,PS3NOTWITHINMEMRANGE(addr)); return 0; + //printf("In range.\n%11x %d\n",emuoffset,PS3NOTWITHINMEMRANGE(addr)); + //emuoffset = 0x330000000; uint32_t output; // temp var used for output of function ReadProcessMemory(emuhandle, (LPVOID)(emuoffset + addr), &output, sizeof(output), NULL); MEM_ByteSwap32((uint32_t *)&output); // byteswap @@ -1231,6 +1245,16 @@ float PS3_MEM_ReadFloat(const uint32_t addr) return output; } +uint32_t PS3_MEM_ReadWord(const uint32_t addr) //function may or may not work idk +{ + if(!emuoffset || PSPNOTWITHINMEMRANGE(addr)) + return 0; + uint32_t output; // temp var used for output of function + ReadProcessMemory(emuhandle, (LPVOID)(emuoffset + addr), &output, sizeof(output), NULL); + //MEM_ByteSwap32((uint32_t *)&output); // byteswap + return output; +} + void PS3_MEM_WriteFloat(const uint32_t addr, float value) { if(!emuoffset || PS3NOTWITHINMEMRANGE(addr)) diff --git a/memory.h b/memory.h index 37f4bd3..c2a4cf1 100644 --- a/memory.h +++ b/memory.h @@ -32,7 +32,7 @@ #define PS2WITHINMEMRANGE(X) (!PS2NOTWITHINMEMRANGE(X)) #define SSNOTWITHINMEMRANGE(X) (X > 0xFFFFF) #define SSWITHINMEMRANGE(X) (!SSNOTWITHINMEMRANGE(X)) -#define PS3NOTWITHINMEMRANGE(X) (X > 0xCC00000) +#define PS3NOTWITHINMEMRANGE(X) (X > 0x0FFFFFFF) #define PS3WITHINMEMRANGE(X) (!PS3NOTWITHINMEMRANGE(X)) #define PSPNOTWITHINMEMRANGE(X) (X > 0x1F00000) #define PSPWITHINMEMRANGE(X) (!PSPNOTWITHINMEMRANGE(X)) From 5440412a406825a2274645ba1ebd13056f3860b5 Mon Sep 17 00:00:00 2001 From: luke01234 <95252713+luke01234@users.noreply.github.com> Date: Fri, 14 Mar 2025 18:27:03 -0500 Subject: [PATCH 9/9] Updated the readme to include Germs : Nerawareta Machi --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8b52991..42f6a26 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,7 @@ avoid clicking off the window. | Echo Night (USA) | SLUS-00820 | Good | Not fully tested | - | - | | Future Cop: L.A.P.D. (USA) | SLUS-00739 | Fair | Not fully tested | - | - | | G-Police (USA) | SLUS-00544
SLUS-00556 | Good | Not full tested | - | - | +| Germs : Nerawareta Machi (JP) | SLPS-02107 | Good | Not full tested | - | **Germs Nerawareta Machi(JP).cht** | | Hellnight (Europe) | SLES-01562 | Good | Requires supplied cheat file
Not fully tested | - | **Hellnight_SLES-10562.cht** | | Hybrid (Japan, Europe) | SLPS-01102
SLES-03531 | Fair | Requires supplied cheat file
Not fully tested | - | **Hybrid_SLPS-01102.cht (Japan)
Hybrid_SLES-03531.cht (Europe)** | | Iron Soldier 3 (USA) | SLUS-01061 | Good | Advanced Controls not supported
Requires supplied cheat file
Not fully tested | - | **IronSoldier3_SLUS-01061.cht** |