User File #45021043588541420

Upload All User Files

#45021043588541420 - NES Rad Racer II - FCEUX TASing script

TASe_XOR_RR2.lua
894 downloads
Uploaded 2/9/2018 12:25 PM by FatRatKnight (see all 245)
A script I used, including the TAS Editor helper in there, hence the filename. (Actually, I sort of didn't want to bother renaming the file)
There's not a lot to the script. Mostly keeping track of distance, speed, sub-speed, and the music. This script is also how I measure my distance loss, to more easily compare segments where speed dips below 255 MPH.
Really the music was being tracked because I wanted to dance to it more easily. With a car.
--[[  Leeland Kirwan (FatRatKnight), 2014
Allows user input to "mix" with TAS Editor using XOR logic.
If Recording is checked, this script will do its intended job.

Tap a P1 key to toggle input. If "All" is selected, will use other player keys
for related player. If an individual player is selected, uses P1 controls. You
can hold down a key to affect multiple frames, toggling the key on each frame.

For reference, Superimpose uses OR logic, and does not allow user input to
clear stored input. A great inconvience for those wishing to use the keyboard
to toggle individual input rather than mouse.
]]--

local btnstr= {A = "A", B   = "B", select= "S", start= "T",
               up= "U", down= "D", left  = "L", right= "R"}
local btnval= {A = 0x01, B   = 0x02, select= 0x04, start= 0x08,
               up= 0x10, down= 0x20, left  = 0x40, right= 0x80}
local plval= {["1P"]= 1, ["2P"]= 2, ["3P"]= 3, ["4P"]= 4}
local OldJoy= {{},{},{},{}}
--*****************************************************************************
local function InputToggle()
--*****************************************************************************
--Needs readonly mode to work, but won't interfere too much otherwise.
--Toggles inputs recorded in TAS Editor.

    if not taseditor.engaged() then return end  -- Escape

    taseditor.clearinputchanges() -- Guessing something horrible w/o this.

    local frame= emu.framecount()

    local plSel= plval[taseditor.getrecordermode()]
    local plLow = plSel or 1   -- Get the for loop range!
    local plHigh= plSel or 4   -- Hardcoded 4 doesn't appear harmful...

    local P1joy= nil                                -- If one player, get P1.
    if plSel then P1joy= joypad.getimmediate(1) end -- Otherwise, get all.

    local changed= false  -- Flag, so I don't interfere too much
    local History= ""     -- Information for TASer in History list

    for pl= plLow, plHigh do
        local pad= taseditor.getinput(frame,pl)
        local joy= P1joy or joypad.getimmediate(pl) -- Pick out the joypad

        local mask= 0                     -- Convert messy table to numbers
        for btn,pressed in pairs(joy) do
            if pressed and not OldJoy[pl][btn] then
                mask= bit.bor(mask,btnval[btn])
                History= History .. pl .. btnstr[btn]
            end
        end

        taseditor.submitinputchange(frame,pl,bit.bxor(pad,mask))
        OldJoy[pl]= joy  -- To avoid repeated triggers
        changed= changed or (mask ~= 0) -- If the bitmask did something, apply!
    end

    if changed then taseditor.applyinputchanges(History) end
end
taseditor.registerauto(InputToggle)

--#############################################################################
--#############################################################################
--If you need some other code and other registers, I recommend them here.
--If you need the "while true do" loop, that's down below.

local R1u, R1s= memory.readbyte, memory.readbytesigned

--*****************************************************************************
local Draw= {}
--*****************************************************************************
--Coordinates is the top-left pixel of the 3x5 digit.
--Used for drawing compact, colored numbers.

local Px,Li= gui.pixel, gui.line

Draw[0]= function(x,y,c) -- ###
    Li(x  ,y  ,x  ,y+4,c)-- # #
    Li(x+2,y  ,x+2,y+4,c)-- # #
    Px(x+1,y  ,c)        -- # #
    Px(x+1,y+4,c)        -- ###
end

Draw[1]= function(x,y,c) --  #
    Li(x  ,y+4,x+2,y+4,c)-- ##
    Li(x+1,y  ,x+1,y+3,c)--  #
    Px(x  ,y+1,c)        --  #
end                      -- ###

Draw[2]= function(x,y,c) -- ###
    Li(x  ,y  ,x+2,y  ,c)--   #
    Li(x  ,y+3,x+2,y+1,c)-- ###
    Li(x  ,y+4,x+2,y+4,c)-- #
    Px(x  ,y+2,c)        -- ###
    Px(x+2,y+2,c)
end

Draw[3]= function(x,y,c) -- ###
    Li(x  ,y  ,x+1,y  ,c)--   #
    Li(x  ,y+2,x+1,y+2,c)-- ###
    Li(x  ,y+4,x+1,y+4,c)--   #
    Li(x+2,y  ,x+2,y+4,c)-- ###
end

Draw[4]= function(x,y,c) -- # #
    Li(x  ,y  ,x  ,y+2,c)-- # #
    Li(x+2,y  ,x+2,y+4,c)-- ###
    Px(x+1,y+2,c)        --   #
end                      --   #

Draw[5]= function(x,y,c) -- ###
    Li(x  ,y  ,x+2,y  ,c)-- #
    Li(x  ,y+1,x+2,y+3,c)-- ###
    Li(x  ,y+4,x+2,y+4,c)--   #
    Px(x  ,y+2,c)        -- ###
    Px(x+2,y+2,c)
end

Draw[6]= function(x,y,c) -- ###
    Li(x  ,y  ,x+2,y  ,c)-- #
    Li(x  ,y+1,x  ,y+4,c)-- ###
    Li(x+2,y+2,x+2,y+4,c)-- # #
    Px(x+1,y+2,c)        -- ###
    Px(x+1,y+4,c)
end
                         -- ###
Draw[7]= function(x,y,c) --   #
    Li(x  ,y  ,x+1,y  ,c)--  ##
    Li(x+2,y  ,x+1,y+4,c)--  #
end                      --  #

Draw[8]= function(x,y,c) -- ###
    Li(x  ,y  ,x  ,y+4,c)-- # #
    Li(x+2,y  ,x+2,y+4,c)-- ###
    Px(x+1,y  ,c)        -- # #
    Px(x+1,y+2,c)        -- ###
    Px(x+1,y+4,c)
end

Draw[9]= function(x,y,c) -- ###
    Li(x  ,y  ,x  ,y+2,c)-- # #
    Li(x+2,y  ,x+2,y+3,c)-- ###
    Li(x  ,y+4,x+2,y+4,c)--   #
    Px(x+1,y  ,c)        -- ###
    Px(x+1,y+2,c)
end

Draw[10]=function(x,y,c) --  #
    Li(x  ,y+1,x  ,y+4,c)-- # #
    Li(x+2,y+1,x+2,y+4,c)-- # #
    Px(x+1,y  ,c)        -- ###
    Px(x+1,y+3,c)        -- # #
end

Draw[11]=function(x,y,c) -- ##
    Li(x  ,y  ,x  ,y+4,c)-- # #
    Li(x+1,y  ,x+2,y+1,c)-- ##
    Li(x+1,y+4,x+2,y+3,c)-- # #
    Px(x+1,y+2,c)        -- ##
end

Draw[12]=function(x,y,c) --  #
    Li(x  ,y+1,x  ,y+3,c)-- # #
    Li(x+1,y  ,x+2,y+1,c)-- #
    Li(x+1,y+4,x+2,y+3,c)-- # #
end                      --  #

Draw[13]=function(x,y,c) -- ##
    Li(x  ,y  ,x  ,y+4,c)-- # #
    Li(x+2,y+1,x+2,y+3,c)-- # #
    Px(x+1,y  ,c)        -- # #
    Px(x+1,y+4,c)        -- ##
end

Draw[14]=function(x,y,c) -- ###
    Li(x  ,y  ,x  ,y+4,c)-- #
    Li(x+1,y  ,x+2,y  ,c)-- ##
    Li(x+1,y+4,x+2,y+4,c)-- #
    Px(x+1,y+2,c)        -- ###
end

Draw[15]=function(x,y,c) -- ###
    Li(x  ,y  ,x  ,y+4,c)-- #
    Li(x+1,y  ,x+2,y  ,c)-- ##
    Px(x+1,y+2,c)        -- #
end                      -- #

--*****************************************************************************
local function __DN_AnyBase(right, y, Number, c, bkgnd, div)
--*****************************************************************************
-- Works with any base from 2 to 16. Paints the input number.
-- Returns the x position where it would paint another digit.
-- It only works with integers. Rounds fractions toward zero.

    if div < 2 then return end  -- Prevents the function from never returning.

    local Digit= {}
    local Negative= false
    if Number < 0 then
        Number= -Number
        Negative= true
    end

    Number= math.floor(Number)
    c= c or "white"
    bkgnd= bkgnd or "clear"

    local i= 0
    if Number < 1 then
        Digit[1]= 0
        i= 1
    end

    while (Number >= 1) do
        i= i+1
        Digit[i]= Number % div
        Number= math.floor(Number/div)
    end

    if Negative then  i= i+1  end
    local x= right - i*4
    gui.box(x+1, y-1, right+1, y+5,bkgnd,bkgnd)

    i= 1
    while Draw[Digit[i]] do
        Draw[Digit[i]](right-2,y,c)
        right= right-4
        i=i+1
    end

    if Negative then
        gui.line(right, y+2,right-2,y+2,c)
        right= right-4
    end
    return right
end
--*****************************************************************************
local function DrawNum(right, y, Number, c, bkgnd)
--*****************************************************************************
-- Paints the input number as right-aligned. Decimal version.
    return __DN_AnyBase(right, y, Number, c, bkgnd, 10)
end
--*****************************************************************************
local function DrawNumx(right, y, Number, c, bkgnd)
--*****************************************************************************
-- Paints the input number as right-aligned. Hexadecimal version.
    return __DN_AnyBase(right, y, Number, c, bkgnd, 16)
end

--*****************************************************************************
local function MusicDisp() -- For sake of "dancing" to music
--*****************************************************************************
    DrawNumx(254,  9,R1u(0x070F),"white" ,"black") -- Melody
    DrawNumx(254, 16,R1u(0x0710),"white" ,"black") -- Harmony
    DrawNumx(254, 23,R1u(0x0711),"white" ,"black") -- Base
    DrawNumx(254, 30,R1u(0x0712),"white" ,"black") -- Drum-related thing
    DrawNumx(254, 37,R1u(0x0713),"white" ,"black") -- Drum-related thing

    DrawNumx(246,  9,R1u(0x071D),"green" ,"black") -- Timer
    DrawNumx(246, 16,R1u(0x071E),"green" ,"black")
    DrawNumx(246, 23,R1u(0x071F),"green" ,"black")
    DrawNumx(246, 30,R1u(0x0720),"green" ,"black")
    DrawNumx(246, 37,R1u(0x0721),"green" ,"black")

    DrawNumx(238, 30,R1u(0x0727),"orange","black") -- Drum thing hit
end

--*****************************************************************************
local function BasicHUD()
--*****************************************************************************
    DrawNum( 120,193,R1u(0x005F),"white" ,"black") -- Speed
    DrawNumx(128,193,R1u(0x0053),"grey"  ,"black") -- Speed

    DrawNum( 120,186,R1s(0x0065),"white" ,"black") -- Position
    DrawNumx(128,186,R1u(0x0064),"grey"  ,"black") -- Position

    DrawNumx(254,200,R1u(0x0066),"grey"  ,"black") -- Distance
    DrawNumx(246,200,R1u(0x0067),"white" ,"black")
    DrawNumx(246,193,R1u(0x0039),"white" ,"black")
    local d= R1u(0x0066) + (R1u(0x0067)%0x20)*0x100 + R1u(0x0039)*0x2000
    DrawNum( 254,207,d          ,"green" ,"black")

    local l= R1u(0x0044) + R1u(0x0045)*30 + R1u(0x0046)*1800
    DrawNum( 254,214,(l*255)-d-36218,"orange","black")

    MusicDisp()
end
gui.register(BasicHUD)

--                   FatRatKnight             TheSwordUser
--C1 loss:13333  0'52"4 1'41"2 2'17"7     0'52"5 1'41"6 2'18"0
--C2 loss:    0  0'38"5 1'21"4 2'04"2     0'38"6 1'21"4 2'04"3
--C3 loss:29399  0'38"7 1'29"5 2'07"0     0'38"8 1'29"6 2'07"1
--C4 loss: 4486  0'39"8 1'27"3 2'20"8     0'39"9 1'27"3 2'20"9
--C5 loss:    0  0'47"1 1'27"8 2'19"2     0'47"2 1'27"9 2'19"3
--C6 loss:39412  0'39"8 1'25"0 2'20"0     0'40"1 1'25"8 2'23"1
--C7 loss:18549  0'43"0 1'36"6 2'22"7     0'44"0 1'37"6 2'23"7
--C8 loss:17802  0'35"7 1'14"3 2'20"5     0'36"3 1'15"2 2'23"1
--rr2180

--C1 loss:11605  0'52"4 1'41'1 2'17"1     rr3125 (+ 945)

--TheSwordUser TAS: https://youtu.be/IQVnMVzukag

--Safety tip:
--  Driving in time with the music you're listening to is not recommended for
--  safety in traffic. Please, do not compromise your driving for the sake of
--  musicality. Thank you for reading this public service announcement.

--#############################################################################
--#############################################################################
-- Ugh, need this loop on the very bottom...

--*****************************************************************************
while true do
--*****************************************************************************
-- Exists to detect frame advances, and thus clear the OldJoy array.
    for i= 1, 4 do OldJoy[i]= {} end -- Retrigger keys

-- Any code that needs this loop can go here.

    emu.frameadvance()
end