Here's my Work-In-Progress script. Some stuff I planned is partly implemented but not working. There are ways to switch options around in massive quantities, but only a few of them can be switched individually at this moment.
I'm using a way to handle input similar to what I did
in this subtitles script. It works as a repeater for certain functions just fine.
This is yet another rewrite of my Multitrack script. Hopefully, I've organized things even better than before. The rewrite is incomplete, but keeping it private wouldn't generate any interest in it (
not as though posting it publicly here did any better...), so here it is now:
Download Multitrack_DeSmuME.luaLanguage: lua
--Multitracker v3
--Wow, I rewrite this script a LOT
local PresetSwitch= "E" -- Switch between a few different presets
--Display
local solid= "numpad*" -- Make the display less
local clear= "numpad/" -- or more transparant.
local DispUp= "numpad8"
local DispDn= "numpad2" -- For moving the
local DispRt= "numpad6" -- display around.
local DispLf= "numpad4"
local MoreFutr= "numpad3"
local LessFutr= "numpad9" -- These will determine
local MorePast= "numpad7" -- how many frames you
local LessPast= "numpad1" -- want to display.
local ResetFP= "numpad5"
local opt= "numpad+" -- For changing control options
local Insert= "A"
local Delete= "S"
local BackupReadSwitch= "R" -- Revert to backup copy
local BackupWriteSwitch= "F" -- Copy input into backup
local BackupDisplaySwitch= "V"
local MessageDuration= 400
local OptionPreset= {
{name= "Edit Mode",
DispX= 190, DispY= -70, Past= -12, Future= 12, opaque= 1,
TJ= true , FJ= true , RJ= true , SJ= true ,
CS= true , RS= true , SS= true , StyP= -30, StyF= 30},
{name= "Standby",
DispX= 150, DispY= -10, Past= 0, Future= 0, opaque= 0,
TJ= true , FJ= true , RJ= false, SJ= false,
CS= true , RS= false, SS= false, StyP= 0, StyF= 0},
{name= "Joypad Overwrite",
DispX= 190, DispY= -90, Past= -12, Future= 16, opaque= 1,
TJ= true , FJ= true , RJ= false, SJ= false,
CS= true , RS= true , SS= true , StyP= -60, StyF= 60},
{name= "Stylus Overwrite",
DispX= 190, DispY= -70, Past= -6, Future= 6, opaque= 1,
TJ= true , FJ= true , RJ= true , SJ= true ,
CS= true , RS= false, SS= false, StyP= -10, StyF= 10}
}
local shade= 0x00000080
local white= 0xFFFFFFFF
local red= 0xFF2000FF
local green= 0x00FF00FF
local mint= 0xC0FFC0FF
local blue= 0x0040FFFF
local orange=0xFFC000FF
local yellow=0xFFFF00FF
local cyan= 0x00FFFFFF
local purple=0x8020FFFF
local redish=0xC00000FF
local ltgrey=0xC0C0C0FF
local Clr= {
white ,red ,orange,green,
white ,red ,orange,green,
mint ,purple,yellow,cyan,
ltgrey,redish,orange,green, --Watermark
ltgrey,redish,orange,green,
mint ,purple,yellow,cyan
}
local WtrInterval= 10
--#############################################################################
--#############################################################################
--Global necessities
local NULLTBL= {} -- I prefer not constructing a new table every time.
local function NULLFN() end --You never know when you need to call nothing.
local btn={"left","up","right","down","A","B","X","Y","L","R","start","select",
"lid","debug"}
local ThisInput= {}
local ThisStylus={}
local JoypadList= {}
local StylusList= {}
local BackupList= {} --Joypad only
local ShowBackup= true
local BackupOverride= false
local JoypadInsert= 0
local JoypadBuffer= {}
local StylusInsert= 0
local StylusBuffer= {}
--local CopyBuffer_J= {}
--local CupyBuffer_S= {}
local TrueSwitch, FalseSwitch= {},{}
local ReadJoy, StickyJoy= {},{}
local DispX,DispY , Past,Future , StyP,StyF , Opaque
local ControlStylus, ReadStylus, StickyStylus
local WID , HGT= 256 , 192
local fc, lastfc= 0, 0
--*****************************************************************************
local function UpdateFC() lastfc= fc; fc= movie.framecount() end
--*****************************************************************************
--My global "clock", so to speak.
--*****************************************************************************
local function Within(V,l,h) return (V >= l) and (V <= h) end
local function Limits(V,l,h) return math.max(math.min(V,h),l) end
--*****************************************************************************
--Range checking and range limiting functions.
local MsgTmr= 0
local MsgTxt= ""
local MsgClr= white
--*****************************************************************************
local function DisplayMessage()
--*****************************************************************************
if MsgTmr < MessageDuration then
gui.text(1,-190,MsgTxt,MsgClr)
MsgTmr= MsgTmr+1
end
end
--*****************************************************************************
local function SetMessage(str,clr)
--*****************************************************************************
if not str then MsgTmr= math.huge; return end
MsgTmr= 0
MsgTxt= str
if clr then MsgClr= clr
else MsgClr= white end
end
--#############################################################################
--#############################################################################
--Handle outside scripts
--require("YummyButton")
--local CreateBtn= {text= "Y", }
--for i= 1, #btn do
--end
--#############################################################################
--#############################################################################
--Joypad handler
--*****************************************************************************
local function JoyToNum(Joys) -- Expects a table containing joypad buttons
--*****************************************************************************
-- Returns a number representing button presses.
-- These numbers are the primary storage for this version of this script.
local joynum= 0
for i= 1, #btn do
if Joys[btn[i]] then
joynum= bit.bor(joynum, bit.lshift(1,i))
end
end
return joynum
end
--*****************************************************************************
local function ReadJoynum(inp, button) -- Expects... Certain numbers!
--*****************************************************************************
-- Returns true or false. True if the indicated button is pressed
-- according to the input. False otherwise.
return ( bit.band(inp , bit.lshift( 1, button )) ~= 0 )
end
--*****************************************************************************
local function LoadJoypad()
--*****************************************************************************
local joys= JoypadList[fc]
if BackupOverride == "read" then joys= BackupList[fc] end
for i= 1, #btn do
if joys and ReadJoy[i] and ReadJoynum(joys, i) then
ThisInput[btn[i]]= TrueSwitch[i]
else
ThisInput[btn[i]]= FalseSwitch[i]
end
end
end
--*****************************************************************************
local function RegBeforeHandleJoypad()
--*****************************************************************************
--DeSmuME, emu.registerbefore. Not portable across emulators.
--If the "invert" option existed like in FCEUX, this function would be one line
local joys= joypad.peek()
for i= 1, #btn do
if type(ThisInput[btn[i]]) == "string" then
joys[btn[i]]= not joys[btn[i]]
else
joys[btn[i]]= ThisInput[btn[i]]
end
end
joypad.set(joys)
end
--*****************************************************************************
local function RegAfterHandleJoypad()
--*****************************************************************************
--Just say fc is properly updated by now.
local joys= JoyToNum(joypad.read())
JoypadList[fc-1]= joys
if (not BackupList[fc-1]) or BackupOverride == "write" then
BackupList[fc-1]= joys
end
LoadJoypad()
end
Jo, LastJo= joypad.peek(), joypad.peek()
--*****************************************************************************
local function ScanJoypad()
--*****************************************************************************
LastJo= Jo
Jo= joypad.peek()
for i= 1, #btn do
if (not Jo[btn[i]]) and LastJo[btn[i]] and StickyJoy[i] then
if ThisInput[btn[i]] then
ThisInput[btn[i]]= FalseSwitch[i]
else
ThisInput[btn[i]]= TrueSwitch[i]
end
end
end
end
--#############################################################################
--#############################################################################
--Stylus handler
--*****************************************************************************
local function StyToNum(Stys) -- Expects a table containing stylus control
--*****************************************************************************
-- Returns a number representing stylus position.
-- Low numbers are x, high is y.
if not Stys.touch then return false end
return Stys.x + bit.lshift(Stys.y,8)
end
--*****************************************************************************
local function ReadStynum(inp)
--*****************************************************************************
-- Returns two values, x,y. If not pressed, returns false,false instead.
if not inp then return false , false end
return bit.band(inp,0xFF) , bit.rshift(bit.band(inp,0xFF00),8)
end
--*****************************************************************************
local function ClearStylus()
--*****************************************************************************
ThisStylus.touch= false
ThisStylus.x= 0
ThisStylus.y= 0
end
--*****************************************************************************
local function LoadStylus()
--*****************************************************************************
local x,y= ReadStynum(StylusList[fc])
if x then ThisStylus.touch= true; ThisStylus.x= x; ThisStylus.y= y
else ClearStylus() end
end
--*****************************************************************************
local function RegBeforeHandleStylus()
--*****************************************************************************
local Stys= stylus.peek()
if not ControlStylus then Stys.touch= false end
if (not Stys.touch) and ThisStylus.touch then
stylus.set(ThisStylus)
end
end
--*****************************************************************************
local function RegAfterHandleStylus()
--*****************************************************************************
--fc is updated by this point. Joy.
StylusList[fc-1]= StyToNum(stylus.get())
if ReadStylus then LoadStylus() end
end
--*****************************************************************************
local function ScanStylus()
--*****************************************************************************
if StickyStylus then
local Poke= stylus.peek()
if Poke.touch then
ThisStylus.x= Poke.x
ThisStylus.y= Poke.y
ThisStylus.touch= true
end
end
end
--#############################################################################
--#############################################################################
--Display
--*****************************************************************************
local function FakeBox(x1,y1,x2,y2,fill)
--*****************************************************************************
--Gets around DeSmuME's problem of boxes that cross over top and touch screen.
--Fills only. No support for borders, yet.
local test = (y1 < 0)
if (y2 < 0) then test= not test end
if test then
gui.box(x1,y1,x2, 0,fill)
gui.box(x1, 0,x2,y2,fill)
else
gui.box(x1,y1,x2,y2,fill)
end
end
--*****************************************************************************
local function FakeBox2(x1,y1,x2,y2,fill,border)
--*****************************************************************************
local test = (y1 < 0)
if (y2 < 0) then test= not test end
if test then
gui.line(x1,y1,x2,y1,border)
gui.line(x1,y2,x2,y2,border)
if not within(y1,y2-1,y2+1) then
-- ... Forget it...
end
else
gui.box(x1,y1,x2,y2,fill,border)
end
end
--*****************************************************************************
local Draw= {}
--*****************************************************************************
function Draw.left(x,y,color) -- ##
gui.line(x+1,y ,x+2,y ,color) -- #
gui.line(x+1,y+2,x+2,y+2,color) -- ##
gui.pixel(x ,y+1,color)
end
function Draw.up(x,y,color) -- #
gui.line(x ,y+1,x ,y+2,color) -- # #
gui.line(x+2,y+1,x+2,y+2,color) -- # #
gui.pixel(x+1,y ,color)
end
function Draw.right(x,y,color) -- ##
gui.line(x ,y ,x+1,y ,color) -- #
gui.line(x ,y+2,x+1,y+2,color) -- ##
gui.pixel(x+2,y+1,color)
end
function Draw.down(x,y,color) -- # #
gui.line(x ,y ,x ,y+1,color) -- # #
gui.line(x+2,y ,x+2,y+1,color) -- #
gui.pixel(x+1,y+2,color)
end
function Draw.A(x,y,color) -- ###
gui.box(x ,y ,x+2,y+1,color) -- ###
gui.pixel(x ,y+2,color) -- # #
gui.pixel(x+2,y+2,color)
end
function Draw.B(x,y,color) -- ###
gui.line(x ,y ,x+2,y ,color) -- #
gui.line(x ,y+2,x+2,y+2,color) -- ###
gui.pixel(x ,y+1,color)
end
function Draw.X(x,y,color) -- # #
gui.line(x ,y ,x+2,y+2,color) -- #
gui.pixel(x ,y+2,color) -- # #
gui.pixel(x+2,y ,color)
end
function Draw.Y(x,y,color)
gui.line(x+1,y+1,x+1,y+2,color) -- # #
gui.pixel(x ,y ,color) -- #
gui.pixel(x+2,y ,color) -- #
end
function Draw.L(x,y,color) -- #
gui.line(x ,y+2,x+2,y+2,color) -- #
gui.line(x ,y ,x ,y+1,color) -- ###
end
function Draw.R(x,y,color)
gui.line(x ,y ,x ,y+2,color) -- ##
gui.line(x+1,y ,x+1,y+1,color) -- ##
gui.pixel(x+2,y+2,color) -- # #
end
function Draw.start(x,y,color) -- #
gui.line(x+1,y ,x+1,y+2,color) -- ###
gui.pixel(x ,y+1,color) -- #
gui.pixel(x+2,y+1,color)
end
function Draw.select(x,y,color) -- ###
gui.line(x ,y ,x+2,y ,color) -- # #
gui.line(x ,y+2,x+2,y+2,color) -- ###
gui.pixel(x ,y+1,color)
gui.pixel(x+2,y+1,color)
end
function Draw.lid(x,y,color) -- #
gui.line(x ,y ,x+2,y+2,color) -- ##
gui.line(x ,y+1,x+1,y+2,color) -- ##
end
function Draw.debug(x,y,color) -- #
gui.pixel(x+1,y ,color)
gui.pixel(x ,y+2,color) -- # #
gui.pixel(x+2,y+2,color)
end
function Draw.stylus(x,y,color) -- ###
gui.line(x ,y ,x+2,y ,color) -- #
gui.line(x ,y+2,x+2,y+2,color) -- ###
gui.pixel(x+1,y+1,color)
end
--*****************************************************************************
local function ShowFrame(x,y,input)
--*****************************************************************************
--DeSmuME specific display. It has no separate players to scan.
--input = Absolute frame
local WtrMrk= 1
if input%WtrInterval == 0 then WtrMrk= 13 end
x= x-4
for i= 1, #btn do
local clrnum= WtrMrk
--Display is rough... Use this color, but if Tuesday, that color instead!
if input == fc then
local test= ThisInput[btn[i]]
if test == "inv" then
test= not Jo[btn[i]]
elseif test == nil then
test= Jo[btn[i]]
end
if test then
clrnum= clrnum+3
else
clrnum= clrnum+1
end
elseif JoypadList[input] then
if ReadJoynum(JoypadList[input], i) then
if (input > fc) and not ReadJoy[i] then
clrnum= clrnum+2 -- Ignored
else
clrnum= clrnum+3 -- Pressed
end
else
clrnum= clrnum+1 -- Not pressed
end
end
if ShowBackup and BackupList[input] then
if ReadJoynum(BackupList[input], i) then
clrnum= clrnum+8 -- Oh, there's a backup
else
clrnum= clrnum+4 -- Backup not pressed
end
end
Draw[btn[i]](x+i*4,y,Clr[clrnum])
end
end
local MaxRange= math.floor(HGT/2 - 3)
local width= #btn*4
--*****************************************************************************
local function JoypadDisplay()
--*****************************************************************************
local up, dn
if Past <= -1 then
up= DispY + Past*4 -3
dn= DispY + math.min(-1,Future)*4 +1
FakeBox(DispX,up,DispX+width,dn,shade)
end
if Future >= 1 then
up= DispY + math.max(1,Past)*4 +1
dn= DispY + Future*4 +5
FakeBox(DispX,up,DispX+width,dn,shade)
end
if Past <= 0 and Future >= 0 then
local color= blue
for i= 1, #btn do
if not JoypadList[fc] then color= yellow; break end
local test = ThisInput[btn[i]]
if ReadJoynum(JoypadList[fc], i) then test= not test end
if test then color= green; break end
end
gui.box(DispX-1, DispY-2, DispX+width+1, DispY+4, shade,color)
end
local X= DispX+1
for i= Past, Future do
local Y= DispY + i*4
if i < 0 then Y= Y-2
elseif i > 0 then Y= Y+2 end
local FC= fc+i
ShowFrame(X,Y,FC)
if ShowBackup and BackupList[FC] then
local color= green
if (BackupList[FC] == JoypadList[FC]) then
color= blue
end
gui.line(DispX-2,Y,DispX-2,Y+2,color)
end
end
end
--*****************************************************************************
local function StylusDisplay1()
--*****************************************************************************
-- Pixel trail version
-- Anyone with better ideas? It's not particularly easy to see these pixels.
local x,y,color
local cmp
local tot
if StyP == -1 then
x,y= ReadStynum(StylusList[fc-1])
if x then gui.pixel(x,y,0xFF8000FF) end
else
cmp= (-256)/(StyP+1)
tot= 0
for i= StyP, -1 do
x,y= ReadStynum(StylusList[fc+i])
color= (0xFF00007F
+ math.floor(math.min(tot,0x80))
+ bit.lshift(math.floor(math.max(tot-0x80,0)),16)
)
if x then gui.pixel(x,y,color) end
tot= tot+cmp
end
end
if StyF == 1 then
x,y= ReadStynum(StylusList[fc+1])
if x then gui.pixel(x,y,0x0080FFFF) end
else
cmp= (256)/(StyF-1)
tot= 0
for i= StyF, 1, -1 do
x,y= ReadStynum(StylusList[fc+i])
color= (0x0000FF7F
+ math.floor(math.min(tot,0x80))
+ bit.lshift(math.floor(math.max(tot-0x80,0)),16)
)
if x then gui.pixel(x,y,color) end
tot= tot+cmp
end
end
x,y= ReadStynum(StylusList[fc])
if x then gui.pixel(x,y,green) end
if ThisStylus.touch then
gui.pixel(ThisStylus.x,ThisStylus.y,white)
end
end
--*****************************************************************************
local function NormalizeDisplay()
--*****************************************************************************
DispX= Limits(DispX,2,WID-width-2)
DispY= Limits(DispY,-HGT-Past*4+3,HGT-Future*4-6)
end
local btnswitches= {TrueSwitch, FalseSwitch, ReadJoy, StickyJoy}
local TrueVals= { "inv" , nil , true , true }
local Mat= {}
--*****************************************************************************
local function OptionsDisplay()
--*****************************************************************************
for i= 1, #btnswitches do
for j= 1, #btn do
local txt= "N"
if btnswitches[i][j] == TrueVals[i] then txt= "Y" end
gui.text(10*j, 8*i, txt)
end
end
end
--#############################################################################
--#############################################################################
--Handle user input
local lastkeys, keys= input.get(), input.get()
--*****************************************************************************
local function UpdateKeys() lastkeys= keys; keys= input.get() end
--*****************************************************************************
local repeater= 0
local KF, RF --KeyFunction, RepeaterFunction
--*****************************************************************************
local function KeyReader()
--*****************************************************************************
UpdateKeys()
for k,v in pairs(keys) do
local ThisKey= k
if keys.control then ThisKey= "c+" .. k end
if not lastkeys[k] then
repeater= 0
if KF[ThisKey] then KF[ThisKey]() end
if RF[ThisKey] then RF[ThisKey]() end
end
if repeater >= 3 then
if RF[ThisKey] then RF[ThisKey]() end
end
end
repeater= repeater+1
end
--*****************************************************************************
local function MouseHandler()
--*****************************************************************************
--KeyReader should be called first, and that updates our keys already!
if (not keys.leftclick) or (not lastkeys.leftclick) then return end
if keys.control then
DispX= DispX + keys.xmouse - lastkeys.xmouse
DispY= DispY + keys.ymouse - lastkeys.ymouse
else
ScanStylus()
end
end
--*****************************************************************************
local function MouseHandler2()
--*****************************************************************************
if keys.rightclick and lastkeys.rightclick then
DispX= DispX + keys.xmouse - lastkeys.xmouse
DispY= DispY + keys.ymouse - lastkeys.ymouse
end
ScanStylus()
end
local KF1, KF2, RF1= {}, {}, {}
-------------------------------------------------------------------------------
RF1[solid]= function() Opaque= math.min(Opaque + .125 , 1) end
RF1[clear]= function() Opaque= math.max(Opaque - .125 , 0) end
-------------------------------------------------------------------------------
RF1[DispUp]= function() DispY= DispY-1 end
RF1[DispDn]= function() DispY= DispY+1 end
RF1[DispRt]= function() DispX= DispX+1 end
RF1[DispLf]= function() DispX= DispX-1 end
-------------------------------------------------------------------------------
RF1[MoreFutr]= function() Future= Future+1; Past= math.max(Past,Future-MaxRange) end
RF1[LessFutr]= function() Future= Future-1; Past= math.min(Past,Future) end
RF1[MorePast]= function() Past = Past -1; Future= math.min(Future,Past+MaxRange) end
RF1[LessPast]= function() Past = Past +1; Future= math.max(Future,Past) end
KF1[ResetFP]= function() Future= 12; Past= -12 end
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
KF1.space= function() --Mostly a hack ... I'm out of joypad stuff...
-------------------------------------------------------------------------------
if ThisStylus.touch then
ClearStylus()
else
LoadStylus()
end
end
if false then
-------------------------------------------------------------------------------
KF1[BackupDisplaySwitch]= function()
-------------------------------------------------------------------------------
end
KF2[OptUp]= function() end
KF2[OptDn]= function() end
KF2[OptRt]= function() end
KF2[OptLf]= function() end
KF2[OptHit]= function() end
end
local HandleDisplay, UsualDisplay
-------------------------------------------------------------------------------
KF1[opt]= function()
-------------------------------------------------------------------------------
KF= KF2
RF= NULLTBL
HandleDisplay= OptionsDisplay
end
--Cheap functions. Bad on runtime with enough frames stacked up.
-------------------------------------------------------------------------------
KF1[Insert]= function()
-------------------------------------------------------------------------------
local frame= fc
while JoypadList[frame] do frame=frame+1 end
for i= frame, (fc+1), -1 do
JoypadList[i]= JoypadList[i-1]
StylusList[i]= StylusList[i-1]
end
JoypadList[fc]= 0
StylusList[fc]= false
LoadJoypad()
LoadStylus()
end
-------------------------------------------------------------------------------
KF1[Delete]= function()
-------------------------------------------------------------------------------
local i= fc
while JoypadList[i] do
JoypadList[i]= JoypadList[i+1]
StylusList[i]= StylusList[i+1]
i=i+1
end
LoadJoypad()
LoadStylus()
end
-------------------------------------------------------------------------------
KF1[BackupReadSwitch]= function()
-------------------------------------------------------------------------------
if BackupOverride == "read" then
BackupOverride= false
SetMessage("End backup read",white)
else
BackupOverride= "read"
SetMessage("Reading from backup list...",green)
end
end
-------------------------------------------------------------------------------
KF1[BackupWriteSwitch]= function()
-------------------------------------------------------------------------------
if BackupOverride == "write" then
BackupOverride= false
SetMessage("End backup overwrite",white)
else
BackupOverride= "write"
SetMessage("Merging input into backup...",yellow)
end
end
-------------------------------------------------------------------------------
KF1[BackupDisplaySwitch]= function() ShowBackup= not ShowBackup end
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
KF2[opt]= function()
-------------------------------------------------------------------------------
KF= KF1
RF= RF1
HandleDisplay= UsualDisplay
end
local OC= 0
-------------------------------------------------------------------------------
KF1[PresetSwitch]= function()
-------------------------------------------------------------------------------
OC= (OC % #OptionPreset)+1
SetMessage(OptionPreset[OC].name,green)
DispX= OptionPreset[OC].DispX
DispY= OptionPreset[OC].DispY
Past= OptionPreset[OC].Past
Future=OptionPreset[OC].Future
Opaque=OptionPreset[OC].opaque
StyP= OptionPreset[OC].StyP
StyF= OptionPreset[OC].StyF
if OptionPreset[OC].TJ then
for i= 1, #btn do TrueSwitch[i]= "inv" end
else
for i= 1, #btn do TrueSwitch[i]= true end
end
if OptionPreset[OC].FJ then
for i= 1, #btn do FalseSwitch[i]= nil end
else
for i= 1, #btn do FalseSwitch[i]= false end
end
for i= 1, #btn do
ReadJoy[i]= OptionPreset[OC].RJ
StickyJoy[i]= OptionPreset[OC].SJ
end
ControlStylus= OptionPreset[OC].CS
ReadStylus= OptionPreset[OC].RS
StickyStylus= OptionPreset[OC].SS
LoadJoypad()
LoadStylus()
end
KF1[PresetSwitch]()
--#############################################################################
--#############################################################################
--Top level routines to actually run my stuff.
KF= KF1
RF= RF1
--*****************************************************************************
function UsualDisplay()
--*****************************************************************************
if Opaque > 0 then
gui.opacity(Opaque)
NormalizeDisplay()
JoypadDisplay()
StylusDisplay1()
gui.opacity(1)
end
end
HandleDisplay= UsualDisplay
--*****************************************************************************
local function UnpausedSanityScan()
--*****************************************************************************
--For unpaused stateload with this script running.
--Ensures we have the proper input when the frame count spontaneously changes.
UpdateFC()
if fc ~= lastfc then
if BackupOverride then
SetMessage("Auto-ended backup read/write",white)
BackupOverride= false
end
LoadJoypad()
LoadStylus()
end
end
--*****************************************************************************
local function LoadFix()
--*****************************************************************************
local _fc= movie.framecount()
if Within(_fc,fc,fc+1) then return end
UpdateFC()
if BackupOverride then
SetMessage("Auto-ended backup read/write",white)
BackupOverride= false
end
LoadJoypad()
LoadStylus()
end
--*****************************************************************************
local function RegBefore()
--*****************************************************************************
UnpausedSanityScan()
RegBeforeHandleJoypad()
RegBeforeHandleStylus()
end
emu.registerbefore(RegBefore)
--*****************************************************************************
local function RegAfter()
--*****************************************************************************
UpdateFC()
RegAfterHandleJoypad()
RegAfterHandleStylus()
if keys.space then KF1.space() end --Hack
end
emu.registerafter(RegAfter)
--*****************************************************************************
local function RegGui()
--*****************************************************************************
LoadFix()
KeyReader()
MouseHandler2()
ScanJoypad()
HandleDisplay()
DisplayMessage()
end
gui.register(RegGui)
I found a glitch with DeSmuME's frameadvance. Have this as the only piece of code:
while true do emu.frameadvance() end
Now run the one-line script and use the frame advance key. The emulator's frame counter will increment, but no actual emulation will take place. Pausing and unpausing the emulation still works fine, however.
The window header of the version I'm using reads
DeSmuME 0.9.6 x86.