yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
mesen_emulator_adapter.cc
Go to the documentation of this file.
2
3#include "absl/status/statusor.h"
4#include "absl/strings/str_format.h"
5
6namespace yaze {
7namespace emu {
8namespace mesen {
9
10namespace {
11
12absl::StatusOr<emu::input::SnesButton> MapButton(InputButton button) {
13 switch (button) {
26 default:
27 return absl::InvalidArgumentError(absl::StrFormat(
28 "Unsupported button value: %d", static_cast<int>(button)));
29 }
30}
31
32} // namespace
33
36
38 if (client_) {
39 client_->Disconnect();
40 }
41}
42
44 return client_->Connect();
45}
46
47absl::Status MesenEmulatorAdapter::Connect(const std::string& socket_path) {
48 return client_->Connect(socket_path);
49}
50
52 return client_ && client_->IsConnected();
53}
54
56 if (!IsConnected()) return false;
57 auto state = client_->GetState();
58 if (!state.ok()) return false;
59 return state->running;
60}
61
63 if (IsConnected()) client_->Pause();
64}
65
67 if (IsConnected()) client_->Resume();
68}
69
71 if (IsConnected()) client_->Reset();
72}
73
74absl::Status MesenEmulatorAdapter::Step(int count) {
75 if (!IsConnected()) return absl::UnavailableError("Not connected");
76 return client_->Step(count);
77}
78
80 if (!IsConnected()) return absl::UnavailableError("Not connected");
81 return client_->Step(1, "over");
82}
83
85 if (!IsConnected()) return absl::UnavailableError("Not connected");
86 return client_->Step(1, "out");
87}
88
89absl::Status MesenEmulatorAdapter::LoadRom(const std::string& path) {
90 if (!IsConnected()) return absl::UnavailableError("Not connected");
91 return absl::UnimplementedError(
92 "LoadRom not supported via Mesen2 Socket yet");
93}
94
96 return "";
97}
98
99absl::StatusOr<uint8_t> MesenEmulatorAdapter::ReadByte(uint32_t addr) {
100 if (!IsConnected()) return absl::UnavailableError("Not connected");
101 return client_->ReadByte(addr);
102}
103
104absl::StatusOr<std::vector<uint8_t>> MesenEmulatorAdapter::ReadBlock(
105 uint32_t addr, size_t len) {
106 if (!IsConnected()) return absl::UnavailableError("Not connected");
107 return client_->ReadBlock(addr, len);
108}
109
110absl::Status MesenEmulatorAdapter::WriteByte(uint32_t addr, uint8_t val) {
111 if (!IsConnected()) return absl::UnavailableError("Not connected");
112 return client_->WriteByte(addr, val);
113}
114
116 uint32_t addr, const std::vector<uint8_t>& data) {
117 if (!IsConnected()) return absl::UnavailableError("Not connected");
118 return client_->WriteBlock(addr, data);
119}
120
122 if (!IsConnected()) return absl::UnavailableError("Not connected");
123 auto cpu_status = client_->GetCpuState();
124 if (!cpu_status.ok()) return cpu_status.status();
125
126 auto& mk = *cpu_status;
127 out_state->a = mk.A;
128 out_state->x = mk.X;
129 out_state->y = mk.Y;
130 out_state->sp = mk.SP;
131 out_state->d = mk.D;
132 out_state->pc = mk.PC;
133 out_state->pb = mk.K;
134 out_state->db = mk.DBR;
135 out_state->status = mk.P;
136 out_state->flag_n = mk.P & 0x80;
137 out_state->flag_v = mk.P & 0x40;
138 out_state->flag_z = mk.P & 0x02;
139 out_state->flag_c = mk.P & 0x01;
140
141 return absl::OkStatus();
142}
143
145 if (!IsConnected()) return absl::UnavailableError("Not connected");
146 auto game_state = client_->GetGameState();
147 if (!game_state.ok()) return game_state.status();
148
149 auto& gs = *game_state;
150 response->link_pos_x = gs.link.x;
151 response->link_pos_y = gs.link.y;
152 response->link_state = gs.link.state;
153 response->game_mode = gs.game.mode;
154 response->link_health = gs.items.current_health;
155
156 return absl::OkStatus();
157}
158
160 BreakpointHitResult* response) {
161 return absl::UnimplementedError(
162 "RunToBreakpoint not supported via Mesen2 Socket");
163}
164
165absl::StatusOr<uint32_t> MesenEmulatorAdapter::AddBreakpoint(
166 uint32_t addr, BreakpointKind type, CpuKind cpu,
167 const std::string& condition, const std::string& description) {
168 if (!IsConnected()) return absl::UnavailableError("Not connected");
169
170 if (cpu == CpuKind::kSpc700) {
171 return absl::UnimplementedError(
172 "SPC700 breakpoints are not supported via Mesen2 Socket");
173 }
174 if (cpu != CpuKind::kUnspecified && cpu != CpuKind::k65816) {
175 return absl::InvalidArgumentError(absl::StrFormat(
176 "Unsupported CPU kind for breakpoint: %d", static_cast<int>(cpu)));
177 }
178
180 if (type == BreakpointKind::kRead) mesen_type = mesen::BreakpointType::kRead;
181 else if (type == BreakpointKind::kWrite)
183 else if (type == BreakpointKind::kAccess)
185
186 auto result = client_->AddBreakpoint(addr, mesen_type, condition);
187 if (!result.ok()) return result.status();
188
189 return static_cast<uint32_t>(*result);
190}
191
192absl::Status MesenEmulatorAdapter::RemoveBreakpoint(uint32_t breakpoint_id) {
193 if (!IsConnected()) return absl::UnavailableError("Not connected");
194 return client_->RemoveBreakpoint(breakpoint_id);
195}
196
197absl::Status MesenEmulatorAdapter::ToggleBreakpoint(uint32_t breakpoint_id,
198 bool enabled) {
199 return absl::UnimplementedError(
200 "ToggleBreakpoint not supported via Mesen2 Socket");
201}
202
203std::vector<BreakpointSnapshot> MesenEmulatorAdapter::ListBreakpoints() {
204 return {};
205}
206
208 if (!IsConnected()) return absl::UnavailableError("Not connected");
209 auto mapped_button = MapButton(button);
210 if (!mapped_button.ok()) return mapped_button.status();
211 return client_->SetButton(*mapped_button, true);
212}
213
215 if (!IsConnected()) return absl::UnavailableError("Not connected");
216 auto mapped_button = MapButton(button);
217 if (!mapped_button.ok()) return mapped_button.status();
218 return client_->SetButton(*mapped_button, false);
219}
220
221absl::Status MesenEmulatorAdapter::SaveState(int slot) {
222 if (!IsConnected()) return absl::UnavailableError("Not connected");
223 return client_->SaveState(slot);
224}
225
226absl::Status MesenEmulatorAdapter::LoadState(int slot) {
227 if (!IsConnected()) return absl::UnavailableError("Not connected");
228 return client_->LoadState(slot);
229}
230
245
247 if (!IsConnected()) return absl::UnavailableError("Not connected");
248 return client_->SetCollisionOverlay(enable);
249}
250
251} // namespace mesen
252} // namespace emu
253} // namespace yaze
absl::Status ReleaseButton(InputButton button) override
bool SupportsFeature(EmulatorFeature feature) const override
absl::Status GetGameState(GameSnapshot *out_state) override
std::unique_ptr< MesenSocketClient > client_
std::string GetLoadedRomPath() const override
absl::Status GetCpuState(CpuStateSnapshot *out_state) override
absl::StatusOr< uint8_t > ReadByte(uint32_t addr) override
absl::Status PressButton(InputButton button) override
absl::StatusOr< std::vector< uint8_t > > ReadBlock(uint32_t addr, size_t len) override
absl::Status SetCollisionOverlay(bool enable) override
absl::Status WriteBlock(uint32_t addr, const std::vector< uint8_t > &data) override
absl::Status Step(int count) override
std::vector< BreakpointSnapshot > ListBreakpoints() override
absl::Status LoadState(int slot) override
absl::StatusOr< uint32_t > AddBreakpoint(uint32_t addr, BreakpointKind type, CpuKind cpu, const std::string &condition, const std::string &description) override
absl::Status ToggleBreakpoint(uint32_t breakpoint_id, bool enabled) override
absl::Status WriteByte(uint32_t addr, uint8_t val) override
absl::Status RemoveBreakpoint(uint32_t breakpoint_id) override
absl::Status Connect()
Explicitly connect to a Mesen2 socket (replaces auto-connect).
absl::Status LoadRom(const std::string &path) override
absl::Status RunToBreakpoint(BreakpointHitResult *response) override
absl::Status SaveState(int slot) override
Unix socket client for Mesen2-OoS fork.
absl::StatusOr< emu::input::SnesButton > MapButton(InputButton button)
BreakpointType
Breakpoint types.
EmulatorFeature
Features that emulator backends may optionally support. Use with IEmulator::SupportsFeature() to quer...