Skip to content
This repository has been archived by the owner on Sep 6, 2022. It is now read-only.

Commit

Permalink
InfoDisplay updates automatically, script deactivates when not in a r…
Browse files Browse the repository at this point in the history
…ace(not working properly yet)
  • Loading branch information
SwareJonge committed Oct 21, 2019
1 parent ec92423 commit 5f0b2aa
Show file tree
Hide file tree
Showing 19 changed files with 982 additions and 400 deletions.
3 changes: 3 additions & 0 deletions Data/MKW_Pointers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ local function getPlayerBasePointer()
local offset3 = 0x10
local offset4 = 0x10
local offset5 = 0x0
if ReadValue32(pointer) == 0 then
return 0
end
local address1 = GetPointerNormal(pointer)
local address2 = GetPointerNormal(address1 + offset1)
local address3 = GetPointerNormal(address2 + offset2)
Expand Down
68 changes: 46 additions & 22 deletions Data/MKW_core.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ local function getGameID()
end
core.getGameID = getGameID

--local function checkIfInRace(x)
-- if x >= 0x80000000 and x < 0x90000000 and x ~= nil then
-- return true
--else return false
--end
--end
core.checkIfInRace = checkIfInRace

local function getPos()
local pointer
if getGameID() == "RMCP01" then pointer = 0x9C2EF8
Expand Down Expand Up @@ -59,49 +67,52 @@ local function getPrevPos()
end
core.getPrevPos = getPrevPos


local function getSpd()
local PrevXpos = getPrevPos().X
local PrevYpos = getPrevPos().Y
local PrevZpos = getPrevPos().Z
local Xpos = getPos().X
local Ypos = getPos().Y
local Zpos = getPos().Z
return {X = (Xpos - PrevXpos),
Y = (Ypos - PrevYpos),
Z = (Zpos - PrevZpos),
XZ = math.sqrt(((Xpos - PrevXpos)^2) + (Zpos - PrevZpos)^2),
XYZ = math.sqrt(((Xpos - PrevXpos)^2) + ((Ypos - PrevYpos)^2) + (Zpos - PrevZpos)^2)}
return {X = (Xpos - PrevXpos), Y = (Ypos - PrevYpos), Z = (Zpos - PrevZpos), XZ = math.sqrt(((Xpos - PrevXpos)^2) + (Zpos - PrevZpos)^2), XYZ = math.sqrt(((Xpos - PrevXpos)^2) + ((Ypos - PrevYpos)^2) + (Zpos - PrevZpos)^2)}
end
core.getSpd = getSpd

local function getInput()
local pointer
local pointer = 0
if getGameID() == "RMCP01" then pointer = 0x42E324
elseif getGameID() == "RMCE01" then pointer = 0x429FA4
elseif getGameID() == "RMCJ01" then pointer = 0x42DCA4
elseif getGameID() == "RMCJ01" then pointer = 0x42DC14
elseif getGameID() == "RMCK01" then pointer = 0x41C2B4
end
if ReadValue32(pointer) >= 0x80000000 then
local offset = 0x2840
local address = GetPointerNormal(pointer)
return {
ABLR = ReadValue8(address + offset + 0x1),
X = ReadValue8(address + offset + 0xC),
Y = ReadValue8(address + offset + 0xD),
DPAD = ReadValue8(address + offset + 0xF)}
else return {ABLR = 0, X = 0, Y = 0, DPAD = 0}
end
local offset = 0x2840
local address = GetPointerNormal(pointer)
if ReadValue32(pointer) == 0 then
return {ABLR = 0, X = 0, Y = 0, DPAD = 0}
end
return {
ABLR = ReadValue8(address + offset + 0x1),
X = ReadValue8(address + offset + 0xC),
Y = ReadValue8(address + offset + 0xD),
DPAD = ReadValue8(address + offset + 0xF)}
end
core.getInput = getInput

local function getDistGhost()
return {X = (32797 - getPos().X), Y = (5133 - getPos().Y), Z = (974 - getPos().Z)}
local function PosToAngle()
local Xspd = getSpd().X
if getSpd().X == 0 then Xspd = math.pi / 2
end
local angle = math.atan(getSpd().Z * Xspd)
local finalAngle = angle * 65536 % 360
local sine = math.sin(finalAngle)
return {A = finalAngle, S = sine}
end
core.getDistGhost = getDistGhost
core.PosToAngle = PosToAngle

