From 0b266c95523f944e62acf9251eb27450a8d73a04 Mon Sep 17 00:00:00 2001
From: pixel <pixel>
Date: Mon, 8 Dec 2003 15:12:56 +0000
Subject: LUA everywhere! Wheee!

---
 cd-tool.cpp           |    6 +-
 includes/isobuilder.h |   15 +-
 includes/luacd.h      |   49 ++-
 lib/cdutils.cpp       |   18 +-
 lib/isobuilder.cpp    |   37 +-
 lib/luacd.cpp         | 1113 +++++++++++++++++++++++++++++++++++++++++++++++--
 6 files changed, 1190 insertions(+), 48 deletions(-)

diff --git a/cd-tool.cpp b/cd-tool.cpp
index fd123a2..4cf9588 100644
--- a/cd-tool.cpp
+++ b/cd-tool.cpp
@@ -17,7 +17,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/* $Id: cd-tool.cpp,v 1.17 2003-12-07 04:44:38 pixel Exp $ */
+/* $Id: cd-tool.cpp,v 1.18 2003-12-08 15:12:56 pixel Exp $ */
 
 #include <getopt.h>
 #include <stdio.h>
@@ -343,8 +343,7 @@ virtual int startup() throw (GeneralException) {
         LuaInput::pushconstruct(L);
         LuaOutput::pushconstruct(L);
         LuaBuffer::pushconstruct(L);
-        Luacdutils::pushstatics(L);
-        Luacdfile::pushstatics(L);
+        CD_PUSHSTATICS(L);
         L->push("print");
         L->push(myprint);
         L->settable(LUA_GLOBALSINDEX);
@@ -353,7 +352,6 @@ virtual int startup() throw (GeneralException) {
         lcdutil.push(L);
         L->settable(LUA_GLOBALSINDEX);
         L->load(&Input(arg1));
-        getchar();
     } else {
 	showhelp();
 	printm(M_ERROR, "Command %s unknow.\n", argv[optind]);
diff --git a/includes/isobuilder.h b/includes/isobuilder.h
index e8cba8e..96bb9d9 100644
--- a/includes/isobuilder.h
+++ b/includes/isobuilder.h
@@ -17,7 +17,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/* $Id: isobuilder.h,v 1.5 2003-12-04 03:40:38 pixel Exp $ */
+/* $Id: isobuilder.h,v 1.6 2003-12-08 15:12:57 pixel Exp $ */
 
 #ifndef __ISOBUILDER_H__
 #define __ISOBUILDER_H__
@@ -70,18 +70,19 @@ class isobuilder : public Base {
     };
       isobuilder(Handle * w, int mode = MODE2_FORM1);
       ~isobuilder();
+    void foreword(cdutils *);
     void foreword(Handle * forewords, int mode = MODE_RAW);
     void foreword(Byte * forewords, int mode = MODE_RAW);
     int getdispsect();
-    int putfile(Handle * file, int mode = -1, int n = -1);
-    void putdatas(Byte * datas, size_t size, int mode = -1, int n = -1);
-    void createsector(Byte * datas, int type = -1, int n = -1);
+    int putfile(Handle * file, int mode = -1, int sector = -1);
+    int putdatas(Byte * datas, size_t size, int mode = -1, int sector = -1);
+    int createsector(Byte * datas, int mode = -1, int sector = -1);
     void setEOF();
     void clearEOF();
     DirTree * setbasics(PVD pvd, int rootsize = 1, int ptsize = 1, int nvd = 1, int rootsect = -1) throw (GeneralException);
-    DirTree * createdir(DirTree *, const String & _name, int size = 1, cdutils::DirEntry * = 0, int mode = MODE2_FORM1) throw (GeneralException);
-    DirTree * createfile(DirTree *, Handle * file, const String & _name, cdutils::DirEntry * = 0, int mode = MODE2_FORM1) throw (GeneralException);
-    void copydir(DirTree *, const String & _name, cdutils *, cdutils::DirEntry *, int mode = MODE2_FORM1);
+    DirTree * createdir(DirTree *, const String & _name, int size = 1, cdutils::DirEntry * = 0, int mode = -1) throw (GeneralException);
+    DirTree * createfile(DirTree *, Handle * file, const String & _name, cdutils::DirEntry * = 0, int mode = -1) throw (GeneralException);
+    void copydir(DirTree *, const String & _name, cdutils *, cdutils::DirEntry *, int mode = -1);
     static PVD createpvd(Handle *);
     static PVD createpvd(cdutils *);
     static PVD createpvd(Byte *);
diff --git a/includes/luacd.h b/includes/luacd.h
index f32eadd..2c66d96 100644
--- a/includes/luacd.h
+++ b/includes/luacd.h
@@ -17,7 +17,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/* $Id: luacd.h,v 1.2 2003-12-07 04:44:38 pixel Exp $ */
+/* $Id: luacd.h,v 1.3 2003-12-08 15:12:57 pixel Exp $ */
 
 #ifndef __LUACD_H__
 #define __LUACD_H__
@@ -26,10 +26,19 @@
 #include <BLua.h>
 #include <LuaHandle.h>
 #include <cdutils.h>
+#include <isobuilder.h>
+
+#define CD_PUSHSTATICS(L) { \
+    Luacdutils::pushstatics(L); \
+    Luacdfile::pushstatics(L); \
+    LuaPVD::pushstatics(L); \
+    LuaDirTree::pushstatics(L); \
+    Luaisobuilder::pushstatics(L); \
+}
 
 class Luacdutils : public LuaObject {
   public:
-    static void pushstatics(Lua *);
+    static void pushstatics(Lua *) throw (GeneralException);
       Luacdutils(cdutils *);
   protected:
     virtual void pushmembers(Lua *);
@@ -47,10 +56,44 @@ class Luacdfile : public LuaHandle {
 class Luadirentry : public LuaObject {
   public:
       Luadirentry(cdutils::DirEntry *);
-    const cdutils::DirEntry * getdir();
   protected:
     virtual void pushmembers(Lua *);
     cdutils::DirEntry * dir;
 };
 
+class Luacddate : public LuaObject {
+  public:
+      Luacddate(isobuilder::Date *);
+  private:
+    virtual void pushmembers(Lua *);
+    struct isobuilder::Date * date;
+};
+
+class LuaPVD : public LuaObject {
+  public:
+    static void pushstatics(Lua *) throw (GeneralException);
+      LuaPVD(struct isobuilder::PVD *);
+  private:
+    virtual void pushmembers(Lua *);
+    struct isobuilder::PVD * pvd;
+};
+
+class LuaDirTree : public LuaObject {
+  public:
+    static void pushstatics(Lua *) throw (GeneralException);
+      LuaDirTree(isobuilder::DirTree *);
+  private:
+    virtual void pushmembers(Lua *);
+    isobuilder::DirTree * dir;
+};
+
+class Luaisobuilder : public LuaObject {
+  public:
+    static void pushstatics(Lua *) throw (GeneralException);
+      Luaisobuilder(isobuilder *);
+  private:
+    virtual void pushmembers(Lua *);
+    isobuilder * iso;
+};
+
 #endif
diff --git a/lib/cdutils.cpp b/lib/cdutils.cpp
index b3468e7..ba830f6 100644
--- a/lib/cdutils.cpp
+++ b/lib/cdutils.cpp
@@ -17,7 +17,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/* $Id: cdutils.cpp,v 1.16 2003-12-04 00:57:35 pixel Exp $ */
+/* $Id: cdutils.cpp,v 1.17 2003-12-08 15:12:57 pixel Exp $ */
 
 #include <stdio.h>
 #include <string.h>
@@ -805,12 +805,22 @@ cdfile::cdfile(cdutils * _cd, const cdutils::DirEntry * d, int _mode) : Handle(-
 }
 
 cdfile::cdfile(cdutils * _cd, int _sector, ssize_t _size, int _mode) : Handle(-1), cd(_cd), sector(_sector), mode(_mode), size(_size), name("raw reading") {
-    if (_size == -1) {
-        size = 0;
-    }
+    Byte datas[2352];
+    bool eof;
+
     if (mode == GUESS) {
         mode = cd->guess_type(sector);
     }
+    if (_size == -1) {
+        size = 0;
+        if ((mode == MODE2_FORM1) || (mode == MODE2_FORM2)) {
+            do {
+                cd->read_sector(datas, MODE_RAW, sector + size++);
+                eof = datas[18] & 0x80;
+            } while (!eof);
+            size *= sec_sizes[mode];
+        }
+    }
     dir = 0;
     itell = 0;
 }
diff --git a/lib/isobuilder.cpp b/lib/isobuilder.cpp
index a25243c..85760d5 100644
--- a/lib/isobuilder.cpp
+++ b/lib/isobuilder.cpp
@@ -17,7 +17,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/* $Id: isobuilder.cpp,v 1.6 2003-12-06 04:26:17 pixel Exp $ */
+/* $Id: isobuilder.cpp,v 1.7 2003-12-08 15:12:57 pixel Exp $ */
 
 #include "isobuilder.h"
 
@@ -425,6 +425,14 @@ isobuilder::~isobuilder() {
         delete root;
 }
 
+void isobuilder::foreword(cdutils * cd) {
+    Byte sect[2352];
+    for (int i = 0; i < 16; i++) {
+        cd->read_sector(sect, MODE_RAW, i);
+        createsector(sect, MODE_RAW, i);
+    }
+}
+
 void isobuilder::foreword(Handle * forewords, int mode) {
     Byte sect[2352];
     for (int i = 0; i < 16; i++) {
@@ -474,15 +482,18 @@ int isobuilder::putfile(Handle * file, int mode, int n) {
     return fsect;
 }
 
-void isobuilder::putdatas(Byte * _datas, size_t size, int smode, int n) {
+int isobuilder::putdatas(Byte * _datas, size_t size, int smode, int n) {
     Byte datas[2352];
     size_t eating;
+    int dsect;
     if (n >= 0) {
         sector = n;
     } else {
         sector = lastdispsect;
     }
 
+    dsect = sector;
+
     if (smode < 0)
         smode = dmode;
 
@@ -501,16 +512,21 @@ void isobuilder::putdatas(Byte * _datas, size_t size, int smode, int n) {
         }
         createsector(datas, smode);
     }
+
+    return dsect;
 }
 
-void isobuilder::createsector(Byte * datas, int smode, int n) {
+int isobuilder::createsector(Byte * datas, int smode, int n) {
     Byte dsector[2352];
+    int rsector;
     if (n >= 0)
         sector = n;
 
     if (smode < 0)
         smode = dmode;
 
+    rsector = sector;
+
     w->seek(2352 * sector, SEEK_SET);
 
     memcpy(dsector + sec_offsts[smode], datas, sec_sizes[smode]);
@@ -539,6 +555,8 @@ void isobuilder::createsector(Byte * datas, int smode, int n) {
 
     nsectors = MAX(nsectors, sector);
     lastdispsect = MAX(lastdispsect, sector);
+
+    return rsector;
 }
 
 void isobuilder::setEOF() {
@@ -596,7 +614,10 @@ isobuilder::DirTree * isobuilder::createdir(DirTree * p, const String & _name, i
         r->name = _name;
     r->size = size * 2048;
     r->sector = lastdispsect;
-    r->mode = mode;
+    if (mode >= 0)
+        r->mode = mode;
+    else
+        r->mode = dmode;
 
     lastdispsect += size;
 
@@ -624,7 +645,10 @@ isobuilder::DirTree * isobuilder::createfile(DirTree * p, Handle * file, const S
         r->name = _name;
     r->size = file->GetSize();
     r->sector = putfile(file, mode);
-    r->mode = mode;
+    if (mode >= 0)
+        r->mode = mode;
+    else
+        r->mode = dmode;
 }
 
 void isobuilder::copydir(isobuilder::DirTree * r, const String & _name, cdutils * cd, cdutils::DirEntry * d, int mode) {
@@ -633,6 +657,9 @@ void isobuilder::copydir(isobuilder::DirTree * r, const String & _name, cdutils
     int nsectors = d->Size / 2048, ssize, c = 0;
     int fsize, osize;
 
+    if (mode < 0)
+        mode = dmode;
+
     r->fromdir(d);
     if (_name != "")
         r->name = _name;
diff --git a/lib/luacd.cpp b/lib/luacd.cpp
index bda2c10..47cb05b 100644
--- a/lib/luacd.cpp
+++ b/lib/luacd.cpp
@@ -17,14 +17,14 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/* $Id: luacd.cpp,v 1.2 2003-12-07 04:44:39 pixel Exp $ */
+/* $Id: luacd.cpp,v 1.3 2003-12-08 15:12:57 pixel Exp $ */
 
 #include "luacd.h"
 
 
-/****************************\
+ /**************************\
 |**  class cdutils exports **|
-\****************************/
+ \**************************/
 
 Luacdutils::Luacdutils(cdutils * _cd) : cd(_cd) { }
 
@@ -309,11 +309,17 @@ int sLua_cdutils::cdutils_proceed(Lua * L, int n, cdutils * cd, int caller) {
     case CDUTILS_FINDPATH:
         path = L->tostring(2);
         bdir = cd->find_path(&datas, path);
-        dir = (cdutils::DirEntry *) malloc(bdir->R);
-        memcpy(dir, bdir, bdir->R);
-        {
+        if ((bdir) && bdir->R) {
+            dir = (cdutils::DirEntry *) malloc(bdir->R);
+            memcpy(dir, bdir, bdir->R);
+        } else {
+            dir = 0;
+        }
+        if (dir) {
             Luadirentry ldir(dir);
             ldir.pushdestruct(L);
+        } else {
+            L->push();
         }
         r = 1;
         free(datas);
@@ -321,11 +327,17 @@ int sLua_cdutils::cdutils_proceed(Lua * L, int n, cdutils * cd, int caller) {
     case CDUTILS_FINDPARENT:
         path = L->tostring(2);
         bdir = cd->find_parent(&datas, path);
-        dir = (cdutils::DirEntry *) malloc(bdir->R);
-        memcpy(dir, bdir, bdir->R);
-        {
+        if ((bdir) && bdir->R) {
+            dir = (cdutils::DirEntry *) malloc(bdir->R);
+            memcpy(dir, bdir, bdir->R);
+        } else {
+            dir = 0;
+        }
+        if (dir) {
             Luadirentry ldir(dir);
             ldir.pushdestruct(L);
+        } else {
+            L->push();
         }
         r = 1;
         free(datas);
@@ -334,11 +346,17 @@ int sLua_cdutils::cdutils_proceed(Lua * L, int n, cdutils * cd, int caller) {
         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);
-        {
+        if ((bdir) && bdir->R) {
+            dir = (cdutils::DirEntry *) malloc(bdir->R);
+            memcpy(dir, bdir, bdir->R);
+        } else {
+            dir = 0;
+        }
+        if (dir) {
             Luadirentry ldir(dir);
             ldir.pushdestruct(L);
+        } else {
+            L->push();
         }
         r = 1;
         free(datas);
@@ -350,10 +368,19 @@ int sLua_cdutils::cdutils_proceed(Lua * L, int n, cdutils * cd, int caller) {
 int sLua_cdutils::cdutils_proceed_statics(Lua * L, int n, int caller) {
     int r = 0;
     Uint32 x;
+    Handle * isor = 0, * isow = 0;
+    Uint32 msf, start = 150;
+    Byte m, s, f;
 
     switch(caller) {
     case CDUTILS_NEWCDUTILS:
-        /***TODO***/
+        isor = (Handle *) LuaObject::getme(L, 1);
+        if (n == 2)
+            isow = (Handle *) LuaObject::getme(L, 2);
+        {
+            Luacdutils cd(new cdutils(isor, isow));
+            cd.pushdestruct(L);
+        }
         break;
     case CDUTILS_SWAPWORD:
         x = L->tonumber();
@@ -381,7 +408,20 @@ int sLua_cdutils::cdutils_proceed_statics(Lua * L, int n, int caller) {
         r = 1;
         break;
     case CDUTILS_FROM_MSF:
-        /***TODO***/
+        if (n <= 2) {
+            msf = L->tonumber(1);
+            if (n == 2)
+                start = L->tonumber(2);
+            L->push((lua_Number) cdutils::from_MSF(msf, start));
+        } else {
+            m = L->tonumber(1);
+            s = L->tonumber(2);
+            f = L->tonumber(3);
+            if (n == 4)
+                start = L->tonumber(4);
+            L->push((lua_Number) cdutils::from_MSF(m, s, f, start));
+        }
+        r = 1;
         break;
     }
 
@@ -389,9 +429,9 @@ int sLua_cdutils::cdutils_proceed_statics(Lua * L, int n, int caller) {
 }
 
 
-/***************************\
+ /*************************\
 |**  class cdfile exports **|
-\***************************/
+ \*************************/
 
 Luacdfile::Luacdfile(cdfile * h) : LuaHandle(h) { }
 
@@ -415,17 +455,53 @@ void Luacdfile::pushmembers(Lua * L) {
     LuaHandle::pushmembers(L);
 }
 
-void Luacdfile::pushstatics(Lua * L) {
+void Luacdfile::pushstatics(Lua * L) throw (GeneralException) {
     CHECK_FUNCTIONS(cdfile);
     PUSH_FUNCTION(cdfile, CDFILE_NEWCDFILE);
 }
 
 int sLua_cdfile::cdfile_proceed_statics(Lua * L, int n, int caller) {
     int r = 0;
+    bool invalid = false;
+    cdutils * cd;
+    cdutils::DirEntry * dir;
+    int sector, mode = GUESS;
+    ssize_t size = -1;
+    cdfile * cdf;
 
     switch(caller) {
     case CDFILE_NEWCDFILE:
-        /****TODO****/
+        cd = (cdutils *) LuaObject::getme(L, 1);
+        if (L->islightuserdata(2)) {
+            if (n <= 3) {
+                dir = (cdutils::DirEntry *) LuaObject::getme(L, 2);
+                if (n == 3)
+                    mode = L->tonumber(3);
+                cdf = new cdfile(cd, dir, mode);
+            } else {
+                invalid = true;
+            }
+        } else if (L->isnumber(2)) {
+            if (n >= 2) {
+                sector = L->tonumber(2);
+                if (n >= 3)
+                    size = L->tonumber(3);
+                if (n == 4)
+                    mode = L->tonumber(4);
+                cdf = new cdfile(cd, sector, size, mode);
+            } else {
+                invalid = true;
+            }
+        } else {
+            invalid = true;
+        }
+        if (invalid) {
+            L->error("Invalid arguments to constructor of cdutils");
+        } else {
+            Luacdfile luacdf(cdf);
+            luacdf.pushdestruct(L);
+            r = 1;
+        }
         break;
     }
 
@@ -433,23 +509,44 @@ int sLua_cdfile::cdfile_proceed_statics(Lua * L, int n, int caller) {
 }
 
 
-
-Luadirentry::Luadirentry(cdutils::DirEntry * _dir) : dir(_dir) { }
+ /***************************\
+|**  class direntry exports **|
+ \***************************/
 
 typedef cdutils::DirEntry direntry;
 
+Luadirentry::Luadirentry(cdutils::DirEntry * _dir) : dir(_dir) { }
+
 enum direntry_methods_t {
     DIRENTRY_INDEX = 0,
+    DIRENTRY_HASXA,
+    DIRENTRY_ISXADIR,
+    DIRENTRY_ISXAAUDIO,
+    DIRENTRY_ISXASTR,
+    DIRENTRY_ISXAXA,
+    DIRENTRY_ISXAFORM1,
 };
 
 struct lua_functypes_t direntry_methods[] = {
-    { DIRENTRY_INDEX, "index", 2, 2, {LUA_OBJECT, LUA_STRING} },
+    { DIRENTRY_INDEX,     "index",     1, 1, {LUA_STRING} },
+    { DIRENTRY_HASXA,     "hasxa",     0, 0, 0 },
+    { DIRENTRY_ISXADIR,   "isxadir",   0, 0, 0 },
+    { DIRENTRY_ISXAAUDIO, "isxaaudio", 0, 0, 0 },
+    { DIRENTRY_ISXASTR,   "isxastr",   0, 0, 0 },
+    { DIRENTRY_ISXAXA,    "isxaxa",    0, 0, 0 },
+    { DIRENTRY_ISXAFORM1, "isxaform1", 0, 0, 0 },
     { -1, 0, 0, 0, 0 }
 };
 
 class sLua_direntry : public Base {
   public:
-      DECLARE_METHOD(direntry, DIRENTRY_INDEX);
+    DECLARE_METHOD(direntry, DIRENTRY_INDEX);
+    DECLARE_METHOD(direntry, DIRENTRY_HASXA);
+    DECLARE_METHOD(direntry, DIRENTRY_ISXADIR);
+    DECLARE_METHOD(direntry, DIRENTRY_ISXAAUDIO);
+    DECLARE_METHOD(direntry, DIRENTRY_ISXASTR);
+    DECLARE_METHOD(direntry, DIRENTRY_ISXAXA);
+    DECLARE_METHOD(direntry, DIRENTRY_ISXAFORM1);
   private:
     static int direntry_proceed(Lua * L, int n, direntry * obj, int caller);
 };
@@ -458,13 +555,61 @@ void Luadirentry::pushmembers(Lua * L) {
     pushme(L, dir);
 
     PUSH_METAMETHOD(direntry, DIRENTRY_INDEX);
+    PUSH_METHOD(direntry, DIRENTRY_HASXA);
+    PUSH_METHOD(direntry, DIRENTRY_ISXADIR);
+    PUSH_METHOD(direntry, DIRENTRY_ISXAAUDIO);
+    PUSH_METHOD(direntry, DIRENTRY_ISXASTR);
+    PUSH_METHOD(direntry, DIRENTRY_ISXAXA);
+    PUSH_METHOD(direntry, DIRENTRY_ISXAFORM1);
 }
 
 int sLua_direntry::direntry_proceed(Lua * L, int n, direntry * dir, int caller) {
-    int r = 0;
+    int r = 0, s, pad;
     String index;
+    bool has_xa = false;
+    Byte * p;
+
+    s = 33 + dir->N;
+    if (s & 1) {
+        s++;
+        pad = 1;
+    } else {
+        pad = 0;
+    }
+    if (s != dir->R) {
+        if ((s + 14) == dir->R) {
+            p = (Byte *) dir->id + dir->N + pad;
+            if ((p[6] == 'X') && (p[7] == 'A')) {
+                has_xa = true;
+            }
+        }
+    }
 
     switch (caller) {
+    case DIRENTRY_HASXA:
+        L->push(has_xa);
+        r = 1;
+        break;
+    case DIRENTRY_ISXADIR:
+        L->push(p[4] & 0x80 ? true : false);
+        r = 1;
+        break;
+    case DIRENTRY_ISXAAUDIO:
+        L->push(p[4] & 0x40 ? true : false);
+        r = 1;
+        break;
+    case DIRENTRY_ISXASTR:
+        L->push(p[4] & 0x20 ? true : false);
+        r = 1;
+        break;
+    case DIRENTRY_ISXAXA:
+        L->push(p[4] & 0x10 ? true : false);
+        r = 1;
+        break;
+    case DIRENTRY_ISXAFORM1:
+        L->push(p[4] & 0x08 ? true : false);
+        r = 1;
+        break;
     case DIRENTRY_INDEX:
         index = L->tostring();
         r = 1;
@@ -513,6 +658,924 @@ int sLua_direntry::direntry_proceed(Lua * L, int n, direntry * dir, int caller)
     return r;
 }
 
-const cdutils::DirEntry * Luadirentry::getdir() {
-    return dir;
+
+ /***************************\
+|**  class direntry exports **|
+ \***************************/
+
+typedef isobuilder::Date cddate;
+
+Luacddate::Luacddate(isobuilder::Date * _date) : date(_date) { }
+
+enum cddate_methods_t {
+    CDDATE_INDEX = 0,
+    CDDATE_NEWINDEX,
+};
+
+struct lua_functypes_t cddate_methods[] = {
+    { CDDATE_INDEX,    "index",    1, 1, {LUA_STRING} },
+    { CDDATE_NEWINDEX, "newindex", 2, 2, {LUA_STRING, LUA_NUMBER} },
+    { -1, 0, 0, 0, 0 }
+};
+
+class sLua_cddate : public Base {
+  public:
+    DECLARE_METHOD(cddate, CDDATE_INDEX);
+    DECLARE_METHOD(cddate, CDDATE_NEWINDEX);
+  private:
+    static int cddate_proceed(Lua * L, int n, cddate * obj, int caller);
+};
+
+void Luacddate::pushmembers(Lua * L) {
+    pushme(L, date);
+
+    PUSH_METAMETHOD(cddate, CDDATE_INDEX);
+    PUSH_METAMETHOD(cddate, CDDATE_NEWINDEX);
+}
+
+int sLua_cddate::cddate_proceed(Lua * L, int n, cddate * date, int caller) {
+    int r, value;
+    String key;
+
+    switch (caller) {
+    case CDDATE_INDEX:
+        key = L->tostring(2);
+        r = 1;
+        if (key == "year") {
+            L->push((lua_Number) date->year);
+        } else if (key == "month") {
+            L->push((lua_Number) date->month);
+        } else if (key == "day") {
+            L->push((lua_Number) date->day);
+        } else if (key == "hour") {
+            L->push((lua_Number) date->hour);
+        } else if (key == "minute") {
+            L->push((lua_Number) date->minute);
+        } else if (key == "second") {
+            L->push((lua_Number) date->second);
+        } else if (key == "hundredths") {
+            L->push((lua_Number) date->hundredths);
+        } else if (key == "offset") {
+            L->push((lua_Number) date->offset);
+        } else {
+            L->error("Key " + key + " not in class Date");
+        }
+        break;
+    case CDDATE_NEWINDEX:
+        key = L->tostring(2);
+        value = L->tonumber(3);
+        if (key == "year") {
+            date->year = value;
+        } else if (key == "month") {
+            date->month = value;
+        } else if (key == "day") {
+            date->day = value;
+        } else if (key == "hour") {
+            date->hour = value;
+        } else if (key == "minute") {
+            date->minute = value;
+        } else if (key == "second") {
+            date->second = value;
+        } else if (key == "hundredths") {
+            date->hundredths = value;
+        } else if (key == "offset") {
+            date->offset = value;
+        } else {
+            L->error("Key " + key + " not in class Date");
+        }
+        break;
+    }
+
+    return r;
+}
+
+
+ /**********************\
+|**  class PVD exports **|
+ \**********************/
+
+typedef isobuilder::PVD PVD;
+
+LuaPVD::LuaPVD(struct isobuilder::PVD * _pvd) : pvd(_pvd) { }
+
+enum PVD_methods_t {
+    PVD_INDEX = 0,
+    PVD_NEWINDEX,
+};
+
+enum PVD_functions_t {
+    PVD_NEWPVD = 0,
+};
+
+struct lua_functypes_t PVD_methods[] = {
+    { PVD_INDEX,    "index",    1, 1, {LUA_ANY} },
+    { PVD_NEWINDEX, "newindex", 2, 2, {LUA_ANY, LUA_ANY} },
+    { -1, 0, 0, 0, 0 }
+};
+
+struct lua_functypes_t PVD_functions[] = {
+    { PVD_NEWPVD,   "PVD",      0, 0, 0 },
+    { -1, 0, 0, 0, 0 }
+};
+
+class sLua_PVD : public Base {
+  public:
+    DECLARE_METHOD(PVD, PVD_INDEX);
+    DECLARE_METHOD(PVD, PVD_NEWINDEX);
+
+    DECLARE_FUNCTION(PVD, PVD_NEWPVD);
+
+  private:
+    static int PVD_proceed(Lua * L, int n, PVD * obj, int caller);
+    static int PVD_proceed_statics(Lua * L, int n, int caller);
+};
+
+void LuaPVD::pushmembers(Lua * L) {
+    pushme(L, pvd);
+
+    PUSH_METAMETHOD(PVD, PVD_INDEX);
+    PUSH_METAMETHOD(PVD, PVD_NEWINDEX);
+}
+
+void LuaPVD::pushstatics(Lua * L) throw (GeneralException) {
+    CHECK_METHODS(PVD);
+    CHECK_FUNCTIONS(PVD);
+
+    PUSH_FUNCTION(PVD, PVD_NEWPVD);
+}
+
+int sLua_PVD::PVD_proceed(Lua * L, int n, PVD * pvd, int caller) {
+    int r = 0, key_i, value_i;
+    String key_s, value_s;
+    cddate * value_date;
+    bool invalid = false, keyisstring;
+
+    if (L->isnumber(2)) {
+        keyisstring = false;
+        key_i = L->tonumber(2);
+    } else {
+        keyisstring = true;
+        key_s = L->tonumber(2);
+    }
+
+    switch (caller) {
+    case PVD_INDEX:
+        r = 1;
+        if        (keyisstring && (key_s == "sysid")) {
+            L->push(pvd->sysid);
+        } else if (keyisstring && (key_s == "volid")) {
+            L->push(pvd->volid);
+        } else if (keyisstring && (key_s == "volsetid")) {
+            L->push(pvd->volsetid);
+        } else if (keyisstring && (key_s == "pubid")) {
+            L->push(pvd->pubid);
+        } else if (keyisstring && (key_s == "prepid")) {
+            L->push(pvd->prepid);
+        } else if (keyisstring && (key_s == "appid")) {
+            L->push(pvd->appid);
+        } else if (keyisstring && (key_s == "copyright")) {
+            L->push(pvd->copyright);
+        } else if (keyisstring && (key_s == "abstract")) {
+            L->push(pvd->abstract);
+        } else if (keyisstring && (key_s == "biblio")) {
+            L->push(pvd->biblio);
+        } else if (keyisstring && (key_s == "volcreat")) {
+            {
+                Luacddate date(&pvd->volcreat);
+                date.push(L);
+            }
+        } else if (keyisstring && (key_s == "modif")) {
+            {
+                Luacddate date(&pvd->modif);
+                date.push(L);
+            }
+        } else if (keyisstring && (key_s == "volexp")) {
+            {
+                Luacddate date(&pvd->volexp);
+                date.push(L);
+            }
+        } else if (keyisstring && (key_s == "voleff")) {
+            {
+                Luacddate date(&pvd->voleff);
+                date.push(L);
+            }
+        } else if (!keyisstring && (key_i >= 0) && (key_i < 512)) {
+            L->push((lua_Number) pvd->appdata[key_i]);
+        } else {
+            invalid = true;
+        }
+        break;
+    case PVD_NEWINDEX:
+        if        (keyisstring && (key_s == "sysid")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->sysid = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "volid")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->volid = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "volsetid")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->volsetid = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "pubid")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->pubid = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "prepid")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->prepid = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "appid")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->appid = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "copyright")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->copyright = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "abstract")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->abstract = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "biblio")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->biblio = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "volcreat")) {
+            if (L->islightuserdata(3)) {
+                value_date = (cddate *) LuaObject::getme(L, 3);
+                pvd->volcreat = *value_date;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "modif")) {
+            if (L->islightuserdata(3)) {
+                value_date = (cddate *) LuaObject::getme(L, 3);
+                pvd->modif = *value_date;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "volexp")) {
+            if (L->islightuserdata(3)) {
+                value_date = (cddate *) LuaObject::getme(L, 3);
+                pvd->volexp = *value_date;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "voleff")) {
+            if (L->islightuserdata(3)) {
+                value_date = (cddate *) LuaObject::getme(L, 3);
+                pvd->voleff = *value_date;
+            } else {
+                invalid = true;
+            }
+        } else if (!keyisstring && (key_i >= 0) && (key_i < 512)) {
+            if (L->isnumber(3)) {
+                pvd->appdata[key_i] = L->tonumber(3);
+            } else {
+                invalid = true;
+            }
+        } else {
+            invalid = true;
+        }
+        break;
+    }
+
+    if (invalid) {
+        L->error("Invalid usage of structure PVD");
+    }
+
+    return r;
+}
+
+int sLua_PVD::PVD_proceed_statics(Lua * L, int n, int caller) {
+    int r = 0;
+
+    switch (caller) {
+    case PVD_NEWPVD:
+        r = 1;
+        {
+            LuaPVD pvd(new PVD);
+            pvd.pushdestruct(L);
+        }
+        break;
+    }
+
+    return r;
+}
+
+
+ /**************************\
+|**  class DirTree exports **|
+ \**************************/
+
+typedef isobuilder::DirTree DirTree;
+
+LuaDirTree::LuaDirTree(isobuilder::DirTree * _dir) : dir(_dir) { }
+
+enum DirTree_methods_t {
+    DIRTREE_INDEX = 0,
+    DIRTREE_NEWINDEX,
+    DIRTREE_FROMDIR,
+    DIRTREE_SETBASICSXA,
+    DIRTREE_FIND,
+};
+
+enum DirTree_functions_t {
+    DIRTREE_NEWDIRTREE = 0,
+};
+
+struct lua_functypes_t DirTree_methods[] = {
+    { DIRTREE_INDEX,       "index",       1, 1, {LUA_STRING} },
+    { DIRTREE_NEWINDEX,    "newindex",    2, 2, {LUA_STRING, LUA_ANY} },
+    { DIRTREE_FROMDIR,     "fromdir",     1, 1, {LUA_OBJECT} },
+    { DIRTREE_SETBASICSXA, "setbasicsxa", 0, 0, 0 },
+    { DIRTREE_FIND,        "find",        1, 1, {LUA_STRING} },
+    { -1, 0, 0, 0, 0 }
+};
+
+struct lua_functypes_t DirTree_functions[] = {
+    { DIRTREE_NEWDIRTREE, "DirTree", 1, 2, {LUA_OBJECT, LUA_BOOLEAN} },
+    { -1, 0, 0, 0, 0 }
+};
+
+class sLua_DirTree : public Base {
+  public:
+    DECLARE_METHOD(DirTree, DIRTREE_INDEX);
+    DECLARE_METHOD(DirTree, DIRTREE_NEWINDEX);
+    DECLARE_METHOD(DirTree, DIRTREE_FROMDIR);
+    DECLARE_METHOD(DirTree, DIRTREE_SETBASICSXA);
+    DECLARE_METHOD(DirTree, DIRTREE_FIND);
+
+    DECLARE_FUNCTION(DirTree, DIRTREE_NEWDIRTREE);
+  private:
+    static int DirTree_proceed(Lua * L, int n, DirTree * obj, int caller);
+    static int DirTree_proceed_statics(Lua * L, int n, int caller);
+};
+
+void LuaDirTree::pushmembers(Lua * L) {
+    pushme(L, dir);
+
+    PUSH_METAMETHOD(DirTree, DIRTREE_INDEX);
+    PUSH_METAMETHOD(DirTree, DIRTREE_NEWINDEX);
+
+    PUSH_METHOD(DirTree, DIRTREE_FROMDIR);
+    PUSH_METHOD(DirTree, DIRTREE_SETBASICSXA);
+    PUSH_METHOD(DirTree, DIRTREE_FIND);
+}
+
+void LuaDirTree::pushstatics(Lua * L) throw (GeneralException) {
+    CHECK_METHODS(DirTree);
+    CHECK_FUNCTIONS(DirTree);
+
+    PUSH_FUNCTION(DirTree, DIRTREE_NEWDIRTREE);
+}
+
+int sLua_DirTree::DirTree_proceed(Lua * L, int n, DirTree * dir, int caller) {
+    int r = 0, value_i;
+    direntry * dirent;
+    DirTree * rdir;
+    String f, key, value_s;
+    bool invalid = false, value_b;
+    cddate * value_date;
+
+    switch (caller) {
+    case DIRTREE_FROMDIR:
+        dirent = (direntry *) LuaObject::getme(L, 2);
+        dir->fromdir(dirent);
+        break;
+    case DIRTREE_SETBASICSXA:
+        dir->setbasicsxa();
+        break;
+    case DIRTREE_FIND:
+        f = L->tostring(2);
+        rdir = dir->Find(f);
+        if (rdir) {
+            LuaDirTree dirt(rdir);
+            dirt.push(L);
+        } else {
+            L->push();
+        }
+        break;
+    case DIRTREE_INDEX:
+        key = L->tostring(2);
+        r = 1;
+        if        (key == "sector") {
+            L->push((lua_Number) dir->sector);
+        } else if (key == "size") {
+            L->push((lua_Number) dir->size);
+        } else if (key == "hidden") {
+            L->push(dir->hidden);
+        } else if (key == "hardhide") {
+            L->push(dir->hardhide);
+        } else if (key == "name") {
+            L->push(dir->name);
+        } else if (key == "creation") {
+            Luacddate date(&dir->creation);
+            date.push(L);
+        } else if (key == "have_xa") {
+            L->push(dir->have_xa);
+        } else if (key == "xa_dir") {
+            L->push(dir->xa_dir);
+        } else if (key == "xa_audio") {
+            L->push(dir->xa_audio);
+        } else if (key == "xa_str") {
+            L->push(dir->xa_str);
+        } else if (key == "xa_xa") {
+            L->push(dir->xa_xa);
+        } else if (key == "xa_form1") {
+            L->push(dir->xa_form1);
+        } else if (key == "mode") {
+            L->push((lua_Number) dir->mode);
+        } else if (key == "father") {
+            LuaDirTree tdir(dir->Father());
+            tdir.push(L);
+        } else if (key == "child") {
+            LuaDirTree tdir(dir->Child());
+            tdir.push(L);
+        } else if (key == "brother") {
+            LuaDirTree tdir(dir->Brother());
+            tdir.push(L);
+        } else {
+            invalid = true;
+        }
+        break;
+    case DIRTREE_NEWINDEX:
+        key = L->tostring(2);
+        if        (key == "sector") {
+            if (L->isnumber(3)) {
+                value_i = L->tonumber(3);
+                dir->sector = value_i;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "size") {
+            if (L->isnumber(3)) {
+                value_i = L->tonumber(3);
+                dir->size = value_i;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "hidden") {
+            if (L->isboolean(3)) {
+                value_b = L->toboolean(3);
+                dir->hidden = value_b;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "hardhide") {
+            if (L->isboolean(3)) {
+                value_b = L->toboolean(3);
+                dir->hardhide = value_b;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "name") {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                dir->name = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "creation") {
+            if (L->islightuserdata(3)) {
+                value_date = (cddate *) LuaObject::getme(L, 3);
+                dir->creation = *value_date;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "have_xa") {
+            if (L->isboolean(3)) {
+                value_b = L->toboolean(3);
+                dir->have_xa = value_b;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "xa_dir") {
+            if (L->isboolean(3)) {
+                value_b = L->toboolean(3);
+                dir->xa_dir = value_b;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "xa_audio") {
+            if (L->isboolean(3)) {
+                value_b = L->toboolean(3);
+                dir->xa_audio = value_b;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "xa_str") {
+            if (L->isboolean(3)) {
+                value_b = L->toboolean(3);
+                dir->xa_str = value_b;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "xa_xa") {
+            if (L->isboolean(3)) {
+                value_b = L->toboolean(3);
+                dir->xa_xa = value_b;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "xa_form1") {
+            if (L->isboolean(3)) {
+                value_b = L->toboolean(3);
+                dir->xa_form1 = value_b;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "mode") {
+            if (L->isnumber(3)) {
+                value_i = L->tonumber(3);
+                dir->mode = value_i;
+            } else {
+                invalid = true;
+            }
+        } else {
+            invalid = true;
+        }
+        break;
+    }
+
+    if (invalid) {
+        L->error("Invalid usage of structure DirTree");
+    }
+
+    return r;
+}
+
+int sLua_DirTree::DirTree_proceed_statics(Lua * L, int n, int caller) {
+    int r;
+    DirTree * father;
+    bool dir = true;
+
+    switch (caller) {
+    case DIRTREE_NEWDIRTREE:
+        father = (DirTree *) LuaObject::getme(L, 1);
+        if (n == 2)
+            dir = L->toboolean(2);
+        {
+            LuaDirTree dirt(new DirTree(father, dir));
+            dirt.pushdestruct(L);
+        }
+        break;
+    }
+
+    return r;
+}
+
+
+ /*****************************\
+|**  class isobuilder exports **|
+ \*****************************/
+
+Luaisobuilder::Luaisobuilder(isobuilder * _iso) : iso(_iso) { }
+
+enum isobuilder_methods_t {
+    ISOBUILDER_FOREWORD = 0,
+    ISOBUILDER_FOREWORD_HANDLE,
+    ISOBUILDER_FOREWORD_ARRAY,
+    ISOBUILDER_GETDISPSECT,
+    ISOBUILDER_PUTFILE,
+    ISOBUILDER_PUTDATAS,
+    ISOBUILDER_CREATESECTOR,
+    ISOBUILDER_SETEOF,
+    ISOBUILDER_CLEAREOF,
+    ISOBUILDER_SETBASICS,
+    ISOBUILDER_CREATEDIR,
+    ISOBUILDER_CREATEFILE,
+    ISOBUILDER_COPYDIR,
+    ISOBUILDER_CLOSE,
+};
+
+enum isobuilder_functions_t {
+    ISOBUILDER_NEWISOBUILDER = 0,
+    ISOBUILDER_CREATEPVD_HANDLE,
+    ISOBUILDER_CREATEPVD,
+    ISOBUILDER_CREATEPVD_ARRAY,
+};
+
+struct lua_functypes_t isobuilder_methods[] = {
+    { ISOBUILDER_FOREWORD,          "foreword",          1, 1, {LUA_OBJECT} },
+    { ISOBUILDER_FOREWORD_HANDLE,   "foreword_handle",   1, 2, {LUA_OBJECT, LUA_NUMBER} },
+    { ISOBUILDER_FOREWORD_ARRAY,    "foreword_array",    1, 2, {LUA_TABLE, LUA_NUMBER} },
+    { ISOBUILDER_GETDISPSECT,       "getdispsect",       0, 0, 0},
+    { ISOBUILDER_PUTFILE,           "putfile",           1, 3, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER} },
+    { ISOBUILDER_PUTDATAS,          "putdatas",          2, 4, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
+    { ISOBUILDER_CREATESECTOR,      "createsector",      1, 3, {LUA_TABLE, LUA_NUMBER, LUA_NUMBER} },
+    { ISOBUILDER_SETEOF,            "setEOF",            0, 0, 0 },
+    { ISOBUILDER_CLEAREOF,          "clearEOF",          0, 0, 0 },
+    { ISOBUILDER_SETBASICS,         "setbasics",         1, 5, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
+    { ISOBUILDER_CREATEDIR,         "createdir",         2, 5, {LUA_OBJECT, LUA_STRING, LUA_NUMBER, LUA_OBJECT, LUA_NUMBER} },
+    { ISOBUILDER_CREATEFILE,        "createfile",        3, 5, {LUA_OBJECT, LUA_OBJECT, LUA_STRING, LUA_OBJECT, LUA_NUMBER} },
+    { ISOBUILDER_COPYDIR,           "copydir",           4, 5, {LUA_OBJECT, LUA_STRING, LUA_OBJECT, LUA_OBJECT, LUA_NUMBER} },
+    { ISOBUILDER_CLOSE,             "close",             0, 2, {LUA_OBJECT, LUA_NUMBER} },
+    { -1, 0, 0, 0, 0 }
+};
+
+struct lua_functypes_t isobuilder_functions[] = {
+    { ISOBUILDER_NEWISOBUILDER,     "isobuilder",        1, 2, {LUA_OBJECT, LUA_NUMBER} },
+    { ISOBUILDER_CREATEPVD_HANDLE,  "createpvd_handle",  1, 1, {LUA_OBJECT} },
+    { ISOBUILDER_CREATEPVD,         "createpvd",         1, 1, {LUA_OBJECT} },
+    { ISOBUILDER_CREATEPVD_ARRAY,   "createpvd_array",   1, 1, {LUA_TABLE} },
+    { -1, 0, 0, 0, 0 }
+};
+
+class sLua_isobuilder : public Base {
+  public:
+    DECLARE_METHOD(isobuilder, ISOBUILDER_FOREWORD);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_FOREWORD_HANDLE);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_FOREWORD_ARRAY);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_GETDISPSECT);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_PUTFILE);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_PUTDATAS);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_CREATESECTOR);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_SETEOF);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_CLEAREOF);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_SETBASICS);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_CREATEDIR);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_CREATEFILE);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_COPYDIR);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_CLOSE);
+
+    DECLARE_FUNCTION(isobuilder, ISOBUILDER_NEWISOBUILDER);
+    DECLARE_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD_HANDLE);
+    DECLARE_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD);
+    DECLARE_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD_ARRAY);
+
+  private:
+    static int isobuilder_proceed(Lua * L, int n, isobuilder * obj, int caller);
+    static int isobuilder_proceed_statics(Lua * L, int n, int caller);
+};
+
+void Luaisobuilder::pushmembers(Lua * L) {
+    pushme(L, iso);
+
+    PUSH_METHOD(isobuilder, ISOBUILDER_FOREWORD);
+    PUSH_METHOD(isobuilder, ISOBUILDER_FOREWORD_HANDLE);
+    PUSH_METHOD(isobuilder, ISOBUILDER_FOREWORD_ARRAY);
+    PUSH_METHOD(isobuilder, ISOBUILDER_GETDISPSECT);
+    PUSH_METHOD(isobuilder, ISOBUILDER_PUTFILE);
+    PUSH_METHOD(isobuilder, ISOBUILDER_PUTDATAS);
+    PUSH_METHOD(isobuilder, ISOBUILDER_CREATESECTOR);
+    PUSH_METHOD(isobuilder, ISOBUILDER_SETEOF);
+    PUSH_METHOD(isobuilder, ISOBUILDER_CLEAREOF);
+    PUSH_METHOD(isobuilder, ISOBUILDER_SETBASICS);
+    PUSH_METHOD(isobuilder, ISOBUILDER_CREATEDIR);
+    PUSH_METHOD(isobuilder, ISOBUILDER_CREATEFILE);
+    PUSH_METHOD(isobuilder, ISOBUILDER_COPYDIR);
+    PUSH_METHOD(isobuilder, ISOBUILDER_CLOSE);
+}
+
+void Luaisobuilder::pushstatics(Lua * L) throw (GeneralException) {
+    CHECK_METHODS(isobuilder);
+    CHECK_FUNCTIONS(isobuilder);
+
+    PUSH_FUNCTION(isobuilder, ISOBUILDER_NEWISOBUILDER);
+    PUSH_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD_HANDLE);
+    PUSH_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD);
+    PUSH_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD_ARRAY);
+}
+
+int sLua_isobuilder::isobuilder_proceed(Lua * L, int n, isobuilder * iso, int caller) {
+    int r = 0, i;
+    Handle * h = 0;
+    int mode = -1, sector = -1, rootsize = 1, ptsize = 1, nvd = 1, rootsect = -1;
+    size_t size;
+    Byte datas[2352 * 16], * p;
+    PVD * pvd;
+    DirTree * dirt, * rdir;
+    direntry * dire = 0;
+    String name;
+    cdutils * cd;
+
+    switch (caller) {
+    case ISOBUILDER_FOREWORD:
+        cd = (cdutils *) LuaObject::getme(L, 2);
+        iso->foreword(cd);
+        break;
+    case ISOBUILDER_FOREWORD_HANDLE:
+        mode = MODE_RAW;
+        h = (Handle *) LuaObject::getme(L, 2);
+        if (n == 2)
+            mode = L->tonumber(3);
+        iso->foreword(h, mode);
+        break;
+    case ISOBUILDER_FOREWORD_ARRAY:
+        mode = MODE_RAW;
+        if (n == 2)
+            mode = L->tonumber(3);
+        for (i = 0; i < 16 * 2352; i++) {
+            L->push((lua_Number) i);
+            L->gettable(2);
+            datas[i] = L->tonumber();
+            L->pop();
+        }
+        iso->foreword(datas, mode);
+        break;
+    case ISOBUILDER_GETDISPSECT:
+        L->push((lua_Number) iso->getdispsect());
+        r = 1;
+        break;
+    case ISOBUILDER_PUTFILE:
+        h = (Handle *) LuaObject::getme(L, 2);
+        if (n >= 2)
+            mode = L->tonumber(3);
+        if (n >= 3)
+            sector = L->tonumber(4);
+        L->push((lua_Number) iso->putfile(h, mode, sector));
+        r = 1;
+        break;
+    case ISOBUILDER_PUTDATAS:
+        size = L->tonumber(3);
+        if (n >= 3)
+            mode = L->tonumber(4);
+        if (n >= 4)
+            sector = L->tonumber(5);
+        p = (Byte *) malloc(size);
+        for (i = 0; i < size; i++) {
+            L->push((lua_Number) i);
+            L->gettable(2);
+            p[i] = L->tonumber();
+            L->pop();
+        }
+        L->push((lua_Number) iso->putdatas(p, size, mode, sector));
+        r = 1;
+        free(p);
+        break;
+    case ISOBUILDER_CREATESECTOR:
+        if (n >= 2)
+            mode = L->tonumber(3);
+        if (n >= 3)
+            sector = L->tonumber(4);
+        for (i = 0; i < 2352; i++) {
+            L->push((lua_Number) i);
+            L->gettable(2);
+            datas[i] = L->tonumber();
+            L->pop();
+        }
+        L->push((lua_Number) iso->createsector(datas, mode, sector));
+        r = 1;
+        break;
+    case ISOBUILDER_SETEOF:
+        iso->setEOF();
+        break;
+    case ISOBUILDER_CLEAREOF:
+        iso->clearEOF();
+        break;
+    case ISOBUILDER_SETBASICS:
+        pvd = (PVD *) LuaObject::getme(L, 2);
+        if (n >= 2)
+            rootsize = L->tonumber(3);
+        if (n >= 3)
+            ptsize = L->tonumber(4);
+        if (n >= 4)
+            nvd = L->tonumber(5);
+        if (n >= 5)
+            rootsect = L->tonumber(6);
+        rdir = iso->setbasics(*pvd, rootsize, ptsize, nvd, rootsect);
+        {
+            LuaDirTree t(rdir);
+            t.push(L);
+        }
+        r = 1;
+        break;
+    case ISOBUILDER_CREATEDIR:
+        size = 1;
+        dirt = 0;
+        dirt = (DirTree *) LuaObject::getme(L, 2);
+        name = L->tostring(3);
+        if (n >= 3)
+            size = L->tonumber(4);
+        if (n >= 4)
+            dire = (direntry *) LuaObject::getme(L, 5);
+        if (n >= 5)
+            mode = L->tonumber(6);
+        rdir = iso->createdir(dirt, name, size, dire, mode);
+        {
+            LuaDirTree t(rdir);
+            t.push(L);
+        }
+        r = 1;
+        break;
+    case ISOBUILDER_CREATEFILE:
+        dirt = (DirTree *) LuaObject::getme(L, 2);
+        h = (Handle *) LuaObject::getme(L, 3);
+        name = L->tostring(4);
+        if (n >= 4)
+            dire = (direntry *) LuaObject::getme(L, 5);
+        if (n >= 5)
+            mode = L->tonumber(6);
+        rdir = iso->createfile(dirt, h, name, dire, mode);
+        {
+            LuaDirTree t(rdir);
+            t.push(L);
+        }
+        r = 1;
+        break;
+    case ISOBUILDER_COPYDIR:
+        dirt = (DirTree *) LuaObject::getme(L, 2);
+        name = L->tostring(3);
+        cd = (cdutils *) LuaObject::getme(L, 4);
+        dire = (direntry *) LuaObject::getme(L, 5);
+        if (n >= 5)
+            mode = L->tonumber(6);
+        iso->copydir(dirt, name, cd, dire, mode);
+        break;
+    case ISOBUILDER_CLOSE:
+        if (n >= 1)
+            h = (Handle *) LuaObject::getme(L, 2);
+        if (n >= 2)
+            mode = L->tonumber(3);
+        iso->close(h, mode);
+        break;
+    }
+
+    return r;
+}
+
+int sLua_isobuilder::isobuilder_proceed_statics(Lua * L, int n, int caller) {
+    int r = 0, i;
+    Handle * h;
+    int mode = MODE2_FORM1;
+    cdutils * cd;
+    Byte datas[2048];
+    PVD * pvd;
+
+    switch (caller) {
+    case ISOBUILDER_NEWISOBUILDER:
+        h = (Handle *) LuaObject::getme(L, 1);
+        if (n >= 2)
+            mode = L->tonumber();
+        {
+            Luaisobuilder t(new isobuilder(h, mode));
+            t.pushdestruct(L);
+        }
+        r = 1;
+        break;
+    case ISOBUILDER_CREATEPVD_HANDLE:
+        h = (Handle *) LuaObject::getme(L, 1);
+        pvd = new PVD(isobuilder::createpvd(h));
+        {
+            LuaPVD t(pvd);
+            t.pushdestruct(L);
+        }
+        r = 1;
+        break;
+    case ISOBUILDER_CREATEPVD:
+        cd = (cdutils *) LuaObject::getme(L, 1);
+        pvd = new PVD(isobuilder::createpvd(cd));
+        {
+            LuaPVD t(pvd);
+            t.pushdestruct(L);
+        }
+        r = 1;
+        break;
+    case ISOBUILDER_CREATEPVD_ARRAY:
+        for (i = 0; i < 2048; i++) {
+            L->push((lua_Number) i);
+            L->gettable(1);
+            datas[i] = L->tonumber();
+            L->pop();
+        }
+        pvd = new PVD(isobuilder::createpvd(datas));
+        {
+            LuaPVD t(pvd);
+            t.pushdestruct(L);
+        }
+        r = 1;
+        break;
+    }
+
+    return r;
 }
-- 
cgit v1.2.3