From 05323fb6502e44de16e9ae54ae69d0bd0a0e9363 Mon Sep 17 00:00:00 2001 From: beauxq Date: Sun, 13 Aug 2023 21:03:21 -0700 Subject: [PATCH 1/3] add READ_CORE_RAM and WRITE_CORE_RAM --- data/lua/connector_ladx_bizhawk.lua | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/data/lua/connector_ladx_bizhawk.lua b/data/lua/connector_ladx_bizhawk.lua index 6a5fbf700c5b..10da8746bb05 100644 --- a/data/lua/connector_ladx_bizhawk.lua +++ b/data/lua/connector_ladx_bizhawk.lua @@ -49,6 +49,13 @@ require('common') udp:setsockname('127.0.0.1', 55355) udp:settimeout(0) +local domains = { + ["READ_CORE_MEMORY"] = "System Bus", + ["READ_CORE_RAM"] = "Main RAM", + ["WRITE_CORE_MEMORY"] = "System Bus", + ["WRITE_CORE_RAM"] = "Main RAM" +} + function on_vblank() -- Attempt to lessen the CPU load by only polling the UDP socket every x frames. -- x = 10 is entirely arbitrary, very little thought went into it. @@ -95,7 +102,7 @@ function on_vblank() -- NOTE: No newline is intentional here for 1:1 RetroArch compatibility udp:sendto("GET_STATUS CONTENTLESS", msg_or_ip, port_or_nil) end - elseif command == "READ_CORE_MEMORY" then + elseif command == "READ_CORE_MEMORY" or command == "READ_CORE_RAM" then local _, address, length = string.match(data, "(%S+) (%S+) (%S+)") address = stripPrefix(address, "0x") address = tonumber(address, 16) @@ -107,7 +114,7 @@ function on_vblank() -- Using memory.read_bytes_as_array() and explicitly using the System Bus -- as the active memory domain solves this incompatibility, allowing us -- to hopefully use whatever GB(C) emulator we want. - local mem = memory.read_bytes_as_array(address, length, "System Bus") + local mem = memory.read_bytes_as_array(address, length, domains[command]) local hex_string = "" for _, v in ipairs(mem) do hex_string = hex_string .. string.format("%02X ", v) @@ -116,7 +123,7 @@ function on_vblank() hex_string = hex_string:sub(1, -2) -- Hang head in shame, remove last " " local reply = string.format("%s %02x %s\n", command, address, hex_string) udp:sendto(reply, msg_or_ip, port_or_nil) - elseif command == "WRITE_CORE_MEMORY" then + elseif command == "WRITE_CORE_MEMORY" or command == "WRITE_CORE_RAM" then local _, address = string.match(data, "(%S+) (%S+)") address = stripPrefix(address, "0x") address = tonumber(address, 16) @@ -131,7 +138,7 @@ function on_vblank() i = i + 1 end - memory.write_bytes_as_array(address, to_write, "System Bus") + memory.write_bytes_as_array(address, to_write, domains[command]) local reply = string.format("%s %02x %d\n", command, address, i - 3) udp:sendto(reply, msg_or_ip, port_or_nil) end From ad4d2cf3d106fe048a08497e8a79d3b118d2d308 Mon Sep 17 00:00:00 2001 From: Doug Hoskisson Date: Tue, 15 Aug 2023 19:25:28 -0700 Subject: [PATCH 2/3] frame instead of memory execute --- data/lua/connector_ladx_bizhawk.lua | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/data/lua/connector_ladx_bizhawk.lua b/data/lua/connector_ladx_bizhawk.lua index 10da8746bb05..31e3ecf51637 100644 --- a/data/lua/connector_ladx_bizhawk.lua +++ b/data/lua/connector_ladx_bizhawk.lua @@ -56,6 +56,8 @@ local domains = { ["WRITE_CORE_RAM"] = "Main RAM" } +local frame_count = 0; + function on_vblank() -- Attempt to lessen the CPU load by only polling the UDP socket every x frames. -- x = 10 is entirely arbitrary, very little thought went into it. @@ -69,6 +71,12 @@ function on_vblank() --while emu.framecount() % 10 ~= 0 do -- emu.frameadvance() --end + frame_count = frame_count + 1 + if frame_count >= 10 then + frame_count = 0 + else + return + end local data, msg_or_ip, port_or_nil = udp:receivefrom() if data then @@ -145,8 +153,9 @@ function on_vblank() end end -event.onmemoryexecute(on_vblank, 0x40, "ap_connector_vblank") +event.onframeend(on_vblank, "ap_connector_frame") +print("connector loaded") while true do emu.yield() end From ef052518bdc7237f85d4852ab394d35f7b11c603 Mon Sep 17 00:00:00 2001 From: beauxq Date: Wed, 16 Aug 2023 12:20:47 -0700 Subject: [PATCH 3/3] choose event based on system --- data/lua/connector_ladx_bizhawk.lua | 35 +++++++++-------------------- 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/data/lua/connector_ladx_bizhawk.lua b/data/lua/connector_ladx_bizhawk.lua index 31e3ecf51637..ebbdc887dde4 100644 --- a/data/lua/connector_ladx_bizhawk.lua +++ b/data/lua/connector_ladx_bizhawk.lua @@ -3,7 +3,7 @@ -- SPDX-License-Identifier: MIT -- This script attempts to implement the basic functionality needed in order for --- the LADXR Archipelago client to be able to talk to EmuHawk instead of RetroArch +-- the some Archipelago clients to be able to talk to EmuHawk instead of RetroArch -- by reproducing the RetroArch API with EmuHawk's Lua interface. -- -- RetroArch UDP API: https://github.com/libretro/RetroArch/blob/master/command.c @@ -56,28 +56,8 @@ local domains = { ["WRITE_CORE_RAM"] = "Main RAM" } -local frame_count = 0; - -function on_vblank() - -- Attempt to lessen the CPU load by only polling the UDP socket every x frames. - -- x = 10 is entirely arbitrary, very little thought went into it. - -- We could try to make use of client.get_approx_framerate() here, but the values returned - -- seemed more or less arbitrary as well. - -- - -- NOTE: Never mind the above, the LADXR Archipelago client appears to run into problems with - -- interwoven GET_STATUS calls, leading to stopped communication. - -- For GB(C), polling the socket on every frame is OK-ish, so we just do that. - -- - --while emu.framecount() % 10 ~= 0 do - -- emu.frameadvance() - --end - frame_count = frame_count + 1 - if frame_count >= 10 then - frame_count = 0 - else - return - end - +-- receive a udp packet and handle it +local function server_handle() local data, msg_or_ip, port_or_nil = udp:receivefrom() if data then -- "data" format is "COMMAND [PARAMETERS] [...]" @@ -153,7 +133,14 @@ function on_vblank() end end -event.onframeend(on_vblank, "ap_connector_frame") +if emu.getsystemid() == "GBC" then + -- This is a workaround for: https://github.com/TASEmulators/BizHawk/issues/3711 + event.onmemoryexecute(server_handle, 0x40, "ap_connector_vblank") + print("using vblank event") +else + event.onframeend(server_handle, "ap_connector_frame") + print("using frame event") +end print("connector loaded") while true do