_FRK_Fn= {} _FRK_Fn.version= 1 --FatRatKnight -- Various little functions for use. -- Shortly, I will list out functions and keywords that the script provides -- access to. But first, I feel a need to explain a few things... -- Option keywords are simply global variables that this auxillary script looks -- for. If they are anything other than false or nil by the time your script -- calls requrie("FRKfunctions"), this script will react accordingly. -- Reserved variable names are those the script uses, but allows access for -- other scripts. Sorry about taking valuble names away from you, but I figure -- you might want direct access to them. -- Functions are just that. Functions that do stuff, the whole point of this -- auxillary script. I copied down their line numbers for your convenience. -- If the quick description isn't enough, then perhaps the more detailed -- comments and actual code might be. -- Options for individual functions can be changed by altering its number -- after the require("FRKfunctions") line. --List of option keywords: -- _FRK_SkipRename Convenient names aren't used for these functions -- _FRK_NoAutoReg Will not automatically fill registers --List of reserved variable names: -- keys For checking current keys. -- lastkeys For checking previous keys. --List of functions: -- 82 UpdateKeys() Updates this script's key tables -- 97 Press(button) Checks for a key hit -- 109 PressRepeater(button) Like Press, but if held for long -- 133 Release(button) Checks for when a key is released -- 144 MouseMoved() Returns how far the mouse moved -- 166 FBoxOldFast(x1, y1, x2, y2, color) Faster at drawing, but stupid -- 180 FBoxOld(x1, y1, x2, y2, color) Border-only box; corners fix -- 210 FakeBox(x1, y1, x2, y2, Fill, Border) Fill-and-Border box; corners fix -- 230 Draw[digit](Left,Top,color) Paints tiny digit on screen -- 354 _FRK_Fn._DN_AnyBase(right, top, Number, color, bkgnd, div) -- Paints a right-aligned number using any base from 2 to 16. -- 405 DrawNum(right, top, Number, color, bkgnd) Paints a beautiful number -- 413 DrawNumx(right, top, Number, color, bkgnd) Hexidecimal version -- 504 ProcessReg() Removes functions in registers and stores 'em -- 521 ApplyReg() Sets registers -- 534 AddReg(name, function) -- 543 RemoveReg(name, pos) -- 564 limits(value,low,high) Returns value or specified limits -- 575 within(value,low,high) Returns T/F; Is it within range? --List of options for individual functions: _FRK_Fn.RepeaterDelay= 5 --How long should PressRepeater wait? -- input.get family --***************************************************************************** function _FRK_Fn.UpdateKeys() --***************************************************************************** -- Moves keys into lastkeys, then puts fresh keyboard input into keys. -- Meant to simplify the process of registering keyhits. -- Stick this thing at the beginning of a gui.register function or main loop. lastkeys= keys keys= input.get() end keys= input.get() -- Sanity. Want xmouse and ymouse to exist. lastkeys= keys -- Otherwise, MouseMoved pings an error at me. --***************************************************************************** function _FRK_Fn.Press(button) -- Expects a key --***************************************************************************** -- Returns true or false. It's true at the moment the user hits the button. -- 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 _FRK_Fn.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. -- It works fine if there are multiple calls to different buttons. Not so fine -- if there's multiple calls to the same button. Only one repeater variable... if keys[button] then if not lastkeys[button] or repeater >= _FRK_Fn.RepeaterDelay then return true else repeater = repeater + 1 end elseif lastkeys[button] then -- To allow more calls for other buttons repeater= 0 end return false end --***************************************************************************** function _FRK_Fn.Release(button) -- Expects a key --***************************************************************************** -- Returns true or false. It's true at the moment the user releases the button. -- Might be a good idea to know when the user ain't holding it anymore. -- Eh, I don't see any obvious application, but may as well have it. return ((not keys[button]) and lastkeys[button]) end --***************************************************************************** function _FRK_Fn.MouseMoved() --***************************************************************************** -- Returns two values: x,y -- This function tells you how far the mouse moved since the last update. -- It's simply the difference of what position it is now and what it once was. return (keys.xmouse - lastkeys.xmouse) , (keys.ymouse - lastkeys.ymouse) end -- Display family -- For helping you see --***************************************************************************** function _FRK_Fn.FBoxOldFast(x1, y1, x2, y2, color) --***************************************************************************** -- Gets around FCEUX's problem of double-painting the corners. -- This particular function doesn't make sure the x and y are good. -- Call this instead if you need processing speed and know its fine gui.line(x1 ,y1 ,x2-1,y1 ,color) -- top gui.line(x2 ,y1 ,x2 ,y2-1,color) -- right gui.line(x1+1,y2 ,x2 ,y2 ,color) -- bottom gui.line(x1 ,y1+1,x1 ,y2 ,color) -- left end --***************************************************************************** function _FRK_Fn.FBoxOld(x1, y1, x2, y2, color) --***************************************************************************** -- Gets around FCEUX's problem of double-painting the corners. -- This has several sanity checks to ensure a properly drawn box. -- It acts like the old-style border-only box. if (x1 == x2) and (y1 == y2) then -- Sanity: Is it a single dot? gui.pixel(x1,y1,color) elseif (x1 == x2) or (y1 == y2) then -- Sanity: A straight line? gui.line(x1,y1,x2,y2,color) else --(x1 ~= x2) and (y1 ~= y2) local temp if x1 > x2 then temp= x1; x1= x2; x2= temp -- Sanity: Without these checks, end -- This function may end up putting if y1 > y2 then -- two or four out-of-place pixels temp= y1; y1= y2; y2= temp -- near the corners. end gui.line(x1 ,y1 ,x2-1,y1 ,color) -- top gui.line(x2 ,y1 ,x2 ,y2-1,color) -- right gui.line(x1+1,y2 ,x2 ,y2 ,color) -- bottom gui.line(x1 ,y1+1,x1 ,y2 ,color) -- left end end --***************************************************************************** function _FRK_Fn.FakeBox(x1, y1, x2, y2, Fill, Border) --***************************************************************************** -- Gets around FCEUX's problem of double-painting the corners. -- It acts like the new-style fill-and-border box. Not quite perfectly... -- One "problem" is that, if you specify Fill only, it won't successfully -- mimic the actual gui.box fill. if not Border then Border= Fill end gui.box(x1,y1,x2,y2,Fill,0) FBoxOld(x1,y1,x2,y2,Border) end --### # ### ### # # ### ### ### ### ### # ## # ## ### ### --# # ## # # # # # # # # # # # # # # # # # # # # # --# # # ### ### ### ### ### ## ### ### # # ## # # # ## ## --# # # # # # # # # # # # # ### # # # # # # # # --### ### ### ### # ### ### # ### ### # # ## # ## ### # --***************************************************************************** _FRK_Fn.Draw= {} --Draw[button]( Left , Top , color ) --***************************************************************************** --Coordinates is the top-left pixel of the 3x5 digit. --Used for drawing compact, colored numbers. local d= _FRK_Fn.Draw function d.D0(left, top, color) gui.line(left ,top ,left ,top+4,color) gui.line(left+2,top ,left+2,top+4,color) gui.pixel(left+1,top ,color) gui.pixel(left+1,top+4,color) end function d.D1(left, top, color) gui.line(left ,top+4,left+2,top+4,color) gui.line(left+1,top ,left+1,top+3,color) gui.pixel(left ,top+1,color) end function d.D2(left, top, color) gui.line(left ,top ,left+2,top ,color) gui.line(left ,top+3,left+2,top+1,color) gui.line(left ,top+4,left+2,top+4,color) gui.pixel(left ,top+2,color) gui.pixel(left+2,top+2,color) end function d.D3(left, top, color) gui.line(left ,top ,left+1,top ,color) gui.line(left ,top+2,left+1,top+2,color) gui.line(left ,top+4,left+1,top+4,color) gui.line(left+2,top ,left+2,top+4,color) end function d.D4(left, top, color) gui.line(left ,top ,left ,top+2,color) gui.line(left+2,top ,left+2,top+4,color) gui.pixel(left+1,top+2,color) end function d.D5(left, top, color) gui.line(left ,top ,left+2,top ,color) gui.line(left ,top+1,left+2,top+3,color) gui.line(left ,top+4,left+2,top+4,color) gui.pixel(left ,top+2,color) gui.pixel(left+2,top+2,color) end function d.D6(left, top, color) gui.line(left ,top ,left+2,top ,color) gui.line(left ,top+1,left ,top+4,color) gui.line(left+2,top+2,left+2,top+4,color) gui.pixel(left+1,top+2,color) gui.pixel(left+1,top+4,color) end function d.D7(left, top, color) gui.line(left ,top ,left+1,top ,color) gui.line(left+2,top ,left+1,top+4,color) end function d.D8(left, top, color) gui.line(left ,top ,left ,top+4,color) gui.line(left+2,top ,left+2,top+4,color) gui.pixel(left+1,top ,color) gui.pixel(left+1,top+2,color) gui.pixel(left+1,top+4,color) end function d.D9(left, top, color) gui.line(left ,top ,left ,top+2,color) gui.line(left+2,top ,left+2,top+3,color) gui.line(left ,top+4,left+2,top+4,color) gui.pixel(left+1,top ,color) gui.pixel(left+1,top+2,color) end function d.DA(left, top, color) gui.line(left ,top+1,left ,top+4,color) gui.line(left+2,top+1,left+2,top+4,color) gui.pixel(left+1,top ,color) gui.pixel(left+1,top+3,color) end function d.DB(left, top, color) gui.line(left ,top ,left ,top+4,color) gui.line(left+1,top ,left+2,top+1,color) gui.line(left+1,top+4,left+2,top+3,color) gui.pixel(left+1,top+2,color) end function d.DC(left, top, color) gui.line(left ,top+1,left ,top+3,color) gui.line(left+1,top ,left+2,top+1,color) gui.line(left+1,top+4,left+2,top+3,color) end function d.DD(left, top, color) gui.line(left ,top ,left ,top+4,color) gui.line(left+2,top+1,left+2,top+3,color) gui.pixel(left+1,top ,color) gui.pixel(left+1,top+4,color) end function d.DE(left, top, color) gui.line(left ,top ,left ,top+4,color) gui.line(left+1,top ,left+2,top ,color) gui.line(left+1,top+4,left+2,top+4,color) gui.pixel(left+1,top+2,color) end function d.DF(left, top, color) gui.line(left ,top ,left ,top+4,color) gui.line(left+1,top ,left+2,top ,color) gui.pixel(left+1,top+2,color) end d[0],d[1],d[2],d[3],d[4]= d.D0, d.D1, d.D2, d.D3, d.D4 d[5],d[6],d[7],d[8],d[9]= d.D5, d.D6, d.D7, d.D8, d.D9 d[10],d[11],d[12],d[13],d[14],d[15]= d.DA, d.DB, d.DC, d.DD, d.DE, d.DF --***************************************************************************** function _FRK_Fn._DN_AnyBase(right, top, Number, color, 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) if not color then color= "white" end if not bkgnd then bkgnd= "clear" end 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 left= right - i*4 FakeBox(left+1, top-1, right+1, top+5,bkgnd,bkgnd) i= 1 while _FRK_Fn.Draw[Digit[i]] do _FRK_Fn.Draw[Digit[i]](right-2,top,color) right= right-4 i=i+1 end if Negative then gui.line(right, top+2,right-2,top+2,color) right= right-4 end return right end --***************************************************************************** function _FRK_Fn.DrawNum(right, top, Number, color, bkgnd) --***************************************************************************** -- Paints the input number as right-aligned. Decimal version. return _FRK_Fn._DN_AnyBase(right, top, Number, color, bkgnd, 10) end --***************************************************************************** function _FRK_Fn.DrawNumx(right, top, Number, color, bkgnd) --***************************************************************************** -- Paints the input number as right-aligned. Hexadecimal version. return _FRK_Fn._DN_AnyBase(right, top, Number, color, bkgnd, 16) end -- Registry family -- For overloading the usual registers with multiple separate functions. local RegNames= {"Before", "After", "Exit", "Gui", "Save", "Load"} _FRK_Fn.RegList= {} _FRK_Fn.RegList.Before={} _FRK_Fn.RegList.After= {} _FRK_Fn.RegList.Exit= {} _FRK_Fn.RegList.Gui= {} _FRK_Fn.RegList.Save= {} _FRK_Fn.RegList.Load= {} --***************************************************************************** _FRK_Fn.RegFn= {} --RegFn[name]() For various registers --***************************************************************************** function _FRK_Fn.RegFn.Before() local i= 1 while (_FRK_Fn.RegList.Before[i]) do _FRK_Fn.RegList.Before[i]() i= i+1 end end function _FRK_Fn.RegFn.After() local i= 1 while (_FRK_Fn.RegList.After[i]) do _FRK_Fn.RegList.After[i]() i= i+1 end end function _FRK_Fn.RegFn.Exit() local i= 1 while (_FRK_Fn.RegList.Exit[i]) do _FRK_Fn.RegList.Exit[i]() i= i+1 end end function _FRK_Fn.RegFn.Gui() local i= 1 while (_FRK_Fn.RegList.Gui[i]) do _FRK_Fn.RegList.Gui[i]() i= i+1 end end function _FRK_Fn.RegFn.Save() local i= 1 while (_FRK_Fn.RegList.Save[i]) do _FRK_Fn.RegList.Save[i]() i= i+1 end end function _FRK_Fn.RegFn.Load() local i= 1 while (_FRK_Fn.RegList.Load[i]) do _FRK_Fn.RegList.Load[i]() i= i+1 end end local EmuRegisters={ emu.registerbefore, emu.registerafter, emu.registerexit, gui.register, savestate.registersave, savestate.registerload } --***************************************************************************** function _FRK_Fn.ProcessRegisters() --***************************************************************************** -- Any functions in registers, such as those that might be inserted by -- auxillary files, are removed from their registers and inserted into my -- table of functions to execute. -- All registers will be empty after excecution of this function. for i= 1, 6 do local test= EmuRegisters[i]() -- Make sure the function exists. Also, make sure it isn't ourselves... if test and (test ~= _FRK_Fn.RegFn[ RegNames[i] ]) then table.insert(_FRK_Fn.RegList[ RegNames[i] ],1,test) end end end --***************************************************************************** function _FRK_Fn.ApplyRegisters() --***************************************************************************** -- Fills the registers with functions that will excecute functions stored in -- my tables. for i= 1, 6 do if _FRK_Fn.RegList[ RegNames[i] ][ 1 ] then EmuRegisters[i](_FRK_Fn.RegFn[ RegNames[i] ]) end end end --***************************************************************************** function _FRK_Fn.AddRegister(name, fn) --***************************************************************************** -- Name should be "Before", "After", "Exit", "Gui", "Save", or "Load". -- Recommended for use if you plan to add functions to the register. table.insert(_FRK_Fn.RegList[name],fn) end --***************************************************************************** function _FRK_Fn.RemoveRegister(name, pos) --***************************************************************************** -- Name should be "Before", "After", "Exit", "Gui", "Save", or "Load". -- You may omit pos. Doing so will remove and return the first function that's -- been inserted into my table. return table.remove(_FRK_Fn.RegList[name],pos) end -- Miscellaneous family --***************************************************************************** function _FRK_Fn.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. -- Sometimes, you'd rather crop the number to some specific limits. return math.max(math.min(value,high),low) end --***************************************************************************** function _FRK_Fn.within( value , low , high ) -- Expects numbers --***************************************************************************** -- Returns true if value is between low and high, inclusive. False otherwise. -- Sometimes, you just want to know if the number is within a certain range. return ( value >= low ) and ( value <= high ) end --============================================================================= if not _FRK_SkipRename then --============================================================================= UpdateKeys= _FRK_Fn.UpdateKeys Press= _FRK_Fn.Press PressRepeater= _FRK_Fn.PressRepeater Release= _FRK_Fn.Release MouseMoved= _FRK_Fn.MouseMoved FBoxOldFast= _FRK_Fn.FBoxOldFast FBoxOld= _FRK_Fn.FBoxOld FakeBox= _FRK_Fn.FakeBox Draw= _FRK_Fn.Draw DrawNum= _FRK_Fn.DrawNum DrawNumx= _FRK_Fn.DrawNumx ProcessReg= _FRK_Fn.ProcessRegisters ApplyReg= _FRK_Fn.ApplyRegisters AddReg= _FRK_Fn.AddRegister RemoveReg= _FRK_Fn.RemoveRegister limits= _FRK_Fn.limits within= _FRK_Fn.within end --============================================================================= if not _FRK_NoAutoReg then --============================================================================= emu.registerbefore( _FRK_Fn.RegFn.Before) emu.registerafter( _FRK_Fn.RegFn.After ) emu.registerexit( _FRK_Fn.RegFn.Exit ) gui.register( _FRK_Fn.RegFn.Gui ) savestate.registersave(_FRK_Fn.RegFn.Save ) savestate.registerload(_FRK_Fn.RegFn.Load ) end