* 1 new Lua function in Joypad library: getimmediate()

* 1 new Lua function in TAS Editor library: getsuperimpose()
* added 5 new Lua scripts demonstrating some TAS Editor library functions
* updated fceux.chm and online documentation, uploaded HelpNDoc3 project file

[[Split portion of a mixed commit.]]
This commit is contained in:
ansstuff 2012-02-01 22:02:26 +00:00
parent b935762d10
commit c1469cb418
18 changed files with 408 additions and 21 deletions

View File

@ -1,3 +1,12 @@
02-feb-2012 - AnS - updated fceux.chm and online documentation, uploaded HelpNDoc3 project file
02-feb-2012 - AnS - added Lua scripts demonstrating some TAS Editor library functions
02-feb-2012 - AnS - new Lua function in TAS Editor library: getsuperimpose()
02-feb-2012 - AnS - new Lua function in Joypad library: getimmediate()
30-jan-2012 - AnS - Taseditor: 9 new Lua functions in TAS Editor library
30-jan-2012 - AnS - Taseditor: Added "Restore Playback (TAS Editor)" hotkey (Enter by default)
30-jan-2012 - AnS - Taseditor: Help->Show Tooltips
30-jan-2012 - AnS - Taseditor: quicksave/quickload hotkeys save/load current branch
23-jan-2012 - prg - sdl: pause will now show/ungrab cursor in fullscreen. this can be disabled with the SDL.NoFullscreenCursor option
12-jan-2012 - AnS - Tasedit: File->New Project, INPUT_TYPE_1P
12-jan-2012 - AnS - Tasedit: resizing TAS Editor window

View File

@ -0,0 +1,61 @@
---------------------------------------------------------------------------
-- Display Input at Selection cursor
---------------------------------------------------------------------------
-- Showcases following functions:
-- * taseditor.getselection()
-- * taseditor.getinput()
---------------------------------------------------------------------------
-- Usage:
-- Run the script, unpause emulation (or simply Frame Advance once).
-- Now you can see additional joypad icon at the bottom left corner of FCEUX screen.
-- This icon displays which buttons are held at the selected frame.
-- If you have several frames selected, the joypad icon will only display buttons
-- of the first selected frame.
-- By default the script only shows 1P joypad, but you can change "num=2, on=false"
-- to "num=2, on=true" to also display 2P joypad and so on.
---------------------------------------------------------------------------
pads = {
{num=1, on=true, color="red", x=9, y=200, w=34, h=10},
{num=2, on=false, color="yellow", x=54, y=200, w=34, h=10},
{num=3, on=false, color="green", x=99, y=200, w=34, h=10},
{num=4, on=false, color="orange", x=144, y=200, w=34, h=10}
}
buttons = {
A = {x=30, y=5, w=3, h=3, bitmask=1},
B = {x=24, y=5, w=3, h=3, bitmask=2},
select = {x=18, y=7, w=3, h=1, bitmask=4},
start = {x=12, y=7, w=3, h=1, bitmask=8},
up = {x=4, y=1, w=2, h=2, bitmask=16},
down = {x=4, y=7, w=2, h=2, bitmask=32},
left = {x=1, y=4, w=2, h=2, bitmask=64},
right = {x=7, y=4, w=2, h=2, bitmask=128}
}
function draw_joypads()
if (taseditor.engaged()) then
selection_table = taseditor.getselection();
if (selection_table ~= nil) then
selection_start = selection_table[1];
for _, pad in ipairs(pads) do
if pad.on then
gui.drawbox(pad.x, pad.y, pad.x+pad.w, pad.y+pad.h, "#3070ffb0")
gui.drawbox(pad.x+4, pad.y+4, pad.x+6, pad.y+6, "black")
controller = taseditor.getinput(selection_start, pad.num)
for name, btn in pairs(buttons) do
if (AND(controller, btn.bitmask) ~= 0) then
gui.drawbox(pad.x + btn.x, pad.y + btn.y, pad.x + btn.x + btn.w, pad.y + btn.y + btn.h, pad.color)
else
gui.drawbox(pad.x + btn.x, pad.y + btn.y, pad.x + btn.x + btn.w, pad.y + btn.y + btn.h, "black")
end
end
end
end
end
end
end
taseditor.registerauto(draw_joypads);

