@@ -68,6 +68,8 @@ struct RareGameBuildAddrs {
68
68
uint32_t player_offset_gun_y;
69
69
uint32_t player_offset_aim_mode;
70
70
uint32_t player_offset_aim_multiplier;
71
+ uint32_t player_offset_gun_left_x;
72
+ uint32_t player_offset_gun_left_y;
71
73
};
72
74
73
75
std::map<GoldeneyeGame::GameBuild, RareGameBuildAddrs> supported_builds = {
@@ -91,24 +93,27 @@ std::map<GoldeneyeGame::GameBuild, RareGameBuildAddrs> supported_builds = {
91
93
// unfortunately gets triggered when health bar appears...
92
94
{GoldeneyeGame::GameBuild::PerfectDark_Devkit_33,
93
95
{0x825CBC59 , 0x30303333 , 0 , 0 , 0x82620E08 , 0 , 0x826284C4 , 0x1A4C , 0x0 ,
94
- 0x14C , 0x15C , 0x1690 , 0x1694 , 0xCFC , 0xD00 , 0x128 , 0 }},
96
+ 0x14C , 0x15C , 0x1690 , 0x1694 , 0xCFC , 0xD00 , 0x128 , 0x179C , 0x14A0 ,
97
+ 0x14A4 }},
95
98
{GoldeneyeGame::GameBuild::PerfectDark_Release_52,
96
99
{0x825EC0E5 , 0x30303532 , 0 , 0 , 0x826419C0 , 0 , 0x8264909C , 0x1A4C , 0x0 ,
97
- 0x14C , 0x15C , 0x1690 , 0x1694 , 0xCFC , 0xD00 , 0x128 , 0 }},
100
+ 0x14C , 0x15C , 0x1690 , 0x1694 , 0xCFC , 0xD00 , 0x128 , 0x179C , 0x14A0 ,
101
+ 0x14A4 }},
98
102
{GoldeneyeGame::GameBuild::PerfectDark_Devkit_102,
99
103
{0x825EC0E5 , 0x30313032 , 0 , 0 , 0x82641A80 , 0 , 0x82649274 , 0x1A4C , 0x0 ,
100
- 0x14C , 0x15C , 0x1690 , 0x1694 , 0xCFC , 0xD00 , 0x128 , 0 }},
104
+ 0x14C , 0x15C , 0x1690 , 0x1694 , 0xCFC , 0xD00 , 0x128 , 0x179C , 0x14A0 ,
105
+ 0x14A4 }},
101
106
// TODO: test these!
102
107
/*
103
108
{
104
109
GoldeneyeGame::GameBuild::PerfectDark_Release_104,
105
110
{0x825EC0D5, 0x30313034, 0, 0, 0x82641A80, 0, 0x82649264, 0x1A4C, 0x0,
106
- 0x14C, 0x15C, 0x1690, 0x1694, 0xCFC, 0xD00, 0x128, 0}
111
+ 0x14C, 0x15C, 0x1690, 0x1694, 0xCFC, 0xD00, 0x128, 0, 0x14A0, 0x14A4 }
107
112
},
108
113
{
109
114
GoldeneyeGame::GameBuild::PerfectDark_Release_107,
110
115
{0x825FC25D, 0x30313037, 0, 0, 0x8265A200, 0, 0x826619E4, 0x1A4C, 0x0,
111
- 0x14C, 0x15C, 0x1690, 0x1694, 0xCFC, 0xD00, 0x128, 0}
116
+ 0x14C, 0x15C, 0x1690, 0x1694, 0xCFC, 0xD00, 0x128, 0, 0x14A0, 0x14A4 }
112
117
},*/
113
118
};
114
119
@@ -139,7 +144,7 @@ bool GoldeneyeGame::DoHooks(uint32_t user_index, RawInputState& input_state,
139
144
if (!IsGameSupported ()) {
140
145
return false ;
141
146
}
142
-
147
+ auto title_id = kernel_state ()-> title_id ();
143
148
auto & game_addrs = supported_builds[game_build_];
144
149
145
150
// Move menu selection crosshair
@@ -290,6 +295,17 @@ bool GoldeneyeGame::DoHooks(uint32_t user_index, RawInputState& input_state,
290
295
xe::be<float >* player_gun_y =
291
296
(xe::be<float >*)(player + game_addrs.player_offset_gun_y );
292
297
298
+ // PD Duel Wield
299
+
300
+ static xe::be<float >* player_gun_left_x;
301
+ static xe::be<float >* player_gun_left_y;
302
+ if (title_id == kTitleIdPerfectDark ) {
303
+ player_gun_left_x =
304
+ (xe::be<float >*)(player + game_addrs.player_offset_gun_left_x );
305
+ player_gun_left_y =
306
+ (xe::be<float >*)(player + game_addrs.player_offset_gun_left_y );
307
+ }
308
+
293
309
uint32_t player_aim_mode =
294
310
*(xe::be<uint32_t >*)(player + game_addrs.player_offset_aim_mode );
295
311
@@ -298,6 +314,10 @@ bool GoldeneyeGame::DoHooks(uint32_t user_index, RawInputState& input_state,
298
314
// Entering aim mode, reset gun position
299
315
*player_gun_x = 0 ;
300
316
*player_gun_y = 0 ;
317
+ if (title_id == kTitleIdPerfectDark ) {
318
+ *player_gun_left_x = 0 ;
319
+ *player_gun_left_y = 0 ;
320
+ }
301
321
}
302
322
// Always reset crosshair after entering/exiting aim mode
303
323
// Otherwise non-aim-mode will still fire toward it...
@@ -360,6 +380,10 @@ bool GoldeneyeGame::DoHooks(uint32_t user_index, RawInputState& input_state,
360
380
*player_crosshair_y = chY;
361
381
*player_gun_x = (chX * gun_multiplier);
362
382
*player_gun_y = (chY * gun_multiplier);
383
+ if (title_id == kTitleIdPerfectDark ) {
384
+ *player_gun_left_x = (chX * gun_multiplier);
385
+ *player_gun_left_y = (chY * gun_multiplier);
386
+ }
363
387
364
388
// Turn camera when crosshair is past a certain point
365
389
float camX = (float )*player_cam_x;
@@ -490,6 +514,11 @@ bool GoldeneyeGame::DoHooks(uint32_t user_index, RawInputState& input_state,
490
514
*player_crosshair_y = (gY * crosshair_multiplier);
491
515
*player_gun_x = gX ;
492
516
*player_gun_y = gY ;
517
+
518
+ if (title_id == kTitleIdPerfectDark ) {
519
+ *player_gun_left_x = gX ;
520
+ *player_gun_left_y = gY ;
521
+ }
493
522
}
494
523
495
524
return true ;
@@ -528,16 +557,20 @@ bool GoldeneyeGame::ModifierKeyHandler(uint32_t user_index,
528
557
float thumb_lx = (int16_t )out_state->gamepad .thumb_lx ;
529
558
float thumb_ly = (int16_t )out_state->gamepad .thumb_ly ;
530
559
531
- // Work out angle from the current stick values
532
- float angle = atan2f (thumb_ly, thumb_lx);
560
+ if (thumb_lx != 0 ||
561
+ thumb_ly !=
562
+ 0 ) { // Required otherwise stick is pushed to the right by default.
533
563
534
- // Sticks get set to SHRT_MAX if key pressed, use half of that
535
- float distance = (float )SHRT_MAX;
536
- distance /= 2 ;
564
+ // Work out angle from the current stick values
565
+ float angle = atan2f (thumb_ly, thumb_lx);
537
566
538
- out_state->gamepad .thumb_lx = (int16_t )(distance * cosf (angle));
539
- out_state->gamepad .thumb_ly = (int16_t )(distance * sinf (angle));
567
+ // Sticks get set to SHRT_MAX if key pressed, use half of that
568
+ float distance = (float )SHRT_MAX;
569
+ distance /= 2 ;
540
570
571
+ out_state->gamepad .thumb_lx = (int16_t )(distance * cosf (angle));
572
+ out_state->gamepad .thumb_ly = (int16_t )(distance * sinf (angle));
573
+ }
541
574
// Return true to signal that we've handled the modifier, so default modifier
542
575
// won't be used
543
576
return true ;
0 commit comments