forked from Ports/goldeneye-pc-port
M-24: playtest QoL — F12 screenshot + mouse frees on focus loss
port/src/video.c: F12 sets a request flag consumed in videoEndFrame (render thread, GL context current) -> ppm/shot_NNN.ppm via the existing gfx_opengl_dump_bound_fbo. SDL_WINDOWEVENT_FOCUS_LOST/GAINED now call inputSetMouseGrab(0/1) so alt-tabbing away releases the trapped cursor. port/src/input.c: add inputSetMouseGrab() — toggles SDL relative-mouse mode (respecting MouseEnabled), zeroes the aim delta, and gates inputUpdate mouse reads on a mouseGrabbed flag. -level_09 3/3 runs crash-free to frame 900, unregressed (91.6%).
This commit is contained in:
1 parent
546d803870
commit
46fa579e54
5 files changed
+64
-6
No files matched your search
+8
-1
@@ -261,9 +261,16 @@ Pre-playtest QoL, port-layer only, no `src/` / game-logic change.
|
||||
- Verified: `-level_09` boots crash-free to 900+ frames @ 91.65% coverage
|
||||
(unregressed); `-level_20` crash-free; `ge007.ini` written then re-read
|
||||
with no unknown-key warnings. Build green (`ntsc-final`).
|
||||
- **`port/src/video.c` QoL:** **F12** takes a screenshot
|
||||
(`ppm/shot_NNN.ppm`, dumped on the render thread via the existing
|
||||
`gfx_opengl_dump_bound_fbo`); window **focus loss frees the mouse**
|
||||
(`inputSetMouseGrab(0)` on `SDL_WINDOWEVENT_FOCUS_LOST`, re-grab on
|
||||
gain) so alt-tab works. `inputSetMouseGrab()` also zeroes the aim delta
|
||||
and suspends mouse reads while released.
|
||||
- Alt-Enter fullscreen toggle already existed (`gfx_sdl2.cpp:299`).
|
||||
- **Still TODO (not started):** key rebinding, gamepad hotplug
|
||||
(`SDL_CONTROLLERDEVICEADDED/REMOVED`), mouse-wheel weapon cycle,
|
||||
screenshot/mouse-release hotkeys, on-screen FPS overlay.
|
||||
on-screen FPS overlay, window-title FPS.
|
||||
|
||||
## Next task (M-24 — Opus 5)
|
||||
|
||||
|
||||
@@ -12,10 +12,14 @@ export PATH="/c/msys64/mingw64/bin:$PATH" && ./build-pc.sh ntsc-final
|
||||
./build-pc/ge007.x86_64.exe -level_XX # bare — pools auto-injected (D121)
|
||||
```
|
||||
|
||||
Controls: `port/src/input.c` — keyboard+mouse or SDL gamepad. Known input
|
||||
polish gaps (do not re-log): D118a mouse yaw slower than pitch, D118b
|
||||
mouse-Y may feel inverted. Difficulty for a bare `-level_XX` boot defaults
|
||||
to Agent; use the menu path (mission select → difficulty) to test 00/007.
|
||||
Controls: `port/src/input.c` — keyboard+mouse or SDL gamepad. Mouse-look is
|
||||
mode-aware since M-24 (hold RMB = analog aim). Tune feel in
|
||||
`data/ge007.ini` `[Input]` (`MouseAimSpeed` 50, `MouseTurnSpeed` 100,
|
||||
`MouseInvertY` 0) with the game closed. Known residual (do not re-log):
|
||||
D118a — hipfire pitch is digital vs analog yaw. **F12** = screenshot to
|
||||
`ppm/shot_NNN.ppm`. Alt-tab away frees the cursor (re-grabs on focus).
|
||||
Difficulty for a bare `-level_XX` boot defaults to Agent; use the menu path
|
||||
(mission select → difficulty) to test 00/007.
|
||||
|
||||
Objective status: `src/game/objective_status.c`
|
||||
(`get_status_of_objective()` `:161`); objective propDefs are
|
||||
|
||||
@@ -38,6 +38,12 @@ int inputConnectedMask(void);
|
||||
* mouse-aim accumulator maintained by inputUpdate(). */
|
||||
unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y);
|
||||
|
||||
/* Grab/release the mouse (relative-mouse mode). The host event pump calls
|
||||
* this on window focus loss/gain so alt-tabbing frees the cursor. A release
|
||||
* also suspends mouse-aim reads until re-grabbed. No-op if the mouse is
|
||||
* disabled in config. */
|
||||
void inputSetMouseGrab(int on);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
+17
-1
@@ -123,6 +123,7 @@ static int connectedMask = 0x1; /* controller 0 always present */
|
||||
static SDL_GameController *pads[MAX_PADS];
|
||||
|
||||
static int mouseEnabled = 1;
|
||||
static int mouseGrabbed = 1; /* released while the window is unfocused */
|
||||
static int mouseAimSpeed = 50; /* aim-mode sensitivity, percent */
|
||||
static int mouseTurnSpeed = 100; /* hipfire yaw sensitivity, percent */
|
||||
static int mouseInvertY = 0; /* 1 = mouse-down looks up */
|
||||
@@ -182,6 +183,7 @@ int inputInit(void)
|
||||
inputOpenPads();
|
||||
|
||||
/* Relative mouse mode for mouse-look. ESC still quits (video.c). */
|
||||
mouseGrabbed = mouseEnabled;
|
||||
if (mouseEnabled) {
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
/* Drain the initial jump. */
|
||||
@@ -212,7 +214,7 @@ void inputUpdate(void)
|
||||
{
|
||||
SDL_GameControllerUpdate();
|
||||
|
||||
if (!mouseEnabled) {
|
||||
if (!mouseEnabled || !mouseGrabbed) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -379,6 +381,20 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
|
||||
return button;
|
||||
}
|
||||
|
||||
void inputSetMouseGrab(int on)
|
||||
{
|
||||
int want = on && mouseEnabled;
|
||||
if (want == mouseGrabbed) {
|
||||
return;
|
||||
}
|
||||
mouseGrabbed = want;
|
||||
SDL_SetRelativeMouseMode(want ? SDL_TRUE : SDL_FALSE);
|
||||
if (want) {
|
||||
SDL_GetRelativeMouseState(NULL, NULL); /* drain the accumulated jump */
|
||||
}
|
||||
mouseDX = mouseDY = 0.0;
|
||||
}
|
||||
|
||||
int inputConnectedMask(void)
|
||||
{
|
||||
return connectedMask;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "platform.h"
|
||||
#include "system.h"
|
||||
#include "video.h"
|
||||
#include "input.h"
|
||||
|
||||
#include "../fast3d/gfx_api.h"
|
||||
#include "../fast3d/gfx_sdl.h"
|
||||
@@ -46,6 +47,9 @@ static struct GfxRenderingAPI *renderingAPI;
|
||||
static int initDone = 0;
|
||||
|
||||
static u32 frames = 0;
|
||||
/* Set by the host event pump (F12), consumed on the render thread in
|
||||
* videoEndFrame where a GL context is current. */
|
||||
static volatile int screenshotReq = 0;
|
||||
static double fpsWindowStart = 0.0;
|
||||
static int fpsNumFrames = 0;
|
||||
static float vidAvgFPS = 0.f;
|
||||
@@ -147,6 +151,8 @@ void videoPumpEvents(void)
|
||||
if (ev.key.keysym.sym == SDLK_ESCAPE) {
|
||||
sysLogPrintf(LOG_INFO, "video: ESC -> quit");
|
||||
exit(0);
|
||||
} else if (ev.key.keysym.sym == SDLK_F12 && !ev.key.repeat) {
|
||||
screenshotReq = 1;
|
||||
}
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
@@ -155,6 +161,10 @@ void videoPumpEvents(void)
|
||||
exit(0);
|
||||
} else if (ev.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||
gfx_sdl_update_cached_size();
|
||||
} else if (ev.window.event == SDL_WINDOWEVENT_FOCUS_LOST) {
|
||||
inputSetMouseGrab(0); /* free the cursor when alt-tabbed away */
|
||||
} else if (ev.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
|
||||
inputSetMouseGrab(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -201,6 +211,21 @@ void videoEndFrame(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (screenshotReq) {
|
||||
screenshotReq = 0;
|
||||
static int shotNum = 0;
|
||||
char path[128];
|
||||
GE_MKDIR("ppm");
|
||||
snprintf(path, sizeof(path), "ppm/shot_%03d.ppm", shotNum++);
|
||||
if (gfx_opengl_dump_bound_fbo((uint32_t)gfx_current_dimensions.width,
|
||||
(uint32_t)gfx_current_dimensions.height, path)) {
|
||||
sysLogPrintf(LOG_INFO, "video: screenshot -> %s "
|
||||
"(view with tools_pc/ppm2bmp.py)", path);
|
||||
} else {
|
||||
sysLogPrintf(LOG_WARNING, "video: screenshot failed");
|
||||
}
|
||||
}
|
||||
|
||||
++frames;
|
||||
++fpsNumFrames;
|
||||
|
||||
|
||||
Reference in new issue
Block a user