--FrameCounter in Race
local function getFrameOfInput()
local frameaddress
local frameaddress = 0x0
if getGameID() == "RMCP01" then frameaddress = 0x9C38C2
elseif getGameID() == "RMCE01" then frameaddress = 0x9BF0BA
elseif getGameID() == "RMCJ01" then frameaddress = 0x9C2922
Expand Down Expand Up @@ -152,13 +163,26 @@ local function calculateEuler()
local qx2 = qx*qx
local qy2 = qy*qy
local qz2 = qz*qz
local test= qx*qy + qz*qw
if (test > 0.499) then
Yvalue = 360/math.pi*math_atan2(qx,qw)
Zvalue = 90
Xvalue = 0
return {X = Xvalue, Y = Yvalue, Z = Zvalue}
end
if (test < -0.499) then
Yvalue = -360/math.pi*math_atan2(qx,qw)
Zvalue = -90
Xvalue = 0
return {X = Xvalue, Y = Yvalue, Z = Zvalue}
end
local h = math_atan2(2*qy*qw-2*qx*qz, 1-2*qy2-2*qz2)
local a = math.asin(2*qx*qy + 2*qz*qw)
local b = math_atan2(2*qx*qw-2*qy*qz, 1-2*qx2-2*qz2)
Yvalue = (h*180/math.pi)
Zvalue = (a*180/math.pi)
Xvalue = (b*180/math.pi)
return {Y = (Yvalue + 90) %360, X = (Xvalue - 90) %360, Z = Zvalue}
return {X = (Xvalue - 90) % 360, Y = (Yvalue - 90) % 360, Z = Zvalue}
end
core.calculateEuler = calculateEuler

Expand Down
178 changes: 178 additions & 0 deletions Data/MKW_ghost_core.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
local core = require "MKW_core"

local ghost_core = {}

local function getGhostAddressPointer()
local gameID = core.getGameID()
local baseAddress = 0x0

if gameID == "RMCE01" then baseAddress = 0x9B8F70
elseif gameID == "RMCP01" then baseAddress = 0x9BD730
elseif gameID == "RMCJ01" then baseAddress = 0x9BC790
elseif gameID == "RMCK01" then baseAddress = 0x9ABD70
end


local offset1 = 0x1FC
local offset2 = 0x4
local address1 = GetPointerNormal(baseAddress)
local address2 = GetPointerNormal(address1 + offset1)
local address3 = GetPointerNormal(address2 + offset2)

local offsetFaceButton = 0x94
local addressF1 = GetPointerNormal(address3 + offsetFaceButton)
local offsetDirectionInput = 0x98
local addressD1 = GetPointerNormal(address3 + offsetDirectionInput)
local offsetTrickInput = 0x9C
local addressT1 = GetPointerNormal(address3 + offsetTrickInput)

local offset3 = 0x4

return addressF1+offset3, addressD1+offset3, addressT1+offset3
end
ghost_core.getGhostAddressPointer = getGhostAddressPointer

local function getGhostAddresses()
local addressF1, addressD1, addressT1 = getGhostAddressPointer()

local addressF2 = GetPointerNormal(addressF1)
local addressD2 = GetPointerNormal(addressD1)
local addressT2 = GetPointerNormal(addressT1)

return addressF2, addressD2, addressT2
end
ghost_core.getGhostAddresses = getGhostAddresses


-- ###############################

local function maskFaceButton(aButton, bButton, lButton, prevMask)
local x8Mask = 0x0
if bButton == 1 and (prevMask == 0x1 or prevMask == 0x5 or prevMask == 0xB or prevMask == 0xF) then
x8Mask = 0x8
end
return aButton * 0x1 + bButton * 0x2 + lButton * 0x4 + x8Mask
end
ghost_core.maskFaceButton = maskFaceButton

function maskDirectionInput(horizontalInput, verticalInput)
return (horizontalInput << 4) + verticalInput
end
ghost_core.maskDirectionInput = maskDirectionInput

function maskTrickInput(trickInput)
return trickInput << 4
end
ghost_core.maskTrickInput = maskTrickInput

-- ###############################

local function writeRKGData(writeAddress, inputData, durationData)
WriteValue8(writeAddress, inputData)
WriteValue8(writeAddress + 0x1, durationData)

return writeAddress + 0x2
end

-- ###############################

function writeInputsIntoRKG(input_ghost)
local currentAddress = 0x0

local addressFaceButton, addressDirectionInput, addressTrickInput = getGhostAddresses()
local addressFaceButtonPointer, addressDirectionInputPointer, addressTrickInputPointer = getGhostAddressPointer()

local prevInput = maskFaceButton(input_ghost[1][1], input_ghost[1][2], input_ghost[1][3], 0x0)
local amountCurrentFrames = 0x0

