TASEmulators / BizHawk

BizHawk is a multi-system emulator written in C#. BizHawk provides nice features for casual gamers such as full screen, and joypad support in addition to full rerecording and debugging tools for all system cores.
http://tasvideos.org/BizHawk.html
Other
2.15k stars 380 forks source link

[Lua request] Read bytes as string (memory.read_bytes) #3035

Open gocha opened 2 years ago

gocha commented 2 years ago

I need a lua function that reads binary data from memory as a string. I would like to get the entire memory into a variable and do some complex pattern matching and file extraction.

datastring = memory.read_bytes(0, 0x200000, "WRAM")
-- Use `string.find()` to find a specific piece of data. Save the found data to a file. etc.

BizHawk provides memory.read_bytes_as_array(), but it does not allow me to use the convenience functions in string library to the result. Also, if I try to convert a 2MB table to a string, like string.char(unpack(tbl)), it will fail because it has too many arguments.

Lua string can handle data containing \x00. The standard file:read() and file:write() also handle strings when reading or writing binary data. I think the behavior of returning a sequence of bytes as a string makes sense.

I'm using BizHawk 2.7.

How to implement this?

Actually, I tried to implement this myself and failed. Since the return value of the function is not text, I think I should construct and return a Lua string without converting it to a .NET string. However, since I am not familiar with NLua, I could not figure out how to define such a function.

With your help, I may be able to create a pull request myself.

Thanks for reading.

gocha commented 2 years ago

Workaround

For now, we can use the workaround with table.concat(), although it may be a bit slow.

function byte_array_to_string(a)
    t = {}
    for _, v in ipairs(a) do
        table.insert(t, string.char(v))
    end
    return table.concat(t)
end

name = "MainRAM"
size = memory.getmemorydomainsize(name)
data_array = memory.read_bytes_as_array(0, size, name)
data = byte_array_to_string(data_array)

file, errmsg = io.open(name .. ".bin", "wb")
if file then
    file:write(data)
    file:close()
else
    print(errmsg)
end

Programming in Lua : 11.6 – String Buffers

YoshiRulz commented 2 years ago

I'm going to suggest that your use case would be better served by an external tool.

gocha commented 2 years ago

I won't drop my request for Lua improvements, but the information on ExternalTools looks useful to me. Thank you for letting me know. ♥

YoshiRulz commented 1 year ago

Need to revisit this for KeraLua.