View File

@ -0,0 +1,52 @@
---------------------------------------------------------------------------
-- Invert Selection
---------------------------------------------------------------------------
-- Showcases following functions:
-- * taseditor.getselection()
-- * taseditor.setselection()
---------------------------------------------------------------------------
-- Usage:
-- Run the script, unpause emulation (or simply Frame Advance once).
-- Now you can press "Run function" button to invert current Selection.
-- Previously selected frames become deselected, all other frames become selected.
---------------------------------------------------------------------------
function display_selection()
if (taseditor.engaged()) then
selection_table = taseditor.getselection();
if (selection_table ~= nil) then
selection_size = #selection_table;
gui.text(0, 10, "Selection: " .. selection_size .. " rows");
else
gui.text(0, 10, "Selection: no");
end
end
end
function invert_selection()
old_sel = taseditor.getselection();
new_sel = {};
-- Select all
movie_size = movie.length();
for i = 0, movie_size do
new_sel[i + 1] = i;
end
if (selection_table ~= nil) then
-- Substract current selection from new selection set
for i = #old_sel, 1, -1 do
selected_frame = old_sel[i];
-- we're taking advantage of the fact that "old_sel" is sorted in ascending order
-- so we can safely use table.remove to remove indexes from the end to the beginning
table.remove(new_sel, selected_frame + 1);
end
end
-- Apply new set to TAS Editor selection
taseditor.setselection(new_sel);
end
taseditor.registerauto(display_selection);
taseditor.registermanual(invert_selection);

View File

@ -0,0 +1,95 @@
---------------------------------------------------------------------------
-- Recording Input while Rewinding Playback frame-by-frame
---------------------------------------------------------------------------
-- Showcases following functions:
-- * taseditor.getrecordermode()
-- * taseditor.getsuperimpose()
-- * taseditor.getinput()
-- * taseditor.setinput()
-- * taseditor.clearinputchanges()
-- * taseditor.applyinputchanges()
---------------------------------------------------------------------------
-- Usage:
-- Run the script, unpause emulation (or simply Frame Advance once).
-- Now you can hold some joypad buttons and press "Rewind Frame" hotkey
-- to Record those buttons into PREVIOUS frame.
-- Try using this crazy method alongside with Frame Advance Recording.
-- This script supports multitracking and superimpose.
---------------------------------------------------------------------------
-- This function reads joypad input table and converts it to single byte
function GetCurrentInputByte(player)
input_byte = 0;
input_table = joypad.getimmediate(player);
if (input_table ~= nil) then
-- A B select start up down left right
if (input_table.A) then input_byte = OR(input_byte, 1) end;
if (input_table.B) then input_byte = OR(input_byte, 2) end;
if (input_table.select) then input_byte = OR(input_byte, 4) end;
if (input_table.start) then input_byte = OR(input_byte, 8) end;
if (input_table.up) then input_byte = OR(input_byte, 16) end;
if (input_table.down) then input_byte = OR(input_byte, 32) end;
if (input_table.left) then input_byte = OR(input_byte, 64) end;
if (input_table.right) then input_byte = OR(input_byte, 128) end;
end
return input_byte;
end
function reversed_recorder()
if taseditor.engaged() then
playback_position = movie.framecount();
if (playback_position == (playback_last_position - 1)) then
-- Playback cursor moved up 1 frame, probably Rewind was used this frame
if (not movie.readonly()) then
-- Recording on
recording_mode = taseditor.getrecordermode();
superimpose = taseditor.getsuperimpose();
taseditor.clearinputchanges();
name = "Record";
if (recording_mode == "All") then
-- Recording all 4 joypads
for target_player = 1, 4 do
new_joypad_input = GetCurrentInputByte(target_player);
old_joypad_input = taseditor.getinput(playback_position, target_player);
-- Superimpose with old input if needed
if (superimpose == 1 or (superimpose == 2 and new_joypad_input == 0)) then
new_joypad_input = OR(new_joypad_input, old_joypad_input);
end
-- Add joypad info to name
if (new_joypad_input ~= old_joypad_input) then
name = name .. "(" .. target_player .. "P)";
end
taseditor.submitinputchange(playback_position, target_player, new_joypad_input);
end
-- Write to movie data
taseditor.applyinputchanges(name);
else
-- Recording target_player using 1P keys
new_joypad_input = GetCurrentInputByte(1);
target_player = 1;
if (recording_mode == "2P") then target_player = 2 end;
if (recording_mode == "3P") then target_player = 3 end;
if (recording_mode == "4P") then target_player = 4 end;
old_joypad_input = taseditor.getinput(playback_position, target_player);
-- Superimpose with old input if needed
if (superimpose == 1 or (superimpose == 2 and new_joypad_input == 0)) then
new_joypad_input = OR(new_joypad_input, old_joypad_input);
end
-- Add joypad info to name
if (new_joypad_input ~= old_joypad_input) then
name = name .. "(" .. recording_mode .. ")";
end
-- Write to movie data
taseditor.submitinputchange(playback_position, target_player, new_joypad_input);
taseditor.applyinputchanges(name);
end
end
end
playback_last_position = playback_position;
end
end
playback_last_position = movie.framecount();
taseditor.registerauto(reversed_recorder);