currentAddress = addressFaceButton

for _, inputs in ipairs(input_ghost) do
local currentInput = maskFaceButton(inputs[1], inputs[2], inputs[3], prevInput)
if prevInput ~= currentInput then
currentAddress = writeRKGData(currentAddress, prevInput, amountCurrentFrames)

prevInput = currentInput
amountCurrentFrames = 0x1
else
if amountCurrentFrames >= 0xFF then
currentAddress = writeRKGData(currentAddress, prevInput, amountCurrentFrames)

prevInput = currentInput
amountCurrentFrames = 0x1
else
amountCurrentFrames = amountCurrentFrames + 1
end
end
end

currentAddress = writeRKGData(currentAddress, prevInput, amountCurrentFrames)

WriteValue32(addressDirectionInputPointer, currentAddress + 0x80000000)

prevInput = maskDirectionInput(input_ghost[1][4], input_ghost[1][5])
amountCurrentFrames = 0x0

for _, inputs in ipairs(input_ghost) do
local currentInput = maskDirectionInput(inputs[4], inputs[5])
if prevInput ~= currentInput then
currentAddress = writeRKGData(currentAddress, prevInput, amountCurrentFrames)

prevInput = currentInput
amountCurrentFrames = 0x1
else
if amountCurrentFrames >= 0xFF then
currentAddress = writeRKGData(currentAddress, prevInput, amountCurrentFrames)

prevInput = currentInput
amountCurrentFrames = 0x1
else
amountCurrentFrames = amountCurrentFrames + 1
end
end
end

currentAddress = writeRKGData(currentAddress, prevInput, amountCurrentFrames)

WriteValue32(addressTrickInputPointer, currentAddress + 0x80000000)

prevInput = maskTrickInput(input_ghost[1][6])
amountCurrentFrames = 0x0

for _, inputs in ipairs(input_ghost) do
local currentInput = maskTrickInput(inputs[6])
if prevInput ~= currentInput then
local inputData = prevInput + math.floor(amountCurrentFrames / 0x100)

currentAddress = writeRKGData(currentAddress, inputData, amountCurrentFrames % 0x100)

prevInput = currentInput
amountCurrentFrames = 0x1
else
if amountCurrentFrames >= 0xFFF then
local inputData = prevInput + math.floor(amountCurrentFrames / 0x100)

currentAddress = writeRKGData(currentAddress, inputData, amountCurrentFrames % 0x100)

prevInput = currentInput
amountCurrentFrames = 0x1
else
amountCurrentFrames = amountCurrentFrames + 1
end
end
end

local inputData = prevInput + math.floor(amountCurrentFrames / 0x100)
currentAddress = writeRKGData(currentAddress, inputData, amountCurrentFrames % 0x100)

endOfFile = addressFaceButton + 0x2774
while currentAddress < endOfFile do
WriteValue16(currentAddress, 0x0)
currentAddress = currentAddress + 0x2
end
end
ghost_core.writeInputsIntoRKG = writeInputsIntoRKG

-- ###############################

return ghost_core
79 changes: 79 additions & 0 deletions Data/READMII_TAS_Toolkit.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
IMPORTANT information is marked and suggest to be the minimum to read.

This is a compilation of multiple lua scripts for Swarejonge's custom LUA Dolphin Version.

This includes scripts to run the players inputs using an input file and manipulate the racing ghost using an input file, effectively replacing TAS Code.
There is also a script of storing the raw ghost data as both the ghost input file and the runners input file.

This is using the latest MKW_core.lua version

How to use:
-Download Swarejonge's custom LUA Dolphin Version
-Merge this folder with the custom LUA Dolphin version, so that the folder "Scripts" gets merged and MKW_core.lua gets replaced
-Run the Scripts with "Tools > Execute Script"

Credits:
-Swarejonge for his custom Dolphin version and his provided MKW_core.lua
-Star and Swarejonge for help with specific pointers in memory data
-Malleo and TASPlasma for their previous input reader scripts


IMPORTANT: Using MKW_ghost_store_inputs_runner.lua WILL OVERWRITE BOTH RUNNER AND GHOST INPUT FILES. Prepare copies of them if you want to store inputs of a new ghost.
IMPORTANT: MKW_TAS_Toolkit_active_reload.lua RELOADS BOTH INPUT FILES ON EVERY FRAME. This will cause HUGE FRAMEDROPS for running Dolphin normally. ONLY USE WHILE TASING.

