2011-01-11 20:41:46 +02:00
|
|
|
#include "externals.h"
|
|
|
|
#include "internals.h"
|
2011-04-11 12:12:57 +03:00
|
|
|
#include "list.h"
|
2011-04-18 15:32:21 +03:00
|
|
|
#include "idf.h"
|
2011-01-11 20:41:46 +02:00
|
|
|
|
2009-08-26 08:25:53 +03:00
|
|
|
#ifndef STEAD_PATH
|
|
|
|
#define STEAD_PATH "./stead"
|
|
|
|
#endif
|
|
|
|
|
2009-02-21 12:52:44 +02:00
|
|
|
/* the Lua interpreter */
|
|
|
|
|
2011-02-19 15:23:09 +02:00
|
|
|
static gtimer_t instead_timer = NULL_TIMER;
|
2010-10-30 15:54:41 +03:00
|
|
|
static int instead_timer_nr = 0;
|
|
|
|
|
2009-02-21 12:52:44 +02:00
|
|
|
char *fromgame(const char *s);
|
|
|
|
char *togame(const char *s);
|
|
|
|
lua_State *L = NULL;
|
|
|
|
|
2009-08-26 08:25:53 +03:00
|
|
|
static int report (lua_State *L, int status)
|
|
|
|
{
|
|
|
|
if (status && !lua_isnil(L, -1)) {
|
2010-02-17 07:51:10 +02:00
|
|
|
char *p;
|
2009-08-26 08:25:53 +03:00
|
|
|
const char *msg = lua_tostring(L, -1);
|
|
|
|
if (msg == NULL)
|
|
|
|
msg = "(error object is not a string)";
|
|
|
|
fprintf(stderr,"Error: %s\n", msg);
|
2010-02-17 07:51:10 +02:00
|
|
|
p = fromgame(msg);
|
|
|
|
game_err_msg(p?p:msg);
|
|
|
|
if (p)
|
|
|
|
free(p);
|
2009-08-26 08:25:53 +03:00
|
|
|
lua_pop(L, 1);
|
|
|
|
status = -1;
|
2010-10-30 15:54:41 +03:00
|
|
|
gfx_del_timer(instead_timer); /* to avoid error loops */
|
2011-02-19 15:23:09 +02:00
|
|
|
instead_timer = NULL_TIMER;
|
2009-08-26 08:25:53 +03:00
|
|
|
}
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int traceback (lua_State *L)
|
|
|
|
{
|
|
|
|
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
|
|
|
|
if (!lua_istable(L, -1)) {
|
|
|
|
lua_pop(L, 1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
lua_getfield(L, -1, "traceback");
|
|
|
|
if (!lua_isfunction(L, -1)) {
|
|
|
|
lua_pop(L, 2);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
lua_pushvalue(L, 1); /* pass error message */
|
|
|
|
lua_pushinteger(L, 2); /* skip this function and traceback */
|
|
|
|
lua_call(L, 2, 1); /* call debug.traceback */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int docall (lua_State *L)
|
|
|
|
{
|
|
|
|
int status;
|
|
|
|
int base = 0;
|
|
|
|
if (debug_sw) {
|
|
|
|
base = lua_gettop(L); /* function index */
|
|
|
|
lua_pushcfunction(L, traceback); /* push traceback function */
|
|
|
|
lua_insert(L, base); /* put it under chunk and args */
|
|
|
|
}
|
|
|
|
status = lua_pcall(L, 0, LUA_MULTRET, base);
|
|
|
|
if (debug_sw)
|
|
|
|
lua_remove(L, base); /* remove traceback function */
|
|
|
|
/* force a complete garbage collection in case of errors */
|
|
|
|
if (status != 0)
|
|
|
|
lua_gc(L, LUA_GCCOLLECT, 0);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int dofile (lua_State *L, const char *name) {
|
|
|
|
int status = luaL_loadfile(L, name) || docall(L);
|
|
|
|
return report(L, status);
|
|
|
|
}
|
|
|
|
|
2011-04-18 16:56:33 +03:00
|
|
|
static const char *idf_reader(lua_State *L, void *data, size_t *size)
|
|
|
|
{
|
|
|
|
static char buff[4096];
|
|
|
|
int rc;
|
|
|
|
rc = idf_read((idff_t)data, buff, 1, sizeof(buff));
|
|
|
|
*size = rc;
|
|
|
|
if (!rc)
|
|
|
|
return NULL;
|
|
|
|
return buff;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int dofile_idf (lua_State *L, idff_t idf, const char *name) {
|
|
|
|
int status = lua_load(L, idf_reader, idf, name) || docall(L);
|
|
|
|
return report(L, status);
|
|
|
|
}
|
|
|
|
|
2009-08-26 08:25:53 +03:00
|
|
|
static int dostring (lua_State *L, const char *s) {
|
|
|
|
int status = luaL_loadstring(L, s) || docall(L);
|
|
|
|
return report(L, status);
|
|
|
|
}
|
|
|
|
|
2009-02-21 12:52:44 +02:00
|
|
|
char *getstring(char *cmd)
|
|
|
|
{
|
|
|
|
char *s;
|
2009-11-13 10:19:23 +02:00
|
|
|
int N;
|
2009-02-21 12:52:44 +02:00
|
|
|
if (!L)
|
|
|
|
return NULL;
|
2009-08-26 08:25:53 +03:00
|
|
|
if (dostring(L, cmd))
|
|
|
|
return NULL;
|
2009-11-13 10:19:23 +02:00
|
|
|
N = lua_gettop(L); /* number of arguments */
|
2010-02-01 17:37:51 +02:00
|
|
|
if (-N >=0)
|
2009-11-13 10:19:23 +02:00
|
|
|
return NULL;
|
|
|
|
s = (char*)lua_tostring(L, -N);
|
2009-02-21 12:52:44 +02:00
|
|
|
if (s)
|
|
|
|
s = fromgame(s);
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2009-11-12 11:07:17 +02:00
|
|
|
int instead_eval(char *s)
|
2009-02-21 12:52:44 +02:00
|
|
|
{
|
2009-11-12 11:07:17 +02:00
|
|
|
if (!L)
|
|
|
|
return -1;
|
|
|
|
if (dostring(L, s))
|
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-11-13 10:19:23 +02:00
|
|
|
int instead_clear(void)
|
|
|
|
{
|
|
|
|
int N;
|
|
|
|
if (!L)
|
|
|
|
return -1;
|
|
|
|
N = lua_gettop(L); /* number of arguments */
|
|
|
|
lua_pop(L, N);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-11-12 11:07:17 +02:00
|
|
|
char *instead_retval(int n)
|
|
|
|
{
|
|
|
|
char *s;
|
2009-11-13 10:19:23 +02:00
|
|
|
int N;
|
|
|
|
if (!L)
|
|
|
|
return NULL;
|
|
|
|
N = lua_gettop(L); /* number of arguments */
|
2009-11-13 10:42:48 +02:00
|
|
|
/* fprintf(stderr,"%d\n", N); */
|
2009-11-13 10:19:23 +02:00
|
|
|
if (n - N >= 0)
|
|
|
|
return NULL;
|
|
|
|
s = (char*)lua_tostring(L, n - N);
|
2009-11-12 11:07:17 +02:00
|
|
|
if (s)
|
|
|
|
s = fromgame(s);
|
|
|
|
return s;
|
2009-02-21 12:52:44 +02:00
|
|
|
}
|
|
|
|
|
2009-11-13 10:19:23 +02:00
|
|
|
int instead_bretval(int n)
|
|
|
|
{
|
|
|
|
int N;
|
|
|
|
if (!L)
|
|
|
|
return 0;
|
|
|
|
N = lua_gettop(L); /* number of arguments */
|
|
|
|
if (n - N >= 0)
|
|
|
|
return 1;
|
|
|
|
return lua_toboolean(L, n - N);
|
2009-11-14 20:10:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int instead_iretval(int n)
|
|
|
|
{
|
|
|
|
int N;
|
|
|
|
if (!L)
|
|
|
|
return 0;
|
|
|
|
N = lua_gettop(L); /* number of arguments */
|
|
|
|
if (n - N >= 0)
|
|
|
|
return 0;
|
|
|
|
return lua_tonumber(L, n - N);
|
2009-11-13 10:19:23 +02:00
|
|
|
}
|
2010-09-22 13:15:23 +03:00
|
|
|
|
2010-09-15 11:35:54 +03:00
|
|
|
char *instead_cmd(char *s)
|
|
|
|
{
|
2010-09-16 16:16:43 +03:00
|
|
|
struct instead_args args[] = {
|
|
|
|
{ .val = NULL, .type = INSTEAD_STR },
|
|
|
|
{ .val = NULL, },
|
|
|
|
};
|
2010-09-15 11:35:54 +03:00
|
|
|
if (!s)
|
|
|
|
return NULL;
|
2010-09-16 16:16:43 +03:00
|
|
|
s = togame(s);
|
|
|
|
if (!s)
|
|
|
|
return NULL;
|
|
|
|
args[0].val = s;
|
|
|
|
instead_function("iface:cmd", args);
|
|
|
|
free(s);
|
|
|
|
return instead_retval(0);
|
2010-09-15 11:35:54 +03:00
|
|
|
}
|
2010-09-22 13:15:23 +03:00
|
|
|
|
2010-09-16 16:16:43 +03:00
|
|
|
int instead_function(char *s, struct instead_args *args)
|
2010-09-15 11:35:54 +03:00
|
|
|
{
|
2010-09-16 16:16:43 +03:00
|
|
|
int base = 0;
|
|
|
|
int status = 0;
|
|
|
|
int n = 0;
|
2010-09-15 11:35:54 +03:00
|
|
|
char *p;
|
|
|
|
char f[64];
|
|
|
|
int method = 0;
|
2010-11-01 19:23:54 +02:00
|
|
|
if (!L)
|
|
|
|
return -1;
|
2010-09-15 11:35:54 +03:00
|
|
|
strcpy(f, s);
|
|
|
|
p = strchr(f, '.');
|
|
|
|
if (!p)
|
|
|
|
p = strchr(f, ':');
|
|
|
|
if (p) {
|
|
|
|
if (*p == ':')
|
|
|
|
method = 1;
|
|
|
|
*p = 0;
|
|
|
|
p ++;
|
|
|
|
lua_getglobal(L, f);
|
|
|
|
lua_getfield(L, -1, p);
|
|
|
|
lua_remove(L, -2);
|
|
|
|
if (method)
|
|
|
|
lua_getglobal(L, f);
|
|
|
|
} else
|
|
|
|
lua_getglobal(L, s);
|
|
|
|
if (args) {
|
2010-09-16 16:16:43 +03:00
|
|
|
while (args->val) {
|
|
|
|
switch(args->type) {
|
|
|
|
case INSTEAD_NIL:
|
2010-09-15 11:35:54 +03:00
|
|
|
lua_pushnil(L);
|
2010-09-16 16:16:43 +03:00
|
|
|
break;
|
|
|
|
case INSTEAD_NUM:
|
|
|
|
lua_pushnumber(L, atoi(args->val));
|
|
|
|
break;
|
|
|
|
case INSTEAD_BOOL:
|
|
|
|
if (!strcmp(args->val, "true"))
|
|
|
|
lua_pushboolean(L, 1);
|
|
|
|
else
|
|
|
|
lua_pushboolean(L, 0);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
case INSTEAD_STR:
|
|
|
|
lua_pushstring(L, args->val);
|
|
|
|
}
|
|
|
|
args ++;
|
|
|
|
n ++;
|
2010-09-15 11:35:54 +03:00
|
|
|
}
|
|
|
|
}
|
2010-09-22 09:48:40 +03:00
|
|
|
if (debug_sw) {
|
|
|
|
base = lua_gettop(L) - (method + n); /* function index */
|
|
|
|
lua_pushcfunction(L, traceback); /* push traceback function */
|
|
|
|
lua_insert(L, base); /* put it under chunk and args */
|
|
|
|
}
|
2010-09-16 16:16:43 +03:00
|
|
|
status = lua_pcall(L, method + n, LUA_MULTRET, base);
|
2010-09-22 09:48:40 +03:00
|
|
|
if (debug_sw)
|
|
|
|
lua_remove(L, base); /* remove traceback function */
|
2010-09-16 16:16:43 +03:00
|
|
|
if (status) {
|
|
|
|
fprintf(stderr, "Error calling:%s\n", s);
|
|
|
|
lua_gc(L, LUA_GCCOLLECT, 0);
|
2010-09-15 11:35:54 +03:00
|
|
|
}
|
2010-09-16 16:16:43 +03:00
|
|
|
return report(L, status);
|
2010-09-15 11:35:54 +03:00
|
|
|
}
|
2009-02-21 12:52:44 +02:00
|
|
|
|
|
|
|
int luacall(char *cmd)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
if (!L)
|
|
|
|
return -1;
|
2009-08-26 08:25:53 +03:00
|
|
|
if (dostring(L, cmd)) {
|
|
|
|
return -1;
|
2009-02-21 12:52:44 +02:00
|
|
|
}
|
|
|
|
rc = lua_tonumber(L, -1);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2009-08-26 08:25:53 +03:00
|
|
|
#ifdef _HAVE_ICONV
|
2009-02-21 12:52:44 +02:00
|
|
|
static char *curcp = "UTF-8";
|
|
|
|
static char *fromcp = NULL;
|
|
|
|
#endif
|
|
|
|
|
2009-08-26 08:25:53 +03:00
|
|
|
#ifdef _HAVE_ICONV
|
2009-02-21 12:52:44 +02:00
|
|
|
char *fromgame(const char *s)
|
|
|
|
{
|
|
|
|
iconv_t han;
|
|
|
|
char *str;
|
|
|
|
if (!s)
|
|
|
|
return NULL;
|
|
|
|
if (!fromcp)
|
|
|
|
goto out0;
|
|
|
|
han = iconv_open(curcp, fromcp);
|
|
|
|
if (han == (iconv_t)-1)
|
|
|
|
goto out0;
|
|
|
|
if (!(str = decode(han, s)))
|
|
|
|
goto out1;
|
|
|
|
iconv_close(han);
|
|
|
|
return str;
|
|
|
|
out1:
|
|
|
|
iconv_close(han);
|
|
|
|
out0:
|
|
|
|
return strdup(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
char *togame(const char *s)
|
|
|
|
{
|
|
|
|
iconv_t han;
|
|
|
|
char *str;
|
|
|
|
if (!s)
|
|
|
|
return NULL;
|
|
|
|
if (!fromcp)
|
|
|
|
goto out0;
|
|
|
|
han = iconv_open(fromcp, curcp);
|
|
|
|
if (han == (iconv_t)-1)
|
|
|
|
goto out0;
|
|
|
|
if (!(str = decode(han, s)))
|
|
|
|
goto out1;
|
|
|
|
iconv_close(han);
|
|
|
|
return str;
|
|
|
|
out1:
|
|
|
|
iconv_close(han);
|
|
|
|
out0:
|
|
|
|
return strdup(s);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
char *fromgame(const char *s)
|
|
|
|
{
|
|
|
|
if (!s)
|
|
|
|
return NULL;
|
|
|
|
return strdup(s);
|
|
|
|
}
|
|
|
|
char *togame(const char *s)
|
|
|
|
{
|
|
|
|
if (!s)
|
|
|
|
return NULL;
|
|
|
|
return strdup(s);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
int instead_load(char *game)
|
|
|
|
{
|
2011-04-18 16:56:33 +03:00
|
|
|
idff_t idf = idf_open(game_idf, game);
|
|
|
|
if (idf) {
|
|
|
|
int rc = dofile_idf(L, idf, game);
|
|
|
|
idf_close(idf);
|
|
|
|
if (rc)
|
|
|
|
return -1;
|
|
|
|
} else if (dofile(L, dirpath(game))) {
|
2009-02-21 12:52:44 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2010-02-01 17:37:51 +02:00
|
|
|
instead_clear();
|
2009-08-26 08:25:53 +03:00
|
|
|
#ifdef _HAVE_ICONV
|
2009-02-21 12:52:44 +02:00
|
|
|
if (fromcp)
|
|
|
|
free(fromcp);
|
|
|
|
fromcp = getstring("return game.codepage;");
|
2009-11-13 10:19:23 +02:00
|
|
|
instead_clear();
|
2009-02-21 12:52:44 +02:00
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-10-12 08:07:15 +03:00
|
|
|
typedef struct LoadF {
|
|
|
|
int extraline;
|
|
|
|
unsigned char byte;
|
|
|
|
FILE *f;
|
2011-04-18 15:32:21 +03:00
|
|
|
idff_t idff;
|
2010-09-10 13:06:30 +03:00
|
|
|
int enc;
|
2009-10-12 09:35:06 +03:00
|
|
|
unsigned char buff[4096];
|
2009-10-12 08:07:15 +03:00
|
|
|
} LoadF;
|
|
|
|
|
|
|
|
static const char *getF (lua_State *L, void *ud, size_t *size) {
|
|
|
|
int i = 0;
|
|
|
|
LoadF *lf = (LoadF *)ud;
|
|
|
|
(void)L;
|
|
|
|
if (lf->extraline) {
|
|
|
|
lf->extraline = 0;
|
|
|
|
*size = 1;
|
|
|
|
return "\n";
|
|
|
|
}
|
2011-04-18 15:32:21 +03:00
|
|
|
|
|
|
|
if (lf->f && feof(lf->f))
|
|
|
|
return NULL;
|
|
|
|
if (lf->idff && idf_eof(lf->idff))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (lf->idff)
|
|
|
|
*size = idf_read(lf->idff, lf->buff, 1, sizeof(lf->buff));
|
|
|
|
else
|
|
|
|
*size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
|
|
|
|
|
2010-09-10 13:06:30 +03:00
|
|
|
if (lf->enc) {
|
|
|
|
for (i = 0; i < *size; i ++) {
|
|
|
|
unsigned char b = lf->buff[i];
|
|
|
|
lf->buff[i] ^= lf->byte;
|
|
|
|
lf->buff[i] = (lf->buff[i] >> 3) | (lf->buff[i] << 5);
|
|
|
|
lf->byte = b;
|
|
|
|
}
|
2009-10-12 08:07:15 +03:00
|
|
|
}
|
|
|
|
return (*size > 0) ? (char*)lf->buff : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int errfile (lua_State *L, const char *what, int fnameindex) {
|
|
|
|
const char *serr = strerror(errno);
|
|
|
|
const char *filename = lua_tostring(L, fnameindex) + 1;
|
|
|
|
lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
|
|
|
|
lua_remove(L, fnameindex);
|
|
|
|
return LUA_ERRFILE;
|
|
|
|
}
|
|
|
|
|
2010-09-10 13:06:30 +03:00
|
|
|
static int loadfile (lua_State *L, const char *filename, int enc) {
|
2009-10-12 08:07:15 +03:00
|
|
|
LoadF lf;
|
|
|
|
int status, readstatus;
|
|
|
|
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
|
|
|
|
lf.extraline = 0;
|
|
|
|
lua_pushfstring(L, "@%s", filename);
|
2011-04-18 15:32:21 +03:00
|
|
|
lf.idff = idf_open(game_idf, filename);
|
|
|
|
if (!lf.idff)
|
2011-04-18 15:37:57 +03:00
|
|
|
lf.f = fopen(dirpath(filename), "rb");
|
2011-04-18 15:32:21 +03:00
|
|
|
else
|
|
|
|
lf.f = NULL;
|
2009-10-12 08:07:15 +03:00
|
|
|
lf.byte = 0xcc;
|
2010-09-10 13:06:30 +03:00
|
|
|
lf.enc = enc;
|
2011-04-18 15:32:21 +03:00
|
|
|
if (lf.f == NULL && lf.idff == NULL) return errfile(L, "open", fnameindex);
|
2009-10-12 08:07:15 +03:00
|
|
|
status = lua_load(L, getF, &lf, lua_tostring(L, -1));
|
2011-04-18 15:32:21 +03:00
|
|
|
|
|
|
|
if (lf.f)
|
|
|
|
readstatus = ferror(lf.f);
|
|
|
|
else
|
|
|
|
readstatus = idf_error(lf.idff);
|
|
|
|
|
|
|
|
if (filename) {
|
|
|
|
if (lf.f)
|
|
|
|
fclose(lf.f); /* close file (even in case of errors) */
|
|
|
|
idf_close(lf.idff);
|
|
|
|
}
|
2009-10-12 08:07:15 +03:00
|
|
|
if (readstatus) {
|
|
|
|
lua_settop(L, fnameindex); /* ignore results from `lua_load' */
|
|
|
|
return errfile(L, "read", fnameindex);
|
|
|
|
}
|
|
|
|
lua_remove(L, fnameindex);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int luaB_doencfile (lua_State *L) {
|
|
|
|
const char *fname = luaL_optstring(L, 1, NULL);
|
|
|
|
int n = lua_gettop(L);
|
2011-04-18 15:37:57 +03:00
|
|
|
if (loadfile(L, fname, 1) != 0) lua_error(L);
|
2010-09-10 13:06:30 +03:00
|
|
|
lua_call(L, 0, LUA_MULTRET);
|
|
|
|
return lua_gettop(L) - n;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int luaB_dofile (lua_State *L) {
|
|
|
|
const char *fname = luaL_optstring(L, 1, NULL);
|
|
|
|
int n = lua_gettop(L);
|
2011-04-18 15:37:57 +03:00
|
|
|
if (loadfile(L, fname, 0) != 0) lua_error(L);
|
2009-10-12 08:07:15 +03:00
|
|
|
lua_call(L, 0, LUA_MULTRET);
|
|
|
|
return lua_gettop(L) - n;
|
|
|
|
}
|
|
|
|
|
2009-10-12 20:02:59 +03:00
|
|
|
static int luaB_print (lua_State *L) {
|
|
|
|
int n = lua_gettop(L); /* number of arguments */
|
|
|
|
int i;
|
|
|
|
lua_getglobal(L, "tostring");
|
|
|
|
for (i=1; i<=n; i++) {
|
|
|
|
const char *s;
|
|
|
|
lua_pushvalue(L, -1); /* function to be called */
|
|
|
|
lua_pushvalue(L, i); /* value to print */
|
|
|
|
lua_call(L, 1, 1);
|
|
|
|
s = lua_tostring(L, -1); /* get result */
|
|
|
|
if (s == NULL)
|
|
|
|
return luaL_error(L, LUA_QL("tostring") " must return a string to "LUA_QL("print"));
|
|
|
|
if (i>1) fputs("\t", stdout);
|
|
|
|
fputs(s, stdout);
|
|
|
|
lua_pop(L, 1); /* pop result */
|
|
|
|
}
|
|
|
|
fputs("\n", stdout);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-11-12 11:07:17 +02:00
|
|
|
static int luaB_is_sound(lua_State *L) {
|
|
|
|
const char *chan = luaL_optstring(L, 1, NULL);
|
|
|
|
int c, r;
|
|
|
|
if (!chan)
|
|
|
|
c = -1;
|
|
|
|
else
|
|
|
|
c = atoi(chan);
|
|
|
|
r = snd_playing(c);
|
|
|
|
lua_pushboolean(L, (r != 0)); /* else not a number */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2010-06-03 18:12:42 +03:00
|
|
|
static int luaB_get_savepath(lua_State *L) {
|
2010-11-23 19:32:47 +02:00
|
|
|
lua_pushstring(L, dirname(game_save_path(1, 0)));
|
2010-06-03 16:23:38 +03:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2010-09-13 12:27:39 +03:00
|
|
|
static int luaB_get_gamepath(lua_State *L) {
|
|
|
|
char path[PATH_MAX];
|
2010-09-13 13:29:12 +03:00
|
|
|
char *p = getdir(path, sizeof(path));
|
|
|
|
if (p)
|
|
|
|
unix_path(p);
|
2010-09-13 12:27:39 +03:00
|
|
|
lua_pushstring(L, p);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2010-09-16 10:31:18 +03:00
|
|
|
static int luaB_get_steadpath(lua_State *L) {
|
|
|
|
char stead_path[PATH_MAX];
|
|
|
|
strcpy(stead_path, game_cwd);
|
|
|
|
strcat(stead_path, "/");
|
|
|
|
strcat(stead_path, STEAD_PATH);
|
|
|
|
unix_path(stead_path);
|
|
|
|
lua_pushstring(L, stead_path);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2010-01-20 21:35:33 +02:00
|
|
|
|
2010-01-20 22:23:28 +02:00
|
|
|
extern void mouse_reset(int hl); /* too bad */
|
2011-04-11 12:12:57 +03:00
|
|
|
extern void mouse_restore(void);
|
2010-01-20 21:35:33 +02:00
|
|
|
|
|
|
|
static void instead_timer_do(void *data)
|
|
|
|
{
|
2010-01-21 07:35:53 +02:00
|
|
|
char *p;
|
2010-01-20 21:35:33 +02:00
|
|
|
if (game_paused())
|
2010-01-21 09:37:34 +02:00
|
|
|
goto out;
|
2010-09-16 16:16:43 +03:00
|
|
|
if (instead_function("stead.timer", NULL)) {
|
2010-01-20 22:23:28 +02:00
|
|
|
instead_clear();
|
2010-01-21 09:37:34 +02:00
|
|
|
goto out;
|
2010-01-20 22:23:28 +02:00
|
|
|
}
|
2010-01-21 07:35:53 +02:00
|
|
|
p = instead_retval(0); instead_clear();
|
|
|
|
if (!p)
|
2010-01-21 09:37:34 +02:00
|
|
|
goto out;
|
2010-01-20 22:23:28 +02:00
|
|
|
mouse_reset(0);
|
2011-04-11 12:12:57 +03:00
|
|
|
// fprintf(stderr, "cmd =%s\n", p);
|
2010-01-21 07:35:53 +02:00
|
|
|
game_cmd(p); free(p);
|
2011-04-11 12:12:57 +03:00
|
|
|
mouse_restore();
|
2010-01-23 17:30:48 +02:00
|
|
|
game_cursor(CURSOR_ON);
|
2010-01-21 09:37:34 +02:00
|
|
|
out:
|
2011-04-29 11:56:00 +03:00
|
|
|
instead_timer_nr = 0;
|
2010-01-20 21:35:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static int instead_fn(int interval, void *p)
|
|
|
|
{
|
2011-04-29 11:56:00 +03:00
|
|
|
if (instead_timer_nr)
|
|
|
|
return interval; /* framedrop */
|
|
|
|
instead_timer_nr ++;
|
2010-01-20 21:35:33 +02:00
|
|
|
push_user_event(instead_timer_do, NULL);
|
|
|
|
return interval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int luaB_set_timer(lua_State *L) {
|
|
|
|
const char *delay = luaL_optstring(L, 1, NULL);
|
|
|
|
int d;
|
|
|
|
gfx_del_timer(instead_timer);
|
2011-02-19 15:23:09 +02:00
|
|
|
instead_timer = NULL_TIMER;
|
2010-01-20 21:35:33 +02:00
|
|
|
if (!delay)
|
|
|
|
d = 0;
|
|
|
|
else
|
|
|
|
d = atoi(delay);
|
|
|
|
if (!d)
|
2010-01-21 09:37:34 +02:00
|
|
|
return 0;
|
|
|
|
instead_timer_nr = 0;
|
2010-01-20 21:35:33 +02:00
|
|
|
instead_timer = gfx_add_timer(d, instead_fn, NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-10-30 15:54:41 +03:00
|
|
|
extern int theme_setvar(char *name, char *val);
|
|
|
|
extern char *theme_getvar(const char *name);
|
|
|
|
|
|
|
|
static int luaB_theme_var(lua_State *L) {
|
|
|
|
const char *var = luaL_optstring(L, 1, NULL);
|
|
|
|
const char *val = luaL_optstring(L, 2, NULL);
|
|
|
|
if (var && !val) { /* get */
|
|
|
|
char *p = theme_getvar(var);
|
|
|
|
if (p) {
|
|
|
|
lua_pushstring(L, p);
|
|
|
|
free(p);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (!val || !var)
|
|
|
|
return 0;
|
|
|
|
game_own_theme = 1;
|
|
|
|
if (!opt_owntheme)
|
|
|
|
return 0;
|
|
|
|
if (!theme_setvar((char*)var, (char*)val))
|
|
|
|
game_theme_changed = 2;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-07-25 22:58:31 +03:00
|
|
|
static int luaB_theme_name(lua_State *L) {
|
|
|
|
if (game_own_theme && opt_owntheme)
|
2011-07-26 11:06:15 +03:00
|
|
|
lua_pushstring(L, ".");
|
|
|
|
else
|
|
|
|
lua_pushstring(L, curtheme_dir);
|
2011-07-25 22:58:31 +03:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-03-10 12:40:55 +02:00
|
|
|
extern int dir_iter_factory (lua_State *L);
|
|
|
|
extern int luaopen_lfs (lua_State *L);
|
|
|
|
|
2011-04-11 12:12:57 +03:00
|
|
|
static LIST_HEAD(sprites);
|
|
|
|
|
|
|
|
static LIST_HEAD(fonts);
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
struct list_head list;
|
|
|
|
char *name;
|
|
|
|
fnt_t fnt;
|
|
|
|
} _fnt_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
struct list_head list;
|
|
|
|
char *name;
|
|
|
|
img_t img;
|
|
|
|
} _spr_t;
|
|
|
|
|
|
|
|
static void sprites_free(void)
|
|
|
|
{
|
|
|
|
// fprintf(stderr, "sprites free \n");
|
|
|
|
while (!list_empty(&sprites)) {
|
|
|
|
_spr_t *sp = (_spr_t*)(sprites.next);
|
|
|
|
free(sp->name);
|
|
|
|
cache_forget(gfx_image_cache(), sp->img);
|
|
|
|
list_del(&sp->list);
|
|
|
|
free(sp);
|
|
|
|
}
|
|
|
|
while (!list_empty(&fonts)) {
|
|
|
|
_fnt_t *fn = (_fnt_t*)(fonts.next);
|
|
|
|
fnt_free(fn->fnt);
|
|
|
|
free(fn->name);
|
|
|
|
list_del(&fn->list);
|
|
|
|
free(fn);
|
|
|
|
}
|
|
|
|
game_pict_modify(NULL);
|
|
|
|
cache_shrink(gfx_image_cache());
|
|
|
|
}
|
|
|
|
|
|
|
|
static _spr_t *sprite_lookup(const char *name)
|
|
|
|
{
|
|
|
|
struct list_head *pos;
|
|
|
|
_spr_t *sp;
|
|
|
|
list_for_each(pos, &sprites) {
|
|
|
|
sp = (_spr_t*)pos;
|
|
|
|
if (!strcmp(name, sp->name)) {
|
|
|
|
list_move(&sp->list, &sprites); // move it on head
|
|
|
|
return sp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static _fnt_t *font_lookup(const char *name)
|
|
|
|
{
|
|
|
|
struct list_head *pos;
|
|
|
|
_fnt_t *fn;
|
|
|
|
list_for_each(pos, &fonts) {
|
|
|
|
fn = (_fnt_t*)pos;
|
|
|
|
if (!strcmp(name, fn->name)) {
|
|
|
|
list_move(&fn->list, &fonts); // move it on head
|
|
|
|
return fn;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static _spr_t *sprite_new(const char *name, img_t img)
|
|
|
|
{
|
|
|
|
_spr_t *sp;
|
|
|
|
sp = malloc(sizeof(_spr_t));
|
|
|
|
if (!sp)
|
|
|
|
return NULL;
|
|
|
|
INIT_LIST_HEAD(&sp->list);
|
|
|
|
sp->name = strdup(name);
|
|
|
|
if (!sp->name) {
|
|
|
|
free(sp);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
sp->img = img;
|
|
|
|
if (cache_add(gfx_image_cache(), name, img)) {
|
|
|
|
free(sp->name);
|
|
|
|
free(sp);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
// fprintf(stderr, "added: %s\n", name);
|
|
|
|
list_add(&sp->list, &sprites);
|
|
|
|
return sp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static _fnt_t *font_new(const char *name, fnt_t fnt)
|
|
|
|
{
|
|
|
|
_fnt_t *fn;
|
|
|
|
fn = malloc(sizeof(_fnt_t));
|
|
|
|
if (!fn)
|
|
|
|
return NULL;
|
|
|
|
INIT_LIST_HEAD(&fn->list);
|
|
|
|
fn->name = strdup(name);
|
|
|
|
if (!fn->name) {
|
|
|
|
free(fn);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
fn->fnt = fnt;
|
|
|
|
list_add(&fn->list, &fonts);
|
|
|
|
return fn;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sprite_name(const char *name, char *sname, int size)
|
|
|
|
{
|
|
|
|
unsigned long h = 0;
|
|
|
|
if (!sname || !size)
|
|
|
|
return;
|
|
|
|
h = hash_string(name);
|
|
|
|
do { /* new uniq name */
|
|
|
|
snprintf(sname, size, "spr:%lx", h);
|
|
|
|
h ++;
|
|
|
|
} while (sprite_lookup(sname) || cache_lookup(gfx_image_cache(), sname));
|
|
|
|
sname[size - 1] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void font_name(const char *name, char *sname, int size)
|
|
|
|
{
|
|
|
|
unsigned long h = 0;
|
|
|
|
if (!sname || !size)
|
|
|
|
return;
|
|
|
|
h = hash_string(name);
|
|
|
|
do { /* new uniq name */
|
|
|
|
snprintf(sname, size, "fnt:%lx", h);
|
|
|
|
h ++;
|
|
|
|
} while (font_lookup(sname));
|
|
|
|
sname[size - 1] = 0;
|
|
|
|
}
|
|
|
|
|
2011-04-12 12:08:08 +03:00
|
|
|
static int _free_sprite(const char *key);
|
|
|
|
|
2011-04-11 12:12:57 +03:00
|
|
|
static int luaB_free_sprites(lua_State *L) {
|
|
|
|
sprites_free();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int luaB_load_sprite(lua_State *L) {
|
|
|
|
img_t img = NULL;
|
|
|
|
_spr_t *sp;
|
|
|
|
const char *key;
|
|
|
|
char sname[sizeof(unsigned long) * 2 + 16];
|
|
|
|
|
|
|
|
const char *fname = luaL_optstring(L, 1, NULL);
|
|
|
|
const char *desc = luaL_optstring(L, 2, NULL);
|
|
|
|
|
|
|
|
if (!fname)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
img = gfx_load_image((char*)fname);
|
2011-04-12 10:02:57 +03:00
|
|
|
if (img)
|
|
|
|
img = gfx_display_alpha(img); /*speed up */
|
2011-04-11 12:12:57 +03:00
|
|
|
if (img)
|
|
|
|
theme_img_scale(&img);
|
|
|
|
|
|
|
|
if (!img)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
if (!desc || sprite_lookup(desc)) {
|
|
|
|
key = sname;
|
|
|
|
sprite_name(fname, sname, sizeof(sname));
|
|
|
|
} else
|
|
|
|
key = desc;
|
|
|
|
sp = sprite_new(key, img);
|
|
|
|
if (!sp)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
lua_pushstring(L, key);
|
|
|
|
return 1;
|
|
|
|
err:
|
|
|
|
gfx_free_image(img);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int luaB_load_font(lua_State *L) {
|
|
|
|
fnt_t fnt = NULL;
|
|
|
|
_fnt_t *fn;
|
|
|
|
const char *key;
|
|
|
|
char sname[sizeof(unsigned long) * 2 + 16];
|
|
|
|
struct game_theme *t = &game_theme;
|
|
|
|
|
|
|
|
const char *fname = luaL_optstring(L, 1, NULL);
|
|
|
|
int sz = luaL_optnumber(L, 2, t->font_size) * game_theme.scale;
|
|
|
|
const char *desc = luaL_optstring(L, 3, NULL);
|
|
|
|
if (!fname)
|
|
|
|
return 0;
|
|
|
|
|
2011-04-17 17:06:01 +03:00
|
|
|
fnt = fnt_load((char*)fname, sz);
|
2011-04-11 12:12:57 +03:00
|
|
|
|
|
|
|
if (!fnt)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!desc || font_lookup(desc)) {
|
|
|
|
key = sname;
|
|
|
|
font_name(fname, sname, sizeof(sname));
|
|
|
|
} else
|
|
|
|
key = desc;
|
|
|
|
|
|
|
|
fn = font_new(key, fnt);
|
|
|
|
if (!fn)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
lua_pushstring(L, key);
|
|
|
|
return 1;
|
|
|
|
err:
|
|
|
|
fnt_free(fnt);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int luaB_text_size(lua_State *L) {
|
|
|
|
_fnt_t *fn;
|
|
|
|
int w = 0, h = 0;
|
|
|
|
|
|
|
|
const char *font = luaL_optstring(L, 1, NULL);
|
|
|
|
const char *text = luaL_optstring(L, 2, NULL);
|
|
|
|
|
|
|
|
if (!font)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
fn = font_lookup(font);
|
|
|
|
|
|
|
|
if (!fn)
|
|
|
|
return 0;
|
|
|
|
if (!text) {
|
|
|
|
w = 0;
|
2011-04-18 11:43:28 +03:00
|
|
|
h = ceil((float)fnt_height(fn->fnt) / game_theme.scale);
|
|
|
|
} else {
|
2011-04-11 12:12:57 +03:00
|
|
|
txt_size(fn->fnt, text, &w, &h);
|
2011-04-18 11:43:28 +03:00
|
|
|
w = ceil((float)w / game_theme.scale);
|
|
|
|
h = ceil((float)h / game_theme.scale);
|
|
|
|
}
|
2011-04-11 12:12:57 +03:00
|
|
|
lua_pushnumber(L, w);
|
|
|
|
lua_pushnumber(L, h);
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
2011-04-14 12:32:37 +03:00
|
|
|
static int luaB_font_size_scaled(lua_State *L) {
|
|
|
|
int sz = luaL_optnumber(L, 1, game_theme.font_size);
|
|
|
|
lua_pushnumber(L, FONT_SZ(sz));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-04-11 12:12:57 +03:00
|
|
|
static int luaB_text_sprite(lua_State *L) {
|
|
|
|
img_t img = NULL;
|
|
|
|
_spr_t *sp;
|
|
|
|
_fnt_t *fn;
|
|
|
|
const char *key;
|
|
|
|
char sname[sizeof(unsigned long) * 2 + 16];
|
|
|
|
|
|
|
|
const char *font = luaL_optstring(L, 1, NULL);
|
|
|
|
const char *text = luaL_optstring(L, 2, NULL);
|
2011-04-12 12:08:08 +03:00
|
|
|
char txtkey[32];
|
2011-04-11 12:12:57 +03:00
|
|
|
const char *color = luaL_optstring(L, 3, NULL);
|
|
|
|
int style = luaL_optnumber(L, 4, 0);
|
2011-06-18 10:20:10 +03:00
|
|
|
const char *desc = luaL_optstring(L, 5, NULL);
|
|
|
|
|
2011-04-11 12:12:57 +03:00
|
|
|
color_t col = { .r = game_theme.fgcol.r, .g = game_theme.fgcol.g, .b = game_theme.fgcol.b };
|
|
|
|
|
|
|
|
if (!font)
|
|
|
|
return 0;
|
|
|
|
if (color)
|
|
|
|
gfx_parse_color (color, &col);
|
|
|
|
if (!text)
|
|
|
|
text = "";
|
|
|
|
|
|
|
|
fn = font_lookup(font);
|
|
|
|
|
|
|
|
if (!fn)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
fnt_style(fn->fnt, style);
|
|
|
|
|
|
|
|
img = fnt_render(fn->fnt, text, col);
|
2011-04-12 10:02:57 +03:00
|
|
|
if (img)
|
|
|
|
img = gfx_display_alpha(img); /*speed up */
|
|
|
|
|
2011-04-11 12:12:57 +03:00
|
|
|
if (!img)
|
|
|
|
return 0;
|
|
|
|
|
2011-06-18 10:20:10 +03:00
|
|
|
if (!desc || sprite_lookup(desc)) {
|
|
|
|
key = sname;
|
|
|
|
strncpy(txtkey, text, sizeof(txtkey));
|
|
|
|
txtkey[sizeof(txtkey) - 1] = 0;
|
|
|
|
sprite_name(txtkey, sname, sizeof(sname));
|
|
|
|
} else
|
|
|
|
key = desc;
|
|
|
|
|
2011-04-11 12:12:57 +03:00
|
|
|
sp = sprite_new(key, img);
|
|
|
|
|
|
|
|
if (!sp)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
lua_pushstring(L, key);
|
|
|
|
return 1;
|
|
|
|
err:
|
|
|
|
gfx_free_image(img);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-04-12 07:36:58 +03:00
|
|
|
static img_t grab_sprite(const char *dst, int *xoff, int *yoff)
|
|
|
|
{
|
|
|
|
img_t d;
|
2011-04-15 10:37:11 +03:00
|
|
|
if (DIRECT_MODE && !strcmp(dst, "screen")) {
|
2011-04-12 07:36:58 +03:00
|
|
|
d = gfx_screen(NULL);
|
|
|
|
*xoff = game_theme.xoff;
|
|
|
|
*yoff = game_theme.yoff;
|
|
|
|
} else {
|
|
|
|
*xoff = 0;
|
|
|
|
*yoff = 0;
|
|
|
|
d = cache_lookup(gfx_image_cache(), dst);
|
|
|
|
}
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-04-11 12:12:57 +03:00
|
|
|
static int luaB_sprite_size(lua_State *L) {
|
|
|
|
img_t s = NULL;
|
|
|
|
float v;
|
|
|
|
int w, h;
|
2011-04-12 07:36:58 +03:00
|
|
|
int xoff, yoff;
|
2011-04-11 12:12:57 +03:00
|
|
|
const char *src = luaL_optstring(L, 1, NULL);
|
|
|
|
if (!src)
|
|
|
|
return 0;
|
2011-04-12 07:36:58 +03:00
|
|
|
s = grab_sprite(src, &xoff, &yoff);
|
2011-04-11 12:12:57 +03:00
|
|
|
if (!s)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
v = game_theme.scale;
|
2011-04-12 07:36:58 +03:00
|
|
|
|
2011-04-18 11:43:28 +03:00
|
|
|
w = ceil ((float)(gfx_img_w(s) - xoff * 2) / v);
|
|
|
|
h = ceil ((float)(gfx_img_h(s) - yoff * 2) / v);
|
2011-04-12 07:36:58 +03:00
|
|
|
|
2011-04-11 12:12:57 +03:00
|
|
|
lua_pushnumber(L, w);
|
|
|
|
lua_pushnumber(L, h);
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int luaB_draw_sprite(lua_State *L) {
|
|
|
|
img_t s, d;
|
|
|
|
img_t img2 = NULL;
|
|
|
|
float v;
|
|
|
|
const char *src = luaL_optstring(L, 1, NULL);
|
|
|
|
int x = luaL_optnumber(L, 2, 0);
|
|
|
|
int y = luaL_optnumber(L, 3, 0);
|
2011-04-23 12:37:59 +03:00
|
|
|
int w = luaL_optnumber(L, 4, -1);
|
|
|
|
int h = luaL_optnumber(L, 5, -1);
|
2011-04-11 12:12:57 +03:00
|
|
|
const char *dst = luaL_optstring(L, 6, NULL);
|
|
|
|
int xx = luaL_optnumber(L, 7, 0);
|
|
|
|
int yy = luaL_optnumber(L, 8, 0);
|
|
|
|
int alpha = luaL_optnumber(L, 9, 255);
|
|
|
|
int xoff = 0, yoff = 0;
|
|
|
|
int xoff0 = 0, yoff0 = 0;
|
|
|
|
if (!src || !dst)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
s = grab_sprite(src, &xoff0, &yoff0);
|
|
|
|
|
|
|
|
d = grab_sprite(dst, &xoff, &yoff);
|
|
|
|
|
|
|
|
if (!s || !d)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
v = game_theme.scale;
|
|
|
|
|
|
|
|
if (v != 1.0f) {
|
|
|
|
x *= v;
|
|
|
|
y *= v;
|
2011-04-23 12:37:59 +03:00
|
|
|
if (w != -1)
|
|
|
|
w = ceil(w * v);
|
|
|
|
if (h != -1)
|
|
|
|
h = ceil(h * v);
|
2011-04-11 12:12:57 +03:00
|
|
|
xx *= v;
|
|
|
|
yy *= v;
|
|
|
|
}
|
|
|
|
|
2011-04-23 12:37:59 +03:00
|
|
|
if (w == -1)
|
2011-04-11 12:12:57 +03:00
|
|
|
w = gfx_img_w(s) - 2 * xoff0;
|
2011-04-23 12:37:59 +03:00
|
|
|
if (h == -1)
|
2011-04-11 12:12:57 +03:00
|
|
|
h = gfx_img_h(s) - 2 * yoff0;
|
|
|
|
|
|
|
|
game_pict_modify(d);
|
|
|
|
|
|
|
|
if (alpha != 255) {
|
|
|
|
img2 = gfx_alpha_img(s, alpha);
|
|
|
|
if (img2)
|
|
|
|
s = img2;
|
|
|
|
}
|
2011-04-23 11:50:30 +03:00
|
|
|
gfx_clip(game_theme.xoff, game_theme.yoff, game_theme.w - 2*game_theme.xoff, game_theme.h - 2*game_theme.yoff);
|
2011-04-11 12:12:57 +03:00
|
|
|
gfx_draw_from(s, x + xoff0, y + yoff0, w, h, d, xx + xoff, yy + yoff);
|
2011-04-14 16:49:15 +03:00
|
|
|
gfx_noclip();
|
2011-04-11 12:12:57 +03:00
|
|
|
gfx_free_image(img2);
|
|
|
|
lua_pushboolean(L, 1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-04-13 20:42:11 +03:00
|
|
|
static int luaB_copy_sprite(lua_State *L) {
|
|
|
|
img_t s, d;
|
|
|
|
img_t img2 = NULL;
|
|
|
|
float v;
|
|
|
|
const char *src = luaL_optstring(L, 1, NULL);
|
|
|
|
int x = luaL_optnumber(L, 2, 0);
|
|
|
|
int y = luaL_optnumber(L, 3, 0);
|
2011-04-23 12:37:59 +03:00
|
|
|
int w = luaL_optnumber(L, 4, -1);
|
|
|
|
int h = luaL_optnumber(L, 5, -1);
|
2011-04-13 20:42:11 +03:00
|
|
|
const char *dst = luaL_optstring(L, 6, NULL);
|
|
|
|
int xx = luaL_optnumber(L, 7, 0);
|
|
|
|
int yy = luaL_optnumber(L, 8, 0);
|
|
|
|
int xoff = 0, yoff = 0;
|
|
|
|
int xoff0 = 0, yoff0 = 0;
|
|
|
|
if (!src || !dst)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
s = grab_sprite(src, &xoff0, &yoff0);
|
|
|
|
|
|
|
|
d = grab_sprite(dst, &xoff, &yoff);
|
|
|
|
|
|
|
|
if (!s || !d)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
v = game_theme.scale;
|
|
|
|
|
|
|
|
if (v != 1.0f) {
|
|
|
|
x *= v;
|
|
|
|
y *= v;
|
2011-04-23 12:37:59 +03:00
|
|
|
if (w != -1)
|
|
|
|
w = ceil(w * v);
|
|
|
|
if (h != -1)
|
|
|
|
h = ceil(h * v);
|
2011-04-13 20:42:11 +03:00
|
|
|
xx *= v;
|
|
|
|
yy *= v;
|
|
|
|
}
|
|
|
|
|
2011-04-23 12:37:59 +03:00
|
|
|
if (w == -1)
|
2011-04-13 20:42:11 +03:00
|
|
|
w = gfx_img_w(s) - 2 * xoff0;
|
2011-04-23 12:37:59 +03:00
|
|
|
if (h == -1)
|
2011-04-13 20:42:11 +03:00
|
|
|
h = gfx_img_h(s) - 2 * yoff0;
|
|
|
|
|
|
|
|
game_pict_modify(d);
|
|
|
|
|
2011-04-23 11:50:30 +03:00
|
|
|
gfx_clip(game_theme.xoff, game_theme.yoff, game_theme.w - game_theme.xoff * 2, game_theme.h - game_theme.yoff * 2);
|
2011-04-13 20:42:11 +03:00
|
|
|
gfx_copy_from(s, x + xoff0, y + yoff0, w, h, d, xx + xoff, yy + yoff);
|
2011-04-14 16:49:15 +03:00
|
|
|
gfx_noclip();
|
2011-04-13 20:42:11 +03:00
|
|
|
gfx_free_image(img2);
|
|
|
|
lua_pushboolean(L, 1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-04-11 12:12:57 +03:00
|
|
|
|
|
|
|
static int luaB_alpha_sprite(lua_State *L) {
|
|
|
|
_spr_t *sp;
|
|
|
|
img_t s;
|
|
|
|
img_t img2 = NULL;
|
|
|
|
const char *key;
|
|
|
|
char sname[sizeof(unsigned long) * 2 + 16];
|
|
|
|
|
|
|
|
const char *src = luaL_optstring(L, 1, NULL);
|
|
|
|
int alpha = luaL_optnumber(L, 2, 255);
|
|
|
|
const char *desc = luaL_optstring(L, 3, NULL);
|
|
|
|
|
|
|
|
if (!src)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
s = cache_lookup(gfx_image_cache(), src);
|
|
|
|
if (!s)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
img2 = gfx_alpha_img(s, alpha);
|
|
|
|
if (!img2)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!desc || sprite_lookup(desc)) {
|
|
|
|
key = sname;
|
|
|
|
sprite_name(src, sname, sizeof(sname));
|
|
|
|
} else
|
|
|
|
key = desc;
|
|
|
|
|
|
|
|
sp = sprite_new(key, img2);
|
|
|
|
if (!sp)
|
|
|
|
goto err;
|
|
|
|
lua_pushstring(L, sname);
|
|
|
|
return 1;
|
|
|
|
err:
|
|
|
|
gfx_free_image(img2);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-04-12 12:08:08 +03:00
|
|
|
static int luaB_dup_sprite(lua_State *L) {
|
|
|
|
_spr_t *sp;
|
|
|
|
img_t s;
|
|
|
|
img_t img2 = NULL;
|
|
|
|
const char *key;
|
|
|
|
char sname[sizeof(unsigned long) * 2 + 16];
|
|
|
|
const char *src = luaL_optstring(L, 1, NULL);
|
|
|
|
const char *desc = luaL_optstring(L, 2, NULL);
|
|
|
|
|
|
|
|
if (!src)
|
|
|
|
return 0;
|
|
|
|
|
2011-04-12 15:42:21 +03:00
|
|
|
s = cache_lookup(gfx_image_cache(), src);
|
2011-04-12 12:08:08 +03:00
|
|
|
if (!s)
|
|
|
|
return 0;
|
2011-04-12 15:42:21 +03:00
|
|
|
|
|
|
|
img2 = gfx_alpha_img(s, 255);
|
|
|
|
|
2011-04-12 12:08:08 +03:00
|
|
|
if (!img2)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!desc || sprite_lookup(desc)) {
|
|
|
|
key = sname;
|
|
|
|
sprite_name(src, sname, sizeof(sname));
|
|
|
|
} else
|
|
|
|
key = desc;
|
|
|
|
|
|
|
|
sp = sprite_new(key, img2);
|
|
|
|
if (!sp)
|
|
|
|
goto err;
|
|
|
|
lua_pushstring(L, sname);
|
|
|
|
return 1;
|
|
|
|
err:
|
|
|
|
gfx_free_image(img2);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-04-12 07:50:03 +03:00
|
|
|
static int luaB_scale_sprite(lua_State *L) {
|
|
|
|
_spr_t *sp;
|
|
|
|
img_t s;
|
|
|
|
img_t img2 = NULL;
|
|
|
|
const char *key;
|
|
|
|
char sname[sizeof(unsigned long) * 2 + 16];
|
|
|
|
|
|
|
|
const char *src = luaL_optstring(L, 1, NULL);
|
2011-04-12 13:44:17 +03:00
|
|
|
float xs = luaL_optnumber(L, 2, 0);
|
|
|
|
float ys = luaL_optnumber(L, 3, 0);
|
2011-04-12 07:50:03 +03:00
|
|
|
const char *desc = luaL_optstring(L, 4, NULL);
|
|
|
|
|
|
|
|
if (!src)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
s = cache_lookup(gfx_image_cache(), src);
|
|
|
|
if (!s)
|
|
|
|
return 0;
|
2011-04-12 13:44:17 +03:00
|
|
|
|
|
|
|
if (xs == 0)
|
|
|
|
xs = 1.0f;
|
|
|
|
|
|
|
|
if (ys == 0)
|
|
|
|
ys = xs;
|
|
|
|
|
2011-04-12 07:50:03 +03:00
|
|
|
img2 = gfx_scale(s, xs, ys);
|
2011-04-12 10:42:01 +03:00
|
|
|
|
2011-04-12 07:50:03 +03:00
|
|
|
if (!img2)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!desc || sprite_lookup(desc)) {
|
|
|
|
key = sname;
|
|
|
|
sprite_name(src, sname, sizeof(sname));
|
|
|
|
} else
|
|
|
|
key = desc;
|
|
|
|
|
|
|
|
sp = sprite_new(key, img2);
|
|
|
|
if (!sp)
|
|
|
|
goto err;
|
|
|
|
lua_pushstring(L, sname);
|
|
|
|
return 1;
|
|
|
|
err:
|
|
|
|
gfx_free_image(img2);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-04-11 12:12:57 +03:00
|
|
|
|
2011-04-12 10:42:01 +03:00
|
|
|
static int luaB_rotate_sprite(lua_State *L) {
|
|
|
|
_spr_t *sp;
|
|
|
|
img_t s;
|
|
|
|
img_t img2 = NULL;
|
|
|
|
const char *key;
|
|
|
|
char sname[sizeof(unsigned long) * 2 + 16];
|
|
|
|
|
|
|
|
const char *src = luaL_optstring(L, 1, NULL);
|
|
|
|
float angle = luaL_optnumber(L, 2, 1.0f);
|
|
|
|
const char *desc = luaL_optstring(L, 3, NULL);
|
|
|
|
|
|
|
|
if (!src)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
s = cache_lookup(gfx_image_cache(), src);
|
|
|
|
if (!s)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
img2 = gfx_rotate(s, angle);
|
|
|
|
|
|
|
|
if (!img2)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!desc || sprite_lookup(desc)) {
|
|
|
|
key = sname;
|
|
|
|
sprite_name(src, sname, sizeof(sname));
|
|
|
|
} else
|
|
|
|
key = desc;
|
|
|
|
|
|
|
|
sp = sprite_new(key, img2);
|
|
|
|
if (!sp)
|
|
|
|
goto err;
|
|
|
|
lua_pushstring(L, sname);
|
|
|
|
return 1;
|
|
|
|
err:
|
|
|
|
gfx_free_image(img2);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-04-11 12:12:57 +03:00
|
|
|
static int luaB_fill_sprite(lua_State *L) {
|
|
|
|
img_t d;
|
|
|
|
float v;
|
|
|
|
const char *dst = luaL_optstring(L, 1, NULL);
|
|
|
|
int x = luaL_optnumber(L, 2, 0);
|
|
|
|
int y = luaL_optnumber(L, 3, 0);
|
2011-04-23 12:37:59 +03:00
|
|
|
int w = luaL_optnumber(L, 4, -1);
|
|
|
|
int h = luaL_optnumber(L, 5, -1);
|
2011-04-23 15:48:16 +03:00
|
|
|
const char *color = luaL_optstring(L, 6, NULL);
|
2011-04-11 12:12:57 +03:00
|
|
|
int xoff = 0, yoff = 0;
|
|
|
|
color_t col = { .r = game_theme.bgcol.r, .g = game_theme.bgcol.g, .b = game_theme.bgcol.b };
|
|
|
|
if (!dst)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
d = grab_sprite(dst, &xoff, &yoff);
|
|
|
|
|
|
|
|
if (color)
|
|
|
|
gfx_parse_color(color, &col);
|
|
|
|
|
|
|
|
if (!d)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
v = game_theme.scale;
|
|
|
|
|
|
|
|
if (v != 1.0f) {
|
|
|
|
x *= v;
|
|
|
|
y *= v;
|
2011-04-23 12:37:59 +03:00
|
|
|
if (w != -1)
|
|
|
|
w = ceil(w * v);
|
|
|
|
if (h != -1)
|
|
|
|
h = ceil(h * v);
|
2011-04-11 12:12:57 +03:00
|
|
|
}
|
2011-04-23 12:37:59 +03:00
|
|
|
if (w == -1)
|
2011-04-11 12:12:57 +03:00
|
|
|
w = gfx_img_w(d) - 2 * xoff;
|
2011-04-23 12:37:59 +03:00
|
|
|
if (h == -1)
|
2011-04-11 12:12:57 +03:00
|
|
|
h = gfx_img_h(d) - 2 * yoff;
|
|
|
|
game_pict_modify(d);
|
2011-04-23 12:51:12 +03:00
|
|
|
gfx_clip(game_theme.xoff, game_theme.yoff, game_theme.w - 2*game_theme.xoff, game_theme.h - 2*game_theme.yoff);
|
2011-04-11 12:12:57 +03:00
|
|
|
gfx_img_fill(d, x + xoff, y + yoff, w, h, col);
|
2011-04-23 12:51:12 +03:00
|
|
|
gfx_noclip();
|
2011-04-11 12:12:57 +03:00
|
|
|
lua_pushboolean(L, 1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-04-23 15:48:16 +03:00
|
|
|
static int luaB_pixel_sprite(lua_State *L) {
|
|
|
|
img_t d;
|
|
|
|
float v;
|
2011-04-28 14:15:58 +03:00
|
|
|
int rc, w, h;
|
2011-04-23 15:48:16 +03:00
|
|
|
color_t col = { .r = game_theme.bgcol.r, .g = game_theme.bgcol.g, .b = game_theme.bgcol.b, .a = 255 };
|
|
|
|
const char *dst = luaL_optstring(L, 1, NULL);
|
|
|
|
int x = luaL_optnumber(L, 2, 0);
|
|
|
|
int y = luaL_optnumber(L, 3, 0);
|
|
|
|
const char *color = luaL_optstring(L, 4, NULL);
|
|
|
|
int alpha = luaL_optnumber(L, 5, 255);
|
|
|
|
int xoff = 0, yoff = 0;
|
|
|
|
|
|
|
|
if (!dst)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
d = grab_sprite(dst, &xoff, &yoff);
|
|
|
|
|
|
|
|
if (color)
|
|
|
|
gfx_parse_color(color, &col);
|
|
|
|
|
|
|
|
if (!d)
|
|
|
|
return 0;
|
|
|
|
|
2011-04-28 14:15:58 +03:00
|
|
|
w = gfx_img_w(d) - 2 * xoff;
|
|
|
|
h = gfx_img_h(d) - 2 * yoff;
|
|
|
|
|
2011-04-23 15:48:16 +03:00
|
|
|
v = game_theme.scale;
|
|
|
|
|
|
|
|
if (v != 1.0f) {
|
|
|
|
x *= v;
|
|
|
|
y *= v;
|
|
|
|
}
|
2011-04-28 14:15:58 +03:00
|
|
|
|
2011-04-23 15:48:16 +03:00
|
|
|
if (color) {
|
2011-04-28 14:15:58 +03:00
|
|
|
if (x < 0 || y < 0 || x >= w || y >= h)
|
|
|
|
return 0;
|
2011-04-23 15:48:16 +03:00
|
|
|
game_pict_modify(d);
|
|
|
|
col.a = alpha;
|
|
|
|
rc = gfx_set_pixel(d, x + xoff, y + yoff, col);
|
|
|
|
} else {
|
|
|
|
rc = gfx_get_pixel(d, x + xoff, y + yoff, &col);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rc)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
lua_pushnumber(L, col.r);
|
|
|
|
lua_pushnumber(L, col.g);
|
|
|
|
lua_pushnumber(L, col.b);
|
|
|
|
lua_pushnumber(L, col.a);
|
|
|
|
return 4;
|
|
|
|
}
|
|
|
|
|
2011-04-12 12:08:08 +03:00
|
|
|
static int _free_sprite(const char *key)
|
|
|
|
{
|
2011-04-11 12:12:57 +03:00
|
|
|
_spr_t *sp;
|
|
|
|
if (!key)
|
2011-04-12 12:08:08 +03:00
|
|
|
return -1;
|
2011-04-11 12:12:57 +03:00
|
|
|
sp = sprite_lookup(key);
|
2011-04-12 12:08:08 +03:00
|
|
|
|
2011-04-11 12:12:57 +03:00
|
|
|
if (!sp)
|
2011-04-12 12:08:08 +03:00
|
|
|
return -1;
|
|
|
|
|
2011-04-11 12:12:57 +03:00
|
|
|
cache_forget(gfx_image_cache(), sp->img);
|
|
|
|
cache_shrink(gfx_image_cache());
|
|
|
|
|
|
|
|
list_del(&sp->list);
|
|
|
|
free(sp->name); free(sp);
|
2011-04-12 12:08:08 +03:00
|
|
|
return 0;
|
|
|
|
}
|
2011-04-11 12:12:57 +03:00
|
|
|
|
2011-04-12 12:08:08 +03:00
|
|
|
static int luaB_free_sprite(lua_State *L) {
|
|
|
|
const char *key = luaL_optstring(L, 1, NULL);
|
|
|
|
if (_free_sprite(key))
|
|
|
|
return 0;
|
2011-04-11 12:12:57 +03:00
|
|
|
lua_pushboolean(L, 1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-04-12 14:34:50 +03:00
|
|
|
static int luaB_show_menu(lua_State *L) {
|
|
|
|
menu_toggle();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-04-11 12:12:57 +03:00
|
|
|
static int luaB_free_font(lua_State *L) {
|
|
|
|
const char *key = luaL_optstring(L, 1, NULL);
|
|
|
|
_fnt_t *fn;
|
|
|
|
if (!key)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
fn = font_lookup(key);
|
|
|
|
if (!fn)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
list_del(&fn->list);
|
|
|
|
free(fn->name); free(fn);
|
|
|
|
lua_pushboolean(L, 1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-04-15 10:23:46 +03:00
|
|
|
static int luaB_load_sound(lua_State *L) {
|
|
|
|
int rc;
|
|
|
|
const char *fname = luaL_optstring(L, 1, NULL);
|
|
|
|
if (!fname)
|
|
|
|
return 0;
|
|
|
|
rc = sound_load(fname);
|
|
|
|
if (rc)
|
|
|
|
return 0;
|
|
|
|
lua_pushstring(L, fname);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-04-15 10:37:11 +03:00
|
|
|
|
2011-04-15 10:23:46 +03:00
|
|
|
static int luaB_free_sound(lua_State *L) {
|
|
|
|
const char *fname = luaL_optstring(L, 1, NULL);
|
|
|
|
if (!fname)
|
|
|
|
return 0;
|
|
|
|
sound_unload(fname);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int luaB_free_sounds(lua_State *L) {
|
|
|
|
sounds_free();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-04-15 11:12:06 +03:00
|
|
|
static int luaB_panning_sound(lua_State *L) {
|
|
|
|
int chan = luaL_optnumber(L, 1, -1);
|
|
|
|
int left = luaL_optnumber(L, 2, 255);
|
|
|
|
int right = luaL_optnumber(L, 3, 255);
|
|
|
|
snd_panning(chan, left, right);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int luaB_volume_sound(lua_State *L) {
|
|
|
|
int vol = luaL_optnumber(L, 1, -1);
|
2011-04-15 12:58:17 +03:00
|
|
|
vol = snd_volume_mus(vol);
|
2011-04-15 11:12:06 +03:00
|
|
|
lua_pushnumber(L, vol);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-04-15 10:23:46 +03:00
|
|
|
static int luaB_channel_sound(lua_State *L) {
|
|
|
|
const char *s;
|
|
|
|
int ch = luaL_optnumber(L, 1, 0);
|
|
|
|
ch = ch % SND_CHANNELS;
|
|
|
|
s = sound_channel(ch);
|
|
|
|
if (s) {
|
|
|
|
lua_pushstring(L, s);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-04-15 10:37:11 +03:00
|
|
|
static int luaB_mouse_pos(lua_State *L) {
|
2011-04-15 15:18:16 +03:00
|
|
|
int x = luaL_optnumber(L, 1, -1);
|
|
|
|
int y = luaL_optnumber(L, 2, -1);
|
2011-04-15 10:37:11 +03:00
|
|
|
float v = game_theme.scale;
|
2011-04-15 15:18:16 +03:00
|
|
|
if (x != -1 && y != -1) {
|
2011-04-15 15:39:13 +03:00
|
|
|
x *= v;
|
|
|
|
y *= v;
|
2011-04-20 10:50:19 +03:00
|
|
|
gfx_warp_cursor(x + game_theme.xoff, y + game_theme.yoff);
|
2011-04-15 15:18:16 +03:00
|
|
|
x = -1;
|
|
|
|
y = -1;
|
|
|
|
}
|
2011-04-15 10:37:11 +03:00
|
|
|
gfx_cursor(&x, &y);
|
|
|
|
x = (x - game_theme.xoff) / v;
|
|
|
|
y = (y - game_theme.yoff) / v;
|
|
|
|
lua_pushnumber(L, x);
|
|
|
|
lua_pushnumber(L, y);
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
2011-04-26 17:16:12 +03:00
|
|
|
static int luaB_get_ticks(lua_State *L) {
|
|
|
|
lua_pushnumber(L, gfx_ticks());
|
|
|
|
return 1;
|
|
|
|
}
|
2011-04-15 10:37:11 +03:00
|
|
|
|
2011-04-28 22:29:21 +03:00
|
|
|
static int luaB_bit_and(lua_State *L) {
|
|
|
|
unsigned int a = luaL_optnumber(L, 1, 0);
|
|
|
|
unsigned int b = luaL_optnumber(L, 2, 0);
|
2011-04-28 22:45:59 +03:00
|
|
|
unsigned int r = a & b;
|
|
|
|
lua_pushnumber(L, r);
|
2011-04-28 22:29:21 +03:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int luaB_bit_or(lua_State *L) {
|
|
|
|
unsigned int a = luaL_optnumber(L, 1, 0);
|
|
|
|
unsigned int b = luaL_optnumber(L, 2, 0);
|
2011-04-28 22:45:59 +03:00
|
|
|
unsigned int r = a | b;
|
|
|
|
lua_pushnumber(L, r);
|
2011-04-28 22:29:21 +03:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int luaB_bit_xor(lua_State *L) {
|
|
|
|
unsigned int a = luaL_optnumber(L, 1, 0);
|
|
|
|
unsigned int b = luaL_optnumber(L, 2, 0);
|
2011-04-28 22:45:59 +03:00
|
|
|
unsigned int r = a ^ b;
|
|
|
|
lua_pushnumber(L, r);
|
2011-04-28 22:29:21 +03:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int luaB_bit_shl(lua_State *L) {
|
|
|
|
unsigned int a = luaL_optnumber(L, 1, 0);
|
|
|
|
unsigned int b = luaL_optnumber(L, 2, 0);
|
2011-04-28 22:45:59 +03:00
|
|
|
unsigned int r = a << b;
|
|
|
|
lua_pushnumber(L, r);
|
2011-04-28 22:29:21 +03:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int luaB_bit_shr(lua_State *L) {
|
|
|
|
unsigned int a = luaL_optnumber(L, 1, 0);
|
|
|
|
unsigned int b = luaL_optnumber(L, 2, 0);
|
2011-04-28 22:45:59 +03:00
|
|
|
unsigned int r = a >> b;
|
|
|
|
lua_pushnumber(L, r);
|
2011-04-28 22:29:21 +03:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int luaB_bit_not(lua_State *L) {
|
|
|
|
unsigned int a = luaL_optnumber(L, 1, 0);
|
2011-04-28 22:45:59 +03:00
|
|
|
unsigned int r = ~a;
|
|
|
|
lua_pushnumber(L, r);
|
2011-04-28 22:29:21 +03:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-04-28 22:37:57 +03:00
|
|
|
static int luaB_bit_div(lua_State *L) {
|
|
|
|
unsigned int a = luaL_optnumber(L, 1, 0);
|
|
|
|
unsigned int b = luaL_optnumber(L, 2, 1);
|
2011-04-28 22:45:59 +03:00
|
|
|
unsigned int r;
|
2011-04-28 22:37:57 +03:00
|
|
|
if (b) {
|
2011-04-28 22:45:59 +03:00
|
|
|
r = a / b;
|
|
|
|
lua_pushnumber(L, r);
|
2011-04-28 22:37:57 +03:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-04-30 08:25:29 +03:00
|
|
|
static int luaB_bit_idiv(lua_State *L) {
|
|
|
|
int a = luaL_optnumber(L, 1, 0);
|
|
|
|
int b = luaL_optnumber(L, 2, 1);
|
|
|
|
int r;
|
|
|
|
if (b) {
|
|
|
|
r = a / b;
|
|
|
|
lua_pushnumber(L, r);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-04-28 22:41:33 +03:00
|
|
|
static int luaB_bit_mod(lua_State *L) {
|
|
|
|
unsigned int a = luaL_optnumber(L, 1, 0);
|
|
|
|
unsigned int b = luaL_optnumber(L, 2, 1);
|
2011-04-28 22:45:59 +03:00
|
|
|
unsigned int r;
|
2011-04-28 22:41:33 +03:00
|
|
|
if (b) {
|
2011-04-28 22:45:59 +03:00
|
|
|
r = a % b;
|
|
|
|
lua_pushnumber(L, r);
|
2011-04-28 22:41:33 +03:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-04-28 22:45:59 +03:00
|
|
|
static int luaB_bit_mul(lua_State *L) {
|
|
|
|
unsigned int a = luaL_optnumber(L, 1, 0);
|
|
|
|
unsigned int b = luaL_optnumber(L, 2, 0);
|
|
|
|
unsigned int r = a * b;
|
|
|
|
lua_pushnumber(L, r);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-04-30 08:25:29 +03:00
|
|
|
static int luaB_bit_imul(lua_State *L) {
|
|
|
|
int a = luaL_optnumber(L, 1, 0);
|
|
|
|
int b = luaL_optnumber(L, 2, 0);
|
|
|
|
int r = a * b;
|
|
|
|
lua_pushnumber(L, r);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-04-28 23:12:02 +03:00
|
|
|
static int luaB_bit_sub(lua_State *L) {
|
|
|
|
unsigned int a = luaL_optnumber(L, 1, 0);
|
|
|
|
unsigned int b = luaL_optnumber(L, 2, 0);
|
|
|
|
unsigned int r = a - b;
|
|
|
|
lua_pushnumber(L, r);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int luaB_bit_add(lua_State *L) {
|
|
|
|
unsigned int a = luaL_optnumber(L, 1, 0);
|
|
|
|
unsigned int b = luaL_optnumber(L, 2, 0);
|
|
|
|
unsigned int r = a + b;
|
|
|
|
lua_pushnumber(L, r);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-04-30 08:56:30 +03:00
|
|
|
static int luaB_bit_unsigned(lua_State *L) {
|
|
|
|
unsigned int a = luaL_optnumber(L, 1, 0);
|
|
|
|
lua_pushnumber(L, a);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int luaB_bit_signed(lua_State *L) {
|
|
|
|
unsigned int a = luaL_optnumber(L, 1, 0);
|
|
|
|
lua_pushnumber(L, (int)a);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-10-12 08:07:15 +03:00
|
|
|
static const luaL_Reg base_funcs[] = {
|
|
|
|
{"doencfile", luaB_doencfile},
|
2010-09-10 13:06:30 +03:00
|
|
|
{"dofile", luaB_dofile},
|
2009-10-12 20:02:59 +03:00
|
|
|
{"print", luaB_print}, /* for some mystic, it is needed in win version (with -debug) */
|
2009-11-12 11:07:17 +02:00
|
|
|
{"is_sound", luaB_is_sound},
|
2010-06-05 12:56:55 +03:00
|
|
|
{"get_savepath", luaB_get_savepath},
|
2010-09-13 12:27:39 +03:00
|
|
|
{"get_gamepath", luaB_get_gamepath},
|
2010-09-16 10:31:18 +03:00
|
|
|
{"get_steadpath", luaB_get_steadpath},
|
2010-01-20 21:35:33 +02:00
|
|
|
{"set_timer", luaB_set_timer},
|
2010-10-30 15:54:41 +03:00
|
|
|
{"theme_var", luaB_theme_var},
|
2011-07-25 22:58:31 +03:00
|
|
|
{"theme_name", luaB_theme_name},
|
2011-03-19 10:10:23 +02:00
|
|
|
{"readdir", dir_iter_factory},
|
2011-04-12 14:34:50 +03:00
|
|
|
{"menu_toggle", luaB_show_menu},
|
2011-04-11 12:12:57 +03:00
|
|
|
|
2011-04-15 10:23:46 +03:00
|
|
|
{"sound_load", luaB_load_sound},
|
|
|
|
{"sound_free", luaB_free_sound},
|
|
|
|
{"sound_channel", luaB_channel_sound},
|
2011-04-15 11:12:06 +03:00
|
|
|
{"sound_panning", luaB_panning_sound},
|
|
|
|
{"sound_volume", luaB_volume_sound},
|
2011-04-15 10:23:46 +03:00
|
|
|
{"sounds_free", luaB_free_sounds},
|
2011-04-15 10:37:11 +03:00
|
|
|
|
|
|
|
{"mouse_pos", luaB_mouse_pos},
|
2011-04-15 10:23:46 +03:00
|
|
|
|
2011-04-11 12:12:57 +03:00
|
|
|
{"font_load", luaB_load_font},
|
|
|
|
{"font_free", luaB_free_font},
|
2011-04-14 12:32:37 +03:00
|
|
|
{"font_scaled_size", luaB_font_size_scaled},
|
2011-04-26 17:16:12 +03:00
|
|
|
{"get_ticks", luaB_get_ticks},
|
2011-04-11 12:12:57 +03:00
|
|
|
{"sprite_load", luaB_load_sprite},
|
|
|
|
{"sprite_text", luaB_text_sprite},
|
|
|
|
{"sprite_free", luaB_free_sprite},
|
|
|
|
{"sprites_free", luaB_free_sprites},
|
|
|
|
{"sprite_draw", luaB_draw_sprite},
|
2011-04-13 20:42:11 +03:00
|
|
|
{"sprite_copy", luaB_copy_sprite},
|
2011-04-11 12:12:57 +03:00
|
|
|
{"sprite_fill", luaB_fill_sprite},
|
2011-04-12 12:08:08 +03:00
|
|
|
{"sprite_dup", luaB_dup_sprite},
|
2011-04-11 12:12:57 +03:00
|
|
|
{"sprite_alpha", luaB_alpha_sprite},
|
|
|
|
{"sprite_size", luaB_sprite_size},
|
2011-04-12 07:50:03 +03:00
|
|
|
{"sprite_scale", luaB_scale_sprite},
|
2011-04-12 10:42:01 +03:00
|
|
|
{"sprite_rotate", luaB_rotate_sprite},
|
2011-04-11 12:12:57 +03:00
|
|
|
{"sprite_text_size", luaB_text_size},
|
2011-04-23 15:48:16 +03:00
|
|
|
{"sprite_pixel", luaB_pixel_sprite},
|
2011-04-28 22:29:21 +03:00
|
|
|
|
|
|
|
{"bit_or", luaB_bit_or},
|
|
|
|
{"bit_and", luaB_bit_and},
|
|
|
|
{"bit_xor", luaB_bit_xor},
|
|
|
|
{"bit_shl", luaB_bit_shl},
|
|
|
|
{"bit_shr", luaB_bit_shr},
|
|
|
|
{"bit_not", luaB_bit_not},
|
2011-04-28 22:37:57 +03:00
|
|
|
{"bit_div", luaB_bit_div},
|
2011-04-30 08:25:29 +03:00
|
|
|
{"bit_idiv", luaB_bit_idiv},
|
2011-04-28 22:41:33 +03:00
|
|
|
{"bit_mod", luaB_bit_mod},
|
2011-04-28 22:45:59 +03:00
|
|
|
{"bit_mul", luaB_bit_mul},
|
2011-04-30 08:25:29 +03:00
|
|
|
{"bit_imul", luaB_bit_imul},
|
2011-04-28 23:12:02 +03:00
|
|
|
{"bit_sub", luaB_bit_sub},
|
|
|
|
{"bit_add", luaB_bit_add},
|
2011-04-30 08:56:30 +03:00
|
|
|
{"bit_signed", luaB_bit_signed},
|
|
|
|
{"bit_unsigned", luaB_bit_unsigned},
|
2009-10-12 08:07:15 +03:00
|
|
|
{NULL, NULL}
|
|
|
|
};
|
|
|
|
|
2010-07-15 09:59:57 +03:00
|
|
|
int instead_lang(void)
|
|
|
|
{
|
|
|
|
char lang[64];
|
|
|
|
if (!L)
|
|
|
|
return 0;
|
|
|
|
if (opt_lang && *opt_lang)
|
|
|
|
snprintf(lang, sizeof(lang) - 1, "LANG='%s'", opt_lang);
|
|
|
|
else
|
|
|
|
snprintf(lang, sizeof(lang) - 1, "LANG='en'");
|
|
|
|
instead_eval(lang); instead_clear();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-06-07 13:43:43 +03:00
|
|
|
static int instead_package(void)
|
2009-02-21 12:52:44 +02:00
|
|
|
{
|
2010-06-07 13:18:44 +03:00
|
|
|
char *p;
|
2010-06-08 06:25:41 +03:00
|
|
|
char stead_path[PATH_MAX] = "package.path=\"./?.lua;";
|
|
|
|
|
|
|
|
p = game_local_stead_path();
|
|
|
|
if (p) {
|
|
|
|
strcat(stead_path, p);
|
|
|
|
strcat(stead_path, "/?.lua");
|
|
|
|
strcat(stead_path, ";");
|
|
|
|
}
|
2010-06-07 13:43:43 +03:00
|
|
|
|
2011-03-12 19:34:18 +02:00
|
|
|
if (STEAD_PATH[0] != '/') {
|
2010-06-07 13:43:43 +03:00
|
|
|
strcat(stead_path, game_cwd);
|
2010-06-07 13:18:44 +03:00
|
|
|
strcat(stead_path, "/");
|
|
|
|
strcat(stead_path, STEAD_PATH);
|
|
|
|
} else {
|
2010-06-07 13:43:43 +03:00
|
|
|
strcat(stead_path, STEAD_PATH);
|
2010-06-07 13:18:44 +03:00
|
|
|
}
|
|
|
|
strcat(stead_path, "/?.lua");
|
2010-06-07 13:43:43 +03:00
|
|
|
strcat(stead_path, "\"");
|
|
|
|
instead_eval(stead_path); instead_clear();
|
|
|
|
/* putenv(stead_path); */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int instead_init(void)
|
|
|
|
{
|
|
|
|
setlocale(LC_ALL,"");
|
|
|
|
setlocale(LC_NUMERIC,"C"); /* to avoid . -> , in numbers */
|
2009-02-21 12:52:44 +02:00
|
|
|
// strcpy(curcp, "UTF-8");
|
2010-06-07 13:43:43 +03:00
|
|
|
|
2009-02-21 12:52:44 +02:00
|
|
|
/* initialize Lua */
|
2010-06-07 13:43:43 +03:00
|
|
|
|
2009-02-21 12:52:44 +02:00
|
|
|
L = lua_open();
|
2009-10-12 08:07:15 +03:00
|
|
|
if (!L)
|
|
|
|
return -1;
|
2010-06-07 13:43:43 +03:00
|
|
|
|
2009-02-21 12:52:44 +02:00
|
|
|
luaL_openlibs(L);
|
2009-10-12 08:07:15 +03:00
|
|
|
luaL_register(L, "_G", base_funcs);
|
2011-03-10 12:40:55 +02:00
|
|
|
luaopen_lfs (L);
|
2010-06-07 13:43:43 +03:00
|
|
|
|
|
|
|
instead_package();
|
2010-07-15 09:59:57 +03:00
|
|
|
instead_lang();
|
2010-06-07 13:43:43 +03:00
|
|
|
|
2010-09-10 13:06:30 +03:00
|
|
|
if (dofile(L, dirpath(STEAD_PATH"/stead.lua"))) {
|
2009-02-21 12:52:44 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2009-09-20 13:21:11 +03:00
|
|
|
|
2010-09-10 13:06:30 +03:00
|
|
|
if (dofile(L, dirpath(STEAD_PATH"/gui.lua"))) {
|
2010-02-01 17:40:04 +02:00
|
|
|
instead_clear();
|
2009-02-21 12:52:44 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
/* cleanup Lua */
|
2010-02-01 17:40:04 +02:00
|
|
|
instead_clear();
|
2011-04-11 12:12:57 +03:00
|
|
|
srand(time(NULL));
|
2009-02-21 12:52:44 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void instead_done(void)
|
|
|
|
{
|
2010-01-20 21:35:33 +02:00
|
|
|
gfx_del_timer(instead_timer);
|
2011-02-19 15:23:09 +02:00
|
|
|
instead_timer = NULL_TIMER;
|
2009-08-26 08:25:53 +03:00
|
|
|
#ifdef _HAVE_ICONV
|
2009-02-21 12:52:44 +02:00
|
|
|
if (fromcp)
|
|
|
|
free(fromcp);
|
|
|
|
#endif
|
|
|
|
if (L)
|
|
|
|
lua_close(L);
|
|
|
|
L = NULL;
|
2009-08-26 08:25:53 +03:00
|
|
|
#ifdef _HAVE_ICONV
|
2009-02-21 12:52:44 +02:00
|
|
|
fromcp = NULL;
|
2009-08-26 08:25:53 +03:00
|
|
|
#endif
|
2011-04-11 12:12:57 +03:00
|
|
|
sprites_free();
|
2009-02-21 12:52:44 +02:00
|
|
|
}
|
|
|
|
|
2009-10-12 08:07:15 +03:00
|
|
|
int instead_encode(const char *s, const char *d)
|
|
|
|
{
|
|
|
|
FILE *src;
|
|
|
|
FILE *dst;
|
|
|
|
size_t size;
|
|
|
|
int i = 0;
|
|
|
|
unsigned char byte = 0xcc;
|
2009-10-12 09:35:06 +03:00
|
|
|
unsigned char buff[4096];
|
2009-10-12 08:07:15 +03:00
|
|
|
|
2009-10-31 15:43:25 +02:00
|
|
|
src = fopen(s, "rb");
|
2009-10-12 08:07:15 +03:00
|
|
|
if (!src) {
|
|
|
|
fprintf(stderr,"Can't open on read: '%s'.\n", s);
|
|
|
|
return -1;
|
|
|
|
}
|
2009-10-31 15:43:25 +02:00
|
|
|
dst = fopen(d, "wb");
|
2009-10-12 08:07:15 +03:00
|
|
|
if (!dst) {
|
|
|
|
fprintf(stderr,"Can't open on write: '%s'.\n", s);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
while ((size = fread(buff, 1, sizeof(buff), src))) {
|
|
|
|
for (i = 0; i < size; i++) {
|
|
|
|
buff[i] = (buff[i] << 3) | (buff[i] >> 5);
|
|
|
|
buff[i] ^= byte;
|
|
|
|
byte = buff[i];
|
|
|
|
}
|
|
|
|
if (fwrite(buff, 1, size, dst) != size) {
|
|
|
|
fprintf(stderr, "Error while writing file: '%s'.\n", d);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fclose(src);
|
|
|
|
fclose(dst);
|
|
|
|
return 0;
|
2009-10-12 09:35:06 +03:00
|
|
|
}
|