View File

@ -0,0 +1,61 @@
---------------------------------------------------------------------------
-- Showing Markers' Notes on screen
---------------------------------------------------------------------------
-- Showcases following functions:
-- * taseditor.getmarker()
-- * taseditor.getnote()
-- * taseditor.getselection()
---------------------------------------------------------------------------
-- Usage:
-- Run the script, unpause emulation (or simply Frame Advance once).
-- Now you can observe Marker Notes not only in TAS Editor window,
-- but also in FCEUX main screen.
-- This script automatically divides long Notes into several lines of text
---------------------------------------------------------------------------
-- Custom function for word-wrapping long lines of text
function DisplayText(x, y, text, max_num_chars)
while string.len(text) >= max_num_chars do
-- Find last spacebar within first max_num_chars of text
last_spacebar = string.find(string.reverse(string.sub(text, 1, max_num_chars)), " ");
if (last_spacebar ~= nil) then
-- Output substring up to the spacebar
substring_len = max_num_chars - last_spacebar;
else
-- No spacebar found within first max_num_chars of the string
-- output substring up to the first spacebar (this substring will have length > max_num_chars)
substring_len = string.find(text, " ");
if (substring_len == nil) then
-- No spacebars found at all, output whole string
substring_len = string.len(text);
else
-- Don't output the spacebar
substring_len = substring_len - 1;
end
end
gui.text(x, y, string.sub(text, 1, substring_len));
text = string.sub(text, substring_len + 2);
-- Next line
y = y + 8;
end
gui.text(x, y, text);
end
function ShowNotes()
if taseditor.engaged() then
-- Take Marker near Playback cursor and display its Note in upper half of the screen
playback_position = movie.framecount();
note = taseditor.getnote(taseditor.getmarker(playback_position));
DisplayText(1, 9, note, 50);
-- Take Marker near Selection cursor and display its Note in lower half of the screen
current_selection = taseditor.getselection();
if (current_selection ~= nil) then
selection_position = current_selection[1];
note = taseditor.getnote(taseditor.getmarker(selection_position));
DisplayText(1, 190, note, 50);
end
end
end
taseditor.registerauto(ShowNotes)

View File

@ -0,0 +1,45 @@
---------------------------------------------------------------------------
-- Swap 1P and 2P buttons at Selected frames
---------------------------------------------------------------------------
-- Showcases following functions:
-- * taseditor.getselection()
-- * taseditor.clearinputchanges()
-- * taseditor.getinput()
-- * taseditor.submitinputchange()
-- * taseditor.applyinputchanges()
---------------------------------------------------------------------------
-- Usage:
-- Use the script when you want to exchange recorded input between joypads.
-- Run the script, unpause emulation (or simply Frame Advance once).
-- Now you can select several frames of input data and then
-- press "Run function" button to swap inputs of 1P and 2P.
---------------------------------------------------------------------------
function swap()
selection_table = taseditor.getselection();
if (selection_table ~= nil) then
taseditor.clearinputchanges();
for i = 1, #selection_table do
selected_frame = selection_table[i];
joypad1data = taseditor.getinput(selected_frame, 1);
joypad2data = taseditor.getinput(selected_frame, 2);
taseditor.submitinputchange(selected_frame, 1, joypad2data);
taseditor.submitinputchange(selected_frame, 2, joypad1data);
end
taseditor.applyinputchanges("Swap 1P/2P");
end
end
taseditor.registermanual(swap);

