Skip to content

Instantly share code, notes, and snippets.

@adituv
Last active February 20, 2024 03:07
Show Gist options
  • Save adituv/265be838fa183d93634b3fd9833c0479 to your computer and use it in GitHub Desktop.
Save adituv/265be838fa183d93634b3fd9833c0479 to your computer and use it in GitHub Desktop.
Bizhawk shim for VBA-rr lua scripts
-- VBA/Bizhawk shim, to allow lua scripts written for VBA-rr to run in BizHawk.
-- Copy and paste this script into the start of a VBA-rr script to make it run in
-- BizHawk with no further modifications.
-- Changes to BizHawk's built-in tables persist while the lua console window is open.
-- Make sure we don't copy our already-updated objects.
if type(joypad.get) == "userdata" then
bizJoypad = copytable(joypad)
end
if vba == nil then
-- Assume we're in BizHawk and haven't yet applied the shim if vba is nil
suppressPolyfillWarnings = false
function warn(message)
if not suppressPolyfillWarnings then
console.log("WARNING: " .. message)
end
end
--------------------------------------------------------------------------------------------
-- Non-table functions --
--------------------------------------------------------------------------------------------
addressof = function ()
-- addressof intentionally not implemented because why on earth would you want to expose
-- memory addresses of tables in the process to the lua script?
error("addressof not implemented")
end
copytable = function (tbl)
local result = {}
for k,v in pairs(tbl) do
result[k] = v
end
return result
end
AND = function(x1, ...)
local result = x1
for _,v in ipairs(arg) do
result = bit.band(result,v)
end
return result
end
OR = function(x1, ...)
local result = x1
for _,v in ipairs(arg) do
result = bit.bor(result,v)
end
return result
end
XOR = function(x1, ...)
local result = x1
for _,v in ipairs(arg) do
result = bit.bxor(result,v)
end
return result
end
SHIFT = function(x, n)
if n > 0 then
return bit.rshift(x, n)
else
return bit.lshift(x, -n)
end
end
BIT = function(...)
local result = 0
for _,v in ipairs(arg) do
result = bit.set(result, v)
end
return result
end
--------------------------------------------------------------------------------------------
-- vba/emu table --
--------------------------------------------------------------------------------------------
vba = {
frameadvance = emu.frameadvance,
pause = client.pause,
framecount = emu.framecount,
lagcount = emu.lagcount,
lagged = emu.islagged,
emulating = function ()
warn("vba.emulating not implemented. Assuming true.")
return true
end,
registerbefore = event.oninputpoll,
registerafter = event.onframeend,
registerexit = event.onexit,
message = gui.addmessage,
print = console.log
}
--------------------------------------------------------------------------------------------
-- memory table --
--------------------------------------------------------------------------------------------
memory.readbyte = function(address, domain)
local domain = domain or "System Bus"
return memory.read_u8(address, domain)
end
memory.readbyteunsigned = memory.readbyte
memory.readword = function(address, domain)
local domain = domain or "System Bus"
return memory.read_u16_le(address, domain)
end
memory.readshort = memory.readword
memory.readwordunsigned = memory.readword
memory.readshortunsigned = memory.readword
memory.readdword = function(address, domain)
local domain = domain or "System Bus"
return memory.read_u32_le(address, domain)
end
memory.readlong = memory.readdword
memory.readdwordunsigned = memory.readdword
memory.readlongunsigned = memory.readdword
memory.readbytesigned = function(address, domain
local domain = domain or "System Bus"
return memory.read_s8(address, domain)
end
memory.readwordsigned = function(address, domain)
local domain = domain or "System Bus"
return memory.read_s16_le(address, domain)
end
memory.readshortsigned = memory.readwordsigned
memory.readdwordsigned = function(address, domain)
local domain = domain or "System Bus"
return memory.read_s32_le(address, domain)
end
memory.readlongsigned = memory.readdwordsigned
memory.writebyte = function(address, value, domain)
local domain = domain or "System Bus"
return memory.write_s8(address, value, domain)
end
memory.writeword = function(address, value, domain)
local domain = domain or "System Bus"
return memory.write_s16_le(address, value, domain)
end
memory.writeshort = memory.writeword
memory.writedword = function(address, value, domain)
local domain = domain or "System Bus"
return memory.write_s32_le(address, value, domain)
end
memory.writelong = memory.writedword
memory.registerwrite = function(addr, func)
event.onmemorywrite(func, addr)
end
memory.register = memory.registerwrite
memory.registerexec = function(addr, func)
event.onmemoryexecute(func, addr)
end
memory.registerrun = memory.registerexec
memory.registerexecute = memory.registerexec
--------------------------------------------------------------------------------------------
-- joypad table --
--------------------------------------------------------------------------------------------
-- Difference between BizHawk's joypad functions and VBA-rr's:
-- * Button names are all title case in BizHawk
-- * BizHawk also includes peripherals like the tilt sensor
joypad = {
get = function(controller)
local buttons = bizJoypad.get()
-- Translate title case button names to lowercase
-- Removing the title case ones is probably unnecessary?
buttons["start"] = buttons["Start"]
buttons["select"] = buttons["Select"]
buttons["left"] = buttons["Left"]
buttons["right"] = buttons["Right"]
buttons["up"] = buttons["Up"]
buttons["down"] = buttons["Down"]
return buttons
end,
read = joypad.get,
getdown = function(controller)
local buttons = joypad.get(controller)
for k,v in pairs(buttons) do
if not v then
buttons[k] = nil
end
end
return allButtons
end,
readdown = joypad.getdown,
getup = function(controller)
local buttons = joypad.get(controller)
for k,v in pairs(buttons) do
if v then
buttons[k] = nil
end
end
return buttons
end,
readup = joypad.getup,
set = function(controller, buttons)
local buttons = buttons or {}
-- VBA-rr's joypad.set can only press new buttons, and not change
-- a button to unpress. Remove all "false" values to preserve
-- functionality
for k,v in pairs(buttons) do
if not v then
buttons[k] = nil
end
end
bizJoypad.set(buttons)
end,
write = joypad.set
}
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment