View Page Source

Revision (current)
Last Updated by MESHUGGAH on 1/5/2019 3:08 PM
Back to Page

This page documents various lua functions in lsnes.

Unless otherwise noted, functions are in rr1 version and work anywhere.

%%TOC%%

!!!Bit manipulation functions

!!(Generic remarks)
Bit manipulation functions work on 48-bit numbers and return 48-bit results. Negative numbers are interpreted as two's complement.

!!bit.none / bit.bnot
>Syntax: Number bit.none(Number n...)%%%
>Syntax: Number bit.bnot(Number n...)

Returns number that has bit i set exactly when none of the arguments has the bit i set.

When called with one argument, this is the same as the bitwise NOT.

!!bit.any / bit.bor
>Syntax: Number bit.any(Number n...)%%%
>Syntax: Number bit.bor(Number n...)

Returns number that has bit i set exactly when any of the arguments has the bit i set.

If called with two arguments, this is the same as bitwise OR.

!!bit.all / bit.band
>Syntax: Number bit.all(Number n...)%%%
>Syntax: Number bit.band(Number n...)

Returns number that has bit i set exactly when all of the arguments have the bit i set.

If called with two arguments, this is the same as bitwise AND.

!!bit.parity
>Syntax: Number bit.parity(Number n...)%%%
>Syntax: Number bit.bxor(Number n...)

Returns number that has bit i set exactly when odd number of the arguments has the bit i set.

If called with two arguments, this is the same as bitwise XOR.