Binary file not shown.

Binary file not shown.

View File

@ -962,14 +962,14 @@ BEGIN
CONTROL "Automatically backup movies",IDC_MOVIE_AUTOBACKUP,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,122,114,10
CONTROL "Load full savestate-movies:",IDC_FULLSAVESTATES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,141,110,10
LTEXT "Loading states in record mode",IDC_STATIC,24,153,106,8
LTEXT "does not immediately truncate",IDC_STATIC,23,163,107,8
LTEXT "movie, next frame input does it",IDC_STATIC,23,173,108,8
LTEXT "Loading states in record mode",IDC_STATIC,25,153,106,8
LTEXT "will not immediately truncate",IDC_STATIC,25,163,107,8
LTEXT "movie, next frame input will.",IDC_STATIC,25,173,108,8
CONTROL "Close after playback",IDC_MOVIE_CLOSEAFTERPLAYBACK,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,45,89,10
CONTROL "Always suggest Read-Only replay",IDC_MOVIE_SUGGEST_READONLY,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,8,125,10
LTEXT "(VBA-rr and SNES9x style)",IDC_STATIC,24,184,93,8
LTEXT "(VBA-rr and SNES9x style)",IDC_STATIC,25,184,93,8
END
DWBDIALOGSIMPLE DIALOGEX 33, 99, 250, 39

View File

@ -25,14 +25,17 @@ public:
void save(EMUFILE *os);
bool load(EMUFILE *is);
// saved vars
bool not_empty;
int flash_phase;
int flash_type;
SNAPSHOT snapshot;
std::vector<uint8> savestate;
std::vector<uint8> saved_screenshot;
int parent_branch;
// not saved vars
int flash_phase;
int flash_type;
private:
};

View File

