189 ImGui::SameLine(ImGui::GetWindowWidth() - 100);
191 float pulse = 0.7f + 0.3f * std::sin(ImGui::GetTime() * 2.0f);
192 ImVec4 connected_color = ImVec4(0.1f, pulse, 0.3f, 1.0f);
195 ImGui::TextColored(theme.status_error,
"%s Disconnected",
ICON_MD_ERROR);
202 ImGui::TextDisabled(
"Socket");
203 const char* preview =
205 selected_socket_index_ < static_cast<int>(
socket_paths_.size()))
207 :
"No sockets found";
208 ImGui::SetNextItemWidth(-40);
209 if (ImGui::BeginCombo(
"##mesen_socket_combo", preview)) {
210 for (
int i = 0; i < static_cast<int>(
socket_paths_.size()); ++i) {
218 ImGui::SetItemDefaultFocus();
228 ImGui::TextDisabled(
"Path");
229 ImGui::SetNextItemWidth(-1);
230 ImGui::InputTextWithHint(
"##mesen_socket_path",
231 "/tmp/mesen2-12345.sock",
263 ImGui::SetNextItemWidth(60);
271 ImGui::TextColored(theme.text_secondary_color,
"%s",
288 ImGui::Text(
"Position:");
290 ImGui::TextColored(theme.text_secondary_color,
"X=%d, Y=%d Layer: %d",
291 link.x, link.y, link.layer);
294 ImGui::Text(
"Direction:");
296 ImGui::TextColored(theme.text_secondary_color,
"%s (0x%02X)",
297 DirectionToString(link.direction), link.direction);
299 ImGui::Text(
" State:");
301 ImGui::TextColored(theme.text_secondary_color,
"0x%02X", link.state);
305 items.max_health > 0 ?
static_cast<float>(items.current_health) /
306 static_cast<float>(items.max_health)
308 ImVec4 health_color = HealthColor(health_ratio);
310 ImGui::Text(
"Health:");
314 int full_hearts = items.current_health / 8;
315 int max_hearts = items.max_health / 8;
318 for (
int i = 0; i < full_hearts; ++i) {
319 ImGui::SameLine(0, 0);
325 ImVec4(0.3f, 0.3f, 0.3f, 1.0f));
326 for (
int i = full_hearts; i < max_hearts; ++i) {
327 ImGui::SameLine(0, 0);
333 ImGui::TextColored(theme.text_secondary_color,
" (%d/%d)",
334 items.current_health, items.max_health);
337 ImGui::Text(
"Items:");
339 ImGui::TextColored(theme.text_secondary_color,
340 "Magic: %d Rupees: %d Bombs: %d Arrows: %d",
341 items.magic, items.rupees, items.bombs, items.arrows);
350 std::string header = absl::StrFormat(
"%s Active Sprites (%zu/16)",
353 if (ImGui::CollapsingHeader(header.c_str(),
355 ? ImGuiTreeNodeFlags_DefaultOpen
362 ImGui::TextDisabled(
" No active sprites");
365 if (ImGui::BeginChild(
"SpriteList", ImVec2(0, 120),
true)) {
366 for (
const auto& sprite :
sprites_) {
367 ImGui::PushID(sprite.slot);
370 ImGui::TextColored(theme.text_secondary_color,
"[%d]", sprite.slot);
374 ImVec4 sprite_color =
376 ? ImVec4(0.4f, 0.8f, 0.4f, 1.0f)
377 : ImVec4(0.5f, 0.5f, 0.5f, 1.0f);
378 ImGui::TextColored(sprite_color,
"Type: 0x%02X", sprite.type);
381 ImGui::Text(
"@ %d,%d", sprite.x, sprite.y);
384 if (sprite.health > 0) {
385 ImGui::TextColored(ImVec4(0.8f, 0.3f, 0.3f, 1.0f),
"HP:%d",
390 ImGui::TextColored(theme.text_secondary_color,
"State:%d",
409 ? ImGuiTreeNodeFlags_DefaultOpen
413 ImGui::Text(
"Mode:");
415 ImGui::TextColored(theme.text_secondary_color,
"%d (Submode: %d)",
416 game.mode, game.submode);
418 ImGui::Text(
"Location:");
421 ImGui::TextColored(ImVec4(0.6f, 0.4f, 0.2f, 1.0f),
422 "Dungeon Room: 0x%04X", game.room_id);
424 ImGui::TextColored(ImVec4(0.2f, 0.6f, 0.2f, 1.0f),
425 "Overworld Area: 0x%02X", game.overworld_area);
429 ImGui::Text(
"Frame:");
431 ImGui::TextColored(theme.text_secondary_color,
"%llu",
emu_state_.
frame);
434 ImGui::Text(
" FPS:");
436 ImGui::TextColored(theme.text_secondary_color,
"%.1f",
emu_state_.
fps);
442 ImGui::TextColored(theme.text_secondary_color,
443 "PC=$%02X:%04X A=$%04X X=$%04X Y=$%04X",
446 ImGui::TextColored(theme.text_secondary_color,
447 "SP=$%04X D=$%04X DBR=$%02X P=$%02X",