From 3cda8a2e602b7bb649e27e97d4eb17e6f807be69 Mon Sep 17 00:00:00 2001 From: Brian Degenhardt Date: Sat, 8 Aug 2026 20:44:15 -0700 Subject: [PATCH] PINE: stop savestate slot from clobbering the gsctl socket slot The loadstate/savestate positional was named "slot", which is also the global option selecting the PINE socket. argparse shares one namespace, so the positional overwrote it and `gsctl.py loadstate 1` dialled pcsx2.sock.1 instead of the emulator's socket, failing to connect. Give the positional its own dest and keep "slot" as the metavar, so the command line is unchanged. --- tools/gsctl.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/gsctl.py b/tools/gsctl.py index 2fcafbc093..4755db6c4d 100644 --- a/tools/gsctl.py +++ b/tools/gsctl.py @@ -213,11 +213,15 @@ def main(): p.add_argument("key") p.add_argument("value", nargs="?") + # dest must NOT be "slot": that is the global --slot (the PINE socket slot), + # and a same-named positional overwrites it in the shared namespace, so + # `gsctl.py loadstate 1` would dial socket pcsx2.sock.1 instead of the + # emulator's and always fail to connect. p = sub.add_parser("loadstate", help="load a savestate slot") - p.add_argument("slot", type=int) + p.add_argument("state_slot", type=int, metavar="slot") p = sub.add_parser("savestate", help="save to a savestate slot") - p.add_argument("slot", type=int) + p.add_argument("state_slot", type=int, metavar="slot") args = ap.parse_args() @@ -270,9 +274,9 @@ def main(): if result.get("restart_required"): print("note: this key forces a GS device reopen", file=sys.stderr) elif args.cmd == "loadstate": - pine.load_state(args.slot) + pine.load_state(args.state_slot) elif args.cmd == "savestate": - pine.save_state(args.slot) + pine.save_state(args.state_slot) except KeyboardInterrupt: pass except (PineError, OSError) as e: