Skip to content

Commit 76fb842

Browse files
committed
Merge remote-tracking branch 'neon-fgs/coup' into port-friends-of-joanna
2 parents 24fb9f3 + 6c34d57 commit 76fb842

31 files changed

Lines changed: 356 additions & 130 deletions

.github/workflows/c-cpp.yml

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ name: C/C++ CI
22

33
on:
44
push:
5-
branches: [ "port", "port-friends-of-joanna" ]
5+
branches: [ ]
66
pull_request:
7-
branches: [ "port" ]
7+
branches: [ ]
88
workflow_dispatch:
99

1010
jobs:
@@ -284,24 +284,16 @@ jobs:
284284
cache-key: flatpak-builder-${{ github.sha }}
285285
upload-artifact: false
286286

287-
# - name: Build Flatpak bundle
288-
# run: |
289-
# cd dist/linux/
290-
# flatpak-builder build --force-clean io.github.fgsfdsfgs.perfect_dark.yaml
291-
# flatpak build-export export build
292-
# flatpak build-bundle export io.github.fgsfdsfgs.perfect_dark.flatpak io.github.fgsfdsfgs.perfect_dark
293-
294287
- name: Upload artifact
295288
uses: actions/upload-artifact@v4
296289
with:
297290
name: io.github.fgsfdsfgs.perfect_dark.flatpak
298291
path: io.github.fgsfdsfgs.perfect_dark.flatpak
299292
retention-days: 0
300293

301-
302294
publish-latest-build:
303295
runs-on: ubuntu-latest
304-
if: github.ref == 'refs/heads/port'
296+
if: github.ref == 'refs/heads/coup' || startsWith(github.ref, 'refs/heads/mod/') || startsWith(github.ref, 'refs/heads/builds/')
305297
needs: [build-i686-windows, build-i686-linux, build-x86_64-windows, build-x86_64-linux, build-arm64-nswitch, build-x86_64-osx, build-arm64-osx, build-flatpak-bundle]
306298
permissions:
307299
contents: write
@@ -323,7 +315,6 @@ jobs:
323315
zip -r ../ci-release/pd-i686-windows.zip pd-i686-windows
324316
zip -r ../ci-release/pd-x86_64-windows.zip pd-x86_64-windows
325317
zip -r ../ci-release/pd-arm64-nswitch.zip pd-arm64-nswitch
326-
mv io.github.fgsfdsfgs.perfect_dark.flatpak/io.github.fgsfdsfgs.perfect_dark.flatpak ../ci-release/
327318
popd
328319
git tag --force ci-dev-build port
329320
git push --force origin ci-dev-build

README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,41 @@ Counter-op is highly experimental and mostly untested.
88

