aboutsummaryrefslogtreecommitdiff
path: root/engines/sword25/util/lua
diff options
context:
space:
mode:
authorMatthew Hoops2011-05-31 14:16:29 -0400
committerMatthew Hoops2011-05-31 14:16:29 -0400
commitaa49b38c5a8032586cb94fc4ca07149eecabe64a (patch)
treeea5c7617f8c482c8cf4141b728b3ccff5a7f84c7 /engines/sword25/util/lua
parentd3ea9ab2a9334747eb445c1b45aa30cb17ffdf1b (diff)
parentc86a6c466fabe31fbf36363aa8d0ac8ea6001b9f (diff)
downloadscummvm-rg350-aa49b38c5a8032586cb94fc4ca07149eecabe64a.tar.gz
scummvm-rg350-aa49b38c5a8032586cb94fc4ca07149eecabe64a.tar.bz2
scummvm-rg350-aa49b38c5a8032586cb94fc4ca07149eecabe64a.zip
Merge remote branch 'upstream/master' into t7g-ios
Conflicts: engines/groovie/script.cpp
Diffstat (limited to 'engines/sword25/util/lua')
-rw-r--r--engines/sword25/util/lua/lapi.cpp16
-rw-r--r--engines/sword25/util/lua/lauxlib.cpp50
-rw-r--r--engines/sword25/util/lua/ldo.cpp30
-rw-r--r--engines/sword25/util/lua/ldump.cpp164
-rw-r--r--engines/sword25/util/lua/liolib.cpp222
-rw-r--r--engines/sword25/util/lua/llex.cpp20
-rw-r--r--engines/sword25/util/lua/lmathlib.cpp4
-rw-r--r--engines/sword25/util/lua/loadlib.cpp197
-rw-r--r--engines/sword25/util/lua/loslib.cpp77
-rw-r--r--engines/sword25/util/lua/lua.h2
-rw-r--r--engines/sword25/util/lua/luaconf.h35
-rw-r--r--engines/sword25/util/lua/lundump.cpp225
-rw-r--r--engines/sword25/util/lua/lundump.h36
-rw-r--r--engines/sword25/util/lua/lvm.cpp2
-rw-r--r--engines/sword25/util/lua/print.cpp227
-rw-r--r--engines/sword25/util/lua/scummvm_file.cpp205
-rw-r--r--engines/sword25/util/lua/scummvm_file.h56
17 files changed, 542 insertions, 1026 deletions
diff --git a/engines/sword25/util/lua/lapi.cpp b/engines/sword25/util/lua/lapi.cpp
index b1118db368..16f8460e39 100644
--- a/engines/sword25/util/lua/lapi.cpp
+++ b/engines/sword25/util/lua/lapi.cpp
@@ -26,9 +26,8 @@
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
-#include "lundump.h"
#include "lvm.h"
-
+#include "common/textconsole.h"
const char lua_ident[] =
@@ -876,17 +875,8 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
- int status;
- TValue *o;
- lua_lock(L);
- api_checknelems(L, 1);
- o = L->top - 1;
- if (isLfunction(o))
- status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
- else
- status = 1;
- lua_unlock(L);
- return status;
+ error("lua_dump not supported: Handling of precompiled LUA scripts has been removed in ScummVM");
+ return 1; // error
}
diff --git a/engines/sword25/util/lua/lauxlib.cpp b/engines/sword25/util/lua/lauxlib.cpp
index 53c0556625..8978cd5613 100644
--- a/engines/sword25/util/lua/lauxlib.cpp
+++ b/engines/sword25/util/lua/lauxlib.cpp
@@ -6,7 +6,6 @@
#include <ctype.h>
-#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -23,7 +22,8 @@
#include "lua.h"
#include "lauxlib.h"
-
+#include "scummvm_file.h"
+#include "common/textconsole.h"
#define FREELIST_REF 0 /* free list of references */
@@ -521,7 +521,7 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
typedef struct LoadF {
int extraline;
- FILE *f;
+ Sword25::Sword25FileProxy *f;
char buff[LUAL_BUFFERSIZE];
} LoadF;
@@ -534,27 +534,31 @@ static const char *getF (lua_State *L, void *ud, size_t *size) {
*size = 1;
return "\n";
}
- if (feof(lf->f)) return NULL;
- *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
+ if (lf->f->eof()) return NULL;
+ *size = lf->f->read(lf->buff, 1, sizeof(lf->buff));
return (*size > 0) ? 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;
+ const char *serr = "General error";
+ 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;
}
LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
LoadF lf;
int status, readstatus;
- int c;
+// int c;
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
lf.extraline = 0;
+
+ lua_pushfstring(L, "@%s", filename);
+ lf.f = new Sword25::Sword25FileProxy(filename, "r");
+/*
if (filename == NULL) {
lua_pushliteral(L, "=stdin");
lf.f = stdin;
@@ -564,23 +568,25 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
lf.f = fopen(filename, "r");
if (lf.f == NULL) return errfile(L, "open", fnameindex);
}
- c = getc(lf.f);
- if (c == '#') { /* Unix exec. file? */
+
+ c = lf.f->getc();
+ if (c == '#') { // Unix exec. file?
lf.extraline = 1;
- while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */
- if (c == '\n') c = getc(lf.f);
+ while ((c = lf.f->getc()) != EOF && c != '\n') ; // skip first line
+ if (c == '\n') c = lf.f->getc();
}
- if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
- lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
+ if (c == LUA_SIGNATURE[0] && filename) { // binary file?
+ lf.f = freopen(filename, "rb", lf.f); // reopen in binary mode
if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
- /* skip eventual `#!...' */
- while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
+ // skip eventual `#!...'
+ while ((c = lf.f->getc()) != EOF && c != LUA_SIGNATURE[0]) ;
lf.extraline = 0;
}
ungetc(c, lf.f);
+*/
status = lua_load(L, getF, &lf, lua_tostring(L, -1));
- readstatus = ferror(lf.f);
- if (filename) fclose(lf.f); /* close file (even in case of errors) */
+ readstatus = 0; //ferror(lf.f);
+ if (filename) delete lf.f; // close file (even in case of errors)
if (readstatus) {
lua_settop(L, fnameindex); /* ignore results from `lua_load' */
return errfile(L, "read", fnameindex);
@@ -638,7 +644,7 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
static int panic (lua_State *L) {
(void)L; /* to avoid warnings */
- fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
+ warning("PANIC: unprotected error in call to Lua API (%s)\n",
lua_tostring(L, -1));
return 0;
}
diff --git a/engines/sword25/util/lua/ldo.cpp b/engines/sword25/util/lua/ldo.cpp
index 07508fbb14..bbcdf98b3d 100644
--- a/engines/sword25/util/lua/ldo.cpp
+++ b/engines/sword25/util/lua/ldo.cpp
@@ -5,6 +5,16 @@
*/
+// FIXME: LUAI_THROW and LUAI_TRY use either throw/catch or setjmp/longjmp.
+// Neither of these is supported in ScummVM. So we need to come up
+// with a replacement. The most simple, direct and crude approach:
+// Replace "throw" with an "error()" call. Of course we only
+// would want to do that if this actually never happens...
+#define FORBIDDEN_SYMBOL_EXCEPTION_setjmp
+#define FORBIDDEN_SYMBOL_EXCEPTION_longjmp
+
+#include "common/textconsole.h"
+
#include <setjmp.h>
#include <stdlib.h>
#include <string.h>
@@ -26,10 +36,9 @@
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
-#include "lundump.h"
#include "lvm.h"
#include "lzio.h"
-
+#include "common/textconsole.h"
@@ -94,6 +103,11 @@ static void resetstack (lua_State *L, int status) {
void luaD_throw (lua_State *L, int errcode) {
if (L->errorJmp) {
L->errorJmp->status = errcode;
+ // FIXME: LUAI_THROW and LUAI_TRY use either throw/catch or setjmp/longjmp.
+ // Neither of these is supported in ScummVM. So we need to come up
+ // with a replacement. The most simple, direct and crude approach:
+ // Replace "throw" with an "error()" call. Of course we only
+ // would want to do that if this actually never happens...
LUAI_THROW(L, L->errorJmp);
}
else {
@@ -103,7 +117,7 @@ void luaD_throw (lua_State *L, int errcode) {
lua_unlock(L);
G(L)->panic(L);
}
- exit(EXIT_FAILURE);
+ error("luaD_throw failure");
}
}
@@ -113,6 +127,11 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
lj.status = 0;
lj.previous = L->errorJmp; /* chain new error handler */
L->errorJmp = &lj;
+ // FIXME: LUAI_THROW and LUAI_TRY use either throw/catch or setjmp/longjmp.
+ // Neither of these is supported in ScummVM. So we need to come up
+ // with a replacement. The most simple, direct and crude approach:
+ // Replace "throw" with an "error()" call. Of course we only
+ // would want to do that if this actually never happens...
LUAI_TRY(L, &lj,
(*f)(L, ud);
);
@@ -494,8 +513,9 @@ static void f_parser (lua_State *L, void *ud) {
struct SParser *p = cast(struct SParser *, ud);
int c = luaZ_lookahead(p->z);
luaC_checkGC(L);
- tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z,
- &p->buff, p->name);
+ if (c == LUA_SIGNATURE[0])
+ error("Handling of precompiled LUA scripts has been removed in ScummVM");
+ tf = luaY_parser(L, p->z, &p->buff, p->name);
cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L)));
cl->l.p = tf;
for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */
diff --git a/engines/sword25/util/lua/ldump.cpp b/engines/sword25/util/lua/ldump.cpp
deleted file mode 100644
index 3ce16542d6..0000000000
--- a/engines/sword25/util/lua/ldump.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
-** $Id$
-** save precompiled Lua chunks
-** See Copyright Notice in lua.h
-*/
-
-#include <stddef.h>
-
-#define ldump_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "lobject.h"
-#include "lstate.h"
-#include "lundump.h"
-
-typedef struct {
- lua_State* L;
- lua_Writer writer;
- void* data;
- int strip;
- int status;
-} DumpState;
-
-#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D)
-#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D)
-
-static void DumpBlock(const void* b, size_t size, DumpState* D)
-{
- if (D->status==0)
- {
- lua_unlock(D->L);
- D->status=(*D->writer)(D->L,b,size,D->data);
- lua_lock(D->L);
- }
-}
-
-static void DumpChar(int y, DumpState* D)
-{
- char x=(char)y;
- DumpVar(x,D);
-}
-
-static void DumpInt(int x, DumpState* D)
-{
- DumpVar(x,D);
-}
-
-static void DumpNumber(lua_Number x, DumpState* D)
-{
- DumpVar(x,D);
-}
-
-static void DumpVector(const void* b, int n, size_t size, DumpState* D)
-{
- DumpInt(n,D);
- DumpMem(b,n,size,D);
-}
-
-static void DumpString(const TString* s, DumpState* D)
-{
- if (s==NULL || getstr(s)==NULL)
- {
- size_t size=0;
- DumpVar(size,D);
- }
- else
- {
- size_t size=s->tsv.len+1; /* include trailing '\0' */
- DumpVar(size,D);
- DumpBlock(getstr(s),size,D);
- }
-}
-
-#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D)
-
-static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
-
-static void DumpConstants(const Proto* f, DumpState* D)
-{
- int i,n=f->sizek;
- DumpInt(n,D);
- for (i=0; i<n; i++)
- {
- const TValue* o=&f->k[i];
- DumpChar(ttype(o),D);
- switch (ttype(o))
- {
- case LUA_TNIL:
- break;
- case LUA_TBOOLEAN:
- DumpChar(bvalue(o),D);
- break;
- case LUA_TNUMBER:
- DumpNumber(nvalue(o),D);
- break;
- case LUA_TSTRING:
- DumpString(rawtsvalue(o),D);
- break;
- default:
- lua_assert(0); /* cannot happen */
- break;
- }
- }
- n=f->sizep;
- DumpInt(n,D);
- for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
-}
-
-static void DumpDebug(const Proto* f, DumpState* D)
-{
- int i,n;
- n= (D->strip) ? 0 : f->sizelineinfo;
- DumpVector(f->lineinfo,n,sizeof(int),D);
- n= (D->strip) ? 0 : f->sizelocvars;
- DumpInt(n,D);
- for (i=0; i<n; i++)
- {
- DumpString(f->locvars[i].varname,D);
- DumpInt(f->locvars[i].startpc,D);
- DumpInt(f->locvars[i].endpc,D);
- }
- n= (D->strip) ? 0 : f->sizeupvalues;
- DumpInt(n,D);
- for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
-}
-
-static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
-{
- DumpString((f->source==p || D->strip) ? NULL : f->source,D);
- DumpInt(f->linedefined,D);
- DumpInt(f->lastlinedefined,D);
- DumpChar(f->nups,D);
- DumpChar(f->numparams,D);
- DumpChar(f->is_vararg,D);
- DumpChar(f->maxstacksize,D);
- DumpCode(f,D);
- DumpConstants(f,D);
- DumpDebug(f,D);
-}
-
-static void DumpHeader(DumpState* D)
-{
- char h[LUAC_HEADERSIZE];
- luaU_header(h);
- DumpBlock(h,LUAC_HEADERSIZE,D);
-}
-
-/*
-** dump Lua function as precompiled chunk
-*/
-int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
-{
- DumpState D;
- D.L=L;
- D.writer=w;
- D.data=data;
- D.strip=strip;
- D.status=0;
- DumpHeader(&D);
- DumpFunction(f,NULL,&D);
- return D.status;
-}
diff --git a/engines/sword25/util/lua/liolib.cpp b/engines/sword25/util/lua/liolib.cpp
index aa44dcafa3..b505d1e4df 100644
--- a/engines/sword25/util/lua/liolib.cpp
+++ b/engines/sword25/util/lua/liolib.cpp
@@ -5,7 +5,6 @@
*/
-#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -17,7 +16,8 @@
#include "lauxlib.h"
#include "lualib.h"
-
+#include "common/textconsole.h"
+#include "scummvm_file.h"
#define IO_INPUT 1
@@ -28,7 +28,7 @@ static const char *const fnames[] = {"input", "output"};
static int pushresult (lua_State *L, int i, const char *filename) {
- int en = errno; /* calls to Lua API may change this value */
+ int en = 0; /*errno;*/ // Currently hardcoded for ScumMVM, this may need to be changed
if (i) {
lua_pushboolean(L, 1);
return 1;
@@ -36,55 +36,56 @@ static int pushresult (lua_State *L, int i, const char *filename) {
else {
lua_pushnil(L);
if (filename)
- lua_pushfstring(L, "%s: %s", filename, strerror(en));
+ lua_pushfstring(L, "%s: %s", filename, "General error" /*strerror(en)*/);
else
- lua_pushfstring(L, "%s", strerror(en));
+ lua_pushfstring(L, "%s", "General error" /*strerror(en)*/);
lua_pushinteger(L, en);
return 3;
}
}
-
+/*
static void fileerror (lua_State *L, int arg, const char *filename) {
- lua_pushfstring(L, "%s: %s", filename, strerror(errno));
+ lua_pushfstring(L, "%s: %s", filename, "LUA I/O error descriptions have been removed in ScummVM");
luaL_argerror(L, arg, lua_tostring(L, -1));
}
-
+*/
#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
-
+#define tofileProxy(L) ((Sword25::Sword25FileProxy **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
static int io_type (lua_State *L) {
+ return luaL_error(L, "%s", "LUA I/O has been removed in ScummVM");
+/*
void *ud;
luaL_checkany(L, 1);
ud = lua_touserdata(L, 1);
lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1))
- lua_pushnil(L); /* not a file */
+ lua_pushnil(L); // not a file
else if (*((FILE **)ud) == NULL)
lua_pushliteral(L, "closed file");
else
lua_pushliteral(L, "file");
return 1;
+*/
}
-
-static FILE *tofile (lua_State *L) {
- FILE **f = tofilep(L);
+static Sword25::Sword25FileProxy *tofile (lua_State *L) {
+ Sword25::Sword25FileProxy **f = tofileProxy(L);
if (*f == NULL)
luaL_error(L, "attempt to use a closed file");
return *f;
}
-
/*
** When creating file handles, always creates a `closed' file handle
** before opening the actual file; so, if there is a memory error, the
** file is not left opened.
*/
-static FILE **newfile (lua_State *L) {
- FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
+static Sword25::Sword25FileProxy **newfile (lua_State *L) {
+ Sword25::Sword25FileProxy **pf = (Sword25::Sword25FileProxy **)lua_newuserdata(L, sizeof(Sword25::Sword25FileProxy *));
*pf = NULL; /* file handle is currently `closed' */
luaL_getmetatable(L, LUA_FILEHANDLE);
lua_setmetatable(L, -2);
@@ -106,10 +107,13 @@ static int io_noclose (lua_State *L) {
** function to close 'popen' files
*/
static int io_pclose (lua_State *L) {
+ error("LUA I/O has been removed in ScummVM");
+/*
FILE **p = tofilep(L);
int ok = lua_pclose(L, *p);
*p = NULL;
return pushresult(L, ok, NULL);
+ */
}
@@ -117,52 +121,63 @@ static int io_pclose (lua_State *L) {
** function to close regular files
*/
static int io_fclose (lua_State *L) {
+ error("LUA I/O has been removed in ScummVM");
+ /*
FILE **p = tofilep(L);
int ok = (fclose(*p) == 0);
*p = NULL;
return pushresult(L, ok, NULL);
+ */
}
-
+/*
static int aux_close (lua_State *L) {
lua_getfenv(L, 1);
lua_getfield(L, -1, "__close");
return (lua_tocfunction(L, -1))(L);
}
-
+*/
static int io_close (lua_State *L) {
if (lua_isnone(L, 1))
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
- tofile(L); /* make sure argument is a file */
- return aux_close(L);
+
+ Sword25::Sword25FileProxy **f = tofileProxy(L);
+ delete *f;
+ *f = NULL;
+
+ return 0;
}
static int io_gc (lua_State *L) {
- FILE *f = *tofilep(L);
- /* ignore closed files */
- if (f != NULL)
- aux_close(L);
+ Sword25::Sword25FileProxy **f = tofileProxy(L);
+ // ignore closed files
+ if (*f != NULL)
+ delete *f;
+
return 0;
}
static int io_tostring (lua_State *L) {
+ error("LUA I/O has been removed in ScummVM");
+ /*
FILE *f = *tofilep(L);
if (f == NULL)
lua_pushliteral(L, "file (closed)");
else
lua_pushfstring(L, "file (%p)", f);
return 1;
+ */
}
static int io_open (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
- FILE **pf = newfile(L);
- *pf = fopen(filename, mode);
+ Sword25::Sword25FileProxy **pf = newfile(L);
+ *pf = new Sword25::Sword25FileProxy(filename, mode);
return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
}
@@ -172,21 +187,22 @@ static int io_open (lua_State *L) {
** correct __close for 'popen' files
*/
static int io_popen (lua_State *L) {
+ error("LUA I/O has been removed in ScummVM");
+/*
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
FILE **pf = newfile(L);
*pf = lua_popen(L, filename, mode);
return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
+ */
}
static int io_tmpfile (lua_State *L) {
- FILE **pf = newfile(L);
- *pf = tmpfile();
- return (*pf == NULL) ? pushresult(L, 0, NULL) : 1;
+ return luaL_error(L, "%s", "LUA I/O error descriptions have been removed in ScummVM");
}
-
+/*
static FILE *getiofile (lua_State *L, int findex) {
FILE *f;
lua_rawgeti(L, LUA_ENVIRONINDEX, findex);
@@ -195,8 +211,8 @@ static FILE *getiofile (lua_State *L, int findex) {
luaL_error(L, "standard %s file is closed", fnames[findex - 1]);
return f;
}
-
-
+*/
+/*
static int g_iofile (lua_State *L, int f, const char *mode) {
if (!lua_isnoneornil(L, 1)) {
const char *filename = lua_tostring(L, 1);
@@ -207,24 +223,26 @@ static int g_iofile (lua_State *L, int f, const char *mode) {
fileerror(L, 1, filename);
}
else {
- tofile(L); /* check that it's a valid file handle */
+ tofile(L); // check that it's a valid file handle
lua_pushvalue(L, 1);
}
lua_rawseti(L, LUA_ENVIRONINDEX, f);
}
- /* return current value */
+ // return current value
lua_rawgeti(L, LUA_ENVIRONINDEX, f);
return 1;
}
-
+*/
static int io_input (lua_State *L) {
- return g_iofile(L, IO_INPUT, "r");
+ error("LUA I/O has been removed in ScummVM");
+// return g_iofile(L, IO_INPUT, "r");
}
static int io_output (lua_State *L) {
- return g_iofile(L, IO_OUTPUT, "w");
+ error("LUA I/O has been removed in ScummVM");
+// return g_iofile(L, IO_OUTPUT, "w");
}
@@ -246,8 +264,10 @@ static int f_lines (lua_State *L) {
static int io_lines (lua_State *L) {
- if (lua_isnoneornil(L, 1)) { /* no arguments? */
- /* will iterate over default input */
+ error("LUA I/O has been removed in ScummVM");
+/*
+ if (lua_isnoneornil(L, 1)) { // no arguments?
+ // will iterate over default input
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT);
return f_lines(L);
}
@@ -260,6 +280,7 @@ static int io_lines (lua_State *L) {
aux_lines(L, lua_gettop(L), 1);
return 1;
}
+ */
}
@@ -269,18 +290,18 @@ static int io_lines (lua_State *L) {
** =======================================================
*/
-
-static int read_number (lua_State *L, FILE *f) {
+/*
+static int read_number (lua_State *L, Sword25::Sword25FileProxy *f) {
lua_Number d;
if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
lua_pushnumber(L, d);
return 1;
}
- else return 0; /* read fails */
+ else return 0; // read fails
}
-static int test_eof (lua_State *L, FILE *f) {
+static int test_eof (lua_State *L, Sword25::Sword25FileProxy *f) {
int c = getc(f);
ungetc(c, f);
lua_pushlstring(L, NULL, 0);
@@ -288,56 +309,56 @@ static int test_eof (lua_State *L, FILE *f) {
}
-static int read_line (lua_State *L, FILE *f) {
+static int read_line (lua_State *L, Sword25::Sword25FileProxy *f) {
luaL_Buffer b;
luaL_buffinit(L, &b);
for (;;) {
size_t l;
char *p = luaL_prepbuffer(&b);
- if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
- luaL_pushresult(&b); /* close buffer */
- return (lua_objlen(L, -1) > 0); /* check whether read something */
+ if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { // eof?
+ luaL_pushresult(&b); // close buffer
+ return (lua_objlen(L, -1) > 0); // check whether read something
}
l = strlen(p);
if (l == 0 || p[l-1] != '\n')
luaL_addsize(&b, l);
else {
- luaL_addsize(&b, l - 1); /* do not include `eol' */
- luaL_pushresult(&b); /* close buffer */
- return 1; /* read at least an `eol' */
+ luaL_addsize(&b, l - 1); // do not include `eol'
+ luaL_pushresult(&b); // close buffer
+ return 1; // read at least an `eol'
}
}
}
-static int read_chars (lua_State *L, FILE *f, size_t n) {
- size_t rlen; /* how much to read */
- size_t nr; /* number of chars actually read */
+static int read_chars (lua_State *L, Sword25::Sword25FileProxy *f, size_t n) {
+ size_t rlen; // how much to read
+ size_t nr; // number of chars actually read
luaL_Buffer b;
luaL_buffinit(L, &b);
- rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
+ rlen = LUAL_BUFFERSIZE; // try to read that much each time
do {
char *p = luaL_prepbuffer(&b);
- if (rlen > n) rlen = n; /* cannot read more than asked */
+ if (rlen > n) rlen = n; // cannot read more than asked
nr = fread(p, sizeof(char), rlen, f);
luaL_addsize(&b, nr);
- n -= nr; /* still have to read `n' chars */
- } while (n > 0 && nr == rlen); /* until end of count or eof */
- luaL_pushresult(&b); /* close buffer */
+ n -= nr; // still have to read `n' chars
+ } while (n > 0 && nr == rlen); // until end of count or eof
+ luaL_pushresult(&b); // close buffer
return (n == 0 || lua_objlen(L, -1) > 0);
}
-static int g_read (lua_State *L, FILE *f, int first) {
+static int g_read (lua_State *L, Sword25::Sword25FileProxy *f, int first) {
int nargs = lua_gettop(L) - 1;
int success;
int n;
clearerr(f);
- if (nargs == 0) { /* no arguments? */
+ if (nargs == 0) { // no arguments?
success = read_line(L, f);
- n = first+1; /* to return 1 result */
+ n = first+1; // to return 1 result
}
- else { /* ensure stack space for all results and for auxlib's buffer */
+ else { // ensure stack space for all results and for auxlib's buffer
luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
success = 1;
for (n = first; nargs-- && success; n++) {
@@ -349,15 +370,15 @@ static int g_read (lua_State *L, FILE *f, int first) {
const char *p = lua_tostring(L, n);
luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
switch (p[1]) {
- case 'n': /* number */
+ case 'n': // number
success = read_number(L, f);
break;
- case 'l': /* line */
+ case 'l': // line
success = read_line(L, f);
break;
- case 'a': /* file */
- read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */
- success = 1; /* always success */
+ case 'a': // file
+ read_chars(L, f, ~((size_t)0)); // read MAX_SIZE_T chars
+ success = 1; // always success
break;
default:
return luaL_argerror(L, n, "invalid format");
@@ -368,58 +389,66 @@ static int g_read (lua_State *L, FILE *f, int first) {
if (ferror(f))
return pushresult(L, 0, NULL);
if (!success) {
- lua_pop(L, 1); /* remove last result */
- lua_pushnil(L); /* push nil instead */
+ lua_pop(L, 1); // remove last result
+ lua_pushnil(L); // push nil instead
}
return n - first;
}
-
+*/
static int io_read (lua_State *L) {
- return g_read(L, getiofile(L, IO_INPUT), 1);
+ error("LUA I/O has been removed in ScummVM");
+// return g_read(L, getiofile(L, IO_INPUT), 1);
}
static int f_read (lua_State *L) {
- return g_read(L, tofile(L), 2);
+ error("LUA I/O has been removed in ScummVM");
+// return g_read(L, tofile(L), 2);
}
static int io_readline (lua_State *L) {
+ error("LUA I/O has been removed in ScummVM");
+/*
FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
int sucess;
- if (f == NULL) /* file is already closed? */
+ if (f == NULL) // file is already closed?
luaL_error(L, "file is already closed");
sucess = read_line(L, f);
if (ferror(f))
- return luaL_error(L, "%s", strerror(errno));
+ return luaL_error(L, "%s", "LUA I/O error descriptions have been removed in ScummVM");
if (sucess) return 1;
- else { /* EOF */
- if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
+ else { // EOF
+ if (lua_toboolean(L, lua_upvalueindex(2))) { // generator created file?
lua_settop(L, 0);
lua_pushvalue(L, lua_upvalueindex(1));
- aux_close(L); /* close it */
+ aux_close(L); // close it
}
return 0;
}
+*/
}
/* }====================================================== */
-static int g_write (lua_State *L, FILE *f, int arg) {
+static int g_write (lua_State *L, Sword25::Sword25FileProxy *f, int arg) {
int nargs = lua_gettop(L) - 1;
int status = 1;
for (; nargs--; arg++) {
if (lua_type(L, arg) == LUA_TNUMBER) {
- /* optimization: could be done exactly as for strings */
- status = status &&
- fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
- }
+ // optimization: could be done exactly as for strings
+ if (status) {
+ char buffer[20];
+ sprintf(buffer, LUA_NUMBER_FMT, lua_tonumber(L, arg));
+ status = f->write(buffer, strlen(buffer)) == strlen(buffer);
+ }
+ }
else {
size_t l;
const char *s = luaL_checklstring(L, arg, &l);
- status = status && (fwrite(s, sizeof(char), l, f) == l);
+ status = status && (f->write(s, l) == l);
}
}
return pushresult(L, status, NULL);
@@ -427,7 +456,8 @@ static int g_write (lua_State *L, FILE *f, int arg) {
static int io_write (lua_State *L) {
- return g_write(L, getiofile(L, IO_OUTPUT), 1);
+ error("LUA I/O has been removed in ScummVM");
+// return g_write(L, getiofile(L, IO_OUTPUT), 1);
}
@@ -437,6 +467,8 @@ static int f_write (lua_State *L) {
static int f_seek (lua_State *L) {
+ error("LUA I/O has been removed in ScummVM");
+ /*
static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
static const char *const modenames[] = {"set", "cur", "end", NULL};
FILE *f = tofile(L);
@@ -444,15 +476,18 @@ static int f_seek (lua_State *L) {
long offset = luaL_optlong(L, 3, 0);
op = fseek(f, offset, mode[op]);
if (op)
- return pushresult(L, 0, NULL); /* error */
+ return pushresult(L, 0, NULL); // error
else {
lua_pushinteger(L, ftell(f));
return 1;
}
+*/
}
static int f_setvbuf (lua_State *L) {
+ error("LUA I/O has been removed in ScummVM");
+ /*
static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
static const char *const modenames[] = {"no", "full", "line", NULL};
FILE *f = tofile(L);
@@ -460,17 +495,20 @@ static int f_setvbuf (lua_State *L) {
lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
int res = setvbuf(f, NULL, mode[op], sz);
return pushresult(L, res == 0, NULL);
+ */
}
static int io_flush (lua_State *L) {
- return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
+ error("LUA I/O has been removed in ScummVM");
+// return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
}
static int f_flush (lua_State *L) {
- return pushresult(L, fflush(tofile(L)) == 0, NULL);
+ error("LUA I/O has been removed in ScummVM");
+// return pushresult(L, fflush(tofile(L)) == 0, NULL);
}
@@ -511,18 +549,18 @@ static void createmeta (lua_State *L) {
luaL_register(L, NULL, flib); /* file methods */
}
-
+/*
static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
*newfile(L) = f;
if (k > 0) {
lua_pushvalue(L, -1);
lua_rawseti(L, LUA_ENVIRONINDEX, k);
}
- lua_pushvalue(L, -2); /* copy environment */
- lua_setfenv(L, -2); /* set it */
+ lua_pushvalue(L, -2); // copy environment
+ lua_setfenv(L, -2); // set it
lua_setfield(L, -3, fname);
}
-
+*/
static void newfenv (lua_State *L, lua_CFunction cls) {
lua_createtable(L, 0, 1);
@@ -540,9 +578,11 @@ LUALIB_API int luaopen_io (lua_State *L) {
luaL_register(L, LUA_IOLIBNAME, iolib);
/* create (and set) default files */
newfenv(L, io_noclose); /* close function for default files */
+/*
createstdfile(L, stdin, IO_INPUT, "stdin");
createstdfile(L, stdout, IO_OUTPUT, "stdout");
createstdfile(L, stderr, 0, "stderr");
+*/
lua_pop(L, 1); /* pop environment for default files */
lua_getfield(L, -1, "popen");
newfenv(L, io_pclose); /* create environment for 'popen' */
diff --git a/engines/sword25/util/lua/llex.cpp b/engines/sword25/util/lua/llex.cpp
index fdde2b8e5f..4d73a6a600 100644
--- a/engines/sword25/util/lua/llex.cpp
+++ b/engines/sword25/util/lua/llex.cpp
@@ -6,7 +6,7 @@
#include <ctype.h>
-#include <locale.h>
+#include <stdio.h>
#include <string.h>
#define llex_c
@@ -176,9 +176,23 @@ static void buffreplace (LexState *ls, char from, char to) {
static void trydecpoint (LexState *ls, SemInfo *seminfo) {
/* format error: try to update decimal point separator */
- struct lconv *cv = localeconv();
+ // Normally we'd use localeconv() to get the decimal point separator, but
+ // annoyingly that is not available on some platforms, e.g. Android. Figure
+ // it out by formatting a known value and extract the separator from that
+ // instead. The result could be cached, but considering the game I doubt
+ // this will ever be a bottleneck. Note that the separator is assumed to fit
+ // in a char, but that was a limitation in the original code as well.
char old = ls->decpoint;
- ls->decpoint = (cv ? cv->decimal_point[0] : '.');
+ char buf[5];
+ int i;
+ sprintf(buf, "%.1f", 1.0);
+ ls->decpoint = '.';
+ for (i = 0; buf[i]; i++) {
+ if (!isspace(buf[i]) && !isdigit(buf[i])) {
+ ls->decpoint = buf[i];
+ break;
+ }
+ }
buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */
if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) {
/* format error with correct decimal point: no more options */
diff --git a/engines/sword25/util/lua/lmathlib.cpp b/engines/sword25/util/lua/lmathlib.cpp
index 7e64d75789..6c36bbcf4e 100644
--- a/engines/sword25/util/lua/lmathlib.cpp
+++ b/engines/sword25/util/lua/lmathlib.cpp
@@ -5,6 +5,10 @@
*/
+// FIXME: rand and srand should be replaced by a RandomSource
+#define FORBIDDEN_SYMBOL_EXCEPTION_rand
+#define FORBIDDEN_SYMBOL_EXCEPTION_srand
+
#include <stdlib.h>
// MSVC does not define M_PI, M_SQRT2 and other math defines by default.
// _USE_MATH_DEFINES must be defined in order to have these defined, thus
diff --git a/engines/sword25/util/lua/loadlib.cpp b/engines/sword25/util/lua/loadlib.cpp
index 2549e2bdb1..9795a575f5 100644
--- a/engines/sword25/util/lua/loadlib.cpp
+++ b/engines/sword25/util/lua/loadlib.cpp
@@ -9,10 +9,6 @@
*/
-#include <stdlib.h>
-#include <string.h>
-
-
#define loadlib_c
#define LUA_LIB
@@ -35,18 +31,6 @@
#define LIB_FAIL "open"
-/* error codes for ll_loadfunc */
-#define ERRLIB 1
-#define ERRFUNC 2
-
-#define setprogdir(L) ((void)0)
-
-
-static void ll_unloadlib (void *lib);
-static void *ll_load (lua_State *L, const char *path);
-static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
-
-
/*
** {======================================================
** Fallback for other systems
@@ -60,24 +44,6 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
#define DLMSG "dynamic libraries not enabled; check your Lua installation"
-static void ll_unloadlib (void *lib) {
- (void)lib; /* to avoid warnings */
-}
-
-
-static void *ll_load (lua_State *L, const char *path) {
- (void)path; /* to avoid warnings */
- lua_pushliteral(L, DLMSG);
- return NULL;
-}
-
-
-static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
- (void)lib; (void)sym; /* to avoid warnings */
- lua_pushliteral(L, DLMSG);
- return NULL;
-}
-
/* }====================================================== */
@@ -108,39 +74,33 @@ static void **ll_register (lua_State *L, const char *path) {
*/
static int gctm (lua_State *L) {
void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
- if (*lib) ll_unloadlib(*lib);
*lib = NULL; /* mark library as closed */
return 0;
}
-static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
- void **reg = ll_register(L, path);
- if (*reg == NULL) *reg = ll_load(L, path);
- if (*reg == NULL)
- return ERRLIB; /* unable to load library */
- else {
- lua_CFunction f = ll_sym(L, *reg, sym);
- if (f == NULL)
- return ERRFUNC; /* unable to find function */
- lua_pushcfunction(L, f);
- return 0; /* return function */
- }
-}
+/* error codes for ll_loadfunc */
+#define ERRLIB 1
+#define ERRFUNC 2
static int ll_loadlib (lua_State *L) {
const char *path = luaL_checkstring(L, 1);
- const char *init = luaL_checkstring(L, 2);
- int stat = ll_loadfunc(L, path, init);
- if (stat == 0) /* no errors? */
- return 1; /* return the loaded function */
- else { /* error; error message is on stack top */
- lua_pushnil(L);
- lua_insert(L, -2);
- lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
- return 3; /* return nil, error message, and where */
+// const char *init = luaL_checkstring(L, 2);
+ int stat;
+ void **reg = ll_register(L, path);
+ if (*reg == NULL) {
+ stat = ERRLIB; /* unable to load library */
+ } else {
+ stat = ERRFUNC; /* unable to find function */
}
+ lua_pushliteral(L, DLMSG);
+
+ /* error; error message is on stack top */
+ lua_pushnil(L);
+ lua_insert(L, -2);
+ lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
+ return 3; /* return nil, error message, and where */
}
@@ -152,109 +112,6 @@ static int ll_loadlib (lua_State *L) {
*/
-static int readable (const char *filename) {
- FILE *f = fopen(filename, "r"); /* try to open file */
- if (f == NULL) return 0; /* open failed */
- fclose(f);
- return 1;
-}
-
-
-static const char *pushnexttemplate (lua_State *L, const char *path) {
- const char *l;
- while (*path == *LUA_PATHSEP) path++; /* skip separators */
- if (*path == '\0') return NULL; /* no more templates */
- l = strchr(path, *LUA_PATHSEP); /* find next separator */
- if (l == NULL) l = path + strlen(path);
- lua_pushlstring(L, path, l - path); /* template */
- return l;
-}
-
-
-static const char *findfile (lua_State *L, const char *name,
- const char *pname) {
- const char *path;
- name = luaL_gsub(L, name, ".", LUA_DIRSEP);
- lua_getfield(L, LUA_ENVIRONINDEX, pname);
- path = lua_tostring(L, -1);
- if (path == NULL)
- luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
- lua_pushliteral(L, ""); /* error accumulator */
- while ((path = pushnexttemplate(L, path)) != NULL) {
- const char *filename;
- filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
- lua_remove(L, -2); /* remove path template */
- if (readable(filename)) /* does file exist and is readable? */
- return filename; /* return that file name */
- lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
- lua_remove(L, -2); /* remove file name */
- lua_concat(L, 2); /* add entry to possible error message */
- }
- return NULL; /* not found */
-}
-
-
-static void loaderror (lua_State *L, const char *filename) {
- luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s",
- lua_tostring(L, 1), filename, lua_tostring(L, -1));
-}
-
-
-static int loader_Lua (lua_State *L) {
- const char *filename;
- const char *name = luaL_checkstring(L, 1);
- filename = findfile(L, name, "path");
- if (filename == NULL) return 1; /* library not found in this path */
- if (luaL_loadfile(L, filename) != 0)
- loaderror(L, filename);
- return 1; /* library loaded successfully */
-}
-
-
-static const char *mkfuncname (lua_State *L, const char *modname) {
- const char *funcname;
- const char *mark = strchr(modname, *LUA_IGMARK);
- if (mark) modname = mark + 1;
- funcname = luaL_gsub(L, modname, ".", LUA_OFSEP);
- funcname = lua_pushfstring(L, POF"%s", funcname);
- lua_remove(L, -2); /* remove 'gsub' result */
- return funcname;
-}
-
-
-static int loader_C (lua_State *L) {
- const char *funcname;
- const char *name = luaL_checkstring(L, 1);
- const char *filename = findfile(L, name, "cpath");
- if (filename == NULL) return 1; /* library not found in this path */
- funcname = mkfuncname(L, name);
- if (ll_loadfunc(L, filename, funcname) != 0)
- loaderror(L, filename);
- return 1; /* library loaded successfully */
-}
-
-
-static int loader_Croot (lua_State *L) {
- const char *funcname;
- const char *filename;
- const char *name = luaL_checkstring(L, 1);
- const char *p = strchr(name, '.');
- int stat;
- if (p == NULL) return 0; /* is root */
- lua_pushlstring(L, name, p - name);
- filename = findfile(L, lua_tostring(L, -1), "cpath");
- if (filename == NULL) return 1; /* root not found */
- funcname = mkfuncname(L, name);
- if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
- if (stat != ERRFUNC) loaderror(L, filename); /* real error */
- lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
- name, filename);
- return 1; /* function not found */
- }
- return 1;
-}
-
-
static int loader_preload (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
lua_getfield(L, LUA_ENVIRONINDEX, "preload");
@@ -407,23 +264,11 @@ static int ll_seeall (lua_State *L) {
-/* auxiliary mark (for internal use) */
-#define AUXMARK "\1"
-
static void setpath (lua_State *L, const char *fieldname, const char *envname,
const char *def) {
- const char *path = getenv(envname);
- if (path == NULL) /* no environment variable? */
- lua_pushstring(L, def); /* use default */
- else {
- /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
- path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
- LUA_PATHSEP AUXMARK LUA_PATHSEP);
- luaL_gsub(L, path, AUXMARK, def);
- lua_remove(L, -2);
- }
- setprogdir(L);
- lua_setfield(L, -2, fieldname);
+ // no environment variable -> use default
+ lua_pushstring(L, def);
+ lua_setfield(L, -2, fieldname);
}
@@ -442,7 +287,7 @@ static const luaL_Reg ll_funcs[] = {
static const lua_CFunction loaders[] =
- {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
+ {loader_preload, NULL};
LUALIB_API int luaopen_package (lua_State *L) {
diff --git a/engines/sword25/util/lua/loslib.cpp b/engines/sword25/util/lua/loslib.cpp
index 035925ceb5..b61f8c65e1 100644
--- a/engines/sword25/util/lua/loslib.cpp
+++ b/engines/sword25/util/lua/loslib.cpp
@@ -4,11 +4,9 @@
** See Copyright Notice in lua.h
*/
+// FIXME: Get rid of all time.h stuff
+#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
-#include <errno.h>
-#include <locale.h>
-#include <stdlib.h>
-#include <string.h>
#include <time.h>
#define loslib_c
@@ -19,54 +17,53 @@
#include "lauxlib.h"
#include "lualib.h"
-
-static int os_pushresult (lua_State *L, int i, const char *filename) {
- int en = errno; /* calls to Lua API may change this value */
- if (i) {
- lua_pushboolean(L, 1);
- return 1;
- }
- else {
- lua_pushnil(L);
- lua_pushfstring(L, "%s: %s", filename, strerror(en));
- lua_pushinteger(L, en);
- return 3;
- }
-}
+#include "common/system.h"
+#include "common/textconsole.h"
static int os_execute (lua_State *L) {
- lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
+ // Non-portable call, removed in ScummVM.
+ // FIXME: Is this ever invoked? If so, investigate that code further.
+ lua_pushinteger(L, -1); // signal that an error occurred
return 1;
}
static int os_remove (lua_State *L) {
- const char *filename = luaL_checkstring(L, 1);
- return os_pushresult(L, remove(filename) == 0, filename);
+ // Non-portable call that deletes a file. Removed in ScummVM.
+ // This call is invoked in sword25 when loading games in order to remove the
+ // temporary savegame thumbnail that the original engine code created. We
+ // embed the thumbnail in the savegame instead, so this call is not needed at
+ // all.
+ return 1;
}
static int os_rename (lua_State *L) {
- const char *fromname = luaL_checkstring(L, 1);
- const char *toname = luaL_checkstring(L, 2);
- return os_pushresult(L, rename(fromname, toname) == 0, fromname);
+ // Non-portable call, removed in ScummVM.
+ return 1;
}
static int os_tmpname (lua_State *L) {
+ // Non-portable call, removed in ScummVM.
+ // FIXME: Why do we return an error in tmpname, but for other
+ // removed methods we just do nothing?
return luaL_error(L, "unable to generate a unique filename");
}
static int os_getenv (lua_State *L) {
- lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
+ // Non-portable call, removed in ScummVM.
+ // FIXME: Is this ever invoked? If so, investigate that code further.
+ lua_pushstring(L, NULL);
return 1;
}
static int os_clock (lua_State *L) {
- lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
+ // Non-portable call to clock() replaced by invocation of OSystem::getMillis.
+ lua_pushnumber(L, ((lua_Number)g_system->getMillis())/(lua_Number)1000);
return 1;
}
@@ -117,6 +114,12 @@ static int getfield (lua_State *L, const char *key, int d) {
static int os_date (lua_State *L) {
const char *s = luaL_optstring(L, 1, "%c");
+ // FIXME: Rewrite the code below to use OSystem::getTimeAndDate
+ // Alternatively, remove it, if sword25 does not use it.
+ //
+ // The former would mean sacrificing the ability to choose the timezone, *or*
+ // we would have to drive an effort to add time zone support to OSystem (is it
+ // worth that, though???)
time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
struct tm *stm;
if (*s == '!') { /* UTC? */
@@ -162,6 +165,8 @@ static int os_date (lua_State *L) {
static int os_time (lua_State *L) {
+ // FIXME: Rewrite the code below to use OSystem::getTimeAndDate.
+ // Alternatively, remove it, if sword25 does not use it.
time_t t;
if (lua_isnoneornil(L, 1)) /* called without args? */
t = time(NULL); /* get current time */
@@ -187,6 +192,9 @@ static int os_time (lua_State *L) {
static int os_difftime (lua_State *L) {
+ // FIXME: difftime is not portable, unfortunately.
+ // So we either have to replace this code, or just remove it,
+ // depending on whether sword25 actually uses it.
lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
(time_t)(luaL_optnumber(L, 2, 0))));
return 1;
@@ -196,19 +204,20 @@ static int os_difftime (lua_State *L) {
static int os_setlocale (lua_State *L) {
- static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
- LC_NUMERIC, LC_TIME};
- static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
- "numeric", "time", NULL};
- const char *l = luaL_optstring(L, 1, NULL);
- int op = luaL_checkoption(L, 2, "all", catnames);
- lua_pushstring(L, setlocale(cat[op], l));
+ // Non-portable call to set the numeric locale. Removed in ScummVM, as it's
+ // not used in sword25.
return 1;
}
static int os_exit (lua_State *L) {
- exit(luaL_optint(L, 1, EXIT_SUCCESS));
+ // FIXME: Using exit is not portable!
+ // Using OSystem::quit() isn't really a great idea, either.
+ // We really would prefer to let the main run loop exit, so that
+ // our main() can perform cleanup.
+ if (0 == luaL_optint(L, 1, EXIT_SUCCESS))
+ g_system->quit();
+ error("LUA os_exit invokes with non-zero exit value");
}
static const luaL_Reg syslib[] = {
diff --git a/engines/sword25/util/lua/lua.h b/engines/sword25/util/lua/lua.h
index 088a511cf9..417cdadf8b 100644
--- a/engines/sword25/util/lua/lua.h
+++ b/engines/sword25/util/lua/lua.h
@@ -9,6 +9,8 @@
#ifndef lua_h
#define lua_h
+#include "common/scummsys.h"
+
#include <stdarg.h>
#include <stddef.h>
diff --git a/engines/sword25/util/lua/luaconf.h b/engines/sword25/util/lua/luaconf.h
index 669b0e7a49..f3509e969b 100644
--- a/engines/sword25/util/lua/luaconf.h
+++ b/engines/sword25/util/lua/luaconf.h
@@ -183,7 +183,11 @@
#define LUAI_DATA /* empty */
#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
- defined(__ELF__)
+ defined(__ELF__) && !defined(__PLAYSTATION2__)
+/*
+** The PS2 gcc compiler doesn't like the visibility attribute, so
+** we use the normal "extern" definitions in the block below
+*/
#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
#define LUAI_DATA LUAI_FUNC
@@ -345,7 +349,7 @@
/*
@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting
@* facility.
-** CHANGE it to 2 if you want the old behaviour, or undefine it to turn
+** CHANGE it to 2 if you want the old behavior, or undefine it to turn
** off the advisory error when nesting [[...]].
*/
#define LUA_COMPAT_LSTR 1
@@ -634,33 +638,6 @@ union luai_Cast { double l_d; long l_l; };
/*
-@@ lua_tmpnam is the function that the OS library uses to create a
-@* temporary name.
-@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam.
-** CHANGE them if you have an alternative to tmpnam (which is considered
-** insecure) or if you want the original tmpnam anyway. By default, Lua
-** uses tmpnam except when POSIX is available, where it uses mkstemp.
-*/
-#if defined(loslib_c) || defined(luaall_c)
-
-#if defined(LUA_USE_MKSTEMP)
-#include <unistd.h>
-#define LUA_TMPNAMBUFSIZE 32
-#define lua_tmpnam(b,e) { \
- strcpy(b, "/tmp/lua_XXXXXX"); \
- e = mkstemp(b); \
- if (e != -1) close(e); \
- e = (e == -1); }
-
-#else
-#define LUA_TMPNAMBUFSIZE L_tmpnam
-#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
-#endif
-
-#endif
-
-
-/*
@@ lua_popen spawns a new process connected to the current one through
@* the file streams.
** CHANGE it if you have a way to implement it in your system.
diff --git a/engines/sword25/util/lua/lundump.cpp b/engines/sword25/util/lua/lundump.cpp
deleted file mode 100644
index 4ffc623575..0000000000
--- a/engines/sword25/util/lua/lundump.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
-** $Id$
-** load precompiled Lua chunks
-** See Copyright Notice in lua.h
-*/
-
-#include <string.h>
-
-#define lundump_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstring.h"
-#include "lundump.h"
-#include "lzio.h"
-
-typedef struct {
- lua_State* L;
- ZIO* Z;
- Mbuffer* b;
- const char* name;
-} LoadState;
-
-#ifdef LUAC_TRUST_BINARIES
-#define IF(c,s)
-#define error(S,s)
-#else
-#define IF(c,s) if (c) error(S,s)
-
-static void error(LoadState* S, const char* why)
-{
- luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why);
- luaD_throw(S->L,LUA_ERRSYNTAX);
-}
-#endif
-
-#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
-#define LoadByte(S) (lu_byte)LoadChar(S)
-#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
-#define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
-
-static void LoadBlock(LoadState* S, void* b, size_t size)
-{
- size_t r=luaZ_read(S->Z,b,size);
- UNUSED(r);
- IF (r!=0, "unexpected end");
-}
-
-static int LoadChar(LoadState* S)
-{
- char x;
- LoadVar(S,x);
- return x;
-}
-
-static int LoadInt(LoadState* S)
-{
- int x;
- LoadVar(S,x);
- IF (x<0, "bad integer");
- return x;
-}
-
-static lua_Number LoadNumber(LoadState* S)
-{
- lua_Number x;
- LoadVar(S,x);
- return x;
-}
-
-static TString* LoadString(LoadState* S)
-{
- size_t size;
- LoadVar(S,size);
- if (size==0)
- return NULL;
- else
- {
- char* s=luaZ_openspace(S->L,S->b,size);
- LoadBlock(S,s,size);
- return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
- }
-}
-
-static void LoadCode(LoadState* S, Proto* f)
-{
- int n=LoadInt(S);
- f->code=luaM_newvector(S->L,n,Instruction);
- f->sizecode=n;
- LoadVector(S,f->code,n,sizeof(Instruction));
-}
-
-static Proto* LoadFunction(LoadState* S, TString* p);
-
-static void LoadConstants(LoadState* S, Proto* f)
-{
- int i,n;
- n=LoadInt(S);
- f->k=luaM_newvector(S->L,n,TValue);
- f->sizek=n;
- for (i=0; i<n; i++) setnilvalue(&f->k[i]);
- for (i=0; i<n; i++)
- {
- TValue* o=&f->k[i];
- int t=LoadChar(S);
- switch (t)
- {
- case LUA_TNIL:
- setnilvalue(o);
- break;
- case LUA_TBOOLEAN:
- setbvalue(o,LoadChar(S));
- break;
- case LUA_TNUMBER:
- setnvalue(o,LoadNumber(S));
- break;
- case LUA_TSTRING:
- setsvalue2n(S->L,o,LoadString(S));
- break;
- default:
- error(S,"bad constant");
- break;
- }
- }
- n=LoadInt(S);
- f->p=luaM_newvector(S->L,n,Proto*);
- f->sizep=n;
- for (i=0; i<n; i++) f->p[i]=NULL;
- for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
-}
-
-static void LoadDebug(LoadState* S, Proto* f)
-{
- int i,n;
- n=LoadInt(S);
- f->lineinfo=luaM_newvector(S->L,n,int);
- f->sizelineinfo=n;
- LoadVector(S,f->lineinfo,n,sizeof(int));
- n=LoadInt(S);
- f->locvars=luaM_newvector(S->L,n,LocVar);
- f->sizelocvars=n;
- for (i=0; i<n; i++) f->locvars[i].varname=NULL;
- for (i=0; i<n; i++)
- {
- f->locvars[i].varname=LoadString(S);
- f->locvars[i].startpc=LoadInt(S);
- f->locvars[i].endpc=LoadInt(S);
- }
- n=LoadInt(S);
- f->upvalues=luaM_newvector(S->L,n,TString*);
- f->sizeupvalues=n;
- for (i=0; i<n; i++) f->upvalues[i]=NULL;
- for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
-}
-
-static Proto* LoadFunction(LoadState* S, TString* p)
-{
- Proto* f=luaF_newproto(S->L);
- setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
- f->source=LoadString(S); if (f->source==NULL) f->source=p;
- f->linedefined=LoadInt(S);
- f->lastlinedefined=LoadInt(S);
- f->nups=LoadByte(S);
- f->numparams=LoadByte(S);
- f->is_vararg=LoadByte(S);
- f->maxstacksize=LoadByte(S);
- LoadCode(S,f);
- LoadConstants(S,f);
- LoadDebug(S,f);
- IF (!luaG_checkcode(f), "bad code");
- S->L->top--;
- return f;
-}
-
-static void LoadHeader(LoadState* S)
-{
- char h[LUAC_HEADERSIZE];
- char s[LUAC_HEADERSIZE];
- luaU_header(h);
- LoadBlock(S,s,LUAC_HEADERSIZE);
- IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
-}
-
-/*
-** load precompiled chunk
-*/
-Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
-{
- LoadState S;
- if (*name=='@' || *name=='=')
- S.name=name+1;
- else if (*name==LUA_SIGNATURE[0])
- S.name="binary string";
- else
- S.name=name;
- S.L=L;
- S.Z=Z;
- S.b=buff;
- LoadHeader(&S);
- return LoadFunction(&S,luaS_newliteral(L,"=?"));
-}
-
-/*
-* make header
-*/
-void luaU_header (char* h)
-{
- int x=1;
- memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
- h+=sizeof(LUA_SIGNATURE)-1;
- *h++=(char)LUAC_VERSION;
- *h++=(char)LUAC_FORMAT;
- *h++=(char)*(char*)&x; /* endianness */
- *h++=(char)sizeof(int);
- *h++=(char)sizeof(size_t);
- *h++=(char)sizeof(Instruction);
- *h++=(char)sizeof(lua_Number);
- *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
-}
diff --git a/engines/sword25/util/lua/lundump.h b/engines/sword25/util/lua/lundump.h
deleted file mode 100644
index f791a4f173..0000000000
--- a/engines/sword25/util/lua/lundump.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-** $Id$
-** load precompiled Lua chunks
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lundump_h
-#define lundump_h
-
-#include "lobject.h"
-#include "lzio.h"
-
-/* load one chunk; from lundump.c */
-LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
-
-/* make header; from lundump.c */
-LUAI_FUNC void luaU_header (char* h);
-
-/* dump one chunk; from ldump.c */
-LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
-
-#ifdef luac_c
-/* print one chunk; from print.c */
-LUAI_FUNC void luaU_print (const Proto* f, int full);
-#endif
-
-/* for header of binary files -- this is Lua 5.1 */
-#define LUAC_VERSION 0x51
-
-/* for header of binary files -- this is the official format */
-#define LUAC_FORMAT 0
-
-/* size of header of binary files */
-#define LUAC_HEADERSIZE 12
-
-#endif
diff --git a/engines/sword25/util/lua/lvm.cpp b/engines/sword25/util/lua/lvm.cpp
index ae70fe2645..fb700c20a2 100644
--- a/engines/sword25/util/lua/lvm.cpp
+++ b/engines/sword25/util/lua/lvm.cpp
@@ -202,7 +202,7 @@ static int l_strcmp (const TString *ls, const TString *rs) {
const char *r = getstr(rs);
size_t lr = rs->tsv.len;
for (;;) {
- int temp = strcoll(l, r);
+ int temp = strcmp(l, r);
if (temp != 0) return temp;
else { /* strings are equal up to a `\0' */
size_t len = strlen(l); /* index of first `\0' in both strings */
diff --git a/engines/sword25/util/lua/print.cpp b/engines/sword25/util/lua/print.cpp
deleted file mode 100644
index 22039c9861..0000000000
--- a/engines/sword25/util/lua/print.cpp
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
-** $Id$
-** print bytecodes
-** See Copyright Notice in lua.h
-*/
-
-#include <ctype.h>
-#include <stdio.h>
-
-#define luac_c
-#define LUA_CORE
-
-#include "ldebug.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lundump.h"
-
-#define PrintFunction luaU_print
-
-#define Sizeof(x) ((int)sizeof(x))
-#define VOID(p) ((const void*)(p))
-
-static void PrintString(const TString* ts)
-{
- const char* s=getstr(ts);
- size_t i,n=ts->tsv.len;
- putchar('"');
- for (i=0; i<n; i++)
- {
- int c=s[i];
- switch (c)
- {
- case '"': printf("\\\""); break;
- case '\\': printf("\\\\"); break;
- case '\a': printf("\\a"); break;
- case '\b': printf("\\b"); break;
- case '\f': printf("\\f"); break;
- case '\n': printf("\\n"); break;
- case '\r': printf("\\r"); break;
- case '\t': printf("\\t"); break;
- case '\v': printf("\\v"); break;
- default: if (isprint((unsigned char)c))
- putchar(c);
- else
- printf("\\%03u",(unsigned char)c);
- }
- }
- putchar('"');
-}
-
-static void PrintConstant(const Proto* f, int i)
-{
- const TValue* o=&f->k[i];
- switch (ttype(o))
- {
- case LUA_TNIL:
- printf("nil");
- break;
- case LUA_TBOOLEAN:
- printf(bvalue(o) ? "true" : "false");
- break;
- case LUA_TNUMBER:
- printf(LUA_NUMBER_FMT,nvalue(o));
- break;
- case LUA_TSTRING:
- PrintString(rawtsvalue(o));
- break;
- default: /* cannot happen */
- printf("? type=%d",ttype(o));
- break;
- }
-}
-
-static void PrintCode(const Proto* f)
-{
- const Instruction* code=f->code;
- int pc,n=f->sizecode;
- for (pc=0; pc<n; pc++)
- {
- Instruction i=code[pc];
- OpCode o=GET_OPCODE(i);
- int a=GETARG_A(i);
- int b=GETARG_B(i);
- int c=GETARG_C(i);
- int bx=GETARG_Bx(i);
- int sbx=GETARG_sBx(i);
- int line=getline(f,pc);
- printf("\t%d\t",pc+1);
- if (line>0) printf("[%d]\t",line); else printf("[-]\t");
- printf("%-9s\t",luaP_opnames[o]);
- switch (getOpMode(o))
- {
- case iABC:
- printf("%d",a);
- if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b);
- if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c);
- break;
- case iABx:
- if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx);
- break;
- case iAsBx:
- if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx);
- break;
- }
- switch (o)
- {
- case OP_LOADK:
- printf("\t; "); PrintConstant(f,bx);
- break;
- case OP_GETUPVAL:
- case OP_SETUPVAL:
- printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-");
- break;
- case OP_GETGLOBAL:
- case OP_SETGLOBAL:
- printf("\t; %s",svalue(&f->k[bx]));
- break;
- case OP_GETTABLE:
- case OP_SELF:
- if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
- break;
- case OP_SETTABLE:
- case OP_ADD:
- case OP_SUB:
- case OP_MUL:
- case OP_DIV:
- case OP_POW:
- case OP_EQ:
- case OP_LT:
- case OP_LE:
- if (ISK(b) || ISK(c))
- {
- printf("\t; ");
- if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
- printf(" ");
- if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
- }
- break;
- case OP_JMP:
- case OP_FORLOOP:
- case OP_FORPREP:
- printf("\t; to %d",sbx+pc+2);
- break;
- case OP_CLOSURE:
- printf("\t; %p",VOID(f->p[bx]));
- break;
- case OP_SETLIST:
- if (c==0) printf("\t; %d",(int)code[++pc]);
- else printf("\t; %d",c);
- break;
- default:
- break;
- }
- printf("\n");
- }
-}
-
-#define SS(x) (x==1)?"":"s"
-#define S(x) x,SS(x)
-
-static void PrintHeader(const Proto* f)
-{
- const char* s=getstr(f->source);
- if (*s=='@' || *s=='=')
- s++;
- else if (*s==LUA_SIGNATURE[0])
- s="(bstring)";
- else
- s="(string)";
- printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n",
- (f->linedefined==0)?"main":"function",s,
- f->linedefined,f->lastlinedefined,
- S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f));
- printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
- f->numparams,f->is_vararg?"+":"",SS(f->numparams),
- S(f->maxstacksize),S(f->nups));
- printf("%d local%s, %d constant%s, %d function%s\n",
- S(f->sizelocvars),S(f->sizek),S(f->sizep));
-}
-
-static void PrintConstants(const Proto* f)
-{
- int i,n=f->sizek;
- printf("constants (%d) for %p:\n",n,VOID(f));
- for (i=0; i<n; i++)
- {
- printf("\t%d\t",i+1);
- PrintConstant(f,i);
- printf("\n");
- }
-}
-
-static void PrintLocals(const Proto* f)
-{
- int i,n=f->sizelocvars;
- printf("locals (%d) for %p:\n",n,VOID(f));
- for (i=0; i<n; i++)
- {
- printf("\t%d\t%s\t%d\t%d\n",
- i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
- }
-}
-
-static void PrintUpvalues(const Proto* f)
-{
- int i,n=f->sizeupvalues;
- printf("upvalues (%d) for %p:\n",n,VOID(f));
- if (f->upvalues==NULL) return;
- for (i=0; i<n; i++)
- {
- printf("\t%d\t%s\n",i,getstr(f->upvalues[i]));
- }
-}
-
-void PrintFunction(const Proto* f, int full)
-{
- int i,n=f->sizep;
- PrintHeader(f);
- PrintCode(f);
- if (full)
- {
- PrintConstants(f);
- PrintLocals(f);
- PrintUpvalues(f);
- }
- for (i=0; i<n; i++) PrintFunction(f->p[i],full);
-}
diff --git a/engines/sword25/util/lua/scummvm_file.cpp b/engines/sword25/util/lua/scummvm_file.cpp
new file mode 100644
index 0000000000..3c0377d0ee
--- /dev/null
+++ b/engines/sword25/util/lua/scummvm_file.cpp
@@ -0,0 +1,205 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "sword25/util/lua/scummvm_file.h"
+#include "common/config-manager.h"
+#include "common/util.h"
+
+namespace Sword25 {
+
+Sword25FileProxy::Sword25FileProxy(const Common::String &filename, const Common::String &mode) {
+ assert(filename.contains("config.lua"));
+ if (mode == "r")
+ setupConfigFile();
+}
+
+void Sword25FileProxy::setupConfigFile() {
+ double sfxVolume = ConfMan.hasKey("sfx_volume") ? 1.0 : 1.0 * ConfMan.getInt("sfx_volume") / 255.0;
+ double musicVolume = ConfMan.hasKey("music_volume") ? 0.5 : 1.0 * ConfMan.getInt("music_volume") / 255.0;
+ double speechVolume = ConfMan.hasKey("speech_volume") ? 1.0 : 1.0 * ConfMan.getInt("speech_volume") / 255.0;
+ bool subtitles = ConfMan.hasKey("subtitles") ? true : ConfMan.getBool("subtitles");
+
+ _readData = Common::String::format(
+"GAME_LANGUAGE = \"%s\"\r\n\
+GAME_SUBTITLES = %s\r\n\
+MAX_MEMORY_USAGE = 256000000\r\n\
+GFX_VSYNC_ACTIVE = true\r\n\
+SFX_SAMPLING_RATE = 44100\r\n\
+SFX_CHANNEL_COUNT = 32\r\n\
+SFX_SOUND_VOLUME = %f\r\n\
+SFX_MUSIC_VOLUME = %f\r\n\
+SFX_SPEECH_VOLUME = %f\r\n",
+ getLanguage().c_str(), subtitles ? "true" : "false", sfxVolume, musicVolume, speechVolume);
+
+ _readPos = 0;
+}
+
+Sword25FileProxy::~Sword25FileProxy() {
+ if (!_settings.empty())
+ writeSettings();
+}
+
+size_t Sword25FileProxy::read(void *ptr, size_t size, size_t count) {
+ size_t bytesRead = MIN<size_t>(_readData.size() - _readPos, size * count);
+ memmove(ptr, &_readData.c_str()[_readPos], bytesRead);
+ _readPos += bytesRead;
+ return bytesRead / size;
+}
+
+size_t Sword25FileProxy::write(const char *ptr, size_t count) {
+ // Loop through the provided line(s)
+ while (*ptr) {
+ if ((*ptr == '-') && (*(ptr + 1) == '-')) {
+ // Comment line to skip over
+ while ((*ptr != '\r') && (*ptr != '\n'))
+ ++ptr;
+ } else {
+ // Legitimate data
+ const char *p = strchr(ptr, '\n');
+ if (!p) p = ptr + strlen(ptr);
+ while ((*p == '\r') || (*p == '\n'))
+ ++p;
+
+ _settings += Common::String(ptr, p - ptr);
+ ptr = p;
+ }
+
+ while ((*ptr == '\r') || (*ptr == '\n'))
+ ++ptr;
+ }
+
+ return count;
+}
+
+void Sword25FileProxy::writeSettings() {
+ // Loop through the setting lines
+ const char *pSrc = _settings.c_str();
+ while (*pSrc) {
+ if ((*pSrc != '\r') && (*pSrc != '\n')) {
+ const char *p = strchr(pSrc, '=');
+ assert(p);
+
+ // Get the setting name
+ const char *pEnd = p - 1;
+ while (*pEnd == ' ')
+ --pEnd;
+ Common::String settingName(pSrc, pEnd - pSrc + 1);
+
+ // Get the setting value
+ const char *pStart = p + 1;
+ while (*pStart == ' ')
+ ++pStart;
+
+ pEnd = pStart + 1;
+ while ((*pEnd != '\r') && (*pEnd != '\n') && (*pEnd != '\0'))
+ ++pEnd;
+ Common::String value(pStart + (*pStart == '"' ? 1 : 0), pEnd - pStart - (*pStart == '"' ? 2 : 0));
+
+ // Update the setting
+ updateSetting(settingName, value);
+ pSrc = pEnd;
+ }
+
+ // Move to next line
+ while ((*pSrc == '\r') || (*pSrc == '\n'))
+ ++pSrc;
+ }
+
+ ConfMan.flushToDisk();
+}
+
+void Sword25FileProxy::updateSetting(const Common::String &setting, const Common::String &value) {
+ if (setting == "GAME_LANGUAGE")
+ setLanguage(value);
+ else if (setting == "GAME_SUBTITLES")
+ ConfMan.setBool("subtitles", value == "true");
+ else if (setting == "SFX_SOUND_VOLUME") {
+ double v = strtod(value.c_str(), NULL);
+ ConfMan.setInt("sfx_volume", (int)(v * 255));
+ } else if (setting == "SFX_MUSIC_VOLUME") {
+ double v = strtod(value.c_str(), NULL);
+ ConfMan.setInt("music_volume", (int)(v * 255));
+ } else if (setting == "SFX_SPEECH_VOLUME") {
+ double v = strtod(value.c_str(), NULL);
+ ConfMan.setInt("speech_volume", (int)(v * 255));
+ } else {
+ // All other settings are ignored
+ }
+}
+
+/**
+ * Get the language code used by the game for each language it supports
+ */
+Common::String Sword25FileProxy::getLanguage() {
+ Common::Language lang = Common::parseLanguage(ConfMan.get("language"));
+ switch (lang) {
+ case Common::EN_ANY:
+ return "en";
+ case Common::DE_DEU:
+ return "de";
+ case Common::ES_ESP:
+ return "es";
+ case Common::FR_FRA:
+ return "fr";
+ case Common::HU_HUN:
+ return "hr";
+ case Common::IT_ITA:
+ return "it";
+ case Common::PL_POL:
+ return "pl";
+ case Common::PT_BRA:
+ return "pt";
+ case Common::RU_RUS:
+ return "ru";
+ default:
+ error("Unknown language '%s' encountered", ConfMan.get("language").c_str());
+ break;
+ }
+}
+
+/**
+ * Set the language code fro the game
+ */
+void Sword25FileProxy::setLanguage(const Common::String &lang) {
+ if (lang == "en")
+ ConfMan.set("language", Common::getLanguageCode(Common::EN_ANY));
+ else if (lang == "de")
+ ConfMan.set("language", Common::getLanguageCode(Common::DE_DEU));
+ else if (lang == "es")
+ ConfMan.set("language", Common::getLanguageCode(Common::ES_ESP));
+ else if (lang == "fr")
+ ConfMan.set("language", Common::getLanguageCode(Common::FR_FRA));
+ else if (lang == "hr")
+ ConfMan.set("language", Common::getLanguageCode(Common::HU_HUN));
+ else if (lang == "it")
+ ConfMan.set("language", Common::getLanguageCode(Common::IT_ITA));
+ else if (lang == "pl")
+ ConfMan.set("language", Common::getLanguageCode(Common::PL_POL));
+ else if (lang == "pt")
+ ConfMan.set("language", Common::getLanguageCode(Common::PT_BRA));
+ else if (lang == "ru")
+ ConfMan.set("language", Common::getLanguageCode(Common::RU_RUS));
+ else
+ error("Unknown language encountered");
+}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/util/lua/scummvm_file.h b/engines/sword25/util/lua/scummvm_file.h
new file mode 100644
index 0000000000..a4cbd2a6cf
--- /dev/null
+++ b/engines/sword25/util/lua/scummvm_file.h
@@ -0,0 +1,56 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SWORD25_SCUMMVM_FILE_H
+#define SWORD25_SCUMMVM_FILE_H
+
+#include "common/str.h"
+
+namespace Sword25 {
+
+/**
+ * The following class acts as a proxy interface to the I/O code, pretending that the ScummVM
+ * settings are a properly formatted 'config.lua' file
+ */
+class Sword25FileProxy {
+private:
+ Common::String _readData;
+ uint _readPos;
+ Common::String _settings;
+
+ void setupConfigFile();
+ Common::String getLanguage();
+ void setLanguage(const Common::String &lang);
+ void writeSettings();
+ void updateSetting(const Common::String &setting, const Common::String &value);
+public:
+ Sword25FileProxy(const Common::String &filename, const Common::String &mode);
+ ~Sword25FileProxy();
+
+ bool eof() const { return _readPos >= _readData.size(); }
+ size_t read(void *ptr, size_t size, size_t count);
+ size_t write(const char *ptr, size_t count);
+};
+
+} // End of namespace Sword25
+
+#endif