BizHawk Emulator Lua Scripting for Debug
Users browsing this thread: 1 Guest(s)

BizHawk is a multi-platform emulator that the TAS community likes to use for its recording support and Lua scripting. Recently, I've been experimenting with its embeded mupen64plus emulator and Lua scripting for debugging purposes and have found it quite useful. I am attaching some basic Lua scripts that I've written for SM64. It has even worked with the few SM64 hacks I've tested with it.

​SM64_OSD.lua:
This script demonstrates basic memory reading and gui.print() usage for displaying the status of Mario, levels, camera, terrain to screen.
[Image: SmpJ8EX.png]

​SM64_objects.lua:
This script uses button capture to cycle through objects and parses and displays the information about them.
Controls:
* DPad Right/Left: next/prev object
* DPad Down/Up: cycle through hex display: 0x000, 0x130, Off
[Image: sRJ6ZDW.gif]

​SM64_form.lua:
This Lua script creates a custom user form. It has a button to find the Koopa object and then 3 fields to enter floats into for the X,Y,Z scaling object parameters. This could definitely be expanded to implement something like Bowser64 or any custom fields.
[Image: cHkutOC.gif]

The BizHawk Lua API is quite extensive. There are many features that I haven't touched, so please check it out! Please feel free to post any scripts you come up with here.


Attached Files
Size: 9.06 KB / Downloads: 216 .zip   BizHawk_Lua_SM64.zip


Very cool stuff! I noticed in the documentation that BizHawk's Lua API provides hooks for CPU read/write/execute events, which is awesome, but I wasn't able to get them working with the N64 emulator. I wrote a small script to test the functions here http://pastebin.com/raw/fHS5fTJk. The console spits out "Mupen64Plus does not implement memory execute callbacks" when using the onmemoryexecute hook, and when using the onmemoryread/write hooks, the debugger window indicates that breakpoints have been added but they don't seem to trigger anything when they should. I was a little disheartened that these functions in particular don't work, but having built-in scripting for reading and modifying memory is very nice nonetheless. Never knew something like this was available for N64 emulation.
(This post was last modified: 24-08-2016, 08:46 AM by shygoo.)
My threads are now being maintained here

(24-08-2016, 08:45 AM)shygoo Wrote: Very cool stuff! I noticed in the documentation that BizHawk's Lua API provides hooks for CPU read/write/execute events, which is awesome, but I wasn't able to get them working with the N64 emulator. I wrote a small script to test the functions here http://pastebin.com/raw/fHS5fTJk. The console spits out "Mupen64Plus does not implement memory execute callbacks" when using the onmemoryexecute hook, and when using the onmemoryread/write hooks, the debugger window indicates that breakpoints have been added but they don't seem to trigger anything when they should. I was a little disheartened that these functions in particular don't work, but having built-in scripting for reading and modifying memory is very nice nonetheless. Never knew something like this was available for N64 emulation.


Nice, I hadn't read about those 'event' APIs yet. It would be great if any of those callbacks worked. I took your code and ran my own tests with the same outcomes. I even tried omitting the address because "If no address is given, it will attach to every memory read/write" but that didn't seem to fire either.

According to the Issue tracker Request: add N64 debugging support, the N64 onmemoryread and onmemorywrite may work. I dug into the code a bit and see the hooks there as well: N64.IDebuggable.cs Lines 76-139 and methods in mupen64plusCoreApi.cs native interface, but haven't traced it all the way back into mupen64plus core. There might be some flag or method call needed to get mupen64plus to enable these breakpoints.

Edit: I had a chat with the BizHawk devs and apparently 1.11.6 doesn't support all the event features (like onmemoryexecute) and all the memory events only work if mupen is configured to use the Interpreter (or Pure Interpreter) core. You can grab the latest dev build from AppVeyor and configure the "N64->Plugins->Global->Core Type". Once setup, then all read/write/exec trigger, however, it grinds emulation speed to a halt (e.g., I get 2 fps with all three enabled):

[Image: VEDNrEn.png]

Code:
​local MARIO_Y     = 0x8033B1B0 -- mario y position
local MARIO_BEH_A = 0x802CB1C0 -- one of mario's behavior routines

local count_r = 0
local count_w = 0
local count_e = 0

-- callbacks
function memReadCallback()
  count_r = count_r + 1
end

function memWriteCallback()
  count_w = count_w + 1
end

function memExecCallback()
  count_e = count_e + 1
end

local mario_y_r = event.onmemoryread(memReadCallback, MARIO_Y)
local mario_y_w = event.onmemorywrite(memWriteCallback, MARIO_Y)
local mario_beh_a_x = event.onmemoryexecute(memExecCallback, MARIO_BEH_A)

