mirror of https://github.com/odrling/Aegisub
Remove libauto3 that somehow escaped before.
Originally committed to SVN as r3198.
This commit is contained in:
parent
98d909b361
commit
2fef9e3111
|
@ -1,12 +0,0 @@
|
|||
if HAVE_AUTO3_LUA
|
||||
|
||||
AM_CFLAGS = -DAUTO3LIB @LUA50_CFLAGS@
|
||||
AM_LDFLAGS = @LUA50_LDFLAGS@
|
||||
|
||||
lib_LTLIBRARIES = libaegisub-auto3-2.2.la
|
||||
libaegisub_auto3_2_2_la_SOURCES = auto3.c
|
||||
noinst_HEADERS = auto3.h
|
||||
|
||||
endif
|
||||
|
||||
EXTRA_DIST= callables.c
|
|
@ -1,18 +0,0 @@
|
|||
Automation 3 support in Automation 4 needs to be built as a separate library,
|
||||
to be able to have two versions of Lua side by side. This is required since
|
||||
Automation 3, and especially scripts written for it, relies on the Lua 5.0
|
||||
API.
|
||||
|
||||
|
||||
Compiling on Windows
|
||||
--------------------
|
||||
If you are building on Windows, be aware that Microsoft Visual C++ 2005
|
||||
(version 8) CAN NOT COMPILE LUA 5.0 CORRECTLY. While the build will succeed,
|
||||
the built binaries are broken and do not work correctly.
|
||||
|
||||
You need to use Microsoft Visual C++ .NET 2003 (version 7.1) to build the
|
||||
Windows version of this library. Other compilers might also work.
|
||||
|
||||
You should not need to build this DLL yourself even if you are building
|
||||
Aegisub; just get one built on someone else. Unless, of course, you want to
|
||||
hack the Auto3 code.
|
|
@ -1,944 +0,0 @@
|
|||
// Copyright (c) 2005, 2006, 2007, Niels Martin Hansen
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// AEGISUB
|
||||
//
|
||||
// Website: http://aegisub.cellosoft.com
|
||||
// Contact: mailto:jiifurusu@gmail.com
|
||||
//
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "auto3.h"
|
||||
|
||||
|
||||
// Win32 DLL entry point
|
||||
#ifdef WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <wchar.h>
|
||||
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
// TODO: Destroy any still-alive scripts/interpreters here on unload?
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
struct script_reader_data {
|
||||
FILE *f;
|
||||
int isfirst;
|
||||
#define SCRIPT_READER_BUFSIZE 512
|
||||
char databuf[SCRIPT_READER_BUFSIZE];
|
||||
};
|
||||
static const char *script_reader_func(lua_State *L, void *data, size_t *size)
|
||||
{
|
||||
struct script_reader_data *self;
|
||||
unsigned char *b;
|
||||
FILE *f;
|
||||
|
||||
self = (struct script_reader_data *)(data);
|
||||
b = (unsigned char *)self->databuf;
|
||||
f = self->f;
|
||||
|
||||
if (feof(f)) {
|
||||
*size = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (self->isfirst) {
|
||||
self->isfirst = 0;
|
||||
// check if file is sensible and maybe skip bom
|
||||
if ((*size = fread(b, 1, 4, f)) == 4) {
|
||||
if (b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF) {
|
||||
// got an utf8 file with bom
|
||||
// nothing further to do, already skipped the bom
|
||||
fseek(f, -1, SEEK_CUR);
|
||||
} else {
|
||||
// oops, not utf8 with bom
|
||||
// check if there is some other BOM in place and complain if there is...
|
||||
if ((b[0] == 0xFF && b[1] == 0xFE && b[2] == 0x00 && b[3] == 0x00) || // utf32be
|
||||
(b[0] == 0x00 && b[1] == 0x00 && b[2] == 0xFE && b[3] == 0xFF) || // utf32le
|
||||
(b[0] == 0xFF && b[1] == 0xFE) || // utf16be
|
||||
(b[0] == 0xFE && b[1] == 0xFF) || // utf16le
|
||||
(b[0] == 0x2B && b[1] == 0x2F && b[2] == 0x76) || // utf7
|
||||
(b[0] == 0x00 && b[2] == 0x00) || // looks like utf16be
|
||||
(b[1] == 0x00 && b[3] == 0x00)) { // looks like utf16le
|
||||
// can't support these files
|
||||
*size = 0;
|
||||
self->isfirst = -1;
|
||||
strcpy(self->databuf, "File is an unsupported UTF");
|
||||
return NULL;
|
||||
}
|
||||
// assume utf8 without bom, and rewind file
|
||||
fseek(f, 0, SEEK_SET);
|
||||
}
|
||||
} else {
|
||||
// hmm, rather short file this...
|
||||
// doesn't have a bom, assume it's just ascii/utf8 without bom
|
||||
return self->databuf; // *size is already set
|
||||
}
|
||||
}
|
||||
|
||||
*size = fread(b, 1, SCRIPT_READER_BUFSIZE, f);
|
||||
|
||||
return self->databuf;
|
||||
}
|
||||
static int Auto3LuaLoad(lua_State *L, filename_t filename, const char *prettyname, char **error)
|
||||
{
|
||||
struct script_reader_data script_reader;
|
||||
int res;
|
||||
|
||||
script_reader.f =
|
||||
#ifdef WIN32
|
||||
_wfopen(filename, L"rb");
|
||||
#else
|
||||
fopen(filename, "rb");
|
||||
#endif
|
||||
if (!script_reader.f) return -1;
|
||||
|
||||
script_reader.isfirst = 1;
|
||||
|
||||
res = lua_load(L, script_reader_func, &script_reader, prettyname);
|
||||
|
||||
fclose(script_reader.f);
|
||||
|
||||
if (res) {
|
||||
*error = Auto3Strdup(lua_tostring(L, -1));
|
||||
return res;
|
||||
}
|
||||
if (script_reader.isfirst == -1) {
|
||||
// Signals we got a bad UTF
|
||||
*error = Auto3Strdup(script_reader.databuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Read the 'config' global and create config struct
|
||||
static int Auto3ParseConfigData(lua_State *L, struct Auto3Interpreter *script, char **error)
|
||||
{
|
||||
struct Auto3ConfigOption *opt;
|
||||
int i, n;
|
||||
const char *tmp;
|
||||
|
||||
if (!lua_istable(L, -1)) {
|
||||
// No 'config' table at all, just make the sentinel option
|
||||
script->config = calloc(1, sizeof(struct Auto3ConfigOption));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get expected number of elements in table
|
||||
n = luaL_getn(L, -1);
|
||||
// Allocate memory for max number of elements + 1
|
||||
script->config = calloc(n+1, sizeof(struct Auto3ConfigOption));
|
||||
|
||||
// Prepare traversal
|
||||
lua_pushnil(L);
|
||||
opt = script->config;
|
||||
|
||||
// Get at most n options
|
||||
i = 1;
|
||||
while (lua_next(L, -2)) {
|
||||
if (i > n) {
|
||||
// More options than we have space for...
|
||||
// Just ignore the extra options for now
|
||||
lua_pop(L, 2);
|
||||
break;
|
||||
}
|
||||
|
||||
// Top of stack should be the next option living in a table
|
||||
if (lua_istable(L, -1)) {
|
||||
|
||||
// get the "kind"
|
||||
lua_pushstring(L, "kind");
|
||||
lua_gettable(L, -2);
|
||||
if (lua_isstring(L, -1)) {
|
||||
// use C standard lib functions here, as it's probably faster than messing around with unicode
|
||||
// lua is known to always properly null-terminate strings, and the strings are known to be pure ascii
|
||||
tmp = lua_tostring(L, -1);
|
||||
if (strcmp(tmp, "label") == 0) {
|
||||
opt->kind = COK_LABEL;
|
||||
} else if (strcmp(tmp, "text") == 0) {
|
||||
opt->kind = COK_TEXT;
|
||||
} else if (strcmp(tmp, "int") == 0) {
|
||||
opt->kind = COK_INT;
|
||||
} else if (strcmp(tmp, "float") == 0) {
|
||||
opt->kind = COK_FLOAT;
|
||||
} else if (strcmp(tmp, "bool") == 0) {
|
||||
opt->kind = COK_BOOL;
|
||||
} else if (strcmp(tmp, "colour") == 0) {
|
||||
opt->kind = COK_COLOUR;
|
||||
} else if (strcmp(tmp, "style") == 0) {
|
||||
opt->kind = COK_STYLE;
|
||||
} else {
|
||||
opt->kind = COK_INVALID;
|
||||
}
|
||||
} else {
|
||||
opt->kind = COK_INVALID;
|
||||
}
|
||||
|
||||
// remove "kind" string from stack again
|
||||
lua_pop(L, 1);
|
||||
|
||||
// no need to check for rest if this one is already deemed invalid
|
||||
if (opt->kind != COK_INVALID) {
|
||||
// name
|
||||
lua_pushstring(L, "name");
|
||||
lua_gettable(L, -2);
|
||||
if (lua_isstring(L, -1)) {
|
||||
opt->name = Auto3Strdup(lua_tostring(L, -1));
|
||||
} else {
|
||||
// name is required to be valid
|
||||
opt->kind = COK_INVALID;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
// label
|
||||
lua_pushstring(L, "label");
|
||||
lua_gettable(L, -2);
|
||||
if (lua_isstring(L, -1)) {
|
||||
opt->label = Auto3Strdup(lua_tostring(L, -1));
|
||||
} else {
|
||||
// label is also required
|
||||
opt->kind = COK_INVALID;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
// hint
|
||||
lua_pushstring(L, "hint");
|
||||
lua_gettable(L, -2);
|
||||
if (lua_isstring(L, -1)) {
|
||||
opt->hint = Auto3Strdup(lua_tostring(L, -1));
|
||||
} else {
|
||||
opt->hint = Auto3Strdup("");
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
// min
|
||||
lua_pushstring(L, "min");
|
||||
lua_gettable(L, -2);
|
||||
if (lua_isnumber(L, -1)) {
|
||||
opt->min.valid = 1;
|
||||
opt->min.floatval = (float)lua_tonumber(L, -1);
|
||||
opt->min.intval = (int)opt->min.floatval;
|
||||
} else {
|
||||
opt->min.valid = 0;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
// max
|
||||
lua_pushstring(L, "max");
|
||||
lua_gettable(L, -2);
|
||||
if (lua_isnumber(L, -1)) {
|
||||
opt->max.valid = 1;
|
||||
opt->max.floatval = (float)lua_tonumber(L, -1);
|
||||
opt->max.intval = (int)opt->max.floatval;
|
||||
} else {
|
||||
opt->max.valid = 0;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
// default
|
||||
lua_pushstring(L, "default");
|
||||
lua_gettable(L, -2);
|
||||
switch (opt->kind) {
|
||||
case COK_LABEL:
|
||||
// nothing to do, nothing expected
|
||||
break;
|
||||
case COK_TEXT:
|
||||
case COK_STYLE:
|
||||
case COK_COLOUR:
|
||||
// expect it to be a string
|
||||
if (lua_isstring(L, -1)) {
|
||||
opt->default_val.stringval = Auto3Strdup(lua_tostring(L, -1));
|
||||
opt->value.stringval = Auto3Strdup(opt->default_val.stringval);
|
||||
} else {
|
||||
// not a string, baaaad scripter
|
||||
opt->kind = COK_INVALID;
|
||||
}
|
||||
break;
|
||||
case COK_INT:
|
||||
// expect it to be a number
|
||||
if (lua_isnumber(L, -1)) {
|
||||
opt->default_val.intval = (int)lua_tonumber(L, -1);
|
||||
opt->value.intval = opt->default_val.intval;
|
||||
} else {
|
||||
opt->kind = COK_INVALID;
|
||||
}
|
||||
break;
|
||||
case COK_FLOAT:
|
||||
// expect it to be a number
|
||||
if (lua_isnumber(L, -1)) {
|
||||
opt->default_val.floatval = (float)lua_tonumber(L, -1);
|
||||
opt->value.floatval = opt->default_val.floatval;
|
||||
} else {
|
||||
opt->kind = COK_INVALID;
|
||||
}
|
||||
break;
|
||||
case COK_BOOL:
|
||||
// expect it to be a bool
|
||||
if (lua_isboolean(L, -1)) {
|
||||
opt->default_val.intval = lua_toboolean(L, -1);
|
||||
opt->value.intval = opt->default_val.intval;
|
||||
} else {
|
||||
opt->kind = COK_INVALID;
|
||||
}
|
||||
break;
|
||||
case COK_INVALID:
|
||||
break;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
// On to next structure to be filled
|
||||
opt++;
|
||||
}
|
||||
|
||||
// Remove option table from stack
|
||||
lua_pop(L, 1);
|
||||
// Such that the current key is on top, and we can get the next
|
||||
}
|
||||
|
||||
|
||||
// Remove 'config' table from stack
|
||||
lua_pop(L, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Keeping this file a bit shorter: put all functions called from Lua into a separate file
|
||||
#define BUILDING_AUTO3_C
|
||||
#include "callables.c"
|
||||
|
||||
|
||||
// Create a new interpreter
|
||||
AUTO3_API struct Auto3Interpreter *CreateAuto3Script(const filename_t filename, const char *prettyname, struct Auto3Callbacks *cb, char **error)
|
||||
{
|
||||
struct Auto3Interpreter *script;
|
||||
lua_State *L;
|
||||
|
||||
script = malloc(sizeof(struct Auto3Interpreter));
|
||||
if (!script) return NULL;
|
||||
// Copy in callbacks
|
||||
memcpy(&script->cb, cb, sizeof(struct Auto3Callbacks));
|
||||
|
||||
|
||||
// Init Lua
|
||||
script->L = lua_open();
|
||||
if (!script->L) goto failearly;
|
||||
L = script->L;
|
||||
|
||||
|
||||
// register standard libs
|
||||
lua_pushcfunction(L, luaopen_base); lua_call(L, 0, 0);
|
||||
lua_pushcfunction(L, luaopen_string); lua_call(L, 0, 0);
|
||||
lua_pushcfunction(L, luaopen_table); lua_call(L, 0, 0);
|
||||
lua_pushcfunction(L, luaopen_math); lua_call(L, 0, 0);
|
||||
// dofile and loadfile are replaced with include
|
||||
lua_pushnil(L);
|
||||
lua_setglobal(L, "dofile");
|
||||
lua_pushnil(L);
|
||||
lua_setglobal(L, "loadfile");
|
||||
lua_pushlightuserdata(L, script);
|
||||
lua_pushcclosure(L, LuaInclude, 1);
|
||||
lua_setglobal(L, "include");
|
||||
|
||||
// reference to the script object
|
||||
lua_pushlightuserdata(L, script);
|
||||
|
||||
// make "aegisub" table
|
||||
lua_newtable(L);
|
||||
|
||||
// put helper functions in it
|
||||
// colorstring_to_rgb is moved to utils.auto3
|
||||
lua_pushstring(L, "text_extents");
|
||||
lua_pushvalue(L, -3);
|
||||
lua_pushcclosure(L, LuaTextExtents, 1);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "frame_from_ms");
|
||||
lua_pushvalue(L, -3);
|
||||
lua_pushcclosure(L, LuaFrameFromMs, 1);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "ms_from_frame");
|
||||
lua_pushvalue(L, -3);
|
||||
lua_pushcclosure(L, LuaMsFromFrame, 1);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "report_progress");
|
||||
lua_pushvalue(L, -3);
|
||||
lua_pushcclosure(L, LuaReportProgress, 1);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "output_debug");
|
||||
lua_pushvalue(L, -3);
|
||||
lua_pushcclosure(L, LuaOutputDebug, 1);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "set_status");
|
||||
lua_pushvalue(L, -3);
|
||||
lua_pushcclosure(L, LuaSetStatus, 1);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "lua_automation_version");
|
||||
lua_pushnumber(L, 3);
|
||||
lua_settable(L, -3);
|
||||
|
||||
// store table
|
||||
lua_setglobal(L, "aegisub");
|
||||
// remove ref to script object
|
||||
lua_pop(L, 1);
|
||||
|
||||
|
||||
// Read the script
|
||||
if (Auto3LuaLoad(L, filename, prettyname, error)) {
|
||||
// error is already filled
|
||||
goto faillua;
|
||||
}
|
||||
|
||||
// Execute the script
|
||||
if (lua_pcall(L, 0, 0, 0)) {
|
||||
*error = Auto3Strdup(lua_tostring(L, -1));
|
||||
goto faillua;
|
||||
}
|
||||
|
||||
|
||||
// Script has been run, stuff exists in the global environment
|
||||
lua_getglobal(L, "version");
|
||||
if (!lua_isnumber(L, -1)) {
|
||||
*error = Auto3Strdup("'version' value not found or not a number");
|
||||
goto faillua;
|
||||
}
|
||||
if ((int)lua_tonumber(L, -1) != 3) {
|
||||
// invalid version
|
||||
*error = Auto3Strdup("'version' must be 3 for Automation 3 scripts");
|
||||
goto faillua;
|
||||
}
|
||||
// skip 'kind', it's useless
|
||||
// name
|
||||
lua_getglobal(L, "name");
|
||||
if (!lua_isstring(L, -1)) {
|
||||
script->name = Auto3Strdup(prettyname);
|
||||
} else {
|
||||
script->name = Auto3Strdup(lua_tostring(L, -1));
|
||||
}
|
||||
// description (optional)
|
||||
lua_getglobal(L, "description");
|
||||
if (lua_isstring(L, -1)) {
|
||||
script->description = Auto3Strdup(lua_tostring(L, -1));
|
||||
} else {
|
||||
script->description = Auto3Strdup("");
|
||||
}
|
||||
lua_pop(L, 3);
|
||||
|
||||
|
||||
// Parse the config data
|
||||
lua_getglobal(L, "configuration");
|
||||
if (Auto3ParseConfigData(L, script, error)) {
|
||||
goto faildescription;
|
||||
}
|
||||
|
||||
|
||||
return script;
|
||||
|
||||
|
||||
// Various fail-cases
|
||||
faildescription:
|
||||
free(script->description);
|
||||
free(script->name);
|
||||
faillua:
|
||||
lua_close(script->L);
|
||||
failearly:
|
||||
free(script);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// Release an interpreter
|
||||
AUTO3_API void DestroyAuto3Script(struct Auto3Interpreter *script)
|
||||
{
|
||||
struct Auto3ConfigOption *opt;
|
||||
|
||||
// free the config data
|
||||
opt = script->config;
|
||||
while (opt->name) {
|
||||
free(opt->name);
|
||||
free(opt->label);
|
||||
free(opt->hint);
|
||||
if (opt->kind == COK_TEXT || opt->kind == COK_COLOUR || opt->kind == COK_STYLE) {
|
||||
free(opt->default_val.stringval);
|
||||
free(opt->value.stringval);
|
||||
}
|
||||
|
||||
opt++;
|
||||
}
|
||||
free(script->config);
|
||||
|
||||
// free the rest
|
||||
free(script->description);
|
||||
free(script->name);
|
||||
lua_close(script->L);
|
||||
free(script);
|
||||
}
|
||||
|
||||
|
||||
// Our "malloc" function, allocate memory for strings with this
|
||||
AUTO3_API void *Auto3Malloc(size_t amount)
|
||||
{
|
||||
return malloc(amount);
|
||||
}
|
||||
|
||||
// Convenience function, use this for duplicating strings this lib should own
|
||||
AUTO3_API char *Auto3Strdup(const char *str)
|
||||
{
|
||||
#if _MSC_VER >= 1400
|
||||
// MS Visual C++ 2004 or newer
|
||||
return _strdup(str);
|
||||
#else
|
||||
return strdup(str);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Our "free" function, free generated error messages with this
|
||||
AUTO3_API void Auto3Free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
|
||||
static void MakeMetaInfoTable(lua_State *L, struct Auto3Interpreter *script)
|
||||
{
|
||||
int res_x, res_y;
|
||||
|
||||
script->cb.get_meta_info(script->cb.rwdata, &res_x, &res_y);
|
||||
|
||||
lua_newtable(L);
|
||||
|
||||
lua_pushstring(L, "res_x");
|
||||
lua_pushnumber(L, res_x);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "res_y");
|
||||
lua_pushnumber(L, res_y);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
|
||||
|
||||
static void MakeStylesTable(lua_State *L, struct Auto3Interpreter *script)
|
||||
{
|
||||
char *name, *fontname, *color1, *color2, *color3, *color4;
|
||||
int fontsize, bold, italic, underline, strikeout, borderstyle, align, margin_l, margin_r, margin_v, encoding;
|
||||
float scale_x, scale_y, spacing, angle, outline, shadow;
|
||||
int n;
|
||||
|
||||
lua_newtable(L);
|
||||
n = -1;
|
||||
|
||||
script->cb.reset_style_pointer(script->cb.rwdata);
|
||||
while (script->cb.get_next_style(script->cb.rwdata, &name, &fontname, &fontsize, &color1, &color2, &color3, &color4,
|
||||
&bold, &italic, &underline, &strikeout, &scale_x, &scale_y, &spacing, &angle, &borderstyle, &outline,
|
||||
&shadow, &align, &margin_l, &margin_r, &margin_v, &encoding)) {
|
||||
n++;
|
||||
|
||||
// Got a style...
|
||||
lua_pushstring(L, name); // name for table index
|
||||
lua_newtable(L);
|
||||
|
||||
// Set properties
|
||||
|
||||
lua_pushstring(L, "name");
|
||||
lua_pushstring(L, name);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "fontname");
|
||||
lua_pushstring(L, fontname);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "fontsize");
|
||||
lua_pushnumber(L, fontsize);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "color1");
|
||||
lua_pushstring(L, color1);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "color2");
|
||||
lua_pushstring(L, color2);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "color3");
|
||||
lua_pushstring(L, color3);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "color4");
|
||||
lua_pushstring(L, color4);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "bold");
|
||||
lua_pushboolean(L, bold);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "italic");
|
||||
lua_pushboolean(L, italic);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "underline");
|
||||
lua_pushboolean(L, underline);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "strikeout");
|
||||
lua_pushboolean(L, strikeout);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "scale_x");
|
||||
lua_pushnumber(L, scale_x);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "scale_y");
|
||||
lua_pushnumber(L, scale_y);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "spacing");
|
||||
lua_pushnumber(L, spacing);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "angle");
|
||||
lua_pushnumber(L, angle);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "borderstyle");
|
||||
lua_pushnumber(L, borderstyle);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "outline");
|
||||
lua_pushnumber(L, outline);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "shadow");
|
||||
lua_pushnumber(L, shadow);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "align");
|
||||
lua_pushnumber(L, align);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "margin_l");
|
||||
lua_pushnumber(L, margin_l);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "margin_r");
|
||||
lua_pushnumber(L, margin_r);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "margin_v");
|
||||
lua_pushnumber(L, margin_v);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "encoding");
|
||||
lua_pushnumber(L, encoding);
|
||||
lua_settable(L, -3);
|
||||
|
||||
// Store to numeric index
|
||||
lua_pushnumber(L, n);
|
||||
lua_pushvalue(L, -2); // extra copy of table
|
||||
lua_settable(L, -5);
|
||||
// And named index
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
|
||||
// Finally, make -1 key in table (because the name 'n' might clash with a style name)
|
||||
lua_pushnumber(L, -1);
|
||||
lua_pushnumber(L, n);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
|
||||
|
||||
static void MakeEventsTable(lua_State *L, struct Auto3Interpreter *script)
|
||||
{
|
||||
int layer, start_time, end_time, margin_l, margin_r, margin_v, comment;
|
||||
char *style, *actor, *effect, *text;
|
||||
int n;
|
||||
|
||||
lua_newtable(L);
|
||||
n = -1;
|
||||
|
||||
script->cb.reset_subs_pointer(script->cb.rwdata);
|
||||
while (script->cb.get_next_sub(script->cb.rwdata, &layer, &start_time, &end_time, &style, &actor,
|
||||
&margin_l, &margin_r, &margin_v, &effect, &text, &comment)) {
|
||||
n++;
|
||||
|
||||
// Got a line...
|
||||
lua_pushnumber(L, n);
|
||||
lua_newtable(L);
|
||||
|
||||
lua_pushstring(L, "kind");
|
||||
if (comment)
|
||||
lua_pushstring(L, "comment");
|
||||
else
|
||||
lua_pushstring(L, "dialogue");
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "layer");
|
||||
lua_pushnumber(L, layer);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "start_time");
|
||||
lua_pushnumber(L, start_time);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "end_time");
|
||||
lua_pushnumber(L, end_time);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "style");
|
||||
lua_pushstring(L, style);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "name");
|
||||
lua_pushstring(L, actor);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "margin_l");
|
||||
lua_pushnumber(L, margin_l);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "margin_r");
|
||||
lua_pushnumber(L, margin_r);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "margin_v");
|
||||
lua_pushnumber(L, margin_v);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "effect");
|
||||
lua_pushstring(L, effect);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "text");
|
||||
lua_pushstring(L, text);
|
||||
lua_settable(L, -3);
|
||||
|
||||
// No parsing karaoke data here, that can just as well be done in Lua code
|
||||
|
||||
// Store at numeric index
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
|
||||
// Finally, make 'n' key in table
|
||||
lua_pushstring(L, "n");
|
||||
lua_pushnumber(L, n+1);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
|
||||
|
||||
static void MakeConfigSettingsTable(lua_State *L, struct Auto3Interpreter *script)
|
||||
{
|
||||
struct Auto3ConfigOption *opt;
|
||||
|
||||
lua_newtable(L);
|
||||
|
||||
opt = script->config;
|
||||
while (opt->name) {
|
||||
lua_pushstring(L, opt->name);
|
||||
|
||||
switch (opt->kind) {
|
||||
case COK_TEXT:
|
||||
case COK_STYLE:
|
||||
case COK_COLOUR:
|
||||
lua_pushstring(L, opt->value.stringval);
|
||||
break;
|
||||
|
||||
case COK_INT:
|
||||
lua_pushnumber(L, opt->value.intval);
|
||||
break;
|
||||
|
||||
case COK_FLOAT:
|
||||
lua_pushnumber(L, opt->value.floatval);
|
||||
break;
|
||||
|
||||
case COK_BOOL:
|
||||
lua_pushboolean(L, opt->value.intval);
|
||||
break;
|
||||
|
||||
default:
|
||||
lua_pushnil(L);
|
||||
break;
|
||||
}
|
||||
|
||||
lua_settable(L, -3);
|
||||
|
||||
opt++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void ReadBackSubs(lua_State *L, struct Auto3Interpreter *script)
|
||||
{
|
||||
int layer, start_time, end_time, margin_l, margin_r, margin_v, comment;
|
||||
const char *style, *actor, *effect, *text, *kind;
|
||||
int i, n;
|
||||
|
||||
script->cb.start_subs_write(script->cb.rwdata);
|
||||
|
||||
i = 0;
|
||||
n = luaL_getn(L, -1);
|
||||
while (i <= n) {
|
||||
// Assume n is always correct, this is not entirely compatible
|
||||
lua_rawgeti(L, -1, i);
|
||||
if (script->cb.set_progress) script->cb.set_progress(script->cb.logdata, 100.f * i / n);
|
||||
i++;
|
||||
if (!lua_istable(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
lua_pushstring(L, "kind");
|
||||
lua_gettable(L, -2);
|
||||
if (!lua_isstring(L, -1)) {
|
||||
lua_pop(L, 2);
|
||||
continue;
|
||||
}
|
||||
kind = lua_tostring(L, -1);
|
||||
// leave kind on stack so it won't be gc'd
|
||||
|
||||
// Make comment rather tell if this is a "non-dialogue" line
|
||||
comment = strcmp(kind, "dialogue");
|
||||
// then test if it's a dialogue line (not non-dialogue) or is an actual comment
|
||||
if (!comment || strcmp(kind, "comment")) {
|
||||
|
||||
lua_pushstring(L, "layer");
|
||||
lua_gettable(L, -3);
|
||||
lua_pushstring(L, "start_time");
|
||||
lua_gettable(L, -4);
|
||||
lua_pushstring(L, "end_time");
|
||||
lua_gettable(L, -5);
|
||||
lua_pushstring(L, "style");
|
||||
lua_gettable(L, -6);
|
||||
lua_pushstring(L, "name");
|
||||
lua_gettable(L, -7);
|
||||
lua_pushstring(L, "margin_l");
|
||||
lua_gettable(L, -8);
|
||||
lua_pushstring(L, "margin_r");
|
||||
lua_gettable(L, -9);
|
||||
lua_pushstring(L, "margin_v");
|
||||
lua_gettable(L, -10);
|
||||
lua_pushstring(L, "effect");
|
||||
lua_gettable(L, -11);
|
||||
lua_pushstring(L, "text");
|
||||
lua_gettable(L, -12);
|
||||
|
||||
if (lua_isnumber(L, -10) && lua_isnumber(L, -9) && lua_isnumber(L, -8) &&
|
||||
lua_isstring(L, -7) && lua_isstring(L, -6) && lua_isnumber(L, -5) &&
|
||||
lua_isnumber(L, -4) && lua_isnumber(L, -3) && lua_isstring(L, -2) &&
|
||||
lua_isstring(L, -1)) {
|
||||
layer = (int)lua_tonumber(L, -10);
|
||||
start_time = (int)lua_tonumber(L, -9);
|
||||
end_time = (int)lua_tonumber(L, -8);
|
||||
style = lua_tostring(L, -7);
|
||||
actor = lua_tostring(L, -6);
|
||||
margin_l = (int)lua_tonumber(L, -5);
|
||||
margin_r = (int)lua_tonumber(L, -4);
|
||||
margin_v = (int)lua_tonumber(L, -3);
|
||||
effect = lua_tostring(L, -2);
|
||||
text = lua_tostring(L, -1);
|
||||
|
||||
script->cb.write_sub(script->cb.rwdata, layer, start_time, end_time, style, actor,
|
||||
margin_l, margin_r, margin_v, effect, text, comment);
|
||||
|
||||
} else {
|
||||
if (script->cb.log_error) script->cb.log_error(script->cb.logdata, "Skipping output line with invalid fields");
|
||||
}
|
||||
|
||||
lua_pop(L, 10);
|
||||
}
|
||||
|
||||
lua_pop(L, 2); // pop line and 'kind'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Start the script execution
|
||||
AUTO3_API int RunAuto3Script(struct Auto3Interpreter *script)
|
||||
{
|
||||
lua_State *L;
|
||||
|
||||
L = script->L;
|
||||
|
||||
if (script->cb.set_status) script->cb.set_status(script->cb.logdata, "Preparing subtitle data");
|
||||
if (script->cb.set_progress) script->cb.set_progress(script->cb.logdata, 0);
|
||||
|
||||
// first put the function itself on the stack
|
||||
lua_getglobal(L, "process_lines");
|
||||
|
||||
// now put the four arguments on the stack
|
||||
MakeMetaInfoTable(L, script);
|
||||
MakeStylesTable(L, script);
|
||||
MakeEventsTable(L, script);
|
||||
MakeConfigSettingsTable(L, script);
|
||||
|
||||
// do the actual call
|
||||
if (script->cb.set_status) script->cb.set_status(script->cb.logdata, "Running script");
|
||||
if (lua_pcall(L, 4, 1, 0)) {
|
||||
if (script->cb.log_error) {
|
||||
script->cb.log_error(script->cb.logdata, "Runtime error in script:");
|
||||
script->cb.log_error(script->cb.logdata, lua_tostring(L, -1));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check for initial sanity
|
||||
if (!lua_istable(L, -1)) {
|
||||
if (script->cb.log_error) script->cb.log_error(script->cb.logdata, "Script did not return a table, unable to process result");
|
||||
}
|
||||
|
||||
// Read back subtitles
|
||||
if (script->cb.set_status) script->cb.set_status(script->cb.logdata, "Reading back subtitle data");
|
||||
if (script->cb.set_progress) script->cb.set_progress(script->cb.logdata, 0);
|
||||
ReadBackSubs(L, script);
|
||||
|
||||
// Finished
|
||||
if (script->cb.set_progress) script->cb.set_progress(script->cb.logdata, 100);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,225 +0,0 @@
|
|||
// Copyright (c) 2007, Niels Martin Hansen
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// AEGISUB
|
||||
//
|
||||
// Website: http://aegisub.cellosoft.com
|
||||
// Contact: mailto:jiifurusu@gmail.com
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifdef AUTO3LIB
|
||||
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// On Win32, filenames are wide, but whatever encoding the system uses everywhere else
|
||||
#ifdef WIN32
|
||||
typedef wchar_t* filename_t;
|
||||
#else
|
||||
typedef char* filename_t;
|
||||
#endif
|
||||
|
||||
// All other strings involved are UTF-8, no need to do conversion back and forth here
|
||||
// So just hardcode char* as type for everything else
|
||||
|
||||
|
||||
#ifndef AUTO3LIB
|
||||
// Definitions used when building Aegisub (ie. importing the symbols)
|
||||
// I believe GCC also knows about __declspec(dllimport) etc. and does something sensible with it
|
||||
# ifdef _MSC_VER
|
||||
# define AUTO3_API __declspec(dllimport)
|
||||
# else
|
||||
# define AUTO3_API
|
||||
# endif
|
||||
#else
|
||||
// Otherwise we're exporting the symbols
|
||||
# ifdef _MSC_VER
|
||||
# define AUTO3_API __declspec(dllexport)
|
||||
# else
|
||||
# define AUTO3_API
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
// Stuff for configuration dialogs
|
||||
enum Auto3ConfigOptionKind {
|
||||
COK_INVALID = 0,
|
||||
COK_LABEL, // static text
|
||||
COK_TEXT, // textbox
|
||||
COK_INT, // integer entry, should get spin-button is possible
|
||||
COK_FLOAT, // float entry, also try for spin-button on this
|
||||
COK_BOOL, // bool entry, use a checkbox
|
||||
COK_COLOUR, // colour entry, use a picker if possible, otherwise text box
|
||||
COK_STYLE // style name, listbox with names of styles defined in subs
|
||||
};
|
||||
struct Auto3ConfigOption {
|
||||
char *name;
|
||||
enum Auto3ConfigOptionKind kind;
|
||||
char *label;
|
||||
char *hint;
|
||||
struct {
|
||||
int valid; // non-zero if the value is present
|
||||
int intval;
|
||||
float floatval;
|
||||
} min, max;
|
||||
union {
|
||||
char *stringval; // text, colour (vb-hex style-line format), style
|
||||
int intval; // also bool, nonzero is true
|
||||
float floatval;
|
||||
} default_val, value;
|
||||
};
|
||||
|
||||
|
||||
// Callback interface
|
||||
// The application should provide ALL of these functions
|
||||
struct Auto3Callbacks {
|
||||
// Logging and status
|
||||
// pointer passed to logging/status callbacks
|
||||
void *logdata;
|
||||
// log error during script execution
|
||||
void (*log_error)(void *cbdata, const char *msg);
|
||||
// log message during script execution
|
||||
void (*log_message)(void *cbdata, const char *msg);
|
||||
// set progress during script execution
|
||||
void (*set_progress)(void *cbdata, float progress);
|
||||
// set status message during script execution
|
||||
void (*set_status)(void *cbdata, const char* msg);
|
||||
|
||||
// Reading/writing subtitles and related information
|
||||
// pointer passed to read/write data callbacks
|
||||
void *rwdata;
|
||||
// application sets *res_x and *res_y to appropriate values
|
||||
void (*get_meta_info)(void *cbdata, int *res_x, int *res_y);
|
||||
// set style pointer to point at first style
|
||||
void (*reset_style_pointer)(void *cbdata);
|
||||
// Get the next style, the application must fill the data into its own buffers, which it then fill in pointers to
|
||||
// (Ie. the application owns all strings allocated for this callback.)
|
||||
// Return non-zero if a style was found and values filled, otherwise return zero
|
||||
int (*get_next_style)(
|
||||
void *cbdata, char **name, char **fontname, int *fontsize, char **color1, char **color2, char **color3, char **color4,
|
||||
int *bold, int *italic, int *underline, int *strikeout, float *scale_x, float *scale_y, float *spacing, float *angle,
|
||||
int *borderstyle, float *outline, float *shadow, int *align, int *margin_l, int *margin_r, int *margin_v, int *encoding);
|
||||
// set subtitle pointer to point at first subtitle line
|
||||
void (*reset_subs_pointer)(void *cbdata);
|
||||
// Get next subtitle line, the application must fill the data into its own buffers, and then fill in pointers to those
|
||||
// Return non-zero if a style was found and values filled, otherwise return zero
|
||||
int (*get_next_sub)(
|
||||
void *cbdata, int *layer, int *start_time, int *end_time, char **style, char **actor,
|
||||
int *margin_l, int *margin_r, int *margin_v, char **effect, char **text, int *comment);
|
||||
// start writing back new subtitles, application must clear all subtitle lines and be ready to write
|
||||
void (*start_subs_write)(void *cbdata);
|
||||
// Write a subtitle line back to subtitle file, char pointers are owned by the lib
|
||||
void (*write_sub)(void *cbdata, int layer, int start_time, int end_time, const char *style, const char *actor,
|
||||
int margin_l, int margin_r, int margin_v, const char *effect, const char *text, int comment);
|
||||
|
||||
// Getting various environment information during runtime
|
||||
// pointer passed to runtime data callbacks
|
||||
void *rundata;
|
||||
// Resolve a filename passed to the include function
|
||||
// The result must be allocated with Auto3Malloc and will be free'd by the lib
|
||||
filename_t (*resolve_include)(void *cbdata, const char *incname);
|
||||
// Get sizing information for a text string given a style
|
||||
void (*text_extents)(void *cbdata, const char *text, const char *fontname, int fontsize, int bold, int italic,
|
||||
int spacing, float scale_x, float scale_y, int encoding,
|
||||
float *out_width, float *out_height, float *out_descent, float *out_extlead);
|
||||
// Convert a time in milliseconds to a video frame number
|
||||
int (*frame_from_ms)(void *cbdata, int ms);
|
||||
// Convert a video frame number to a time in milliseconds
|
||||
int (*ms_from_frame)(void *cbdata, int frame);
|
||||
};
|
||||
|
||||
|
||||
// Describes an interpreter
|
||||
struct Auto3Interpreter {
|
||||
// Public attributes, treat them as read-only
|
||||
char *name;
|
||||
char *description;
|
||||
|
||||
// Configuration dialog options
|
||||
// End of list marked with name==NULL
|
||||
// You may change the "value" field of these (in fact, do so)
|
||||
struct Auto3ConfigOption *config;
|
||||
|
||||
// Callbacks
|
||||
// This is filled in from the 'cb' argument to the Create function,
|
||||
// but may be modified later by the application
|
||||
struct Auto3Callbacks cb;
|
||||
|
||||
#ifdef AUTO3LIB
|
||||
// Private data
|
||||
lua_State *L;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
// Create a new interpreter
|
||||
// filename is name of script file
|
||||
// prettyname is a UTF-8 string used as identifier for the script in error messages
|
||||
// cb should point to an Auto3Callbacks struct filled in; a copy of this struct will be made
|
||||
// error will be filled with any error message on fail, the application is responsible for freeing this string (use Auto3Free)
|
||||
// Returns pointer to interpreter object if successful, otherwise NULL
|
||||
AUTO3_API struct Auto3Interpreter *CreateAuto3Script(const filename_t filename, const char *prettyname, struct Auto3Callbacks *cb, char **error);
|
||||
// Release an interpreter
|
||||
AUTO3_API void DestroyAuto3Script(struct Auto3Interpreter *script);
|
||||
|
||||
// Our "malloc" function, allocate memory for strings with this
|
||||
AUTO3_API void *Auto3Malloc(size_t amount);
|
||||
// Convenience function, use this for duplicating strings this lib should own
|
||||
AUTO3_API char *Auto3Strdup(const char *str);
|
||||
// Our "free" function, free strings with this
|
||||
AUTO3_API void Auto3Free(void *ptr);
|
||||
|
||||
// Start the script execution
|
||||
// script->logcbdata and log->rwcbdata should be set to sensible values before this call.
|
||||
// The value fields in the config dialog should also be set to values entered by the user here.
|
||||
// This will first call get_meta_info,
|
||||
// then reset_style pointer followed by a number of calls to get_next_style,
|
||||
// then a call to reset_subs_pointer followed by a number of calls to get_next_sub,
|
||||
// then actual processing will take place.
|
||||
// After processing, start_subs_write will be called, followed by a number of calls to write_sub.
|
||||
// Any number of calls to the logging/status functions can take place during script execution
|
||||
// Returns non-zero on error
|
||||
AUTO3_API int RunAuto3Script(struct Auto3Interpreter *script);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}; // extern "C"
|
||||
#endif
|
|
@ -1,375 +0,0 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="auto3_vc9"
|
||||
ProjectGUID="{F57D079E-3022-40FA-9BC9-C149D89D9EC9}"
|
||||
RootNamespace="auto3_vc9"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\..\build\aegisub_vs2008\suffix_debug32.vsprops;..\..\build\aegisub_vs2008\libraries_outdirs.vsprops;.\auto3_vc9.vsprops"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;AUTO3_VC9_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\..\build\aegisub_vs2008\suffix_release32.vsprops;..\..\build\aegisub_vs2008\libraries_outdirs.vsprops;.\auto3_vc9.vsprops"
|
||||
CharacterSet="0"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;AUTO3_VC9_EXPORTS"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\..\build\aegisub_vs2008\suffix_debug64.vsprops;..\..\build\aegisub_vs2008\libraries_outdirs.vsprops;.\auto3_vc9.vsprops"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;AUTO3_VC9_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\..\build\aegisub_vs2008\suffix_release64.vsprops;..\..\build\aegisub_vs2008\libraries_outdirs.vsprops;.\auto3_vc9.vsprops"
|
||||
CharacterSet="0"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;AUTO3_VC9_EXPORTS"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\auto3.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\callables.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\auto3.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="auto3_vc9"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="$(ProjectDir)../../../contrib/lua50/include/"
|
||||
PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;AUTO3LIB"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(ExecutableOutDir)/libauto3_$(PlatformConfigSuffix).dll"
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
|
@ -1,207 +0,0 @@
|
|||
// Copyright (c) 2005, 2006, 2007, Niels Martin Hansen
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// AEGISUB
|
||||
//
|
||||
// Website: http://aegisub.cellosoft.com
|
||||
// Contact: mailto:jiifurusu@gmail.com
|
||||
//
|
||||
|
||||
// DO NOT compile this file separately! It's included as part of auto3.c
|
||||
#ifndef BUILDING_AUTO3_C
|
||||
# error callables.c can not be compiled separately. It is included as part of auto3.c.
|
||||
#endif
|
||||
|
||||
|
||||
static struct Auto3Interpreter* GetScriptObject(lua_State *L)
|
||||
{
|
||||
return (struct Auto3Interpreter *)lua_touserdata(L, lua_upvalueindex(1));
|
||||
}
|
||||
|
||||
|
||||
static int LuaInclude(lua_State *L)
|
||||
{
|
||||
filename_t filename;
|
||||
const char *incname;
|
||||
char *error;
|
||||
struct Auto3Interpreter *script;
|
||||
script = GetScriptObject(L);
|
||||
|
||||
if (!script->cb.resolve_include) {
|
||||
lua_pushstring(L, "Attempt to use include, but not implemented by host application");
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
incname = luaL_checkstring(L, 1);
|
||||
|
||||
filename = script->cb.resolve_include(script->cb.rundata, incname);
|
||||
|
||||
if (filename) {
|
||||
// Load include
|
||||
if (Auto3LuaLoad(L, filename, incname, &error)) {
|
||||
free(filename);
|
||||
lua_pushfstring(L, "Failed to include file '%s', error: %s", incname, error);
|
||||
lua_error(L);
|
||||
}
|
||||
// Run include (don't protect, we're already in a protected environment, we'd just propagate it anyway)
|
||||
lua_call(L, 0, 0);
|
||||
free(filename);
|
||||
} else {
|
||||
lua_pushfstring(L, "Failed to resolve include file '%s'", incname);
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
// Not really compatible, but I don't think anyone have ever exploited that includes can return stuff
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int LuaTextExtents(lua_State *L)
|
||||
{
|
||||
struct Auto3Interpreter *script;
|
||||
const char *text, *fontname;
|
||||
int fontsize, bold, italic, spacing, encoding;
|
||||
float scale_x, scale_y;
|
||||
float out_width, out_height, out_descent, out_extlead;
|
||||
|
||||
script = GetScriptObject(L);
|
||||
|
||||
if (!script->cb.text_extents) return 0;
|
||||
|
||||
// get text
|
||||
text = luaL_checkstring(L, 2);
|
||||
|
||||
// check we have style table
|
||||
if (!lua_istable(L, 1)) {
|
||||
lua_pushstring(L, "First argument to text_extents must be style table");
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
// get style def
|
||||
lua_pushstring(L, "fontname"); lua_gettable(L, 1);
|
||||
fontname = lua_tostring(L, -1);
|
||||
|
||||
lua_pushstring(L, "fontsize"); lua_gettable(L, 1);
|
||||
fontsize = (int)lua_tonumber(L, -1);
|
||||
|
||||
lua_pushstring(L, "bold"); lua_gettable(L, 1);
|
||||
bold = lua_toboolean(L, -1);
|
||||
|
||||
lua_pushstring(L, "italic"); lua_gettable(L, 1);
|
||||
italic = lua_toboolean(L, -1);
|
||||
|
||||
lua_pushstring(L, "scale_x"); lua_gettable(L, 1);
|
||||
scale_x = (float)lua_tonumber(L, -1);
|
||||
|
||||
lua_pushstring(L, "scale_y"); lua_gettable(L, 1);
|
||||
scale_y = (float)lua_tonumber(L, -1);
|
||||
|
||||
lua_pushstring(L, "spacing"); lua_gettable(L, 1);
|
||||
spacing = (int)lua_tonumber(L, -1);
|
||||
|
||||
lua_pushstring(L, "encoding"); lua_gettable(L, 1);
|
||||
encoding = (int)lua_tonumber(L, -1);
|
||||
|
||||
// get measurements
|
||||
script->cb.text_extents(script->cb.rundata, text, fontname, fontsize, bold, italic,
|
||||
spacing, scale_x, scale_y, encoding, &out_width, &out_height, &out_descent, &out_extlead);
|
||||
|
||||
// remove strings and stuff
|
||||
lua_pop(L, 8);
|
||||
|
||||
// return result
|
||||
lua_pushnumber(L, out_width);
|
||||
lua_pushnumber(L, out_height);
|
||||
lua_pushnumber(L, out_descent);
|
||||
lua_pushnumber(L, out_extlead);
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
||||
static int LuaFrameFromMs(lua_State *L)
|
||||
{
|
||||
int frame;
|
||||
struct Auto3Interpreter *script;
|
||||
script = GetScriptObject(L);
|
||||
|
||||
if (!script->cb.frame_from_ms) return 0;
|
||||
|
||||
frame = script->cb.frame_from_ms(script->cb.rundata, luaL_checkint(L, 1));
|
||||
lua_pushnumber(L, frame);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int LuaMsFromFrame(lua_State *L)
|
||||
{
|
||||
int ms;
|
||||
struct Auto3Interpreter *script;
|
||||
script = GetScriptObject(L);
|
||||
|
||||
if (!script->cb.ms_from_frame) return 0;
|
||||
|
||||
ms = script->cb.ms_from_frame(script->cb.rundata, luaL_checkint(L, 1));
|
||||
lua_pushnumber(L, ms);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int LuaReportProgress(lua_State *L)
|
||||
{
|
||||
struct Auto3Interpreter *script;
|
||||
script = GetScriptObject(L);
|
||||
|
||||
if (script->cb.set_progress) script->cb.set_progress(script->cb.logdata, (float)luaL_checknumber(L, 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int LuaOutputDebug(lua_State *L)
|
||||
{
|
||||
struct Auto3Interpreter *script;
|
||||
script = GetScriptObject(L);
|
||||
|
||||
if (script->cb.log_message) script->cb.log_message(script->cb.logdata, luaL_checkstring(L, 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int LuaSetStatus(lua_State *L)
|
||||
{
|
||||
struct Auto3Interpreter *script;
|
||||
script = GetScriptObject(L);
|
||||
|
||||
if (script->cb.set_status) script->cb.set_status(script->cb.logdata, luaL_checkstring(L, 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue