summaryrefslogtreecommitdiff
path: root/lib/luacd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/luacd.cpp')
-rw-r--r--lib/luacd.cpp371
1 files changed, 371 insertions, 0 deletions
diff --git a/lib/luacd.cpp b/lib/luacd.cpp
new file mode 100644
index 0000000..9d8f6df
--- /dev/null
+++ b/lib/luacd.cpp
@@ -0,0 +1,371 @@
+/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 2002-2003 Nicolas "Pixel" Noble
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: luacd.cpp,v 1.1 2003-12-06 04:26:17 pixel Exp $ */
+
+#include "luacd.h"
+
+Luacdfile::Luacdfile(cdfile * h) : LuaHandle(h) { }
+Luacdutils::Luacdutils(cdutils * _cd) : cd(_cd) { }
+Luadirentry::Luadirentry(cdutils::DirEntry * _dir) : dir(_dir) { }
+
+enum {
+ LUA_ANY = 0,
+ LUA_OBJECT,
+ LUA_TABLE,
+ LUA_BOOLEAN,
+ LUA_NUMBER,
+ LUA_STRING,
+ LUA_FUNCTION,
+};
+
+enum {
+ CDUTILS_GUESSTYPE = 0,
+ CDUTILS_SECTORSEEK,
+ CDUTILS_READSECTOR,
+ CDUTILS_READDATAS,
+ CDUTILS_READFILE,
+ CDUTILS_WRITESECTOR,
+ CDUTILS_WRITEDATAS,
+ CDUTILS_WRITEFILE,
+ CDUTILS_GETISOINFOS,
+ CDUTILS_GETPTINFOS,
+ CDUTILS_FINDPATH,
+ CDUTILS_FINDPARENT,
+ CDUTILS_FINDDIRENTRY,
+};
+
+struct functypes_t {
+ int number;
+ char * name;
+ int minargs, maxargs;
+ int argtypes[32];
+};
+
+struct functypes_t cdfunctions[] = {
+ { CDUTILS_GUESSTYPE, "cdutils::guesstype", 0, 1, {LUA_NUMBER} },
+ { CDUTILS_SECTORSEEK, "cdutils::sectorseek", 1, 1, {LUA_NUMBER} },
+ { CDUTILS_READSECTOR, "cdutils::readsector", 0, 2, {LUA_NUMBER, LUA_NUMBER} },
+ { CDUTILS_READDATAS, "cdutils::readdatas", 3, 3, {LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
+ { CDUTILS_READFILE, "cdutils::readfile", 4, 4, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
+ { CDUTILS_WRITESECTOR, "cdutils::writesector", 1, 3, {LUA_TABLE, LUA_NUMBER, LUA_NUMBER} },
+ { CDUTILS_WRITEDATAS, "cdutils::writedatas", 4, 4, {LUA_TABLE, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
+ { CDUTILS_WRITEFILE, "cdutils::writefile", 1, 3, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER} },
+ { CDUTILS_GETISOINFOS, "cdutils::getisoinfos", 0, 0, 0 },
+ { CDUTILS_GETPTINFOS, "cdutils::getptinfos", 0, 0, 0 },
+ { CDUTILS_FINDPATH, "cdutils::findpath", 1, 1, {LUA_STRING} },
+ { CDUTILS_FINDPARENT, "cdutils::findparent", 1, 1, {LUA_STRING} },
+ { CDUTILS_FINDDIRENTRY, "cdutils::finddirentry", 2, 2, {LUA_OBJECT, LUA_STRING} },
+};
+
+#define DECLARE_FUNC(enumvar) static int method_##enumvar(lua_State * L) { return multiplex(enumvar, L); }
+#define PUSH_FUNC(enumvar) pushit(L, cdfunctions[enumvar].name, sLuacd::method_##enumvar)
+
+class sLuacd : public Base {
+ public:
+ static int newcdfile(lua_State * L);
+ static int newcdutils(lua_State * L);
+
+ DECLARE_FUNC(CDUTILS_GUESSTYPE);
+ DECLARE_FUNC(CDUTILS_SECTORSEEK);
+ DECLARE_FUNC(CDUTILS_READSECTOR);
+ DECLARE_FUNC(CDUTILS_READDATAS);
+ DECLARE_FUNC(CDUTILS_READFILE);
+ DECLARE_FUNC(CDUTILS_WRITESECTOR);
+ DECLARE_FUNC(CDUTILS_WRITEDATAS);
+ DECLARE_FUNC(CDUTILS_WRITEFILE);
+ DECLARE_FUNC(CDUTILS_GETISOINFOS);
+ DECLARE_FUNC(CDUTILS_GETPTINFOS);
+ DECLARE_FUNC(CDUTILS_FINDPATH);
+ DECLARE_FUNC(CDUTILS_FINDPARENT);
+ DECLARE_FUNC(CDUTILS_FINDDIRENTRY);
+
+ private:
+ static int multiplex(int caller, lua_State * L);
+ static int proceed(Lua * L, int n, void * obj, int caller);
+};
+
+void Luacdfile::pushconstruct(Lua * L) {
+ L->declarefunc("cdfile", sLuacd::newcdfile);
+}
+
+void Luacdutils::pushconstruct(Lua * L) {
+ L->declarefunc("cdutils", sLuacd::newcdutils);
+}
+
+int sLuacd::newcdfile(lua_State * _L) {
+ /***TODO***/
+ /* Creation of a 'cdfile' from within lua. */
+
+ return 0;
+}
+
+int sLuacd::newcdutils(lua_State * _L) {
+ /***TODO***/
+ /* Creation of a 'cdutils' from within lua. */
+
+ return 0;
+}
+
+int sLuacd::multiplex(int caller, lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop() - 1;
+ void * obj = LuaObject::getme(L);
+ int i;
+ bool invalid = false;
+
+ if ((n < cdfunctions[caller].minargs) || (n > cdfunctions[caller].maxargs)) {
+ invalid = true;
+ } else {
+ for (i = 0; i < cdfunctions[caller].maxargs && !invalid; i++) {
+ if (n >= (i + 1)) {
+ switch(cdfunctions[caller].argtypes[i]) {
+ case LUA_ANY:
+ break;
+ case LUA_OBJECT:
+ invalid = !L->istable(i + 2);
+ if (!invalid) {
+ L->push("__obj");
+ L->gettable(i + 2);
+ invalid = L->islightuserdata();
+ L->pop();
+ }
+ break;
+ case LUA_TABLE:
+ invalid = !L->istable(i + 2);
+ break;
+ case LUA_BOOLEAN:
+ invalid = !L->isboolean(i + 2);
+ break;
+ case LUA_NUMBER:
+ invalid = !L->isnumber(i + 2);
+ break;
+ case LUA_STRING:
+ invalid = !L->isstring(i + 2);
+ break;
+ case LUA_FUNCTION:
+ invalid = !L->isfunction(i + 2);
+ break;
+ }
+ }
+ }
+ }
+
+ if (invalid) {
+ L->error(String("Invalid arguments to method `") + cdfunctions[caller].name + "'");
+ }
+
+ return proceed(L, n, obj, caller);
+}
+
+int sLuacd::proceed(Lua * L, int n, void * obj, int caller) {
+ int r = 0, sect = -1, mode = GUESS, size, i;
+ Handle * h;
+ Byte sdatas[2352], * datas;
+ String path;
+
+ cdutils * cd = (cdutils *) obj;
+ cdutils::DirEntry * dir = (cdutils::DirEntry *) obj, * bdir, * adir;
+
+ switch(caller) {
+ case CDUTILS_GUESSTYPE:
+ if (n == 1) {
+ sect = L->tonumber();
+ }
+ L->push((lua_Number) cd->guess_type(sect));
+ r = 1;
+ break;
+ case CDUTILS_SECTORSEEK:
+ sect = L->tonumber();
+ cd->sector_seek(sect);
+ break;
+ case CDUTILS_READSECTOR:
+ if (n >= 1)
+ mode = L->tonumber(2);
+ if (n == 2)
+ sect = L->tonumber(3);
+ size = cd->read_sector(sdatas, mode, sect);
+ L->newtable();
+ for (i = 0; i < size; i++) {
+ L->push((lua_Number) i);
+ L->push((lua_Number) sdatas[i]);
+ L->settable();
+ }
+ r = 1;
+ break;
+ case CDUTILS_READDATAS:
+ mode = L->tonumber(2);
+ sect = L->tonumber(3);
+ size = L->tonumber(4);
+ datas = (Byte *) malloc(size);
+ cd->read_datas(datas, mode, sect, size);
+ L->newtable();
+ for (i = 0; i < size; i++) {
+ L->push((lua_Number) i);
+ L->push((lua_Number) datas[i]);
+ L->settable();
+ }
+ r = 1;
+ free(datas);
+ break;
+ case CDUTILS_READFILE:
+ h = (Handle *) LuaObject::getme(L, 2);
+ mode = L->tonumber(3);
+ sect = L->tonumber(4);
+ size = L->tonumber(5);
+ cd->read_file(h, mode, sect, size);
+ break;
+ case CDUTILS_WRITESECTOR:
+ if (n >= 2)
+ mode = L->tonumber(3);
+ if (n == 3)
+ sect = L->tonumber(4);
+ for (i = 0; i < 2352; i++) {
+ L->push((lua_Number) i);
+ L->gettable(2);
+ sdatas[i] = L->tonumber();
+ L->pop();
+ }
+ cd->write_sector(datas, mode, sect);
+ break;
+ case CDUTILS_WRITEDATAS:
+ mode = L->tonumber(3);
+ sect = L->tonumber(4);
+ size = L->tonumber(5);
+ datas = (Byte *) malloc(size);
+
+ for (i = 0; i < size; i++) {
+ L->push((lua_Number) i);
+ L->gettable(2);
+ sdatas[i] = L->tonumber();
+ L->pop();
+ }
+ cd->write_datas(datas, mode, sect, size);
+ free(datas);
+ break;
+ case CDUTILS_WRITEFILE:
+ h = (Handle *) LuaObject::getme(L, 2);
+ if (n >= 2)
+ mode = L->tonumber(3);
+ if (n == 3)
+ sect = L->tonumber(4);
+ cd->write_file(h, mode, sect);
+ break;
+ case CDUTILS_GETISOINFOS:
+ L->push((lua_Number) cd->get_iso_infos());
+ r = 1;
+ break;
+ case CDUTILS_GETPTINFOS:
+ L->push((lua_Number) cd->get_pt_infos());
+ r = 1;
+ break;
+ case CDUTILS_FINDPATH:
+ path = L->tostring(2);
+ bdir = cd->find_path(&datas, path);
+ dir = (cdutils::DirEntry *) malloc(bdir->R);
+ memcpy(dir, bdir, bdir->R);
+ {
+ Luadirentry ldir(dir);
+ ldir.pushdestruct(L);
+ }
+ r = 1;
+ free(datas);
+ break;
+ case CDUTILS_FINDPARENT:
+ path = L->tostring(2);
+ bdir = cd->find_parent(&datas, path);
+ dir = (cdutils::DirEntry *) malloc(bdir->R);
+ memcpy(dir, bdir, bdir->R);
+ {
+ Luadirentry ldir(dir);
+ ldir.pushdestruct(L);
+ }
+ r = 1;
+ free(datas);
+ break;
+ case CDUTILS_FINDDIRENTRY:
+ adir = (cdutils::DirEntry *) LuaObject::getme(L, 2);
+ path = L->tostring(3);
+ bdir = cd->find_dir_entry(&datas, adir, path);
+ dir = (cdutils::DirEntry *) malloc(bdir->R);
+ memcpy(dir, bdir, bdir->R);
+ {
+ Luadirentry ldir(dir);
+ ldir.pushdestruct(L);
+ }
+ r = 1;
+ free(datas);
+ break;
+ }
+ return r;
+}
+
+void Luacdfile::pushmembers(Lua * L) {
+ LuaHandle::pushmembers(L);
+}
+
+void Luacdutils::pushmembers(Lua * L) {
+ pushme(L, cd);
+
+ PUSH_FUNC(CDUTILS_GUESSTYPE);
+ PUSH_FUNC(CDUTILS_SECTORSEEK);
+ PUSH_FUNC(CDUTILS_READSECTOR);
+ PUSH_FUNC(CDUTILS_READDATAS);
+ PUSH_FUNC(CDUTILS_READFILE);
+ PUSH_FUNC(CDUTILS_WRITESECTOR);
+ PUSH_FUNC(CDUTILS_WRITEDATAS);
+ PUSH_FUNC(CDUTILS_WRITEFILE);
+ PUSH_FUNC(CDUTILS_GETISOINFOS);
+ PUSH_FUNC(CDUTILS_GETPTINFOS);
+ PUSH_FUNC(CDUTILS_FINDPATH);
+ PUSH_FUNC(CDUTILS_FINDPARENT);
+ PUSH_FUNC(CDUTILS_FINDDIRENTRY);
+
+ L->push("MODE0");
+ L->push((lua_Number) MODE0);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("MODE1");
+ L->push((lua_Number) MODE1);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("MODE2");
+ L->push((lua_Number) MODE2);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("MODE2_FORM1");
+ L->push((lua_Number) MODE2_FORM1);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("MODE2_FORM2");
+ L->push((lua_Number) MODE2_FORM2);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("MORE_RAW");
+ L->push((lua_Number) MODE_RAW);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("GUESS");
+ L->push((lua_Number) GUESS);
+ L->settable(LUA_GLOBALSINDEX);
+}
+
+void Luadirentry::pushmembers(Lua * L) {
+ pushme(L, dir);
+}