1+ //===========================================================
2+ // Mouse Injector for Dolphin
3+ //==========================================================================
4+ // Copyright (C) 2019-2020 Carnivorous
5+ // All rights reserved.
6+ //
7+ // Mouse Injector is free software; you can redistribute it and/or modify it
8+ // under the terms of the GNU General Public License as published by the Free
9+ // Software Foundation; either version 2 of the License, or (at your option)
10+ // any later version.
11+ //
12+ // This program is distributed in the hope that it will be useful, but
13+ // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14+ // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15+ // for more details.
16+ //
17+ // You should have received a copy of the GNU General Public License
18+ // along with this program; if not, visit http://www.gnu.org/licenses/gpl-2.0.html
19+ //==========================================================================
20+ #include <stdint.h>
21+ #include "../main.h"
22+ #include "../memory.h"
23+ #include "../mouse.h"
24+ #include "game.h"
25+
26+ #define HYB_CAMY 0x156E7C
27+ #define HYB_CAMY2 0x9E7B8
28+ #define HYB_CAMX 0xEE2EE
29+
30+ #define HYB_IS_NOT_PAUSED 0x9E770
31+
32+ static uint8_t PS1_HYB_Status (void );
33+ static void PS1_HYB_Inject (void );
34+
35+ static const GAMEDRIVER GAMEDRIVER_INTERFACE =
36+ {
37+ "Hybrid" ,
38+ PS1_HYB_Status ,
39+ PS1_HYB_Inject ,
40+ 1 , // 1000 Hz tickrate
41+ 0 // crosshair sway supported for driver
42+ };
43+
44+ const GAMEDRIVER * GAME_PS1_HYBRID_JAPAN = & GAMEDRIVER_INTERFACE ;
45+
46+ static float xAccumulator = 0.f ;
47+ static float yAccumulator = 0.f ;
48+
49+ //==========================================================================
50+ // Purpose: return 1 if game is detected
51+ //==========================================================================
52+ static uint8_t PS1_HYB_Status (void )
53+ {
54+ // SLPS_011.02
55+ return (PS1_MEM_ReadWord (0x93C4 ) == 0x534C5053U &&
56+ PS1_MEM_ReadWord (0x93C8 ) == 0x5F303131U &&
57+ PS1_MEM_ReadWord (0x93CC ) == 0x2E30323BU );
58+ }
59+ //==========================================================================
60+ // Purpose: calculate mouse look and inject into current game
61+ //==========================================================================
62+ static void PS1_HYB_Inject (void )
63+ {
64+ // TODO: 25/50 FPS cheat
65+
66+ if (xmouse == 0 && ymouse == 0 ) // if mouse is idle
67+ return ;
68+
69+ if (!PS1_MEM_ReadByte (HYB_IS_NOT_PAUSED ))
70+ return ;
71+
72+ uint16_t camX = PS1_MEM_ReadHalfword (HYB_CAMX );
73+ int16_t camY = PS1_MEM_ReadInt16 (HYB_CAMY );
74+ float camXF = (float )camX ;
75+ float camYF = (float )camY ;
76+
77+ const float looksensitivity = (float )sensitivity / 20.f ;
78+
79+ float dx = (float )xmouse * looksensitivity ;
80+ AccumulateAddRemainder (& camXF , & xAccumulator , xmouse , dx );
81+ while (camXF > 4096.f )
82+ camXF -= 4096.f ;
83+ while (camXF < 0.f )
84+ camXF += 4096.f ;
85+
86+ float ym = (float )(invertpitch ? - ymouse : ymouse );
87+ float dy = ym * looksensitivity ;
88+ AccumulateAddRemainder (& camYF , & yAccumulator , ym , dy );
89+ camYF = ClampFloat (camYF , -340.f , 340.f );
90+
91+ PS1_MEM_WriteHalfword (HYB_CAMX , (uint16_t )camXF );
92+ PS1_MEM_WriteInt16 (HYB_CAMY , (int16_t )camYF );
93+ // PS1_MEM_WriteInt16(HYB_CAMY2, (int16_t)camYF);
94+ }
0 commit comments