Executable Files:
~/Scripts/MKW_GHOST_store_inputs.lua --stores the ghosts input from the internal mkw memory into the ~/mkw_input_reader_ghost.lua input file
~/Scripts/MKW_GHOST_store_inputs_runner.lua --stores the ghosts input from the internal mkw memory into BOTH ~/mkw_input_reader_ghost.lua AND ~/mkw_input_reader_runner.lua input files
~/Scripts/MKW_TAS_Toolkit.lua --when loaded, uses the currently saved ~/mkw_input_reader_ghost.lua AND ~/mkw_input_reader_runner.lua input files to influence the runners and ghosts inputs, savestate compatible
~/Scripts/MKW_TAS_Toolkit_active_reload.lua --when loaded, uses ~/mkw_input_reader_ghost.lua AND ~/mkw_input_reader_runner.lua input files to influence the runners and ghosts inputs, savestate compatible
--updates with changing the files in realtime, CAUSES HEAVY FRAMEDROPS, ONLY USE WHILE TASING
~/Scripts/MKW_TAS_Toolkit_input_writer.lua --writes inputs made with Controller/TAS-Input into the ~/mkw_input_reader_runner.lua input file, saves file when script is canceled, savestate compatible
--keeps old inputs alive, if they are not overwritten, fills gaps between frames with the basic input of no button pressed
~/Scripts/MKW_TAS_Toolkit_rewrite.lua --rewrites the ~/mkw_input_reader_runner.lua input file to match the commentated frames
--can be run while MKW_TAS_Toolkit_active_reload is active, if you pause the game, start the script and then run the next frame

Helper Files:
~/MKW_core.lua --latest MKW_core.lua version, current standard
~/MKW_ghost_core.lua --used for pointer finding in all ghost based lua scripts
--includes basic function to overwrite ghost data using an input list

Input Files:
~/mkw_input_reader_ghost.lua --representates the inputs of the ghost
~/mkw_input_reader_runner.lua --representates the inputs of the runner

Test Files:
~/Test_Scripts/TEST_MKW_GHOST_overwrite_data_copy.lua --converts the ~/mkw_input_reader_ghost.lua input file into binary RKG data saved in the ~/mkw_input_reader_ghost_raw.rrkg file (Raw RKG, does not include header or checksum)
--made to compare converted inputs with the actual RKG file

Deprecated/Deleted Files:
~/Scripts/MKW_ghost_overwrite.lua --overwrite the ghost in the internal mkw memory using the ~/mkw_input_reader_ghost.lua input file, DOES NOT affect save data
--effectively replaced by MKW_TAS_Toolkit.lua


-----------------------
versions:

v1.2
-fixed ~/MKW_ghost_core.lua RKG face button masking
-fixed ~/Scripts/MKW_TAS_Toolkit.lua and ~/Scripts/MKW_TAS_Toolkit_active_reload.lua to not crash when frame does not exist
-added ~/Scripts/MKW_TAS_Toolkit_rewrite.lua for a quality of life change
-added ~/Test_Scripts/TEST_MKW_GHOST_overwrite_data_copy.lua to write raw RKG data into a file
-not mentioned v1.1 changes:
-added ~/MKW_Pointers.lua for some global race data pointers__by Swarejonge
-updated ~/MKW_ghost_core.lua for ghost data pointers of other ISO-regions__by Swarejonge

v1.1
-swapped position of horizontal and vertical inputs
-updated ~/MKW_core.lua to match latest version__by Swarejonge
-updated ~/Scripts/MKW_GHOST_store_inputs.lua and ~/Scripts/MKW_GHOST_store_inputs_runner.lua to be able to convert *.RKG files corrupted by "Ghost always saves"-code
-updated ~/MKW_ghost_core.lua to refactor the ghost overwriting function
-updated ~/Scripts/MKW_TAS_Toolkit.lua and ~/Scripts/MKW_TAS_Toolkit_active_reload.lua:
-ghost and/or runner files will now only be read, if they are existing
-deleting the ~/mkw_input_reader_runner.lua will cause to only replace ghost in the memory, effectively replacing the deprecated ~/Scripts/MKW_ghost_overwrite.lua
-deleting the ~/mkw_input_reader_ghost.lua will cause to only the runner inputs to be run
-deleting both input files will effectively do nothing
-updated ~/Scripts/MKW_TAS_Toolkit_active_reload.lua to surely only reload, when a savestate or new frame is loaded
-added ~/Scripts/MKW_TAS_Toolkit_input_writer.lua as a new support for TASing with Controller/TAS-Input

v1
-initial release
Loading

0 comments on commit 5f0b2aa

Please sign in to comment.