From 845451a49fe822f4ccbf221e9b56889d5386713d Mon Sep 17 00:00:00 2001 From: pixel Date: Sat, 6 Dec 2003 04:26:15 +0000 Subject: Having LUA now in cd-tool! Yay! --- lib/luacd.cpp | 371 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 371 insertions(+) create mode 100644 lib/luacd.cpp (limited to 'lib/luacd.cpp') 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); +} -- cgit v1.2.3