!!bit.lrotate
>Syntax: Number bit.lrotate(Number base, [[Number nplaces], [[Number nbits])
* If __nplaces__ is not specified, defaults to 1.
* If __nbits__ is not specified, defaults to 48.

Returns __base__, assumed to be __nbits__ bits, rotated left by __nplaces__ places.

Behavior is undefined if __nbits__ is greater than 48 or if __nplaces__ is greater than 47.

!!bit.rrotate
>Syntax: Number bit.rrotate(Number base, [[Number nplaces], [[Number nbits])
* If __nplaces__ is not specified, defaults to 1.
* If __nbits__ is not specified, defaults to 48.

Returns __base__, assumed to be __nbits__ bits, rotated right by __nplaces__ places.

Behavior is undefined if __nbits__ is greater than 48 or if __nplaces__ is greater than 47.

!!bit.lshift
>Syntax: Number bit.lshift(Number base, [[Number nplaces], [[Number nbits])
* If __nplaces__ is not specified, defaults to 1.
* If __nbits__ is not specified, defaults to 48.

Returns __base__, assumed to be __nbits__ bits, shifted left by __nplaces__ places.

The bits that leave __nbits__ least significant bits are discarded. The shifted in bits are zeroes.

Behavior is undefined if __nbits__ is greater than 48 or if __nplaces__ is greater than 47.

!!bit.lrshift
>Syntax: Number bit.lrshift(Number base, [[Number nplaces], [[Number nbits])
* If __nplaces__ is not specified, defaults to 1.
* If __nbits__ is not specified, defaults to 48.

Returns __base__, assumed to be __nbits__ bits, shifted logically right by __nplaces__ places.

The bits that drop off the right end are discarded. The shifted in bits are zeroes.

Behavior is undefined if __nbits__ is greater than 48 or if __nplaces__ is greater than 47.

!!bit.arshift
>Syntax: Number bit.arshift(Number base, [[Number nplaces], [[Number nbits])
* If __nplaces__ is not specified, defaults to 1.
* If __nbits__ is not specified, defaults to 48.

Returns __base__, assumed to be __nbits__ bits, shifted arithmetically right by __nplaces__ places.

The bits that drop off the right end are discarded. The shifted in bits are copies of the most significant bit.

Behavior is undefined if __nbits__ is greater than 48 or if __nplaces__ is greater than 47.

!!bit.extract
>Syntax: Number bit.extract(Number base, Number/Boolean place...)
* Since rr1-Δ5

Returns a number where ith bit is taken from the ith __place__th bit of __base__.

As special case, if ith __place__ is boolean, the ith returned bit is that value (1 if argument was true, 0 if false).

!!bit.value
>Syntax: Number bit.value(Number/nil place...)
* Since rr1-Δ5

Returns number that has all __place__th bits set.

As special case, any nil arguments are ignored.

!!bit.test_any
>Syntax: Boolean bit.test_any(Number a, Number b)
* Since rr1-Δ16 / rr2-β2

Returns true if a and b have common set bit or bits.

!!bit.test_all
>Syntax: Boolean bit.test_all(Number a, Number b)
* Since rr1-Δ16 / rr2-β2

Returns true if a has all the bits set in b set.

!!bit.popcount
>Syntax: Number bit.popcount(Number a)
* Since rr1-Δ16 / rr2-β2

Returns population count (number of set bits) of a.

!!bit.clshift
>Syntax: Number,Number bit.clshift(Number a, Number b, [[Number places], [[Number bits])
* Since rr1-Δ16 / rr2-β2

Chained shift of a and b left by specified number of places (default 1). The numbers are treated as having specified number of bits (default 48).

!!bit.crshift
>Syntax: Number,Number bit.crshift(Number a, Number b, [[Number places], [[Number bits])
* Since rr1-Δ16 / rr2-β2

Chained shift of a and b right by specified number of places (default 1). The numbers are treated as having specified number of bits (default 48).

!!bit.flagdecode
>Syntax: String bit.flagdecode(Number a, Number bits, [[String set], [[String clear])
* Since rr1-Δ16 / rr2-β2

Returns string where ith character is ith character (only character or '*') of set if corresponding bit is set, otherwise corresponding character of clear.

!!bit.rflagdecode
>Syntax: String bit.rflagdecode(Number a, Number bits, [[String set], [[String clear])
* Since rr1-Δ16 / rr2-β2

Same as bit.flagdecode, but reverses the output string.
!!!GUI functions
!!(Color notation)
* -1 is fully transparent.
* 16777216 * a + 65536 * r + 256 * g + b for other colors, where a is transparency.
* * The range of r, g and b and a is 0-255.
* * Alpha 0 is fully opaque, alpha 256 is fully transparent.
* * The a of this notation only goes to 255, despite there being alpha 256.

!!(Coordinate system)
* Origin is at top left of the game area.
* Positive directions are right and down.
* Left gap and top gap have negative coordinates.

!!(Draw order)
* The primitives are drawn in order they are specified.
* Gap settings always overtake everything else.

!!(Valid in)
* These primitives (unless otherwise noted) are only valid in callbacks __on_paint__ and __on_video__.
* If called in __on_paint__, the screen is affected.
* If called in __on_video__, the dumped video is affected.

!!gui.screenshot
>Syntax: none gui.screenshot(string filename)
* Valid anywhere.

Take a screenshot in PNG format and save it to __filename__


!!gui.circle
>Syntax: none gui.circle(Number x, Number y, Number r, [[Number thickness], [[Number outline_color], [[Number fill_color])
* thickness defaults to 1
* outline_color defaults to white
* fill_color defaults to transparent

Draws a circle centered at (__x__,__y__) with radius __r__.

The outline is of thickness __thickness__ and is drawn using color specified by __outline_color__

The interior region is filled with color __fill_color__.

!!gui.resolution
> Syntax (number width, number height) gui.resolution()

Returns the width (__width__) and height (__height__) of game area.

!!gui.left_gap / gui.top_gap / gui.right_gap / gui.bottom_gap
> Syntax none gui.left_gap(number pixels)%%%
> Syntax none gui.top_gap(number pixels)%%%
> Syntax none gui.right_gap(number pixels)%%%
> Syntax none gui.bottom_gap(number pixels)

Sets the width of drawable blank area to the left/top/right/bottom of the game area to __pixels__.

!!gui.repaint
> Syntax: none gui.repaint()
* Valid anywhere.

Arranges __on_paint__ hook to be called as soon as possible.

!!gui.subframe_update
> Syntax: none gui.subframe_update(boolean enabled)
* Valid anywhere

Enables (__enabled__=true)/Disables (__enabled__=false) calling of __on_paint__ on every subframe (as opposed to just when new frame is available).

!!gui.color
> Syntax: Number gui.color(Number r, Number g, Number b, [[Number a])
* Valid anywhere.
* __a__ defaults to 0 if not specified.

Returns the color code for color (__r__,__g__,__b__) (0-255 each channel) with alpha of __a__ (0-256).

!!gui.status
> Syntax: none gui.status(String name, String value)
* Valid anywhere

Set status __name__ to value __value__.

If __value__ is "", the status __name__ is erased.

!!gui.crosshair
> Syntax: none gui.crosshair(Number x, Number y, Number size, [[Number color])
* __color__ defaults to white.

Draws a crosshair of size __size__ at (__x__,__y__) using color __color__.

!!gui.line
> Syntax: none gui.color(Number x1, Number y1, Number x2, Number y2, [[Number color])
* __color__ defaults to white.

Draws a line from (__x1__,__y1__) to (__x2__,__y2__) using color __color__.

!!gui.pixel
> Syntax: none gui.pixel(Number x, Number y, [[Number color])
* __color__ defaults to white.

Draws pixel at (__x__,__y__) using color __color__.

Be careful with this function. Even if it is the lightest of all draw functions, lots of draw functions don't do any good to performance.

!!gui.rectangle
> Syntax: none gui.rectangle(Number x, Number y, Number w, Number h, [[Number thickness], [[Number outline_color], [[Number fill_color])
* __tickness__ defaults to 1.
* __outline_color__ defaults to white.
* __fill_color__ defaults to transparent.

Draws rectangle of size (__w__,__h__) with top-left corner at (__x__,__y__). Outline is of thickness __thickness__ and is colored with color __outline_color__.

The interior is filled with color __fill_color__.

!!gui.box
> Syntax: none gui.box(Number x, Number y, Number w, Number h, [[Number thickness], [[Number hilight_color], [[Number shadow_color], [[Number fill_color])
* Since rr1-Δ6
* __thickness__ defaults to 1.
* __hilight_color__ defaults to white.
* __shadow_color__ defaults to dark gray.
* __fill_color__ defaults to gray.

Draws rectangle of size (__w__,__h__) with top-left corner at (__x__,__y__).

The outline is of thickness __thickness__ and is colored with __hilight_color__/__shadow_color__ to create a 3D effect.

The interior is filled with fill_color.

!!gui.text / gui.textH / gui.textV / gui.textHV
> Syntax: none gui.text(Number x, Number y, String text, [[Number fgcolor], [[Number bgcolor])%%%
> Syntax: none gui.textH(Number x, Number y, String text, [[Number fgcolor], [[Number bgcolor])%%%
> Syntax: none gui.textV(Number x, Number y, String text, [[Number fgcolor], [[Number bgcolor])%%%
> Syntax: none gui.textHV(Number x, Number y, String text, [[Number fgcolor], [[Number bgcolor])
* __fgcolor__ defaults to white.
* __bgcolor__ defaults to transparent.

Draws text string __text__ starting from (__x__, __y__).

The text will be colored using color __fgcolor__ and the text background is colored using __bgcolor__.

The {{H}} variants will draw the text using double width, and the {{V}} variants will draw the text using double height.

!!gui.bitmap_draw
> Syntax: none gui.bitmap_draw(Number x, Number y, BITMAP bmp, PALETTE pal)%%%
> Syntax: none gui.bitmap_draw(Number x, Number y, DBITMAP bmp)
* Since rr1-Δ4.

Render bitmap __bmp__ with upper-left corner at (__x__,__y__).

If the bitmap is indexed, it will be rendered using palette __pal__.

!!gui.palette_new
> Syntax: PALETTE gui.palette_new()
* Since rr1-Δ4.
* Can be used anywhere.

Returns a new PALETTE object. All colors are initialized to transparent.

!!gui.palette_set
> Syntax: none gui.palette_set(PALETTE pal, number idx, number color)
* Since rr1-Δ4.
* Can be used anywhere.

Sets the color index __idx__ in palette __pal__ to color __color__.

!!gui.bitmap_new
> Syntax: BITMAP gui.bitmap_new(number width, number height, __false__)%%%
> Syntax: DBITMAP gui.bitmap_new(number width, number height, __true__)
* Since rr1-Δ4.
* Can be used anywhere.

Returns a new bitmap of size __width__ by __height__.

The third argument determines if the bitmap is indexed (false) or not (true).

!!gui.bitmap_pset
> Syntax: none gui.bitmap_pset(BITMAP/DBITMAP bmp, number x, number y, number c)
* Since rr1-Δ4.
* Can be used anywhere.

Sets the pixel at (__x__,__y__) in bitmap __bmp__ to color __c__.

The __c__ is color index for indexed bitmaps and color for non-indexed ones.

!!gui.bitmap_size
> Syntax: (Number w, Number h) gui.bitmap_size(BITMAP/DBITMAP bmp)
* Since rr1-Δ4.
* Can be used anywhere.

Returns the width (__w__) and height (__h__) of bitmap __bmp__.

!!gui.bitmap_blit
> Syntax: none gui.bitmap_blit(BITMAP target, number dx, number dy, BITMAP source, number sx, number sy, number w, number h, [[number colorkey])%%%
> Syntax: none gui.bitmap_blit(DBITMAP target, number dx, number dy, DBITMAP source, number sx, number sy, number w, number h, [[number colorkey])
* Since rr1-Δ4.
* Can be used anywhere.
* __colorkey__ defaults to NONE.

Blits region of size __w__ by __h__ starting from (__sx__,__sy__) from __source__ to region starting from (__dx__,__dy__) in __target__.

If __colorkey__ is specified, the pixels with that color are not blitted.

Note that this copies pixels, not composites those. This matters when copying (partially) transparent regions.

!!gui.bitmap_load
> Syntax: BITMAP/DBITMAP gui.bitmap_load(string filename)
* Since rr1-Δ4.
* Can be used anywhere

Loads BITMAP or DBITMAP from file __filename__ and returns the result.

If the result is indexed or not depends on the file.

!!gui.rainbow
> Syntax: Number gui.rainbow(Number step, Number steps, Number base)
* Since rr1-Δ6.
* Can be used anywhere

Performs hue rotation on color __base__.

The rotation is __step__/__steps__ of full hue circle. The positive direction is red->yellow->green->cyan->blue->magenta->red.

The rotation will preserve saturation, value and opacity.

!!!Hostmemory functions
!!(Generic)
These read/write memory space that is preserved over saves and loads.

All functions use little-endian byte order.

The data types are:
* byte (unspecified is byte) is 8 bits.
* word is 16 bits.
* dword is 32 bits.
* qword is 64 bits.

!!hostmemory.read / hostmemory.readbyte / hostmemory.readword / hostmemory.readdword / hostmemory.readqword
> Syntax: Number hostmemory.read(Number address)%%%
> Syntax: Number hostmemory.readbyte(Number address)%%%
> Syntax: Number hostmemory.readword(Number address)%%%
> Syntax: Number hostmemory.readdword(Number address)%%%
> Syntax: Number hostmemory.readqword(Number address)

Returns the unsigned value read from address __address__ (or false if out of bounds). 

!!hostmemory.readsbyte / hostmemory.readsword / hostmemory.readsdword / hostmemory.readsqword
> Syntax: Number hostmemory.readsbyte(Number address)%%%
> Syntax: Number hostmemory.readsword(Number address)%%%
> Syntax: Number hostmemory.readsdword(Number address)%%%
> Syntax: Number hostmemory.readsqword(Number address)

Returns the signed (two's complement) value read from address __address__ (or false if out of bounds).

!!hostmemory.write / hostmemory.writebyte / hostmemory.writeword / hostmemory.writedword / hostmemory.writeqword
> Syntax: Number hostmemory.write(Number address, Number value)%%%
> Syntax: Number hostmemory.writebyte(Number address, Number value)%%%
> Syntax: Number hostmemory.writeword(Number address, Number value)%%%
> Syntax: Number hostmemory.writedword(Number address, Number value)%%%
> Syntax: Number hostmemory.writeqword(Number address, Number value)

Writes the value __value__ (two's complement if negative) to address __address__ (extending memory if out of bounds).

!!!Input functions
!!(Generic)
Unless otherwise noted, these are only valid in __on_input__ callback.

Physical controllers 0-3 are on port #1 and controllers 4-7 are on port #2.

The control indices are:
|Index|SNES gamepad|GB(C) gamepad|mouse|justifier|superscope|
|0|B|A|xaxis|xaxis|xaxis|
|1|Y|B|yaxis|yaxis|yaxis|
|2|select|select|L|trigger|trigger|
|3|start|start|R|start|cursor|
|4|up|right|-|-|turbo|
|5|down|left|-|-|pause|
|6|left|up|-|-|-|
|7|right|down|-|-|-|
|8|A|-|-|-|-|
|9|X|-|-|-|-|
|10|L|-|-|-|-|
|11|R|-|-|-|-|

!!input.set
> Syntax: none input.set(number controller, number index, number value)
* This function does nothing in read-only mode.

Set input on physical controller __controller__ control index __index__ to value __value__.

In case of buttons, zero is released, anything else is pressed.

!!input.get
> Syntax: number input.get(number controller, number index)

Returns the value of physical controller __controller__ input index __index__.

!!input.reset
> Syntax: none input.reset([[number delay])
* Only valid in __on_input__ callback with subframe flag clear.
* __delay__ defaults to 0.
* Nonzero __delay__ since rr1-Δ8.
* This function does nothing in read-only mode.

Resets console. If __delay__ is specified and delayed reset is supported, the reset will be delayed by that amount (but still at most one frame).

!!input.raw
> Syntax: table input.raw()
* Can be used anywhere.

Returns a table of tables. The outer table is indexed by key name.

The inner table has the following fields:
* last_value: Raw value of input.
  * For keys, this is 0 for released, 1 for pressed.
  * For mouse, this is coordinate relative to top left of draw area (note that this may be negative!).
  * For axis types, this is raw value of axis.
  * For hats, 1 is up, 2 is right, 4 is down, 8 is left. Diagonals are OR of primary directions.
* cal_left: Left/Top calibration limit.
* cal_center: Center calibration value.
* cal_right: Right/Bottom calibration limit.
* cal_tolerance: Tolerance of button (the width of dead zone, 0<x<1).
* ktype: The type of the key.
  * disabled: Disabled axis.
  * key: Key
  * axis: Axis
  * axis-inverse: Axis (inverted).
  * hat: Hat
  * mouse: Mouse axis.
  * pressure-mp: Pressure-sensitive button, reads cal_left when released, cal_right when pressed.
  * pressure-m0: Pressure-sensitive button, reads cal_left when released, cal_center when pressed.
  * pressure-0m: Pressure-sensitive button, reads cal_center when released, cal_left when pressed.
  * pressure-0p: Pressure-sensitive button, reads cal_center when released, cal_right when pressed.
  * pressure-pm: Pressure-sensitive button, reads cal_right when released, cal_left when pressed.
  * pressure-p0: Pressure-sensitive button, reads cal_right when released, cal_center when pressed.

For mouse axes, cal_left is top/left edge of draw area, cal_center is top/left edge of game area, and cal_right is bottom/right edge of draw area.

!!input.keyhook
> Syntax: none input.keyhook(string key, boolean enabled)
* Can be used anywhere.

If __enabled__=true, requests __on_keyhook__ callback to happen when key __key__ changes state.

If __enabled__=false, requests that state changes on key __key__ do not cause callbacks to __on_keyhook__.

!!input.geta
> Syntax: Tuple input.geta(Number controller)
* Since rr1-Δ5

Get all input indices of physical controller __controller__ at once. The returned tuple is in control index order.

!!input.seta
> Syntax: none input.seta(Number controller, Number values...)
* Since rr1-Δ5

Set all input indices of physical controller __controller__ at once. The __value__s are in control index order.

!!input.joyget
> Syntax: table input.joyget(Number controller)
* Since rr1-Δ15

Returns a table, indexes by control name containing state of logical controller __controller__.

!!input.joyset
> Syntax: none input.joyset(Number controller, table state)
* Since rr1-Δ14ε1

Set state of logical controller __controller__ to __state__. The __state__ is indexed by control name.

For buttons, nil/false is released, anything else is pressed (normal lua boolean rules).

!!!Memory functions
!!(Generic)
These functions read/write console memory space.

The byte order used depends on the target address. Normally it is little-endian, but DSP memory is host-endian.

The data types are:
* byte (unspecified is byte) is 8 bits.
* word is 16 bits.
* dword is 32 bits.
* qword is 64 bits.

!!memory.read / memory.readbyte / memory.readword / memory.readdword / memory.readqword
> Syntax: Number memory.read(Number address)%%%
> Syntax: Number memory.readbyte(Number address)%%%
> Syntax: Number memory.readword(Number address)%%%
> Syntax: Number memory.readdword(Number address)%%%
> Syntax: Number memory.readqword(Number address)

Returns the unsigned value read from address __address__ (out of bounds bytes read as zeroes).

!!memory.readsbyte / memory.readsword / memory.readsdword / memory.readsqword
> Syntax: Number memory.readsbyte(Number address)%%%
> Syntax: Number memory.readsword(Number address)%%%
> Syntax: Number memory.readsdword(Number address)%%%
> Syntax: Number memory.readsqword(Number address)

Returns the signed (two's complement) value read from address __address__ (out of bounds bytes read as zeroes).

!!memory.write / memory.writebyte / memory.writeword / memory.writedword / memory.writeqword
> Syntax: None memory.write(Number address, Number value)%%%
> Syntax: None memory.writebyte(Number address, Number value)%%%
> Syntax: None memory.writeword(Number address, Number value)%%%
> Syntax: None memory.writedword(Number address, Number value)%%%
> Syntax: None memory.writeqword(Number address, Number value)

Writes the value __value__ (two's complement if negative) to address __address__ (writes out of bounds are ignored).

!!memory.mapbyte / memory.mapsbyte / memory.mapword / memory.mapsword / memory.mapdword / memory.mapsdword / memory.mapqword / memory.mapsqword
> Syntax: Table memory.map<type>()%%%
> Syntax: Table memory.map<type>(Number base, Number aperturesize)
* Since: rr1-Δ15ε2

Map area of size __aperturesize__ starting from __base__ (the entire map space if not specified) with specified type.

The returned table can be read/written to read/write console memory space.

The index values to this table are measured in bytes.

!!memory.map_structure()
> Syntax: MAP_STRUCTURE memory.map_structure()%%%
> Syntax: none MAP_STRUCTURE(String field, Number address, String type)%%%
> Syntax: MAP_STRUCTURE:<field>
* Since: rr1-Δ15ε2

Returns an object that works like a structure that maps console memory variables as fields.

On call to object, the field __field__ is mapped to memory address __address__ (with type __type__, which can be "byte", "sbyte", "word", "sword", "dword", "sdword", "qword" or "sqword").

!!memory.vma_count
> Syntax: number memory.vma_count()

Returns the number of VMAs active.

!!memory.read_vma
> Syntax: Table/Nil memory.read_vma(Number vma)

Returns a table (Nil if index is out of range) about __vma__th VMA (zero-based).

The returned table has the following fields:
* region_name: Readable name of region
* baseaddr: Starting address of region.
* size: Size of region in bytes.
* lastaddr: Last address belonging to the region.
* readonly: True if VMA is read-only, false if VMA is writable.
* native_endian: True if VMA is native-endian, false if little-endian.

Invalid VMA index causes nil to be returned.

!!memory.find_vma
> Syntax: Table/Nil memory.find_vma(Number address)

Return the information (the same table as returned by memory.read_vma) about the VMA where address __address__ belongs to.

If the address __address__ is not covered by any VMA, returns nil.

!!memory.hash_state
> Syntax: String memory.hash_state()

Return hash (hexadecimal) of state of the entire system. Mainly useful for debugging core savestate code.

!!memory.hash_region
> Syntax: String memory.hash_region(Number base, Number size)
* Since rr1-Δ8

Returns the SHA-256 hash (hexadecimal) of the contents of memory in region of size __size__ starting from __base__.

!!memory.readregion
> Syntax: Table memory.readregion(Number base, Number size)
* Since: rr1-Δ15ε2

Returns a table (zero-based) containing the byte values of memory region of size __size__ starting from __base__.

Note that behavior is undefined if the specified range crosses a VMA boundary.

!!memory.writeregion
> Syntax: None memory.writeregion(Number base, Number size, Table data)
* Since: rr1-Δ15ε2

Writes contents of tabe __data__ (zero-based) as byte values to memory region of size __size__ starting from __base__.

Note that behavior is undefined if the specified range crosses a VMA boundary.

!!!Movie functions
!!movie.currentframe
> Syntax: Number movie.currentframe()

Returns the current frame number. 

!!movie.framecount
> Syntax: Number movie.framecount()

Returns the number of frames in movie.

!!movie.readonly
> Syntax: Boolean movie.readonly()

Returns true in readonly mode, otherwise false.

!!movie.readwrite
> Syntax: none movie.readwrite()

Set readwrite mode.

Note: Does not trigger callback to __on_readwrite__.

!!movie.frame_subframes
> Syntax: Number movie.frame_subframes(Number frame)

Returns the number of subframes in frame __frame__.

!!movie.read_subframes
> Syntax: Table movie.read_subframes(Number frame, Number subframe)

Reads subframe __subframe__ (0-based) of frame __frame__.

Return value is a table with numeric indices:
* 0: Frame sync flag.
* 1: Reset flag.
* 2: Delay field low (units of 0).
* 3: Delay field high (units of 10000)
* 4-99: Controller buttons/axes.

The index i of controller c is at table index 12 * c + i + 4.

Buttons/flags read as 0 (released, not set) or 1 (pressed, set).

!!movie.read_rtc
> Syntax: (Number seconds, Number sseconds) movie.read_rtc()

Returns the current RTC time. __seconds__ is in whole seconds (since 19700101T000000Z) and __sseconds__ is  subsecond ticks (32040.5*768 per second for SNES, 32768*64 per second for second for GB(C)) in second.

!!movie.unsafe_rewind
> Syntax: none movie.unsafe_rewind()
> Syntax: none movie.unsafe_rewind(UNSAFEREWIND r)
* Since rr1-Δ9.

If called without parameters, triggers call to __on_set_rewind__ with state.

If called with parameter __r__, rewinds to that state.

The state rewinded must be in past or the results are undefined.

!!movie.rerecords
> Syntax: Number movie.rerecords()
* Since: rr1-Δ14.

Returns the current rerecord count.

!!!Settings functions
!!(Generic)
On failure, the first return value is nil and the second is error message.

!!settings.set
> Syntax: true settings.set(String name, String value)

Sets setting __name__ to value __value__. 

!!setting.get
> Syntax: String/false settings.get(String name)

Reads setting __name__. Returns value or false if setting is not set.

!!setting.blank
> Syntax: true setting.blank(String name)

Blanks setting __name__. Returns true on success.

!!setting.is_set
> Syntax: boolean setting.is_set(String name)

Checks if setting __name__ is set. Returns true if it is, false if it isn't.

!!!Misc. functions
!!exec
> Syntax: none exec(String cmd)

Invokes emulator command __cmd__.

!!print
> Syntax: none print(...)
Print value(s)

Prints values of all arguments (note: Table, function, thread, light userdata and userdata values can't be printed). The arguments are printed separated by tabs.

!!utime
> Syntax: (Number secs, Number usecs) utime()
* Since: rr1-Δ5.

Return the current time. __secs__ is the number of seconds since 19700101T000000Z. __usecs__ is the number of microseconds within second.

!!emulator_ready
> Syntax: boolean emulator_ready()
* Since: rr1-Δ5.

Returns true if on_startup has already been called, false otherwise.

!!set_idle_timeout
> Syntax: none set_idle_timeout(Number microsecs)
* Since: rr1-Δ5.

After __microsecs__ microseconds have passed and the emulator is idle, call the on_idle callback.

!!set_timer_timeout
> Syntax: none set_timer_timeout(Number microsecs)
* Since: rr1-Δ5.

After __microsecs__ microseconds have passed, call the on_timer callback.

!!bus_address
> Syntax: Number bus_address(Number address)
* Since: rr1-Δ10.

Returns the map address corresponding to address __address__ on physical console bus.

Currently only supported for SNES & co.

!!loopwrapper(
> Syntax: Function loopwrapper(Function fn, ...)
* Since: rr1-Δ14ε1

First calls function __fn__ with function suspending the execution of the function when called and any remaining arguments.

When the function calls the suspend function, loopwrapper returns function that will resume __fn__ when called.

The suspend function returns the values passed to resume function as parameters.

This is handy for using functions that have internal loops, that need to run over a long time, as callbacks.

!!!Callbacks
!!(Generic)
These all are defined by Lua scripts.

Return fast from these hooks or the performance suffers. Not returning at all locks up the emulator.

!!on_paint
Called when screen is rerendered. Any draw primitives here affect the drawn screen.

Parameter: boolean non_synthetic

__non_synthetic__ is true if __on_paint__ is triggered by actual frame from console or by a subframe (if requested). It is false for calls triggered by gui.request_paint().

!!on_video
Called when video frame is rendered. Any draw primitives here affect dumped video frame.

* May be called multiple times per frame if multiple dumpers are active.
* SDMP dumper does not call this.

!!on_input
Called when input for frame is decided. May change the input in readwrite mode.

Parameter: boolean subframe

__subframe__ is true if this is in response to subframe. Otherwise false.

!!on_reset
Called when console resets.

!!on_frame
Called after frame has completed (after __on_paint__)

!!on_readwrite
Called when entering readwrite mode.

!!on_startup
Called when the emulator starts up.

!!on_pre_load
* Parameter #1: String savename

Called before loading a savestate or movie.

Parameter: String __name__

The name of savestate or movie to load is passed as __name__.

!!on_err_load
Called if loading savestate or movie failed.

Parameter: String __name__

The name of savestate or movie attempted to load is passed as __name__.

!!on_post_load
Called if loading savestate or movie succeeded.

* Parameter: String name
* Parameter: boolean is_state.

The name of savestate/movie is __name__. __is_state__ is true if savestate, false for movies.

!!on_pre_save
Called before saving savestate or movie (except if movie save was requested from Lua).

* Parameter: String name
* Parameter: boolean is_state.

__name__ is the name of savestate or movie. __is_state__ is true if this is savestate, false if movie.

!!on_err_save
Called if saving savestate or movie failed (except if movie save was requested from Lua).

* Parameter: String name

__name__ is the name of savestate or movie that failed to save.

!!on_post_save
Called if saving savestate or movie succeeded (except if movie save was requested from Lua).

* Parameter: String name
* Parameter: boolean is_state.

__name__ is the name of savestate or movie. __is_state__ is true if this is savestate, false if movie.

!!on_snoop
Called just before answering a poll from emulator core. Can't alter the result.

* Parameter: number port
* Parameter: number controller
* Parameter: number index
* Parameter: number value.

The poll is for port __port__, controller __controller__, control index __index__ and the value to be returned is __value__.

!!on_quit
Called just before the emulator quits.

!!on_keyhook
Called if status of key has changed (and callbacks have been requested for that key).

* Parameter: String key
* Parameter: Table state

The key state change is for is __key__. __state__ is state table, in the same format  as the inner tables of input.raw.

!!on_set_rewind
Called when unsafe rewind point has been set up.

* Parameter: UNSAFEREWIND state

The state object is passed as __state__.

!!on_pre_rewind
Called just before unsafe rewind occurs.

!!on_post_rewind
Called just after unsafe rewind has occured.

!!on_frame_emulated
* Since: rr1-Δ5.

Called just after frame emulation finishes, but before __on_paint__.

!!on_idle
Called when the specified idle timeout expires and the emulator is idle.

!!on_timer
Called when the specified timer timeout expires.