diff options
author | Matthew Hoops | 2011-05-31 14:16:29 -0400 |
---|---|---|
committer | Matthew Hoops | 2011-05-31 14:16:29 -0400 |
commit | aa49b38c5a8032586cb94fc4ca07149eecabe64a (patch) | |
tree | ea5c7617f8c482c8cf4141b728b3ccff5a7f84c7 /engines/sword25/util/lua | |
parent | d3ea9ab2a9334747eb445c1b45aa30cb17ffdf1b (diff) | |
parent | c86a6c466fabe31fbf36363aa8d0ac8ea6001b9f (diff) | |
download | scummvm-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.cpp | 16 | ||||
-rw-r--r-- | engines/sword25/util/lua/lauxlib.cpp | 50 | ||||
-rw-r--r-- | engines/sword25/util/lua/ldo.cpp | 30 | ||||
-rw-r--r-- | engines/sword25/util/lua/ldump.cpp | 164 | ||||
-rw-r--r-- | engines/sword25/util/lua/liolib.cpp | 222 | ||||
-rw-r--r-- | engines/sword25/util/lua/llex.cpp | 20 | ||||
-rw-r--r-- | engines/sword25/util/lua/lmathlib.cpp | 4 | ||||
-rw-r--r-- | engines/sword25/util/lua/loadlib.cpp | 197 | ||||
-rw-r--r-- | engines/sword25/util/lua/loslib.cpp | 77 | ||||
-rw-r--r-- | engines/sword25/util/lua/lua.h | 2 | ||||
-rw-r--r-- | engines/sword25/util/lua/luaconf.h | 35 | ||||
-rw-r--r-- | engines/sword25/util/lua/lundump.cpp | 225 | ||||
-rw-r--r-- | engines/sword25/util/lua/lundump.h | 36 | ||||
-rw-r--r-- | engines/sword25/util/lua/lvm.cpp | 2 | ||||
-rw-r--r-- | engines/sword25/util/lua/print.cpp | 227 | ||||
-rw-r--r-- | engines/sword25/util/lua/scummvm_file.cpp | 205 | ||||
-rw-r--r-- | engines/sword25/util/lua/scummvm_file.h | 56 |
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 |