99
[Setup instructions below.](https://github.com/cylonicboom/perfect-dark-neon/tree/port-friends-of-joanna?tab=readme-ov-file#building--setup-friends-of-joanna)
1010

11+
# Catherine's Opinionated Unofficial Patches
12+
13+
## `port` + Catherine's mods
14+
15+
This is a collection of all my port mods merged together:
16+
17+
![Screenshot 2025-03-16 at 03 35 29](https://github.com/user-attachments/assets/f479809d-e91f-4869-8c8b-c478ad5af590)
18+
19+
20+
# Mod: Moon Jump
21+
22+
Reimplements the classic Moon Jump Gameshark code, with some differences: changing the player's elevation is not required to jump, and I added a seperate button for toggling gravity.
23+
24+
![image](https://github.com/user-attachments/assets/09d3ef02-be38-4d54-921c-79cb9f6cf0f4)
25+
26+
[Perfect Dark PC Port - Moon Jump [nRP5k1Zn1mc].webm](https://github.com/user-attachments/assets/52401da4-d36b-4e70-a66b-eff8815e889e)
27+
28+
# Mod: Toggle Gangsta
29+
30+
Adds a bindable button for toggling gangsta mode.
31+
32+
![Screenshot 2025-02-21 at 19 23 56](https://github.com/user-attachments/assets/8de027b9-f40b-40da-913a-d15c9c41dcf5)
33+
![Screenshot 2025-02-21 at 19 24 38](https://github.com/user-attachments/assets/dc6b5a8f-5601-41d0-a273-f8f65c043c78)
34+
35+
# Mod: Perfect Dark without Pausing
36+
37+
[![](http://img.youtube.com/vi/MHwGS0cP-3g/0.jpg)](https://www.youtube.com/watch?v=MHwGS0cP-3g)
38+
39+
40+
The pausing-blur effect can now be disabled via an in-game option. Leave it off for an extra challenge.
41+
42+
To toggle: `Options -> Extended -> Video -> Enable Local Pausing`
43+
44+
This branch closely follows `fgsfdsfgs/perfect_dark`@`port`
45+
1146
# Perfect Dark port
1247

1348
# Perfect Dark port (`port-net`)

include/PR/os_cont.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
/*---------------------------------------------------------------------*
2323
Copyright (C) 1998 Nintendo. (Originated by SGI)
24-
24+
2525
$RCSfile: os_cont.h,v $
2626
$Revision: 1.1 $
2727
$Date: 1998/10/09 08:01:05 $
@@ -47,7 +47,7 @@ extern "C" {
4747
*/
4848

4949
/*
50-
* Structure for controllers
50+
* Structure for controllers
5151
*/
5252

5353
typedef struct {
@@ -100,7 +100,7 @@ typedef struct {
100100
#ifdef _HW_VERSION_1
101101
#define CONT_FRAME_ERROR 0x2
102102
#define CONT_COLLISION_ERROR 0x1
103-
#endif
103+
#endif
104104

105105
/* Controller type */
106106

port/src/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ PD_CONSTRUCTOR static void gameConfigInit(void)
182182
configRegisterInt("Game.CenterHUD", &g_HudCenter, 0, 2);
183183
configRegisterInt("Game.MenuMouseControl", &g_MenuMouseControl, 0, 1);
184184
configRegisterFloat("Game.ScreenShakeIntensity", &g_ViShakeIntensityMult, 0.f, 10.f);
185+
configRegisterInt("Game.PausingEnabled", &g_PausingEnabled, 0, 1);
185186
configRegisterInt("Game.TickRateDivisor", &g_TickRateDiv, 0, 10);
186187
configRegisterInt("Game.ExtraSleep", &g_TickExtraSleep, 0, 1);
187188
configRegisterInt("Game.SkipIntro", &g_SkipIntro, 0, 1);

port/src/optionsmenu.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,20 @@ static MenuItemHandlerResult menuhandlerCenterHUD(s32 operation, struct menuitem
980980
return 0;
981981
}
982982

983+
static MenuItemHandlerResult menuhandlerSetPausingEnabled(s32 operation, struct menuitem *item, union handlerdata *data)
984+
{
985+
switch (operation) {
986+
case MENUOP_GET:
987+
return g_PausingEnabled;
988+
break;
989+
case MENUOP_SET:
990+
g_PausingEnabled = data->checkbox.value;
991+
break;
992+
}
993+
994+
return 0;
995+
}
996+
983997
static MenuItemHandlerResult menuhandlerScreenShake(s32 operation, struct menuitem *item, union handlerdata *data)
984998
{
985999
switch (operation) {
@@ -1139,6 +1153,14 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
11391153
20,
11401154
menuhandlerScreenShake,
11411155
},
1156+
{
1157+
MENUITEMTYPE_CHECKBOX,
1158+
0,
1159+
MENUITEMFLAG_LITERAL_TEXT,
1160+
(uintptr_t)"Enable Local Pausing",
1161+
20,
1162+
menuhandlerSetPausingEnabled,
1163+
},
11421164
{
11431165
MENUITEMTYPE_SEPARATOR,
11441166
0,
@@ -1646,7 +1668,10 @@ static const struct menubind menuBinds[] = {
16461668
{ CK_8000, "Cycle Crouch [+]\n", "N64 Ext 8000\n" },
16471669
{ CK_4000, "Half Crouch [+]\n", "N64 Ext 4000\n" },
16481670
{ CK_2000, "Full Crouch [+]\n", "N64 Ext 2000\n" },
1649-
{ CK_0040, "Toggle Eyelids [+]\n", "N64 Ext 0040\n" },
1671+
{ CK_0080, "Moon Jump [+]\n", "N64 Ext 0080\n" }, // TODO: gate this behind a cheat
1672+
{ CK_0100, "Toggle Gravity [+]\n","N64 Ext 0100\n" }, // TODO: gate this behind a cheat
1673+
{ CK_0040, "Toggle Eyelids [+]\n","N64 Ext 0040\n" },
1674+
{ CK_0200, "Toggle Gangsta [+]\n","N64 Ext 0200\n" },
16501675
{ CK_ACCEPT, "UI Accept [+]\n", "EXT UI Accept\n" },
16511676
{ CK_CANCEL, "UI Cancel [+]\n", "EXT UI Cancel\n" },
16521677
};
@@ -1688,6 +1713,10 @@ struct menuitem g_ExtendedBindsMenuItems[] = {
16881713
DEFINE_MENU_BIND(),
16891714
DEFINE_MENU_BIND(),
16901715
DEFINE_MENU_BIND(),
1716+
DEFINE_MENU_BIND(),
1717+
DEFINE_MENU_BIND(),
1718+
DEFINE_MENU_BIND(),
1719+
DEFINE_MENU_BIND(),
16911720
{
16921721
MENUITEMTYPE_SEPARATOR,
16931722
0,

src/game/bondbike.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ void bbikeApplyMoveData(struct movedata *data)
209209
|| contmode == CONTROLMODE_13
210210
|| contmode == CONTROLMODE_11
211211
|| contmode == CONTROLMODE_PC)
212-
&& !lvIsPaused()) {
212+
&& !g_Vars.currentplayer->pausemode) {
213213
u32 lmask, rmask;
214214
if (contmode == CONTROLMODE_PC) {
215215
lmask = L_CBUTTONS;
@@ -218,8 +218,10 @@ void bbikeApplyMoveData(struct movedata *data)
218218
lmask = L_JPAD | L_CBUTTONS;
219219
rmask = R_JPAD | R_CBUTTONS;
220220
}
221-
data->digitalstepleft = joyCountButtonsOnSpecificSamples(0, contnum, lmask);
222-
data->digitalstepright = joyCountButtonsOnSpecificSamples(0, contnum, rmask);
221+
if (g_Vars.currentplayer->pausemode == PAUSEMODE_UNPAUSED) {
222+
data->digitalstepleft = joyCountButtonsOnSpecificSamples(0, contnum, lmask);
223+
data->digitalstepright = joyCountButtonsOnSpecificSamples(0, contnum, rmask);
224+
}
223225
}
224226

225227
// Forward/back

src/game/bondeyespy.c

Lines changed: 53 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "game/player.h"
1010
#include "game/hudmsg.h"
1111
#include "game/inv.h"
12+
#include "game/lv.h"
1213
#include "game/mplayer/ingame.h"
1314
#include "game/playermgr.h"
1415
#include "game/stagetable.h"
@@ -702,7 +703,9 @@ void eyespyProcessInput(bool allowbuttons)
702703
s8 c1sticky = joyGetStickY(contpad1);
703704
s8 c2sticky;
704705
u32 c1buttons = allowbuttons ? joyGetButtons(contpad1, 0xffffffff) : 0;
706+
u32 c1buttonsthisframe = allowbuttons ? joyGetButtonsPressedThisFrame(contpad1, 0xffffffff): 0;
705707
u32 c2buttons;
708+
u32 c2buttonsthisframe;
706709
bool domovecentre = true;
707710
s32 controlmode = optionsGetControlMode(g_Vars.currentplayerstats->mpindex);
708711

@@ -722,6 +725,7 @@ void eyespyProcessInput(bool allowbuttons)
722725
f32 tmp;
723726
u32 umask, dmask, lmask, rmask;
724727

728+
bool pausepressed;
725729
if (controlmode == CONTROLMODE_PC) {
726730
umask = U_CBUTTONS;
727731
dmask = D_CBUTTONS;
@@ -740,6 +744,7 @@ void eyespyProcessInput(bool allowbuttons)
740744
c2sticky = joyGetStickY(contpad2);
741745

742746
c2buttons = allowbuttons ? joyGetButtons(contpad2, 0xffffffff) : 0;
747+
c2buttonsthisframe = allowbuttons ? joyGetButtonsPressedThisFrame(contpad2, 0xffffffff) : 0;
743748
} else {
744749
#ifndef PLATFORM_N64
745750
if (controlmode == CONTROLMODE_PC) {
@@ -753,25 +758,27 @@ void eyespyProcessInput(bool allowbuttons)
753758
}
754759
#endif
755760
c2buttons = c1buttons;
761+
c2buttonsthisframe = c1buttonsthisframe;
756762
}
757763

764+
pausepressed = c1buttonsthisframe & START_BUTTON;
758765
if (controlmode == CONTROLMODE_13 || controlmode == CONTROLMODE_14) {
759766
aimpressed = c1buttons & Z_TRIG;
760767
shootpressed = c1buttons & A_BUTTON;
761-
exitpressed = c1buttons & R_TRIG;
762-
activatepressed = c1buttons & B_BUTTON;
768+
exitpressed = c1buttonsthisframe & R_TRIG;
769+
activatepressed = c1buttonsthisframe & B_BUTTON;
763770
} else if (controlmode <= CONTROLMODE_14 || controlmode == CONTROLMODE_PC) {
764771
aimpressed = c1buttons & (R_TRIG);
765772
shootpressed = c1buttons & Z_TRIG;
766773
#ifndef PLATFORM_N64
767774
if (controlmode == CONTROLMODE_PC) {
768-
exitpressed = c1buttons & (BUTTON_WPNBACK | BUTTON_RADIAL);
769-
activatepressed = c1buttons & (BUTTON_CANCEL_USE | BUTTON_ACCEPT_USE);
775+
exitpressed = c1buttonsthisframe & (BUTTON_WPNBACK | BUTTON_RADIAL);
776+
activatepressed = c1buttonsthisframe & (BUTTON_CANCEL_USE | BUTTON_ACCEPT_USE);
770777
} else
771778
#endif
772779
{
773-
exitpressed = (c1buttons | c2buttons) & A_BUTTON;
774-
activatepressed = (c1buttons | c2buttons) & B_BUTTON;
780+
exitpressed = (c1buttonsthisframe | c2buttonsthisframe) & A_BUTTON;
781+
activatepressed = (c1buttonsthisframe | c2buttonsthisframe) & B_BUTTON;
775782
}
776783
} else {
777784
if (controlmode >= CONTROLMODE_23) {
@@ -782,8 +789,8 @@ void eyespyProcessInput(bool allowbuttons)
782789
shootpressed = c1buttons & Z_TRIG;
783790
}
784791

785-
exitpressed = (c1buttons | c2buttons) & A_BUTTON;
786-
activatepressed = (c1buttons | c2buttons) & B_BUTTON;
792+
exitpressed = (c1buttonsthisframe | c2buttonsthisframe) & A_BUTTON;
793+
activatepressed = (c1buttonsthisframe | c2buttonsthisframe) & B_BUTTON;
787794
}
788795

789796
// Apply safe zone for c1stickx
@@ -932,7 +939,7 @@ void eyespyProcessInput(bool allowbuttons)
932939
&& g_Vars.currentplayer->pausemode == PAUSEMODE_UNPAUSED
933940
&& (c1buttons & START_BUTTON)) {
934941
if (!g_Vars.mplayerisrunning) {
935-
playerPause(MENUROOT_MAINMENU);
942+
playerStartPause(MENUROOT_MAINMENU);
936943
} else {
937944
mpPushPauseDialog();
938945
}
@@ -1187,33 +1194,49 @@ void eyespyProcessInput(bool allowbuttons)
11871194
return;
11881195
}
11891196

1190-
// Handle trigger
1191-
if (g_Vars.currentplayer->eyespy->camerashuttertime <= 0 && shootpressed && g_Vars.currentplayer->eyespy->active) {
1192-
if (g_Vars.currentplayer->eyespy->camerabuttonheld == false) {
1193-
g_Vars.currentplayer->eyespy->camerabuttonheld = true;
1194-
g_Vars.currentplayer->eyespy->camerashuttertime = TICKS(24);
1197+
// handle pause menu
1198+
if (!g_Vars.currentplayer->pausemode) {
1199+
if (g_Vars.currentplayer->eyespy->active && !g_Vars.currentplayer->isdead) {
1200+
if (!( g_Vars.currentplayer->pausemode & (PAUSEMODE_PAUSED | PAUSEMODE_PAUSING) ) && (pausepressed)) {
1201+
if (g_Vars.mplayerisrunning == false) {
1202+
if (g_Vars.lvframenum > 15) {
1203+
playerStartPause(MENUROOT_MAINMENU);
1204+
}
1205+
} else {
1206+
mpPushPauseDialog();
1207+
}
1208+
}
1209+
1210+
}
1211+
// Handle trigger
1212+
if (g_Vars.currentplayer->eyespy->camerashuttertime <= 0 && shootpressed && g_Vars.currentplayer->eyespy->active) {
1213+
if (g_Vars.currentplayer->eyespy->camerabuttonheld == false) {
1214+
g_Vars.currentplayer->eyespy->camerabuttonheld = true;
1215+
g_Vars.currentplayer->eyespy->camerashuttertime = TICKS(24);
1216+
}
1217+
} else {
1218+
g_Vars.currentplayer->eyespy->camerabuttonheld = false;
11951219
}
1196-
} else {
1197-
g_Vars.currentplayer->eyespy->camerabuttonheld = false;
1198-
}
11991220

1200-
// Handle exit
1201-
if (exitpressed && g_Vars.currentplayer->eyespy->active) {
1202-
g_Vars.currentplayer->eyespy->active = false;
1203-
g_Vars.currentplayer->devicesactive &= ~DEVICE_EYESPY;
1204-
}
1221+
// Handle exit
1222+
if (exitpressed && g_Vars.currentplayer->eyespy->active) {
1223+
g_Vars.currentplayer->eyespy->active = false;
1224+
g_Vars.currentplayer->devicesactive &= ~DEVICE_EYESPY;
1225+
}
12051226

1206-
// Handle B button activation
1207-
if (activatepressed && g_Vars.currentplayer->eyespy->active) {
1208-
if (g_Vars.currentplayer->eyespy->buttonheld == false) {
1209-
g_Vars.currentplayer->eyespy->buttonheld = true;
1210-
g_Vars.currentplayer->eyespy->opendoor = true;
1227+
// Handle B button activation
1228+
// but only if not in a pause-like state
1229+
if (activatepressed && g_Vars.currentplayer->eyespy->active) {
1230+
if (g_Vars.currentplayer->eyespy->buttonheld == false) {
1231+
g_Vars.currentplayer->eyespy->buttonheld = true;
1232+
g_Vars.currentplayer->eyespy->opendoor = true;
1233+
} else {
1234+
g_Vars.currentplayer->eyespy->opendoor = false;
1235+
}
12111236
} else {
12121237
g_Vars.currentplayer->eyespy->opendoor = false;
1238+
g_Vars.currentplayer->eyespy->buttonheld = false;
12131239
}
1214-
} else {
1215-
g_Vars.currentplayer->eyespy->opendoor = false;
1216-
g_Vars.currentplayer->eyespy->buttonheld = false;
12171240
}
12181241

12191242
g_Vars.currentplayer->eyespy->hit = g_EyespyHit;

src/game/bondgun.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3645,6 +3645,13 @@ u8 *bgunGetGunMem(void)
36453645
return g_Vars.currentplayer->gunctrl.gunmem;
36463646
}
36473647

3648+
#ifndef PLATFORM_N64
3649+
u8 *bgunGetInvMem(void)
3650+
{
3651+
return g_Vars.currentplayer->gunctrl.invmem;
3652+
}
3653+
#endif
3654+
36483655
u32 bgunCalculateGunMemCapacity(void)
36493656
{
36503657
if (IS4MB() && PLAYERCOUNT() == 2) {
@@ -3662,7 +3669,8 @@ u32 bgunCalculateGunMemCapacity(void)
36623669
return g_BgunGunMemBaseSizeDefault + 25 * 1024;
36633670
}
36643671
#else
3665-
return g_BgunGunMemBaseSizeDefault + stageGetCurrent()->extragunmem;
3672+
// extra space to store invmen
3673+
return (g_BgunGunMemBaseSizeDefault * 2) + stageGetCurrent()->extragunmem;
36663674
#endif
36673675
}
36683676

src/game/bondgunreset.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ void bgunReset(void)
151151
}
152152

153153
g_Vars.currentplayer->gunctrl.gunmem = mempAlloc(i, MEMPOOL_STAGE);
154+
g_Vars.currentplayer->gunctrl.wantsgangsta = 0;
155+
g_Vars.currentplayer->gunctrl.invmem = mempAlloc(i, MEMPOOL_STAGE);
154156
g_Vars.currentplayer->gunctrl.handfilenum = 0;
155157
g_Vars.currentplayer->gunctrl.handmemloadptr = 0;
156158
g_Vars.currentplayer->gunctrl.handmemloadremaining = 0;

0 commit comments

Comments
 (0)