yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
mesen_socket_client.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EMU_MESEN_MESEN_SOCKET_CLIENT_H_
2#define YAZE_APP_EMU_MESEN_MESEN_SOCKET_CLIENT_H_
3
4#include <atomic>
5#include <cstdint>
6#include <functional>
7#include <memory>
8#include <mutex>
9#include <string>
10#include <thread>
11#include <unordered_map>
12#include <vector>
13
14#include "absl/status/status.h"
15#include "absl/status/statusor.h"
17
18namespace yaze {
19namespace emu {
20namespace mesen {
21
22#ifdef _WIN32
23using SocketHandle = std::uintptr_t;
24#else
25using SocketHandle = int;
26#endif
27
29 static_cast<SocketHandle>(-1);
30
34struct CpuState {
35 uint16_t A;
36 uint16_t X;
37 uint16_t Y;
38 uint16_t SP;
39 uint16_t D; // Direct page
40 uint32_t PC;
41 uint8_t K; // Program bank
42 uint8_t DBR; // Data bank
43 uint8_t P; // Processor status
45};
46
50struct MesenState {
51 bool running;
52 bool paused;
54 uint64_t frame;
55 double fps;
57};
58
62struct LinkState {
63 uint16_t x;
64 uint16_t y;
65 uint8_t layer;
66 uint8_t direction; // 0=up, 2=down, 4=left, 6=right
67 uint8_t state;
68 uint8_t pose;
69};
70
74struct GameItems {
76 uint8_t max_health;
77 uint8_t magic;
78 uint16_t rupees;
79 uint8_t bombs;
80 uint8_t arrows;
81};
82
86struct GameMode {
87 uint8_t mode;
88 uint8_t submode;
89 bool indoors;
90 uint16_t room_id; // Valid when indoors
91 uint8_t overworld_area; // Valid when !indoors
92};
93
102
107 int slot;
108 uint8_t type;
109 uint8_t state;
110 uint16_t x;
111 uint16_t y;
112 uint8_t health;
113 uint8_t subtype;
114};
115
120
125 std::string type; // "breakpoint_hit", "frame_complete", etc.
126 std::string raw_json; // Full event payload
127 uint32_t address; // For breakpoint events
128 uint64_t frame; // Frame number when event occurred
129};
130
131using EventCallback = std::function<void(const MesenEvent&)>;
132using EventListenerId = uint64_t;
133
141 public:
144
145 // Disable copy
148
149 // ──────────────────────────────────────────────────────────────────────────
150 // Connection Management
151 // ──────────────────────────────────────────────────────────────────────────
152
160 absl::Status Connect();
161
169 absl::Status Connect(const std::string& socket_path);
170
174 void Disconnect();
175
179 bool IsConnected() const;
180
184 const std::string& GetSocketPath() const { return socket_path_; }
185
189 static std::vector<std::string> ListAvailableSockets();
190
191 // ──────────────────────────────────────────────────────────────────────────
192 // Control Commands
193 // ──────────────────────────────────────────────────────────────────────────
194
198 absl::Status Ping();
199
203 absl::StatusOr<MesenState> GetState();
204
208 absl::Status Pause();
209
213 absl::Status Resume();
214
218 absl::Status Reset();
219
223 absl::Status Frame();
224
230 absl::Status Step(int count = 1, const std::string& mode = "into");
231
232 // ──────────────────────────────────────────────────────────────────────────
233 // Input Commands
234 // ──────────────────────────────────────────────────────────────────────────
235
241 absl::Status SetButton(emu::input::SnesButton button, bool pressed);
242
246 absl::Status SetButtons(const emu::input::ControllerState& state);
247
248 // ──────────────────────────────────────────────────────────────────────────
249 // Memory Access
250 // ──────────────────────────────────────────────────────────────────────────
251
255 absl::StatusOr<uint8_t> ReadByte(uint32_t addr);
256
260 absl::StatusOr<uint16_t> ReadWord(uint32_t addr);
261
265 absl::StatusOr<std::vector<uint8_t>> ReadBlock(uint32_t addr, size_t len);
266
270 absl::Status WriteByte(uint32_t addr, uint8_t value);
271
275 absl::Status WriteWord(uint32_t addr, uint16_t value);
276
280 absl::Status WriteBlock(uint32_t addr, const std::vector<uint8_t>& data);
281
282 // ──────────────────────────────────────────────────────────────────────────
283 // Debugging Commands
284 // ──────────────────────────────────────────────────────────────────────────
285
289 absl::StatusOr<CpuState> GetCpuState();
290
294 absl::StatusOr<std::string> Disassemble(uint32_t addr, int count = 10);
295
300 absl::StatusOr<int> AddBreakpoint(uint32_t addr, BreakpointType type,
301 const std::string& condition = "");
302
306 absl::Status RemoveBreakpoint(int id);
307
311 absl::Status ClearBreakpoints();
312
316 absl::StatusOr<std::string> GetTrace(int count = 20);
317
318 // ──────────────────────────────────────────────────────────────────────────
319 // ALTTP-Specific Commands
320 // ──────────────────────────────────────────────────────────────────────────
321
325 absl::StatusOr<GameState> GetGameState();
326
331 absl::StatusOr<std::vector<SpriteInfo>> GetSprites(bool all = false);
332
336 absl::Status SetCollisionOverlay(bool enable,
337 const std::string& colmap = "A");
338
339 // ──────────────────────────────────────────────────────────────────────────
340 // Save State Commands
341 // ──────────────────────────────────────────────────────────────────────────
342
346 absl::Status SaveState(int slot);
347
351 absl::Status LoadState(int slot);
352
357 absl::StatusOr<std::string> Screenshot();
358
359 // ──────────────────────────────────────────────────────────────────────────
360 // Event Subscription
361 // ──────────────────────────────────────────────────────────────────────────
362
367 absl::Status Subscribe(const std::vector<std::string>& events);
368
372 absl::Status Unsubscribe();
373
377 void SetEventCallback(EventCallback callback);
378
384
389
390 // ──────────────────────────────────────────────────────────────────────────
391 // Low-Level Commands
392 // ──────────────────────────────────────────────────────────────────────────
393
397 absl::StatusOr<std::string> SendCommand(const std::string& json);
398
399 private:
403 static std::vector<std::string> FindSocketPaths();
404
408 absl::StatusOr<std::string> ParseResponse(const std::string& response);
409
413 absl::StatusOr<std::string> SendCommandOnSocket(SocketHandle fd,
414 const std::string& json,
415 bool update_connection_state);
416
420 void EventLoop();
421
424#ifdef _WIN32
425 int winsock_startup_error_ = 0;
426 bool winsock_started_ = false;
427#endif
428 std::string socket_path_;
429 std::atomic<bool> connected_{false};
430 std::mutex command_mutex_;
432
433 // Event handling
435 std::unordered_map<EventListenerId, EventCallback> event_listeners_;
437 std::thread event_thread_;
438 std::atomic<bool> event_thread_running_{false};
440
441 // Input state
443};
444
445} // namespace mesen
446} // namespace emu
447} // namespace yaze
448
449#endif // YAZE_APP_EMU_MESEN_MESEN_SOCKET_CLIENT_H_
Local or TCP socket client for the Mesen2-OoS fork.
absl::Status ClearBreakpoints()
Clear all breakpoints.
absl::Status WriteWord(uint32_t addr, uint16_t value)
Write a 16-bit word to memory.
absl::StatusOr< uint8_t > ReadByte(uint32_t addr)
Read a single byte from memory.
void RemoveEventListener(EventListenerId id)
Remove a previously added event listener.
absl::Status Step(int count=1, const std::string &mode="into")
Step N CPU instructions (default 1)
void EventLoop()
Event listening thread function.
void SetEventCallback(EventCallback callback)
Set callback for received events.
absl::Status Ping()
Ping Mesen2 to check connectivity.
absl::Status Resume()
Resume emulation.
absl::StatusOr< CpuState > GetCpuState()
Get CPU register state.
absl::StatusOr< std::string > Screenshot()
Take a screenshot.
absl::StatusOr< std::string > ParseResponse(const std::string &response)
Parse JSON response for success/error.
const std::string & GetSocketPath() const
Get the current socket path.
absl::Status LoadState(int slot)
Load state from slot.
std::unordered_map< EventListenerId, EventCallback > event_listeners_
absl::StatusOr< uint16_t > ReadWord(uint32_t addr)
Read a 16-bit word from memory.
absl::StatusOr< int > AddBreakpoint(uint32_t addr, BreakpointType type, const std::string &condition="")
Add a breakpoint.
emu::input::ControllerState current_input_
MesenSocketClient(const MesenSocketClient &)=delete
static std::vector< std::string > ListAvailableSockets()
List available Mesen2 sockets on the system.
absl::Status SetButtons(const emu::input::ControllerState &state)
Set all buttons at once.
MesenSocketClient & operator=(const MesenSocketClient &)=delete
absl::StatusOr< std::string > GetTrace(int count=20)
Get execution trace log.
absl::StatusOr< GameState > GetGameState()
Get comprehensive ALTTP game state.
absl::Status SetButton(emu::input::SnesButton button, bool pressed)
Set controller button state.
absl::StatusOr< MesenState > GetState()
Get current emulation state.
absl::Status Frame()
Run exactly one frame.
absl::Status SetCollisionOverlay(bool enable, const std::string &colmap="A")
Enable/disable collision overlay.
bool IsConnected() const
Check if connected to Mesen2.
absl::StatusOr< std::string > SendCommand(const std::string &json)
Send a raw JSON command and get raw response.
EventListenerId AddEventListener(EventCallback callback)
Add an event listener without replacing existing listeners.
absl::StatusOr< std::vector< SpriteInfo > > GetSprites(bool all=false)
Get active sprites.
absl::Status RemoveBreakpoint(int id)
Remove a breakpoint by ID.
absl::Status Unsubscribe()
Unsubscribe from events.
absl::Status Subscribe(const std::vector< std::string > &events)
Subscribe to events.
absl::StatusOr< std::string > Disassemble(uint32_t addr, int count=10)
Disassemble instructions at address.
absl::Status Pause()
Pause emulation.
absl::Status Reset()
Reset the console.
absl::Status SaveState(int slot)
Save state to slot.
void Disconnect()
Disconnect from Mesen2.
absl::StatusOr< std::string > SendCommandOnSocket(SocketHandle fd, const std::string &json, bool update_connection_state)
Send a command using a specific socket descriptor.
static std::vector< std::string > FindSocketPaths()
Find available Mesen2 socket paths.
absl::Status WriteByte(uint32_t addr, uint8_t value)
Write a single byte to memory.
absl::StatusOr< std::vector< uint8_t > > ReadBlock(uint32_t addr, size_t len)
Read a block of bytes from memory.
absl::Status Connect()
Auto-discover and connect to first available Mesen2 socket.
absl::Status WriteBlock(uint32_t addr, const std::vector< uint8_t > &data)
Write a block of bytes to memory.
SnesButton
SNES controller button mapping (platform-agnostic)
std::function< void(const MesenEvent &)> EventCallback
BreakpointType
Breakpoint types.
constexpr SocketHandle kInvalidSocketHandle
Controller state (16-bit SNES controller format)
CPU register state from Mesen2.
ALTTP health/items state.
Complete ALTTP game state from GAMESTATE command.
Event from Mesen2 subscription.
Emulation state from Mesen2.
Sprite information from SPRITES command.