Banned User, Player (198)
Joined: 1/6/2023
Posts: 263
Would love to see this implemented, but in the meantime does anybody know how to do it? I believe it's a .maf extension (I would have to check; edit: it's .mar) Also not sure how unlikely it is to desync, hopefully should be pretty close I'd imagine.
Published TASes: #1, #2, #3, #4, #5, #6, #7, #8, #9, #10, #11, #12 Please consider voting for me as Rookie TASer Of 2023 - Voting is in December 2023 My rule is quality TASes over quantity TASes... unless I'm bored.
Site Admin, Skilled player (1237)
Joined: 4/17/2010
Posts: 11274
Location: RU
mar is mame-rr's replay file, which is different from normal mame. But still, you can use lua to dump bizhawk inputs for a given machine during mar replay. For example here's a script that will dump bk2 inputs for a Raiden Fighters .inp movie: Download dump-inp.lua
Language: lua

fields = { { name = "|"}, { tag = ":COIN", mask = 0x1, name = "Coin 1", value = ".", mnemonic = "C" }, { tag = ":COIN", mask = 0x2, name = "Coin 2", value = ".", mnemonic = "C" }, { tag = ":SYSTEM", mask = 0x1, name = "1 Player Start", value = ".", mnemonic = "1" }, { tag = ":SYSTEM", mask = 0x2, name = "2 Players Start", value = ".", mnemonic = "2" }, { tag = ":SYSTEM", mask = 0x8, name = "Service 1", value = ".", mnemonic = "s" }, { tag = ":SYSTEM", mask = 0x4, name = "Service Mode", value = ".", mnemonic = "S" }, { name = "|"}, { tag = ":INPUTS", mask = 0x10, name = "P1 Button 1", value = ".", mnemonic = "1" }, { tag = ":INPUTS", mask = 0x20, name = "P1 Button 2", value = ".", mnemonic = "2" }, { tag = ":INPUTS", mask = 0x40, name = "P1 Button 3", value = ".", mnemonic = "3" }, { tag = ":INPUTS", mask = 0x2, name = "P1 Down", value = ".", mnemonic = "D" }, { tag = ":INPUTS", mask = 0x4, name = "P1 Left", value = ".", mnemonic = "L" }, { tag = ":INPUTS", mask = 0x8, name = "P1 Right", value = ".", mnemonic = "R" }, { tag = ":INPUTS", mask = 0x1, name = "P1 Up", value = ".", mnemonic = "U" }, { name = "|"}, { tag = ":INPUTS", mask = 0x1000, name = "P2 Button 1", value = ".", mnemonic = "1" }, { tag = ":INPUTS", mask = 0x2000, name = "P2 Button 2", value = ".", mnemonic = "2" }, { tag = ":INPUTS", mask = 0x4000, name = "P2 Button 3", value = ".", mnemonic = "3" }, { tag = ":INPUTS", mask = 0x200, name = "P2 Down", value = ".", mnemonic = "D" }, { tag = ":INPUTS", mask = 0x400, name = "P2 Left", value = ".", mnemonic = "L" }, { tag = ":INPUTS", mask = 0x800, name = "P2 Right", value = ".", mnemonic = "R" }, { tag = ":INPUTS", mask = 0x100, name = "P2 Up", value = ".", mnemonic = "U" }, { name = "|"} } local function getscreen() for k,v in pairs(manager.machine.screens) do return v end end local screen = getscreen() local curframe = -1 local function log(s, name) logfile = io.open(name, "ab") logfile:write(s) logfile:close() end function framecount() if curframe == screen:frame_number() then return end local line = "" for i = 1, #fields do local char0 = "!" if fields[i].name ~= "|" then local state = manager.machine.ioport.ports[fields[i].tag]:read() char0 = (state & fields[i].mask == 0) and fields[i].mnemonic or "_" end line = line .. char0 end log(line .. "\n", "log.txt") curframe = screen:frame_number() end emu.register_frame_done(framecount)
And here's a script that displays .mar inputs on the screen, so it can be used to similarly dump bk2 inputs: Download show-mar.lua
Language: lua

-- print(joypad.get()) ------------------------------------------------------------------------------------------- -- Ordered table iterator, allows to iterate on the natural order of the keys of a table -- ------------------------------------------------------------------------------------------- function __genOrderedIndex( t ) local orderedIndex = {} for key in pairs(t) do table.insert( orderedIndex, key ) end table.sort( orderedIndex ) return orderedIndex end function orderedNext(t, state) -- Equivalent of the next function, but returns the keys in the alphabetic -- order. We use a temporary ordered key table that is stored in the -- table being iterated. local key = nil --print("orderedNext: state = "..tostring(state) ) if state == nil then -- the first time, generate the index t.__orderedIndex = __genOrderedIndex( t ) key = t.__orderedIndex[1] else -- fetch the next value for i = 1,table.getn(t.__orderedIndex) do if t.__orderedIndex[i] == state then key = t.__orderedIndex[i+1] end end end if key then return key, t[key] end -- no more value to return, cleanup t.__orderedIndex = nil return end function orderedPairs(t) -- Equivalent of the pairs() function on tables. Allows to iterate -- in order return orderedNext, t, nil end local players = {} local other = {} function ParseInput() local input = joypad.get() local buttons = string.format("%d\n", movie.framecount()) for k, v in orderedPairs(input) do if k:find("^P") then local spacePos = k:find(" ") local playerNum = tonumber(k:sub(2, spacePos)) if playerNum ~= nil then local key = k:sub(spacePos + 1) :gsub("Button ", "") :gsub("Up", "U") :gsub("Down", "D") :gsub("Left", "L") :gsub("Right", "R") if players[playerNum] == nil then players[playerNum] = {} end players[playerNum][key] = v end else local key = k :gsub("Coin ", "C") :gsub("Service Mode", "SM") if k:find("Start") then local spacePos = k:find(" ") local playerNum = k:sub(1, spacePos - 1) key = "S"..playerNum end other[key] = v end end for k, v in pairs(players) do buttons = buttons .. "P" .. k ..": " for kk, vv in orderedPairs(v) do local value = " " if vv then value = kk end buttons = buttons .. value end buttons = buttons .. "\n" end for k, v in orderedPairs(other) do local value = " " if v then value = k end buttons = buttons .. value end gui.text(100, 0, buttons) end gui.register(ParseInput)
To figure out how a bk2 input file needs to be formatted, create a dummy bk2 for that game in bizhawk 2.9 and open its Input Log.txt file in a text editor.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.