while true do
  gui.text(0, 14, "R: " .. count_r .. " W: " .. count_w .. " E: " .. count_e)
  emu.frameadvance()
end
(This post was last modified: 25-08-2016, 07:00 PM by queueRAM. Edit Reason: BizHawk updates )

(25-08-2016, 02:42 PM)queueRAM Wrote:
(24-08-2016, 08:45 AM)shygoo Wrote:
Very cool stuff! I noticed in the documentation that BizHawk's Lua API provides hooks for CPU read/write/execute events, which is awesome, but I wasn't able to get them working with the N64 emulator. I wrote a small script to test the functions here http://pastebin.com/raw/fHS5fTJk. The console spits out "Mupen64Plus does not implement memory execute callbacks" when using the onmemoryexecute hook, and when using the onmemoryread/write hooks, the debugger window indicates that breakpoints have been added but they don't seem to trigger anything when they should. I was a little disheartened that these functions in particular don't work, but having built-in scripting for reading and modifying memory is very nice nonetheless. Never knew something like this was available for N64 emulation.


Nice, I hadn't read about those 'event' APIs yet. It would be great if any of those callbacks worked. I took your code and ran my own tests with the same outcomes. I even tried omitting the address because "If no address is given, it will attach to every memory read/write" but that didn't seem to fire either.

According to the Issue tracker Request: add N64 debugging support, the N64 onmemoryread and onmemorywrite may work. I dug into the code a bit and see the hooks there as well: N64.IDebuggable.cs Lines 76-139 and methods in mupen64plusCoreApi.cs native interface, but haven't traced it all the way back into mupen64plus core. There might be some flag or method call needed to get mupen64plus to enable these breakpoints.

Edit: I had a chat with the BizHawk devs and apparently 1.11.6 doesn't support all the event features (like onmemoryexecute) and all the memory events only work if mupen is configured to use the Interpreter (or Pure Interpreter) core. You can grab the latest dev build from AppVeyor and configure the "N64->Plugins->Global->Core Type". Once setup, then all read/write/exec trigger, however, it grinds emulation speed to a halt (e.g., I get 2 fps with all three enabled):

[Image: VEDNrEn.png]

Code:
​local MARIO_Y     = 0x8033B1B0 -- mario y position
local MARIO_BEH_A = 0x802CB1C0 -- one of mario's behavior routines

local count_r = 0
local count_w = 0
local count_e = 0

-- callbacks
function memReadCallback()
  count_r = count_r + 1
end

function memWriteCallback()
  count_w = count_w + 1
end

function memExecCallback()
  count_e = count_e + 1
end

local mario_y_r = event.onmemoryread(memReadCallback, MARIO_Y)
local mario_y_w = event.onmemorywrite(memWriteCallback, MARIO_Y)
local mario_beh_a_x = event.onmemoryexecute(memExecCallback, MARIO_BEH_A)

while true do
  gui.text(0, 14, "R: " .. count_r .. " W: " .. count_w .. " E: " .. count_e)
  emu.frameadvance()
end


Hey guys, is this thread still alive? I've been trying to figure out how to find the ram addresses for objects in Mario Kart 64. I'm using the Bizhawk emulator. Any tips? I'm working on a project to implement a genetic algorithm to play a game, and I think there's a chance it will work with this game, but I need some way to read what is in from of the user.

(04-10-2016, 06:13 AM)Nick Nelson Wrote: Hey guys, is this thread still alive? I've been trying to figure out how to find the ram addresses for objects in Mario Kart 64. I'm using the Bizhawk emulator. Any tips? I'm working on a project to implement a genetic algorithm to play a game, and I think there's a chance it will work with this game, but I need some way to read what is in from of the user.


For Mario Kart 64, you might be interested in my object notes over in the Mario Kart 64 Hacking thread. Weatherton, one of the MK64 TAS folks, also has some really nice Lua scripts put together for BizHawk which might be of interest: https://github.com/weatherton/BizHawkMarioKart64

[Image: 9pF7Zv4.png]

Thanks! I think this stuff will be useful. In Weatherton's code the addresses for rival1 and rival2 don't return anything. Is it possible that these addresses can vary?

(04-10-2016, 07:50 PM)Nick Nelson Wrote: Thanks! I think this stuff will be useful. In Weatherton's code the addresses for rival1 and rival2 don't return anything. Is it possible that these addresses can vary?


Assuming you're on the US version of the game you should see the rivals change from "Mario" to the set rivals after you select your character. The addresses might be slightly different in the other versions of the game.. haven't actually checked though

Huh, that Saturn port of SM64 looks great.

All joking aside this is actually really neat. Hope to see more in the future!
Who you callin pinhead

BizHawk Emulator Lua Scripting for Debug
Users browsing this thread: 1 Guest(s)