From 37b563361cb0f35c77cf58a1d949b4e6367ad13b Mon Sep 17 00:00:00 2001 From: fatratknight Date: Sat, 1 May 2010 21:44:20 +0000 Subject: [PATCH] Slightly bulky auxiliary script, but has a few handy functions for dealing with input.get, displaying numbers, and adding new functions to the registers without kicking out old ones. --- output/luaScripts/FRKfunctions.lua | 625 +++++++++++++++++++++++++++++ 1 file changed, 625 insertions(+) create mode 100644 output/luaScripts/FRKfunctions.lua diff --git a/output/luaScripts/FRKfunctions.lua b/output/luaScripts/FRKfunctions.lua new file mode 100644 index 00000000..0dfaeb9b --- /dev/null +++ b/output/luaScripts/FRKfunctions.lua @@ -0,0 +1,625 @@ +_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 \ No newline at end of file