diff --git a/runtime/hle/bindings.c b/runtime/hle/bindings.c index 537d3eef..1fe28b41 100644 --- a/runtime/hle/bindings.c +++ b/runtime/hle/bindings.c @@ -235,10 +235,11 @@ bool bind_capture_event(const SDL_Event *e) { case SDL_EVENT_KEY_DOWN: if (e->key.repeat) return true; if (e->key.scancode == SDL_SCANCODE_ESCAPE) { bind_capture_cancel(); return true; } - // F1 (menu), F9 (frame dump), F11 (fullscreen), F12 and the key left of 1 (the console) stay the overlay's; a - // controller capture ignores keys + // F1 (menu), F9 (frame dump), F11 (fullscreen), F12 and the key left of 1 (the console), and PrintScreen + // (screenshot) stay the overlay's; a controller capture ignores keys if (!kd || e->key.scancode == SDL_SCANCODE_F1 || e->key.scancode == SDL_SCANCODE_F9 || e->key.scancode == SDL_SCANCODE_F11 || e->key.scancode == SDL_SCANCODE_F12 || + e->key.scancode == SDL_SCANCODE_PRINTSCREEN || e->key.scancode == SDL_SCANCODE_GRAVE || e->key.scancode >= SDL_SCANCODE_COUNT) return true; cap_dev = -1; assign(BIND_DEV_KEY, cap_slot, e->key.scancode); diff --git a/runtime/hle/input.c b/runtime/hle/input.c index 321088ac..04ef4a69 100644 --- a/runtime/hle/input.c +++ b/runtime/hle/input.c @@ -629,6 +629,10 @@ void input_handle_event(const SDL_Event *e) { break; } } + if (e->type == SDL_EVENT_KEY_DOWN && e->key.scancode == SDL_SCANCODE_PRINTSCREEN && !e->key.repeat) { + extern void photo_take(void); + photo_take(); + } if (e->type == SDL_EVENT_KEY_DOWN && e->key.scancode == SDL_SCANCODE_F9 && !e->key.repeat) g_debug_frame_request = 1; if (e->type == SDL_EVENT_KEY_DOWN && e->key.scancode == SDL_SCANCODE_F6 && !e->key.repeat && profiler_key_available()) prof_toggle(); // start, stop, or acknowledge a full buffer (runtime/prof.h; report: tools/swprof.py) diff --git a/runtime/hle/photo.c b/runtime/hle/photo.c index 0b242464..331538d1 100644 --- a/runtime/hle/photo.c +++ b/runtime/hle/photo.c @@ -84,6 +84,11 @@ void photo_reset(bool on) { if (!on) hour_reset = 1; } +// Request a screenshot to be saved by the presenter on the next frame +void photo_take(void) { + shot(); +} + // (hle/input.c) keys while the free camera is on; true: taken bool photo_key(int scancode) { switch (scancode) { diff --git a/tests/test_pc_controls.c b/tests/test_pc_controls.c index bc2f15b3..ffc2d367 100644 --- a/tests/test_pc_controls.c +++ b/tests/test_pc_controls.c @@ -41,6 +41,8 @@ void control_fly_wheel(float notches) { (void)notches;abort(); } bool freecam_active(void) { return false; } void freecam_toggle(void) { abort(); } void freecam_key(int scancode, bool down) { (void)scancode; (void)down; abort(); } +static int photo_takes = 0; +void photo_take(void) { photo_takes++; } void photo_pad(uint32_t buttons) { (void)buttons; } void freecam_mouse(float dx, float dy) { (void)dx; (void)dy; abort(); } void freecam_pad(float lx, float ly, float rx, float ry, float up, float down, bool fast, bool slow) { @@ -212,4 +214,17 @@ int main(void) { now+=16000000;input_pc_rotate_motion(-40,0);mouse_stick(&sx,&sy);assert(sx<0); rotate_drag=false;now+=16000000;mouse_stick(&sx,&sy);assert(sx==0&&sy==0); puts("PASS: pointer menus keep middle click bound; Rotate-mode drag turns Link through the right stick"); + + // PrintScreen captures a screenshot and does not get swallowed by normal button actions + int shots_before = photo_takes; + e.type = SDL_EVENT_KEY_DOWN; e.key.scancode = SDL_SCANCODE_PRINTSCREEN; e.key.repeat = false; + input_handle_event(&e); + assert(photo_takes == shots_before + 1); + e.key.repeat = true; + input_handle_event(&e); + assert(photo_takes == shots_before + 1); // key repeat ignored + e.type = SDL_EVENT_KEY_UP; + input_handle_event(&e); + assert(photo_takes == shots_before + 1); + puts("PASS: PrintScreen triggers screenshot capture"); }