Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,100 changes: 551 additions & 549 deletions TCP_COMMANDS.md

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions recompiler/src/config_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,15 @@ static RuntimeConfig parse_runtime_block(const toml::value& cfg, const fs::path&
"[video] crt_filter must be \"raw\"|\"crt\"|\"composite\"|\"trinitron\": {}",
mode));
}
if (video.contains("scanlines")) {
rt.video_scanlines = toml::find<bool>(video, "scanlines");
}
if (video.contains("scanline_strength")) {
double s = toml::find<double>(video, "scanline_strength");
if (s < 0.0) s = 0.0;
if (s > 1.0) s = 1.0;
rt.video_scanline_strength = s;
}
if (video.contains("auto_skip_fmv")) {
rt.video_auto_skip_fmv = toml::find<bool>(video, "auto_skip_fmv");
}
Expand Down Expand Up @@ -2296,6 +2305,15 @@ UserSettings load_user_settings(const fs::path& path) {
else if (m == "composite") { s.screen_kind = 2; s.has_screen_kind = true; }
else if (m == "trinitron") { s.screen_kind = 3; s.has_screen_kind = true; }
});
if (v.contains("scanlines")) try_get([&]{
s.scanlines = toml::find<bool>(v, "scanlines"); s.has_scanlines = true;
});
if (v.contains("scanline_strength")) try_get([&]{
double d = toml::find<double>(v, "scanline_strength");
if (d < 0.0) d = 0.0;
if (d > 1.0) d = 1.0;
s.scanline_strength = d; s.has_scanline_strength = true;
});
if (v.contains("auto_skip_fmv")) try_get([&]{
s.auto_skip_fmv = toml::find<bool>(v, "auto_skip_fmv"); s.has_auto_skip_fmv = true;
});
Expand Down Expand Up @@ -2615,6 +2633,10 @@ bool save_user_settings(const fs::path& path, const UserSettings& s) {
: s.screen_kind == 3 ? "trinitron" : "raw";
f << "crt_filter = \"" << k << "\"\n";
}
if (s.has_scanlines)
f << "scanlines = " << (s.scanlines ? "true" : "false") << "\n";
if (s.has_scanline_strength)
f << "scanline_strength = " << s.scanline_strength << "\n";
if (s.has_auto_skip_fmv)
f << "auto_skip_fmv = " << (s.auto_skip_fmv ? "true" : "false") << "\n";
/* turbo_loads is deliberately NOT written back: it is deprecated and no
Expand Down
11 changes: 11 additions & 0 deletions recompiler/src/config_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,13 @@ struct RuntimeConfig {
// PSX_SCREEN env var overrides this at runtime (debug path).
int video_screen_kind = 0;

// scanlines: present-time horizontal scanline darkening (host enhancement,
// orthogonal to crt_filter's colour LUT — the two compose). Off by default;
// scanline_strength 0..1 is the dark-gap depth. PSX_SCANLINES /
// PSX_SCANLINE_STRENGTH override at runtime (debug path).
bool video_scanlines = false;
double video_scanline_strength = 0.5;

// auto_skip_fmv: when true, full-motion videos (streaming XA audio + MDEC
// video) are skipped the instant they're detected — presentation + pacing are
// suppressed and audio muted for the duration, so an FMV ends in a fraction of
Expand Down Expand Up @@ -1196,6 +1203,10 @@ struct UserSettings {
bool has_geometry_correction = false; bool geometry_correction = false;
bool has_perspective_texturing = false; bool perspective_texturing = false;
bool has_screen_kind = false; int screen_kind = 0; // 0..3 (ScreenKind)
// Scanline post-process (see RuntimeConfig::video_scanlines). Strength stored
// 0..1; the launcher ABI carries it as an integer percent.
bool has_scanlines = false; bool scanlines = false;
bool has_scanline_strength = false; double scanline_strength = 0.5;
bool has_auto_skip_fmv = false; bool auto_skip_fmv = false; // skip FMVs
// [video] turbo_loads: DEPRECATED AND IGNORED — the legacy home of the
// generic Turbo loads switch, back when the launcher drew a row for it.
Expand Down
8 changes: 8 additions & 0 deletions runtime/include/gpu_gl_renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,14 @@ int gl_renderer_present_wide_fbo(int disp_x, int disp_y, int disp_h, int linear)
* for the widescreen field-of-view hack. */
void gl_renderer_set_display_aspect(int num, int den);

/* Scanline post-process (host display setting). on toggles the effect; strength
* (0..1) is the depth of the dark gap between PS1 scanlines. Applied at the
* native display-line pitch in the present/interpolation shaders, and faded in
* with output scale so it never shimmers on a sub-2x window. gl_renderer_get_
* scanlines returns the on flag and (via out-param) the current strength. */
void gl_renderer_set_scanlines(int on, float strength);
int gl_renderer_get_scanlines(float *strength);

/* Select full native-wide mirror rendering instead of the centre-splice fast
* path. Textured edge expansion needs the complete mirror surface. */
void gl_renderer_set_wide_fast(int on);
Expand Down
1 change: 1 addition & 0 deletions runtime/include/host_keymap.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ typedef enum HostKeymapAction {
HOST_KEYMAP_DISPLAY_PERF,
HOST_KEYMAP_REWIND, /* default F8 */
HOST_KEYMAP_SAVE_STATE_MENU, /* default F7 */
HOST_KEYMAP_SCANLINES, /* default F6 */
HOST_KEYMAP_ACTION_COUNT
} HostKeymapAction;

Expand Down
20 changes: 20 additions & 0 deletions runtime/src/debug_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -7846,6 +7846,25 @@ static void handle_ws_nw(int id, const char *json)
id, psx_ws_get_native_wide(), ws.mode, ws.nw_extra);
}

/* Live scanline post-process toggle (A/B): `scanline on=<0|1> pct=<0..100>`.
* Either field is optional — omit `on` to keep the current toggle, omit `pct`
* to keep the current strength. Reports the resulting state. */
extern void psx_video_set_scanlines(int on, float strength);
extern int psx_video_get_scanlines(float *strength);
static void handle_scanline(int id, const char *json)
{
int on = json_get_int(json, "on", -1);
int pct = json_get_int(json, "pct", -1);
float cur = 0.f;
int cur_on = psx_video_get_scanlines(&cur);
int new_on = (on >= 0) ? (on ? 1 : 0) : cur_on;
float new_s = (pct >= 0 && pct <= 100) ? (float)pct / 100.f : cur;
psx_video_set_scanlines(new_on, new_s);
cur_on = psx_video_get_scanlines(&cur);
send_fmt("{\"id\":%d,\"ok\":true,\"scanlines\":%d,\"strength_pct\":%d}",
id, cur_on, (int)(cur * 100.f + 0.5f));
}

/* ws_backdrop_ring: dump the always-on auto_backdrop rewrite ring (which windows
* fire, live extent/camera/DL-count, orig vs final bound). Read-only; small
* heap envelope so the per-byte stall of a giant read is never in play. */
Expand Down Expand Up @@ -13531,6 +13550,7 @@ static const CmdEntry s_commands[] = {
{ "kernel_bless", handle_kernel_bless },
{ "ws_aspect", handle_ws_aspect },
{ "ws_nw", handle_ws_nw },
{ "scanline", handle_scanline },
{ "ws_backdrop_ring", handle_ws_backdrop_ring },
{ "ws_ui_groups", handle_ws_ui_groups },
{ "ws_backdrop_margin", handle_ws_backdrop_margin },
Expand Down
Loading