@ -184,7 +184,7 @@ void RECORDER::InputChanged()
for (int i = num_joys-1; i >= 0; i--)
{
// superimpose (bitwise OR) if needed
if (taseditor_config.superimpose == BST_CHECKED || (taseditor_config.superimpose == BST_INDETERMINATE && new_joy[i] == 0))
if (taseditor_config.superimpose == SUPERIMPOSE_CHECKED || (taseditor_config.superimpose == SUPERIMPOSE_INDETERMINATE && new_joy[i] == 0))
new_joy[i] |= old_joy[i];
// change this joystick
currMovieData.records[currFrameCounter].joysticks[i] = new_joy[i];
@ -204,7 +204,7 @@ void RECORDER::InputChanged()
if (multitrack_recording_joypad > MULTITRACK_RECORDING_1P && taseditor_config.use_1p_rec)
new_joy[joy] = new_joy[0];
// superimpose (bitwise OR) if needed
if (taseditor_config.superimpose == BST_CHECKED || (taseditor_config.superimpose == BST_INDETERMINATE && new_joy[joy] == 0))
if (taseditor_config.superimpose == SUPERIMPOSE_CHECKED || (taseditor_config.superimpose == SUPERIMPOSE_INDETERMINATE && new_joy[joy] == 0))
new_joy[joy] |= old_joy[joy];
// other joysticks should not be changed
for (int i = num_joys-1; i >= 0; i--)

View File

@ -8,6 +8,13 @@ enum
MULTITRACK_RECORDING_4P = 4,
};
enum
{
SUPERIMPOSE_UNCHECKED = 0,
SUPERIMPOSE_CHECKED = 1,
SUPERIMPOSE_INDETERMINATE = 2,
};
class RECORDER
{
public:

View File

@ -396,7 +396,7 @@ bool SPLICER::Paste()
++pos;
}
if (!taseditor_config.superimpose_affects_paste || taseditor_config.superimpose == BST_UNCHECKED)
if (!taseditor_config.superimpose_affects_paste || taseditor_config.superimpose == SUPERIMPOSE_UNCHECKED)
{
currMovieData.records[pos].joysticks[0] = 0;
currMovieData.records[pos].joysticks[1] = 0;
@ -412,7 +412,7 @@ bool SPLICER::Paste()
{
case '|': // Joystick mark
// flush buttons to movie data
if (taseditor_config.superimpose_affects_paste && (taseditor_config.superimpose == BST_CHECKED || (taseditor_config.superimpose == BST_INDETERMINATE && new_buttons == 0)))
if (taseditor_config.superimpose_affects_paste && (taseditor_config.superimpose == SUPERIMPOSE_CHECKED || (taseditor_config.superimpose == SUPERIMPOSE_INDETERMINATE && new_buttons == 0)))
{
flash_joy[joy] |= (new_buttons & (~currMovieData.records[pos].joysticks[joy])); // highlight buttons that are new
currMovieData.records[pos].joysticks[joy] |= new_buttons;
@ -438,7 +438,7 @@ bool SPLICER::Paste()
++frame;
}
// before going to next frame, flush buttons to movie data
if (taseditor_config.superimpose_affects_paste && (taseditor_config.superimpose == BST_CHECKED || (taseditor_config.superimpose == BST_INDETERMINATE && new_buttons == 0)))
if (taseditor_config.superimpose_affects_paste && (taseditor_config.superimpose == SUPERIMPOSE_CHECKED || (taseditor_config.superimpose == SUPERIMPOSE_INDETERMINATE && new_buttons == 0)))
{
flash_joy[joy] |= (new_buttons & (~currMovieData.records[pos].joysticks[joy])); // highlight buttons that are new
currMovieData.records[pos].joysticks[joy] |= new_buttons;

View File

@ -26,7 +26,7 @@ TASEDITOR_CONFIG::TASEDITOR_CONFIG()
use_1p_rec = true;
columnset_by_keys = true;
keyboard_for_listview = true;
superimpose = BST_UNCHECKED;
superimpose = 0; // SUPERIMPOSE_UNCHECKED
superimpose_affects_paste = true;
branch_full_movie = true;
branch_only_when_rec = false;

View File

@ -186,6 +186,15 @@ const char* TASEDITOR_LUA::getrecordermode()
return NULL;
}
// int taseditor.getsuperimpose()
int TASEDITOR_LUA::getsuperimpose()
{
if (FCEUMOV_Mode(MOVIEMODE_TASEDITOR))
return taseditor_config.superimpose;
else
return -1;
}
// int taseditor.getlostplayback()
int TASEDITOR_LUA::getlostplayback()
{

View File

@ -48,6 +48,7 @@ public:
void setnote(int index, const char* newtext);
int getcurrentbranch();
const char* getrecordermode();
int getsuperimpose();
int getlostplayback();
int getplaybacktarget();
void setplayback(int frame);

View File

@ -425,7 +425,12 @@ void TASEDITOR_WINDOW::UpdateCheckedItems()
// check option ticks
CheckDlgButton(hwndTasEditor, CHECK_FOLLOW_CURSOR, taseditor_config.follow_playback?MF_CHECKED : MF_UNCHECKED);
CheckDlgButton(hwndTasEditor,CHECK_AUTORESTORE_PLAYBACK,taseditor_config.restore_position?BST_CHECKED:BST_UNCHECKED);
CheckDlgButton(hwndTasEditor, IDC_SUPERIMPOSE, taseditor_config.superimpose);
if (taseditor_config.superimpose == SUPERIMPOSE_UNCHECKED)
CheckDlgButton(hwndTasEditor, IDC_SUPERIMPOSE, BST_UNCHECKED);
else if (taseditor_config.superimpose == SUPERIMPOSE_CHECKED)
CheckDlgButton(hwndTasEditor, IDC_SUPERIMPOSE, BST_CHECKED);
else
CheckDlgButton(hwndTasEditor, IDC_SUPERIMPOSE, BST_INDETERMINATE);
CheckDlgButton(hwndTasEditor, IDC_RUN_AUTO, taseditor_config.enable_auto_function);
CheckDlgButton(hwndTasEditor, CHECK_TURBO_SEEK, taseditor_config.turbo_seek?MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hmenu, ID_VIEW_SHOW_LAG_FRAMES, taseditor_config.show_lag_frames?MF_CHECKED : MF_UNCHECKED);
@ -1130,11 +1135,11 @@ BOOL CALLBACK WndprocTasEditor(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
break;
case IDC_SUPERIMPOSE:
// 3 states of "Superimpose" checkbox
if (taseditor_config.superimpose == BST_UNCHECKED)
taseditor_config.superimpose = BST_CHECKED;
else if (taseditor_config.superimpose == BST_CHECKED)
taseditor_config.superimpose = BST_INDETERMINATE;
else taseditor_config.superimpose = BST_UNCHECKED;
if (taseditor_config.superimpose == SUPERIMPOSE_UNCHECKED)
taseditor_config.superimpose = SUPERIMPOSE_CHECKED;
else if (taseditor_config.superimpose == SUPERIMPOSE_CHECKED)
taseditor_config.superimpose = SUPERIMPOSE_INDETERMINATE;
else taseditor_config.superimpose = SUPERIMPOSE_UNCHECKED;
taseditor_window.UpdateCheckedItems();
break;
case ACCEL_CTRL_A:

View File

@ -379,7 +379,7 @@ static int emu_frameadvance(lua_State *L) {
// It's actually rather disappointing...
}
// bool emu.paused() (getter)
// bool emu.paused()
static int emu_paused(lua_State *L)
{
lua_pushboolean(L, FCEUI_EmulationPaused() != 0);
@ -2274,8 +2274,6 @@ static int joy_get_internal(lua_State *L, bool reportUp, bool reportDown) {
}
// Use the OS-specific code to do the reading.
/*extern void FCEUD_UpdateInput(void); FatRatKnight: What's this call doing here?
FCEUD_UpdateInput(); I commented it out. Should we delete it?*/
extern SFORMAT FCEUCTRL_STATEINFO[];
uint8 buttons = ((uint8 *) FCEUCTRL_STATEINFO[1].v)[which - 1];
@ -2314,6 +2312,32 @@ static int joypad_getup(lua_State *L)
return joy_get_internal(L, true, false);
}
// table joypad.getimmediate(int which)
// Reads immediate state of joypads (at the moment of calling)
static int joypad_getimmediate(lua_State *L)
{
int which = luaL_checkinteger(L,1);
if (which < 1 || which > 4)
{
luaL_error(L,"Invalid input port (valid range 1-4, specified %d)", which);
}
// Currently only supports Windows, sorry...
#ifdef WIN32
extern uint32 GetGamepadPressedImmediate();
uint8 buttons = GetGamepadPressedImmediate() >> ((which - 1) * 8);
lua_newtable(L);
for (int i = 0; i < 8; ++i)
{
lua_pushboolean(L, (buttons & (1 << i)) != 0);
lua_setfield(L, -2, button_mappings[i]);
}
#else
lua_pushnil(L);
#endif
return 1;
}
// joypad.set(int which, table buttons)
//
@ -4153,6 +4177,7 @@ static int gui_register(lua_State *L) {
}
// table sound.get()
static int sound_get(lua_State *L)
{
extern ENVUNIT EnvUnits[3];
@ -4421,6 +4446,17 @@ static int taseditor_getrecordermode(lua_State *L)
return 1;
}
// int taseditor.getsuperimpose()
static int taseditor_getsuperimpose(lua_State *L)
{
#ifdef WIN32
lua_pushinteger(L, taseditor_lua.getsuperimpose());
#else
lua_pushinteger(L, -1);
#endif
return 1;
}
// int taseditor.getlostplayback()
static int taseditor_getlostplayback(lua_State *L)
{
@ -5230,12 +5266,14 @@ static const struct luaL_reg joypadlib[] = {
{"get", joypad_get},
{"getdown", joypad_getdown},
{"getup", joypad_getup},
{"getimmediate", joypad_getimmediate},
{"set", joypad_set},
// alternative names
{"read", joypad_get},
{"write", joypad_set},
{"readdown", joypad_getdown},
{"readup", joypad_getup},
{"readimmediate", joypad_getimmediate},
{NULL,NULL}
};
@ -5351,6 +5389,7 @@ static const struct luaL_reg taseditorlib[] = {
{"setnote", taseditor_setnote},
{"getcurrentbranch", taseditor_getcurrentbranch},
{"getrecordermode", taseditor_getrecordermode},
{"getsuperimpose", taseditor_getsuperimpose},
{"getlostplayback", taseditor_getlostplayback},
{"getplaybacktarget", taseditor_getplaybacktarget},
{"setplayback", taseditor_setplayback},