LUA Functions
Functions
The functions and examples on this page are from v1.9 of the emulator (Tekken 3 V1.01)
Emulator
| Function | Parameters | Notes |
|---|---|---|
| AppHost_GetLocaleTag | ||
| EM_AddGameOSDHook | ||
| EM_AddSnapshotLoadedHook | ||
| EM_AddSnapshotPreLoadedHook | ||
| EM_AddSplashScreenHook | ||
| EM_AddValidTitle | ||
| EM_AddVsyncHook | ||
| EM_CRC32 | ||
| EM_DiscSwap | ||
| EM_GetCDRom | Depreciated (will crash application) Use EM_GetLegacyTitleId to differentiate discs after a call to EM_LoadDiscId()Use EM_GetStoreRegion for store region info. | |
| EM_GetDiscId | Returns the number of the active disc eg. 1 | |
| EM_GetDiscImageName | Returns the filename of the active disc eg. RallyCross_SCUS94308_SCEA.bin | |
| EM_GetImageDataPath | ||
| EM_GetLegacyTitleId | ||
| EM_GetRemapBinding | ||
| EM_GetRequestNtscRegion | ||
| EM_GetSettingCli | ||
| EM_GetStoreRegion | ||
| EM_Launch | ||
| EM_LoadConfig | Returns a LUA table from the users save data | |
| EM_LoadDiscId | ||
| EM_LoadState | ||
| EM_NeoMode | Returns true on a PS4 Pro | |
| EM_PadRead | ||
| EM_PadReadLeftStick | ||
| EM_PadReadRightStick | ||
| EM_PadSetButtonsMode | ||
| EM_PadWrite | ||
| EM_Reboot | Number | Reboot and load specified disc id1 would appear to load disc id 0 |
| EM_RemoveGameOSDHook | ||
| EM_RemoveSnapshotLoadedHook | ||
| EM_RemoveSnapshotPreLoadedHook | ||
| EM_RemoveSplashScreenHook | ||
| EM_RemoveVsyncHook | ||
| EM_SaveConfig | Table | Saves the supplied LUA table to the users save data |
| EM_SaveState | String Optional | Creates a temporary save state |
| EM_SendCommands | String, String | Unclear what commands this accepts |
| EM_SetCDRom | ||
| EM_SetOption | String, String | Sets some emulator Settings menu options |
| EM_SetRemapBinding | Number, String, String | Remap controller inputs Changes are reflected in the Customise Button Assignments menu |
| EM_SetSettingCli | String | Sets a command line executable parameter |
| EM_SnapRead | String | Unclear what this does |
| EM_SnapWrite | String | Unclear what this does |
| EM_ThrottleMax | ||
| EM_ThrottleNormal | ||
| TR_Unlock | Number | Unlocks a trophy |
| uiAddScriptedMenuItem | String, Table { Function, Function } | Adds an item to the custom menu |
| uiAddScriptedMenuLabel | String | Creates a custom menu under Settings |
| uiDrawFill | Number, Number, Number, Number, Number | |
| uiDrawImage | String, Number, Number | |
| uiDrawText | String, Number, Number | |
| uiGetTextSize | String, Number | |
| uiPopMenu | ||
| uiPushMenu | ||
| uiScriptAssetPath | Returns the asset path (--assets-dir?)eg. /app0/scripts/ | |
| uiSetCursorPos | Number, Number |
CPU
| Function | Parameters | Notes |
|---|---|---|
| R3K_AddHook | Number, Number, Function | Hook a program memory address LUA function is executed prior to the instruction at the hooked address Can be applied during runtime |
| R3K_BurnCycles | Number | |
| R3K_FlushCache | ||
| R3K_GetGpr | Number | Returns a register See the gpr table |
| R3K_GetHi | Returns a special register Stores half the result of large integer multiplication | |
| R3K_GetLo | Returns a special register Stores half the result of large integer multiplication | |
| R3K_GetPC | Returns the Program Counter The next instruction to be executed | |
| R3K_InsnReplace | Number, Number, Number | Directly replaces a CPU instruction at a program memory address Can only be applied at initial script load time Replacement is a MIPS instruction in hex |
| R3K_ReadMem16 | Number | Returns a halfword from a memory address 16 bits / 2 bytes |
| R3K_ReadMem32 | Number | Returns a word from a memory address 32 bits / 4 bytes |
| R3K_ReadMem8 | Number | Returns a byte from a memory address 8 bits / 1 byte |
| R3K_ReadMemFloat | Number | |
| R3K_ReadMemString | Number | |
| R3K_RemoveHook | Number, Number | Removes a hook previously added at a program memory address using R3K_AddHook |
| R3K_SetGpr | Number, Number | Write to a register See the gpr table |
| R3K_SetHi | Number | Set a special register Stores half the result of large integer multiplication |
| R3K_SetLo | Number | Set a special register Stores half the result of large integer multiplication |
| R3K_SetPC | Number | Set the Program Counter The next instruction to be executed |
| R3K_WriteMem16 | Number, Number | Set a halfword at a memory address 16 bits / 2 bytes |
| R3K_WriteMem32 | Number, Number | Set a word at a memory address 32 bits / 4 bytes |
| R3K_WriteMem8 | Number, Number | Set a byte at a memory address 8 bits / 1 byte |
| R3K_WriteMemFloat | Number, Number | |
| R3K_WriteMemString | Number, Number, String | |
| R3K_WriteMemStringZ | Number, Number, String | Set a null terminated (?) string at a memory address |
Developer
Tables
gpr
The gpr table contains entries for addressing the CPU registers by name.
For example, to read register v0 you can use R3K_GetGpr(gpr.v0).
| Name | Value | Notes |
|---|---|---|
| zero | 0 | Always zero |
| at | 1 | Reserved for assembler |
| v0 | 2 | First function return value |
| v1 | 3 | Second function return value |
| a0 | 4 | First function argument |
| a1 | 5 | Second function argument |
| a2 | 6 | Third function argument |
| a3 | 7 | Fourth function argument |
| t0 | 8 | Temporary register |
| t1 | 9 | Temporary register |
| t2 | 10 | Temporary register |
| t3 | 11 | Temporary register |
| t4 | 12 | Temporary register |
| t5 | 13 | Temporary register |
| t6 | 14 | Temporary register |
| t7 | 15 | Temporary register |
| s0 | 16 | Saved register |
| s1 | 17 | Saved register |
| s2 | 18 | Saved register |
| s3 | 19 | Saved register |
| s4 | 20 | Saved register |
| s5 | 21 | Saved register |
| s6 | 22 | Saved register |
| s7 | 23 | Saved register |
| t8 | 24 | Temporary register |
| t9 | 25 | Temporary register |
| k0 | 26 | Kernel register |
| k1 | 27 | Kernel register |
| gp | 28 | Global pointer |
| sp | 29 | Stack pointer |
| fp | 30 | Frame pointer |
| ra | 31 | Return address |
Additional Information and Examples
EM_GetSettingCli
EM_LoadConfig
| Returns | Position | Notes |
|---|---|---|
| Table | 1 | A table of values that has previously been saved |
Allows you to load the contents of a LUA table which has previously been saved to the users save data. See EM_SaveConfig for details on saving.
In official releases, this is most typically used for tracking the state of trophy unlocks.
The data is loaded from file default.lsd within the Application Data (Game Progress and UI Appearance Settings / AppSmall) save file for the game. If there is no saved data then an empty table is returned.
See EM_SaveConfig for examples of saving and loading data.
[libSceSaveData] api_id: 60, userId=0x1702a50d, titleId=, dirName=AppSmall, mountMode=0x00000009(0x00000001), blocks=97, fingerprint=not set
[libSceSaveData] Mounted > userId=0x1702a50d, dirName=AppSmall, mountPoint=/savedata0
LuaSaveData Loaded Config /savedata0/default.lsd (78 bytes)
[libSceSaveData] api_id: 2, mountPoint=/savedata0, umount_type=1, user_id=0x1702a50d, dir_name=AppSmall, mount_mode=0x00000009
EM_SaveConfig
| Parameter | Position | Notes |
|---|---|---|
| Table | 1 | A table of values to be saved |
Allows you to save the contents of a LUA table to the users save data. See EM_LoadConfig for details on loading.
In official releases, this is most typically used for tracking the state of trophy unlocks.
The table can be a simple array, or it could contain key/value pairs. You can nest tables within the table, but you cannot nest functions.
The data is saved to file default.lsd within the Application Data (Game Progress and UI Appearance Settings / AppSmall) save file for the game.
When you call EM_SaveConfig it seems to take a moment before the data is actually written to disk (the function will return and LUA continuing executing). It's probably best to avoid calling EM_SaveConfig and EM_LoadConfig in quick succession, otherwise you may end up loading old data back in.
[libSceSaveData] api_id: 60, userId=0x1702a50d, titleId=, dirName=AppSmall, mountMode=0x00000036(0x00000030), blocks=101, fingerprint=not set
[libSceSaveData] Mounted > userId=0x1702a50d, dirName=AppSmall, mountPoint=/savedata0
[libSceSaveData] api_id: 9, param_type=0
LuaSaveData Wrote Config /savedata0/default.lsd (78 bytes)
[libSceSaveData] Backup at Umount is started. > AppSmall.
[libSceSaveData] api_id: 2, mountPoint=/savedata0, umount_type=1, user_id=0x1702a50d, dir_name=AppSmall, mount_mode=0x00000036
-- This example creates a table containing key/value pairs
-- It contains a string, number, boolean and two nested tables (one containing a simple array, another key/value pairs)
-- Create a table with data you want to save
saveData = {}
saveData.message = "Hello there!"
saveData.counter = 3
saveData.arrayTable = { "First", "Second", "Third" }
saveData.anotherTable = {}
saveData.anotherTable.state = true
-- Save the table to save data
EM_SaveConfig(saveData)
-- For demo purposes, wait 5 seconds between
-- saving and loading the data
-- EM_SaveConfig seems to return before the system has actually
-- committed the data to disk
time = os.time()
while os.difftime(os.time(), time) < 5 do end
-- Load the table back from save data
loadedData = EM_LoadConfig()
-- Print the table contents
function print_table(table, prefix)
for key, value in pairs(table) do
print(prefix, key, value, type(value))
if type(value) == "table" then
print_table(value, key)
end
end
end
print("Printing table contents:")
print_table(loadedData, "loadedData")
Printing table contents:
loadedData message Hello there! string
loadedData arrayTable table: 204d941c0 table
arrayTable 1 First string
arrayTable 2 Second string
arrayTable 3 Third string
loadedData anotherTable table: 204d94080 table
anotherTable state true boolean
loadedData counter 3 number
EM_Reboot
| Parameter | Position | Notes |
|---|---|---|
| Number | 1 | The disc id to load 1 = disc 0 |
Allows you to reboot the emulator and load the specified disc image. 1 seems to load disc 0.
# Immediately after calling the function
[xem_app_reboot] --reboot-title-id=SLUS00797
[xem_app_reboot] --request-ntsc-region=1
[xem_app_reboot] --boot-disc-id=0
[xem_app_reboot] --reboot=true
# During application startup, these settings are shown as being
# applied from the command line
(Config) from command line:
(Config) --reboot-title-id=SLUS00797
(Config) --request-ntsc-region=1
(Config) --boot-disc-id=0
(Config) --reboot=true
EM_SaveState
| Parameter | Position | Notes |
|---|---|---|
| String | 1 | Optional name for the save state file |
Creates a save state, by default at a temporary location /temp0/snapshots/{disc_title_id}/snap-{string}-vm{current_playtime}.bin. Supplying a parameter allows you to set a specific filename.
These save states exist outside of the user accessible save state system.
If you wanted to persist them, you can redirect them using command line parameter --snapshot-dir (previously --savestate-dir) to somewhere like /data/my-savestate-folder.
-- Create a save state with the default filename
EM_SaveState()
-- Create a save state with a specific filename
EM_SaveState("my-savestate.bin")
EM_SetOption
| Parameter | Position | Notes |
|---|---|---|
| String | 1 | The name of the option to change |
| String | 2 | The value to set |
Allows you to programmatically change some of the options available to user under the Settings menu. The option does not need to be visible in order for it to be changeable via this function (ie. Rewind can be enabled or disabled without the emulator running with parameter --userui-show-toggle-enhancements-setting).
Additionally some options are not visible in the Setting, such as forcing the controller to digital mode.
| Option | Type | Default | Values | Notes |
|---|---|---|---|---|
| active_post_effect_id | String | Default Modern RetroClassic RetroModern | The name of a Visual Preset JSON file ie. files within /app0/global/presets | |
| boot_disc_id | Number | 0 | ||
| debug_vram_read_delay | Number | 3 | ||
| display_build_information | Boolean | true | ||
| display_video_mode | String | Aspect_4_3_FOR_16_9 | Aspect_1_1 Aspect_4_3_FOR_16_10 Aspect_4_3_FOR_16_9 Native SquarePixels WideZoomStretched | Video Aspect ratio options |
| enable50To60HzVideoConversion | Boolean | false | PAL frame blending toggle | |
| enhancements_enabled | Boolean | false | Rewind functionality toggle | |
| force_analog | Boolean | false | ||
| force_digital | Boolean | false | Controller becomes an original digital pad No user facing option for this Applies immediately | |
| present_delay | Number | -2 | ||
| PSP_right_stick_deadzone_x | Number | 42 | PSPHD carryover? | |
| PSP_right_stick_deadzone_y | Number | 42 | PSPHD carryover? | |
| psp_right_stick_remap_mode | String | None | PSPHD carryover? | |
| psp_right_stick_semicircle_arc_range | Number | 45 | PSPHD carryover? | |
| request_ntsc | Boolean | true | Likely used with region switching functionality to enable a LUA script to select the correct disc image | |
| underscan | Number | 0 | PSPHD carryover? |
EM_SetRemapBinding
| Parameter | Position | Notes |
|---|---|---|
| Number | 1 | The id of the controller |
| String | 2 | Input name (physical controller) |
| String | 3 | Destination input name (virtual PS1 controller) |
Allows you to programmatically remap controller buttons, with changes reflected on Customise Button Assignments menu.
The parameters expect the controller id (0 to 3), the name of the button on the physical controller to be remapped, and the name of the input name on the virtual controller (ie. the original PlayStation input).
To undo a remapping, you simply put the name of the input as both parameters.
eg: EM_SetRemapBinding(0, "kPad_BUTTON_CROSS", "kPad_BUTTON_CROSS")
The Customise Button Assignments interface has a limitation where any remapped buttons are automatically swapped. Remapping the buttons using this function does not have this limitation, and you can remap multiple buttons onto another button without removing that original button. See the Armored Core example.
| Input Name | Notes |
|---|---|
| kPad_BUTTON_L3 | |
| kPad_BUTTON_R3 | |
| kPad_BUTTON_OPTIONS | |
| kPad_BUTTON_UP | |
| kPad_BUTTON_RIGHT | |
| kPad_BUTTON_DOWN | |
| kPad_BUTTON_LEFT | |
| kPad_BUTTON_L2 | |
| kPad_BUTTON_R2 | |
| kPad_BUTTON_L1 | |
| kPad_BUTTON_R1 | |
| kPad_BUTTON_TRIANGLE | |
| kPad_BUTTON_CIRCLE | |
| kPad_BUTTON_CROSS | |
| kPad_BUTTON_SQUARE | |
| kPad_BUTTON_TOUCH_PAD_LEFT | |
| kPad_BUTTON_TOUCH_PAD_RIGHT | |
| kPad_AXIS_LXL | Left Analog Left |
| kPad_AXIS_LXR | Left Analog Right |
| kPad_AXIS_LYU | Left Analog Up |
| kPad_AXIS_LYD | Left Analog Down |
| kPad_AXIS_RXL | Right Analog Left |
| kPad_AXIS_RXR | Right Analog Right |
| kPad_AXIS_RYU | Right Analog Up |
| kPad_AXIS_RYD | Right Analog Down |
-- Swap the Cross and Triangle buttons
-- Player 1
EM_SetRemapBinding(0, "kPad_BUTTON_CROSS", "kPad_BUTTON_TRIANGLE")
EM_SetRemapBinding(0, "kPad_BUTTON_TRIANGLE", "kPad_BUTTON_CROSS")
-- Player 2
EM_SetRemapBinding(1, "kPad_BUTTON_CROSS", "kPad_BUTTON_TRIANGLE")
EM_SetRemapBinding(1, "kPad_BUTTON_TRIANGLE", "kPad_BUTTON_CROSS")
-- Quake 2 "Both Sticks" control scheme has strafe and turn on the wrong
-- analog sticks, relative to a modern control scheme.
-- This swaps the x-axis between analog sticks so move and strafe are on the left stick
-- and turn and look up/down are on the right.
-- Player 1
EM_SetRemapBinding(0, "kPad_AXIS_LXL", "kPad_AXIS_RXL")
EM_SetRemapBinding(0, "kPad_AXIS_LXR", "kPad_AXIS_RXR")
EM_SetRemapBinding(0, "kPad_AXIS_RXL", "kPad_AXIS_LXL")
EM_SetRemapBinding(0, "kPad_AXIS_RXR", "kPad_AXIS_LXR")
-- Player 2
EM_SetRemapBinding(1, "kPad_AXIS_LXL", "kPad_AXIS_RXL")
EM_SetRemapBinding(1, "kPad_AXIS_LXR", "kPad_AXIS_RXR")
EM_SetRemapBinding(1, "kPad_AXIS_RXL", "kPad_AXIS_LXL")
EM_SetRemapBinding(1, "kPad_AXIS_RXR", "kPad_AXIS_LXR")

