1
+ /* *
2
+ ******************************************************************************
3
+ * Xenia : Xbox 360 Emulator Research Project *
4
+ ******************************************************************************
5
+ * Copyright 2023 Ben Vanik. All rights reserved. *
6
+ * Released under the BSD license - see LICENSE in the root for more details. *
7
+ ******************************************************************************
8
+ */
9
+
10
+ #define _USE_MATH_DEFINES
11
+
12
+ #include " xenia/hid/winkey/hookables/JustCause.h"
13
+
14
+ #include " xenia/base/platform_win.h"
15
+ #include " xenia/cpu/processor.h"
16
+ #include " xenia/emulator.h"
17
+ #include " xenia/hid/hid_flags.h"
18
+ #include " xenia/hid/input_system.h"
19
+ #include " xenia/kernel/util/shim_utils.h"
20
+ #include " xenia/kernel/xmodule.h"
21
+ #include " xenia/kernel/xthread.h"
22
+ #include " xenia/xbox.h"
23
+
24
+ using namespace xe ::kernel;
25
+
26
+ DECLARE_double (sensitivity);
27
+ DECLARE_bool (invert_y);
28
+ DECLARE_bool (invert_x);
29
+
30
+ const uint32_t kTitleIdJustCause = 0x534307D5 ;
31
+
32
+ namespace xe {
33
+ namespace hid {
34
+ namespace winkey {
35
+ struct GameBuildAddrs {
36
+ const char * title_version;
37
+ uint32_t cameracontroller_pointer_address;
38
+ uint32_t SteerAddYaw_offset;
39
+ uint32_t SteerAddPitch_offset;
40
+ };
41
+
42
+ std::map<JustCauseGame::GameBuild, GameBuildAddrs> supported_builds{
43
+ {JustCauseGame::GameBuild::JustCause1_TU0,
44
+ {" 1.0" , 0x46965100 , 0x130 , 0x12C }}};
45
+
46
+ JustCauseGame::~JustCauseGame () = default ;
47
+
48
+ bool JustCauseGame::IsGameSupported () {
49
+ if (kernel_state ()->title_id () != kTitleIdJustCause ) {
50
+ return false ;
51
+ }
52
+
53
+ const std::string current_version =
54
+ kernel_state ()->emulator ()->title_version ();
55
+
56
+ for (auto & build : supported_builds) {
57
+ if (current_version == build.second .title_version ) {
58
+ game_build_ = build.first ;
59
+ return true ;
60
+ }
61
+ }
62
+
63
+ return false ;
64
+ }
65
+
66
+ /* float JustCauseGame::DegreetoRadians(float degree) {
67
+ return (float)(degree * (M_PI / 180));
68
+ }
69
+
70
+ float JustCauseGame::RadianstoDegree(float radians) {
71
+ return (float)(radians * (180 / M_PI));
72
+ }
73
+ */
74
+
75
+ bool JustCauseGame::DoHooks (uint32_t user_index, RawInputState& input_state,
76
+ X_INPUT_STATE* out_state) {
77
+ if (!IsGameSupported ()) {
78
+ return false ;
79
+ }
80
+
81
+ if (supported_builds.count (game_build_) == 0 ) {
82
+ return false ;
83
+ }
84
+
85
+ XThread* current_thread = XThread::GetCurrentThread ();
86
+
87
+ if (!current_thread) {
88
+ return false ;
89
+ }
90
+
91
+ /*
92
+ TODO: Vehicle Camera which is CMachineCamera
93
+ and Possibly turrets which is CMountedGunCamera
94
+
95
+ Some addresses used are in radians,
96
+ Vehicle in-game camera is more closer to racing games cameras than a traditional
97
+ GTA-styled freecam.
98
+
99
+ */
100
+
101
+ xe::be<uint32_t >* base_address =
102
+ kernel_memory ()->TranslateVirtual <xe::be<uint32_t >*>(
103
+ supported_builds[game_build_].cameracontroller_pointer_address );
104
+
105
+ if (!base_address || *base_address == NULL ) {
106
+ // Not in game
107
+ return false ;
108
+ }
109
+
110
+ xe::be<uint32_t > x_address =
111
+ *base_address + supported_builds[game_build_].SteerAddYaw_offset ;
112
+ xe::be<uint32_t > y_address =
113
+ *base_address + supported_builds[game_build_].SteerAddPitch_offset ;
114
+
115
+ xe::be<float >* add_x =
116
+ kernel_memory ()->TranslateVirtual <xe::be<float >*>(x_address);
117
+
118
+ xe::be<float >* add_y =
119
+ kernel_memory ()->TranslateVirtual <xe::be<float >*>(y_address);
120
+
121
+ float camx = *add_x;
122
+ float camy = *add_y;
123
+ // X-axis = 0 to 360
124
+ if (!cvars::invert_x) {
125
+ camx += (input_state.mouse .x_delta / 5 .f ) * (float )cvars::sensitivity;
126
+
127
+ } else {
128
+ camx -= (input_state.mouse .x_delta / 5 .f ) * (float )cvars::sensitivity;
129
+ }
130
+ *add_x = camx;
131
+ // Y-axis = -90 to 90
132
+ if (!cvars::invert_y) {
133
+ camy += (input_state.mouse .y_delta / 5 .f ) * (float )cvars::sensitivity;
134
+ } else {
135
+ camy -= (input_state.mouse .y_delta / 5 .f ) * (float )cvars::sensitivity;
136
+ }
137
+ *add_y = camy;
138
+
139
+ return true ;
140
+ }
141
+
142
+ std::string JustCauseGame::ChooseBinds () { return " Default" ; }
143
+
144
+ bool JustCauseGame::ModifierKeyHandler (uint32_t user_index,
145
+ RawInputState& input_state,
146
+ X_INPUT_STATE* out_state) {
147
+ return false ;
148
+ }
149
+ } // namespace winkey
150
+ } // namespace hid
151
+ } // namespace xe
0 commit comments