I'm making a Lua script for BizHawk to automate some of the more repetitive maneuvers for Mario Kart 64. I've worked with adelikat some to get to this point and he added a multi-line text box capability for me. The GUI elements largely work but I need some help interfacing with the game. I figured I'd start this thread to solicit input.
The current script automates an optimal Mini-Turbo routine based on four pieces of input (the item input is not currently used). When I click the "Generate Input" button the resulting input is produced in the text box at the right using the N64 mnemonic format (e.g. |0|......A.....R... 127,000). I then want to be able to enter that input into the game using the "Execute Input" button. How would I do that?
Here is a screen capture of the interface:
My code is as follows:
Language: lua
-------------This Lua script is developed by Drew Weatherton for the BizHawk emulator--------------
------Purpose: Partially automate the process of executing perfect maneuvers in Mario Kart 64------
-- React to a button click
function GenerateButton()
--Variables, from Interface:
Direction = forms.gettext(DirectionDropdown);
SharpTurn = forms.ischecked(CheckboxSharpTurn);
InitialSlideFrames = tonumber(forms.gettext(TextBoxInitialSlideFrames));
GlideTurnFrames = tonumber(forms.gettext(TextBoxGlideTurnFrames));
ItemFrame = 0 -- positive number is more complicated
--------------- Mini-Turbo INPUT LOGIC -----------------------------------------------
--NOTE: I use the movie mnemonic format (e.g. |0|......A.....R... 127,000)
--Add an array to store my inputs in
FramesQueue = {}
--Initial inward-facing hop / slide
local i = 1
while i <= InitialSlideFrames do
FramesQueue[#FramesQueue+1] = "|0|......A.....R... 127,000"
i = i +1
end
--First outward-facing slide phase
local i = 1
while i <= 10 do
FramesQueue[#FramesQueue+1] = "|0|......A.....R...-127,000"
i =i +1
end
--First inward-facing slide charge, Smoke -> Yellow
if SharpTurn == true then
FramesQueue[#FramesQueue+1] = "|0|......A.....R... 127,000"
else
FramesQueue[#FramesQueue+1] = "|0|......A.....R... 039,000"
end
--Second outward-facing slide phase
local i = 1
while i <= 5 do
FramesQueue[#FramesQueue+1] = "|0|......A.....R...-127,000"
i = i +1
end
--Second inward-facing slide charge, Smoke -> Red
if SharpTurn == true then
FramesQueue[#FramesQueue+1] = "|0|......A.....R... 127,000"
else
FramesQueue[#FramesQueue+1] = "|0|......A.....R... 039,000"
end
--Glide turn after afer releasing the MT
local i = 1
while i <= GlideTurnFrames do
FramesQueue[#FramesQueue+1] = "|0|......A.........-127,000"
i = i + 1
end
---------------- THESE DO NOT YET WORK, SO THEY'RE EMPTY ----------------
--Hit Z on the requested frame to select an item
if ItemFrame > 0 then
-- FramesQueue[#ItemFrame] [10] = "Z" -- Need to figure out how to do this...
end
if Direction == Right then
-- It would be nice if this syntax worked, but it does not
--FramesQueue:gsub("-", "$")
--FramesQueue:gsub(" ", "-")
--FramesQueue:gsub("$", " ")
end
--------------------------------------------------------------------------
-- Convert the FramesQueue table
local i = 1
local tableStr = ""
while i <= #FramesQueue do
tableStr = tableStr .. FramesQueue[i] .. "\r\n"
i = i +1
end
-- Verify output to the console
console.log(tableStr)
-- Output to the Main Window
TextBox = forms.textbox(MainWindow, tableStr, 150, 700, "", 250, 40, true)
end
--Generate the User Interface
MainWindow = forms.newform(600, 850, "Mario Kart 64 Automatic Transmission")
LabelTopLeft = forms.label(MainWindow, "Choose your AutoSlide settings", 10, 10, 225, 20)
LabelTopRight = forms.label(MainWindow, "Generated Input", 250, 10, 150, 23)
--I would like to have the textbox exist before clicking "generate" but it's not working, so I've commented it out
--TextBox = forms.textbox(MainWindow, "Input queue", 150, 700, "", 250, 40, true)
------------INPUTS ARE X,Y,WIDTH, HEIGHT -- For Text Boxes: WIDTH, HEIGHT, "signed", X, Y-------
--Manuever Dropdown
LabelDirection = forms.label(MainWindow, "facing slide", 60, 33, 75, 20)
a = { }
a[0] = "Right"
a[1] = "Left"
DirectionDropdown = forms.dropdown(MainWindow, a, 10, 30, 50, 20);
--Sharp Turn?
CheckboxSharpTurn = forms.checkbox(MainWindow, "Sharp Turn?", 20, 70)
-- Initial slide frames entry
LabelInitialSlideFrames = forms.label(MainWindow, "Frames to slide initially", 45, 98, 200, 23)
TextBoxInitialSlideFrames = forms.textbox(MainWindow, "9", 20, 20, "UNSIGNED", 20, 95)
--Glide Turn Frames
LabelGlideTurnFrames = forms.label(MainWindow, "Frames to glide turn", 45, 125, 200, 23)
TextBoxGlideTurnFrames = forms.textbox(MainWindow, "3", 20, 20, "UNSIGNED", 20, 122)
--Item Frame
LabelItemFrame = forms.label(MainWindow, "Frame to hit Z for item", 45, 150, 200, 23)
TextBoxItemFrame = forms.textbox(MainWindow, "0", 20, 20, "UNSIGNED", 20, 147)
--Create Input
GenerateButton = forms.button(MainWindow, "Generate Input", GenerateButton, 10, 180, 100, 23)
ExecuteButton = forms.button(MainWindow, "Execute Input", GenerateButton, 10, 210, 100, 23)
while true do
emu.frameadvance();
end