-- Armored Core did not have support for analog inputs, but with remapping
-- you can make a modern control scheme
--
-- This kind of remapping is not possible from the Customise Button Assignments interface, because
-- remapping the LEFT and RIGHT inputs would ubind them from the physical LEFT and RIGHT buttons
-- making menu navigation extremely difficult
-- Turn Left Right Stick Left (original input Left)
EM_SetRemapBinding(0, "kPad_AXIS_RXL", "kPad_BUTTON_LEFT")
-- Turn Right Right Stick Right (original input Right)
EM_SetRemapBinding(0, "kPad_AXIS_RXR", "kPad_BUTTON_RIGHT")
-- Look Up Right Stick Up (original input L2)
EM_SetRemapBinding(0, "kPad_AXIS_RYU", "kPad_BUTTON_L2")
-- Look Down Right Stick Down (original input R2)
EM_SetRemapBinding(0, "kPad_AXIS_RYD", "kPad_BUTTON_R2")
-- Strafe Left Left Stick Left (original input L2)
EM_SetRemapBinding(0, "kPad_AXIS_LXL", "kPad_BUTTON_L1")
-- Strafe Right Left Stick Right (original input R1)
EM_SetRemapBinding(0, "kPad_AXIS_LXR", "kPad_BUTTON_R1")
-- Forward Left Stick Up (original input UP)
EM_SetRemapBinding(0, "kPad_AXIS_LYU", "kPad_BUTTON_UP")
-- Backwards Left Stick Down (original input Down)
EM_SetRemapBinding(0, "kPad_AXIS_LYD", "kPad_BUTTON_DOWN")
-- Fire R2 (original input Square)
EM_SetRemapBinding(0, "kPad_BUTTON_R2", "kPad_BUTTON_SQUARE")
-- Melee L2 (original input Circle)
EM_SetRemapBinding(0, "kPad_BUTTON_L2", "kPad_BUTTON_CIRCLE")


