mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
TCP input injection for port 2 (set_input/press/clear_input port=2)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 66cc81fe63)
This commit is contained in:
@@ -198,6 +198,8 @@ void debug_server_check_watchpoints(void);
|
||||
/* Returns >= 0 if the debug server wants to override pad input,
|
||||
* -1 if no override is active. Value is PS1 16-bit button mask. */
|
||||
int debug_server_get_input_override(void);
|
||||
/* Port-2 override word (set_input/press "port":2), or -1. */
|
||||
int debug_server_get_input_override_port2(void);
|
||||
|
||||
/* Optional analog-stick override set alongside set_input (lx/ly/rx/ry,
|
||||
* 0..255, 0x80 = centre). Returns 1 and fills st[lx,ly,rx,ry] when armed,
|
||||
|
||||
@@ -286,6 +286,10 @@ static uint64_t s_dirty_break_hits = 0;
|
||||
/* ---- Input override ---- */
|
||||
static int s_input_override = -1;
|
||||
static int s_input_frames = 0;
|
||||
/* Port 2 (set_input / press / clear_input "port":2): digital buttons only,
|
||||
* for driving two-player modes headless. */
|
||||
static int s_input_override_p2 = -1;
|
||||
static int s_input_frames_p2 = 0;
|
||||
/* Optional analog-stick override (set_input lx/ly/rx/ry, 0..255, 0x80 =
|
||||
* centre). Lets injected input drive analog-mode movement; consumed by the
|
||||
* pad sampler alongside the button word. */
|
||||
@@ -8004,6 +8008,12 @@ static void handle_set_input(int id, const char *json)
|
||||
if (pad_type < -1 || pad_type > 2) {
|
||||
send_err(id, "pad_type must be -1 (automatic), 0, 1, or 2"); return;
|
||||
}
|
||||
if (json_get_int(json, "port", 1) == 2) {
|
||||
s_input_override_p2 = (int)(hex_to_u32(val_str) & 0xFFFFu);
|
||||
s_input_frames_p2 = 0;
|
||||
send_ok(id);
|
||||
return;
|
||||
}
|
||||
s_pad_type_override = pad_type;
|
||||
s_input_override = (int)hex_to_u32(val_str);
|
||||
s_input_frames = 0;
|
||||
@@ -8044,6 +8054,12 @@ static void handle_press(int id, const char *json)
|
||||
if (pad_type < -1 || pad_type > 2) {
|
||||
send_err(id, "pad_type must be -1 (automatic), 0, 1, or 2"); return;
|
||||
}
|
||||
if (json_get_int(json, "port", 1) == 2) {
|
||||
s_input_override_p2 = buttons & 0xFFFF;
|
||||
s_input_frames_p2 = frames;
|
||||
send_ok(id);
|
||||
return;
|
||||
}
|
||||
s_pad_type_override = pad_type;
|
||||
s_input_override = buttons;
|
||||
s_input_frames = frames;
|
||||
@@ -8095,6 +8111,7 @@ static void handle_pad_status(int id, const char *json)
|
||||
"\"slot1\":{\"buttons\":\"0x%04X\",\"connected\":%s,\"analog\":%s,\"type\":%d,\"sticks\":[%u,%u,%u,%u],"
|
||||
"\"negcon\":[%u,%u,%u],\"mode_locked\":%s},"
|
||||
"\"override\":%d,\"override_frames\":%d,\"override_pad_type\":%d,"
|
||||
"\"override_p2\":%d,\"override_p2_frames\":%d,"
|
||||
"\"override_axes\":[%u,%u,%u,%u],\"override_axes_valid\":%s,"
|
||||
"\"host_layer\":%s,\"host_buttons\":\"0x%04X\",\"host_axes\":[%u,%u,%u,%u],"
|
||||
"\"host_lt\":%u,\"host_rt\":%u}\n",
|
||||
@@ -8108,6 +8125,7 @@ static void handle_pad_status(int id, const char *json)
|
||||
sticks1[0], sticks1[1], sticks1[2], sticks1[3],
|
||||
neg1[0], neg1[1], neg1[2], sio_get_pad_mode_locked(1) ? "true" : "false",
|
||||
s_input_override, s_input_frames, s_pad_type_override,
|
||||
s_input_override_p2, s_input_frames_p2,
|
||||
s_axis_st[0], s_axis_st[1], s_axis_st[2], s_axis_st[3],
|
||||
s_axis_override ? "true" : "false",
|
||||
s_host_layer ? "true" : "false", s_host_buttons,
|
||||
@@ -8117,7 +8135,12 @@ static void handle_pad_status(int id, const char *json)
|
||||
|
||||
static void handle_clear_input(int id, const char *json)
|
||||
{
|
||||
(void)json;
|
||||
const int port = json_get_int(json, "port", 0); /* 0 = both */
|
||||
if (port == 0 || port == 2) {
|
||||
s_input_override_p2 = -1;
|
||||
s_input_frames_p2 = 0;
|
||||
}
|
||||
if (port == 2) { send_ok(id); return; }
|
||||
s_input_route_active = 0;
|
||||
s_input_route_index = 0;
|
||||
s_input_route_remaining = 0;
|
||||
@@ -16718,6 +16741,16 @@ int debug_server_get_input_override(void)
|
||||
return current;
|
||||
}
|
||||
|
||||
int debug_server_get_input_override_port2(void)
|
||||
{
|
||||
int current = s_input_override_p2;
|
||||
if (s_input_override_p2 >= 0 && s_input_frames_p2 > 0) {
|
||||
if (--s_input_frames_p2 == 0)
|
||||
s_input_override_p2 = -1;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
int debug_server_get_axis_override(unsigned char st[4])
|
||||
{
|
||||
if (!s_axis_override) return 0;
|
||||
|
||||
@@ -6878,6 +6878,18 @@ static PadExtHooks pad_ext_main_hooks(void) {
|
||||
return h;
|
||||
}
|
||||
|
||||
/* TCP port-2 injection (set_input/press "port":2): a digital pad plugged
|
||||
* into port 2 for as long as a test drives it, so headless runs can reach and
|
||||
* play two-player modes. Applied after the normal sampling so it wins. */
|
||||
static void apply_input_override_port2(int override_word) {
|
||||
if (override_word < 0) return;
|
||||
if (!sio_get_pad_connected(1)) {
|
||||
sio_set_pad_connected(1, 1);
|
||||
sio_set_pad_analog(1, 0, 0x80, 0x80, 0x80, 0x80);
|
||||
}
|
||||
sio_set_pad_state_slot(1, (uint16_t)override_word);
|
||||
}
|
||||
|
||||
static void sample_pad_into_sio(int override) {
|
||||
/* Selfcheck fighter mash owns P1 when enabled (headless-safe). */
|
||||
if (override < 0) {
|
||||
@@ -8098,12 +8110,14 @@ static NetplayVblankEpilogue sdl_vblank_present_body(void) {
|
||||
|
||||
/* Check debug server input override. */
|
||||
int override = debug_server_get_input_override();
|
||||
int override_p2 = debug_server_get_input_override_port2();
|
||||
#else
|
||||
/* Production: skip debug server. Still need to advance frame counter
|
||||
* locally so anything else that reads it continues to work. */
|
||||
extern uint64_t s_frame_count;
|
||||
s_frame_count++;
|
||||
int override = -1;
|
||||
int override_p2 = -1;
|
||||
#endif
|
||||
|
||||
psx_local_mouse_begin(sdl_window, local_mouse_live(override));
|
||||
@@ -8299,6 +8313,7 @@ static NetplayVblankEpilogue sdl_vblank_present_body(void) {
|
||||
sample_headless_pad_into_sio(override);
|
||||
else
|
||||
sample_pad_into_sio(override);
|
||||
apply_input_override_port2(override_p2);
|
||||
}
|
||||
/* Offline vblank boundary: record/replay/compare (PSX_RB_SELFCHECK).
|
||||
* Defer opening a window while multitap arming is still pending —
|
||||
@@ -8629,6 +8644,7 @@ static NetplayVblankEpilogue sdl_vblank_present_body(void) {
|
||||
SDL_PumpEvents(); // retain native timing when no policy exists
|
||||
}
|
||||
sample_pad_into_sio(override);
|
||||
apply_input_override_port2(override_p2);
|
||||
latency_ring_restamp_input();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user