From 70f353fbc6a80f8ee060c6c991a54dcc1ed1d2bd Mon Sep 17 00:00:00 2001 From: fatratknight Date: Thu, 7 Jan 2010 16:08:14 +0000 Subject: [PATCH] Still prototype-ish. Made things look fancier when setting control options and even has a little help text! Still missing rewind... --- output/luaScripts/Multitrack2.lua | 293 ++++++++++++++++++++---------- 1 file changed, 195 insertions(+), 98 deletions(-) diff --git a/output/luaScripts/Multitrack2.lua b/output/luaScripts/Multitrack2.lua index 19d147c4..4fa1c470 100644 --- a/output/luaScripts/Multitrack2.lua +++ b/output/luaScripts/Multitrack2.lua @@ -1,4 +1,7 @@ -local players= 2 -- You may tweak the number of players here. +-- Multitrack v2 for FCEUX by FatRatKnight + + +local players= 2 -- You may tweak the number of players here. local PlayerSwitch= "S" -- For selecting other players @@ -25,6 +28,13 @@ local key = {"right", "left", "down", "up", "L", "O", "J", "K"} local btn = {"right", "left", "down", "up", "start", "select", "B", "A"} +local shade= 0x00000080 +local white= "#FFFFFFFF" +local red= "#FF2000FF" +local green= 0x00FF00FF +local blue= 0x0040FFFF +local orange="#FFC000FF" + local plmin , plmax= 1 , 1 @@ -172,7 +182,6 @@ Draw[5],Draw[6],Draw[7],Draw[8],Draw[9]=Draw.D5,Draw.D6,Draw.D7,Draw.D8,Draw.D9 --***************************************************************************** function DrawNum(right, top, Number, color, bkgnd) --***************************************************************************** ---FatRatKnight -- Paints the input number as right-aligned. -- Returns the x position where it would paint another digit. -- It only works with integers. Rounds fractions toward zero. @@ -213,29 +222,45 @@ end --***************************************************************************** -function limits( value , low , high ) +function limits( value , low , high ) -- Expects numbers --***************************************************************************** +-- Returns value, low, or high. high is returned if value exceeds high, +-- and low is returned if value is beneath low. + return math.max(math.min(value,high),low) end --***************************************************************************** -function within( value , low , high ) +function within( value , low , high ) -- Expects numbers --***************************************************************************** +-- Returns true if value is between low and high. False otherwise. + return ( value >= low ) and ( value <= high ) end local keys, lastkeys= {}, {} --***************************************************************************** -function press(button) +function press(button) -- Expects a key --***************************************************************************** +-- Returns true or false. +-- Generally, if keys is pressed, the next loop around will set lastkeys, +-- and thus prevent returning true more than once if held. + return (keys[button] and not lastkeys[button]) end local repeater= 0 --***************************************************************************** -function pressrepeater(button) +function pressrepeater(button) -- Expects a key --***************************************************************************** +--DarkKobold & FatRatKnight +-- Returns true or false. +-- Acts much like press if you don't hold the key down. Once held long enough, +-- it will repeatedly return true. +-- Try not to call this function more than once per main loop, since I've only +-- set one repeater variable. Inside a for loop is real bad. + if keys[button] then if not lastkeys[button] or repeater >= 3 then return true @@ -250,8 +275,11 @@ function pressrepeater(button) end --***************************************************************************** -function JoyToNum(Joys) +function JoyToNum(Joys) -- Expects a table containing joypad buttons --***************************************************************************** +-- Returns a number from 0 to 255, representing button presses. +-- These numbers are the primary storage for this version of this script. + local joynum= 0 for i= 1, 8 do @@ -263,28 +291,22 @@ function JoyToNum(Joys) return joynum end -local MsgTmr, Message= 0, "Activated multitrack script. Have fun!" --***************************************************************************** -function NewMsg(text) +function ReadJoynum(input, button) -- Expects... Certain numbers! --***************************************************************************** - MsgTmr= 0 - Message= text -end - -local MsgDuration= 60 ---***************************************************************************** -function DispMsg() ---***************************************************************************** - if MsgTmr < MsgDuration then - MsgTmr= MsgTmr + 1 - gui.text(0,20,Message) - end +-- Returns true or false. True if the indicated button is pressed +-- according to the input. False otherwise. +-- Helper function + return ( bit.band(input , bit.rshift( 0x100,button )) ~= 0 ) end --***************************************************************************** function ShowOnePlayer(x,y,color,button,pl) --***************************************************************************** +-- Displays an individual button. +-- Helper function for DisplayInput. + x= x + 4*button - 3 Draw[btn[button]](x,y,color) end @@ -292,6 +314,9 @@ end --***************************************************************************** function ShowManyPlayers(x,y,color,button,pl) --***************************************************************************** +-- Displays an individual button. Uses 2x3 boxes instead of button graphics. +-- Helper function for DisplayInput. + x= x + (2*players + 1)*(button - 1) + 2*pl - 1 gui.box(x,y,x+1,y+2,0,color) end @@ -301,8 +326,11 @@ local DispX, DispY= 190, 70 local Past, Future= -12, 20 local Opaque= 1 --***************************************************************************** -function DisplayOptions(width) +function DisplayOptions(width) -- Expects width calculated by DisplayInput --***************************************************************************** +-- Returns true if Opaque is 0, as a signal to don't bother painting. +-- Separated from DisplayInput to make it clear which half is doing what. + -- Change opacity? if pressrepeater(solid) then Opaque= Opaque + 1/8 end @@ -355,12 +383,7 @@ end --***************************************************************************** function DisplayInput() --***************************************************************************** -local shade= 0x00000080 -local white= "#FFFFFFFF" -local red= "#FF2000FF" -local green= 0x00FF00FF -local blue= 0x0040FFFF -local yellow="#FFC000FF" +-- Paints on the screen the current input stored within the script's list. --Are we showing all players or just one? local HighlightButton= ShowOnePlayer @@ -411,7 +434,7 @@ local yellow="#FFC000FF" color= white elseif ReadJoynum(scanz,button) then if (i > 0) and not (ReadList[pl][button]) then - color= yellow + color= orange else color= green end @@ -426,13 +449,6 @@ local yellow="#FFC000FF" end ---***************************************************************************** -function ReadJoynum(input, button) ---***************************************************************************** - return ( bit.band(input , bit.rshift( 0x100,button )) ~= 0 ) -end - - --***************************************************************************** function SetInput() --***************************************************************************** @@ -448,7 +464,7 @@ function SetInput() if temp and ReadJoynum(temp,i) and ReadList[pl][i] then ThisInput[pl][btn[i]]= TrueSwitch[pl][i] else - ThisInput[pl][btn[i]]= FalseSwitch[pl][button] + ThisInput[pl][btn[i]]= FalseSwitch[pl][i] end end end @@ -464,86 +480,119 @@ function ApplyInput() end end +local XStart, XDiff= 30, 25 +local YStart, YDiff= 12, 15 +local Status= { {},{},{},{} } +local TargA= {FalseSwitch,TrueSwitch,ReadList,ScriptEdit} +local TrueA= { nil , "inv" , true , true } +local FalsA= { false , true , false , false } + +local BasicText= {"Activate: Lets the joypad activate input.", + "Remove: Allows the joypad to remove input.", + "List: Should the script remember button presses?", + "Keys: Allow the script-specific keys to work?"} + --***************************************************************************** function HandleOptions() --***************************************************************************** - Draw.B( 32,2,"red") - Draw.right(37,2,"white") - Draw.B( 42,2,"green") +-- Lets the user make adjustments on the various controls of this script. +-- The interface here still needs some work. Bleh. - Draw.B( 52,2,"green") - Draw.right(57,2,"white") - Draw.B( 62,2,"red") + Draw.B( XStart + XDiff ,YStart,red) + Draw.right(XStart + XDiff + 5,YStart,white) + Draw.B( XStart + XDiff +10,YStart,green) - Draw.right(72,2,"green") - Draw.right(72,6,"green") - Draw.left( 76,2,"green") - Draw.left( 76,6,"red") - Draw.down( 80,2,"red") - Draw.down( 80,6,"green") + Draw.B( XStart + XDiff*2 ,YStart,green) + Draw.right(XStart + XDiff*2+ 5,YStart,white) + Draw.B( XStart + XDiff*2+10,YStart,red) - for i= 1, 8 do - gui.text( 1, 12*i, btn[i]) + Draw.right(XStart + XDiff*3 ,YStart ,green) + Draw.right(XStart + XDiff*3 ,YStart+4,green) + Draw.left( XStart + XDiff*3+ 4,YStart ,green) + Draw.left( XStart + XDiff*3+ 4,YStart+4,red) + Draw.down( XStart + XDiff*3+ 8,YStart ,red) + Draw.down( XStart + XDiff*3+ 8,YStart+4,green) - if FalseSwitch[plmin][i] == nil then - gui.text(31, 12*i, "Yes") - else - gui.text(31, 12*i, "No") - end - if TrueSwitch[plmin][i] == "inv" then - gui.text(51, 12*i, "Yes") - else - gui.text(51, 12*i, "No") + local BtnX= math.floor((keys.xmouse- XStart+4)/XDiff) + local BtnY= math.floor((keys.ymouse- YStart-6)/YDiff) + + for i= 1, 4 do + for j= 1, 8 do + Status[i][j]= TargA[i][plmin][j] + local pl= plmin+1 + while (pl <= plmax) do + if Status[i][j] ~= TargA[i][pl][j] then + Status[i][j]= "???" + break + end + pl= pl+1 + end + if Status[i][j] == TrueA[i] then Status[i][j]= "Yes" + elseif Status[i][j] == FalsA[i] then Status[i][j]= "No" end end + end - if ReadList[plmin][i] then - gui.text(71, 12*i, "Yes") - else - gui.text(71, 12*i, "No") + if within( BtnY , 1 , 9 ) then + if within( BtnX , 1 , 4 ) then + local LowX=BtnX*XDiff +XStart -4 + local LowY=BtnY*YDiff +YStart -3 + gui.box(LowX,LowY,LowX+XDiff-2,LowY+YDiff-2,blue,blue) + gui.text(1,170,BasicText[BtnX]) end - if ScriptEdit[plmin][i] then - gui.text(91, 12*i, "Yes") - else - gui.text(91, 12*i, "No") + end + + for i= 1, 5 do + local Xpos= XStart + XDiff*i -5 + gui.line(Xpos,0,Xpos,YStart + YDiff*10,green) + end + + for j= 1, 8 do + local Ypos= YStart + YDiff*j + gui.line( 0, Ypos-4, XStart + XDiff*5, Ypos-4, green) + gui.text( 1, Ypos, btn[j]) + Draw[btn[j]](XStart + XDiff - 12, Ypos, green) + + for i= 1, 4 do + gui.text(XStart + XDiff*i, Ypos, Status[i][j]) end end + for i= 1, 4 do + gui.text(XStart + XDiff*i, YStart + YDiff*9, "All") + end + if press("leftclick") then - local BtnX= math.floor((keys.xmouse- 8)/20) - local BtnY= math.floor((keys.ymouse- 4)/12) - if within( BtnY , 1 , 8 ) then - if BtnX == 1 then - if FalseSwitch[plmin][BtnY] == nil then - FalseSwitch[plmin][BtnY]= false - else - FalseSwitch[plmin][BtnY]= nil + if within( BtnY , 1 , 9 ) then + if within( BtnX , 1 , 4 ) then + local LoopS, LoopF= 1, 8 + if within( BtnY , 1 , 8 ) then + LoopS, LoopF= BtnY, BtnY end - elseif BtnX == 2 then - if TrueSwitch[plmin][BtnY] == "inv" then - TrueSwitch[plmin][BtnY]= true - else - TrueSwitch[plmin][BtnY]= "inv" - end - elseif BtnX == 3 then - if ReadList[plmin][BtnY] then - ReadList[plmin][BtnY]= false - else - ReadList[plmin][BtnY]= true - end - elseif BtnX == 4 then - if ScriptEdit[plmin][BtnY] then - ScriptEdit[plmin][BtnY]= false - else - ScriptEdit[plmin][BtnY]= true + + local Target, TstT, TstF= TargA[BtnX], TrueA[BtnX], FalsA[BtnX] + + for pl= plmin, plmax do + for Loop= LoopS, LoopF do + if Target[plmax][LoopF] == TstT then + Target[pl][Loop]= TstF + else + Target[pl][Loop]= TstT + end + end end + end end end + end --***************************************************************************** function CatchInput() --***************************************************************************** +-- For use with registerbefore. It will get the input and paste it into +-- the input list, no questions asked. + fc= movie.framecount() for pl= 1, players do InputList[pl][fc-1]= JoyToNum(joypad.get(pl)) @@ -556,6 +605,9 @@ emu.registerbefore(CatchInput) --***************************************************************************** function OnLoad() --***************************************************************************** +-- For use with registerload. It updates ThisInput so we're not stuck with +-- junk being carried over when we load something. + fc= movie.framecount() SetInput() ApplyInput() -- Sanity versus unpaused stateload @@ -566,12 +618,14 @@ savestate.registerload(OnLoad) --***************************************************************************** function ItIsYourTurn() --***************************************************************************** +-- For use with gui.register. I need to catch input while paused! +-- Needed for a half-decent interface. + local fc_= movie.framecount() keys= input.get() if fc ~= fc_ then -- Sanity versus unusual jump (Reset cycle?) OnLoad() - fc= fc_ end if press(PlayerSwitch) then @@ -594,7 +648,7 @@ function ItIsYourTurn() if keys[opt] then gui.opacity(1) HandleOptions() - + SetInput() else if pressrepeater(Insert) then for pl= plmin, plmax do @@ -627,13 +681,56 @@ function ItIsYourTurn() ApplyInput() lastkeys= keys - gui.pixel(0,0,"clear") end gui.register(ItIsYourTurn) emu.pause() -while true do +--***************************************************************************** +while true do -- Main loop +--***************************************************************************** +-- Currently does nothing. Everything that needs to be done are in registers. +-- I could just remove this, if I can't make reason to keep it. emu.frameadvance() -end \ No newline at end of file +end + + + +--Someday, I'll implement these texts! + + + +--With both joypad options on, you have full control. +--Held buttons will toggle the script's stored input. + +--With this on-off set-up, auto-hold will not +--accidentally cancel input, such as from load state. + +--With this off-on set, you can use auto-hold to +--elegantly strip off unwanted input. + +--With both joypad options off, you ensure you can't +--accidentally change what's stored in the script. + + +--List on: Script will apply input stored within. +--This is the whole point of the script, ya know. + +--List off: Stored input is ignored. A good idea if +--you don't want the script interfering. + + +--Keys on: Script keys will toggle the button press +--for the current frame. Meant for precise edits. + +--Keys off: Script-specific keys are no longer a +--factor. Long-term control is meant for joypad! + + +--Apparently, you've selected "All players" and +--they have different options set. + + +--This is the 'All' button. Selecting this will set +--all 'Yes' or all 'No' for this particular option. \ No newline at end of file