EM_SetSettingCli
| Parameter | Position | Notes |
|---|---|---|
| String | 1 | The name and value of the parameter to set eg. "--userui-settings-graphics=1" |
Allows you to apply or change an executable command line parameter at run time. Note that not all commands will have immediate effect, with some requiring a reload of the emulator. A straight reboot of the emulator will not persist commands applied via this function.
For a list of available parameters see Command Line Parameters.
You can set non-existent settings, which might be useful as a method of keeping track of what options have been selected during the current session when implementing a custom menu using uiAddScriptedMenuLabel
-- Display the Graphics option on the emulators Settings menu
EM_SetSettingCli("--userui-settings-graphics=1")
uiAddScriptedMenuItem
| Compatibility | |
|---|---|
| Armored Core Master of Arena V1.02+ Armored Core Project Phantasma V1.03+ | ✅ |
| Parameter | Position | Notes |
|---|---|---|
| String | 1 | The name of the menu option. This can be regular text, or it can be the name of an entry in the localisation file. eg. "i18nHumanPlus" |
| Table | 2 | A table containing two functions. The first function is called to determine the state of the option (ticked or unticked). The second function is called when the user selects the option. |
Adds an option to the custom menu under the emulators Settings menu. You should call this after creating the custom menu option with uiAddScriptedMenuLabel.
See Scripted Menu for a detailed explanation.
uiAddScriptedMenuLabel
| Compatibility | |
|---|---|
| Armored Core Master of Arena V1.02+ Armored Core Project Phantasma V1.03+ | ✅ |
| Parameter | Position | Notes |
|---|---|---|
| String | 1 | The name of the menu. This can be regular text, or it can be the name of an entry in the localisation file. eg. "i18nHumanPlus" |
Adds a custom menu under the emulators Settings menu. If a menu has previously been created, calling this function again will re-instantiate the custom menu (thus removing any previously added options).
See Scripted Menu for a detailed explanation.
R3K_SetPC
| Parameter | Position | Notes |
|---|---|---|
| Number | 1 | A program memory address to set the Program Counter to |
Allows you to set the Program Counter to a specific program memory address, which will set what instruction will be executed next.
Useful when you've hooked a program memory address and don't want that original instruction to actually be executed.
--- You've hooked a program memory address but don't want to execute the original instruction
DOOR_START_PC = 0x80013bc4
DOOR_START_OP = 0x27BDFFE8
R3K_AddHook(DOOR_START_PC, DOOR_START_OP, function()
print("!!! Starting Door Sequence !!! ")
EM_ThrottleMax()
R3K_SetGpr(gpr.v0, 0x8001417C)
-- Increment the current Program Counter by 4 to move to the next instruction
R3K_SetPC(R3K_GetPC() + 0x4)
end