summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/cdabstract.cpp384
-rw-r--r--lib/cdreader.cpp668
-rw-r--r--lib/cdutils.cpp1904
-rw-r--r--lib/dteutils.cpp638
-rw-r--r--lib/isobuilder.cpp1752
-rw-r--r--lib/luacd.cpp3318
-rw-r--r--lib/luapsx.cpp614
-rw-r--r--lib/lzss.cpp928
-rw-r--r--lib/mips.cpp2136
-rw-r--r--lib/mipsdis.cpp360
-rw-r--r--lib/mipsdump.cpp414
-rw-r--r--lib/mipsmem.cpp698
-rw-r--r--lib/mipsobj.cpp538
-rw-r--r--lib/yazedc.cpp546
14 files changed, 7449 insertions, 7449 deletions
diff --git a/lib/cdabstract.cpp b/lib/cdabstract.cpp
index ceb5f70..44663f6 100644
--- a/lib/cdabstract.cpp
+++ b/lib/cdabstract.cpp
@@ -1,192 +1,192 @@
-/*
- * 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: cdabstract.cpp,v 1.8 2004-11-27 21:44:48 pixel Exp $ */
-
-#include "cdabstract.h"
-#include "Input.h"
-#include "cdreader.h"
-
-#ifdef __linux__
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <linux/cdrom.h>
-#endif
-
-#if defined (_MSC_VER) || defined (__MINGW32__)
-#include <windowsx.h>
-#endif
-
-Handle * cdabstract::open_cd(const String & nom) {
- if (nom.extract(0, 2).toupper() == "CD:") {
- return new cdreader(nom.extract(3));
- } else {
- return new Input(nom);
- }
-}
-
-bool cdabstract::canprobe() {
-#ifdef __linux__
- return true;
-#endif
-#ifdef _WIN32
- OSVERSIONINFO ov;
- memset(&ov, 0, sizeof(OSVERSIONINFO));
- ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-
- GetVersionEx(&ov);
-
- return ((ov.dwPlatformId == VER_PLATFORM_WIN32_NT) && (ov.dwMajorVersion > 4));
-#endif
- return false;
-}
-
-std::vector<String> cdabstract::probe() throw (GeneralException) {
- int i;
- std::vector<String> r;
- String probed;
-
- if (!canprobe())
- throw GeneralException("Can't probe CD devices on this platform.");
-
-#ifdef __linux__
- if (subprobe(probed = "/dev/cdrom"))
- r.push_back(probed);
-
- for (i = 0; i < 63; i++) {
- probed.set("/dev/cdroms/cdrom%i", i);
- if (subprobe(probed))
- r.push_back(probed);
- }
- for (i = 'a'; i <= 'z'; i++) {
- probed.set("/dev/hd%c", i);
- if (subprobe(probed))
- r.push_back(probed);
- }
-#endif
-
-#ifdef _WIN32
- for (i = 'A'; i <= 'Z'; i++) {
- probed.set("%c:\\", i);
- if (subprobe(probed))
- r.push_back(probed);
- }
-#endif
-
- return r;
-}
-
-#ifdef _WIN32
-HANDLE cdabstract::OpenIOCTLFile(char cLetter) {
- HANDLE hF;
- char szFName[16];
- OSVERSIONINFO ov;
- DWORD dwFlags;
- DWORD dwIOCTLAttr = 0;
-
- memset(&ov, 0, sizeof(OSVERSIONINFO));
- ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&ov);
-
- if((ov.dwPlatformId == VER_PLATFORM_WIN32_NT) && (ov.dwMajorVersion > 4))
- dwFlags = GENERIC_READ | GENERIC_WRITE; // add gen write on W2k/XP
- else dwFlags = GENERIC_READ;
-
- sprintf(szFName, "\\\\.\\%c:", cLetter);
-
- hF = CreateFile(szFName, dwFlags, FILE_SHARE_READ, // open drive
- NULL, OPEN_EXISTING, dwIOCTLAttr, NULL);
-
- if (hF == INVALID_HANDLE_VALUE) { // mmm... no success?
- dwFlags ^= GENERIC_WRITE; // -> try write toggle
- hF = CreateFile(szFName, dwFlags, FILE_SHARE_READ, // -> open drive again
- NULL, OPEN_EXISTING, dwIOCTLAttr, NULL);
- if (hF == INVALID_HANDLE_VALUE)
- return NULL;
- }
- return hF;
-}
-
-typedef struct {
- ULONG Length;
- UCHAR PortNumber;
- UCHAR PathId;
- UCHAR TargetId;
- UCHAR Lun;
-} SCSI_ADDRESS, *PSCSI_ADDRESS;
-
-void cdabstract::GetIOCTLAdapter(HANDLE hF, int * iDA, int * iDT, int * iDL) {
- char szBuf[1024];
- PSCSI_ADDRESS pSA;
- DWORD dwRet;
-
- *iDA = *iDT = *iDL = -1;
-
- if (hF == NULL)
- return;
-
- memset(szBuf,0,1024);
-
- pSA = (PSCSI_ADDRESS)szBuf;
- pSA->Length = sizeof(SCSI_ADDRESS);
-
- if (!DeviceIoControl(hF, IOCTL_SCSI_GET_ADDRESS, NULL, 0, pSA,
- sizeof(SCSI_ADDRESS), &dwRet, NULL))
- return;
-
- *iDA = pSA->PortNumber;
- *iDT = pSA->TargetId;
- *iDL = pSA->Lun;
-}
-#endif
-
-bool cdabstract::subprobe(String & probed) {
-#ifdef __linux__
- int h, caps;
-
- h = open(probed.to_charp(), O_RDONLY | O_NONBLOCK);
-
- if (ioctl(h, CDROM_GET_CAPABILITY, &caps) < 0) {
- close(h);
- return false;
- } else {
- close(h);
- return true;
- }
-#endif
-
-#ifdef _WIN32
- int iDA, iDT, iDL;
- char letter[4];
- HANDLE h;
-
- if (GetDriveType(probed.to_charp()) == DRIVE_CDROM) {
- h = OpenIOCTLFile(probed[0]);
- GetIOCTLAdapter(h, &iDA, &iDT, &iDL);
- CloseHandle(h);
- if ((iDA != -1) && (iDT != -1) && (iDL != -1)) {
- probed += String().set(" [%i:%i:%i]", iDA, iDT, iDL);
- return true;
- }
- }
-#endif
-
- return false;
-}
+/*
+ * 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: cdabstract.cpp,v 1.9 2004-11-27 21:47:56 pixel Exp $ */
+
+#include "cdabstract.h"
+#include "Input.h"
+#include "cdreader.h"
+
+#ifdef __linux__
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <linux/cdrom.h>
+#endif
+
+#if defined (_MSC_VER) || defined (__MINGW32__)
+#include <windowsx.h>
+#endif
+
+Handle * cdabstract::open_cd(const String & nom) {
+ if (nom.extract(0, 2).toupper() == "CD:") {
+ return new cdreader(nom.extract(3));
+ } else {
+ return new Input(nom);
+ }
+}
+
+bool cdabstract::canprobe() {
+#ifdef __linux__
+ return true;
+#endif
+#ifdef _WIN32
+ OSVERSIONINFO ov;
+ memset(&ov, 0, sizeof(OSVERSIONINFO));
+ ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+ GetVersionEx(&ov);
+
+ return ((ov.dwPlatformId == VER_PLATFORM_WIN32_NT) && (ov.dwMajorVersion > 4));
+#endif
+ return false;
+}
+
+std::vector<String> cdabstract::probe() throw (GeneralException) {
+ int i;
+ std::vector<String> r;
+ String probed;
+
+ if (!canprobe())
+ throw GeneralException("Can't probe CD devices on this platform.");
+
+#ifdef __linux__
+ if (subprobe(probed = "/dev/cdrom"))
+ r.push_back(probed);
+
+ for (i = 0; i < 63; i++) {
+ probed.set("/dev/cdroms/cdrom%i", i);
+ if (subprobe(probed))
+ r.push_back(probed);
+ }
+ for (i = 'a'; i <= 'z'; i++) {
+ probed.set("/dev/hd%c", i);
+ if (subprobe(probed))
+ r.push_back(probed);
+ }
+#endif
+
+#ifdef _WIN32
+ for (i = 'A'; i <= 'Z'; i++) {
+ probed.set("%c:\\", i);
+ if (subprobe(probed))
+ r.push_back(probed);
+ }
+#endif
+
+ return r;
+}
+
+#ifdef _WIN32
+HANDLE cdabstract::OpenIOCTLFile(char cLetter) {
+ HANDLE hF;
+ char szFName[16];
+ OSVERSIONINFO ov;
+ DWORD dwFlags;
+ DWORD dwIOCTLAttr = 0;
+
+ memset(&ov, 0, sizeof(OSVERSIONINFO));
+ ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&ov);
+
+ if((ov.dwPlatformId == VER_PLATFORM_WIN32_NT) && (ov.dwMajorVersion > 4))
+ dwFlags = GENERIC_READ | GENERIC_WRITE; // add gen write on W2k/XP
+ else dwFlags = GENERIC_READ;
+
+ sprintf(szFName, "\\\\.\\%c:", cLetter);
+
+ hF = CreateFile(szFName, dwFlags, FILE_SHARE_READ, // open drive
+ NULL, OPEN_EXISTING, dwIOCTLAttr, NULL);
+
+ if (hF == INVALID_HANDLE_VALUE) { // mmm... no success?
+ dwFlags ^= GENERIC_WRITE; // -> try write toggle
+ hF = CreateFile(szFName, dwFlags, FILE_SHARE_READ, // -> open drive again
+ NULL, OPEN_EXISTING, dwIOCTLAttr, NULL);
+ if (hF == INVALID_HANDLE_VALUE)
+ return NULL;
+ }
+ return hF;
+}
+
+typedef struct {
+ ULONG Length;
+ UCHAR PortNumber;
+ UCHAR PathId;
+ UCHAR TargetId;
+ UCHAR Lun;
+} SCSI_ADDRESS, *PSCSI_ADDRESS;
+
+void cdabstract::GetIOCTLAdapter(HANDLE hF, int * iDA, int * iDT, int * iDL) {
+ char szBuf[1024];
+ PSCSI_ADDRESS pSA;
+ DWORD dwRet;
+
+ *iDA = *iDT = *iDL = -1;
+
+ if (hF == NULL)
+ return;
+
+ memset(szBuf,0,1024);
+
+ pSA = (PSCSI_ADDRESS)szBuf;
+ pSA->Length = sizeof(SCSI_ADDRESS);
+
+ if (!DeviceIoControl(hF, IOCTL_SCSI_GET_ADDRESS, NULL, 0, pSA,
+ sizeof(SCSI_ADDRESS), &dwRet, NULL))
+ return;
+
+ *iDA = pSA->PortNumber;
+ *iDT = pSA->TargetId;
+ *iDL = pSA->Lun;
+}
+#endif
+
+bool cdabstract::subprobe(String & probed) {
+#ifdef __linux__
+ int h, caps;
+
+ h = open(probed.to_charp(), O_RDONLY | O_NONBLOCK);
+
+ if (ioctl(h, CDROM_GET_CAPABILITY, &caps) < 0) {
+ close(h);
+ return false;
+ } else {
+ close(h);
+ return true;
+ }
+#endif
+
+#ifdef _WIN32
+ int iDA, iDT, iDL;
+ char letter[4];
+ HANDLE h;
+
+ if (GetDriveType(probed.to_charp()) == DRIVE_CDROM) {
+ h = OpenIOCTLFile(probed[0]);
+ GetIOCTLAdapter(h, &iDA, &iDT, &iDL);
+ CloseHandle(h);
+ if ((iDA != -1) && (iDT != -1) && (iDL != -1)) {
+ probed += String().set(" [%i:%i:%i]", iDA, iDT, iDL);
+ return true;
+ }
+ }
+#endif
+
+ return false;
+}
diff --git a/lib/cdreader.cpp b/lib/cdreader.cpp
index 7777c4d..af1b419 100644
--- a/lib/cdreader.cpp
+++ b/lib/cdreader.cpp
@@ -1,334 +1,334 @@
-/*
- * 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: cdreader.cpp,v 1.20 2004-11-27 21:44:48 pixel Exp $ */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include "cdreader.h"
-#include "Exceptions.h"
-#include "generic.h"
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#else
-#define _(x) x
-#endif
-#include "cdabstract.h"
-
-#define nsectorsarow 1
-#define cachesize 2048
-
-bool cdreader::CanWrite() const {
- return 0;
-}
-
-bool cdreader::CanRead() const {
- return 1;
-}
-
-bool cdreader::CanSeek() const {
- return 1;
-}
-
-String cdreader::GetName() const {
- return n + " raw reading";
-}
-
-ssize_t cdreader::GetSize() const {
- return -1;
-}
-
-off_t cdreader::seek(off_t offset, int whence) throw (GeneralException) {
- switch (whence) {
- case SEEK_SET:
- itell = offset;
- break;
- case SEEK_CUR:
- itell += offset;
- break;
- case SEEK_END:
- throw GeneralException("Can not yet seek from the end of a CD.");
- }
- return itell;
-}
-
-ssize_t cdreader::read(void *buf, size_t count) throw (GeneralException) {
- char sector[2352];
- size_t r = count;
-
- size_t remain = itell % 2352;
- sectorseek(itell / 2352);
-
- while (count > 0) {
- size_t n = MIN(2352 - remain, count);
- fetchsector(sector);
- bcopy(sector + remain, buf, n);
- buf = ((char *) buf) + n;
- itell += n;
- count -= n;
- remain = 0;
- }
-
- return r;
-}
-
-void cdreader::sectorseek(int sec) {
- sector = sec;
-}
-
-void cdreader::fetchsector(void * buf, int sec) {
- if (sec >= 0)
- sector = sec;
-
- if (sectors[sector]) {
- actualize(sectors[sector]);
- memcpy(buf, sectors[sector]->sector, 2352);
- return;
- }
-
- Byte buffers[2352 * nsectorsarow];
-
- getsector(buffers, sec = sector, nsectorsarow);
-
- for (int i = nsectorsarow - 1; i >= 0; i--) {
- introduce(buffers + i * 2352, sec + i);
- }
-
- memcpy(buf, buffers, 2352);
-
- while (nsectors > cachesize) {
- removetail();
- }
-}
-
-cdreader::~cdreader() {
- while (nsectors) {
- removetail();
- }
-}
-
-void cdreader::removetail() {
- if (!tail)
- return;
-
- sectors[tail->n] = 0;
-
- if (head == tail) {
- free(tail);
- head = tail = 0;
- nsectors = 0;
- } else {
- cachedsector * p;
- (p = tail->prev)->next = 0;
- free(tail);
- tail = p;
- nsectors--;
- }
-}
-
-void cdreader::actualize(cachedsector * s) {
- if (s == head)
- return;
-
- if (s != tail) {
- s->next->prev = s->prev;
- } else {
- tail = s->prev;
- }
- s->prev->next = s->next;
-
- head->prev = s;
- s->prev = 0;
- s->next = head;
- head = s;
-}
-
-void cdreader::introduce(Byte * datas, int n) {
- cachedsector * s;
-
- s = (cachedsector *) malloc(sizeof(cachedsector));
- memcpy(s->sector, datas, 2352);
- s->n = n;
-
- if (head) {
- s->next = head;
- head->prev = s;
- head = s;
- } else {
- head = tail = s;
- s->prev = s->next = 0;
- }
- sectors[n] = s;
-
- nsectors++;
-}
-
-#ifdef __linux__
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <linux/cdrom.h>
-
-cdreader::cdreader(const String & no) throw (GeneralException) :
- Handle(open(no.to_charp(), O_RDONLY)), n(no), sector(0) {
- int i;
-
-#ifdef DEBUG
- printm(M_INFO, "Opening cdrom device " + no + "\n");
-#endif
-
- if (GetHandle() < 0) {
- throw IOGeneral(String(_("Error opening file ")) + no + _(" for reading: ") + strerror(errno));
- }
-
- struct stat s;
- fstat(GetHandle(), &s);
-
- if (!S_ISBLK(s.st_mode)) {
- throw GeneralException(no + " is not a block device.");
- }
-
- for (i = 0; i < 400000; i++) {
- sectors[i] = 0;
- }
- head = tail = 0;
- nsectors = 0;
-}
-
-cdreader::cdreader(const cdreader & inp) : Handle(inp), n(inp.n) {
- int i;
-
- for (i = 0; i < 400000; i++) {
- sectors[i] = 0;
- }
- head = tail = 0;
- nsectors = 0;
-}
-
-void cdreader::getsector(void *buf, int sec, int nb) throw (GeneralException) {
- struct cdrom_msf * msf = (struct cdrom_msf *) buf;
- if (sec >= 0)
- sector = sec;
-
- sector += 150;
-
- msf->cdmsf_min0 = sector /CD_SECS /CD_FRAMES;
- msf->cdmsf_sec0 = (sector /CD_FRAMES)%CD_SECS;
- msf->cdmsf_frame0= sector %CD_FRAMES;
- msf->cdmsf_min1 = (sector + nb)/CD_SECS /CD_FRAMES;
- msf->cdmsf_sec1 = ((sector + nb)/CD_FRAMES)%CD_SECS;
- msf->cdmsf_frame1= (sector + nb)%CD_FRAMES;
-
- sector -= 150;
-
- if (ioctl(GetHandle(), CDROMREADRAW, buf) < 0) {
- throw GeneralException(String("unable to read cd sector ") + sector + ": " + strerror(errno));
- }
-
- sector += nb;
-}
-#endif
-
-#if defined (_MSC_VER) || defined (__MINGW32__)
-cdreader::cdreader(const String & no) throw (GeneralException) :
- Handle(-1), n(no), sector(0) {
- if (!(hFile = cdabstract::OpenIOCTLFile(no[0])))
- throw GeneralException("Error opening device " + no);
- for (int i = 0; i < 400000; i++) {
- sectors[i] = 0;
- }
- head = tail = 0;
- nsectors = 0;
-}
-
-cdreader::cdreader(const cdreader & i) : Handle(i), n(i.n) {
- hFile = i.hFile;
- for (int x = 0; x < 400000; x++) {
- sectors[x] = 0;
- }
- head = tail = 0;
- nsectors = 0;
-}
-
-void cdreader::close() throw (GeneralException) {
- CloseHandle(hFile);
-}
-
-typedef enum _TRACK_MODE_TYPE {
- YellowMode2,
- XAForm2,
- CDDA
-} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE;
-
-typedef struct _RAW_READ_INFO {
- LARGE_INTEGER DiskOffset;
- ULONG SectorCount;
- TRACK_MODE_TYPE TrackMode;
-} RAW_READ_INFO, *PRAW_READ_INFO;
-
-void cdreader::getsector(void *buf, int sec, int nb) throw (GeneralException) {
- RAW_READ_INFO rawIOCTL;
- DWORD dwRet;
- BOOL bStat;
- bool done = false;
- if (sec >= 0)
- sector = sec;
-
- rawIOCTL.DiskOffset.QuadPart = sector * 2048;
- rawIOCTL.SectorCount = nb;
- rawIOCTL.TrackMode = YellowMode2;
-
- while (!done) {
- SetLastError(0);
- bStat = DeviceIoControl(hFile, IOCTL_CDROM_RAW_READ,
- &rawIOCTL, sizeof(RAW_READ_INFO),
- buf, 2352 * nb, &dwRet, NULL);
- if (!bStat) {
- DWORD dwErrCode = GetLastError();
- if (dwErrCode == ERROR_INVALID_FUNCTION) {
- if (rawIOCTL.TrackMode == YellowMode2) {
- rawIOCTL.TrackMode = XAForm2;
- continue;
- }
- }
- if (dwErrCode != ERROR_IO_PENDING) {
- LPVOID lpMsgBuf;
- if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPTSTR) &lpMsgBuf, 0, NULL ))
- throw GeneralException("Gave up on reading CD: unknown error");
- String errmsg = (LPCTSTR) lpMsgBuf;
- LocalFree(lpMsgBuf);
- throw GeneralException("Gave up on reading CD: " + errmsg);
- }
- } else {
- done = true;
- }
- }
-
- sector += nb;
-}
-
-#endif
+/*
+ * 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: cdreader.cpp,v 1.21 2004-11-27 21:47:56 pixel Exp $ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "cdreader.h"
+#include "Exceptions.h"
+#include "generic.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#else
+#define _(x) x
+#endif
+#include "cdabstract.h"
+
+#define nsectorsarow 1
+#define cachesize 2048
+
+bool cdreader::CanWrite() const {
+ return 0;
+}
+
+bool cdreader::CanRead() const {
+ return 1;
+}
+
+bool cdreader::CanSeek() const {
+ return 1;
+}
+
+String cdreader::GetName() const {
+ return n + " raw reading";
+}
+
+ssize_t cdreader::GetSize() const {
+ return -1;
+}
+
+off_t cdreader::seek(off_t offset, int whence) throw (GeneralException) {
+ switch (whence) {
+ case SEEK_SET:
+ itell = offset;
+ break;
+ case SEEK_CUR:
+ itell += offset;
+ break;
+ case SEEK_END:
+ throw GeneralException("Can not yet seek from the end of a CD.");
+ }
+ return itell;
+}
+
+ssize_t cdreader::read(void *buf, size_t count) throw (GeneralException) {
+ char sector[2352];
+ size_t r = count;
+
+ size_t remain = itell % 2352;
+ sectorseek(itell / 2352);
+
+ while (count > 0) {
+ size_t n = MIN(2352 - remain, count);
+ fetchsector(sector);
+ bcopy(sector + remain, buf, n);
+ buf = ((char *) buf) + n;
+ itell += n;
+ count -= n;
+ remain = 0;
+ }
+
+ return r;
+}
+
+void cdreader::sectorseek(int sec) {
+ sector = sec;
+}
+
+void cdreader::fetchsector(void * buf, int sec) {
+ if (sec >= 0)
+ sector = sec;
+
+ if (sectors[sector]) {
+ actualize(sectors[sector]);
+ memcpy(buf, sectors[sector]->sector, 2352);
+ return;
+ }
+
+ Byte buffers[2352 * nsectorsarow];
+
+ getsector(buffers, sec = sector, nsectorsarow);
+
+ for (int i = nsectorsarow - 1; i >= 0; i--) {
+ introduce(buffers + i * 2352, sec + i);
+ }
+
+ memcpy(buf, buffers, 2352);
+
+ while (nsectors > cachesize) {
+ removetail();
+ }
+}
+
+cdreader::~cdreader() {
+ while (nsectors) {
+ removetail();
+ }
+}
+
+void cdreader::removetail() {
+ if (!tail)
+ return;
+
+ sectors[tail->n] = 0;
+
+ if (head == tail) {
+ free(tail);
+ head = tail = 0;
+ nsectors = 0;
+ } else {
+ cachedsector * p;
+ (p = tail->prev)->next = 0;
+ free(tail);
+ tail = p;
+ nsectors--;
+ }
+}
+
+void cdreader::actualize(cachedsector * s) {
+ if (s == head)
+ return;
+
+ if (s != tail) {
+ s->next->prev = s->prev;
+ } else {
+ tail = s->prev;
+ }
+ s->prev->next = s->next;
+
+ head->prev = s;
+ s->prev = 0;
+ s->next = head;
+ head = s;
+}
+
+void cdreader::introduce(Byte * datas, int n) {
+ cachedsector * s;
+
+ s = (cachedsector *) malloc(sizeof(cachedsector));
+ memcpy(s->sector, datas, 2352);
+ s->n = n;
+
+ if (head) {
+ s->next = head;
+ head->prev = s;
+ head = s;
+ } else {
+ head = tail = s;
+ s->prev = s->next = 0;
+ }
+ sectors[n] = s;
+
+ nsectors++;
+}
+
+#ifdef __linux__
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/cdrom.h>
+
+cdreader::cdreader(const String & no) throw (GeneralException) :
+ Handle(open(no.to_charp(), O_RDONLY)), n(no), sector(0) {
+ int i;
+
+#ifdef DEBUG
+ printm(M_INFO, "Opening cdrom device " + no + "\n");
+#endif
+
+ if (GetHandle() < 0) {
+ throw IOGeneral(String(_("Error opening file ")) + no + _(" for reading: ") + strerror(errno));
+ }
+
+ struct stat s;
+ fstat(GetHandle(), &s);
+
+ if (!S_ISBLK(s.st_mode)) {
+ throw GeneralException(no + " is not a block device.");
+ }
+
+ for (i = 0; i < 400000; i++) {
+ sectors[i] = 0;
+ }
+ head = tail = 0;
+ nsectors = 0;
+}
+
+cdreader::cdreader(const cdreader & inp) : Handle(inp), n(inp.n) {
+ int i;
+
+ for (i = 0; i < 400000; i++) {
+ sectors[i] = 0;
+ }
+ head = tail = 0;
+ nsectors = 0;
+}
+
+void cdreader::getsector(void *buf, int sec, int nb) throw (GeneralException) {
+ struct cdrom_msf * msf = (struct cdrom_msf *) buf;
+ if (sec >= 0)
+ sector = sec;
+
+ sector += 150;
+
+ msf->cdmsf_min0 = sector /CD_SECS /CD_FRAMES;
+ msf->cdmsf_sec0 = (sector /CD_FRAMES)%CD_SECS;
+ msf->cdmsf_frame0= sector %CD_FRAMES;
+ msf->cdmsf_min1 = (sector + nb)/CD_SECS /CD_FRAMES;
+ msf->cdmsf_sec1 = ((sector + nb)/CD_FRAMES)%CD_SECS;
+ msf->cdmsf_frame1= (sector + nb)%CD_FRAMES;
+
+ sector -= 150;
+
+ if (ioctl(GetHandle(), CDROMREADRAW, buf) < 0) {
+ throw GeneralException(String("unable to read cd sector ") + sector + ": " + strerror(errno));
+ }
+
+ sector += nb;
+}
+#endif
+
+#if defined (_MSC_VER) || defined (__MINGW32__)
+cdreader::cdreader(const String & no) throw (GeneralException) :
+ Handle(-1), n(no), sector(0) {
+ if (!(hFile = cdabstract::OpenIOCTLFile(no[0])))
+ throw GeneralException("Error opening device " + no);
+ for (int i = 0; i < 400000; i++) {
+ sectors[i] = 0;
+ }
+ head = tail = 0;
+ nsectors = 0;
+}
+
+cdreader::cdreader(const cdreader & i) : Handle(i), n(i.n) {
+ hFile = i.hFile;
+ for (int x = 0; x < 400000; x++) {
+ sectors[x] = 0;
+ }
+ head = tail = 0;
+ nsectors = 0;
+}
+
+void cdreader::close() throw (GeneralException) {
+ CloseHandle(hFile);
+}
+
+typedef enum _TRACK_MODE_TYPE {
+ YellowMode2,
+ XAForm2,
+ CDDA
+} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE;
+
+typedef struct _RAW_READ_INFO {
+ LARGE_INTEGER DiskOffset;
+ ULONG SectorCount;
+ TRACK_MODE_TYPE TrackMode;
+} RAW_READ_INFO, *PRAW_READ_INFO;
+
+void cdreader::getsector(void *buf, int sec, int nb) throw (GeneralException) {
+ RAW_READ_INFO rawIOCTL;
+ DWORD dwRet;
+ BOOL bStat;
+ bool done = false;
+ if (sec >= 0)
+ sector = sec;
+
+ rawIOCTL.DiskOffset.QuadPart = sector * 2048;
+ rawIOCTL.SectorCount = nb;
+ rawIOCTL.TrackMode = YellowMode2;
+
+ while (!done) {
+ SetLastError(0);
+ bStat = DeviceIoControl(hFile, IOCTL_CDROM_RAW_READ,
+ &rawIOCTL, sizeof(RAW_READ_INFO),
+ buf, 2352 * nb, &dwRet, NULL);
+ if (!bStat) {
+ DWORD dwErrCode = GetLastError();
+ if (dwErrCode == ERROR_INVALID_FUNCTION) {
+ if (rawIOCTL.TrackMode == YellowMode2) {
+ rawIOCTL.TrackMode = XAForm2;
+ continue;
+ }
+ }
+ if (dwErrCode != ERROR_IO_PENDING) {
+ LPVOID lpMsgBuf;
+ if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf, 0, NULL ))
+ throw GeneralException("Gave up on reading CD: unknown error");
+ String errmsg = (LPCTSTR) lpMsgBuf;
+ LocalFree(lpMsgBuf);
+ throw GeneralException("Gave up on reading CD: " + errmsg);
+ }
+ } else {
+ done = true;
+ }
+ }
+
+ sector += nb;
+}
+
+#endif
diff --git a/lib/cdutils.cpp b/lib/cdutils.cpp
index 953b76e..ea4ff4c 100644
--- a/lib/cdutils.cpp
+++ b/lib/cdutils.cpp
@@ -1,952 +1,952 @@
-/*
- * 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: cdutils.cpp,v 1.32 2004-10-20 07:15:43 pixel Exp $ */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "generic.h"
-#include "cdutils.h"
-#include "Output.h"
-
-const long sec_sizes[7] = {0, 2048, 2336, 2048, 2324, 2352, 2352};
-const long sec_offsts[7] = {0, 16, 16, 24, 24, 0, 0};
-const String sec_modes[7] = {"MODE 0 (empty)", "MODE 1", "MODE 2", "MODE 2 FORM 1", "MODE 2 FORM 2", "Raw", "Autodetect"};
-
-cdutils::cdutils(Handle * r, Handle * w) : rootDir(0), f_iso_r(r), f_iso_w(w), ppf_file(0), pt1(-1), pt2(-1), snum(0), ptl(0), root(0) {}
-
-cdutils::~cdutils() {
- if (ppf_file)
- delete ppf_file;
- free(rootDir);
-}
-
-unsigned char cdutils::from_BCD(unsigned char x) {
- return ((x & 0xf) + ((x & 0xf0) >> 4) * 10);
-}
-
-unsigned char cdutils::to_BCD(unsigned char x) {
- return ((x / 10) << 4) | (x % 10);
-}
-
-bool cdutils::is_valid_BCD(unsigned char x) {
- return (((x & 15) < 10) && ((x >> 4) < 10));
-}
-
-unsigned long cdutils::from_MSF(unsigned char m, unsigned char s, unsigned char f, unsigned long start) {
- return (from_BCD(m) * 60 + from_BCD(s)) * 75 + from_BCD(f) - start;
-}
-
-unsigned long cdutils::from_MSF(unsigned long msf, unsigned long start) {
- unsigned char
- f = msf & 0xff,
- s = (msf >> 8) & 0xff,
- m = (msf >> 16) & 0xff;
-
- return from_MSF(m, s, f, start);
-}
-
-void cdutils::to_MSF(int sect, unsigned char & m, unsigned char & s, unsigned char & f, unsigned long start) {
- sect += start;
- f = to_BCD(sect % 75);
- sect /= 75;
- s = to_BCD(sect % 60);
- m = to_BCD(sect / 60);
-}
-
-unsigned long cdutils::to_MSF(int sect, unsigned long start) {
- unsigned char m, s, f;
- to_MSF(sect, m, s, f, start);
- return f | (s << 8) | (m << 16);
-}
-
-Handle * cdutils::open_ppf(String ppf, String comment) throw (GeneralException) {
- int i, l;
-
- if (ppf_file)
- throw GeneralException("Tried to open_ppf() while already opened.");
- ppf_file = new Output(ppf);
- ppf_file->write("PPF20\001", 6);
-
- l = comment.strlen();
- if (l >= 50) {
- ppf_file->write(comment.to_charp(), 50);
- } else {
- char * t = " ";
- ppf_file->write(comment.to_charp(), l);
- for (i = l; i < 50; i++) {
- ppf_file->write(t, 1);
- }
- }
-
- l = f_iso_r->GetSize();
- ppf_file->write(&l, sizeof(l));
-
- f_iso_r->seek(0x9320, SEEK_SET);
-// copy(f_iso_r, ppf_file, 1024);
- return ppf_file;
-}
-
-void cdutils::write_ppf(Byte * old_sec, Byte * new_sec, int sec_num) {
- int i, l = 0, o;
-
- for (i = 0; i < 2352; i++) {
- if (old_sec[i] == new_sec[i]) {
- if (l != 0) {
- o = 2352 * sec_num + i;
- ppf_file->write(&o, sizeof(o));
- ppf_file->write(&l, 1);
- ppf_file->write(new_sec + i - l - 1, l);
- l = 0;
- }
- } else {
- l++;
- if (l == 255) {
- o = 2352 * sec_num + i;
- ppf_file->write(&o, 4);
- ppf_file->write(&l, 1);
- ppf_file->write(new_sec + i - 255, 255);
- l = 0;
- }
- }
- }
-}
-
-void cdutils::close_ppf() throw (GeneralException) {
- if (ppf_file) {
- delete ppf_file;
- ppf_file = 0;
- } else {
- throw GeneralException("Tried to close_ppf() without previous opening");
- }
-}
-
-void cdutils::set_iso_w(Handle * w) {
- if (!f_iso_w)
- f_iso_w = w;
-}
-
-String cdutils::format_date(String input) {
- String output;
-
- output = input.extract(6, 7) + '/';
- output += input.extract(4, 5) + '/';
- output += input.extract(0, 3) + ' ';
- output += input.extract(8, 9) + ':';
- output += input.extract(10, 11) + ':';
- output += input.extract(12, 13) + '.';
- output += input.extract(14, 15);
- output += String("").set("%+3.1f", ((float) (*((input.to_charp()) + 16))) / 4);
- return output;
-}
-
-Uint16 cdutils::swap_word(Uint16 i) {
- return (i >> 8) | (i << 8);
-}
-
-Uint32 cdutils::swap_dword(Uint32 i) {
- return (i >> 24) | ((i >> 8) & 0x0000ff00) | ((i << 8) & 0x00ff0000) | (i << 24);
-}
-
-int cdutils::guess_type(int number) {
- Byte header[24];
-
- if (number >= 0) {
- sector_seek(number);
- }
-
- f_iso_r->read(header, 24);
- f_iso_r->seek(-24, SEEK_CUR);
- if (header[15] == 1) {
- return MODE_1;
- } else if (header[15] == 2) {
- if (*((unsigned long *) &(header[16])) == *((unsigned long *) &(header[20]))) {
- if ((header[16] == 0) && (header[17] == 0) && (header[19] == 0)) {
- if (header[18] & 0x20) {
- return MODE_2_FORM_2;
- } else {
- return MODE_2_FORM_1;
- }
- }
- }
- return MODE_2;
- }
-
- return MODE_0;
-}
-
-void cdutils::sector_seek(long sector) {
- f_iso_r->seek(2352 * sector);
- if (f_iso_w)
- f_iso_w->seek(2352 * sector);
-}
-
-long cdutils::read_sector(Byte * buffer, int type, int number) {
- try {
- if (number >= 0) {
- sector_seek(number);
- }
-
- if (type == GUESS) {
- type = guess_type();
- }
-
- f_iso_r->seek(sec_offsts[type], SEEK_CUR);
- f_iso_r->read(buffer, sec_sizes[type]);
- f_iso_r->seek(2352 - sec_offsts[type] - sec_sizes[type], SEEK_CUR);
- } catch (GeneralException e) {
- if (number >= 0)
- printm(M_ERROR, "Trouble reading sector %i: %s\n", number, e.GetMsg());
- else
- printm(M_ERROR, "Trouble reading sector: %s\n", e.GetMsg());
-
- if (type != GUESS)
- memset(buffer, 0, sec_sizes[type]);
- return 0;
- }
- return sec_sizes[type];
-}
-
-void cdutils::read_datas(Byte * buffer, long size, int type, int number) {
- Byte sector[2352];
- int i, n, reste;
-
- if (type == GUESS) {
- type = guess_type(number);
- }
-
- n = size / sec_sizes[type];
- reste = size - n * sec_sizes[type];
-
- sector_seek(number);
- for (i = 0; i < n; i++) {
- read_sector(buffer + i * sec_sizes[type], type);
- }
-
- if (reste) {
- read_sector(sector, type);
- bcopy((char *) sector, (char *) (buffer + n * sec_sizes[type]), reste);
- }
-}
-
-void cdutils::read_file(Handle * file, long size, int type, int number) {
- Byte sector[2352];
- int i, n, reste;
-
- if (type == GUESS) {
- type = guess_type(number);
- }
-
- n = size / sec_sizes[type];
- reste = size - n * sec_sizes[type];
-
- for (i = 0; i < n; i++) {
- sector_seek(number + i);
- try {
- read_sector(sector, type);
- }
- catch(...) {
- memset(sector, 0, 2352);
- }
- file->write(sector, sec_sizes[type]);
- }
-
- sector_seek(number + n);
- if (reste) {
- try {
- read_sector(sector, type);
- }
- catch(...) {
- memset(sector, 0, 2352);
- }
- file->write(sector, reste);
- }
-}
-
-void cdutils::write_sector(Byte * buffer, int type, int number) throw (GeneralException) {
- Byte old_sector[2352], new_sector[2352];
-
- if (type == GUESS) {
- type = guess_type(number);
- }
-
- if (number >= 0) {
- sector_seek(number);
- } else {
- number = f_iso_r->tell() / 2352;
- }
-
- f_iso_r->read(old_sector, 2352);
-
- yazedc_o.minute = old_sector[12];
- yazedc_o.second = old_sector[13];
- yazedc_o.frame = old_sector[14];
-
- bcopy((char *) old_sector, (char *) new_sector, 2532);
- bcopy((char *) buffer, (char *) new_sector + sec_offsts[type], sec_sizes[type]);
-
- yazedc_o.do_encode_L2(new_sector, type, 0);
- if (f_iso_w) {
- f_iso_w->write(new_sector, 2352);
- } else if (ppf_file) {
- write_ppf(old_sector, new_sector, number);
- } else {
- throw GeneralException("No writing method for iso file");
- }
-}
-
-void cdutils::write_datas(Byte * buffer, long size, int type, int number) {
- long nbsectors, i;
- unsigned char sector[2352];
-
- if (type == GUESS) {
- type = guess_type(number);
- }
-
- if (number >= 0) {
- sector_seek(number);
- }
-
- nbsectors = size / sec_sizes[type];
-
- for (i = 0; i < nbsectors; i++) {
- write_sector(buffer + i * sec_sizes[type], type, number + i);
- }
-
- if (size % sec_sizes[type]) {
- memset(sector, 0, 2352);
- bcopy((char *) (buffer + i * sec_sizes[type]), (char *) sector, size % sec_sizes[type]);
- write_sector(sector, type, number + i);
- }
-}
-
-void cdutils::write_file(Handle * file, long size, int type, int number) {
- long nbsectors, i;
- unsigned char buffer[2352];
-
- if (type == GUESS) {
- type = guess_type(number);
- }
-
- if (number >= 0) {
- sector_seek(number);
- }
-
- if (size < 0)
- size = file->GetSize();
- nbsectors = size / sec_sizes[type];
-
- if (size % sec_sizes[type]) {
- nbsectors++;
- }
-
- for (i = 0; i < nbsectors; i++) {
- memset(buffer, 0, 2352);
- size = file->read(buffer, sec_sizes[type]);
- write_sector(buffer, type);
- }
-}
-
-void cdutils::create_sector(int type, int number, bool eof) throw (GeneralException) {
- Byte sector[2352];
- if (!f_iso_w)
- throw GeneralException("Can't create sector: ISO not in write mode");
-
- to_MSF(number, yazedc_o.minute, yazedc_o.second, yazedc_o.frame);
- memset(sector, 0, 2352);
- if ((type == MODE2_FORM1) || (type == MODE2_FORM2)) {
- sector[16] = sector[20] = 0; // File Number
- sector[17] = sector[21] = 0; // Channel Number
- sector[18] = sector[22] = 8 | (eof ? 129 : 0) |
- (type == MODE2_FORM2 ? 32 : 0);
- sector[19] = sector[23] = 0; // Coding Info
- }
- yazedc_o.do_encode_L2(sector, type, 0);
-
- f_iso_w->seek(2352 * number);
-
- f_iso_w->write(sector, 2352);
-
- sector_seek(number);
-}
-
-void cdutils::show_head_entry(void) {
- printm(M_BARE, "Sector Size Date Time Flags Name XA flags\n");
-}
-
-int cdutils::show_entry(struct DirEntry * dir) {
- char pbuf[200], pad;
- int s;
- if ((!dir) || (!dir->R)) {
- return 1;
- }
-
- strncpy(pbuf, dir->id, dir->N);
- pbuf[dir->N] = 0;
- if ((dir->N == 1) && (pbuf[0] == 0)) {
- strcpy(pbuf, ".");
- }
- if ((dir->N == 1) && (pbuf[0] == 1)) {
- strcpy(pbuf, "..");
- }
-
- s = 33 + dir->N;
- if (s & 1) {
- s++;
- pad = 1;
- } else {
- pad = 0;
- }
- if (s != dir->R) {
- if ((s + 14) == dir->R) {
- Byte * p;
- p = (Byte *) dir->id + dir->N + pad;
- if ((p[6] == 'X') && (p[7] == 'A')) {
- sprintf(pbuf, "%-14s %c%c%c%c%c", pbuf,
- p[4] & 0x80 ? 'd' : '-',
- p[4] & 0x40 ? 'a' : '-',
- p[4] & 0x20 ? 's' : '-',
- p[4] & 0x10 ? 'x' : '-',
- p[4] & 0x08 ? 'f' : '-');
- }
- }
- }
-
- if (dir->Year < 70)
- dir->Year += 100;
-
- printm(M_BARE, "%6i %9i %2i/%02i/%04i %2i:%02i:%02i%+03.1f %c%c%c%c%c%c%c%c %s\n",
- dir->Sector, dir->Size, dir->Day, dir->Month, dir->Year + 1900, dir->Hour, dir->Minute, dir->Second, ((float) dir->Offset) / 4,
- dir->Flags & 1 ? 'H' : '-', dir->Flags & 2 ? 'D' : '-', dir->Flags & 4 ? 'A' : '-', dir->Flags & 8 ? 'R' : '-',
- dir->Flags & 16 ? 'P' : '-', dir->Flags & 32 ? '1' : '-', dir->Flags & 64 ? '1' : '-', dir->Flags & 128 ? 'C' : '-', pbuf);
- return dir->R;
-}
-
-int cdutils::show_dir(struct DirEntry * dir) {
- unsigned int ptr;
- Byte * buffer;
-
- if (!(dir->Flags & 2)) {
- return 0;
- }
-
- buffer = (Byte *) malloc(dir->Size);
- read_datas(buffer, dir->Size, GUESS, dir->Sector);
-
- ptr = 0;
- while(ptr < dir->Size) {
- ptr += show_entry((struct DirEntry *) &(buffer[ptr]));
- }
-
- free(buffer);
- return 1;
-}
-
-struct cdutils::DirEntry cdutils::find_dir_entry(struct DirEntry * dir, String name) {
- unsigned int ptr, size;
- unsigned char * buffer;
- struct DirEntry r = {0, 0, 0, 0, 0};
-
- if (!(dir->Flags & 2)) {
- return r;
- }
-
- buffer = (unsigned char *) malloc(size = dir->Size);
- read_datas(buffer, dir->Size, GUESS, dir->Sector);
-
- ptr = 0;
- while(ptr < size) {
- dir = (struct DirEntry *) &(buffer[ptr]);
- if (!dir->R) {
- ptr++;
- } else {
- if (!strncmp(name.to_charp(), (char *) &(dir->id), dir->N)) {
- r = *dir;
- }
- ptr += dir->R;
- }
- }
-
- free(buffer);
- return r;
-}
-
-struct cdutils::DirEntry * cdutils::find_dir_entry(Byte ** bufout, struct cdutils::DirEntry * dir, String name) {
- unsigned int ptr, size;
- Byte * buffer;
- struct DirEntry * rdir = 0;
- *bufout = 0;
-
- if (!(dir->Flags & 2)) {
- return 0;
- }
-
- buffer = (Byte *) malloc(size = dir->Size);
- read_datas(buffer, dir->Size, GUESS, dir->Sector);
-
- ptr = 0;
- while(ptr < size) {
- dir = (struct DirEntry *) &(buffer[ptr]);
- if (!dir->R) {
- ptr++;
- } else {
- if (!strncmp(name.to_charp(), (char *) &(dir->id), dir->N)) {
- rdir = dir;
- }
- ptr += dir->R;
- }
- }
-
- if (rdir && rdir->R) {
- free(*bufout);
- *bufout = buffer;
- } else {
- free(buffer);
- rdir = 0;
- }
- return rdir;
-}
-
-int cdutils::show_iso_infos() {
- char buffer[2048];
- char pbuff[130];
- short int s, nogood = 0;
-
- read_sector((Byte *) buffer, GUESS, 16);
-
- printm(M_BARE, "Sector guessed mode : " + sec_modes[guess_type(16)] + "\n");
- printm(M_BARE, "offset-size-info : contents\n");
- printm(M_BARE, " 0 - 1- 1 : %i\n", buffer[0]);
- memcpy(pbuff, buffer + 1, 5);
- pbuff[5] = 0;
- printm(M_BARE, " 1 - 5-`CD001' : %s\n", pbuff);
- printm(M_BARE, " 6 - 2- 1 : %i\n", s = *((short int *) &(buffer[6])));
- printm(M_BARE, "(*this was the signature*)\n");
- if (buffer[0] != 1) nogood = 1;
- if (strcmp(pbuff, "CD001")) nogood = 1;
- if (s != 1) nogood = 1;
-
- if (nogood) {
- printm(M_BARE, "Not a valid iso9660 file.\n");
- return 0;
- }
-
- memcpy(pbuff, buffer + 8, 32);
- pbuff[32] = 0;
- printm(M_BARE, " 8 - 32- SYSID : %s\n", pbuff);
- memcpy(pbuff, buffer + 40, 32);
- pbuff[32] = 0;
- printm(M_BARE, " 40 - 32- VOLID : %s\n", pbuff);
- printm(M_BARE, " 80 - 8- SNum : %li\n", *((long int *) &(buffer[80])));
- printm(M_BARE, " 120 - 4- VOLSiz : %i\n", *((short int *) &(buffer[120])));
- printm(M_BARE, " 124 - 4- VOLNum : %i\n", *((short int *) &(buffer[124])));
- printm(M_BARE, " 128 - 4- SSize : %i\n", *((short int *) &(buffer[128])));
- printm(M_BARE, " 132 - 8- PSize : %li\n", *((long int *) &(buffer[132])));
- printm(M_BARE, " 140 - 4- 1SLPath: %i\n", *((long int *) &(buffer[140])));
- printm(M_BARE, " 144 - 4- 2SLPath: %i\n", *((long int *) &(buffer[144])));
- printm(M_BARE, " 148 - 4- 1SBPath: %i\n", swap_word(*((long int *) &(buffer[150]))));
- printm(M_BARE, " 152 - 4- 2SBPath: %i\n", swap_word(*((long int *) &(buffer[154]))));
- memcpy(pbuff, buffer + 190, 128);
- pbuff[128] = 0;
- printm(M_BARE, " 190 - 128- VStId : %s\n", pbuff);
- memcpy(pbuff, buffer + 318, 128);
- pbuff[128] = 0;
- printm(M_BARE, " 318 - 128- PubId : %s\n", pbuff);
- memcpy(pbuff, buffer + 446, 128);
- pbuff[128] = 0;
- printm(M_BARE, " 446 - 128- DPrId : %s\n", pbuff);
- memcpy(pbuff, buffer + 574, 128);
- pbuff[128] = 0;
- printm(M_BARE, " 574 - 128- AppId : %s\n", pbuff);
- memcpy(pbuff, buffer + 702, 37);
- pbuff[37] = 0;
- printm(M_BARE, " 702 - 37- CpyFile: %s\n", pbuff);
- memcpy(pbuff, buffer + 739, 37);
- pbuff[37] = 0;
- printm(M_BARE, " 739 - 37- AbsFile: %s\n", pbuff);
- memcpy(pbuff, buffer + 776, 37);
- pbuff[37] = 0;
- printm(M_BARE, " 776 - 37- BibFile: %s\n", pbuff);
- printm(M_BARE, " 813 - 17- DTCreat: " + format_date(&buffer[813]) + "\n");
- printm(M_BARE, " 830 - 17- DTModif: " + format_date(&buffer[830]) + "\n");
- printm(M_BARE, " 847 - 17- DTExpir: " + format_date(&buffer[847]) + "\n");
- printm(M_BARE, " 864 - 17- DTEffec: " + format_date(&buffer[864]) + "\n");
-
- printm(M_BARE, "Root record:\n");
- show_head_entry();
- show_entry((DirEntry *) &(buffer[156]));
-
- return 1;
-}
-
-int cdutils::get_iso_infos() {
- Byte buffer[2048];
- char pbuff[130];
- short int s, nogood = 0;
- int rootsec;
-
- read_sector(buffer, GUESS, 16);
-
- memcpy(pbuff, buffer + 1, 5);
- pbuff[5] = 0;
-
- s = *((short int *) &(buffer[6]));
- if (buffer[0] != 1) nogood = 1;
- if (strcmp(pbuff, "CD001")) nogood = 1;
- if (s != 1) nogood = 1;
-
- if (nogood) {
- printm(M_ERROR, "Not a valid iso9660 file.\n");
- return 0;
- }
-
- pt1 = *((short int *) &(buffer[140]));
- pt2 = *((short int *) &(buffer[144]));
- snum = *((int *) &(buffer[80]));
- ptl = *((long int *) &(buffer[132]));
- rootsec = ((struct DirEntry *) (&buffer[156]))->Sector;
- read_sector(buffer, GUESS, rootsec);
- rootDir = (struct DirEntry *) malloc(buffer[0]);
- memcpy(rootDir, buffer, buffer[0]);
- return 1;
-}
-
-int cdutils::get_pt_infos() {
- Byte * buffer;
-
- if ((pt1 <= 0) && (pt2 <= 0))
- if (!get_iso_infos())
- return 0;
-
- if ((!pt1) & (!pt2)) {
- printm(M_ERROR, "No path table defined.\n");
- return 0;
- }
-
- buffer = (Byte *) malloc(ptl);
- read_datas(buffer, ptl, GUESS, !pt1 ? pt2 : pt1);
-
- if (buffer[0] == 1)
- if (buffer[1] == 0)
- if (buffer[6] == 1)
- if (buffer[7] == 0)
- if (buffer[8] == 0)
- if (buffer[9] == 0)
- root = *((unsigned long int *) &(buffer[2]));
-
- free(buffer);
- return root ? 1 : 0;
-}
-
-int cdutils::show_pt_infos() {
- Byte * buffer;
- char pbuf[100];
- int i, ptr;
-
- if ((pt1 <= 0) && (pt2 <= 0))
- if (!get_iso_infos())
- return 0;
-
- if ((!pt1) & (!pt2)) {
- printm(M_ERROR, "No path table defined.\n");
- return 0;
- }
-
- buffer = (Byte *) malloc(ptl + 2);
- read_datas(buffer, ptl, GUESS, !pt1 ? pt2 : pt1);
-
- printm(M_BARE, "node^paren@sector : name\n");
- for (ptr = 0, i = 1; buffer[ptr]; ptr += ptr & 1, i++) {
- strncpy(pbuf, (char *) &(buffer[8 + ptr]), buffer[ptr]);
- pbuf[buffer[ptr]] = 0;
- printm(M_BARE, "%3i ^ %3i @ %6i: %s\n", i, *((unsigned short *) &(buffer[6 + ptr])), *((unsigned long *) &(buffer[2 + ptr])), pbuf);
- ptr += 8 + buffer[ptr];
- }
-
- free(buffer);
- return 1;
-}
-
-struct cdutils::DirEntry cdutils::find_path(String path) {
- char * newpath = path.strdup();
- char ** pts = split(newpath, '/');
- struct DirEntry dir = {0, 0, 0, 0, 0};
-
- if ((pt1 <= 0) && (pt2 <= 0))
- if (!get_iso_infos()) {
- free(newpath);
- return dir;
- }
-
- if ((!pt1) & (!pt2)) {
- printm(M_ERROR, "No path table defined.\n");
- free(newpath);
- return dir;
- }
-
- if (!**pts)
- pts++;
-
- for (dir = *rootDir; *pts; pts++) {
- if (!strlen(*pts))
- continue;
- dir = find_dir_entry(&dir, *pts);
- if (!dir.R) {
- free(newpath);
- return dir;
- }
- }
-
- free(newpath);
- return dir;
-}
-
-struct cdutils::DirEntry cdutils::find_parent(String path) {
- char * newpath = path.strdup();
- char ** pts, * p;
- struct DirEntry dir = {0, 0, 0, 0, 0};
-
- if ((p = strchr(newpath, '/'))) {
- *p = 0;
- }
- if (!*newpath) {
- free(newpath);
- return *rootDir;
- }
- pts = split(newpath, '/');
-
- if ((pt1 <= 0) && (pt2 <= 0))
- if (!get_iso_infos()) {
- free(newpath);
- return dir;
- }
-
- if ((!pt1) & (!pt2)) {
- printm(M_ERROR, "No path table defined.\n");
- free(newpath);
- return dir;
- }
-
- if (!**pts)
- pts++;
-
- for (dir = *rootDir; *pts; pts++) {
- if (!strlen(*pts))
- continue;
- dir = find_dir_entry(&dir, *pts);
- if (!dir.R) {
- free(newpath);
- return dir;
- }
- }
-
- free(newpath);
- return dir;
-}
-
-struct cdutils::DirEntry * cdutils::find_path(Byte ** bufout, String path) {
- char * newpath = path.strdup();
- char ** pts = split(newpath, '/');
- struct DirEntry * dir;
-
- *bufout = 0;
-
- if ((pt1 <= 0) && (pt2 <= 0))
- if (!get_iso_infos()) {
- free(newpath);
- return 0;
- }
-
- if ((!pt1) & (!pt2)) {
- printm(M_ERROR, "No path table defined.\n");
- free(newpath);
- return 0;
- }
-
- if (!**pts)
- pts++;
-
- for (dir = rootDir; *pts; pts++) {
- if (!strlen(*pts))
- continue;
- dir = find_dir_entry(bufout, dir, *pts);
- if (!dir) {
- free(newpath);
- free(*bufout);
- return 0;
- }
- }
-
- if (!dir) {
- free(*bufout);
- }
-
- free(newpath);
- return dir;
-}
-
-struct cdutils::DirEntry * cdutils::find_parent(Byte ** bufout, String path) {
- char * newpath = path.strdup();
- char ** pts, * p;
- struct DirEntry * dir;
-
- *bufout = 0;
-
- if ((p = strchr(newpath, '/'))) {
- *p = 0;
- }
- if (!*newpath) {
- free(newpath);
- return rootDir;
- }
- pts = split(newpath, '/');
-
- if ((pt1 <= 0) && (pt2 <= 0))
- if (!get_iso_infos()) {
- free(newpath);
- return 0;
- }
-
- if ((!pt1) & (!pt2)) {
- printm(M_ERROR, "No path table defined.\n");
- free(newpath);
- return 0;
- }
-
- if (!**pts)
- pts++;
-
- for (dir = rootDir; *pts; pts++) {
- free(*bufout);
- if (!strlen(*pts))
- continue;
- dir = find_dir_entry(bufout, dir, *pts);
- if (!dir) {
- free(newpath);
- return dir;
- }
- }
-
- if (!dir) {
- free(*bufout);
- }
-
- free(newpath);
- return dir;
-}
-
-cdfile::cdfile(cdutils * _cd, const cdutils::DirEntry * d, int _mode) : Handle(-1), cd(_cd), sector(d->Sector), mode(_mode), size(d->Size), name(d->id) {
- if (mode == GUESS) {
- mode = cd->guess_type(sector);
- }
- dir = (cdutils::DirEntry *) malloc(d->R);
- memcpy(dir, d, d->R);
- itell = 0;
-}
-
-cdfile::cdfile(cdutils * _cd, int _sector, ssize_t _size, int _mode) : Handle(-1), cd(_cd), sector(_sector), mode(_mode), size(_size), name("raw reading") {
- 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;
-}
-
-cdfile::~cdfile() {
- free(dir);
-}
-
-ssize_t cdfile::read(void *buf, size_t count) throw (GeneralException) {
- Byte buffer[2352];
- size_t startsec, startbyte, nstartbytes;
-
- count = MIN(count, (size_t) (size - itell));
-
- if (!count) {
- close();
- return 0;
- }
-
- startsec = itell / sec_sizes[mode] + sector;
- startbyte = itell % sec_sizes[mode];
- nstartbytes = sec_sizes[mode] - startbyte;
- nstartbytes = MIN(nstartbytes, count);
- count -= nstartbytes;
-
- cd->read_sector(buffer, mode, startsec);
- memcpy(buf, buffer + startbyte, nstartbytes);
- buf = (Byte *) buf + nstartbytes;
-
- if (count) {
- cd->read_datas((Byte *) buf, count, mode, startsec + 1);
- }
-
- itell += count + nstartbytes;
-
- return count + nstartbytes;
-}
-
-bool cdfile::CanRead() const {
- return true;
-}
-
-String cdfile::GetName() const {
- return String("cdfile: ") + name;
-}
-
-bool cdfile::CanWatch() const {
- return false;
-}
-
-ssize_t cdfile::GetSize() const {
- return size;
-}
-
-bool cdfile::CanSeek() const {
- return true;
-}
-
-off_t cdfile::seek(off_t off, int wheel) throw (GeneralException) {
- switch (wheel) {
- case SEEK_SET:
- itell = off;
- break;
- case SEEK_CUR:
- itell += off;
- break;
- case SEEK_END:
- itell = size + off;
- break;
- }
- return itell;
-}
+/*
+ * 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: cdutils.cpp,v 1.33 2004-11-27 21:47:56 pixel Exp $ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "generic.h"
+#include "cdutils.h"
+#include "Output.h"
+
+const long sec_sizes[7] = {0, 2048, 2336, 2048, 2324, 2352, 2352};
+const long sec_offsts[7] = {0, 16, 16, 24, 24, 0, 0};
+const String sec_modes[7] = {"MODE 0 (empty)", "MODE 1", "MODE 2", "MODE 2 FORM 1", "MODE 2 FORM 2", "Raw", "Autodetect"};
+
+cdutils::cdutils(Handle * r, Handle * w) : rootDir(0), f_iso_r(r), f_iso_w(w), ppf_file(0), pt1(-1), pt2(-1), snum(0), ptl(0), root(0) {}
+
+cdutils::~cdutils() {
+ if (ppf_file)
+ delete ppf_file;
+ free(rootDir);
+}
+
+unsigned char cdutils::from_BCD(unsigned char x) {
+ return ((x & 0xf) + ((x & 0xf0) >> 4) * 10);
+}
+
+unsigned char cdutils::to_BCD(unsigned char x) {
+ return ((x / 10) << 4) | (x % 10);
+}
+
+bool cdutils::is_valid_BCD(unsigned char x) {
+ return (((x & 15) < 10) && ((x >> 4) < 10));
+}
+
+unsigned long cdutils::from_MSF(unsigned char m, unsigned char s, unsigned char f, unsigned long start) {
+ return (from_BCD(m) * 60 + from_BCD(s)) * 75 + from_BCD(f) - start;
+}
+
+unsigned long cdutils::from_MSF(unsigned long msf, unsigned long start) {
+ unsigned char
+ f = msf & 0xff,
+ s = (msf >> 8) & 0xff,
+ m = (msf >> 16) & 0xff;
+
+ return from_MSF(m, s, f, start);
+}
+
+void cdutils::to_MSF(int sect, unsigned char & m, unsigned char & s, unsigned char & f, unsigned long start) {
+ sect += start;
+ f = to_BCD(sect % 75);
+ sect /= 75;
+ s = to_BCD(sect % 60);
+ m = to_BCD(sect / 60);
+}
+
+unsigned long cdutils::to_MSF(int sect, unsigned long start) {
+ unsigned char m, s, f;
+ to_MSF(sect, m, s, f, start);
+ return f | (s << 8) | (m << 16);
+}
+
+Handle * cdutils::open_ppf(String ppf, String comment) throw (GeneralException) {
+ int i, l;
+
+ if (ppf_file)
+ throw GeneralException("Tried to open_ppf() while already opened.");
+ ppf_file = new Output(ppf);
+ ppf_file->write("PPF20\001", 6);
+
+ l = comment.strlen();
+ if (l >= 50) {
+ ppf_file->write(comment.to_charp(), 50);
+ } else {
+ char * t = " ";
+ ppf_file->write(comment.to_charp(), l);
+ for (i = l; i < 50; i++) {
+ ppf_file->write(t, 1);
+ }
+ }
+
+ l = f_iso_r->GetSize();
+ ppf_file->write(&l, sizeof(l));
+
+ f_iso_r->seek(0x9320, SEEK_SET);
+// copy(f_iso_r, ppf_file, 1024);
+ return ppf_file;
+}
+
+void cdutils::write_ppf(Byte * old_sec, Byte * new_sec, int sec_num) {
+ int i, l = 0, o;
+
+ for (i = 0; i < 2352; i++) {
+ if (old_sec[i] == new_sec[i]) {
+ if (l != 0) {
+ o = 2352 * sec_num + i;
+ ppf_file->write(&o, sizeof(o));
+ ppf_file->write(&l, 1);
+ ppf_file->write(new_sec + i - l - 1, l);
+ l = 0;
+ }
+ } else {
+ l++;
+ if (l == 255) {
+ o = 2352 * sec_num + i;
+ ppf_file->write(&o, 4);
+ ppf_file->write(&l, 1);
+ ppf_file->write(new_sec + i - 255, 255);
+ l = 0;
+ }
+ }
+ }
+}
+
+void cdutils::close_ppf() throw (GeneralException) {
+ if (ppf_file) {
+ delete ppf_file;
+ ppf_file = 0;
+ } else {
+ throw GeneralException("Tried to close_ppf() without previous opening");
+ }
+}
+
+void cdutils::set_iso_w(Handle * w) {
+ if (!f_iso_w)
+ f_iso_w = w;
+}
+
+String cdutils::format_date(String input) {
+ String output;
+
+ output = input.extract(6, 7) + '/';
+ output += input.extract(4, 5) + '/';
+ output += input.extract(0, 3) + ' ';
+ output += input.extract(8, 9) + ':';
+ output += input.extract(10, 11) + ':';
+ output += input.extract(12, 13) + '.';
+ output += input.extract(14, 15);
+ output += String("").set("%+3.1f", ((float) (*((input.to_charp()) + 16))) / 4);
+ return output;
+}
+
+Uint16 cdutils::swap_word(Uint16 i) {
+ return (i >> 8) | (i << 8);
+}
+
+Uint32 cdutils::swap_dword(Uint32 i) {
+ return (i >> 24) | ((i >> 8) & 0x0000ff00) | ((i << 8) & 0x00ff0000) | (i << 24);
+}
+
+int cdutils::guess_type(int number) {
+ Byte header[24];
+
+ if (number >= 0) {
+ sector_seek(number);
+ }
+
+ f_iso_r->read(header, 24);
+ f_iso_r->seek(-24, SEEK_CUR);
+ if (header[15] == 1) {
+ return MODE_1;
+ } else if (header[15] == 2) {
+ if (*((unsigned long *) &(header[16])) == *((unsigned long *) &(header[20]))) {
+ if ((header[16] == 0) && (header[17] == 0) && (header[19] == 0)) {
+ if (header[18] & 0x20) {
+ return MODE_2_FORM_2;
+ } else {
+ return MODE_2_FORM_1;
+ }
+ }
+ }
+ return MODE_2;
+ }
+
+ return MODE_0;
+}
+
+void cdutils::sector_seek(long sector) {
+ f_iso_r->seek(2352 * sector);
+ if (f_iso_w)
+ f_iso_w->seek(2352 * sector);
+}
+
+long cdutils::read_sector(Byte * buffer, int type, int number) {
+ try {
+ if (number >= 0) {
+ sector_seek(number);
+ }
+
+ if (type == GUESS) {
+ type = guess_type();
+ }
+
+ f_iso_r->seek(sec_offsts[type], SEEK_CUR);
+ f_iso_r->read(buffer, sec_sizes[type]);
+ f_iso_r->seek(2352 - sec_offsts[type] - sec_sizes[type], SEEK_CUR);
+ } catch (GeneralException e) {
+ if (number >= 0)
+ printm(M_ERROR, "Trouble reading sector %i: %s\n", number, e.GetMsg());
+ else
+ printm(M_ERROR, "Trouble reading sector: %s\n", e.GetMsg());
+
+ if (type != GUESS)
+ memset(buffer, 0, sec_sizes[type]);
+ return 0;
+ }
+ return sec_sizes[type];
+}
+
+void cdutils::read_datas(Byte * buffer, long size, int type, int number) {
+ Byte sector[2352];
+ int i, n, reste;
+
+ if (type == GUESS) {
+ type = guess_type(number);
+ }
+
+ n = size / sec_sizes[type];
+ reste = size - n * sec_sizes[type];
+
+ sector_seek(number);
+ for (i = 0; i < n; i++) {
+ read_sector(buffer + i * sec_sizes[type], type);
+ }
+
+ if (reste) {
+ read_sector(sector, type);
+ bcopy((char *) sector, (char *) (buffer + n * sec_sizes[type]), reste);
+ }
+}
+
+void cdutils::read_file(Handle * file, long size, int type, int number) {
+ Byte sector[2352];
+ int i, n, reste;
+
+ if (type == GUESS) {
+ type = guess_type(number);
+ }
+
+ n = size / sec_sizes[type];
+ reste = size - n * sec_sizes[type];
+
+ for (i = 0; i < n; i++) {
+ sector_seek(number + i);
+ try {
+ read_sector(sector, type);
+ }
+ catch(...) {
+ memset(sector, 0, 2352);
+ }
+ file->write(sector, sec_sizes[type]);
+ }
+
+ sector_seek(number + n);
+ if (reste) {
+ try {
+ read_sector(sector, type);
+ }
+ catch(...) {
+ memset(sector, 0, 2352);
+ }
+ file->write(sector, reste);
+ }
+}
+
+void cdutils::write_sector(Byte * buffer, int type, int number) throw (GeneralException) {
+ Byte old_sector[2352], new_sector[2352];
+
+ if (type == GUESS) {
+ type = guess_type(number);
+ }
+
+ if (number >= 0) {
+ sector_seek(number);
+ } else {
+ number = f_iso_r->tell() / 2352;
+ }
+
+ f_iso_r->read(old_sector, 2352);
+
+ yazedc_o.minute = old_sector[12];
+ yazedc_o.second = old_sector[13];
+ yazedc_o.frame = old_sector[14];
+
+ bcopy((char *) old_sector, (char *) new_sector, 2532);
+ bcopy((char *) buffer, (char *) new_sector + sec_offsts[type], sec_sizes[type]);
+
+ yazedc_o.do_encode_L2(new_sector, type, 0);
+ if (f_iso_w) {
+ f_iso_w->write(new_sector, 2352);
+ } else if (ppf_file) {
+ write_ppf(old_sector, new_sector, number);
+ } else {
+ throw GeneralException("No writing method for iso file");
+ }
+}
+
+void cdutils::write_datas(Byte * buffer, long size, int type, int number) {
+ long nbsectors, i;
+ unsigned char sector[2352];
+
+ if (type == GUESS) {
+ type = guess_type(number);
+ }
+
+ if (number >= 0) {
+ sector_seek(number);
+ }
+
+ nbsectors = size / sec_sizes[type];
+
+ for (i = 0; i < nbsectors; i++) {
+ write_sector(buffer + i * sec_sizes[type], type, number + i);
+ }
+
+ if (size % sec_sizes[type]) {
+ memset(sector, 0, 2352);
+ bcopy((char *) (buffer + i * sec_sizes[type]), (char *) sector, size % sec_sizes[type]);
+ write_sector(sector, type, number + i);
+ }
+}
+
+void cdutils::write_file(Handle * file, long size, int type, int number) {
+ long nbsectors, i;
+ unsigned char buffer[2352];
+
+ if (type == GUESS) {
+ type = guess_type(number);
+ }
+
+ if (number >= 0) {
+ sector_seek(number);
+ }
+
+ if (size < 0)
+ size = file->GetSize();
+ nbsectors = size / sec_sizes[type];
+
+ if (size % sec_sizes[type]) {
+ nbsectors++;
+ }
+
+ for (i = 0; i < nbsectors; i++) {
+ memset(buffer, 0, 2352);
+ size = file->read(buffer, sec_sizes[type]);
+ write_sector(buffer, type);
+ }
+}
+
+void cdutils::create_sector(int type, int number, bool eof) throw (GeneralException) {
+ Byte sector[2352];
+ if (!f_iso_w)
+ throw GeneralException("Can't create sector: ISO not in write mode");
+
+ to_MSF(number, yazedc_o.minute, yazedc_o.second, yazedc_o.frame);
+ memset(sector, 0, 2352);
+ if ((type == MODE2_FORM1) || (type == MODE2_FORM2)) {
+ sector[16] = sector[20] = 0; // File Number
+ sector[17] = sector[21] = 0; // Channel Number
+ sector[18] = sector[22] = 8 | (eof ? 129 : 0) |
+ (type == MODE2_FORM2 ? 32 : 0);
+ sector[19] = sector[23] = 0; // Coding Info
+ }
+ yazedc_o.do_encode_L2(sector, type, 0);
+
+ f_iso_w->seek(2352 * number);
+
+ f_iso_w->write(sector, 2352);
+
+ sector_seek(number);
+}
+
+void cdutils::show_head_entry(void) {
+ printm(M_BARE, "Sector Size Date Time Flags Name XA flags\n");
+}
+
+int cdutils::show_entry(struct DirEntry * dir) {
+ char pbuf[200], pad;
+ int s;
+ if ((!dir) || (!dir->R)) {
+ return 1;
+ }
+
+ strncpy(pbuf, dir->id, dir->N);
+ pbuf[dir->N] = 0;
+ if ((dir->N == 1) && (pbuf[0] == 0)) {
+ strcpy(pbuf, ".");
+ }
+ if ((dir->N == 1) && (pbuf[0] == 1)) {
+ strcpy(pbuf, "..");
+ }
+
+ s = 33 + dir->N;
+ if (s & 1) {
+ s++;
+ pad = 1;
+ } else {
+ pad = 0;
+ }
+ if (s != dir->R) {
+ if ((s + 14) == dir->R) {
+ Byte * p;
+ p = (Byte *) dir->id + dir->N + pad;
+ if ((p[6] == 'X') && (p[7] == 'A')) {
+ sprintf(pbuf, "%-14s %c%c%c%c%c", pbuf,
+ p[4] & 0x80 ? 'd' : '-',
+ p[4] & 0x40 ? 'a' : '-',
+ p[4] & 0x20 ? 's' : '-',
+ p[4] & 0x10 ? 'x' : '-',
+ p[4] & 0x08 ? 'f' : '-');
+ }
+ }
+ }
+
+ if (dir->Year < 70)
+ dir->Year += 100;
+
+ printm(M_BARE, "%6i %9i %2i/%02i/%04i %2i:%02i:%02i%+03.1f %c%c%c%c%c%c%c%c %s\n",
+ dir->Sector, dir->Size, dir->Day, dir->Month, dir->Year + 1900, dir->Hour, dir->Minute, dir->Second, ((float) dir->Offset) / 4,
+ dir->Flags & 1 ? 'H' : '-', dir->Flags & 2 ? 'D' : '-', dir->Flags & 4 ? 'A' : '-', dir->Flags & 8 ? 'R' : '-',
+ dir->Flags & 16 ? 'P' : '-', dir->Flags & 32 ? '1' : '-', dir->Flags & 64 ? '1' : '-', dir->Flags & 128 ? 'C' : '-', pbuf);
+ return dir->R;
+}
+
+int cdutils::show_dir(struct DirEntry * dir) {
+ unsigned int ptr;
+ Byte * buffer;
+
+ if (!(dir->Flags & 2)) {
+ return 0;
+ }
+
+ buffer = (Byte *) malloc(dir->Size);
+ read_datas(buffer, dir->Size, GUESS, dir->Sector);
+
+ ptr = 0;
+ while(ptr < dir->Size) {
+ ptr += show_entry((struct DirEntry *) &(buffer[ptr]));
+ }
+
+ free(buffer);
+ return 1;
+}
+
+struct cdutils::DirEntry cdutils::find_dir_entry(struct DirEntry * dir, String name) {
+ unsigned int ptr, size;
+ unsigned char * buffer;
+ struct DirEntry r = {0, 0, 0, 0, 0};
+
+ if (!(dir->Flags & 2)) {
+ return r;
+ }
+
+ buffer = (unsigned char *) malloc(size = dir->Size);
+ read_datas(buffer, dir->Size, GUESS, dir->Sector);
+
+ ptr = 0;
+ while(ptr < size) {
+ dir = (struct DirEntry *) &(buffer[ptr]);
+ if (!dir->R) {
+ ptr++;
+ } else {
+ if (!strncmp(name.to_charp(), (char *) &(dir->id), dir->N)) {
+ r = *dir;
+ }
+ ptr += dir->R;
+ }
+ }
+
+ free(buffer);
+ return r;
+}
+
+struct cdutils::DirEntry * cdutils::find_dir_entry(Byte ** bufout, struct cdutils::DirEntry * dir, String name) {
+ unsigned int ptr, size;
+ Byte * buffer;
+ struct DirEntry * rdir = 0;
+ *bufout = 0;
+
+ if (!(dir->Flags & 2)) {
+ return 0;
+ }
+
+ buffer = (Byte *) malloc(size = dir->Size);
+ read_datas(buffer, dir->Size, GUESS, dir->Sector);
+
+ ptr = 0;
+ while(ptr < size) {
+ dir = (struct DirEntry *) &(buffer[ptr]);
+ if (!dir->R) {
+ ptr++;
+ } else {
+ if (!strncmp(name.to_charp(), (char *) &(dir->id), dir->N)) {
+ rdir = dir;
+ }
+ ptr += dir->R;
+ }
+ }
+
+ if (rdir && rdir->R) {
+ free(*bufout);
+ *bufout = buffer;
+ } else {
+ free(buffer);
+ rdir = 0;
+ }
+ return rdir;
+}
+
+int cdutils::show_iso_infos() {
+ char buffer[2048];
+ char pbuff[130];
+ short int s, nogood = 0;
+
+ read_sector((Byte *) buffer, GUESS, 16);
+
+ printm(M_BARE, "Sector guessed mode : " + sec_modes[guess_type(16)] + "\n");
+ printm(M_BARE, "offset-size-info : contents\n");
+ printm(M_BARE, " 0 - 1- 1 : %i\n", buffer[0]);
+ memcpy(pbuff, buffer + 1, 5);
+ pbuff[5] = 0;
+ printm(M_BARE, " 1 - 5-`CD001' : %s\n", pbuff);
+ printm(M_BARE, " 6 - 2- 1 : %i\n", s = *((short int *) &(buffer[6])));
+ printm(M_BARE, "(*this was the signature*)\n");
+ if (buffer[0] != 1) nogood = 1;
+ if (strcmp(pbuff, "CD001")) nogood = 1;
+ if (s != 1) nogood = 1;
+
+ if (nogood) {
+ printm(M_BARE, "Not a valid iso9660 file.\n");
+ return 0;
+ }
+
+ memcpy(pbuff, buffer + 8, 32);
+ pbuff[32] = 0;
+ printm(M_BARE, " 8 - 32- SYSID : %s\n", pbuff);
+ memcpy(pbuff, buffer + 40, 32);
+ pbuff[32] = 0;
+ printm(M_BARE, " 40 - 32- VOLID : %s\n", pbuff);
+ printm(M_BARE, " 80 - 8- SNum : %li\n", *((long int *) &(buffer[80])));
+ printm(M_BARE, " 120 - 4- VOLSiz : %i\n", *((short int *) &(buffer[120])));
+ printm(M_BARE, " 124 - 4- VOLNum : %i\n", *((short int *) &(buffer[124])));
+ printm(M_BARE, " 128 - 4- SSize : %i\n", *((short int *) &(buffer[128])));
+ printm(M_BARE, " 132 - 8- PSize : %li\n", *((long int *) &(buffer[132])));
+ printm(M_BARE, " 140 - 4- 1SLPath: %i\n", *((long int *) &(buffer[140])));
+ printm(M_BARE, " 144 - 4- 2SLPath: %i\n", *((long int *) &(buffer[144])));
+ printm(M_BARE, " 148 - 4- 1SBPath: %i\n", swap_word(*((long int *) &(buffer[150]))));
+ printm(M_BARE, " 152 - 4- 2SBPath: %i\n", swap_word(*((long int *) &(buffer[154]))));
+ memcpy(pbuff, buffer + 190, 128);
+ pbuff[128] = 0;
+ printm(M_BARE, " 190 - 128- VStId : %s\n", pbuff);
+ memcpy(pbuff, buffer + 318, 128);
+ pbuff[128] = 0;
+ printm(M_BARE, " 318 - 128- PubId : %s\n", pbuff);
+ memcpy(pbuff, buffer + 446, 128);
+ pbuff[128] = 0;
+ printm(M_BARE, " 446 - 128- DPrId : %s\n", pbuff);
+ memcpy(pbuff, buffer + 574, 128);
+ pbuff[128] = 0;
+ printm(M_BARE, " 574 - 128- AppId : %s\n", pbuff);
+ memcpy(pbuff, buffer + 702, 37);
+ pbuff[37] = 0;
+ printm(M_BARE, " 702 - 37- CpyFile: %s\n", pbuff);
+ memcpy(pbuff, buffer + 739, 37);
+ pbuff[37] = 0;
+ printm(M_BARE, " 739 - 37- AbsFile: %s\n", pbuff);
+ memcpy(pbuff, buffer + 776, 37);
+ pbuff[37] = 0;
+ printm(M_BARE, " 776 - 37- BibFile: %s\n", pbuff);
+ printm(M_BARE, " 813 - 17- DTCreat: " + format_date(&buffer[813]) + "\n");
+ printm(M_BARE, " 830 - 17- DTModif: " + format_date(&buffer[830]) + "\n");
+ printm(M_BARE, " 847 - 17- DTExpir: " + format_date(&buffer[847]) + "\n");
+ printm(M_BARE, " 864 - 17- DTEffec: " + format_date(&buffer[864]) + "\n");
+
+ printm(M_BARE, "Root record:\n");
+ show_head_entry();
+ show_entry((DirEntry *) &(buffer[156]));
+
+ return 1;
+}
+
+int cdutils::get_iso_infos() {
+ Byte buffer[2048];
+ char pbuff[130];
+ short int s, nogood = 0;
+ int rootsec;
+
+ read_sector(buffer, GUESS, 16);
+
+ memcpy(pbuff, buffer + 1, 5);
+ pbuff[5] = 0;
+
+ s = *((short int *) &(buffer[6]));
+ if (buffer[0] != 1) nogood = 1;
+ if (strcmp(pbuff, "CD001")) nogood = 1;
+ if (s != 1) nogood = 1;
+
+ if (nogood) {
+ printm(M_ERROR, "Not a valid iso9660 file.\n");
+ return 0;
+ }
+
+ pt1 = *((short int *) &(buffer[140]));
+ pt2 = *((short int *) &(buffer[144]));
+ snum = *((int *) &(buffer[80]));
+ ptl = *((long int *) &(buffer[132]));
+ rootsec = ((struct DirEntry *) (&buffer[156]))->Sector;
+ read_sector(buffer, GUESS, rootsec);
+ rootDir = (struct DirEntry *) malloc(buffer[0]);
+ memcpy(rootDir, buffer, buffer[0]);
+ return 1;
+}
+
+int cdutils::get_pt_infos() {
+ Byte * buffer;
+
+ if ((pt1 <= 0) && (pt2 <= 0))
+ if (!get_iso_infos())
+ return 0;
+
+ if ((!pt1) & (!pt2)) {
+ printm(M_ERROR, "No path table defined.\n");
+ return 0;
+ }
+
+ buffer = (Byte *) malloc(ptl);
+ read_datas(buffer, ptl, GUESS, !pt1 ? pt2 : pt1);
+
+ if (buffer[0] == 1)
+ if (buffer[1] == 0)
+ if (buffer[6] == 1)
+ if (buffer[7] == 0)
+ if (buffer[8] == 0)
+ if (buffer[9] == 0)
+ root = *((unsigned long int *) &(buffer[2]));
+
+ free(buffer);
+ return root ? 1 : 0;
+}
+
+int cdutils::show_pt_infos() {
+ Byte * buffer;
+ char pbuf[100];
+ int i, ptr;
+
+ if ((pt1 <= 0) && (pt2 <= 0))
+ if (!get_iso_infos())
+ return 0;
+
+ if ((!pt1) & (!pt2)) {
+ printm(M_ERROR, "No path table defined.\n");
+ return 0;
+ }
+
+ buffer = (Byte *) malloc(ptl + 2);
+ read_datas(buffer, ptl, GUESS, !pt1 ? pt2 : pt1);
+
+ printm(M_BARE, "node^paren@sector : name\n");
+ for (ptr = 0, i = 1; buffer[ptr]; ptr += ptr & 1, i++) {
+ strncpy(pbuf, (char *) &(buffer[8 + ptr]), buffer[ptr]);
+ pbuf[buffer[ptr]] = 0;
+ printm(M_BARE, "%3i ^ %3i @ %6i: %s\n", i, *((unsigned short *) &(buffer[6 + ptr])), *((unsigned long *) &(buffer[2 + ptr])), pbuf);
+ ptr += 8 + buffer[ptr];
+ }
+
+ free(buffer);
+ return 1;
+}
+
+struct cdutils::DirEntry cdutils::find_path(String path) {
+ char * newpath = path.strdup();
+ char ** pts = split(newpath, '/');
+ struct DirEntry dir = {0, 0, 0, 0, 0};
+
+ if ((pt1 <= 0) && (pt2 <= 0))
+ if (!get_iso_infos()) {
+ free(newpath);
+ return dir;
+ }
+
+ if ((!pt1) & (!pt2)) {
+ printm(M_ERROR, "No path table defined.\n");
+ free(newpath);
+ return dir;
+ }
+
+ if (!**pts)
+ pts++;
+
+ for (dir = *rootDir; *pts; pts++) {
+ if (!strlen(*pts))
+ continue;
+ dir = find_dir_entry(&dir, *pts);
+ if (!dir.R) {
+ free(newpath);
+ return dir;
+ }
+ }
+
+ free(newpath);
+ return dir;
+}
+
+struct cdutils::DirEntry cdutils::find_parent(String path) {
+ char * newpath = path.strdup();
+ char ** pts, * p;
+ struct DirEntry dir = {0, 0, 0, 0, 0};
+
+ if ((p = strchr(newpath, '/'))) {
+ *p = 0;
+ }
+ if (!*newpath) {
+ free(newpath);
+ return *rootDir;
+ }
+ pts = split(newpath, '/');
+
+ if ((pt1 <= 0) && (pt2 <= 0))
+ if (!get_iso_infos()) {
+ free(newpath);
+ return dir;
+ }
+
+ if ((!pt1) & (!pt2)) {
+ printm(M_ERROR, "No path table defined.\n");
+ free(newpath);
+ return dir;
+ }
+
+ if (!**pts)
+ pts++;
+
+ for (dir = *rootDir; *pts; pts++) {
+ if (!strlen(*pts))
+ continue;
+ dir = find_dir_entry(&dir, *pts);
+ if (!dir.R) {
+ free(newpath);
+ return dir;
+ }
+ }
+
+ free(newpath);
+ return dir;
+}
+
+struct cdutils::DirEntry * cdutils::find_path(Byte ** bufout, String path) {
+ char * newpath = path.strdup();
+ char ** pts = split(newpath, '/');
+ struct DirEntry * dir;
+
+ *bufout = 0;
+
+ if ((pt1 <= 0) && (pt2 <= 0))
+ if (!get_iso_infos()) {
+ free(newpath);
+ return 0;
+ }
+
+ if ((!pt1) & (!pt2)) {
+ printm(M_ERROR, "No path table defined.\n");
+ free(newpath);
+ return 0;
+ }
+
+ if (!**pts)
+ pts++;
+
+ for (dir = rootDir; *pts; pts++) {
+ if (!strlen(*pts))
+ continue;
+ dir = find_dir_entry(bufout, dir, *pts);
+ if (!dir) {
+ free(newpath);
+ free(*bufout);
+ return 0;
+ }
+ }
+
+ if (!dir) {
+ free(*bufout);
+ }
+
+ free(newpath);
+ return dir;
+}
+
+struct cdutils::DirEntry * cdutils::find_parent(Byte ** bufout, String path) {
+ char * newpath = path.strdup();
+ char ** pts, * p;
+ struct DirEntry * dir;
+
+ *bufout = 0;
+
+ if ((p = strchr(newpath, '/'))) {
+ *p = 0;
+ }
+ if (!*newpath) {
+ free(newpath);
+ return rootDir;
+ }
+ pts = split(newpath, '/');
+
+ if ((pt1 <= 0) && (pt2 <= 0))
+ if (!get_iso_infos()) {
+ free(newpath);
+ return 0;
+ }
+
+ if ((!pt1) & (!pt2)) {
+ printm(M_ERROR, "No path table defined.\n");
+ free(newpath);
+ return 0;
+ }
+
+ if (!**pts)
+ pts++;
+
+ for (dir = rootDir; *pts; pts++) {
+ free(*bufout);
+ if (!strlen(*pts))
+ continue;
+ dir = find_dir_entry(bufout, dir, *pts);
+ if (!dir) {
+ free(newpath);
+ return dir;
+ }
+ }
+
+ if (!dir) {
+ free(*bufout);
+ }
+
+ free(newpath);
+ return dir;
+}
+
+cdfile::cdfile(cdutils * _cd, const cdutils::DirEntry * d, int _mode) : Handle(-1), cd(_cd), sector(d->Sector), mode(_mode), size(d->Size), name(d->id) {
+ if (mode == GUESS) {
+ mode = cd->guess_type(sector);
+ }
+ dir = (cdutils::DirEntry *) malloc(d->R);
+ memcpy(dir, d, d->R);
+ itell = 0;
+}
+
+cdfile::cdfile(cdutils * _cd, int _sector, ssize_t _size, int _mode) : Handle(-1), cd(_cd), sector(_sector), mode(_mode), size(_size), name("raw reading") {
+ 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;
+}
+
+cdfile::~cdfile() {
+ free(dir);
+}
+
+ssize_t cdfile::read(void *buf, size_t count) throw (GeneralException) {
+ Byte buffer[2352];
+ size_t startsec, startbyte, nstartbytes;
+
+ count = MIN(count, (size_t) (size - itell));
+
+ if (!count) {
+ close();
+ return 0;
+ }
+
+ startsec = itell / sec_sizes[mode] + sector;
+ startbyte = itell % sec_sizes[mode];
+ nstartbytes = sec_sizes[mode] - startbyte;
+ nstartbytes = MIN(nstartbytes, count);
+ count -= nstartbytes;
+
+ cd->read_sector(buffer, mode, startsec);
+ memcpy(buf, buffer + startbyte, nstartbytes);
+ buf = (Byte *) buf + nstartbytes;
+
+ if (count) {
+ cd->read_datas((Byte *) buf, count, mode, startsec + 1);
+ }
+
+ itell += count + nstartbytes;
+
+ return count + nstartbytes;
+}
+
+bool cdfile::CanRead() const {
+ return true;
+}
+
+String cdfile::GetName() const {
+ return String("cdfile: ") + name;
+}
+
+bool cdfile::CanWatch() const {
+ return false;
+}
+
+ssize_t cdfile::GetSize() const {
+ return size;
+}
+
+bool cdfile::CanSeek() const {
+ return true;
+}
+
+off_t cdfile::seek(off_t off, int wheel) throw (GeneralException) {
+ switch (wheel) {
+ case SEEK_SET:
+ itell = off;
+ break;
+ case SEEK_CUR:
+ itell += off;
+ break;
+ case SEEK_END:
+ itell = size + off;
+ break;
+ }
+ return itell;
+}
diff --git a/lib/dteutils.cpp b/lib/dteutils.cpp
index 42f36bf..85a7df2 100644
--- a/lib/dteutils.cpp
+++ b/lib/dteutils.cpp
@@ -1,319 +1,319 @@
-/*
- * PSX-Tools Bundle Pack
- * Copyright (C) 2002 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
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include "generic.h"
-#include "Handle.h"
-
-class thingtree : public Base {
- public:
- static void addstring(const String, long);
- static long look(const String);
- static void destroy();
- private:
- thingtree();
- thingtree(char, bool, thingtree *, long);
- ~thingtree();
- char thischar;
- bool terminal;
- thingtree * father, * child, * brother;
- long thingentry;
- static thingtree * root;
-};
-
-thingtree * thingtree::root = 0;
-
-thingtree::thingtree(char gchar, bool gterm, thingtree * gfather, long gthingentry) : thischar(gchar), terminal(gterm), thingentry(gthingentry) {
- if (!gfather) {
- if (!root) {
- root = new thingtree();
- }
- father = root;
- } else {
- father = gfather;
- }
- brother = father->child;
- father->child = this;
-}
-
-thingtree::thingtree() : thischar(0), terminal(false), father(0), child(0), brother(0) { }
-
-long thingtree::look(const String s) {
- long currentthing = -1;
- thingtree * ptr = root;
- int i;
-
- if (!ptr) {
- printm(M_ERROR, "Error: thingtree not initialised\n");
- exit(-1);
- }
-
- for (i = 0; s[i]; i++) {
-// printm(M_INFO, "Looking for '%c'\n", *p);
- for (ptr = ptr->child; ptr; ptr = ptr->brother) {
-// printm(M_INFO, "Looking in %p: %c\n", ptr, ptr->thischar);
- if (ptr->thischar == s[i]) {
- if (ptr->terminal) {
- currentthing = ptr->thingentry;
- }
- break;
- }
- }
- if (!ptr) {
-// printm(M_INFO, "Not found.\n");
- break;
- }
- }
-
- if (currentthing == -1) {
- printm(M_ERROR, "Error, can't find any entry for string '" + s + "'\n");
- }
-
- return currentthing;
-}
-
-void thingtree::addstring(const String s, long thingentry) {
- thingtree * ptr, * fptr;
- int i;
-
- if (!root) {
- root = new thingtree();
- }
-
-// printm(M_INFO, "Creating new thingtree entry: %li='%s'\n", thingentry, s);
-
- ptr = root;
- for (i = 0; s[i]; i++) {
- fptr = ptr;
-// printm(M_INFO, "Finding entry for '%c'\n", *p);
- for (ptr = ptr->child; ptr; ptr = ptr->brother) {
-// printm(M_INFO, "Browsing childs: %p = %c\n", ptr, ptr->thischar);
- if (ptr->thischar == s[i])
- break;
- }
-
- if (!ptr) {
-// printm(M_INFO, "Creating new branch for %c\n", *p);
- ptr = new thingtree(s[i], s[i + 1] == 0, fptr, thingentry);
-// printm(M_INFO, "Created branch %p\n", ptr);
- } else {
- if (s[i + 1] == 0) {
- ptr->terminal = true;
- ptr->thingentry = thingentry;
- }
- }
- }
-}
-
-void thingtree::destroy() {
- delete root;
- root = 0;
-}
-
-thingtree::~thingtree() {
- if (father->child == this)
- father->child = brother;
-
- while (child)
- delete child;
-}
-
-String things[256];
-
-char * dte_text;
-char dte_flags[256 * 256];
-long dte_counters[256 * 256];
-long dte_entries[256];
-char alloweds[256];
-long dte_usage[256];
-
-long dte_most;
-long dte_counter;
-long dte_text_size;
-int dte_size;
-long gain;
-long nb_dte = 0;
-long tnb_dte = 0;
-
-void dte_reset(void) {
- memset(dte_counters, 0, 0x40000);
- dte_most = 0;
- dte_counter = 0;
-}
-
-void build_dte(void) {
- int i;
- Uint16 t, t2;
- unsigned short p = 0;
-
- for (i = 0; i < dte_text_size; i++) {
- t = *((Uint16 *) (dte_text + i));
- t2 = *((Uint16 *) (dte_text + i + 1));
- if (t == p) {
- p = 0;
- continue;
- }
- p = t;
- if (!dte_flags[t]) {
-// if ((!dte_flags[t]) && (dte_flags[t2] != 3)) {
- if ((dte_counters[t]++) == 0) {
- nb_dte++;
- }
- if (dte_counters[t] > dte_counter) {
- dte_most = t;
- dte_counter = dte_counters[t];
- }
-// } else if (dte_flags[t] == 3) {
-// i++;
- }
- }
-}
-
-void push_entry(long entry) {
- int i;
- char t[3], c1, c2;
- t[2] = 0;
-
- c1 = dte_most & 0xff;
- c2 = dte_most >> 8;
- t[0] = things[c1][0];
- t[1] = things[c2][0];
-
- for (i = 0; i < 256; i++) {
- if (!dte_entries[i]) {
- dte_entries[i] = entry;
- things[i] = strdup(t);
- thingtree::addstring(t, i);
- break;
- }
- }
-}
-
-void dte_compress() {
- int i, j;
- char c1, c2;
-
- for (i = 0; i < 256; i++) {
- for (j = 0; j < 256; j++) {
- dte_flags[i * 256 + j] = alloweds[i] ? alloweds[j] ? 0 : 1 : 1;
- }
- }
-
- gain = 0;
-
- printm(M_STATUS, "Going for it: dte_size = %i\n", dte_size);
- for (i = 0; i < dte_size; i++) {
- dte_reset();
- build_dte();
- if (!tnb_dte)
- tnb_dte = nb_dte;
- c1 = dte_most & 0xff;
- c2 = dte_most >> 8;
- c1 = things[c1][0];
- c2 = things[c2][0];
- printm(M_INFO, "Entry #%i, most count: %li, couple = 0x%04x = (%c %c)\n", i, dte_counter, (int) dte_most, c1, c2);
- dte_flags[dte_most] = 3;
- gain += dte_counter;
- push_entry(dte_most);
- }
-
- printm(M_STATUS, "Estimated gain: %li bytes, new file size = %li\n", gain, dte_text_size - gain);
-}
-
-void read_thingy(Handle * f) {
- String line, st, thing;
- long code;
- int i;
-
- dte_size = 0;
-
- for (i = 0; i < 256; i++) {
- dte_entries[i] = -1;
- }
-
- while (1) {
- line = "0x";
- *f >> st;
- if (st.strlen()) {
- line += st.extract(0, 1);
- code = line.to_int();
- thing = st.extract(3);
- switch (thing.strlen()) {
- case 0:
- dte_size++;
- dte_entries[code] = 0;
- break;
- case 1:
- alloweds[code] = 1;
- default:
- things[code] = thing;
- thingtree::addstring(thing, code);
- }
- }
- }
-}
-
-void read_thingy_file(Handle * f) {
- String line, trans;
- long code;
- int ptr = 0, i, c;
-
- for (i = 0; i < 256; i++) {
- dte_usage[i] = 0;
- }
-
- while (1) {
- *f >> line;
- if (!line.strlen())
- continue;
- i = 0;
- while (line[i]) {
- if (line[i] == '<') {
- if ((c = line.strchr('>', i)) < 0) {
- printm(M_ERROR, "Error in file: '<' not closed.\n");
- exit(-1);
- }
- i++;
- if (c == 2) {
- trans = "0x" + line.extract(i, 2);
- code = line.to_int();
- dte_text[ptr++] = code;
- printm(M_BARE, "0x%02x-", code);
- } else {
- printm(M_BARE, "Unknow " + trans.extract(2) + "-");
- }
- i += c;
- } else {
- if ((code = thingtree::look(line.extract(i))) == -1)
- exit(-1);
- dte_text[ptr++] = code;
- i += things[code].strlen();
- printm(M_BARE, things[code] + "-");
- dte_usage[code]++;
- }
- }
- printm(M_BARE, "\n");
- }
-
- dte_text[ptr] = dte_text[ptr + 1] = dte_text[ptr + 2] = dte_text[ptr + 3] = 0;
- dte_text_size = ptr;
-}
+/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 2002 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
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include "generic.h"
+#include "Handle.h"
+
+class thingtree : public Base {
+ public:
+ static void addstring(const String, long);
+ static long look(const String);
+ static void destroy();
+ private:
+ thingtree();
+ thingtree(char, bool, thingtree *, long);
+ ~thingtree();
+ char thischar;
+ bool terminal;
+ thingtree * father, * child, * brother;
+ long thingentry;
+ static thingtree * root;
+};
+
+thingtree * thingtree::root = 0;
+
+thingtree::thingtree(char gchar, bool gterm, thingtree * gfather, long gthingentry) : thischar(gchar), terminal(gterm), thingentry(gthingentry) {
+ if (!gfather) {
+ if (!root) {
+ root = new thingtree();
+ }
+ father = root;
+ } else {
+ father = gfather;
+ }
+ brother = father->child;
+ father->child = this;
+}
+
+thingtree::thingtree() : thischar(0), terminal(false), father(0), child(0), brother(0) { }
+
+long thingtree::look(const String s) {
+ long currentthing = -1;
+ thingtree * ptr = root;
+ int i;
+
+ if (!ptr) {
+ printm(M_ERROR, "Error: thingtree not initialised\n");
+ exit(-1);
+ }
+
+ for (i = 0; s[i]; i++) {
+// printm(M_INFO, "Looking for '%c'\n", *p);
+ for (ptr = ptr->child; ptr; ptr = ptr->brother) {
+// printm(M_INFO, "Looking in %p: %c\n", ptr, ptr->thischar);
+ if (ptr->thischar == s[i]) {
+ if (ptr->terminal) {
+ currentthing = ptr->thingentry;
+ }
+ break;
+ }
+ }
+ if (!ptr) {
+// printm(M_INFO, "Not found.\n");
+ break;
+ }
+ }
+
+ if (currentthing == -1) {
+ printm(M_ERROR, "Error, can't find any entry for string '" + s + "'\n");
+ }
+
+ return currentthing;
+}
+
+void thingtree::addstring(const String s, long thingentry) {
+ thingtree * ptr, * fptr;
+ int i;
+
+ if (!root) {
+ root = new thingtree();
+ }
+
+// printm(M_INFO, "Creating new thingtree entry: %li='%s'\n", thingentry, s);
+
+ ptr = root;
+ for (i = 0; s[i]; i++) {
+ fptr = ptr;
+// printm(M_INFO, "Finding entry for '%c'\n", *p);
+ for (ptr = ptr->child; ptr; ptr = ptr->brother) {
+// printm(M_INFO, "Browsing childs: %p = %c\n", ptr, ptr->thischar);
+ if (ptr->thischar == s[i])
+ break;
+ }
+
+ if (!ptr) {
+// printm(M_INFO, "Creating new branch for %c\n", *p);
+ ptr = new thingtree(s[i], s[i + 1] == 0, fptr, thingentry);
+// printm(M_INFO, "Created branch %p\n", ptr);
+ } else {
+ if (s[i + 1] == 0) {
+ ptr->terminal = true;
+ ptr->thingentry = thingentry;
+ }
+ }
+ }
+}
+
+void thingtree::destroy() {
+ delete root;
+ root = 0;
+}
+
+thingtree::~thingtree() {
+ if (father->child == this)
+ father->child = brother;
+
+ while (child)
+ delete child;
+}
+
+String things[256];
+
+char * dte_text;
+char dte_flags[256 * 256];
+long dte_counters[256 * 256];
+long dte_entries[256];
+char alloweds[256];
+long dte_usage[256];
+
+long dte_most;
+long dte_counter;
+long dte_text_size;
+int dte_size;
+long gain;
+long nb_dte = 0;
+long tnb_dte = 0;
+
+void dte_reset(void) {
+ memset(dte_counters, 0, 0x40000);
+ dte_most = 0;
+ dte_counter = 0;
+}
+
+void build_dte(void) {
+ int i;
+ Uint16 t, t2;
+ unsigned short p = 0;
+
+ for (i = 0; i < dte_text_size; i++) {
+ t = *((Uint16 *) (dte_text + i));
+ t2 = *((Uint16 *) (dte_text + i + 1));
+ if (t == p) {
+ p = 0;
+ continue;
+ }
+ p = t;
+ if (!dte_flags[t]) {
+// if ((!dte_flags[t]) && (dte_flags[t2] != 3)) {
+ if ((dte_counters[t]++) == 0) {
+ nb_dte++;
+ }
+ if (dte_counters[t] > dte_counter) {
+ dte_most = t;
+ dte_counter = dte_counters[t];
+ }
+// } else if (dte_flags[t] == 3) {
+// i++;
+ }
+ }
+}
+
+void push_entry(long entry) {
+ int i;
+ char t[3], c1, c2;
+ t[2] = 0;
+
+ c1 = dte_most & 0xff;
+ c2 = dte_most >> 8;
+ t[0] = things[c1][0];
+ t[1] = things[c2][0];
+
+ for (i = 0; i < 256; i++) {
+ if (!dte_entries[i]) {
+ dte_entries[i] = entry;
+ things[i] = strdup(t);
+ thingtree::addstring(t, i);
+ break;
+ }
+ }
+}
+
+void dte_compress() {
+ int i, j;
+ char c1, c2;
+
+ for (i = 0; i < 256; i++) {
+ for (j = 0; j < 256; j++) {
+ dte_flags[i * 256 + j] = alloweds[i] ? alloweds[j] ? 0 : 1 : 1;
+ }
+ }
+
+ gain = 0;
+
+ printm(M_STATUS, "Going for it: dte_size = %i\n", dte_size);
+ for (i = 0; i < dte_size; i++) {
+ dte_reset();
+ build_dte();
+ if (!tnb_dte)
+ tnb_dte = nb_dte;
+ c1 = dte_most & 0xff;
+ c2 = dte_most >> 8;
+ c1 = things[c1][0];
+ c2 = things[c2][0];
+ printm(M_INFO, "Entry #%i, most count: %li, couple = 0x%04x = (%c %c)\n", i, dte_counter, (int) dte_most, c1, c2);
+ dte_flags[dte_most] = 3;
+ gain += dte_counter;
+ push_entry(dte_most);
+ }
+
+ printm(M_STATUS, "Estimated gain: %li bytes, new file size = %li\n", gain, dte_text_size - gain);
+}
+
+void read_thingy(Handle * f) {
+ String line, st, thing;
+ long code;
+ int i;
+
+ dte_size = 0;
+
+ for (i = 0; i < 256; i++) {
+ dte_entries[i] = -1;
+ }
+
+ while (1) {
+ line = "0x";
+ *f >> st;
+ if (st.strlen()) {
+ line += st.extract(0, 1);
+ code = line.to_int();
+ thing = st.extract(3);
+ switch (thing.strlen()) {
+ case 0:
+ dte_size++;
+ dte_entries[code] = 0;
+ break;
+ case 1:
+ alloweds[code] = 1;
+ default:
+ things[code] = thing;
+ thingtree::addstring(thing, code);
+ }
+ }
+ }
+}
+
+void read_thingy_file(Handle * f) {
+ String line, trans;
+ long code;
+ int ptr = 0, i, c;
+
+ for (i = 0; i < 256; i++) {
+ dte_usage[i] = 0;
+ }
+
+ while (1) {
+ *f >> line;
+ if (!line.strlen())
+ continue;
+ i = 0;
+ while (line[i]) {
+ if (line[i] == '<') {
+ if ((c = line.strchr('>', i)) < 0) {
+ printm(M_ERROR, "Error in file: '<' not closed.\n");
+ exit(-1);
+ }
+ i++;
+ if (c == 2) {
+ trans = "0x" + line.extract(i, 2);
+ code = line.to_int();
+ dte_text[ptr++] = code;
+ printm(M_BARE, "0x%02x-", code);
+ } else {
+ printm(M_BARE, "Unknow " + trans.extract(2) + "-");
+ }
+ i += c;
+ } else {
+ if ((code = thingtree::look(line.extract(i))) == -1)
+ exit(-1);
+ dte_text[ptr++] = code;
+ i += things[code].strlen();
+ printm(M_BARE, things[code] + "-");
+ dte_usage[code]++;
+ }
+ }
+ printm(M_BARE, "\n");
+ }
+
+ dte_text[ptr] = dte_text[ptr + 1] = dte_text[ptr + 2] = dte_text[ptr + 3] = 0;
+ dte_text_size = ptr;
+}
diff --git a/lib/isobuilder.cpp b/lib/isobuilder.cpp
index 2b60131..6ed8abd 100644
--- a/lib/isobuilder.cpp
+++ b/lib/isobuilder.cpp
@@ -1,876 +1,876 @@
-/*
- * 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: isobuilder.cpp,v 1.14 2004-10-19 15:58:41 pixel Exp $ */
-
-#include "isobuilder.h"
-
-void isobuilder::Date::dump(Byte * datas) {
- char pbuf[256];
-
- sprintf(pbuf, "%04i", year);
- memcpy(datas + 0, pbuf, 4);
- sprintf(pbuf, "%02i", month);
- memcpy(datas + 4, pbuf, 2);
- sprintf(pbuf, "%02i", day);
- memcpy(datas + 6, pbuf, 2);
- sprintf(pbuf, "%02i", hour);
- memcpy(datas + 8, pbuf, 2);
- sprintf(pbuf, "%02i", minute);
- memcpy(datas + 10, pbuf, 2);
- sprintf(pbuf, "%02i", second);
- memcpy(datas + 12, pbuf, 2);
- sprintf(pbuf, "%02i", hundredths);
- memcpy(datas + 14, pbuf, 2);
-
- *((char *) (datas + 16)) = offset;
-}
-
-isobuilder::Date::Date(int) {
- year = month = day = hour = minute = second = hundredths = offset = 0;
-}
-
-isobuilder::Date::Date(Byte * datas) {
- char pbuf[256];
- char * cdatas = (char *) datas;
-
- memcpy(pbuf, cdatas + 0, 4);
- pbuf[4] = 0;
- sscanf(pbuf, "%d", &year);
-
- memcpy(pbuf, cdatas + 4, 2);
- pbuf[2] = 0;
- sscanf(pbuf, "%d", &month);
-
- memcpy(pbuf, cdatas + 6, 2);
- pbuf[2] = 0;
- sscanf(pbuf, "%d", &day);
-
- memcpy(pbuf, cdatas + 8, 2);
- pbuf[2] = 0;
- sscanf(pbuf, "%d", &hour);
-
- memcpy(pbuf, cdatas + 10, 2);
- pbuf[2] = 0;
- sscanf(pbuf, "%d", &minute);
-
- memcpy(pbuf, cdatas + 12, 2);
- pbuf[2] = 0;
- sscanf(pbuf, "%d", &second);
-
- memcpy(pbuf, cdatas + 14, 2);
- pbuf[2] = 0;
- sscanf(pbuf, "%d", &hundredths);
-
- offset = *(cdatas + 16);
-}
-
-isobuilder::DirTree::DirTree(isobuilder::DirTree * _father, bool _dir) : mode(-1), father(_father), dir(_dir) {
- DirTree * p;
-
- child = brother = 0;
-
- if (!father)
- return;
-
- creation = father->creation;
-
- if (father->child) {
- for (p = father->child; p->brother; p = p->brother);
- p->brother = this;
- } else {
- father->child = this;
- }
-}
-
-isobuilder::DirTree::~DirTree() {
- while (child) {
- delete child;
- }
-
- if (!father)
- return;
-
- if (father->child == this) {
- father->child = brother;
- } else {
- // Dirty, should not happen.
- DirTree * p;
- for (p = father->child; p->brother != this; p = p->brother);
- p->brother = brother;
- }
-}
-
-void isobuilder::DirTree::dumpdirs(isobuilder * builder) throw (GeneralException) {
- Byte * dir, * odir;
- int cursiz, cursectsize, R;
- String oldname;
- DirTree * p;
-
- odir = dir = (Byte *) malloc(cursiz = size);
- cursectsize = 2048;
-
- oldname = name;
- name = ".";
- R = buildentry(dir, cursectsize);
- name = oldname;
- cursectsize -= R;
- dir += R;
-
- if (father) {
- oldname = father->name;
- father->name = "..";
- R = father->buildentry(dir, cursectsize);
- father->name = oldname;
- } else {
- name = "..";
- R = buildentry(dir, cursectsize);
- name = ".";
- }
-
- cursectsize -= R;
- dir += R;
-
- for (p = child; p; p = p->brother) {
- if (p->dir) {
- p->dumpdirs(builder);
- }
- if (p->hardhide)
- continue;
- while (!(R = p->buildentry(dir, cursectsize))) {
- cursiz -= 2048;
- dir += cursectsize;
- cursectsize = 2048;
- if (!cursiz)
- throw GeneralException("Directory is too small! Entries don't fit.");
- }
- cursectsize -= R;
- dir += R;
- }
-
- builder->putdatas(odir, size, mode, sector);
-
- free(odir);
-}
-
-int isobuilder::DirTree::buildpath(Byte * datas, int size, bool bigendian) throw (GeneralException) {
- int N, r, tr;
- Uint16 pn;
- char pbuf[256], pad;
-
- if (!dir) {
- if (brother) {
- return brother->buildpath(datas, size, bigendian);
- } else {
- return 0;
- }
- }
-
- if (!father) {
- numerate(1);
- N = 1;
- pbuf[0] = 0;
- pn = 1;
- } else {
- N = name.strlen();
- strcpy(pbuf, name.to_charp());
- pn = father->node;
- }
-
- pad = N & 1;
- size -= (r = N + pad + 8);
-
- if (size < 0)
- throw GeneralException("Path table too small.");
-
- datas[0] = N;
- datas[1] = 0;
- *((Uint32 *) (datas + 2)) = bigendian ? cdutils::swap_dword(sector) : sector;
- *((Uint16 *) (datas + 6)) = bigendian ? cdutils::swap_word(pn) : pn;
- memcpy(datas + 8, pbuf, N);
- if (pad)
- datas[8 + N] = 0;
-
- datas += r;
-
- if (brother) {
- tr = brother->buildpath(datas, size, bigendian);
- r += tr;
- size -= tr;
- datas += tr;
- }
-
- if (child) {
- tr = child->buildpath(datas, size, bigendian);
- r += tr;
- size -= tr;
- datas += tr;
- }
-
- return r;
-}
-
-int isobuilder::DirTree::buildentry(Byte * buffer, int spaceleft, bool put_xa) {
- int N, R;
- char pbuf[256], pad;
- Byte * p;
- cdutils::DirEntry * d = (cdutils::DirEntry *) buffer;
-
- put_xa = put_xa && have_xa;
-
- memset(pbuf, 0, 256);
-
- if (name == ".") {
- N = 1;
- pbuf[0] = 0;
- } else if (name == "..") {
- N = 1;
- pbuf[0] = 1;
- } else {
- strcpy(pbuf, name.to_charp());
- N = name.strlen();
- if (!dir) {
- N += 2;
- strcat(pbuf, ";1");
- }
- }
-
- R = N + 33;
-
- if (R & 1) {
- R++;
- pad = 1;
- } else {
- pad = 0;
- }
-
- if (put_xa) {
- R += 14;
- p = (Byte *) pbuf + N + pad;
- p[4] = 0x05;
- p[5] = 0x55;
- p[6] = 'X';
- p[7] = 'A';
-
- p[4] |= xa_dir ? 0x80 : 0;
- p[4] |= xa_audio ? 0x40 : 0;
- p[4] |= xa_str ? 0x20 : 0;
- p[4] |= xa_xa ? 0x10 : 0;
- p[4] |= xa_form1 ? 0x08 : 0;
- }
-
- if (R > spaceleft) {
- return 0;
- }
-
- memset(d, 0, R);
-
- d->R = R;
- d->N = N;
- memcpy(d->id, pbuf, N + pad + (put_xa ? 14 : 0));
-
- d->Sector = sector;
- d->BESector = cdutils::swap_dword(sector);
- d->Size = size;
- d->BESize = cdutils::swap_dword(size);
- if (creation.year >= 1000) {
- d->Year = creation.year - 1900;
- } else {
- d->Year = creation.year;
- }
- d->Month = creation.month;
- d->Day = creation.day;
- d->Hour = creation.hour;
- d->Minute = creation.minute;
- d->Second = creation.second;
- d->Offset = creation.offset;
- d->Flags |= hidden ? 1 : 0;
- d->Flags |= dir ? 2 : 0;
-
- return R;
-}
-
-void isobuilder::DirTree::fromdir(cdutils::DirEntry * d) {
- Date t;
- char pbuf[200], pad;
- int s;
- if ((!d) || (!d->R)) {
- return;
- }
-
- if ((d->N == 1) && (d->id[0] == 0)) {
- name = ".";
- } else if ((d->N == 1) && (d->id[0] == 1)) {
- name = "..";
- } else {
- memcpy(pbuf, d->id, s = (d->N - ((d->Flags & 2) ? 0 : 2)));
- pbuf[s] = 0;
- name = pbuf;
- }
- hidden = d->Flags & 1;
- if (d->Year < 70)
- d->Year += 100;
- t.year = d->Year;
- t.month = d->Month;
- t.day = d->Day;
- t.hour = d->Hour;
- t.second = d->Second;
- t.hundredths = 0;
- t.offset = d->Offset;
- creation = t;
-
- s = 33 + d->N;
- if (s & 1) {
- s++;
- pad = 1;
- } else {
- pad = 0;
- }
- if (s != d->R) {
- if ((s + 14) == d->R) {
- Byte * p;
- p = (Byte *) d->id + d->N + pad;
- if ((p[6] == 'X') && (p[7] == 'A')) {
- have_xa = true;
- xa_dir = p[4] & 0x80;
- xa_audio = p[4] & 0x40;
- xa_str = p[4] & 0x20;
- xa_xa = p[4] & 0x10;
- xa_form1 = p[4] & 0x08;
- }
- }
- }
-}
-
-bool isobuilder::DirTree::isdir() {
- return dir;
-}
-
-void isobuilder::DirTree::setbasicsxa() {
- have_xa = true;
- if (dir)
- xa_dir = true;
- xa_form1 = true;
-}
-
-int isobuilder::DirTree::numerate(int n) {
- if (!dir) {
- if (brother) {
- return brother->numerate(n);
- } else {
- return n;
- }
- }
-
- node = n++;
-
- if (brother)
- n = brother->numerate(n);
-
- if (child)
- n = child->numerate(n);
-
- return n;
-}
-
-isobuilder::DirTree * isobuilder::DirTree::Father() {
- return father;
-}
-
-isobuilder::DirTree * isobuilder::DirTree::Brother() {
- return brother;
-}
-
-isobuilder::DirTree * isobuilder::DirTree::Child() {
- return child;
-}
-
-isobuilder::DirTree * isobuilder::DirTree::Find(const String & _name) {
- DirTree * p = 0;
-
- if (name == _name)
- return this;
-
- if (brother)
- p = brother->Find(_name);
-
- if (!p && child)
- return child->Find(_name);
-
- return p;
-}
-
-isobuilder::isobuilder(Handle * _w, int _mode) : w(_w), sector(0), nsectors(0), basics(false), dmode(_mode) {
- Byte sect[2352];
- memset(sect, 0, 2352);
-
- for (int i = 0; i < 16; i++) {
- createsector(sect, MODE2, i);
- }
-}
-
-isobuilder::~isobuilder() {
- if (!closed)
- close();
- if (root)
- 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++) {
- forewords->read(sect, sec_sizes[mode]);
- createsector(sect, mode, i);
- }
-}
-
-void isobuilder::foreword(Byte * forewords, int mode) {
- for (int i = 0; i < 16; i++) {
- createsector(forewords + i * sec_sizes[mode], mode, i);
- }
-}
-
-int isobuilder::getdispsect() {
- return lastdispsect;
-}
-
-int isobuilder::putfile(Handle * file, int mode, int n) {
- Byte datas[2352];
- ssize_t filesize;
- int fsect;
-
- if (mode < 0)
- mode = dmode;
-
- if (n >= 0) {
- sector = n;
- } else {
- sector = lastdispsect;
- }
-
- fsect = sector;
-
- filesize = file->GetSize();
-
- while (filesize > 0) {
- memset(datas, 0, 2352);
- filesize -= file->read(datas, sec_sizes[mode]);
- if ((mode == MODE2_FORM1) || (mode == MODE2_FORM2)) {
- if (filesize) {
- clearEOF();
- } else {
- setEOF();
- }
- }
- createsector(datas, mode);
- }
-
- return fsect;
-}
-
-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;
-
- while (size > 0) {
- memset(datas, 0, 2352);
- eating = MIN(size, (size_t) sec_sizes[smode]);
- memcpy(datas, _datas, eating);
- size -= eating;
- _datas += eating;
- if ((smode == MODE2_FORM1) || (smode == MODE2_FORM2)) {
- if (size) {
- clearEOF();
- } else {
- setEOF();
- }
- }
- createsector(datas, smode);
- }
-
- return dsect;
-}
-
-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]);
-
- if ((smode == MODE2_FORM1) || (smode == MODE2_FORM2)) {
- // Mode 2 Form 2 would be odd, but well....
- dsector[16] = dsector[20] = 0; // File Number
- dsector[17] = dsector[21] = 0; // Channel Number
- dsector[18] = dsector[22] = sub_EOR | sub_EOF | 8 |
- (smode == MODE2_FORM2 ? 32 : 0);
- dsector[19] = dsector[23] = 0; // Coding Info
- }
-
- if (smode != MODE_RAW) {
- sector += 150;
- yazedc_o.minute = cdutils::to_BCD(sector / 60 / 75);
- yazedc_o.second = cdutils::to_BCD((sector / 75) % 60);
- yazedc_o.frame = cdutils::to_BCD(sector % 75);
- sector -= 150;
- yazedc_o.do_encode_L2(dsector, smode, 0);
- }
-
- w->write(dsector, 2352);
-
- sector++;
-
- nsectors = MAX(nsectors, sector);
- lastdispsect = MAX(lastdispsect, sector);
-
- return rsector;
-}
-
-void isobuilder::setEOF() {
- sub_EOF = 128;
- sub_EOR = 1;
-}
-
-void isobuilder::clearEOF() {
- sub_EOF = sub_EOR = 0;
-}
-
-isobuilder::DirTree * isobuilder::setbasics(PVD _pvd, int _rootsize, int _ptsize, int _nvd, int _rootsect) throw (GeneralException) {
- if (basics) {
- throw GeneralException("Basic ISO structures already set");
- }
- basics = true;
-
- pvd = _pvd;
- rootsize = _rootsize;
- ptsize = _ptsize;
- nvd = _nvd;
-
- ptsect = 17 + nvd;
- rootsect = ptsect + ptsize * 4;
- if (_rootsect >= 0)
- rootsect = _rootsect;
- lastdispsect = rootsect + rootsize;
-
- root = new DirTree(0);
- root->name = ".";
- root->creation = pvd.volcreat;
- root->sector = rootsect;
- root->size = rootsize * 2048;
- return root;
-}
-
-isobuilder::DirTree * isobuilder::createdir(DirTree * p, const String & _name, int size, cdutils::DirEntry * d, int mode) throw (GeneralException) {
- DirTree * r;
-
- if (!p)
- throw GeneralException("Empty father");
-
- if (closed)
- throw GeneralException("ISO is closed");
-
- if (!basics)
- throw GeneralException("ISO basis not created (no root!)");
-
- r = new DirTree(p);
-
- r->creation = p->creation;
- if (d)
- r->fromdir(d);
- if (_name != "")
- r->name = _name;
- r->size = size * 2048;
- if (!r->size)
- r->size = d->Size;
- r->sector = lastdispsect;
- if (mode >= 0)
- r->mode = mode;
- else
- r->mode = dmode;
-
- lastdispsect += size;
-
- return r;
-}
-
-isobuilder::DirTree * isobuilder::createfile(DirTree * p, Handle * file, const String & _name, cdutils::DirEntry * d, int mode) throw (GeneralException) {
- DirTree * r;
-
- if (!p)
- throw GeneralException("Empty father");
-
- if (closed)
- throw GeneralException("ISO is closed");
-
- if (!basics)
- throw GeneralException("ISO basis not created (no root!)");
-
- r = new DirTree(p, false);
-
- r->name = _name;
- r->creation = p->creation;
- r->fromdir(d);
- if (_name != "")
- r->name = _name;
- r->size = file->GetSize();
- r->sector = putfile(file, mode);
- if (mode >= 0)
- r->mode = mode;
- else
- r->mode = dmode;
-
- return r;
-}
-
-void isobuilder::copydir(isobuilder::DirTree * r, cdutils * cd, cdutils::DirEntry * d, int mode) {
- Byte datas[2048];
- cdutils::DirEntry * p;
- int nsectors = d->Size / 2048, ssize, c = 0;
- int fsize, osize;
-
- if (mode < 0)
- mode = dmode;
-
- while (nsectors) {
- cd->read_sector(datas, mode, d->Sector + c++);
- nsectors--;
- p = (cdutils::DirEntry *) datas;
- ssize = 2048;
- while ((ssize) && (p->R)) {
- ssize -= p->R;
- char pbuf[256];
- memcpy(pbuf, p->id, p->N);
- pbuf[p->N] = 0;
- if (p->Flags & 2) {
- if (!((p->N == 1) && ((p->id[0] == 0) || (p->id[0] == 1))))
- copydir(createdir(r, "", p->Size / 2048, p, mode), cd, p, mode);
- } else {
- printm(M_INFO, "Dupping %s\n", pbuf);
- int fmode;
- osize = fsize = p->Size;
- if (mode == MODE1) {
- fmode = mode;
- } else {
- fmode = MODE2_FORM1;
- int s, pad;
- s = 33 + p->N;
- if (s & 1) {
- s++;
- pad = 1;
- } else {
- pad = 0;
- }
- if ((s != p->R) && ((s + 14) == p->R)) {
- if (!(p->id[p->N + pad + 4] & 8)) {
- fmode = MODE2;
- fsize = (p->Size / 2048) * 2336;
- }
- }
- }
- p->Size = fsize;
- cdfile * tmp = new cdfile(cd, p, fmode);
- createfile(r, tmp, "", p, fmode)->size = osize;
- delete tmp;
- p->Size = osize;
- }
- p = (cdutils::DirEntry *) (((Byte *) p) + p->R);
- }
- }
-}
-
-isobuilder::PVD isobuilder::createpvd(Handle * f) {
- Byte datas[2048];
- f->read(datas, 2048);
- return createpvd(datas);
-}
-
-isobuilder::PVD isobuilder::createpvd(cdutils * cd) {
- Byte datas[2048];
- cd->read_sector(datas, GUESS, 16);
- return createpvd(datas);
-}
-
-isobuilder::PVD isobuilder::createpvd(Byte * buffer) {
- PVD r;
- char pbuff[256];
-
- memcpy(pbuff, buffer + 8, 32);
- pbuff[32] = 0;
- r.sysid = pbuff;
- r.sysid.rtrim();
- memcpy(pbuff, buffer + 40, 32);
- pbuff[32] = 0;
- r.volid = pbuff;
- r.volid.rtrim();
- memcpy(pbuff, buffer + 190, 128);
- pbuff[128] = 0;
- r.volsetid = pbuff;
- r.volsetid.rtrim();
- memcpy(pbuff, buffer + 318, 128);
- pbuff[128] = 0;
- r.pubid = pbuff;
- r.pubid.rtrim();
- memcpy(pbuff, buffer + 446, 128);
- pbuff[128] = 0;
- r.prepid = pbuff;
- r.prepid.rtrim();
- memcpy(pbuff, buffer + 574, 128);
- pbuff[128] = 0;
- r.appid = pbuff;
- r.appid.rtrim();
- memcpy(pbuff, buffer + 702, 37);
- pbuff[37] = 0;
- r.copyright = pbuff;
- r.copyright.rtrim();
- memcpy(pbuff, buffer + 739, 37);
- pbuff[37] = 0;
- r.abstract = pbuff;
- r.abstract.rtrim();
- memcpy(pbuff, buffer + 776, 37);
- pbuff[37] = 0;
- r.biblio = pbuff;
- r.biblio.rtrim();
-
- r.volcreat = Date(buffer + 813);
- r.modif = Date(buffer + 830);
- r.volexp = Date(buffer + 847);
- r.voleff = Date(buffer + 864);
-
- memcpy(r.appdata, buffer + 883, 512);
-
- return r;
-}
-
-void isobuilder::close(Handle * cue, int mode, int nsects) throw (GeneralException) {
- Byte datas[2048];
- Byte * pdatas;
- char * cdatas = (char *) datas;
- int psize;
-
- if (nsects < 0)
- nsects = nsectors;
-
- memset(datas, 0, 2048);
-
- pdatas = (Byte *) malloc(ptsize * 2048);
- psize = root->buildpath(pdatas, ptsize * 2048);
- putdatas(pdatas, ptsize * 2048, mode, ptsect);
- putdatas(pdatas, ptsize * 2048, mode, ptsect + ptsize);
- root->buildpath(pdatas, ptsize * 2048, true);
- putdatas(pdatas, ptsize * 2048, mode, ptsect + ptsize * 2);
- putdatas(pdatas, ptsize * 2048, mode, ptsect + ptsize * 3);
- free(pdatas);
-
- datas[0] = 1;
- datas[1] = 67;
- datas[2] = 68;
- datas[3] = 48;
- datas[4] = 48;
- datas[5] = 49;
- datas[6] = 1;
- datas[7] = 0;
-
- sprintf(cdatas + 8, "%-32s", pvd.sysid.to_charp());
- sprintf(cdatas + 40, "%-32s", pvd.volid.to_charp());
- *((Uint32 *) (datas + 80)) = nsects;
- *((Uint32 *) (datas + 84)) = cdutils::swap_dword(nsects);
-
- datas[120] = 1;
- datas[121] = 0;
- datas[122] = 0;
- datas[123] = 1;
- datas[124] = 1;
- datas[125] = 0;
- datas[126] = 0;
- datas[127] = 1;
- datas[128] = 0;
- datas[129] = 8;
- datas[130] = 8;
- datas[131] = 0;
- *((Uint32 *) (datas + 132)) = psize;
- *((Uint32 *) (datas + 136)) = cdutils::swap_dword(psize);
- *((Uint32 *) (datas + 140)) = ptsect;
- *((Uint32 *) (datas + 144)) = ptsect + ptsize;
- *((Uint32 *) (datas + 148)) = cdutils::swap_dword(ptsect + ptsize * 2);
- *((Uint32 *) (datas + 152)) = cdutils::swap_dword(ptsect + ptsize * 3);
-
- root->buildentry(datas + 156, 34, false);
-
- sprintf(cdatas + 190, "%-128s", pvd.volsetid.to_charp());
- sprintf(cdatas + 318, "%-128s", pvd.pubid.to_charp());
- sprintf(cdatas + 446, "%-128s", pvd.prepid.to_charp());
- sprintf(cdatas + 574, "%-128s", pvd.appid.to_charp());
- sprintf(cdatas + 702, "%-37s", pvd.copyright.to_charp());
- sprintf(cdatas + 739, "%-37s", pvd.abstract.to_charp());
- sprintf(cdatas + 776, "%-37s", pvd.biblio.to_charp());
-
- pvd.volcreat.dump(datas + 813);
- pvd.modif.dump(datas + 830);
- pvd.volexp.dump(datas + 847);
- pvd.voleff.dump(datas + 864);
-
- memcpy(datas + 883, pvd.appdata, 512);
-
- clearEOF();
- sub_EOR = 1;
- createsector(datas, mode, 16);
-
- memset(datas, 0, 2048);
- datas[0] =255;
- datas[1] = 67;
- datas[2] = 68;
- datas[3] = 48;
- datas[4] = 48;
- datas[5] = 49;
- datas[6] = 1;
-
- setEOF();
- createsector(datas, mode);
-
- root->dumpdirs(this);
-
- closed = true;
-}
+/*
+ * 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: isobuilder.cpp,v 1.15 2004-11-27 21:47:56 pixel Exp $ */
+
+#include "isobuilder.h"
+
+void isobuilder::Date::dump(Byte * datas) {
+ char pbuf[256];
+
+ sprintf(pbuf, "%04i", year);
+ memcpy(datas + 0, pbuf, 4);
+ sprintf(pbuf, "%02i", month);
+ memcpy(datas + 4, pbuf, 2);
+ sprintf(pbuf, "%02i", day);
+ memcpy(datas + 6, pbuf, 2);
+ sprintf(pbuf, "%02i", hour);
+ memcpy(datas + 8, pbuf, 2);
+ sprintf(pbuf, "%02i", minute);
+ memcpy(datas + 10, pbuf, 2);
+ sprintf(pbuf, "%02i", second);
+ memcpy(datas + 12, pbuf, 2);
+ sprintf(pbuf, "%02i", hundredths);
+ memcpy(datas + 14, pbuf, 2);
+
+ *((char *) (datas + 16)) = offset;
+}
+
+isobuilder::Date::Date(int) {
+ year = month = day = hour = minute = second = hundredths = offset = 0;
+}
+
+isobuilder::Date::Date(Byte * datas) {
+ char pbuf[256];
+ char * cdatas = (char *) datas;
+
+ memcpy(pbuf, cdatas + 0, 4);
+ pbuf[4] = 0;
+ sscanf(pbuf, "%d", &year);
+
+ memcpy(pbuf, cdatas + 4, 2);
+ pbuf[2] = 0;
+ sscanf(pbuf, "%d", &month);
+
+ memcpy(pbuf, cdatas + 6, 2);
+ pbuf[2] = 0;
+ sscanf(pbuf, "%d", &day);
+
+ memcpy(pbuf, cdatas + 8, 2);
+ pbuf[2] = 0;
+ sscanf(pbuf, "%d", &hour);
+
+ memcpy(pbuf, cdatas + 10, 2);
+ pbuf[2] = 0;
+ sscanf(pbuf, "%d", &minute);
+
+ memcpy(pbuf, cdatas + 12, 2);
+ pbuf[2] = 0;
+ sscanf(pbuf, "%d", &second);
+
+ memcpy(pbuf, cdatas + 14, 2);
+ pbuf[2] = 0;
+ sscanf(pbuf, "%d", &hundredths);
+
+ offset = *(cdatas + 16);
+}
+
+isobuilder::DirTree::DirTree(isobuilder::DirTree * _father, bool _dir) : mode(-1), father(_father), dir(_dir) {
+ DirTree * p;
+
+ child = brother = 0;
+
+ if (!father)
+ return;
+
+ creation = father->creation;
+
+ if (father->child) {
+ for (p = father->child; p->brother; p = p->brother);
+ p->brother = this;
+ } else {
+ father->child = this;
+ }
+}
+
+isobuilder::DirTree::~DirTree() {
+ while (child) {
+ delete child;
+ }
+
+ if (!father)
+ return;
+
+ if (father->child == this) {
+ father->child = brother;
+ } else {
+ // Dirty, should not happen.
+ DirTree * p;
+ for (p = father->child; p->brother != this; p = p->brother);
+ p->brother = brother;
+ }
+}
+
+void isobuilder::DirTree::dumpdirs(isobuilder * builder) throw (GeneralException) {
+ Byte * dir, * odir;
+ int cursiz, cursectsize, R;
+ String oldname;
+ DirTree * p;
+
+ odir = dir = (Byte *) malloc(cursiz = size);
+ cursectsize = 2048;
+
+ oldname = name;
+ name = ".";
+ R = buildentry(dir, cursectsize);
+ name = oldname;
+ cursectsize -= R;
+ dir += R;
+
+ if (father) {
+ oldname = father->name;
+ father->name = "..";
+ R = father->buildentry(dir, cursectsize);
+ father->name = oldname;
+ } else {
+ name = "..";
+ R = buildentry(dir, cursectsize);
+ name = ".";
+ }
+
+ cursectsize -= R;
+ dir += R;
+
+ for (p = child; p; p = p->brother) {
+ if (p->dir) {
+ p->dumpdirs(builder);
+ }
+ if (p->hardhide)
+ continue;
+ while (!(R = p->buildentry(dir, cursectsize))) {
+ cursiz -= 2048;
+ dir += cursectsize;
+ cursectsize = 2048;
+ if (!cursiz)
+ throw GeneralException("Directory is too small! Entries don't fit.");
+ }
+ cursectsize -= R;
+ dir += R;
+ }
+
+ builder->putdatas(odir, size, mode, sector);
+
+ free(odir);
+}
+
+int isobuilder::DirTree::buildpath(Byte * datas, int size, bool bigendian) throw (GeneralException) {
+ int N, r, tr;
+ Uint16 pn;
+ char pbuf[256], pad;
+
+ if (!dir) {
+ if (brother) {
+ return brother->buildpath(datas, size, bigendian);
+ } else {
+ return 0;
+ }
+ }
+
+ if (!father) {
+ numerate(1);
+ N = 1;
+ pbuf[0] = 0;
+ pn = 1;
+ } else {
+ N = name.strlen();
+ strcpy(pbuf, name.to_charp());
+ pn = father->node;
+ }
+
+ pad = N & 1;
+ size -= (r = N + pad + 8);
+
+ if (size < 0)
+ throw GeneralException("Path table too small.");
+
+ datas[0] = N;
+ datas[1] = 0;
+ *((Uint32 *) (datas + 2)) = bigendian ? cdutils::swap_dword(sector) : sector;
+ *((Uint16 *) (datas + 6)) = bigendian ? cdutils::swap_word(pn) : pn;
+ memcpy(datas + 8, pbuf, N);
+ if (pad)
+ datas[8 + N] = 0;
+
+ datas += r;
+
+ if (brother) {
+ tr = brother->buildpath(datas, size, bigendian);
+ r += tr;
+ size -= tr;
+ datas += tr;
+ }
+
+ if (child) {
+ tr = child->buildpath(datas, size, bigendian);
+ r += tr;
+ size -= tr;
+ datas += tr;
+ }
+
+ return r;
+}
+
+int isobuilder::DirTree::buildentry(Byte * buffer, int spaceleft, bool put_xa) {
+ int N, R;
+ char pbuf[256], pad;
+ Byte * p;
+ cdutils::DirEntry * d = (cdutils::DirEntry *) buffer;
+
+ put_xa = put_xa && have_xa;
+
+ memset(pbuf, 0, 256);
+
+ if (name == ".") {
+ N = 1;
+ pbuf[0] = 0;
+ } else if (name == "..") {
+ N = 1;
+ pbuf[0] = 1;
+ } else {
+ strcpy(pbuf, name.to_charp());
+ N = name.strlen();
+ if (!dir) {
+ N += 2;
+ strcat(pbuf, ";1");
+ }
+ }
+
+ R = N + 33;
+
+ if (R & 1) {
+ R++;
+ pad = 1;
+ } else {
+ pad = 0;
+ }
+
+ if (put_xa) {
+ R += 14;
+ p = (Byte *) pbuf + N + pad;
+ p[4] = 0x05;
+ p[5] = 0x55;
+ p[6] = 'X';
+ p[7] = 'A';
+
+ p[4] |= xa_dir ? 0x80 : 0;
+ p[4] |= xa_audio ? 0x40 : 0;
+ p[4] |= xa_str ? 0x20 : 0;
+ p[4] |= xa_xa ? 0x10 : 0;
+ p[4] |= xa_form1 ? 0x08 : 0;
+ }
+
+ if (R > spaceleft) {
+ return 0;
+ }
+
+ memset(d, 0, R);
+
+ d->R = R;
+ d->N = N;
+ memcpy(d->id, pbuf, N + pad + (put_xa ? 14 : 0));
+
+ d->Sector = sector;
+ d->BESector = cdutils::swap_dword(sector);
+ d->Size = size;
+ d->BESize = cdutils::swap_dword(size);
+ if (creation.year >= 1000) {
+ d->Year = creation.year - 1900;
+ } else {
+ d->Year = creation.year;
+ }
+ d->Month = creation.month;
+ d->Day = creation.day;
+ d->Hour = creation.hour;
+ d->Minute = creation.minute;
+ d->Second = creation.second;
+ d->Offset = creation.offset;
+ d->Flags |= hidden ? 1 : 0;
+ d->Flags |= dir ? 2 : 0;
+
+ return R;
+}
+
+void isobuilder::DirTree::fromdir(cdutils::DirEntry * d) {
+ Date t;
+ char pbuf[200], pad;
+ int s;
+ if ((!d) || (!d->R)) {
+ return;
+ }
+
+ if ((d->N == 1) && (d->id[0] == 0)) {
+ name = ".";
+ } else if ((d->N == 1) && (d->id[0] == 1)) {
+ name = "..";
+ } else {
+ memcpy(pbuf, d->id, s = (d->N - ((d->Flags & 2) ? 0 : 2)));
+ pbuf[s] = 0;
+ name = pbuf;
+ }
+ hidden = d->Flags & 1;
+ if (d->Year < 70)
+ d->Year += 100;
+ t.year = d->Year;
+ t.month = d->Month;
+ t.day = d->Day;
+ t.hour = d->Hour;
+ t.second = d->Second;
+ t.hundredths = 0;
+ t.offset = d->Offset;
+ creation = t;
+
+ s = 33 + d->N;
+ if (s & 1) {
+ s++;
+ pad = 1;
+ } else {
+ pad = 0;
+ }
+ if (s != d->R) {
+ if ((s + 14) == d->R) {
+ Byte * p;
+ p = (Byte *) d->id + d->N + pad;
+ if ((p[6] == 'X') && (p[7] == 'A')) {
+ have_xa = true;
+ xa_dir = p[4] & 0x80;
+ xa_audio = p[4] & 0x40;
+ xa_str = p[4] & 0x20;
+ xa_xa = p[4] & 0x10;
+ xa_form1 = p[4] & 0x08;
+ }
+ }
+ }
+}
+
+bool isobuilder::DirTree::isdir() {
+ return dir;
+}
+
+void isobuilder::DirTree::setbasicsxa() {
+ have_xa = true;
+ if (dir)
+ xa_dir = true;
+ xa_form1 = true;
+}
+
+int isobuilder::DirTree::numerate(int n) {
+ if (!dir) {
+ if (brother) {
+ return brother->numerate(n);
+ } else {
+ return n;
+ }
+ }
+
+ node = n++;
+
+ if (brother)
+ n = brother->numerate(n);
+
+ if (child)
+ n = child->numerate(n);
+
+ return n;
+}
+
+isobuilder::DirTree * isobuilder::DirTree::Father() {
+ return father;
+}
+
+isobuilder::DirTree * isobuilder::DirTree::Brother() {
+ return brother;
+}
+
+isobuilder::DirTree * isobuilder::DirTree::Child() {
+ return child;
+}
+
+isobuilder::DirTree * isobuilder::DirTree::Find(const String & _name) {
+ DirTree * p = 0;
+
+ if (name == _name)
+ return this;
+
+ if (brother)
+ p = brother->Find(_name);
+
+ if (!p && child)
+ return child->Find(_name);
+
+ return p;
+}
+
+isobuilder::isobuilder(Handle * _w, int _mode) : w(_w), sector(0), nsectors(0), basics(false), dmode(_mode) {
+ Byte sect[2352];
+ memset(sect, 0, 2352);
+
+ for (int i = 0; i < 16; i++) {
+ createsector(sect, MODE2, i);
+ }
+}
+
+isobuilder::~isobuilder() {
+ if (!closed)
+ close();
+ if (root)
+ 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++) {
+ forewords->read(sect, sec_sizes[mode]);
+ createsector(sect, mode, i);
+ }
+}
+
+void isobuilder::foreword(Byte * forewords, int mode) {
+ for (int i = 0; i < 16; i++) {
+ createsector(forewords + i * sec_sizes[mode], mode, i);
+ }
+}
+
+int isobuilder::getdispsect() {
+ return lastdispsect;
+}
+
+int isobuilder::putfile(Handle * file, int mode, int n) {
+ Byte datas[2352];
+ ssize_t filesize;
+ int fsect;
+
+ if (mode < 0)
+ mode = dmode;
+
+ if (n >= 0) {
+ sector = n;
+ } else {
+ sector = lastdispsect;
+ }
+
+ fsect = sector;
+
+ filesize = file->GetSize();
+
+ while (filesize > 0) {
+ memset(datas, 0, 2352);
+ filesize -= file->read(datas, sec_sizes[mode]);
+ if ((mode == MODE2_FORM1) || (mode == MODE2_FORM2)) {
+ if (filesize) {
+ clearEOF();
+ } else {
+ setEOF();
+ }
+ }
+ createsector(datas, mode);
+ }
+
+ return fsect;
+}
+
+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;
+
+ while (size > 0) {
+ memset(datas, 0, 2352);
+ eating = MIN(size, (size_t) sec_sizes[smode]);
+ memcpy(datas, _datas, eating);
+ size -= eating;
+ _datas += eating;
+ if ((smode == MODE2_FORM1) || (smode == MODE2_FORM2)) {
+ if (size) {
+ clearEOF();
+ } else {
+ setEOF();
+ }
+ }
+ createsector(datas, smode);
+ }
+
+ return dsect;
+}
+
+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]);
+
+ if ((smode == MODE2_FORM1) || (smode == MODE2_FORM2)) {
+ // Mode 2 Form 2 would be odd, but well....
+ dsector[16] = dsector[20] = 0; // File Number
+ dsector[17] = dsector[21] = 0; // Channel Number
+ dsector[18] = dsector[22] = sub_EOR | sub_EOF | 8 |
+ (smode == MODE2_FORM2 ? 32 : 0);
+ dsector[19] = dsector[23] = 0; // Coding Info
+ }
+
+ if (smode != MODE_RAW) {
+ sector += 150;
+ yazedc_o.minute = cdutils::to_BCD(sector / 60 / 75);
+ yazedc_o.second = cdutils::to_BCD((sector / 75) % 60);
+ yazedc_o.frame = cdutils::to_BCD(sector % 75);
+ sector -= 150;
+ yazedc_o.do_encode_L2(dsector, smode, 0);
+ }
+
+ w->write(dsector, 2352);
+
+ sector++;
+
+ nsectors = MAX(nsectors, sector);
+ lastdispsect = MAX(lastdispsect, sector);
+
+ return rsector;
+}
+
+void isobuilder::setEOF() {
+ sub_EOF = 128;
+ sub_EOR = 1;
+}
+
+void isobuilder::clearEOF() {
+ sub_EOF = sub_EOR = 0;
+}
+
+isobuilder::DirTree * isobuilder::setbasics(PVD _pvd, int _rootsize, int _ptsize, int _nvd, int _rootsect) throw (GeneralException) {
+ if (basics) {
+ throw GeneralException("Basic ISO structures already set");
+ }
+ basics = true;
+
+ pvd = _pvd;
+ rootsize = _rootsize;
+ ptsize = _ptsize;
+ nvd = _nvd;
+
+ ptsect = 17 + nvd;
+ rootsect = ptsect + ptsize * 4;
+ if (_rootsect >= 0)
+ rootsect = _rootsect;
+ lastdispsect = rootsect + rootsize;
+
+ root = new DirTree(0);
+ root->name = ".";
+ root->creation = pvd.volcreat;
+ root->sector = rootsect;
+ root->size = rootsize * 2048;
+ return root;
+}
+
+isobuilder::DirTree * isobuilder::createdir(DirTree * p, const String & _name, int size, cdutils::DirEntry * d, int mode) throw (GeneralException) {
+ DirTree * r;
+
+ if (!p)
+ throw GeneralException("Empty father");
+
+ if (closed)
+ throw GeneralException("ISO is closed");
+
+ if (!basics)
+ throw GeneralException("ISO basis not created (no root!)");
+
+ r = new DirTree(p);
+
+ r->creation = p->creation;
+ if (d)
+ r->fromdir(d);
+ if (_name != "")
+ r->name = _name;
+ r->size = size * 2048;
+ if (!r->size)
+ r->size = d->Size;
+ r->sector = lastdispsect;
+ if (mode >= 0)
+ r->mode = mode;
+ else
+ r->mode = dmode;
+
+ lastdispsect += size;
+
+ return r;
+}
+
+isobuilder::DirTree * isobuilder::createfile(DirTree * p, Handle * file, const String & _name, cdutils::DirEntry * d, int mode) throw (GeneralException) {
+ DirTree * r;
+
+ if (!p)
+ throw GeneralException("Empty father");
+
+ if (closed)
+ throw GeneralException("ISO is closed");
+
+ if (!basics)
+ throw GeneralException("ISO basis not created (no root!)");
+
+ r = new DirTree(p, false);
+
+ r->name = _name;
+ r->creation = p->creation;
+ r->fromdir(d);
+ if (_name != "")
+ r->name = _name;
+ r->size = file->GetSize();
+ r->sector = putfile(file, mode);
+ if (mode >= 0)
+ r->mode = mode;
+ else
+ r->mode = dmode;
+
+ return r;
+}
+
+void isobuilder::copydir(isobuilder::DirTree * r, cdutils * cd, cdutils::DirEntry * d, int mode) {
+ Byte datas[2048];
+ cdutils::DirEntry * p;
+ int nsectors = d->Size / 2048, ssize, c = 0;
+ int fsize, osize;
+
+ if (mode < 0)
+ mode = dmode;
+
+ while (nsectors) {
+ cd->read_sector(datas, mode, d->Sector + c++);
+ nsectors--;
+ p = (cdutils::DirEntry *) datas;
+ ssize = 2048;
+ while ((ssize) && (p->R)) {
+ ssize -= p->R;
+ char pbuf[256];
+ memcpy(pbuf, p->id, p->N);
+ pbuf[p->N] = 0;
+ if (p->Flags & 2) {
+ if (!((p->N == 1) && ((p->id[0] == 0) || (p->id[0] == 1))))
+ copydir(createdir(r, "", p->Size / 2048, p, mode), cd, p, mode);
+ } else {
+ printm(M_INFO, "Dupping %s\n", pbuf);
+ int fmode;
+ osize = fsize = p->Size;
+ if (mode == MODE1) {
+ fmode = mode;
+ } else {
+ fmode = MODE2_FORM1;
+ int s, pad;
+ s = 33 + p->N;
+ if (s & 1) {
+ s++;
+ pad = 1;
+ } else {
+ pad = 0;
+ }
+ if ((s != p->R) && ((s + 14) == p->R)) {
+ if (!(p->id[p->N + pad + 4] & 8)) {
+ fmode = MODE2;
+ fsize = (p->Size / 2048) * 2336;
+ }
+ }
+ }
+ p->Size = fsize;
+ cdfile * tmp = new cdfile(cd, p, fmode);
+ createfile(r, tmp, "", p, fmode)->size = osize;
+ delete tmp;
+ p->Size = osize;
+ }
+ p = (cdutils::DirEntry *) (((Byte *) p) + p->R);
+ }
+ }
+}
+
+isobuilder::PVD isobuilder::createpvd(Handle * f) {
+ Byte datas[2048];
+ f->read(datas, 2048);
+ return createpvd(datas);
+}
+
+isobuilder::PVD isobuilder::createpvd(cdutils * cd) {
+ Byte datas[2048];
+ cd->read_sector(datas, GUESS, 16);
+ return createpvd(datas);
+}
+
+isobuilder::PVD isobuilder::createpvd(Byte * buffer) {
+ PVD r;
+ char pbuff[256];
+
+ memcpy(pbuff, buffer + 8, 32);
+ pbuff[32] = 0;
+ r.sysid = pbuff;
+ r.sysid.rtrim();
+ memcpy(pbuff, buffer + 40, 32);
+ pbuff[32] = 0;
+ r.volid = pbuff;
+ r.volid.rtrim();
+ memcpy(pbuff, buffer + 190, 128);
+ pbuff[128] = 0;
+ r.volsetid = pbuff;
+ r.volsetid.rtrim();
+ memcpy(pbuff, buffer + 318, 128);
+ pbuff[128] = 0;
+ r.pubid = pbuff;
+ r.pubid.rtrim();
+ memcpy(pbuff, buffer + 446, 128);
+ pbuff[128] = 0;
+ r.prepid = pbuff;
+ r.prepid.rtrim();
+ memcpy(pbuff, buffer + 574, 128);
+ pbuff[128] = 0;
+ r.appid = pbuff;
+ r.appid.rtrim();
+ memcpy(pbuff, buffer + 702, 37);
+ pbuff[37] = 0;
+ r.copyright = pbuff;
+ r.copyright.rtrim();
+ memcpy(pbuff, buffer + 739, 37);
+ pbuff[37] = 0;
+ r.abstract = pbuff;
+ r.abstract.rtrim();
+ memcpy(pbuff, buffer + 776, 37);
+ pbuff[37] = 0;
+ r.biblio = pbuff;
+ r.biblio.rtrim();
+
+ r.volcreat = Date(buffer + 813);
+ r.modif = Date(buffer + 830);
+ r.volexp = Date(buffer + 847);
+ r.voleff = Date(buffer + 864);
+
+ memcpy(r.appdata, buffer + 883, 512);
+
+ return r;
+}
+
+void isobuilder::close(Handle * cue, int mode, int nsects) throw (GeneralException) {
+ Byte datas[2048];
+ Byte * pdatas;
+ char * cdatas = (char *) datas;
+ int psize;
+
+ if (nsects < 0)
+ nsects = nsectors;
+
+ memset(datas, 0, 2048);
+
+ pdatas = (Byte *) malloc(ptsize * 2048);
+ psize = root->buildpath(pdatas, ptsize * 2048);
+ putdatas(pdatas, ptsize * 2048, mode, ptsect);
+ putdatas(pdatas, ptsize * 2048, mode, ptsect + ptsize);
+ root->buildpath(pdatas, ptsize * 2048, true);
+ putdatas(pdatas, ptsize * 2048, mode, ptsect + ptsize * 2);
+ putdatas(pdatas, ptsize * 2048, mode, ptsect + ptsize * 3);
+ free(pdatas);
+
+ datas[0] = 1;
+ datas[1] = 67;
+ datas[2] = 68;
+ datas[3] = 48;
+ datas[4] = 48;
+ datas[5] = 49;
+ datas[6] = 1;
+ datas[7] = 0;
+
+ sprintf(cdatas + 8, "%-32s", pvd.sysid.to_charp());
+ sprintf(cdatas + 40, "%-32s", pvd.volid.to_charp());
+ *((Uint32 *) (datas + 80)) = nsects;
+ *((Uint32 *) (datas + 84)) = cdutils::swap_dword(nsects);
+
+ datas[120] = 1;
+ datas[121] = 0;
+ datas[122] = 0;
+ datas[123] = 1;
+ datas[124] = 1;
+ datas[125] = 0;
+ datas[126] = 0;
+ datas[127] = 1;
+ datas[128] = 0;
+ datas[129] = 8;
+ datas[130] = 8;
+ datas[131] = 0;
+ *((Uint32 *) (datas + 132)) = psize;
+ *((Uint32 *) (datas + 136)) = cdutils::swap_dword(psize);
+ *((Uint32 *) (datas + 140)) = ptsect;
+ *((Uint32 *) (datas + 144)) = ptsect + ptsize;
+ *((Uint32 *) (datas + 148)) = cdutils::swap_dword(ptsect + ptsize * 2);
+ *((Uint32 *) (datas + 152)) = cdutils::swap_dword(ptsect + ptsize * 3);
+
+ root->buildentry(datas + 156, 34, false);
+
+ sprintf(cdatas + 190, "%-128s", pvd.volsetid.to_charp());
+ sprintf(cdatas + 318, "%-128s", pvd.pubid.to_charp());
+ sprintf(cdatas + 446, "%-128s", pvd.prepid.to_charp());
+ sprintf(cdatas + 574, "%-128s", pvd.appid.to_charp());
+ sprintf(cdatas + 702, "%-37s", pvd.copyright.to_charp());
+ sprintf(cdatas + 739, "%-37s", pvd.abstract.to_charp());
+ sprintf(cdatas + 776, "%-37s", pvd.biblio.to_charp());
+
+ pvd.volcreat.dump(datas + 813);
+ pvd.modif.dump(datas + 830);
+ pvd.volexp.dump(datas + 847);
+ pvd.voleff.dump(datas + 864);
+
+ memcpy(datas + 883, pvd.appdata, 512);
+
+ clearEOF();
+ sub_EOR = 1;
+ createsector(datas, mode, 16);
+
+ memset(datas, 0, 2048);
+ datas[0] =255;
+ datas[1] = 67;
+ datas[2] = 68;
+ datas[3] = 48;
+ datas[4] = 48;
+ datas[5] = 49;
+ datas[6] = 1;
+
+ setEOF();
+ createsector(datas, mode);
+
+ root->dumpdirs(this);
+
+ closed = true;
+}
diff --git a/lib/luacd.cpp b/lib/luacd.cpp
index e4e2b23..c330921 100644
--- a/lib/luacd.cpp
+++ b/lib/luacd.cpp
@@ -1,1661 +1,1661 @@
-/*
- * 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.14 2004-10-19 15:58:42 pixel Exp $ */
-
-#include "luacd.h"
-
-
- /**************************\
-|** class cdutils exports **|
- \**************************/
-
-Luacdutils::Luacdutils(cdutils * _cd) : cd(_cd) { }
-class Luacdfile : public LuaHandle {
- public:
- Luacdfile(cdfile * h) : LuaHandle(h) {}
-};
-
-enum cdutils_methods_t {
- CDUTILS_SETISOW = 0,
- CDUTILS_GUESSTYPE,
- CDUTILS_SECTORSEEK,
- CDUTILS_READSECTOR,
- CDUTILS_READDATAS,
- CDUTILS_READFILE,
- CDUTILS_WRITESECTOR,
- CDUTILS_WRITEDATAS,
- CDUTILS_WRITEFILE,
- CDUTILS_GETISOINFOS,
- CDUTILS_GETPTINFOS,
- CDUTILS_FINDPATH,
- CDUTILS_FINDPARENT,
- CDUTILS_FINDDIRENTRY,
- CDUTILS_NEWCDFILE,
- CDUTILS_UPDATESIZE,
- CDUTILS_UPDATESECTOR,
- CDUTILS_CREATESECTOR,
-};
-
-enum cdutils_functions_t {
- CDUTILS_NEWCDUTILS = 0,
- CDUTILS_SWAPWORD,
- CDUTILS_SWAPDWORD,
- CDUTILS_FROM_BCD,
- CDUTILS_TO_BCD,
- CDUTILS_IS_VALID_BCD,
- CDUTILS_FROM_MSF,
- CDUTILS_TO_MSF,
-};
-
-struct lua_functypes_t cdutils_methods[] = {
- { CDUTILS_SETISOW, "set_iso_w", 1, 1, {LUA_OBJECT} },
- { CDUTILS_GUESSTYPE, "guessmode", 0, 1, {LUA_NUMBER} },
- { CDUTILS_SECTORSEEK, "sectorseek", 1, 1, {LUA_NUMBER} },
- { CDUTILS_READSECTOR, "readsector", 0, 2, {LUA_NUMBER, LUA_NUMBER} },
- { CDUTILS_READDATAS, "readdatas", 1, 3, {LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
- { CDUTILS_READFILE, "readfile", 2, 4, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
- { CDUTILS_WRITESECTOR, "writesector", 1, 3, {LUA_TABLE, LUA_NUMBER, LUA_NUMBER} },
- { CDUTILS_WRITEDATAS, "writedatas", 2, 4, {LUA_TABLE, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
- { CDUTILS_WRITEFILE, "writefile", 1, 4, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
- { CDUTILS_GETISOINFOS, "getisoinfos", 0, 0, 0 },
- { CDUTILS_GETPTINFOS, "getptinfos", 0, 0, 0 },
- { CDUTILS_FINDPATH, "findpath", 1, 1, {LUA_STRING} },
- { CDUTILS_FINDPARENT, "findparent", 1, 1, {LUA_STRING} },
- { CDUTILS_FINDDIRENTRY, "finddirentry", 2, 2, {LUA_OBJECT, LUA_STRING} },
- { CDUTILS_NEWCDFILE, "cdfile", 1, 3, {LUA_ANY, LUA_NUMBER, LUA_NUMBER} },
- { CDUTILS_UPDATESIZE, "updatesize", 2, 2, {LUA_STRING, LUA_NUMBER} },
- { CDUTILS_UPDATESECTOR, "updatesector", 2, 2, {LUA_STRING, LUA_NUMBER} },
- { CDUTILS_CREATESECTOR, "createsector", 2, 3, {LUA_NUMBER, LUA_NUMBER, LUA_BOOLEAN} },
- { -1, 0, 0, 0, 0 }
-};
-
-struct lua_functypes_t cdutils_functions[] = {
- { CDUTILS_NEWCDUTILS, "cdutils" , 1, 2, {LUA_OBJECT, LUA_OBJECT} },
- { CDUTILS_SWAPWORD, "swapword", 1, 1, {LUA_NUMBER} },
- { CDUTILS_SWAPDWORD, "swapdword", 1, 1, {LUA_NUMBER} },
- { CDUTILS_FROM_BCD, "from_BCD", 1, 1, {LUA_NUMBER} },
- { CDUTILS_TO_BCD, "to_BCD", 1, 1, {LUA_NUMBER} },
- { CDUTILS_IS_VALID_BCD, "is_valid_BCD", 1, 1, {LUA_NUMBER} },
- { CDUTILS_FROM_MSF, "from_MSF", 1, 4, {LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
- { CDUTILS_TO_MSF, "to_MSF", 1, 2, {LUA_NUMBER, LUA_NUMBER} },
- { -1, 0, 0, 0, 0 }
-};
-
-class sLua_cdutils : public Base {
- public:
- DECLARE_METHOD(cdutils, CDUTILS_SETISOW);
- DECLARE_METHOD(cdutils, CDUTILS_GUESSTYPE);
- DECLARE_METHOD(cdutils, CDUTILS_SECTORSEEK);
- DECLARE_METHOD(cdutils, CDUTILS_READSECTOR);
- DECLARE_METHOD(cdutils, CDUTILS_READDATAS);
- DECLARE_METHOD(cdutils, CDUTILS_READFILE);
- DECLARE_METHOD(cdutils, CDUTILS_WRITESECTOR);
- DECLARE_METHOD(cdutils, CDUTILS_WRITEDATAS);
- DECLARE_METHOD(cdutils, CDUTILS_WRITEFILE);
- DECLARE_METHOD(cdutils, CDUTILS_GETISOINFOS);
- DECLARE_METHOD(cdutils, CDUTILS_GETPTINFOS);
- DECLARE_METHOD(cdutils, CDUTILS_FINDPATH);
- DECLARE_METHOD(cdutils, CDUTILS_FINDPARENT);
- DECLARE_METHOD(cdutils, CDUTILS_FINDDIRENTRY);
- DECLARE_METHOD(cdutils, CDUTILS_NEWCDFILE);
- DECLARE_METHOD(cdutils, CDUTILS_UPDATESIZE);
- DECLARE_METHOD(cdutils, CDUTILS_UPDATESECTOR);
- DECLARE_METHOD(cdutils, CDUTILS_CREATESECTOR);
-
- DECLARE_FUNCTION(cdutils, CDUTILS_NEWCDUTILS);
- DECLARE_FUNCTION(cdutils, CDUTILS_SWAPWORD);
- DECLARE_FUNCTION(cdutils, CDUTILS_SWAPDWORD);
- DECLARE_FUNCTION(cdutils, CDUTILS_FROM_BCD);
- DECLARE_FUNCTION(cdutils, CDUTILS_TO_BCD);
- DECLARE_FUNCTION(cdutils, CDUTILS_IS_VALID_BCD);
- DECLARE_FUNCTION(cdutils, CDUTILS_FROM_MSF);
- DECLARE_FUNCTION(cdutils, CDUTILS_TO_MSF);
-
- private:
- static int cdutils_proceed(Lua * L, int n, cdutils * obj, int caller);
- static int cdutils_proceed_statics(Lua * L, int n, int caller);
-};
-
-void Luacdutils::pushmembers(Lua * L) {
- pushme(L, cd);
-
- PUSH_METHOD(cdutils, CDUTILS_SETISOW);
- PUSH_METHOD(cdutils, CDUTILS_GUESSTYPE);
- PUSH_METHOD(cdutils, CDUTILS_SECTORSEEK);
- PUSH_METHOD(cdutils, CDUTILS_READSECTOR);
- PUSH_METHOD(cdutils, CDUTILS_READDATAS);
- PUSH_METHOD(cdutils, CDUTILS_READFILE);
- PUSH_METHOD(cdutils, CDUTILS_WRITESECTOR);
- PUSH_METHOD(cdutils, CDUTILS_WRITEDATAS);
- PUSH_METHOD(cdutils, CDUTILS_WRITEFILE);
- PUSH_METHOD(cdutils, CDUTILS_GETISOINFOS);
- PUSH_METHOD(cdutils, CDUTILS_GETPTINFOS);
- PUSH_METHOD(cdutils, CDUTILS_FINDPATH);
- PUSH_METHOD(cdutils, CDUTILS_FINDPARENT);
- PUSH_METHOD(cdutils, CDUTILS_FINDDIRENTRY);
- PUSH_METHOD(cdutils, CDUTILS_NEWCDFILE);
- PUSH_METHOD(cdutils, CDUTILS_UPDATESIZE);
- PUSH_METHOD(cdutils, CDUTILS_UPDATESECTOR);
- PUSH_METHOD(cdutils, CDUTILS_CREATESECTOR);
-}
-
-void Luacdutils::pushstatics(Lua * L) throw (GeneralException) {
- CHECK_METHODS(cdutils);
- CHECK_FUNCTIONS(cdutils);
-
- PUSH_FUNCTION(cdutils, CDUTILS_NEWCDUTILS);
- PUSH_FUNCTION(cdutils, CDUTILS_SWAPWORD);
- PUSH_FUNCTION(cdutils, CDUTILS_SWAPDWORD);
- PUSH_FUNCTION(cdutils, CDUTILS_FROM_BCD);
- PUSH_FUNCTION(cdutils, CDUTILS_TO_BCD);
- PUSH_FUNCTION(cdutils, CDUTILS_IS_VALID_BCD);
- PUSH_FUNCTION(cdutils, CDUTILS_FROM_MSF);
- PUSH_FUNCTION(cdutils, CDUTILS_TO_MSF);
-
- L->push("MODE0");
- L->push((lua_Number) MODE0);
- L->setvar();
-
- L->push("MODE1");
- L->push((lua_Number) MODE1);
- L->setvar();
-
- L->push("MODE2");
- L->push((lua_Number) MODE2);
- L->setvar();
-
- L->push("MODE2_FORM1");
- L->push((lua_Number) MODE2_FORM1);
- L->setvar();
-
- L->push("MODE2_FORM2");
- L->push((lua_Number) MODE2_FORM2);
- L->setvar();
-
- L->push("MORE_RAW");
- L->push((lua_Number) MODE_RAW);
- L->setvar();
-
- L->push("GUESS");
- L->push((lua_Number) GUESS);
- L->setvar();
-
- int i;
-
- L->push("sec_sizes");
- L->newtable();
- for (i = 0; i <= GUESS; i++) {
- L->push((lua_Number) i);
- L->push((lua_Number) sec_sizes[i]);
- L->settable();
- }
- L->setvar();
-
- L->push("sec_offsts");
- L->newtable();
- for (i = 0; i <= GUESS; i++) {
- L->push((lua_Number) i);
- L->push((lua_Number) sec_offsts[i]);
- L->settable();
- }
- L->setvar();
-
- L->push("sec_modes");
- L->newtable();
- for (i = 0; i <= GUESS; i++) {
- L->push((lua_Number) i);
- L->push(sec_modes[i]);
- L->settable();
- }
- L->setvar();
-}
-
-int sLua_cdutils::cdutils_proceed(Lua * L, int n, cdutils * cd, int caller) {
- int r = 0, sect = -1, mode = GUESS, size = -1, i;
- Handle * h;
- Byte sdatas[2352], * datas;
- String path;
- cdutils::DirEntry * dir, * bdir, * adir, pdir;
- bool invalid = false, eof = false;
- int sector;
- cdfile * cdf;
-
- switch(caller) {
- case CDUTILS_SETISOW:
- h = (Handle *) LuaObject::getme(L, 2);
- cd->set_iso_w(h);
- break;
- case CDUTILS_GUESSTYPE:
- if (n == 1) {
- sect = L->tonumber(2);
- }
- L->push((lua_Number) cd->guess_type(sect));
- r = 1;
- break;
- case CDUTILS_SECTORSEEK:
- sect = L->tonumber(2);
- cd->sector_seek(sect);
- break;
- case CDUTILS_READSECTOR:
- if (n >= 1)
- sect = L->tonumber(2);
- if (n == 2)
- mode = 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:
- size = L->tonumber(2);
- if (n >= 2)
- sect = L->tonumber(3);
- if (n == 3)
- mode = L->tonumber(3);
- datas = (Byte *) malloc(size);
- cd->read_datas(datas, size, mode, sect);
- 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);
- size = L->tonumber(5);
- if (n >= 3)
- sect = L->tonumber(4);
- if (n == 4)
- mode = L->tonumber(5);
- cd->read_file(h, size, mode, sect);
- break;
- case CDUTILS_WRITESECTOR:
- if (n >= 2)
- sect = L->tonumber(3);
- if (n == 3)
- mode = 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:
- size = L->tonumber(3);
- if (n >= 3)
- sect = L->tonumber(4);
- if (n == 4)
- mode = 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, size, mode, sect);
- free(datas);
- break;
- case CDUTILS_WRITEFILE:
- h = (Handle *) LuaObject::getme(L, 2);
- if (n >= 2)
- size = L->tonumber(3);
- if (n >= 3)
- sect = L->tonumber(4);
- if (n == 4)
- mode = L->tonumber(5);
- cd->write_file(h, size, 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);
- 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);
- break;
- case CDUTILS_FINDPARENT:
- path = L->tostring(2);
- bdir = cd->find_parent(&datas, path);
- 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);
- break;
- case CDUTILS_FINDDIRENTRY:
- adir = (cdutils::DirEntry *) LuaObject::getme(L, 2);
- path = L->tostring(3);
- bdir = cd->find_dir_entry(&datas, adir, path);
- 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);
- break;
- case CDUTILS_NEWCDFILE:
- if (L->istable(2)) {
- if (n <= 2) {
- dir = (cdutils::DirEntry *) LuaObject::getme(L, 2);
- if (n == 2)
- mode = L->tonumber(3);
- cdf = new cdfile(cd, dir, mode);
- } else {
- invalid = true;
- }
- } else if (L->isnumber(2)) {
- if (n >= 1) {
- sector = L->tonumber(2);
- if (n >= 2)
- size = L->tonumber(3);
- if (n == 3)
- 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 cdfile");
- } else {
- Luacdfile luacdf(cdf);
- luacdf.pushdestruct(L);
- r = 1;
- }
- break;
- case CDUTILS_UPDATESIZE:
- case CDUTILS_UPDATESECTOR:
- path = L->tostring(2);
- pdir = cd->find_parent(path);
- dir = cd->find_path(&datas, path);
- switch (caller) {
- case CDUTILS_UPDATESIZE:
- dir->Size = tolittle((Uint32) L->tonumber(3));
- dir->BESize = tobig((Uint32) L->tonumber(3));
- break;
- case CDUTILS_UPDATESECTOR:
- dir->Sector = tolittle((Uint32) L->tonumber(3));
- dir->BESector = tobig((Uint32) L->tonumber(3));
- break;
- }
- cd->write_datas(datas, pdir.Size, GUESS, pdir.Sector);
- free(datas);
- break;
- case CDUTILS_CREATESECTOR:
- mode = L->tonumber(2);
- sect = L->tonumber(3);
- if (n == 3)
- eof = L->toboolean(4);
- cd->create_sector(mode, sect, eof);
- break;
- }
-
-
- return r;
-}
-
-int sLua_cdutils::cdutils_proceed_statics(Lua * L, int n, int caller) {
- int r = 0;
- Uint32 x;
- Handle * isor = 0, * isow = 0;
- Uint32 sector, msf, start = 150;
- Byte m, s, f;
-
- switch(caller) {
- case CDUTILS_NEWCDUTILS:
- 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();
- L->push((lua_Number) cdutils::swap_word(x));
- r = 1;
- break;
- case CDUTILS_SWAPDWORD:
- x = L->tonumber();
- L->push((lua_Number) cdutils::swap_dword(x));
- r = 1;
- break;
- case CDUTILS_FROM_BCD:
- x = L->tonumber();
- L->push((lua_Number) cdutils::from_BCD(x));
- r = 1;
- break;
- case CDUTILS_TO_BCD:
- x = L->tonumber();
- L->push((lua_Number) cdutils::to_BCD(x));
- r = 1;
- break;
- case CDUTILS_IS_VALID_BCD:
- x = L->tonumber();
- L->push(cdutils::is_valid_BCD(x));
- r = 1;
- break;
- case CDUTILS_FROM_MSF:
- 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;
- case CDUTILS_TO_MSF:
- sector = L->tonumber(1);
- if (n == 2)
- start = L->tonumber(2);
- cdutils::to_MSF(sector, m, s, f, start);
- msf = cdutils::to_MSF(sector, start);
- L->push((lua_Number) msf);
- L->push((lua_Number) m);
- L->push((lua_Number) s);
- L->push((lua_Number) f);
- r = 4;
- break;
- }
-
- return r;
-}
-
-
- /***************************\
-|** class direntry exports **|
- \***************************/
-
-typedef cdutils::DirEntry direntry;
-
-Luadirentry::Luadirentry(cdutils::DirEntry * _dir) : dir(_dir) { }
-
-enum direntry_methods_t {
- DIRENTRY_INDEX = 0,
- DIRENTRY_ISHIDDEN,
- DIRENTRY_ISDIR,
- DIRENTRY_HASXA,
- DIRENTRY_ISXADIR,
- DIRENTRY_ISXAAUDIO,
- DIRENTRY_ISXASTR,
- DIRENTRY_ISXAXA,
- DIRENTRY_ISXAFORM1,
-};
-
-struct lua_functypes_t direntry_methods[] = {
- { DIRENTRY_INDEX, "index", 1, 1, {LUA_STRING} },
- { DIRENTRY_ISHIDDEN, "ishidden", 0, 0, 0 },
- { DIRENTRY_ISDIR, "isdir", 0, 0, 0 },
- { 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_ISHIDDEN);
- DECLARE_METHOD(direntry, DIRENTRY_ISDIR);
- 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);
-};
-
-void Luadirentry::pushmembers(Lua * L) {
- pushme(L, dir, false);
-
- PUSH_METAMETHOD(direntry, DIRENTRY_INDEX);
- PUSH_METHOD(direntry, DIRENTRY_ISHIDDEN);
- PUSH_METHOD(direntry, DIRENTRY_ISDIR);
- 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, 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_ISHIDDEN:
- L->push(dir->Flags & 1 ? true : false);
- r = 1;
- break;
- case DIRENTRY_ISDIR:
- L->push(dir->Flags & 2 ? true : false);
- 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;
- if (index == "R") {
- L->push((lua_Number) dir->R);
- } else if (index == "NExt") {
- L->push((lua_Number) dir->NExt);
- } else if (index == "Sector") {
- L->push((lua_Number) dir->Sector);
- } else if (index == "Size") {
- L->push((lua_Number) dir->Size);
- } else if (index == "Year") {
- L->push((lua_Number) dir->Year);
- } else if (index == "Month") {
- L->push((lua_Number) dir->Month);
- } else if (index == "Day") {
- L->push((lua_Number) dir->Day);
- } else if (index == "Hour") {
- L->push((lua_Number) dir->Hour);
- } else if (index == "Minute") {
- L->push((lua_Number) dir->Minute);
- } else if (index == "Second") {
- L->push((lua_Number) dir->Second);
- } else if (index == "Offset") {
- L->push((lua_Number) dir->Offset);
- } else if (index == "Flags") {
- L->push((lua_Number) dir->Flags);
- } else if (index == "HandleUnit") {
- L->push((lua_Number) dir->HandleUnit);
- } else if (index == "HandleGap") {
- L->push((lua_Number) dir->HandleGap);
- } else if (index == "VolSeq") {
- L->push((lua_Number) dir->VolSeq);
- } else if (index == "N") {
- L->push((lua_Number) dir->N);
- } else if (index == "id") {
- char pbuf[256];
- memcpy(pbuf, dir->id, dir->N);
- pbuf[dir->N] = 0;
- L->push(pbuf, dir->N);
- } else {
- L->push();
- }
- }
-
- return r;
-}
-
-
- /***************************\
-|** class direntry exports **|
- \***************************/
-
-typedef isobuilder::Date cddate;
-
-Luacddate::Luacddate(isobuilder::Date * _date) : date(_date) { }
-
-enum cddate_methods_t {
- CDDATE_INDEX = 0,
- CDDATE_NEWINDEX,
-};
-
-enum cddate_functions_t {
- CDDATE_NEWCDDATE = 0,
-};
-
-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 }
-};
-
-struct lua_functypes_t cddate_functions[] = {
- { CDDATE_NEWCDDATE, "cddate", 0, 0, 0 },
- { -1, 0, 0, 0, 0 }
-};
-
-class sLua_cddate : public Base {
- public:
- DECLARE_METHOD(cddate, CDDATE_INDEX);
- DECLARE_METHOD(cddate, CDDATE_NEWINDEX);
- DECLARE_FUNCTION(cddate, CDDATE_NEWCDDATE);
- private:
- static int cddate_proceed(Lua * L, int n, cddate * obj, int caller);
- static int cddate_proceed_statics(Lua * L, int n, int caller);
-};
-
-void Luacddate::pushmembers(Lua * L) {
- pushme(L, date, false);
-
- PUSH_METAMETHOD(cddate, CDDATE_INDEX);
- PUSH_METAMETHOD(cddate, CDDATE_NEWINDEX);
-}
-
-void Luacddate::pushstatics(Lua * L) throw (GeneralException) {
- CHECK_METHODS(cddate);
- CHECK_FUNCTIONS(cddate);
-
- PUSH_FUNCTION(cddate, CDDATE_NEWCDDATE);
-}
-
-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:
- r = 0;
- 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;
-}
-
-int sLua_cddate::cddate_proceed_statics(Lua * L, int n, int caller) {
- int r = 0;
-
- switch (caller) {
- case CDDATE_NEWCDDATE:
- {
- Luacddate t(new isobuilder::Date());
- t.pushdestruct(L);
- }
- }
-
- 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, false);
-
- 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 = 0, 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->tostring(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((PVD *) malloc(sizeof(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 if (key == "isdir") {
- L->push(dir->isdir());
- } 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_TABLE, 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_STRING, LUA_OBJECT, LUA_OBJECT, LUA_NUMBER} },
- { ISOBUILDER_COPYDIR, "copydir", 3, 4, {LUA_OBJECT, LUA_OBJECT, LUA_OBJECT, LUA_NUMBER} },
- { ISOBUILDER_CLOSE, "close", 0, 3, {LUA_OBJECT, LUA_NUMBER, 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 {
+/*
+ * 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.15 2004-11-27 21:47:56 pixel Exp $ */
+
+#include "luacd.h"
+
+
+ /**************************\
+|** class cdutils exports **|
+ \**************************/
+
+Luacdutils::Luacdutils(cdutils * _cd) : cd(_cd) { }
+class Luacdfile : public LuaHandle {
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);
+ Luacdfile(cdfile * h) : LuaHandle(h) {}
};
-
-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, nsects = -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);
- name = L->tostring(3);
- h = (Handle *) LuaObject::getme(L, 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);
- cd = (cdutils *) LuaObject::getme(L, 3);
- dire = (direntry *) LuaObject::getme(L, 4);
- if (n >= 4)
- mode = L->tonumber(5);
- iso->copydir(dirt, cd, dire, mode);
- break;
- case ISOBUILDER_CLOSE:
- if (n >= 1)
- h = (Handle *) LuaObject::getme(L, 2);
- if (n >= 2)
- mode = L->tonumber(3);
- if (n >= 3)
- nsects = L->tonumber(4);
- iso->close(h, mode, nsects);
- 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 = (PVD *) malloc(sizeof(PVD));
- *pvd = isobuilder::createpvd(h);
- {
- LuaPVD t(pvd);
- t.pushdestruct(L);
- }
- r = 1;
- break;
- case ISOBUILDER_CREATEPVD:
- cd = (cdutils *) LuaObject::getme(L, 1);
- pvd = (PVD *) malloc(sizeof(PVD));
- *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 = (PVD *) malloc(sizeof(PVD));
- *pvd = isobuilder::createpvd(datas);
- {
- LuaPVD t(pvd);
- t.pushdestruct(L);
- }
- r = 1;
- break;
- }
-
- return r;
-}
+
+enum cdutils_methods_t {
+ CDUTILS_SETISOW = 0,
+ CDUTILS_GUESSTYPE,
+ CDUTILS_SECTORSEEK,
+ CDUTILS_READSECTOR,
+ CDUTILS_READDATAS,
+ CDUTILS_READFILE,
+ CDUTILS_WRITESECTOR,
+ CDUTILS_WRITEDATAS,
+ CDUTILS_WRITEFILE,
+ CDUTILS_GETISOINFOS,
+ CDUTILS_GETPTINFOS,
+ CDUTILS_FINDPATH,
+ CDUTILS_FINDPARENT,
+ CDUTILS_FINDDIRENTRY,
+ CDUTILS_NEWCDFILE,
+ CDUTILS_UPDATESIZE,
+ CDUTILS_UPDATESECTOR,
+ CDUTILS_CREATESECTOR,
+};
+
+enum cdutils_functions_t {
+ CDUTILS_NEWCDUTILS = 0,
+ CDUTILS_SWAPWORD,
+ CDUTILS_SWAPDWORD,
+ CDUTILS_FROM_BCD,
+ CDUTILS_TO_BCD,
+ CDUTILS_IS_VALID_BCD,
+ CDUTILS_FROM_MSF,
+ CDUTILS_TO_MSF,
+};
+
+struct lua_functypes_t cdutils_methods[] = {
+ { CDUTILS_SETISOW, "set_iso_w", 1, 1, {LUA_OBJECT} },
+ { CDUTILS_GUESSTYPE, "guessmode", 0, 1, {LUA_NUMBER} },
+ { CDUTILS_SECTORSEEK, "sectorseek", 1, 1, {LUA_NUMBER} },
+ { CDUTILS_READSECTOR, "readsector", 0, 2, {LUA_NUMBER, LUA_NUMBER} },
+ { CDUTILS_READDATAS, "readdatas", 1, 3, {LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
+ { CDUTILS_READFILE, "readfile", 2, 4, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
+ { CDUTILS_WRITESECTOR, "writesector", 1, 3, {LUA_TABLE, LUA_NUMBER, LUA_NUMBER} },
+ { CDUTILS_WRITEDATAS, "writedatas", 2, 4, {LUA_TABLE, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
+ { CDUTILS_WRITEFILE, "writefile", 1, 4, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
+ { CDUTILS_GETISOINFOS, "getisoinfos", 0, 0, 0 },
+ { CDUTILS_GETPTINFOS, "getptinfos", 0, 0, 0 },
+ { CDUTILS_FINDPATH, "findpath", 1, 1, {LUA_STRING} },
+ { CDUTILS_FINDPARENT, "findparent", 1, 1, {LUA_STRING} },
+ { CDUTILS_FINDDIRENTRY, "finddirentry", 2, 2, {LUA_OBJECT, LUA_STRING} },
+ { CDUTILS_NEWCDFILE, "cdfile", 1, 3, {LUA_ANY, LUA_NUMBER, LUA_NUMBER} },
+ { CDUTILS_UPDATESIZE, "updatesize", 2, 2, {LUA_STRING, LUA_NUMBER} },
+ { CDUTILS_UPDATESECTOR, "updatesector", 2, 2, {LUA_STRING, LUA_NUMBER} },
+ { CDUTILS_CREATESECTOR, "createsector", 2, 3, {LUA_NUMBER, LUA_NUMBER, LUA_BOOLEAN} },
+ { -1, 0, 0, 0, 0 }
+};
+
+struct lua_functypes_t cdutils_functions[] = {
+ { CDUTILS_NEWCDUTILS, "cdutils" , 1, 2, {LUA_OBJECT, LUA_OBJECT} },
+ { CDUTILS_SWAPWORD, "swapword", 1, 1, {LUA_NUMBER} },
+ { CDUTILS_SWAPDWORD, "swapdword", 1, 1, {LUA_NUMBER} },
+ { CDUTILS_FROM_BCD, "from_BCD", 1, 1, {LUA_NUMBER} },
+ { CDUTILS_TO_BCD, "to_BCD", 1, 1, {LUA_NUMBER} },
+ { CDUTILS_IS_VALID_BCD, "is_valid_BCD", 1, 1, {LUA_NUMBER} },
+ { CDUTILS_FROM_MSF, "from_MSF", 1, 4, {LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
+ { CDUTILS_TO_MSF, "to_MSF", 1, 2, {LUA_NUMBER, LUA_NUMBER} },
+ { -1, 0, 0, 0, 0 }
+};
+
+class sLua_cdutils : public Base {
+ public:
+ DECLARE_METHOD(cdutils, CDUTILS_SETISOW);
+ DECLARE_METHOD(cdutils, CDUTILS_GUESSTYPE);
+ DECLARE_METHOD(cdutils, CDUTILS_SECTORSEEK);
+ DECLARE_METHOD(cdutils, CDUTILS_READSECTOR);
+ DECLARE_METHOD(cdutils, CDUTILS_READDATAS);
+ DECLARE_METHOD(cdutils, CDUTILS_READFILE);
+ DECLARE_METHOD(cdutils, CDUTILS_WRITESECTOR);
+ DECLARE_METHOD(cdutils, CDUTILS_WRITEDATAS);
+ DECLARE_METHOD(cdutils, CDUTILS_WRITEFILE);
+ DECLARE_METHOD(cdutils, CDUTILS_GETISOINFOS);
+ DECLARE_METHOD(cdutils, CDUTILS_GETPTINFOS);
+ DECLARE_METHOD(cdutils, CDUTILS_FINDPATH);
+ DECLARE_METHOD(cdutils, CDUTILS_FINDPARENT);
+ DECLARE_METHOD(cdutils, CDUTILS_FINDDIRENTRY);
+ DECLARE_METHOD(cdutils, CDUTILS_NEWCDFILE);
+ DECLARE_METHOD(cdutils, CDUTILS_UPDATESIZE);
+ DECLARE_METHOD(cdutils, CDUTILS_UPDATESECTOR);
+ DECLARE_METHOD(cdutils, CDUTILS_CREATESECTOR);
+
+ DECLARE_FUNCTION(cdutils, CDUTILS_NEWCDUTILS);
+ DECLARE_FUNCTION(cdutils, CDUTILS_SWAPWORD);
+ DECLARE_FUNCTION(cdutils, CDUTILS_SWAPDWORD);
+ DECLARE_FUNCTION(cdutils, CDUTILS_FROM_BCD);
+ DECLARE_FUNCTION(cdutils, CDUTILS_TO_BCD);
+ DECLARE_FUNCTION(cdutils, CDUTILS_IS_VALID_BCD);
+ DECLARE_FUNCTION(cdutils, CDUTILS_FROM_MSF);
+ DECLARE_FUNCTION(cdutils, CDUTILS_TO_MSF);
+
+ private:
+ static int cdutils_proceed(Lua * L, int n, cdutils * obj, int caller);
+ static int cdutils_proceed_statics(Lua * L, int n, int caller);
+};
+
+void Luacdutils::pushmembers(Lua * L) {
+ pushme(L, cd);
+
+ PUSH_METHOD(cdutils, CDUTILS_SETISOW);
+ PUSH_METHOD(cdutils, CDUTILS_GUESSTYPE);
+ PUSH_METHOD(cdutils, CDUTILS_SECTORSEEK);
+ PUSH_METHOD(cdutils, CDUTILS_READSECTOR);
+ PUSH_METHOD(cdutils, CDUTILS_READDATAS);
+ PUSH_METHOD(cdutils, CDUTILS_READFILE);
+ PUSH_METHOD(cdutils, CDUTILS_WRITESECTOR);
+ PUSH_METHOD(cdutils, CDUTILS_WRITEDATAS);
+ PUSH_METHOD(cdutils, CDUTILS_WRITEFILE);
+ PUSH_METHOD(cdutils, CDUTILS_GETISOINFOS);
+ PUSH_METHOD(cdutils, CDUTILS_GETPTINFOS);
+ PUSH_METHOD(cdutils, CDUTILS_FINDPATH);
+ PUSH_METHOD(cdutils, CDUTILS_FINDPARENT);
+ PUSH_METHOD(cdutils, CDUTILS_FINDDIRENTRY);
+ PUSH_METHOD(cdutils, CDUTILS_NEWCDFILE);
+ PUSH_METHOD(cdutils, CDUTILS_UPDATESIZE);
+ PUSH_METHOD(cdutils, CDUTILS_UPDATESECTOR);
+ PUSH_METHOD(cdutils, CDUTILS_CREATESECTOR);
+}
+
+void Luacdutils::pushstatics(Lua * L) throw (GeneralException) {
+ CHECK_METHODS(cdutils);
+ CHECK_FUNCTIONS(cdutils);
+
+ PUSH_FUNCTION(cdutils, CDUTILS_NEWCDUTILS);
+ PUSH_FUNCTION(cdutils, CDUTILS_SWAPWORD);
+ PUSH_FUNCTION(cdutils, CDUTILS_SWAPDWORD);
+ PUSH_FUNCTION(cdutils, CDUTILS_FROM_BCD);
+ PUSH_FUNCTION(cdutils, CDUTILS_TO_BCD);
+ PUSH_FUNCTION(cdutils, CDUTILS_IS_VALID_BCD);
+ PUSH_FUNCTION(cdutils, CDUTILS_FROM_MSF);
+ PUSH_FUNCTION(cdutils, CDUTILS_TO_MSF);
+
+ L->push("MODE0");
+ L->push((lua_Number) MODE0);
+ L->setvar();
+
+ L->push("MODE1");
+ L->push((lua_Number) MODE1);
+ L->setvar();
+
+ L->push("MODE2");
+ L->push((lua_Number) MODE2);
+ L->setvar();
+
+ L->push("MODE2_FORM1");
+ L->push((lua_Number) MODE2_FORM1);
+ L->setvar();
+
+ L->push("MODE2_FORM2");
+ L->push((lua_Number) MODE2_FORM2);
+ L->setvar();
+
+ L->push("MORE_RAW");
+ L->push((lua_Number) MODE_RAW);
+ L->setvar();
+
+ L->push("GUESS");
+ L->push((lua_Number) GUESS);
+ L->setvar();
+
+ int i;
+
+ L->push("sec_sizes");
+ L->newtable();
+ for (i = 0; i <= GUESS; i++) {
+ L->push((lua_Number) i);
+ L->push((lua_Number) sec_sizes[i]);
+ L->settable();
+ }
+ L->setvar();
+
+ L->push("sec_offsts");
+ L->newtable();
+ for (i = 0; i <= GUESS; i++) {
+ L->push((lua_Number) i);
+ L->push((lua_Number) sec_offsts[i]);
+ L->settable();
+ }
+ L->setvar();
+
+ L->push("sec_modes");
+ L->newtable();
+ for (i = 0; i <= GUESS; i++) {
+ L->push((lua_Number) i);
+ L->push(sec_modes[i]);
+ L->settable();
+ }
+ L->setvar();
+}
+
+int sLua_cdutils::cdutils_proceed(Lua * L, int n, cdutils * cd, int caller) {
+ int r = 0, sect = -1, mode = GUESS, size = -1, i;
+ Handle * h;
+ Byte sdatas[2352], * datas;
+ String path;
+ cdutils::DirEntry * dir, * bdir, * adir, pdir;
+ bool invalid = false, eof = false;
+ int sector;
+ cdfile * cdf;
+
+ switch(caller) {
+ case CDUTILS_SETISOW:
+ h = (Handle *) LuaObject::getme(L, 2);
+ cd->set_iso_w(h);
+ break;
+ case CDUTILS_GUESSTYPE:
+ if (n == 1) {
+ sect = L->tonumber(2);
+ }
+ L->push((lua_Number) cd->guess_type(sect));
+ r = 1;
+ break;
+ case CDUTILS_SECTORSEEK:
+ sect = L->tonumber(2);
+ cd->sector_seek(sect);
+ break;
+ case CDUTILS_READSECTOR:
+ if (n >= 1)
+ sect = L->tonumber(2);
+ if (n == 2)
+ mode = 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:
+ size = L->tonumber(2);
+ if (n >= 2)
+ sect = L->tonumber(3);
+ if (n == 3)
+ mode = L->tonumber(3);
+ datas = (Byte *) malloc(size);
+ cd->read_datas(datas, size, mode, sect);
+ 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);
+ size = L->tonumber(5);
+ if (n >= 3)
+ sect = L->tonumber(4);
+ if (n == 4)
+ mode = L->tonumber(5);
+ cd->read_file(h, size, mode, sect);
+ break;
+ case CDUTILS_WRITESECTOR:
+ if (n >= 2)
+ sect = L->tonumber(3);
+ if (n == 3)
+ mode = 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:
+ size = L->tonumber(3);
+ if (n >= 3)
+ sect = L->tonumber(4);
+ if (n == 4)
+ mode = 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, size, mode, sect);
+ free(datas);
+ break;
+ case CDUTILS_WRITEFILE:
+ h = (Handle *) LuaObject::getme(L, 2);
+ if (n >= 2)
+ size = L->tonumber(3);
+ if (n >= 3)
+ sect = L->tonumber(4);
+ if (n == 4)
+ mode = L->tonumber(5);
+ cd->write_file(h, size, 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);
+ 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);
+ break;
+ case CDUTILS_FINDPARENT:
+ path = L->tostring(2);
+ bdir = cd->find_parent(&datas, path);
+ 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);
+ break;
+ case CDUTILS_FINDDIRENTRY:
+ adir = (cdutils::DirEntry *) LuaObject::getme(L, 2);
+ path = L->tostring(3);
+ bdir = cd->find_dir_entry(&datas, adir, path);
+ 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);
+ break;
+ case CDUTILS_NEWCDFILE:
+ if (L->istable(2)) {
+ if (n <= 2) {
+ dir = (cdutils::DirEntry *) LuaObject::getme(L, 2);
+ if (n == 2)
+ mode = L->tonumber(3);
+ cdf = new cdfile(cd, dir, mode);
+ } else {
+ invalid = true;
+ }
+ } else if (L->isnumber(2)) {
+ if (n >= 1) {
+ sector = L->tonumber(2);
+ if (n >= 2)
+ size = L->tonumber(3);
+ if (n == 3)
+ 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 cdfile");
+ } else {
+ Luacdfile luacdf(cdf);
+ luacdf.pushdestruct(L);
+ r = 1;
+ }
+ break;
+ case CDUTILS_UPDATESIZE:
+ case CDUTILS_UPDATESECTOR:
+ path = L->tostring(2);
+ pdir = cd->find_parent(path);
+ dir = cd->find_path(&datas, path);
+ switch (caller) {
+ case CDUTILS_UPDATESIZE:
+ dir->Size = tolittle((Uint32) L->tonumber(3));
+ dir->BESize = tobig((Uint32) L->tonumber(3));
+ break;
+ case CDUTILS_UPDATESECTOR:
+ dir->Sector = tolittle((Uint32) L->tonumber(3));
+ dir->BESector = tobig((Uint32) L->tonumber(3));
+ break;
+ }
+ cd->write_datas(datas, pdir.Size, GUESS, pdir.Sector);
+ free(datas);
+ break;
+ case CDUTILS_CREATESECTOR:
+ mode = L->tonumber(2);
+ sect = L->tonumber(3);
+ if (n == 3)
+ eof = L->toboolean(4);
+ cd->create_sector(mode, sect, eof);
+ break;
+ }
+
+
+ return r;
+}
+
+int sLua_cdutils::cdutils_proceed_statics(Lua * L, int n, int caller) {
+ int r = 0;
+ Uint32 x;
+ Handle * isor = 0, * isow = 0;
+ Uint32 sector, msf, start = 150;
+ Byte m, s, f;
+
+ switch(caller) {
+ case CDUTILS_NEWCDUTILS:
+ 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();
+ L->push((lua_Number) cdutils::swap_word(x));
+ r = 1;
+ break;
+ case CDUTILS_SWAPDWORD:
+ x = L->tonumber();
+ L->push((lua_Number) cdutils::swap_dword(x));
+ r = 1;
+ break;
+ case CDUTILS_FROM_BCD:
+ x = L->tonumber();
+ L->push((lua_Number) cdutils::from_BCD(x));
+ r = 1;
+ break;
+ case CDUTILS_TO_BCD:
+ x = L->tonumber();
+ L->push((lua_Number) cdutils::to_BCD(x));
+ r = 1;
+ break;
+ case CDUTILS_IS_VALID_BCD:
+ x = L->tonumber();
+ L->push(cdutils::is_valid_BCD(x));
+ r = 1;
+ break;
+ case CDUTILS_FROM_MSF:
+ 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;
+ case CDUTILS_TO_MSF:
+ sector = L->tonumber(1);
+ if (n == 2)
+ start = L->tonumber(2);
+ cdutils::to_MSF(sector, m, s, f, start);
+ msf = cdutils::to_MSF(sector, start);
+ L->push((lua_Number) msf);
+ L->push((lua_Number) m);
+ L->push((lua_Number) s);
+ L->push((lua_Number) f);
+ r = 4;
+ break;
+ }
+
+ return r;
+}
+
+
+ /***************************\
+|** class direntry exports **|
+ \***************************/
+
+typedef cdutils::DirEntry direntry;
+
+Luadirentry::Luadirentry(cdutils::DirEntry * _dir) : dir(_dir) { }
+
+enum direntry_methods_t {
+ DIRENTRY_INDEX = 0,
+ DIRENTRY_ISHIDDEN,
+ DIRENTRY_ISDIR,
+ DIRENTRY_HASXA,
+ DIRENTRY_ISXADIR,
+ DIRENTRY_ISXAAUDIO,
+ DIRENTRY_ISXASTR,
+ DIRENTRY_ISXAXA,
+ DIRENTRY_ISXAFORM1,
+};
+
+struct lua_functypes_t direntry_methods[] = {
+ { DIRENTRY_INDEX, "index", 1, 1, {LUA_STRING} },
+ { DIRENTRY_ISHIDDEN, "ishidden", 0, 0, 0 },
+ { DIRENTRY_ISDIR, "isdir", 0, 0, 0 },
+ { 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_ISHIDDEN);
+ DECLARE_METHOD(direntry, DIRENTRY_ISDIR);
+ 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);
+};
+
+void Luadirentry::pushmembers(Lua * L) {
+ pushme(L, dir, false);
+
+ PUSH_METAMETHOD(direntry, DIRENTRY_INDEX);
+ PUSH_METHOD(direntry, DIRENTRY_ISHIDDEN);
+ PUSH_METHOD(direntry, DIRENTRY_ISDIR);
+ 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, 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_ISHIDDEN:
+ L->push(dir->Flags & 1 ? true : false);
+ r = 1;
+ break;
+ case DIRENTRY_ISDIR:
+ L->push(dir->Flags & 2 ? true : false);
+ 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;
+ if (index == "R") {
+ L->push((lua_Number) dir->R);
+ } else if (index == "NExt") {
+ L->push((lua_Number) dir->NExt);
+ } else if (index == "Sector") {
+ L->push((lua_Number) dir->Sector);
+ } else if (index == "Size") {
+ L->push((lua_Number) dir->Size);
+ } else if (index == "Year") {
+ L->push((lua_Number) dir->Year);
+ } else if (index == "Month") {
+ L->push((lua_Number) dir->Month);
+ } else if (index == "Day") {
+ L->push((lua_Number) dir->Day);
+ } else if (index == "Hour") {
+ L->push((lua_Number) dir->Hour);
+ } else if (index == "Minute") {
+ L->push((lua_Number) dir->Minute);
+ } else if (index == "Second") {
+ L->push((lua_Number) dir->Second);
+ } else if (index == "Offset") {
+ L->push((lua_Number) dir->Offset);
+ } else if (index == "Flags") {
+ L->push((lua_Number) dir->Flags);
+ } else if (index == "HandleUnit") {
+ L->push((lua_Number) dir->HandleUnit);
+ } else if (index == "HandleGap") {
+ L->push((lua_Number) dir->HandleGap);
+ } else if (index == "VolSeq") {
+ L->push((lua_Number) dir->VolSeq);
+ } else if (index == "N") {
+ L->push((lua_Number) dir->N);
+ } else if (index == "id") {
+ char pbuf[256];
+ memcpy(pbuf, dir->id, dir->N);
+ pbuf[dir->N] = 0;
+ L->push(pbuf, dir->N);
+ } else {
+ L->push();
+ }
+ }
+
+ return r;
+}
+
+
+ /***************************\
+|** class direntry exports **|
+ \***************************/
+
+typedef isobuilder::Date cddate;
+
+Luacddate::Luacddate(isobuilder::Date * _date) : date(_date) { }
+
+enum cddate_methods_t {
+ CDDATE_INDEX = 0,
+ CDDATE_NEWINDEX,
+};
+
+enum cddate_functions_t {
+ CDDATE_NEWCDDATE = 0,
+};
+
+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 }
+};
+
+struct lua_functypes_t cddate_functions[] = {
+ { CDDATE_NEWCDDATE, "cddate", 0, 0, 0 },
+ { -1, 0, 0, 0, 0 }
+};
+
+class sLua_cddate : public Base {
+ public:
+ DECLARE_METHOD(cddate, CDDATE_INDEX);
+ DECLARE_METHOD(cddate, CDDATE_NEWINDEX);
+ DECLARE_FUNCTION(cddate, CDDATE_NEWCDDATE);
+ private:
+ static int cddate_proceed(Lua * L, int n, cddate * obj, int caller);
+ static int cddate_proceed_statics(Lua * L, int n, int caller);
+};
+
+void Luacddate::pushmembers(Lua * L) {
+ pushme(L, date, false);
+
+ PUSH_METAMETHOD(cddate, CDDATE_INDEX);
+ PUSH_METAMETHOD(cddate, CDDATE_NEWINDEX);
+}
+
+void Luacddate::pushstatics(Lua * L) throw (GeneralException) {
+ CHECK_METHODS(cddate);
+ CHECK_FUNCTIONS(cddate);
+
+ PUSH_FUNCTION(cddate, CDDATE_NEWCDDATE);
+}
+
+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:
+ r = 0;
+ 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;
+}
+
+int sLua_cddate::cddate_proceed_statics(Lua * L, int n, int caller) {
+ int r = 0;
+
+ switch (caller) {
+ case CDDATE_NEWCDDATE:
+ {
+ Luacddate t(new isobuilder::Date());
+ t.pushdestruct(L);
+ }
+ }
+
+ 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, false);
+
+ 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 = 0, 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->tostring(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((PVD *) malloc(sizeof(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 if (key == "isdir") {
+ L->push(dir->isdir());
+ } 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_TABLE, 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_STRING, LUA_OBJECT, LUA_OBJECT, LUA_NUMBER} },
+ { ISOBUILDER_COPYDIR, "copydir", 3, 4, {LUA_OBJECT, LUA_OBJECT, LUA_OBJECT, LUA_NUMBER} },
+ { ISOBUILDER_CLOSE, "close", 0, 3, {LUA_OBJECT, LUA_NUMBER, 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, nsects = -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);
+ name = L->tostring(3);
+ h = (Handle *) LuaObject::getme(L, 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);
+ cd = (cdutils *) LuaObject::getme(L, 3);
+ dire = (direntry *) LuaObject::getme(L, 4);
+ if (n >= 4)
+ mode = L->tonumber(5);
+ iso->copydir(dirt, cd, dire, mode);
+ break;
+ case ISOBUILDER_CLOSE:
+ if (n >= 1)
+ h = (Handle *) LuaObject::getme(L, 2);
+ if (n >= 2)
+ mode = L->tonumber(3);
+ if (n >= 3)
+ nsects = L->tonumber(4);
+ iso->close(h, mode, nsects);
+ 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 = (PVD *) malloc(sizeof(PVD));
+ *pvd = isobuilder::createpvd(h);
+ {
+ LuaPVD t(pvd);
+ t.pushdestruct(L);
+ }
+ r = 1;
+ break;
+ case ISOBUILDER_CREATEPVD:
+ cd = (cdutils *) LuaObject::getme(L, 1);
+ pvd = (PVD *) malloc(sizeof(PVD));
+ *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 = (PVD *) malloc(sizeof(PVD));
+ *pvd = isobuilder::createpvd(datas);
+ {
+ LuaPVD t(pvd);
+ t.pushdestruct(L);
+ }
+ r = 1;
+ break;
+ }
+
+ return r;
+}
diff --git a/lib/luapsx.cpp b/lib/luapsx.cpp
index eb1473b..da66ac6 100644
--- a/lib/luapsx.cpp
+++ b/lib/luapsx.cpp
@@ -1,307 +1,307 @@
-/*
- * 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: luapsx.cpp,v 1.6 2004-11-27 21:44:48 pixel Exp $ */
-
-#include <LuaHandle.h>
-#include "luapsx.h"
-#include "generic.h"
-
-void over(Byte * d, Byte R, Byte G, Byte B, Byte A) {
- d[0] = R;
- d[1] = G;
- d[2] = B;
-}
-
-void alpha(Byte * d, Byte R, Byte G, Byte B, Byte A) {
- A = MIN(A, (Byte) 128);
- d[0] = ((int)d[0] * (128 - A) + R * A) >> 7;
- d[1] = ((int)d[1] * (128 - A) + G * A) >> 7;
- d[2] = ((int)d[2] * (128 - A) + B * A) >> 7;
-}
-
-void lighten(Byte * d, Byte R, Byte G, Byte B, Byte A) {
- A = MIN(A, (Byte) 128);
- R = ((int)d[0] * (128 - A) + R * A) >> 7;
- G = ((int)d[1] * (128 - A) + G * A) >> 7;
- B = ((int)d[2] * (128 - A) + B * A) >> 7;
- d[0] = MAX(R, d[0]);
- d[1] = MAX(G, d[1]);
- d[2] = MAX(B, d[2]);
-}
-
-void darken(Byte * d, Byte R, Byte G, Byte B, Byte A) {
- A = MIN(A, (Byte) 128);
- R = ((int)d[0] * (128 - A) + R * A) >> 7;
- G = ((int)d[1] * (128 - A) + G * A) >> 7;
- B = ((int)d[2] * (128 - A) + B * A) >> 7;
- d[0] = MIN(R, d[0]);
- d[1] = MIN(G, d[1]);
- d[2] = MIN(B, d[2]);
-}
-
-enum {
- BLIT_OVER = 0,
- BLIT_OVER32,
- BLIT_ALPHA,
- BLIT_LIGHTEN,
- BLIT_LIGHTEN32,
- BLIT_DARKEN,
- BLIT_DARKEN32,
-};
-
-typedef void psx;
-
-enum psx_functions_t {
- PSX_BSDECODE = 0,
- PSX_BSENCODE,
- PSX_BLIT,
-};
-
-struct lua_functypes_t psx_functions[] = {
- { PSX_BSDECODE, "bsdecode", 3, 3, { LUA_OBJECT, LUA_NUMBER, LUA_NUMBER } },
- { PSX_BSENCODE, "bsencode", 3, 5, { LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER } },
- { PSX_BLIT, "blit", 9, 9, { LUA_OBJECT, LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER } },
- { -1, 0, 0, 0, 0 }
-};
-
-class sLua_psx : public Base {
- public:
- DECLARE_FUNCTION(psx, PSX_BSDECODE);
- DECLARE_FUNCTION(psx, PSX_BSENCODE);
- DECLARE_FUNCTION(psx, PSX_BLIT);
- private:
- static int psx_proceed_statics(Lua * L, int n, int caller);
-};
-
-void Luapsx::pushstatics(Lua * L) throw (GeneralException ) {
- CHECK_FUNCTIONS(psx);
-
- PUSH_FUNCTION(psx, PSX_BSDECODE);
- PUSH_FUNCTION(psx, PSX_BSENCODE);
- PUSH_FUNCTION(psx, PSX_BLIT);
-
- L->push("BLIT_OVER");
- L->push((lua_Number) BLIT_OVER);
- L->settable(LUA_GLOBALSINDEX);
-
- L->push("BLIT_OVER32");
- L->push((lua_Number) BLIT_OVER32);
- L->settable(LUA_GLOBALSINDEX);
-
- L->push("BLIT_ALPHA");
- L->push((lua_Number) BLIT_ALPHA);
- L->settable(LUA_GLOBALSINDEX);
-
- L->push("BLIT_LIGHTEN");
- L->push((lua_Number) BLIT_LIGHTEN);
- L->settable(LUA_GLOBALSINDEX);
-
- L->push("BLIT_LIGHTEN32");
- L->push((lua_Number) BLIT_LIGHTEN32);
- L->settable(LUA_GLOBALSINDEX);
-
- L->push("BLIT_DARKEN");
- L->push((lua_Number) BLIT_DARKEN);
- L->settable(LUA_GLOBALSINDEX);
-
- L->push("BLIT_DARKEN32");
- L->push((lua_Number) BLIT_DARKEN32);
- L->settable(LUA_GLOBALSINDEX);
-}
-
-int sLua_psx::psx_proceed_statics(Lua * L, int n, int caller) {
- int r = 0;
-
- switch (caller) {
- case PSX_BSDECODE:
- r = 1;
- {
- Buffer * b = new Buffer(true);
- Handle * f = (Handle *) LuaObject::getme(L, 1);
- int width = L->tonumber(2);
- int height = L->tonumber(3);
- Byte * in = (Byte *) malloc(f->GetSize() + 10);
- Byte * out = (Byte *) malloc(width * height * 3);
- LuaBuffer lb(b);
- lb.pushdestruct(L);
- f->read(in, f->GetSize());
- bs_decode_rgb24(out, (bs_header_t *) in, width, height, 0);
- for (int i = 0; i < width * height * 3; i++) {
- b[i] = out[i];
- }
- free(out);
- free(in);
- }
- case PSX_BSENCODE:
- r = 3;
- {
- unsigned short out[0x80000];
- Buffer * b = new Buffer(true);
- LuaBuffer lb(b);
- lb.pushdestruct(L);
- Handle * f = (Handle *) LuaObject::getme(L, 1);
- bs_input_image_t img;
- img.width = L->tonumber(2);
- img.height = L->tonumber(3);
- int max_size = 14112, cur_size;
- int q_scale = 1;
- if (n >= 4)
- max_size = L->tonumber(4);
- if (n >= 5)
- q_scale = L->tonumber(5);
- img.lpbits = (Byte *) malloc(f->GetSize());
- img.top = img.lpbits;
- img.nextline = img.width * 3;
- img.bit = 24;
-
- f->read(img.lpbits, f->GetSize());
-
- bs_init();
-
- cur_size = max_size + 1;
-
- for (cur_size = max_size + 1; max_size < cur_size; q_scale++) {
- cur_size = bs_encode((bs_header_t *) out, &img, 2, q_scale, 0);
- }
-
- for (int i = 0; i < cur_size; i++) {
- b[i] = out[i];
- }
-
- L->push((lua_Number) cur_size);
- L->push((lua_Number) q_scale);
- }
- case PSX_BLIT:
- r = 0;
- {
- Handle * d = (Handle *) LuaObject::getme(L, 1);
- Handle * s = (Handle *) LuaObject::getme(L, 2);
- int dw = L->tonumber(3),
- dh = L->tonumber(4),
- sw = L->tonumber(5),
- sh = L->tonumber(6),
- sx = L->tonumber(7),
- sy = L->tonumber(8),
- bl = L->tonumber(9);
- int bytes, dstart = 0, dskip = 0, sstart = 0, sskip = 0, i, j;
- Byte RGB[3], R, G, B, A = 128;
- void (*op_func)(Byte *, Byte, Byte, Byte, Byte);
-
- switch(bl) {
- case BLIT_OVER:
- bytes = 3;
- op_func = over;
- break;
- case BLIT_OVER32:
- bytes = 4;
- op_func = over;
- break;
- case BLIT_ALPHA:
- bytes = 4;
- op_func = alpha;
- break;
- case BLIT_LIGHTEN:
- bytes = 3;
- op_func = lighten;
- break;
- case BLIT_LIGHTEN32:
- bytes = 4;
- op_func = lighten;
- break;
- case BLIT_DARKEN:
- bytes = 3;
- op_func = darken;
- break;
- case BLIT_DARKEN32:
- bytes = 4;
- op_func = darken;
- break;
- default:
- L->error("Blitting operation unknown.");
- return 0;
- }
-
-#if 0
- if ((sx + sw) < 0)
- return;
-
- if (sx >= dw)
- return;
-
- if ((sy + sh) < 0)
- return;
-
- if (sy >= dh)
- return;
-#endif
-
- if (sy < 0) {
- sstart -= sw * bytes * sy;
- sh += sy;
- sy = 0;
- } else {
- dstart += dw * 3 * sy;
- }
-
- if ((sy + sh) > dh) {
- sh -= (sy + sh) - dh;
- }
-
- if (sx < 0) {
- sstart -= sx * bytes;
- sskip -= sx * bytes;
- sw += sx;
- sx = 0;
- } else {
- dstart += sx * 3;
- }
-
- if ((sx + sw) > dw) {
- sskip += (sx + sw) - dw;
- sw -= (sx + sw) - dw;
- }
-
- dskip = (dw - sw) * 3;
-
- d->seek(dstart);
- s->seek(sstart);
-
- for (i = 0; i < sh; i++, s->seek(sskip, SEEK_CUR), d->seek(dskip, SEEK_CUR)) {
- for (j = 0; j < sw; j++) {
- RGB[0] = d->readU8();
- RGB[1] = d->readU8();
- RGB[2] = d->readU8();
- d->seek(-3, SEEK_CUR);
- R = s->readU8();
- G = s->readU8();
- B = s->readU8();
- if (bytes == 4)
- A = s->readU8();
- op_func(RGB, R, G, B, A);
- d->writeU8(R);
- d->writeU8(G);
- d->writeU8(B);
- }
- }
-
- }
- }
- return r;
-}
+/*
+ * 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: luapsx.cpp,v 1.7 2004-11-27 21:47:56 pixel Exp $ */
+
+#include <LuaHandle.h>
+#include "luapsx.h"
+#include "generic.h"
+
+void over(Byte * d, Byte R, Byte G, Byte B, Byte A) {
+ d[0] = R;
+ d[1] = G;
+ d[2] = B;
+}
+
+void alpha(Byte * d, Byte R, Byte G, Byte B, Byte A) {
+ A = MIN(A, (Byte) 128);
+ d[0] = ((int)d[0] * (128 - A) + R * A) >> 7;
+ d[1] = ((int)d[1] * (128 - A) + G * A) >> 7;
+ d[2] = ((int)d[2] * (128 - A) + B * A) >> 7;
+}
+
+void lighten(Byte * d, Byte R, Byte G, Byte B, Byte A) {
+ A = MIN(A, (Byte) 128);
+ R = ((int)d[0] * (128 - A) + R * A) >> 7;
+ G = ((int)d[1] * (128 - A) + G * A) >> 7;
+ B = ((int)d[2] * (128 - A) + B * A) >> 7;
+ d[0] = MAX(R, d[0]);
+ d[1] = MAX(G, d[1]);
+ d[2] = MAX(B, d[2]);
+}
+
+void darken(Byte * d, Byte R, Byte G, Byte B, Byte A) {
+ A = MIN(A, (Byte) 128);
+ R = ((int)d[0] * (128 - A) + R * A) >> 7;
+ G = ((int)d[1] * (128 - A) + G * A) >> 7;
+ B = ((int)d[2] * (128 - A) + B * A) >> 7;
+ d[0] = MIN(R, d[0]);
+ d[1] = MIN(G, d[1]);
+ d[2] = MIN(B, d[2]);
+}
+
+enum {
+ BLIT_OVER = 0,
+ BLIT_OVER32,
+ BLIT_ALPHA,
+ BLIT_LIGHTEN,
+ BLIT_LIGHTEN32,
+ BLIT_DARKEN,
+ BLIT_DARKEN32,
+};
+
+typedef void psx;
+
+enum psx_functions_t {
+ PSX_BSDECODE = 0,
+ PSX_BSENCODE,
+ PSX_BLIT,
+};
+
+struct lua_functypes_t psx_functions[] = {
+ { PSX_BSDECODE, "bsdecode", 3, 3, { LUA_OBJECT, LUA_NUMBER, LUA_NUMBER } },
+ { PSX_BSENCODE, "bsencode", 3, 5, { LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER } },
+ { PSX_BLIT, "blit", 9, 9, { LUA_OBJECT, LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER } },
+ { -1, 0, 0, 0, 0 }
+};
+
+class sLua_psx : public Base {
+ public:
+ DECLARE_FUNCTION(psx, PSX_BSDECODE);
+ DECLARE_FUNCTION(psx, PSX_BSENCODE);
+ DECLARE_FUNCTION(psx, PSX_BLIT);
+ private:
+ static int psx_proceed_statics(Lua * L, int n, int caller);
+};
+
+void Luapsx::pushstatics(Lua * L) throw (GeneralException ) {
+ CHECK_FUNCTIONS(psx);
+
+ PUSH_FUNCTION(psx, PSX_BSDECODE);
+ PUSH_FUNCTION(psx, PSX_BSENCODE);
+ PUSH_FUNCTION(psx, PSX_BLIT);
+
+ L->push("BLIT_OVER");
+ L->push((lua_Number) BLIT_OVER);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("BLIT_OVER32");
+ L->push((lua_Number) BLIT_OVER32);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("BLIT_ALPHA");
+ L->push((lua_Number) BLIT_ALPHA);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("BLIT_LIGHTEN");
+ L->push((lua_Number) BLIT_LIGHTEN);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("BLIT_LIGHTEN32");
+ L->push((lua_Number) BLIT_LIGHTEN32);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("BLIT_DARKEN");
+ L->push((lua_Number) BLIT_DARKEN);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("BLIT_DARKEN32");
+ L->push((lua_Number) BLIT_DARKEN32);
+ L->settable(LUA_GLOBALSINDEX);
+}
+
+int sLua_psx::psx_proceed_statics(Lua * L, int n, int caller) {
+ int r = 0;
+
+ switch (caller) {
+ case PSX_BSDECODE:
+ r = 1;
+ {
+ Buffer * b = new Buffer(true);
+ Handle * f = (Handle *) LuaObject::getme(L, 1);
+ int width = L->tonumber(2);
+ int height = L->tonumber(3);
+ Byte * in = (Byte *) malloc(f->GetSize() + 10);
+ Byte * out = (Byte *) malloc(width * height * 3);
+ LuaBuffer lb(b);
+ lb.pushdestruct(L);
+ f->read(in, f->GetSize());
+ bs_decode_rgb24(out, (bs_header_t *) in, width, height, 0);
+ for (int i = 0; i < width * height * 3; i++) {
+ b[i] = out[i];
+ }
+ free(out);
+ free(in);
+ }
+ case PSX_BSENCODE:
+ r = 3;
+ {
+ unsigned short out[0x80000];
+ Buffer * b = new Buffer(true);
+ LuaBuffer lb(b);
+ lb.pushdestruct(L);
+ Handle * f = (Handle *) LuaObject::getme(L, 1);
+ bs_input_image_t img;
+ img.width = L->tonumber(2);
+ img.height = L->tonumber(3);
+ int max_size = 14112, cur_size;
+ int q_scale = 1;
+ if (n >= 4)
+ max_size = L->tonumber(4);
+ if (n >= 5)
+ q_scale = L->tonumber(5);
+ img.lpbits = (Byte *) malloc(f->GetSize());
+ img.top = img.lpbits;
+ img.nextline = img.width * 3;
+ img.bit = 24;
+
+ f->read(img.lpbits, f->GetSize());
+
+ bs_init();
+
+ cur_size = max_size + 1;
+
+ for (cur_size = max_size + 1; max_size < cur_size; q_scale++) {
+ cur_size = bs_encode((bs_header_t *) out, &img, 2, q_scale, 0);
+ }
+
+ for (int i = 0; i < cur_size; i++) {
+ b[i] = out[i];
+ }
+
+ L->push((lua_Number) cur_size);
+ L->push((lua_Number) q_scale);
+ }
+ case PSX_BLIT:
+ r = 0;
+ {
+ Handle * d = (Handle *) LuaObject::getme(L, 1);
+ Handle * s = (Handle *) LuaObject::getme(L, 2);
+ int dw = L->tonumber(3),
+ dh = L->tonumber(4),
+ sw = L->tonumber(5),
+ sh = L->tonumber(6),
+ sx = L->tonumber(7),
+ sy = L->tonumber(8),
+ bl = L->tonumber(9);
+ int bytes, dstart = 0, dskip = 0, sstart = 0, sskip = 0, i, j;
+ Byte RGB[3], R, G, B, A = 128;
+ void (*op_func)(Byte *, Byte, Byte, Byte, Byte);
+
+ switch(bl) {
+ case BLIT_OVER:
+ bytes = 3;
+ op_func = over;
+ break;
+ case BLIT_OVER32:
+ bytes = 4;
+ op_func = over;
+ break;
+ case BLIT_ALPHA:
+ bytes = 4;
+ op_func = alpha;
+ break;
+ case BLIT_LIGHTEN:
+ bytes = 3;
+ op_func = lighten;
+ break;
+ case BLIT_LIGHTEN32:
+ bytes = 4;
+ op_func = lighten;
+ break;
+ case BLIT_DARKEN:
+ bytes = 3;
+ op_func = darken;
+ break;
+ case BLIT_DARKEN32:
+ bytes = 4;
+ op_func = darken;
+ break;
+ default:
+ L->error("Blitting operation unknown.");
+ return 0;
+ }
+
+#if 0
+ if ((sx + sw) < 0)
+ return;
+
+ if (sx >= dw)
+ return;
+
+ if ((sy + sh) < 0)
+ return;
+
+ if (sy >= dh)
+ return;
+#endif
+
+ if (sy < 0) {
+ sstart -= sw * bytes * sy;
+ sh += sy;
+ sy = 0;
+ } else {
+ dstart += dw * 3 * sy;
+ }
+
+ if ((sy + sh) > dh) {
+ sh -= (sy + sh) - dh;
+ }
+
+ if (sx < 0) {
+ sstart -= sx * bytes;
+ sskip -= sx * bytes;
+ sw += sx;
+ sx = 0;
+ } else {
+ dstart += sx * 3;
+ }
+
+ if ((sx + sw) > dw) {
+ sskip += (sx + sw) - dw;
+ sw -= (sx + sw) - dw;
+ }
+
+ dskip = (dw - sw) * 3;
+
+ d->seek(dstart);
+ s->seek(sstart);
+
+ for (i = 0; i < sh; i++, s->seek(sskip, SEEK_CUR), d->seek(dskip, SEEK_CUR)) {
+ for (j = 0; j < sw; j++) {
+ RGB[0] = d->readU8();
+ RGB[1] = d->readU8();
+ RGB[2] = d->readU8();
+ d->seek(-3, SEEK_CUR);
+ R = s->readU8();
+ G = s->readU8();
+ B = s->readU8();
+ if (bytes == 4)
+ A = s->readU8();
+ op_func(RGB, R, G, B, A);
+ d->writeU8(R);
+ d->writeU8(G);
+ d->writeU8(B);
+ }
+ }
+
+ }
+ }
+ return r;
+}
diff --git a/lib/lzss.cpp b/lib/lzss.cpp
index 7b134aa..1d7ecfb 100644
--- a/lib/lzss.cpp
+++ b/lib/lzss.cpp
@@ -1,464 +1,464 @@
-/*
- * PSX-Tools Bundle Pack
- * Copyright (C) 2002 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
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <iostream>
-#include "generic.h"
-#include "lzss.h"
-#include "Handle.h"
-
-lzss::lzss() : tolerate(1), blockb(0), scheme(schemes[0]), lzss_maxsize(18), lzss_maxptr(0x0fff) {
- compute_limits();
-}
-
-/*
-
-Valkyrie Profile V2:
-
-JJJJJJJJ LLLLJJJJ
-VVVVVVVV 1111RRRR
-RRRRRRRR 11110000 VVVVVVVV
-
-*/
-
-const lzss::scheme_t lzss::schemes[] = {
-/* Nom 1 I J O N 16 P F W Lm1 Ls1 Lm2 Ls2 Jm1 Js1 Jm2 Js2 Fm1 Fs1 Fm2 Fs2 Vm1 Vs1 Vm2 Vs2 Flags*/
-#if 0 /* Zelda GC */
- {"Yaz0", 0, 1, 1, 0, 0, 0, 0, 0, 0, 0xf0, -4, 0x00, 0, 0x0f, 8, 0xff, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
-#endif
- {"Xenogears", 1, 0, 0, 1, 0, 0, 0, 0, 0, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
- {"DBZ RPG", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0f, 0, 0x00, 0, 0xf0, -4, 0xff, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
- {"FF7", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x0f, 0, 0xff, 0, 0xf0, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
- {"Leen Mean", 1, 1, 1, 1, 0, 0, 0, 0, 0, 0x0f, 0, 0x00, 0, 0xf0, 4, 0xff, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
- {"Metal Max", 0, 0, 0, 1, 0, 0, 2, 0, 0x12, 0x00, 0, 0x0f, 0, 0xff, 0, 0xf0, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
- {"Ogre Battle", 0, 0, 0, 1, 0, 0, 1, 0, 0, 0xf8, -3, 0x00, 0, 0x07, 8, 0xff, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
- {"Lodoss Wars", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x7f, 0, 0xff, 0, 0x80, 1, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
- {"FF6 PSX", 0, 0, 0, 1, 1, 1, 0, 0, 0, 0x1f, 1, 0x00, 0, 0xe0, -4, 0xff, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
- {"Valkyrie-1", 0, 0, 0, 1, 1, 0, 0, 0, 0, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
- {"Valkyrie-2", 0, 0, 0, 1, 1, 0, 0, 2, 0, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x0f, 0, 0xff, 0, 0x00, 0},
- {"ToD", 0, 0, 0,-1, 1, 0, 1, 1, 3, 0x00, 0, 0x0f, 0, 0xff, 0, 0xf0, 4, 0x00, 0, 0xf0, -4, 0xff, 0, 0x00, 0},
- {0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}
-};
-
-Byte lzss::swap_bits(Byte i) {
- i = ((i >> 1) & 0x55) | ((i << 1) & 0xaa);
- i = ((i >> 2) & 0x33) | ((i << 2) & 0xcc);
- i = ((i >> 4) & 0x0f) | ((i << 4) & 0xf0);
- return i;
-}
-
-unsigned int lzss::shift(unsigned int c, int s) {
- return s > 0 ? (c << s) : c >> (-s);
-}
-
-void lzss::compute_limits(void) {
- unsigned char val1, val2;
-
- val1 = val2 = 0xff;
-
- lzss_maxsize = shift(val1 & scheme.l_mask_1, scheme.l_shft_1) |
- shift(val2 & scheme.l_mask_2, scheme.l_shft_2);
- lzss_maxptr = shift(val1 & scheme.j_mask_1, scheme.j_shft_1) |
- shift(val2 & scheme.j_mask_2, scheme.j_shft_2);
-
- lzss_maxsize = lzss_maxsize + 3 + scheme.sixteen_bits;
- lzss_maxptr += scheme.one_jump;
-
- if (scheme.l_mask_1 & scheme.j_mask_1) {
- printm(M_ERROR, "Masks are overlapping for value 1\n");
- exit(-1);
- }
-
- if (scheme.l_mask_2 & scheme.j_mask_2) {
- printm(M_ERROR, "Masks are overlapping for value 2\n");
- exit(-1);
- }
-
- if (shift(scheme.l_mask_1, scheme.l_shft_1) & shift(scheme.l_mask_2, scheme.l_shft_2)) {
- printm(M_ERROR, "Shifts build an overlap for lenght\n");
- exit(-1);
- }
-
- if (shift(scheme.j_mask_1, scheme.j_shft_1) & shift(scheme.j_mask_2, scheme.j_shft_2)) {
- printm(M_ERROR, "Shifts build an overlap for jump\n");
- exit(-1);
- }
-
- printm(M_INFO, "Computed values: maxsize = %i, maxptr = 0x%06x\n", lzss_maxsize, lzss_maxptr);
-}
-
-unsigned int lzss::lzss_decomp(Handle * f_source, Handle * f_cible, int true_length)
-{
- unsigned char bitmap, fbitmap;
- unsigned char valeur;
- unsigned char * text_buf;
- unsigned char val1, val2, val3;
- int negative_error = scheme.negative_trick, overlap_error = scheme.overlap_trick == 1;
- int r = 0;
- int decomp_count;
- int decomp_length;
- int decomp_fill;
- int decomp_jump;
- int decomp_offset = 0;
- int loop_length;
- int whole_count;
- int i, j;
- int length, reads;
-
- compute_limits();
-
- f_source->read(&length, 4);
- if (true_length >= 0) {
- length = true_length;
- }
- whole_count = 0;
-
- printm(M_INFO, "Decompressing %i bytes\n", length);
-
- text_buf = (unsigned char *) malloc(length + 8);
-
- do {
- f_source->read(&bitmap, 1);
- if (scheme.sixteen_bits) {
- f_source->read(&fbitmap, 1);
- printm(M_INFO, "16bits behavior, false bitmap = %02x\n", fbitmap);
- }
- printm(M_INFO, "Begin of block, bitmap = %02x\n", bitmap);
- if (scheme.bitmap_inversed) {
- bitmap = swap_bits(bitmap);
- }
- for (i = 0; i < 8; i++) {
- printm(M_INFO, " - Chunk %i (offset cible = %li = 0x%04x, offset source = %li = 0x%04x)\n", i, f_cible->tell(), f_cible->tell(), f_source->tell(), f_source->tell());
- if (whole_count >= length)
- break;
- if ((bitmap & 1) ^ scheme.one_is_compressed) {
- for (j = 0; j < (scheme.sixteen_bits ? 2 : 1); j++) {
- reads = f_source->read(&valeur, 1);
- if (!reads) {
- printm(M_WARNING, " WARNING! PADDING!\n");
- free(text_buf);
- return length;
- }
- printm(M_INFO, " Copying 0x%02x\n", valeur);
- f_cible->write(&valeur, 1);
- text_buf[r++] = valeur;
- whole_count++;
- }
- } else {
- f_source->read(&val1, 1);
- f_source->read(&val2, 1);
- decomp_length = shift(val1 & scheme.l_mask_1, scheme.l_shft_1) |
- shift(val2 & scheme.l_mask_2, scheme.l_shft_2);
- decomp_fill = shift(val1 & scheme.f_mask_1, scheme.f_shft_1) |
- shift(val2 & scheme.f_mask_2, scheme.f_shft_2);
- decomp_jump = shift(val1 & scheme.j_mask_1, scheme.j_shft_1) |
- shift(val2 & scheme.j_mask_2, scheme.j_shft_2);
- valeur = shift(val1 & scheme.v_mask_1, scheme.v_shft_1) |
- shift(val2 & scheme.v_mask_2, scheme.v_shft_2);
-// decomp_jump &= lzss_maxptr; bad, ugly, non working
- decomp_jump += scheme.one_jump;
- decomp_length = decomp_length + 3 + scheme.sixteen_bits;
- decomp_fill = decomp_fill + 3 + scheme.sixteen_bits;
-#if 0 /* Zelda GC */
- decomp_length--;
- if (decomp_length == 2) {
- printm(M_INFO, "Big jump\n");
- decomp_length = f_source->readU8() + 18;
- }
-#endif
- if ((decomp_length == lzss_maxsize) && (scheme.filling)) {
- if ((decomp_fill == 3) && (scheme.filling == 2)) {
- f_source->read(&val3, 1);
- printm(M_INFO, " Found an extended needle (val1 = 0x%02x, val2 = 0x%02x, val3 = 0x%02x)\n", val1, val2, val3);
- decomp_fill = val1 + 19;
- valeur = val3;
- } else {
- printm(M_INFO, " Found a 0x%02x-filling needle of %li bytes (val1 = 0x%02x, val2 = 0x%02x)\n", valeur, decomp_fill, val1, val2);
- }
- for (decomp_count = 0; decomp_count < decomp_fill; decomp_count++) {
- f_cible->write(&valeur, 1);
- text_buf[r++] = valeur;
- if (!blockb)
- whole_count++;
- }
- if (blockb)
- whole_count++;
- } else {
- switch (scheme.ptrb) {
- case 0:
- decomp_offset = r - decomp_jump;
- break;
- case 1:
- decomp_offset = r - lzss_maxptr - 1 + decomp_jump - scheme.window_start;
- break;
- case 2:
- decomp_offset = decomp_jump - scheme.window_start;
- break;
- }
- decomp_offset += scheme.overlap_trick == -1 ? decomp_length : 0;
- loop_length = decomp_offset + decomp_length;
- if ((loop_length >= r) && (!overlap_error)) {
- if (!tolerate) {
- free(text_buf);
- return 0;
- }
- printm(M_ERROR, "Overlap trick used without it beeing enabled in the scheme.\n");
- overlap_error = 1;
- }
- printm(M_INFO, " Found a needle of %li bytes at %li = 0x%04x, jump of %li = 0x%04x (val1 = 0x%02x, val2 = 0x%02x)\n", decomp_length, decomp_offset, decomp_offset, decomp_jump, decomp_jump, val1, val2);
- for (decomp_count = decomp_offset; decomp_count < loop_length; decomp_count++) {
- if (!blockb)
- whole_count++;
- if (decomp_count < 0) {
- valeur = 0;
- f_cible->write(&valeur, 1);
- text_buf[r++] = 0;
- if (!negative_error) {
- if (!tolerate) {
- free(text_buf);
- return 0;
- }
- printm(M_ERROR, "Negative trick used without it beeing enabled in the scheme.\n");
- negative_error = 1;
- }
- printm(M_INFO, "Filling with 0\n");
- } else {
- f_cible->write(&text_buf[decomp_count], 1);
- printm(M_INFO, "@0x%04x: 0x%02x\n", decomp_count, text_buf[decomp_count]);
- text_buf[r++] = text_buf[decomp_count];
- }
- if (whole_count >= length)
- break;
- }
- if (blockb)
- whole_count++;
- }
- }
- bitmap >>= 1;
- }
- } while (whole_count < length);
- free(text_buf);
-
- return length;
-}
-
-unsigned char lzss::lzss_rd(unsigned char * t, int p) {
- return ((p < 0) ? 0 : (t[p]));
-}
-
-int lzss::lzss_comp_strstr(unsigned char * needle, unsigned char * r, int * l, int sp) {
- char redo[256];
- int length, i, p, ptr, maxlength;
-
- i = 1;
- redo[0] = p = 0;
- while (i < lzss_maxsize) {
- if (needle[i] == needle[p]) {
- redo[i++] = ++p;
- } else if (p > 0) {
- p = redo[p - 1];
- } else {
- redo[i++] = 0;
- }
- }
-
- length = maxlength = 0;
- i = sp;
- p = 0;
- ptr = 0;
-
- while ((i - sp - (scheme.overlap_trick ? p : 0)) < *l) {
- if (needle[p] == lzss_rd(r, i)) {
- if (p == (lzss_maxsize - 1)) {
- *l = lzss_maxsize;
- return i - lzss_maxsize + 1;
- }
- i++;
- p++;
- } else if (p > 0) {
- if (p > maxlength) {
- if (!((i - p) & scheme.sixteen_bits)) {
- ptr = i - (maxlength = p);
- }
- }
- p = redo[p - 1];
- } else {
- i++;
- }
- }
-
- *l = maxlength;
- return ptr;
-}
-
-unsigned char * lzss::lzss_memcomp(unsigned char * r, int * l, int * delta) {
- unsigned char bitmap, * comp;
- int ptr, needle, needle_length, comp_ptr, bitmap_ptr, val1, val2;
- int jump, farest, remaining;
- int j;
-
- comp = (unsigned char *) malloc(3 * *l);
-
- compute_limits();
-
- ptr = 0;
- blk = 0;
- bitmap_count = 0;
- comp_ptr = 1 + scheme.sixteen_bits;
- bitmap = 0;
- bitmap_ptr = 0;
- printm(M_INFO, "Begin of block 0.\n");
- while ((remaining = *l - ptr) > 0) {
- printm(M_INFO, " Remaining bytes: %li\n", remaining);
- lzss_maxsize = MIN(lzss_maxsize, remaining);
- bitmap_count++;
- bitmap >>= 1;
- farest = ptr - lzss_maxptr;
- farest = farest > ((-lzss_maxsize) * scheme.negative_trick) ? farest : -lzss_maxsize * scheme.negative_trick;
- needle_length = ptr - farest;
- if (scheme.ptrb == 2) {
- farest = 0;
- needle_length = MIN(lzss_maxptr - scheme.window_start, ptr);
- }
- needle = lzss_comp_strstr(&r[ptr], r, &needle_length, farest);
- if ((needle < 0) && ((-needle) > needle_length)) {
- needle = -needle_length;
- }
- printm(M_INFO, " - Chunk %i (offset source = %li = 0x%04x, offset cible = %li = 0x%04x)\n", bitmap_count - 1, ptr, ptr, comp_ptr, comp_ptr);
- jump = ptr - needle;
- needle_length = needle_length > remaining ? remaining : needle_length;
-
- if (needle_length & scheme.sixteen_bits) {
- needle_length--;
- }
-
- if ((needle < 0) || (!jump)) {
- printm(M_INFO, " Nothing found.\n");
- } else {
- printm(M_INFO, " Found a needle of %i bytes at offset %i (jump = %i = 0x%04x)\n", needle_length, needle, jump, jump);
- }
-
- if ((needle_length <= (2 + scheme.sixteen_bits)) || (!jump)) {
- if (needle_length > 2) {
- printm(M_ERROR, " ** REJECTED **\n");
- }
- for (j = 0; j < (scheme.sixteen_bits ? 2 : 1); j++) {
- printm(M_INFO, " Repeating 0x%02x\n", r[ptr]);
- comp[comp_ptr] = r[ptr];
- ptr++;
- comp_ptr++;
- }
- bitmap |= 0x80;
- } else {
- int j;
- printm(M_INFO, " Found a needle of %li bytes at %li = 0x%04x\n", needle_length, needle, needle);
- for (j = 0; j < needle_length; j++) {
- printm(M_INFO, "@0x%04x: 0x%02x - @0x%04x: 0x%02x\n", needle + j, lzss_rd(r, needle + j - scheme.window_start), ptr + j, lzss_rd(r, ptr + j));
- if (lzss_rd(r, needle + j) != lzss_rd(r, ptr + j)) {
- printm(M_ERROR, "ERROR!!\n");
- }
- }
- jump -= scheme.one_jump;
- printm(M_INFO, "ptr = %li, needle = %li, jump = %li = 0x%03x\n", ptr, needle, jump, jump);
- ptr += needle_length;
- needle_length -= 3;
- switch (scheme.ptrb) {
- case 0:
- break;
- case 1:
- jump = lzss_maxptr + 1 - jump;
- break;
- case 2:
- jump = needle + scheme.window_start;
- break;
- }
- val1 = comp[comp_ptr++] = (shift(jump, -scheme.j_shft_1) & scheme.j_mask_1) |
- (shift(needle_length, -scheme.l_shft_1) & scheme.l_mask_1);
- val2 = comp[comp_ptr++] = (shift(jump, -scheme.j_shft_2) & scheme.j_mask_2) |
- (shift(needle_length, -scheme.l_shft_2) & scheme.l_mask_2);
- printm(M_INFO, " writing info1 = 0x%02x, info2 = 0x%02x\n", val1, val2);
- }
-
- bitmap ^= scheme.one_is_compressed << 7;
-
- if (bitmap_count == 8) {
- blk++;
- printm(M_INFO, "End of block, writing bitmap = 0x%02x\n", bitmap);
- printm(M_INFO, "Begin of block %li.\n", blk);
- bitmap_count = 0;
- if (scheme.bitmap_inversed)
- bitmap = swap_bits(bitmap);
- comp[bitmap_ptr] = bitmap;
- if (scheme.sixteen_bits) {
- comp[bitmap_ptr + 1] = 0;
- }
- bitmap_ptr = comp_ptr;
- comp_ptr += (scheme.sixteen_bits ? 2 : 1);
- }
- }
-
- if (bitmap_count) {
- bitmap >>= (8 - bitmap_count);
- if (scheme.bitmap_inversed)
- bitmap = swap_bits(bitmap);
- comp[bitmap_ptr] = bitmap;
- if (scheme.sixteen_bits) {
- comp[bitmap_ptr + 1] = 0;
- }
- } else {
- comp_ptr--;
- }
-
- if (delta) {
- *delta = (bitmap_count ? 8 - bitmap_count : 0);
- }
-
- *l = comp_ptr;
- return comp;
-}
-
-void lzss::lzss_comp(Handle * f_source, Handle * f_cible, int * delta) {
- int length = f_source->GetSize(), l;
- unsigned char * r = (unsigned char *) malloc(length), * c;
-
- f_source->read(r, length);
- l = length;
- c = lzss_memcomp(r, &l, delta);
- if (delta) {
- length += *delta;
- }
- f_cible->write(&length, 4);
- if (delta) {
- length -= *delta;
- }
- f_cible->write(c, l);
- free(c);
- free(r);
-}
-
-void lzss::change_scheme(scheme_t new_scheme) {
- scheme = new_scheme;
- compute_limits();
-}
-
-lzss::scheme_t lzss::get_scheme() {
- return scheme;
-}
+/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 2002 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
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <iostream>
+#include "generic.h"
+#include "lzss.h"
+#include "Handle.h"
+
+lzss::lzss() : tolerate(1), blockb(0), scheme(schemes[0]), lzss_maxsize(18), lzss_maxptr(0x0fff) {
+ compute_limits();
+}
+
+/*
+
+Valkyrie Profile V2:
+
+JJJJJJJJ LLLLJJJJ
+VVVVVVVV 1111RRRR
+RRRRRRRR 11110000 VVVVVVVV
+
+*/
+
+const lzss::scheme_t lzss::schemes[] = {
+/* Nom 1 I J O N 16 P F W Lm1 Ls1 Lm2 Ls2 Jm1 Js1 Jm2 Js2 Fm1 Fs1 Fm2 Fs2 Vm1 Vs1 Vm2 Vs2 Flags*/
+#if 0 /* Zelda GC */
+ {"Yaz0", 0, 1, 1, 0, 0, 0, 0, 0, 0, 0xf0, -4, 0x00, 0, 0x0f, 8, 0xff, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+#endif
+ {"Xenogears", 1, 0, 0, 1, 0, 0, 0, 0, 0, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"DBZ RPG", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0f, 0, 0x00, 0, 0xf0, -4, 0xff, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"FF7", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x0f, 0, 0xff, 0, 0xf0, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"Leen Mean", 1, 1, 1, 1, 0, 0, 0, 0, 0, 0x0f, 0, 0x00, 0, 0xf0, 4, 0xff, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"Metal Max", 0, 0, 0, 1, 0, 0, 2, 0, 0x12, 0x00, 0, 0x0f, 0, 0xff, 0, 0xf0, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"Ogre Battle", 0, 0, 0, 1, 0, 0, 1, 0, 0, 0xf8, -3, 0x00, 0, 0x07, 8, 0xff, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"Lodoss Wars", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x7f, 0, 0xff, 0, 0x80, 1, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"FF6 PSX", 0, 0, 0, 1, 1, 1, 0, 0, 0, 0x1f, 1, 0x00, 0, 0xe0, -4, 0xff, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"Valkyrie-1", 0, 0, 0, 1, 1, 0, 0, 0, 0, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"Valkyrie-2", 0, 0, 0, 1, 1, 0, 0, 2, 0, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x0f, 0, 0xff, 0, 0x00, 0},
+ {"ToD", 0, 0, 0,-1, 1, 0, 1, 1, 3, 0x00, 0, 0x0f, 0, 0xff, 0, 0xf0, 4, 0x00, 0, 0xf0, -4, 0xff, 0, 0x00, 0},
+ {0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}
+};
+
+Byte lzss::swap_bits(Byte i) {
+ i = ((i >> 1) & 0x55) | ((i << 1) & 0xaa);
+ i = ((i >> 2) & 0x33) | ((i << 2) & 0xcc);
+ i = ((i >> 4) & 0x0f) | ((i << 4) & 0xf0);
+ return i;
+}
+
+unsigned int lzss::shift(unsigned int c, int s) {
+ return s > 0 ? (c << s) : c >> (-s);
+}
+
+void lzss::compute_limits(void) {
+ unsigned char val1, val2;
+
+ val1 = val2 = 0xff;
+
+ lzss_maxsize = shift(val1 & scheme.l_mask_1, scheme.l_shft_1) |
+ shift(val2 & scheme.l_mask_2, scheme.l_shft_2);
+ lzss_maxptr = shift(val1 & scheme.j_mask_1, scheme.j_shft_1) |
+ shift(val2 & scheme.j_mask_2, scheme.j_shft_2);
+
+ lzss_maxsize = lzss_maxsize + 3 + scheme.sixteen_bits;
+ lzss_maxptr += scheme.one_jump;
+
+ if (scheme.l_mask_1 & scheme.j_mask_1) {
+ printm(M_ERROR, "Masks are overlapping for value 1\n");
+ exit(-1);
+ }
+
+ if (scheme.l_mask_2 & scheme.j_mask_2) {
+ printm(M_ERROR, "Masks are overlapping for value 2\n");
+ exit(-1);
+ }
+
+ if (shift(scheme.l_mask_1, scheme.l_shft_1) & shift(scheme.l_mask_2, scheme.l_shft_2)) {
+ printm(M_ERROR, "Shifts build an overlap for lenght\n");
+ exit(-1);
+ }
+
+ if (shift(scheme.j_mask_1, scheme.j_shft_1) & shift(scheme.j_mask_2, scheme.j_shft_2)) {
+ printm(M_ERROR, "Shifts build an overlap for jump\n");
+ exit(-1);
+ }
+
+ printm(M_INFO, "Computed values: maxsize = %i, maxptr = 0x%06x\n", lzss_maxsize, lzss_maxptr);
+}
+
+unsigned int lzss::lzss_decomp(Handle * f_source, Handle * f_cible, int true_length)
+{
+ unsigned char bitmap, fbitmap;
+ unsigned char valeur;
+ unsigned char * text_buf;
+ unsigned char val1, val2, val3;
+ int negative_error = scheme.negative_trick, overlap_error = scheme.overlap_trick == 1;
+ int r = 0;
+ int decomp_count;
+ int decomp_length;
+ int decomp_fill;
+ int decomp_jump;
+ int decomp_offset = 0;
+ int loop_length;
+ int whole_count;
+ int i, j;
+ int length, reads;
+
+ compute_limits();
+
+ f_source->read(&length, 4);
+ if (true_length >= 0) {
+ length = true_length;
+ }
+ whole_count = 0;
+
+ printm(M_INFO, "Decompressing %i bytes\n", length);
+
+ text_buf = (unsigned char *) malloc(length + 8);
+
+ do {
+ f_source->read(&bitmap, 1);
+ if (scheme.sixteen_bits) {
+ f_source->read(&fbitmap, 1);
+ printm(M_INFO, "16bits behavior, false bitmap = %02x\n", fbitmap);
+ }
+ printm(M_INFO, "Begin of block, bitmap = %02x\n", bitmap);
+ if (scheme.bitmap_inversed) {
+ bitmap = swap_bits(bitmap);
+ }
+ for (i = 0; i < 8; i++) {
+ printm(M_INFO, " - Chunk %i (offset cible = %li = 0x%04x, offset source = %li = 0x%04x)\n", i, f_cible->tell(), f_cible->tell(), f_source->tell(), f_source->tell());
+ if (whole_count >= length)
+ break;
+ if ((bitmap & 1) ^ scheme.one_is_compressed) {
+ for (j = 0; j < (scheme.sixteen_bits ? 2 : 1); j++) {
+ reads = f_source->read(&valeur, 1);
+ if (!reads) {
+ printm(M_WARNING, " WARNING! PADDING!\n");
+ free(text_buf);
+ return length;
+ }
+ printm(M_INFO, " Copying 0x%02x\n", valeur);
+ f_cible->write(&valeur, 1);
+ text_buf[r++] = valeur;
+ whole_count++;
+ }
+ } else {
+ f_source->read(&val1, 1);
+ f_source->read(&val2, 1);
+ decomp_length = shift(val1 & scheme.l_mask_1, scheme.l_shft_1) |
+ shift(val2 & scheme.l_mask_2, scheme.l_shft_2);
+ decomp_fill = shift(val1 & scheme.f_mask_1, scheme.f_shft_1) |
+ shift(val2 & scheme.f_mask_2, scheme.f_shft_2);
+ decomp_jump = shift(val1 & scheme.j_mask_1, scheme.j_shft_1) |
+ shift(val2 & scheme.j_mask_2, scheme.j_shft_2);
+ valeur = shift(val1 & scheme.v_mask_1, scheme.v_shft_1) |
+ shift(val2 & scheme.v_mask_2, scheme.v_shft_2);
+// decomp_jump &= lzss_maxptr; bad, ugly, non working
+ decomp_jump += scheme.one_jump;
+ decomp_length = decomp_length + 3 + scheme.sixteen_bits;
+ decomp_fill = decomp_fill + 3 + scheme.sixteen_bits;
+#if 0 /* Zelda GC */
+ decomp_length--;
+ if (decomp_length == 2) {
+ printm(M_INFO, "Big jump\n");
+ decomp_length = f_source->readU8() + 18;
+ }
+#endif
+ if ((decomp_length == lzss_maxsize) && (scheme.filling)) {
+ if ((decomp_fill == 3) && (scheme.filling == 2)) {
+ f_source->read(&val3, 1);
+ printm(M_INFO, " Found an extended needle (val1 = 0x%02x, val2 = 0x%02x, val3 = 0x%02x)\n", val1, val2, val3);
+ decomp_fill = val1 + 19;
+ valeur = val3;
+ } else {
+ printm(M_INFO, " Found a 0x%02x-filling needle of %li bytes (val1 = 0x%02x, val2 = 0x%02x)\n", valeur, decomp_fill, val1, val2);
+ }
+ for (decomp_count = 0; decomp_count < decomp_fill; decomp_count++) {
+ f_cible->write(&valeur, 1);
+ text_buf[r++] = valeur;
+ if (!blockb)
+ whole_count++;
+ }
+ if (blockb)
+ whole_count++;
+ } else {
+ switch (scheme.ptrb) {
+ case 0:
+ decomp_offset = r - decomp_jump;
+ break;
+ case 1:
+ decomp_offset = r - lzss_maxptr - 1 + decomp_jump - scheme.window_start;
+ break;
+ case 2:
+ decomp_offset = decomp_jump - scheme.window_start;
+ break;
+ }
+ decomp_offset += scheme.overlap_trick == -1 ? decomp_length : 0;
+ loop_length = decomp_offset + decomp_length;
+ if ((loop_length >= r) && (!overlap_error)) {
+ if (!tolerate) {
+ free(text_buf);
+ return 0;
+ }
+ printm(M_ERROR, "Overlap trick used without it beeing enabled in the scheme.\n");
+ overlap_error = 1;
+ }
+ printm(M_INFO, " Found a needle of %li bytes at %li = 0x%04x, jump of %li = 0x%04x (val1 = 0x%02x, val2 = 0x%02x)\n", decomp_length, decomp_offset, decomp_offset, decomp_jump, decomp_jump, val1, val2);
+ for (decomp_count = decomp_offset; decomp_count < loop_length; decomp_count++) {
+ if (!blockb)
+ whole_count++;
+ if (decomp_count < 0) {
+ valeur = 0;
+ f_cible->write(&valeur, 1);
+ text_buf[r++] = 0;
+ if (!negative_error) {
+ if (!tolerate) {
+ free(text_buf);
+ return 0;
+ }
+ printm(M_ERROR, "Negative trick used without it beeing enabled in the scheme.\n");
+ negative_error = 1;
+ }
+ printm(M_INFO, "Filling with 0\n");
+ } else {
+ f_cible->write(&text_buf[decomp_count], 1);
+ printm(M_INFO, "@0x%04x: 0x%02x\n", decomp_count, text_buf[decomp_count]);
+ text_buf[r++] = text_buf[decomp_count];
+ }
+ if (whole_count >= length)
+ break;
+ }
+ if (blockb)
+ whole_count++;
+ }
+ }
+ bitmap >>= 1;
+ }
+ } while (whole_count < length);
+ free(text_buf);
+
+ return length;
+}
+
+unsigned char lzss::lzss_rd(unsigned char * t, int p) {
+ return ((p < 0) ? 0 : (t[p]));
+}
+
+int lzss::lzss_comp_strstr(unsigned char * needle, unsigned char * r, int * l, int sp) {
+ char redo[256];
+ int length, i, p, ptr, maxlength;
+
+ i = 1;
+ redo[0] = p = 0;
+ while (i < lzss_maxsize) {
+ if (needle[i] == needle[p]) {
+ redo[i++] = ++p;
+ } else if (p > 0) {
+ p = redo[p - 1];
+ } else {
+ redo[i++] = 0;
+ }
+ }
+
+ length = maxlength = 0;
+ i = sp;
+ p = 0;
+ ptr = 0;
+
+ while ((i - sp - (scheme.overlap_trick ? p : 0)) < *l) {
+ if (needle[p] == lzss_rd(r, i)) {
+ if (p == (lzss_maxsize - 1)) {
+ *l = lzss_maxsize;
+ return i - lzss_maxsize + 1;
+ }
+ i++;
+ p++;
+ } else if (p > 0) {
+ if (p > maxlength) {
+ if (!((i - p) & scheme.sixteen_bits)) {
+ ptr = i - (maxlength = p);
+ }
+ }
+ p = redo[p - 1];
+ } else {
+ i++;
+ }
+ }
+
+ *l = maxlength;
+ return ptr;
+}
+
+unsigned char * lzss::lzss_memcomp(unsigned char * r, int * l, int * delta) {
+ unsigned char bitmap, * comp;
+ int ptr, needle, needle_length, comp_ptr, bitmap_ptr, val1, val2;
+ int jump, farest, remaining;
+ int j;
+
+ comp = (unsigned char *) malloc(3 * *l);
+
+ compute_limits();
+
+ ptr = 0;
+ blk = 0;
+ bitmap_count = 0;
+ comp_ptr = 1 + scheme.sixteen_bits;
+ bitmap = 0;
+ bitmap_ptr = 0;
+ printm(M_INFO, "Begin of block 0.\n");
+ while ((remaining = *l - ptr) > 0) {
+ printm(M_INFO, " Remaining bytes: %li\n", remaining);
+ lzss_maxsize = MIN(lzss_maxsize, remaining);
+ bitmap_count++;
+ bitmap >>= 1;
+ farest = ptr - lzss_maxptr;
+ farest = farest > ((-lzss_maxsize) * scheme.negative_trick) ? farest : -lzss_maxsize * scheme.negative_trick;
+ needle_length = ptr - farest;
+ if (scheme.ptrb == 2) {
+ farest = 0;
+ needle_length = MIN(lzss_maxptr - scheme.window_start, ptr);
+ }
+ needle = lzss_comp_strstr(&r[ptr], r, &needle_length, farest);
+ if ((needle < 0) && ((-needle) > needle_length)) {
+ needle = -needle_length;
+ }
+ printm(M_INFO, " - Chunk %i (offset source = %li = 0x%04x, offset cible = %li = 0x%04x)\n", bitmap_count - 1, ptr, ptr, comp_ptr, comp_ptr);
+ jump = ptr - needle;
+ needle_length = needle_length > remaining ? remaining : needle_length;
+
+ if (needle_length & scheme.sixteen_bits) {
+ needle_length--;
+ }
+
+ if ((needle < 0) || (!jump)) {
+ printm(M_INFO, " Nothing found.\n");
+ } else {
+ printm(M_INFO, " Found a needle of %i bytes at offset %i (jump = %i = 0x%04x)\n", needle_length, needle, jump, jump);
+ }
+
+ if ((needle_length <= (2 + scheme.sixteen_bits)) || (!jump)) {
+ if (needle_length > 2) {
+ printm(M_ERROR, " ** REJECTED **\n");
+ }
+ for (j = 0; j < (scheme.sixteen_bits ? 2 : 1); j++) {
+ printm(M_INFO, " Repeating 0x%02x\n", r[ptr]);
+ comp[comp_ptr] = r[ptr];
+ ptr++;
+ comp_ptr++;
+ }
+ bitmap |= 0x80;
+ } else {
+ int j;
+ printm(M_INFO, " Found a needle of %li bytes at %li = 0x%04x\n", needle_length, needle, needle);
+ for (j = 0; j < needle_length; j++) {
+ printm(M_INFO, "@0x%04x: 0x%02x - @0x%04x: 0x%02x\n", needle + j, lzss_rd(r, needle + j - scheme.window_start), ptr + j, lzss_rd(r, ptr + j));
+ if (lzss_rd(r, needle + j) != lzss_rd(r, ptr + j)) {
+ printm(M_ERROR, "ERROR!!\n");
+ }
+ }
+ jump -= scheme.one_jump;
+ printm(M_INFO, "ptr = %li, needle = %li, jump = %li = 0x%03x\n", ptr, needle, jump, jump);
+ ptr += needle_length;
+ needle_length -= 3;
+ switch (scheme.ptrb) {
+ case 0:
+ break;
+ case 1:
+ jump = lzss_maxptr + 1 - jump;
+ break;
+ case 2:
+ jump = needle + scheme.window_start;
+ break;
+ }
+ val1 = comp[comp_ptr++] = (shift(jump, -scheme.j_shft_1) & scheme.j_mask_1) |
+ (shift(needle_length, -scheme.l_shft_1) & scheme.l_mask_1);
+ val2 = comp[comp_ptr++] = (shift(jump, -scheme.j_shft_2) & scheme.j_mask_2) |
+ (shift(needle_length, -scheme.l_shft_2) & scheme.l_mask_2);
+ printm(M_INFO, " writing info1 = 0x%02x, info2 = 0x%02x\n", val1, val2);
+ }
+
+ bitmap ^= scheme.one_is_compressed << 7;
+
+ if (bitmap_count == 8) {
+ blk++;
+ printm(M_INFO, "End of block, writing bitmap = 0x%02x\n", bitmap);
+ printm(M_INFO, "Begin of block %li.\n", blk);
+ bitmap_count = 0;
+ if (scheme.bitmap_inversed)
+ bitmap = swap_bits(bitmap);
+ comp[bitmap_ptr] = bitmap;
+ if (scheme.sixteen_bits) {
+ comp[bitmap_ptr + 1] = 0;
+ }
+ bitmap_ptr = comp_ptr;
+ comp_ptr += (scheme.sixteen_bits ? 2 : 1);
+ }
+ }
+
+ if (bitmap_count) {
+ bitmap >>= (8 - bitmap_count);
+ if (scheme.bitmap_inversed)
+ bitmap = swap_bits(bitmap);
+ comp[bitmap_ptr] = bitmap;
+ if (scheme.sixteen_bits) {
+ comp[bitmap_ptr + 1] = 0;
+ }
+ } else {
+ comp_ptr--;
+ }
+
+ if (delta) {
+ *delta = (bitmap_count ? 8 - bitmap_count : 0);
+ }
+
+ *l = comp_ptr;
+ return comp;
+}
+
+void lzss::lzss_comp(Handle * f_source, Handle * f_cible, int * delta) {
+ int length = f_source->GetSize(), l;
+ unsigned char * r = (unsigned char *) malloc(length), * c;
+
+ f_source->read(r, length);
+ l = length;
+ c = lzss_memcomp(r, &l, delta);
+ if (delta) {
+ length += *delta;
+ }
+ f_cible->write(&length, 4);
+ if (delta) {
+ length -= *delta;
+ }
+ f_cible->write(c, l);
+ free(c);
+ free(r);
+}
+
+void lzss::change_scheme(scheme_t new_scheme) {
+ scheme = new_scheme;
+ compute_limits();
+}
+
+lzss::scheme_t lzss::get_scheme() {
+ return scheme;
+}
diff --git a/lib/mips.cpp b/lib/mips.cpp
index 05a1201..3a9a8f9 100644
--- a/lib/mips.cpp
+++ b/lib/mips.cpp
@@ -1,1068 +1,1068 @@
-/*
- * 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: mips.cpp,v 1.4 2004-11-27 21:44:48 pixel Exp $ */
-
-#include "mips.h"
-
-/* Code HIGHLY ripped off^W^W inspired from PCSX. */
-
-#if 1
-char * registers[] = {
- "0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
- "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
- "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
- "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra",
-};
-#else
-char * registers[] = {
- "00", "01", "02", "03", "04", "05", "06", "07",
- "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
- "10", "11", "12", "13", "14", "15", "16", "17",
- "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
-};
-#endif
-
-char * CP0registers[] = {
- "Index" , "Random" , "EntryLo0", "EntryLo1", "Context" , "PageMask" , "Wired" , "*Check me*",
- "BadVAddr" , "Count" , "EntryHi" , "Compare" , "Status" , "Cause" , "ExceptPC" , "PRevID" ,
- "Config" , "LLAddr" , "WatchLo" , "WatchHi" , "XContext", "*RES*" , "*RES*" , "*RES*" ,
- "*RES*" , "*RES* " , "PErr" , "CacheErr", "TagLo" , "TagHi" , "ErrorEPC" , "*RES*" };
-
-typedef void (*TdisR3000AF)(TDis *, Uint32 code, Uint32 pc);
-
-// These macros are used to assemble the disassembler functions
-#define MakeDisF(fn, b) \
- static void fn(TDis * d, Uint32 code, Uint32 pc) { \
- d->pc = pc; \
- b; \
- }
-
-#define _Funct_ ((code ) & 0x3F) // The funct part of the instruction register
-#define _Rd_ ((code >> 11) & 0x1F) // The rd part of the instruction register
-#define _Rt_ ((code >> 16) & 0x1F) // The rt part of the instruction register
-#define _Rs_ ((code >> 21) & 0x1F) // The rs part of the instruction register
-#define _Sa_ ((code >> 6) & 0x1F) // The sa part of the instruction register
-#define _Im_ ( code & 0xFFFF) // The immediate part of the instruction register
- // The signed immediate part of the instruction register
-#define _sIm_ (code & 0x8000 ? - (((~code) & 0x7FFF) + 1) : ( code & 0x7FFF))
-
-#define _Target_ (0x80000000 + ((code & 0x03ffffff) * 4))
-#define _Branch_ (pc + 4 + ((short)_Im_ * 4))
-#define _OfB_ _Im_, _nRs_
-
-#define dName(n) { d->Name(n); }
-#define dGPR(i) { d->PushGPReg(i); }
-#define dCP0(i) { d->PushCPReg(i); }
-#define dImm() { d->PushImm(_Im_); }
-#define dTarget() { d->PushTarget(_Target_); }
-#define dSa() { d->PushSa(_Sa_); }
-#if 0
-#define dOfB() { \
- Uint32 pcode = d->getmem()->Read32(pc - 4); \
- if ((((pcode >> 16) & 0x1F) == _Rs_) && ((pcode >> 26) == 0xf)) { \
- Uint32 full; \
- Uint16 lower; \
- int16 slower; \
- lower = _Im_; \
- slower = *((int16 *) &lower); \
- \
- full = ((pcode & 0xffff) << 16) + slower; \
- \
- d->PushOfB(_Rs_, full, width); \
- \
- dMemRefer(full, width); \
- } else { \
- d->PushOfB(_Rs_, _Im_, width); \
- } \
-}
-#else
-#define dOfB() { \
- d->PushOfB(_Rs_, _Im_, width); \
-}
-#endif
-#define dOffset() { \
- d->PushOffset(_Branch_); \
-}
-// printf(" ; Maybe RefTo %8.8lX", offset);
-#define dFull(full) { \
- d->PushFull(full); \
- d->Comment("MaybeRefTo..."); \
-}
-
-#define sep
-
-#define dInvalid() { \
- d->SetTag(pc, CODE, false); \
- d->SetTag(pc, STOP, true); \
- d->Invalid(); \
-}
-
-#define dSuspect() { \
- d->Suspect(); \
- d->Comment("Suspect!"); \
-}
-#if 0 // with OfB...
-// printf(" ; RefTo %8.8lX - %i bits", offset, width);
-#define dMemRefer(offset, width) { \
- d->PushMemref(offset, width); \
- d->Comment("RefTo..."); \
-}
-#endif
-
-#define Invalidate(reg) { \
- if (!reg) \
- dSuspect(); \
-}
-
-#define SetReg(reg, val) { \
- if (!reg) \
- dSuspect(); \
-}
-
-#define MarkFunction(target) { \
- d->add_function(target); \
-}
-
-#define Branch(branch) { \
- d->add_branch(branch); \
-}
-
-#define Jump(target) { \
- d->add_jump(target); \
-}
-
-#define Stop(target) { \
- d->SetTag(target, STOP, true); \
-}
-
-/*********************************************************
-* Arithmetic with immediate operand *
-* Format: OP rt, rs, immediate *
-*********************************************************/
-
-MakeDisF(disADDI,
- dName("addi");
-
- dGPR(_Rt_); sep;
- if (_Rt_ != _Rs_) {
- dGPR(_Rs_); sep;
- }
- dImm();
-
- Invalidate(_Rt_);
-
- d->Comment("Add immediate");
-)
-
-MakeDisF(disADDIU,
- if (!_Rs_) {
- dName("li");
-
- dGPR(_Rt_); sep;
- dImm();
-
- Uint32 full;
- int32 sfull;
- Uint16 lower;
- int16 slower;
- lower = _Im_;
- slower = *((int16 *) &lower);
-
- sfull = slower;
- full = *((Uint32 *) &sfull);
-
- SetReg(_Rt_, full);
-
- d->Comment("Load immediate");
- } else {
- Uint32 pcode = d->getmem()->Read32(pc - 4);
- if ((((pcode >> 16) & 0x1F) == _Rt_) && (_Rt_ == _Rs_) && ((pcode >> 26) == 0xf)) {
- Uint32 full;
- Uint16 lower;
- int16 slower;
- lower = _Im_;
- slower = *((int16 *) &lower);
-
- full = ((pcode & 0xffff) << 16) + slower;
-
- dName("li");
- dGPR(_Rt_); sep;
- dFull(full);
- SetReg(_Rt_, full);
- d->Comment("Load immediate (aggregate)");
- } else {
- dName("addiu");
-
- dGPR(_Rt_); sep;
- if (_Rt_ != _Rs_) {
- dGPR(_Rs_); sep;
- }
- dImm();
-
- Invalidate(_Rt_);
-
- d->Comment("Add immediate");
- }
- }
-)
-
-MakeDisF(disANDI,
- dName("andi");
-
- dGPR(_Rt_); sep;
- if (_Rt_ != _Rs_) {
- dGPR(_Rs_); sep;
- }
- dImm();
-
- Invalidate(_Rt_);
-
- d->Comment("And immediate");
-)
-
-MakeDisF(disORI,
- if (!_Rs_) {
- dName("liu");
-
- dGPR(_Rt_); sep;
- dImm();
- SetReg(_Rt_, _Im_);
-
- d->Comment("Load immediate without sign extension");
- } else {
- dName("ori");
-
- dGPR(_Rt_); sep;
- if (_Rt_ != _Rs_) {
- dGPR(_Rs_); sep;
- }
- dImm();
- Invalidate(_Rt_);
- d->Comment("Or immediate");
- }
-)
-
-MakeDisF(disSLTI,
- dName("slti");
-
- dGPR(_Rt_); sep;
- if (_Rt_ != _Rs_) {
- dGPR(_Rs_); sep;
- }
- dImm();
-
- Invalidate(_Rt_);
-
- d->Comment(registers[_Rt_] + String(" = ") + registers[_Rs_] + " < immediate ? 1 : 0 (signed)");
-)
-
-MakeDisF(disSLTIU,
- dName("sltiu");
-
- dGPR(_Rt_); sep;
- if (_Rt_ != _Rs_) {
- dGPR(_Rs_); sep;
- }
- dImm();
-
- Invalidate(_Rt_);
-
- d->Comment(registers[_Rt_] + String(" = ") + registers[_Rs_] + " < immediate ? 1 : 0 (unsigned)");
-)
-
-MakeDisF(disXORI,
- dName("xori");
-
- dGPR(_Rt_); sep;
- if (_Rt_ != _Rs_) {
- dGPR(_Rs_); sep;
- }
- dImm();
-
- Invalidate(_Rt_);
-
- d->Comment("XOr immediate");
-)
-
-/*********************************************************
-* Register arithmetic *
-* Format: OP rd, rs, rt *
-*********************************************************/
-MakeDisF(disADD,
- dName("add");
-
- dGPR(_Rd_); sep;
- if (_Rd_ != _Rs_) {
- dGPR(_Rs_); sep;
- }
- dGPR(_Rt_);
-
- Invalidate(_Rt_);
-
- d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " + " + registers[_Rt_]);
-)
-
-MakeDisF(disADDU,
- if (!_Rt_) {
- dName("move");
-
- dGPR(_Rd_); sep;
- dGPR(_Rs_);
- if (_Rs_) {
- Invalidate(_Rd_);
- } else {
- SetReg(_Rd_, 0);
- }
- d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_]);
- } else {
- dName("addu");
-
- dGPR(_Rd_); sep;
- if (_Rd_ != _Rs_) {
- dGPR(_Rs_); sep;
- }
- dGPR(_Rt_);
- Invalidate(_Rd_);
- d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " + " + registers[_Rt_]);
- }
-)
-
-MakeDisF(disAND,
- dName("and");
-
- dGPR(_Rd_); sep;
- if (_Rd_ != _Rs_) {
- dGPR(_Rs_); sep;
- }
- dGPR(_Rt_);
- Invalidate(_Rd_);
- d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " & " + registers[_Rt_]);
-)
-
-MakeDisF(disNOR,
- dName("nor");
-
- dGPR(_Rd_); sep;
- if (_Rd_ != _Rs_) {
- dGPR(_Rs_); sep;
- }
- dGPR(_Rt_);
- Invalidate(_Rd_);
- d->Comment(String(registers[_Rd_]) + " = ~(" + registers[_Rs_] + " & " + registers[_Rt_] + ")");
-)
-
-MakeDisF(disOR,
- dName("or");
-
- dGPR(_Rd_); sep;
- if (_Rd_ != _Rs_) {
- dGPR(_Rs_); sep;
- }
- dGPR(_Rt_);
- Invalidate(_Rd_);
- d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " | " + registers[_Rt_]);
-)
-
-MakeDisF(disSLT,
- dName("slt");
-
- dGPR(_Rd_); sep;
- if (_Rd_ != _Rs_) {
- dGPR(_Rs_); sep;
- }
- dGPR(_Rt_);
- Invalidate(_Rd_);
- d->Comment(registers[_Rd_] + String(" = ") + registers[_Rs_] + " < " + registers[_Rt_] + " ? 1 : 0 (signed)");
-)
-
-MakeDisF(disSLTU,
- dName("sltu");
-
- dGPR(_Rd_); sep;
- if (_Rd_ != _Rs_) {
- dGPR(_Rs_); sep;
- }
- dGPR(_Rt_);
- Invalidate(_Rd_);
- d->Comment(registers[_Rd_] + String(" = ") + registers[_Rs_] + " < " + registers[_Rt_] + " ? 1 : 0 (unsigned)");
-)
-
-MakeDisF(disSUB,
- dName("sub");
-
- dGPR(_Rd_); sep;
- if (_Rd_ != _Rs_) {
- dGPR(_Rs_); sep;
- }
- dGPR(_Rt_);
- Invalidate(_Rd_);
- d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " - " + registers[_Rt_]);
-)
-
-MakeDisF(disSUBU,
- dName("subu");
-
- dGPR(_Rd_); sep;
- if (_Rd_ != _Rs_) {
- dGPR(_Rs_); sep;
- }
- dGPR(_Rt_);
- Invalidate(_Rd_);
- d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " - " + registers[_Rt_]);
-)
-
-MakeDisF(disXOR,
- dName("xor");
-
- dGPR(_Rd_); sep;
- if (_Rd_ != _Rs_) {
- dGPR(_Rs_); sep;
- }
- dGPR(_Rt_);
- Invalidate(_Rd_);
- d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " ^ " + registers[_Rt_]);
-)
-
-/*********************************************************
-* Register arithmetic & Register trap logic *
-* Format: OP rs, rt *
-*********************************************************/
-MakeDisF(disDIV,
- dName("div");
-
- dGPR(_Rs_); sep;
- dGPR(_Rt_);
-
- String c1 = String(registers[_Rs_]) + " / " + registers[_Rt_];
- String c2 = String(registers[_Rs_]) + " %% " + registers[_Rt_];
-
- d->Comment("lo = " + c1 + "; hi = " + c2);
-)
-
-MakeDisF(disDIVU,
- dName("divu");
-
- dGPR(_Rs_); sep;
- dGPR(_Rt_);
-
- d->Comment(String("lo = " ) + registers[_Rs_] + " / " + registers[_Rt_] + "; hi = " + registers[_Rs_] + " % " + registers[_Rt_]);
-)
-
-MakeDisF(disMULT,
- dName("mult");
-
- dGPR(_Rs_); sep;
- dGPR(_Rt_);
-
- d->Comment(String("hilo = ") + registers[_Rs_] + " * " + registers[_Rt_]);
-)
-
-MakeDisF(disMULTU,
- dName("multu");
-
- dGPR(_Rs_); sep;
- dGPR(_Rt_);
-
- d->Comment(String("hilo = ") + registers[_Rs_] + " * " + registers[_Rt_]);
-)
-
-/*********************************************************
-* Register branch logic *
-* Format: OP rs, offset *
-*********************************************************/
-MakeDisF(disBGEZ,
- dName("bgez");
-
- dGPR(_Rs_); sep;
- dOffset();
- Branch(_Branch_);
- d->Comment("Branch if " + String(registers[_Rs_]) + " >= 0");
-)
-
-MakeDisF(disBGEZAL,
- dName("bgezal");
-
- dGPR(_Rs_); sep;
- dOffset();
- Branch(_Branch_);
- d->Comment("Branch and link if " + String(registers[_Rs_]) + " >= 0");
-)
-
-MakeDisF(disBGTZ,
- dName("bgtz");
-
- dGPR(_Rs_); sep;
- dOffset();
- Branch(_Branch_);
- d->Comment("Branch if " + String(registers[_Rs_]) + " > 0");
-)
-
-MakeDisF(disBLEZ,
- dName("blez");
-
- dGPR(_Rs_); sep;
- dOffset();
- Branch(_Branch_);
- d->Comment("Branch if " + String(registers[_Rs_]) + " <= 0");
-)
-
-MakeDisF(disBLTZ,
- dName("bltz");
-
- dGPR(_Rs_); sep;
- dOffset();
- Branch(_Branch_);
- d->Comment("Branch if " + String(registers[_Rs_]) + " < 0");
-)
-
-MakeDisF(disBLTZAL,
- dName("bltzal");
-
- dGPR(_Rs_); sep;
- dOffset();
- Branch(_Branch_);
- d->Comment("Branch and link if " + String(registers[_Rs_]) + " <= 0");
-)
-
-/*********************************************************
-* Shift arithmetic with constant shift *
-* Format: OP rd, rt, sa *
-*********************************************************/
-MakeDisF(disSLL,
- if ((!_Rd_) && (!_Rt_)) {
- dName("nop");
- if (code) {
- dSuspect();
- }
- } else {
- dName("sll");
-
- dGPR(_Rd_); sep;
- if (_Rd_ != _Rt_) {
- dGPR(_Rt_); sep;
- }
- dSa();
- Invalidate(_Rd_);
- d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " << immediate");
- }
-)
-
-MakeDisF(disSRA,
- dName("sra");
-
- dGPR(_Rd_); sep;
- if (_Rd_ != _Rt_) {
- dGPR(_Rt_); sep;
- }
- dSa();
- Invalidate(_Rd_);
- d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " >> immediate (arithmetic)");
-)
-
-MakeDisF(disSRL,
- dName("srl");
-
- dGPR(_Rd_); sep;
- if (_Rd_ != _Rt_) {
- dGPR(_Rt_); sep;
- }
- dSa();
- Invalidate(_Rd_);
- d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " >> immediate (logical)");
-)
-
-/*********************************************************
-* Shift arithmetic with variant register shift *
-* Format: OP rd, rt, rs *
-*********************************************************/
-MakeDisF(disSLLV,
- dName("sllv");
-
- dGPR(_Rd_); sep;
- if (_Rd_ != _Rt_) {
- dGPR(_Rt_); sep;
- }
- dGPR(_Rs_);
- Invalidate(_Rd_);
- d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " << " + registers[_Rs_]);
-)
-
-MakeDisF(disSRAV,
- dName("srav");
-
- dGPR(_Rd_); sep;
- if (_Rd_ != _Rt_) {
- dGPR(_Rt_); sep;
- }
- dGPR(_Rs_);
- Invalidate(_Rd_);
- d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " >> " + registers[_Rs_] + " (arithmetic)");
-)
-
-MakeDisF(disSRLV,
- dName("srlv");
-
- dGPR(_Rd_); sep;
- if (_Rd_ != _Rt_) {
- dGPR(_Rt_); sep;
- }
- dGPR(_Rs_);
- Invalidate(_Rd_);
- d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " >> " + registers[_Rs_] + " (logical)");
-)
-
-/*********************************************************
-* Load higher 16 bits of the first word in GPR with imm *
-* Format: OP rt, immediate *
-*********************************************************/
-MakeDisF(disLUI,
- dName("lui");
-
- dGPR(_Rt_); sep;
- dImm();
-
- Invalidate(_Rt_);
-
- d->Comment("Load upper immediate");
-)
-
-/*********************************************************
-* Move from HI/LO to GPR *
-* Format: OP rd *
-*********************************************************/
-MakeDisF(disMFHI,
- dName("mfhi");
-
- dGPR(_Rd_);
- Invalidate(_Rd_);
-
- d->Comment(String(registers[_Rd_]) + " = hi");
-)
-
-MakeDisF(disMFLO,
- dName("mflo");
-
- dGPR(_Rd_);
- Invalidate(_Rd_);
-
- d->Comment(String(registers[_Rd_]) + " = lo");
-)
-
-/*********************************************************
-* Move from GPR to HI/LO *
-* Format: OP rd *
-*********************************************************/
-MakeDisF(disMTHI,
- dName("mthi");
-
- dGPR(_Rd_);
-
- d->Comment("hi = " + String(registers[_Rd_]));
-)
-
-MakeDisF(disMTLO,
- dName("mtlo");
-
- dGPR(_Rd_);
-
- d->Comment("lo = " + String(registers[_Rd_]));
-)
-
-/*********************************************************
-* Special purpose instructions *
-* Format: OP *
-*********************************************************/
-MakeDisF(disBREAK,
- dName("break");
-
- Stop(pc + 4);
-
- d->Comment("Stops the machine");
-)
-MakeDisF(disRFE, dName("rfe"))
-
-MakeDisF(disSYSCALL,
- int syscall;
- dName("syscall");
- syscall = code & 0xfffff;
-
- d->Comment(String("Syscall number ") + syscall);
-)
-
-MakeDisF(disHLE, dName("hle"))
-
-MakeDisF(disRTPS, dName("rtps"))
-MakeDisF(disOP , dName("op"))
-MakeDisF(disNCLIP, dName("nclip"))
-MakeDisF(disDPCS, dName("dpcs"))
-MakeDisF(disINTPL, dName("intpl"))
-MakeDisF(disMVMVA, dName("mvmva"))
-MakeDisF(disNCDS , dName("ncds"))
-MakeDisF(disCDP , dName("cdp"))
-MakeDisF(disNCDT , dName("ncdt"))
-MakeDisF(disNCCS , dName("nccs"))
-MakeDisF(disCC , dName("cc"))
-MakeDisF(disNCS , dName("ncs"))
-MakeDisF(disNCT , dName("nct"))
-MakeDisF(disSQR , dName("sqr"))
-MakeDisF(disDCPL , dName("dcpl"))
-MakeDisF(disDPCT , dName("dpct"))
-MakeDisF(disAVSZ3, dName("avsz3"))
-MakeDisF(disAVSZ4, dName("avsz4"))
-MakeDisF(disRTPT , dName("rtpt"))
-MakeDisF(disGPF , dName("gpf"))
-MakeDisF(disGPL , dName("gpl"))
-MakeDisF(disNCCT , dName("ncct"))
-
-MakeDisF(disMFC2, dName("mfc2"); dGPR(_Rt_); Invalidate(_Rt_); )
-MakeDisF(disCFC2, dName("cfc2"); dGPR(_Rt_); Invalidate(_Rt_); )
-MakeDisF(disMTC2, dName("mtc2"); dGPR(_Rt_);)
-MakeDisF(disCTC2, dName("ctc2"); dGPR(_Rt_);)
-
-/*********************************************************
-* Register branch logic *
-* Format: OP rs, rt, offset *
-*********************************************************/
-MakeDisF(disBEQ,
- if ((!_Rt_) && (!_Rs_)) {
- dName("b");
-
- dOffset();
- Branch(_Branch_);
- Stop(pc + 8);
-
- d->Comment("Branch always");
- }
- if (!_Rt_) {
- dName("bez");
-
- dGPR(_Rs_); sep;
- dOffset();
- Branch(_Branch_);
-
- d->Comment(String("Branch if ") + registers[_Rs_] + " == 0");
- } else {
- dName("beq");
-
- dGPR(_Rs_); sep;
- dGPR(_Rt_); sep;
- dOffset();
- Branch(_Branch_);
-
- d->Comment(String("Branch if ") + registers[_Rs_] + " == " + registers[_Rt_]);
- }
-)
-
-MakeDisF(disBNE,
- if (!_Rt_) {
- dName("bnz");
-
- dGPR(_Rs_); sep;
- dOffset();
- Branch(_Branch_);
-
- d->Comment(String("Branch if ") + registers[_Rs_] + " != 0");
- } else {
- dName("bne");
-
- dGPR(_Rs_); sep;
- dGPR(_Rt_); sep;
- dOffset();
- Branch(_Branch_);
-
- d->Comment(String("Branch if ") + registers[_Rs_] + " != " + registers[_Rt_]);
- }
-)
-
-/*********************************************************
-* Jump to target *
-* Format: OP target *
-*********************************************************/
-MakeDisF(disJ,
- dName("j");
-
- dTarget();
- Jump(_Target_);
- Stop(pc + 8);
-
- d->Comment("Jump always");
-)
-
-MakeDisF(disJAL,
- dName("jal");
-
- dTarget();
- Invalidate(Rra);
- MarkFunction(_Target_);
-
- d->Comment("Jump and link (function call)");
-)
-
-/*********************************************************
-* Register jump *
-* Format: OP rs, rd *
-*********************************************************/
-MakeDisF(disJR,
- dName("jr");
- dGPR(_Rs_);
- Stop(pc + 8);
-
- d->Comment("Jump register");
-)
-
-MakeDisF(disJALR,
- dName("jalr");
-
- dGPR(_Rs_);
-
- if ((_Rd_) != Rra) {
- sep; dGPR(_Rd_);
- }
-
- Invalidate(_Rd_);
-
- d->Comment("Jump and link register (function call)");
-)
-
-/*********************************************************
-* Load and store for GPR *
-* Format: OP rt, offset(base) *
-*********************************************************/
-MakeDisF(disLB,
- int width = 8;
- dName("lb");
-
- dGPR(_Rt_); sep;
- dOfB();
-
- Invalidate(_Rt_);
- d->Comment("Load signed byte");
-)
-
-MakeDisF(disLBU,
- int width = 8;
- dName("lbu");
-
- dGPR(_Rt_); sep;
- dOfB();
-
- Invalidate(_Rt_);
- d->Comment("Load unsigned byte");
-)
-
-MakeDisF(disLH,
- int width = 16;
- dName("lh");
-
- dGPR(_Rt_); sep;
- dOfB();
-
- Invalidate(_Rt_);
- d->Comment("Load signed half");
-)
-
-MakeDisF(disLHU,
- int width = 16;
- dName("lhu");
-
- dGPR(_Rt_); sep;
- dOfB();
-
- Invalidate(_Rt_);
- d->Comment("Load unsigned half");
-)
-
-MakeDisF(disLW,
- int width = 32;
- dName("lw");
-
- dGPR(_Rt_); sep;
- dOfB();
-
- Invalidate(_Rt_);
- d->Comment("Load word");
-)
-
-MakeDisF(disLWL,
- int width = 32;
- dName("lwl");
-
- dGPR(_Rt_); sep;
- dOfB();
-
- Invalidate(_Rt_);
- d->Comment("Load word left");
-)
-
-MakeDisF(disLWR,
- int width = 32;
- dName("lwr");
-
- dGPR(_Rt_); sep;
- dOfB();
-
- Invalidate(_Rt_);
- d->Comment("Load word right");
-)
-
-MakeDisF(disLWC2,
- int width = 32;
- dName("lwc2");
-
- dCP0(_Rt_); sep;
- dOfB();
-)
-
-MakeDisF(disSB,
- int width = 8;
- dName("sb");
-
- dGPR(_Rt_); sep;
- dOfB();
- d->Comment("Store byte");
-)
-
-MakeDisF(disSH,
- int width = 16;
- dName("sh");
-
- dGPR(_Rt_); sep;
- dOfB();
- d->Comment("Store half");
-)
-
-MakeDisF(disSW,
- int width = 32;
- dName("sw");
-
- dGPR(_Rt_); sep;
- dOfB();
- d->Comment("Store word");
-)
-
-MakeDisF(disSWL,
- int width = 32;
- dName("swl");
-
- dGPR(_Rt_); sep;
- dOfB();
- d->Comment("Store word left");
-)
-
-MakeDisF(disSWR,
- int width = 32;
- dName("swr");
-
- dGPR(_Rt_); sep;
- dOfB();
- d->Comment("Store word right");
-)
-
-MakeDisF(disSWC2,
- int width = 32;
- dName("swc2");
-
- dGPR(_Rt_); sep;
- dOfB();
-)
-
-/*********************************************************
-* Moves between GPR and COPx *
-* Format: OP rt, fs *
-*********************************************************/
-MakeDisF(disMFC0, dName("mfc0"); dGPR(_Rt_); sep; dCP0(_Rd_); Invalidate(_Rt_);)
-MakeDisF(disMTC0, dName("mtc0"); dCP0(_Rd_); sep; dGPR(_Rt_);)
-MakeDisF(disCFC0, dName("cfc0"); dGPR(_Rt_); sep; dCP0(_Rd_); Invalidate(_Rt_);)
-MakeDisF(disCTC0, dName("ctc0"); dCP0(_Rd_); sep; dGPR(_Rt_);)
-
-/*********************************************************
-* Unknow instruction (would generate an exception) *
-* Format: ? *
-*********************************************************/
-MakeDisF(disNULL,
- dName("*** Bad OP ***");
- dInvalid();
-)
-
-
-TdisR3000AF disR3000A_SPECIAL[] = { // Subset of disSPECIAL
- disSLL , disNULL , disSRL , disSRA , disSLLV , disNULL , disSRLV , disSRAV ,
- disJR , disJALR , disNULL, disNULL, disSYSCALL, disBREAK , disNULL , disNULL ,
- disMFHI, disMTHI , disMFLO, disMTLO, disNULL , disNULL , disNULL , disNULL ,
- disMULT, disMULTU, disDIV , disDIVU, disNULL , disNULL , disNULL , disNULL ,
- disADD , disADDU , disSUB , disSUBU, disAND , disOR , disXOR , disNOR ,
- disNULL, disNULL , disSLT , disSLTU, disNULL , disNULL , disNULL , disNULL ,
- disNULL, disNULL , disNULL, disNULL, disNULL , disNULL , disNULL , disNULL ,
- disNULL, disNULL , disNULL, disNULL, disNULL , disNULL , disNULL , disNULL};
-
-MakeDisF(disSPECIAL, disR3000A_SPECIAL[_Funct_](d, code, pc))
-
-TdisR3000AF disR3000A_BCOND[] = { // Subset of disBCOND
- disBLTZ , disBGEZ , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
- disNULL , disNULL , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
- disBLTZAL, disBGEZAL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
- disNULL , disNULL , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
-
-MakeDisF(disBCOND, disR3000A_BCOND[_Rt_](d, code, pc))
-
-TdisR3000AF disR3000A_COP0[] = { // Subset of disCOP0
- disMFC0, disNULL, disCFC0, disNULL, disMTC0, disNULL, disCTC0, disNULL,
- disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
- disRFE , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
- disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
-
-MakeDisF(disCOP0, disR3000A_COP0[_Rs_](d, code, pc))
-
-TdisR3000AF disR3000A_BASIC[] = { // Subset of disBASIC (based on rs)
- disMFC2, disNULL, disCFC2, disNULL, disMTC2, disNULL, disCTC2, disNULL,
- disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
- disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
- disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
-
-MakeDisF(disBASIC, disR3000A_BASIC[_Rs_](d, code, pc))
-
-TdisR3000AF disR3000A_COP2[] = { // Subset of disR3000F_COP2 (based on funct)
- disBASIC, disRTPS , disNULL , disNULL , disNULL, disNULL , disNCLIP, disNULL,
- disNULL , disNULL , disNULL , disNULL , disOP , disNULL , disNULL , disNULL,
- disDPCS , disINTPL, disMVMVA, disNCDS , disCDP , disNULL , disNCDT , disNULL,
- disNULL , disNULL , disNULL , disNCCS , disCC , disNULL , disNCS , disNULL,
- disNCT , disNULL , disNULL , disNULL , disNULL, disNULL , disNULL , disNULL,
- disSQR , disDCPL , disDPCT , disNULL , disNULL, disAVSZ3, disAVSZ4, disNULL,
- disRTPT , disNULL , disNULL , disNULL , disNULL, disNULL , disNULL , disNULL,
- disNULL , disNULL , disNULL , disNULL , disNULL, disGPF , disGPL , disNCCT };
-
-MakeDisF(disCOP2, disR3000A_COP2[_Funct_](d, code, pc))
-
-TdisR3000AF disR3000A[] = {
- disSPECIAL , disBCOND , disJ , disJAL , disBEQ , disBNE , disBLEZ , disBGTZ ,
- disADDI , disADDIU , disSLTI , disSLTIU, disANDI, disORI , disXORI , disLUI ,
- disCOP0 , disNULL , disCOP2 , disNULL , disNULL, disNULL, disNULL , disNULL ,
- disNULL , disNULL , disNULL , disNULL , disNULL, disNULL, disNULL , disNULL ,
- disLB , disLH , disLWL , disLW , disLBU , disLHU , disLWR , disNULL ,
- disSB , disSH , disSWL , disSW , disNULL, disNULL, disSWR , disNULL ,
- disNULL , disNULL , disLWC2 , disNULL , disNULL, disNULL, disNULL , disNULL ,
- disNULL , disNULL , disSWC2 , disHLE , disNULL, disNULL, disNULL , disNULL };
-
-//MakeDisFg(disR3000AF, disR3000A[code >> 26](code, pc))
-
-void decode(TDis * d, Uint32 pc) {
- Uint32 code = d->getmem()->Read32(pc);
- disR3000A[code >> 26](d, code, pc);
-}
+/*
+ * 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: mips.cpp,v 1.5 2004-11-27 21:47:56 pixel Exp $ */
+
+#include "mips.h"
+
+/* Code HIGHLY ripped off^W^W inspired from PCSX. */
+
+#if 1
+char * registers[] = {
+ "0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+ "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra",
+};
+#else
+char * registers[] = {
+ "00", "01", "02", "03", "04", "05", "06", "07",
+ "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
+ "10", "11", "12", "13", "14", "15", "16", "17",
+ "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
+};
+#endif
+
+char * CP0registers[] = {
+ "Index" , "Random" , "EntryLo0", "EntryLo1", "Context" , "PageMask" , "Wired" , "*Check me*",
+ "BadVAddr" , "Count" , "EntryHi" , "Compare" , "Status" , "Cause" , "ExceptPC" , "PRevID" ,
+ "Config" , "LLAddr" , "WatchLo" , "WatchHi" , "XContext", "*RES*" , "*RES*" , "*RES*" ,
+ "*RES*" , "*RES* " , "PErr" , "CacheErr", "TagLo" , "TagHi" , "ErrorEPC" , "*RES*" };
+
+typedef void (*TdisR3000AF)(TDis *, Uint32 code, Uint32 pc);
+
+// These macros are used to assemble the disassembler functions
+#define MakeDisF(fn, b) \
+ static void fn(TDis * d, Uint32 code, Uint32 pc) { \
+ d->pc = pc; \
+ b; \
+ }
+
+#define _Funct_ ((code ) & 0x3F) // The funct part of the instruction register
+#define _Rd_ ((code >> 11) & 0x1F) // The rd part of the instruction register
+#define _Rt_ ((code >> 16) & 0x1F) // The rt part of the instruction register
+#define _Rs_ ((code >> 21) & 0x1F) // The rs part of the instruction register
+#define _Sa_ ((code >> 6) & 0x1F) // The sa part of the instruction register
+#define _Im_ ( code & 0xFFFF) // The immediate part of the instruction register
+ // The signed immediate part of the instruction register
+#define _sIm_ (code & 0x8000 ? - (((~code) & 0x7FFF) + 1) : ( code & 0x7FFF))
+
+#define _Target_ (0x80000000 + ((code & 0x03ffffff) * 4))
+#define _Branch_ (pc + 4 + ((short)_Im_ * 4))
+#define _OfB_ _Im_, _nRs_
+
+#define dName(n) { d->Name(n); }
+#define dGPR(i) { d->PushGPReg(i); }
+#define dCP0(i) { d->PushCPReg(i); }
+#define dImm() { d->PushImm(_Im_); }
+#define dTarget() { d->PushTarget(_Target_); }
+#define dSa() { d->PushSa(_Sa_); }
+#if 0
+#define dOfB() { \
+ Uint32 pcode = d->getmem()->Read32(pc - 4); \
+ if ((((pcode >> 16) & 0x1F) == _Rs_) && ((pcode >> 26) == 0xf)) { \
+ Uint32 full; \
+ Uint16 lower; \
+ int16 slower; \
+ lower = _Im_; \
+ slower = *((int16 *) &lower); \
+ \
+ full = ((pcode & 0xffff) << 16) + slower; \
+ \
+ d->PushOfB(_Rs_, full, width); \
+ \
+ dMemRefer(full, width); \
+ } else { \
+ d->PushOfB(_Rs_, _Im_, width); \
+ } \
+}
+#else
+#define dOfB() { \
+ d->PushOfB(_Rs_, _Im_, width); \
+}
+#endif
+#define dOffset() { \
+ d->PushOffset(_Branch_); \
+}
+// printf(" ; Maybe RefTo %8.8lX", offset);
+#define dFull(full) { \
+ d->PushFull(full); \
+ d->Comment("MaybeRefTo..."); \
+}
+
+#define sep
+
+#define dInvalid() { \
+ d->SetTag(pc, CODE, false); \
+ d->SetTag(pc, STOP, true); \
+ d->Invalid(); \
+}
+
+#define dSuspect() { \
+ d->Suspect(); \
+ d->Comment("Suspect!"); \
+}
+#if 0 // with OfB...
+// printf(" ; RefTo %8.8lX - %i bits", offset, width);
+#define dMemRefer(offset, width) { \
+ d->PushMemref(offset, width); \
+ d->Comment("RefTo..."); \
+}
+#endif
+
+#define Invalidate(reg) { \
+ if (!reg) \
+ dSuspect(); \
+}
+
+#define SetReg(reg, val) { \
+ if (!reg) \
+ dSuspect(); \
+}
+
+#define MarkFunction(target) { \
+ d->add_function(target); \
+}
+
+#define Branch(branch) { \
+ d->add_branch(branch); \
+}
+
+#define Jump(target) { \
+ d->add_jump(target); \
+}
+
+#define Stop(target) { \
+ d->SetTag(target, STOP, true); \
+}
+
+/*********************************************************
+* Arithmetic with immediate operand *
+* Format: OP rt, rs, immediate *
+*********************************************************/
+
+MakeDisF(disADDI,
+ dName("addi");
+
+ dGPR(_Rt_); sep;
+ if (_Rt_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dImm();
+
+ Invalidate(_Rt_);
+
+ d->Comment("Add immediate");
+)
+
+MakeDisF(disADDIU,
+ if (!_Rs_) {
+ dName("li");
+
+ dGPR(_Rt_); sep;
+ dImm();
+
+ Uint32 full;
+ int32 sfull;
+ Uint16 lower;
+ int16 slower;
+ lower = _Im_;
+ slower = *((int16 *) &lower);
+
+ sfull = slower;
+ full = *((Uint32 *) &sfull);
+
+ SetReg(_Rt_, full);
+
+ d->Comment("Load immediate");
+ } else {
+ Uint32 pcode = d->getmem()->Read32(pc - 4);
+ if ((((pcode >> 16) & 0x1F) == _Rt_) && (_Rt_ == _Rs_) && ((pcode >> 26) == 0xf)) {
+ Uint32 full;
+ Uint16 lower;
+ int16 slower;
+ lower = _Im_;
+ slower = *((int16 *) &lower);
+
+ full = ((pcode & 0xffff) << 16) + slower;
+
+ dName("li");
+ dGPR(_Rt_); sep;
+ dFull(full);
+ SetReg(_Rt_, full);
+ d->Comment("Load immediate (aggregate)");
+ } else {
+ dName("addiu");
+
+ dGPR(_Rt_); sep;
+ if (_Rt_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dImm();
+
+ Invalidate(_Rt_);
+
+ d->Comment("Add immediate");
+ }
+ }
+)
+
+MakeDisF(disANDI,
+ dName("andi");
+
+ dGPR(_Rt_); sep;
+ if (_Rt_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dImm();
+
+ Invalidate(_Rt_);
+
+ d->Comment("And immediate");
+)
+
+MakeDisF(disORI,
+ if (!_Rs_) {
+ dName("liu");
+
+ dGPR(_Rt_); sep;
+ dImm();
+ SetReg(_Rt_, _Im_);
+
+ d->Comment("Load immediate without sign extension");
+ } else {
+ dName("ori");
+
+ dGPR(_Rt_); sep;
+ if (_Rt_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dImm();
+ Invalidate(_Rt_);
+ d->Comment("Or immediate");
+ }
+)
+
+MakeDisF(disSLTI,
+ dName("slti");
+
+ dGPR(_Rt_); sep;
+ if (_Rt_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dImm();
+
+ Invalidate(_Rt_);
+
+ d->Comment(registers[_Rt_] + String(" = ") + registers[_Rs_] + " < immediate ? 1 : 0 (signed)");
+)
+
+MakeDisF(disSLTIU,
+ dName("sltiu");
+
+ dGPR(_Rt_); sep;
+ if (_Rt_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dImm();
+
+ Invalidate(_Rt_);
+
+ d->Comment(registers[_Rt_] + String(" = ") + registers[_Rs_] + " < immediate ? 1 : 0 (unsigned)");
+)
+
+MakeDisF(disXORI,
+ dName("xori");
+
+ dGPR(_Rt_); sep;
+ if (_Rt_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dImm();
+
+ Invalidate(_Rt_);
+
+ d->Comment("XOr immediate");
+)
+
+/*********************************************************
+* Register arithmetic *
+* Format: OP rd, rs, rt *
+*********************************************************/
+MakeDisF(disADD,
+ dName("add");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+
+ Invalidate(_Rt_);
+
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " + " + registers[_Rt_]);
+)
+
+MakeDisF(disADDU,
+ if (!_Rt_) {
+ dName("move");
+
+ dGPR(_Rd_); sep;
+ dGPR(_Rs_);
+ if (_Rs_) {
+ Invalidate(_Rd_);
+ } else {
+ SetReg(_Rd_, 0);
+ }
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_]);
+ } else {
+ dName("addu");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " + " + registers[_Rt_]);
+ }
+)
+
+MakeDisF(disAND,
+ dName("and");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " & " + registers[_Rt_]);
+)
+
+MakeDisF(disNOR,
+ dName("nor");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = ~(" + registers[_Rs_] + " & " + registers[_Rt_] + ")");
+)
+
+MakeDisF(disOR,
+ dName("or");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " | " + registers[_Rt_]);
+)
+
+MakeDisF(disSLT,
+ dName("slt");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(registers[_Rd_] + String(" = ") + registers[_Rs_] + " < " + registers[_Rt_] + " ? 1 : 0 (signed)");
+)
+
+MakeDisF(disSLTU,
+ dName("sltu");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(registers[_Rd_] + String(" = ") + registers[_Rs_] + " < " + registers[_Rt_] + " ? 1 : 0 (unsigned)");
+)
+
+MakeDisF(disSUB,
+ dName("sub");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " - " + registers[_Rt_]);
+)
+
+MakeDisF(disSUBU,
+ dName("subu");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " - " + registers[_Rt_]);
+)
+
+MakeDisF(disXOR,
+ dName("xor");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " ^ " + registers[_Rt_]);
+)
+
+/*********************************************************
+* Register arithmetic & Register trap logic *
+* Format: OP rs, rt *
+*********************************************************/
+MakeDisF(disDIV,
+ dName("div");
+
+ dGPR(_Rs_); sep;
+ dGPR(_Rt_);
+
+ String c1 = String(registers[_Rs_]) + " / " + registers[_Rt_];
+ String c2 = String(registers[_Rs_]) + " %% " + registers[_Rt_];
+
+ d->Comment("lo = " + c1 + "; hi = " + c2);
+)
+
+MakeDisF(disDIVU,
+ dName("divu");
+
+ dGPR(_Rs_); sep;
+ dGPR(_Rt_);
+
+ d->Comment(String("lo = " ) + registers[_Rs_] + " / " + registers[_Rt_] + "; hi = " + registers[_Rs_] + " % " + registers[_Rt_]);
+)
+
+MakeDisF(disMULT,
+ dName("mult");
+
+ dGPR(_Rs_); sep;
+ dGPR(_Rt_);
+
+ d->Comment(String("hilo = ") + registers[_Rs_] + " * " + registers[_Rt_]);
+)
+
+MakeDisF(disMULTU,
+ dName("multu");
+
+ dGPR(_Rs_); sep;
+ dGPR(_Rt_);
+
+ d->Comment(String("hilo = ") + registers[_Rs_] + " * " + registers[_Rt_]);
+)
+
+/*********************************************************
+* Register branch logic *
+* Format: OP rs, offset *
+*********************************************************/
+MakeDisF(disBGEZ,
+ dName("bgez");
+
+ dGPR(_Rs_); sep;
+ dOffset();
+ Branch(_Branch_);
+ d->Comment("Branch if " + String(registers[_Rs_]) + " >= 0");
+)
+
+MakeDisF(disBGEZAL,
+ dName("bgezal");
+
+ dGPR(_Rs_); sep;
+ dOffset();
+ Branch(_Branch_);
+ d->Comment("Branch and link if " + String(registers[_Rs_]) + " >= 0");
+)
+
+MakeDisF(disBGTZ,
+ dName("bgtz");
+
+ dGPR(_Rs_); sep;
+ dOffset();
+ Branch(_Branch_);
+ d->Comment("Branch if " + String(registers[_Rs_]) + " > 0");
+)
+
+MakeDisF(disBLEZ,
+ dName("blez");
+
+ dGPR(_Rs_); sep;
+ dOffset();
+ Branch(_Branch_);
+ d->Comment("Branch if " + String(registers[_Rs_]) + " <= 0");
+)
+
+MakeDisF(disBLTZ,
+ dName("bltz");
+
+ dGPR(_Rs_); sep;
+ dOffset();
+ Branch(_Branch_);
+ d->Comment("Branch if " + String(registers[_Rs_]) + " < 0");
+)
+
+MakeDisF(disBLTZAL,
+ dName("bltzal");
+
+ dGPR(_Rs_); sep;
+ dOffset();
+ Branch(_Branch_);
+ d->Comment("Branch and link if " + String(registers[_Rs_]) + " <= 0");
+)
+
+/*********************************************************
+* Shift arithmetic with constant shift *
+* Format: OP rd, rt, sa *
+*********************************************************/
+MakeDisF(disSLL,
+ if ((!_Rd_) && (!_Rt_)) {
+ dName("nop");
+ if (code) {
+ dSuspect();
+ }
+ } else {
+ dName("sll");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rt_) {
+ dGPR(_Rt_); sep;
+ }
+ dSa();
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " << immediate");
+ }
+)
+
+MakeDisF(disSRA,
+ dName("sra");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rt_) {
+ dGPR(_Rt_); sep;
+ }
+ dSa();
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " >> immediate (arithmetic)");
+)
+
+MakeDisF(disSRL,
+ dName("srl");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rt_) {
+ dGPR(_Rt_); sep;
+ }
+ dSa();
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " >> immediate (logical)");
+)
+
+/*********************************************************
+* Shift arithmetic with variant register shift *
+* Format: OP rd, rt, rs *
+*********************************************************/
+MakeDisF(disSLLV,
+ dName("sllv");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rt_) {
+ dGPR(_Rt_); sep;
+ }
+ dGPR(_Rs_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " << " + registers[_Rs_]);
+)
+
+MakeDisF(disSRAV,
+ dName("srav");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rt_) {
+ dGPR(_Rt_); sep;
+ }
+ dGPR(_Rs_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " >> " + registers[_Rs_] + " (arithmetic)");
+)
+
+MakeDisF(disSRLV,
+ dName("srlv");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rt_) {
+ dGPR(_Rt_); sep;
+ }
+ dGPR(_Rs_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " >> " + registers[_Rs_] + " (logical)");
+)
+
+/*********************************************************
+* Load higher 16 bits of the first word in GPR with imm *
+* Format: OP rt, immediate *
+*********************************************************/
+MakeDisF(disLUI,
+ dName("lui");
+
+ dGPR(_Rt_); sep;
+ dImm();
+
+ Invalidate(_Rt_);
+
+ d->Comment("Load upper immediate");
+)
+
+/*********************************************************
+* Move from HI/LO to GPR *
+* Format: OP rd *
+*********************************************************/
+MakeDisF(disMFHI,
+ dName("mfhi");
+
+ dGPR(_Rd_);
+ Invalidate(_Rd_);
+
+ d->Comment(String(registers[_Rd_]) + " = hi");
+)
+
+MakeDisF(disMFLO,
+ dName("mflo");
+
+ dGPR(_Rd_);
+ Invalidate(_Rd_);
+
+ d->Comment(String(registers[_Rd_]) + " = lo");
+)
+
+/*********************************************************
+* Move from GPR to HI/LO *
+* Format: OP rd *
+*********************************************************/
+MakeDisF(disMTHI,
+ dName("mthi");
+
+ dGPR(_Rd_);
+
+ d->Comment("hi = " + String(registers[_Rd_]));
+)
+
+MakeDisF(disMTLO,
+ dName("mtlo");
+
+ dGPR(_Rd_);
+
+ d->Comment("lo = " + String(registers[_Rd_]));
+)
+
+/*********************************************************
+* Special purpose instructions *
+* Format: OP *
+*********************************************************/
+MakeDisF(disBREAK,
+ dName("break");
+
+ Stop(pc + 4);
+
+ d->Comment("Stops the machine");
+)
+MakeDisF(disRFE, dName("rfe"))
+
+MakeDisF(disSYSCALL,
+ int syscall;
+ dName("syscall");
+ syscall = code & 0xfffff;
+
+ d->Comment(String("Syscall number ") + syscall);
+)
+
+MakeDisF(disHLE, dName("hle"))
+
+MakeDisF(disRTPS, dName("rtps"))
+MakeDisF(disOP , dName("op"))
+MakeDisF(disNCLIP, dName("nclip"))
+MakeDisF(disDPCS, dName("dpcs"))
+MakeDisF(disINTPL, dName("intpl"))
+MakeDisF(disMVMVA, dName("mvmva"))
+MakeDisF(disNCDS , dName("ncds"))
+MakeDisF(disCDP , dName("cdp"))
+MakeDisF(disNCDT , dName("ncdt"))
+MakeDisF(disNCCS , dName("nccs"))
+MakeDisF(disCC , dName("cc"))
+MakeDisF(disNCS , dName("ncs"))
+MakeDisF(disNCT , dName("nct"))
+MakeDisF(disSQR , dName("sqr"))
+MakeDisF(disDCPL , dName("dcpl"))
+MakeDisF(disDPCT , dName("dpct"))
+MakeDisF(disAVSZ3, dName("avsz3"))
+MakeDisF(disAVSZ4, dName("avsz4"))
+MakeDisF(disRTPT , dName("rtpt"))
+MakeDisF(disGPF , dName("gpf"))
+MakeDisF(disGPL , dName("gpl"))
+MakeDisF(disNCCT , dName("ncct"))
+
+MakeDisF(disMFC2, dName("mfc2"); dGPR(_Rt_); Invalidate(_Rt_); )
+MakeDisF(disCFC2, dName("cfc2"); dGPR(_Rt_); Invalidate(_Rt_); )
+MakeDisF(disMTC2, dName("mtc2"); dGPR(_Rt_);)
+MakeDisF(disCTC2, dName("ctc2"); dGPR(_Rt_);)
+
+/*********************************************************
+* Register branch logic *
+* Format: OP rs, rt, offset *
+*********************************************************/
+MakeDisF(disBEQ,
+ if ((!_Rt_) && (!_Rs_)) {
+ dName("b");
+
+ dOffset();
+ Branch(_Branch_);
+ Stop(pc + 8);
+
+ d->Comment("Branch always");
+ }
+ if (!_Rt_) {
+ dName("bez");
+
+ dGPR(_Rs_); sep;
+ dOffset();
+ Branch(_Branch_);
+
+ d->Comment(String("Branch if ") + registers[_Rs_] + " == 0");
+ } else {
+ dName("beq");
+
+ dGPR(_Rs_); sep;
+ dGPR(_Rt_); sep;
+ dOffset();
+ Branch(_Branch_);
+
+ d->Comment(String("Branch if ") + registers[_Rs_] + " == " + registers[_Rt_]);
+ }
+)
+
+MakeDisF(disBNE,
+ if (!_Rt_) {
+ dName("bnz");
+
+ dGPR(_Rs_); sep;
+ dOffset();
+ Branch(_Branch_);
+
+ d->Comment(String("Branch if ") + registers[_Rs_] + " != 0");
+ } else {
+ dName("bne");
+
+ dGPR(_Rs_); sep;
+ dGPR(_Rt_); sep;
+ dOffset();
+ Branch(_Branch_);
+
+ d->Comment(String("Branch if ") + registers[_Rs_] + " != " + registers[_Rt_]);
+ }
+)
+
+/*********************************************************
+* Jump to target *
+* Format: OP target *
+*********************************************************/
+MakeDisF(disJ,
+ dName("j");
+
+ dTarget();
+ Jump(_Target_);
+ Stop(pc + 8);
+
+ d->Comment("Jump always");
+)
+
+MakeDisF(disJAL,
+ dName("jal");
+
+ dTarget();
+ Invalidate(Rra);
+ MarkFunction(_Target_);
+
+ d->Comment("Jump and link (function call)");
+)
+
+/*********************************************************
+* Register jump *
+* Format: OP rs, rd *
+*********************************************************/
+MakeDisF(disJR,
+ dName("jr");
+ dGPR(_Rs_);
+ Stop(pc + 8);
+
+ d->Comment("Jump register");
+)
+
+MakeDisF(disJALR,
+ dName("jalr");
+
+ dGPR(_Rs_);
+
+ if ((_Rd_) != Rra) {
+ sep; dGPR(_Rd_);
+ }
+
+ Invalidate(_Rd_);
+
+ d->Comment("Jump and link register (function call)");
+)
+
+/*********************************************************
+* Load and store for GPR *
+* Format: OP rt, offset(base) *
+*********************************************************/
+MakeDisF(disLB,
+ int width = 8;
+ dName("lb");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+
+ Invalidate(_Rt_);
+ d->Comment("Load signed byte");
+)
+
+MakeDisF(disLBU,
+ int width = 8;
+ dName("lbu");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+
+ Invalidate(_Rt_);
+ d->Comment("Load unsigned byte");
+)
+
+MakeDisF(disLH,
+ int width = 16;
+ dName("lh");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+
+ Invalidate(_Rt_);
+ d->Comment("Load signed half");
+)
+
+MakeDisF(disLHU,
+ int width = 16;
+ dName("lhu");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+
+ Invalidate(_Rt_);
+ d->Comment("Load unsigned half");
+)
+
+MakeDisF(disLW,
+ int width = 32;
+ dName("lw");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+
+ Invalidate(_Rt_);
+ d->Comment("Load word");
+)
+
+MakeDisF(disLWL,
+ int width = 32;
+ dName("lwl");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+
+ Invalidate(_Rt_);
+ d->Comment("Load word left");
+)
+
+MakeDisF(disLWR,
+ int width = 32;
+ dName("lwr");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+
+ Invalidate(_Rt_);
+ d->Comment("Load word right");
+)
+
+MakeDisF(disLWC2,
+ int width = 32;
+ dName("lwc2");
+
+ dCP0(_Rt_); sep;
+ dOfB();
+)
+
+MakeDisF(disSB,
+ int width = 8;
+ dName("sb");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+ d->Comment("Store byte");
+)
+
+MakeDisF(disSH,
+ int width = 16;
+ dName("sh");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+ d->Comment("Store half");
+)
+
+MakeDisF(disSW,
+ int width = 32;
+ dName("sw");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+ d->Comment("Store word");
+)
+
+MakeDisF(disSWL,
+ int width = 32;
+ dName("swl");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+ d->Comment("Store word left");
+)
+
+MakeDisF(disSWR,
+ int width = 32;
+ dName("swr");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+ d->Comment("Store word right");
+)
+
+MakeDisF(disSWC2,
+ int width = 32;
+ dName("swc2");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+)
+
+/*********************************************************
+* Moves between GPR and COPx *
+* Format: OP rt, fs *
+*********************************************************/
+MakeDisF(disMFC0, dName("mfc0"); dGPR(_Rt_); sep; dCP0(_Rd_); Invalidate(_Rt_);)
+MakeDisF(disMTC0, dName("mtc0"); dCP0(_Rd_); sep; dGPR(_Rt_);)
+MakeDisF(disCFC0, dName("cfc0"); dGPR(_Rt_); sep; dCP0(_Rd_); Invalidate(_Rt_);)
+MakeDisF(disCTC0, dName("ctc0"); dCP0(_Rd_); sep; dGPR(_Rt_);)
+
+/*********************************************************
+* Unknow instruction (would generate an exception) *
+* Format: ? *
+*********************************************************/
+MakeDisF(disNULL,
+ dName("*** Bad OP ***");
+ dInvalid();
+)
+
+
+TdisR3000AF disR3000A_SPECIAL[] = { // Subset of disSPECIAL
+ disSLL , disNULL , disSRL , disSRA , disSLLV , disNULL , disSRLV , disSRAV ,
+ disJR , disJALR , disNULL, disNULL, disSYSCALL, disBREAK , disNULL , disNULL ,
+ disMFHI, disMTHI , disMFLO, disMTLO, disNULL , disNULL , disNULL , disNULL ,
+ disMULT, disMULTU, disDIV , disDIVU, disNULL , disNULL , disNULL , disNULL ,
+ disADD , disADDU , disSUB , disSUBU, disAND , disOR , disXOR , disNOR ,
+ disNULL, disNULL , disSLT , disSLTU, disNULL , disNULL , disNULL , disNULL ,
+ disNULL, disNULL , disNULL, disNULL, disNULL , disNULL , disNULL , disNULL ,
+ disNULL, disNULL , disNULL, disNULL, disNULL , disNULL , disNULL , disNULL};
+
+MakeDisF(disSPECIAL, disR3000A_SPECIAL[_Funct_](d, code, pc))
+
+TdisR3000AF disR3000A_BCOND[] = { // Subset of disBCOND
+ disBLTZ , disBGEZ , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disNULL , disNULL , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disBLTZAL, disBGEZAL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disNULL , disNULL , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
+
+MakeDisF(disBCOND, disR3000A_BCOND[_Rt_](d, code, pc))
+
+TdisR3000AF disR3000A_COP0[] = { // Subset of disCOP0
+ disMFC0, disNULL, disCFC0, disNULL, disMTC0, disNULL, disCTC0, disNULL,
+ disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disRFE , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
+
+MakeDisF(disCOP0, disR3000A_COP0[_Rs_](d, code, pc))
+
+TdisR3000AF disR3000A_BASIC[] = { // Subset of disBASIC (based on rs)
+ disMFC2, disNULL, disCFC2, disNULL, disMTC2, disNULL, disCTC2, disNULL,
+ disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
+
+MakeDisF(disBASIC, disR3000A_BASIC[_Rs_](d, code, pc))
+
+TdisR3000AF disR3000A_COP2[] = { // Subset of disR3000F_COP2 (based on funct)
+ disBASIC, disRTPS , disNULL , disNULL , disNULL, disNULL , disNCLIP, disNULL,
+ disNULL , disNULL , disNULL , disNULL , disOP , disNULL , disNULL , disNULL,
+ disDPCS , disINTPL, disMVMVA, disNCDS , disCDP , disNULL , disNCDT , disNULL,
+ disNULL , disNULL , disNULL , disNCCS , disCC , disNULL , disNCS , disNULL,
+ disNCT , disNULL , disNULL , disNULL , disNULL, disNULL , disNULL , disNULL,
+ disSQR , disDCPL , disDPCT , disNULL , disNULL, disAVSZ3, disAVSZ4, disNULL,
+ disRTPT , disNULL , disNULL , disNULL , disNULL, disNULL , disNULL , disNULL,
+ disNULL , disNULL , disNULL , disNULL , disNULL, disGPF , disGPL , disNCCT };
+
+MakeDisF(disCOP2, disR3000A_COP2[_Funct_](d, code, pc))
+
+TdisR3000AF disR3000A[] = {
+ disSPECIAL , disBCOND , disJ , disJAL , disBEQ , disBNE , disBLEZ , disBGTZ ,
+ disADDI , disADDIU , disSLTI , disSLTIU, disANDI, disORI , disXORI , disLUI ,
+ disCOP0 , disNULL , disCOP2 , disNULL , disNULL, disNULL, disNULL , disNULL ,
+ disNULL , disNULL , disNULL , disNULL , disNULL, disNULL, disNULL , disNULL ,
+ disLB , disLH , disLWL , disLW , disLBU , disLHU , disLWR , disNULL ,
+ disSB , disSH , disSWL , disSW , disNULL, disNULL, disSWR , disNULL ,
+ disNULL , disNULL , disLWC2 , disNULL , disNULL, disNULL, disNULL , disNULL ,
+ disNULL , disNULL , disSWC2 , disHLE , disNULL, disNULL, disNULL , disNULL };
+
+//MakeDisFg(disR3000AF, disR3000A[code >> 26](code, pc))
+
+void decode(TDis * d, Uint32 pc) {
+ Uint32 code = d->getmem()->Read32(pc);
+ disR3000A[code >> 26](d, code, pc);
+}
diff --git a/lib/mipsdis.cpp b/lib/mipsdis.cpp
index bb6364c..ce63623 100644
--- a/lib/mipsdis.cpp
+++ b/lib/mipsdis.cpp
@@ -1,180 +1,180 @@
-/*
- * 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: mipsdis.cpp,v 1.3 2004-11-27 21:44:48 pixel Exp $ */
-
-#include "mipsdis.h"
-#include "mips.h"
-
-TDis::TDis(mipsmem * _m) : mm(_m) {
- reset();
-}
-
-void TDis::reset() {
- invalid = false;
-}
-
-mipsmem * TDis::getmem() {
- return mm;
-}
-
-void TDis::add_branch(Uint32 target) {
- bheap.push(target);
-}
-
-void TDis::add_jump(Uint32 target) {
- jheap.push(target);
-}
-
-void TDis::add_function(Uint32 target) {
- fheap.push(target);
-}
-
-void TDis::SetTag(Uint32 target, int tag, bool v) {
- mm->SetTag(target, tag, v);
-}
-
-void TDis::Name(const String & name) {
-}
-
-void TDis::PushGPReg(int reg) {
-}
-
-void TDis::PushCPReg(int reg) {
-}
-
-void TDis::PushImm(Uint32 imm) {
-}
-
-void TDis::PushTarget(Uint32 target) {
- new refto_t(target, memdata::getmem(pc, getmem()));
-}
-
-void TDis::PushSa(Uint32 sa) {
-}
-
-void TDis::PushOfB(int reg, Uint32 offset, int width) {
-}
-
-void TDis::PushOffset(Uint32 offset) {
- new refto_t(offset, memdata::getmem(pc, getmem()));
-}
-
-void TDis::PushFull(Uint32 full) {
- if ((full >= 0x80000000) && (full < (0x80000000 + PSXMEM)))
- new refto_t(full, memdata::getmem(pc, getmem()));
-}
-
-void TDis::Invalid() {
- invalid = true;
-}
-
-void TDis::Suspect() {
-}
-
-void TDis::Comment(const String & c) {
-}
-
-Disassembler::Disassembler(mipsmem * _mm) : mm(_mm), dis(new TDis(mm)), started(false), infunction(false) {
-}
-
-Disassembler::~Disassembler() {
- delete dis;
-}
-
-void Disassembler::crawl_code(Uint32 pc) {
- Uint32 branched, ipc;
-
- if (pc == 0xffffffff) {
- pc = mm->GetPC();
- }
-
- dis->bheap.push(pc);
-
- while (dis->bheap.size()) {
- branched = pc = dis->bheap.top();
- dis->bheap.pop();
- printm(M_STATUS, "Crawling to branch %8.8lX\n", pc);
- do {
- if (pc >= (0x80000000 + PSXMEM)) {
- dis->invalid = true;
- break;
- }
- if (mm->GetTag(pc, CODE) || mm->GetTag(pc, INVALID)) {
- pc += 4;
- continue;
- }
- mm->SetTag(pc, CODE, true);
-
- printm(M_STATUS, "Working at %8.8lX\n", pc);
- decode(dis, pc);
-
- pc += 4;
- dis->reset();
- } while (!mm->GetTag(pc, STOP) && !dis->invalid);
-
- if (dis->invalid) {
- for (ipc = branched; ipc <= pc; ipc += 4) {
- mm->SetTag(ipc, CODE, false);
- mm->SetTag(ipc, INVALID, true);
- }
- }
-
- if (dis->invalid && infunction) {
- }
- }
-}
-
-void Disassembler::mainloop(void) {
- Uint32 pc;
-
- infunction = false;
-
- // Crawl the start part.
- printm(M_STATUS, "Starting crawl at %8.8lX\n", mm->GetPC());
- if (!started)
- crawl_code();
-
- started = true;
-
- // Work out all the functions.
- printm(M_STATUS, "Crawling all detected functions\n");
- infunction = true;
- while (dis->fheap.size()) {
- pc = dis->fheap.top();
- dis->fheap.pop();
- printm(M_STATUS, "Crawling function %8.8lX\n", pc);
- if (mm->GetTag(pc, CODE))
- continue;
- crawl_code(pc);
- }
-
- // Complete functions and all the detected jumps.
- printm(M_STATUS, "Fixing all the remaining jumps\n");
-#if 0
- infunction = false;
- while (dis->jheap.size()) {
- pc = dis->jheap.top();
- dis->jheap.pop();
- if (mm->GetTag(pc, CODE))
- continue;
- crawl_code(pc);
- }
-#endif
-}
+/*
+ * 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: mipsdis.cpp,v 1.4 2004-11-27 21:47:56 pixel Exp $ */
+
+#include "mipsdis.h"
+#include "mips.h"
+
+TDis::TDis(mipsmem * _m) : mm(_m) {
+ reset();
+}
+
+void TDis::reset() {
+ invalid = false;
+}
+
+mipsmem * TDis::getmem() {
+ return mm;
+}
+
+void TDis::add_branch(Uint32 target) {
+ bheap.push(target);
+}
+
+void TDis::add_jump(Uint32 target) {
+ jheap.push(target);
+}
+
+void TDis::add_function(Uint32 target) {
+ fheap.push(target);
+}
+
+void TDis::SetTag(Uint32 target, int tag, bool v) {
+ mm->SetTag(target, tag, v);
+}
+
+void TDis::Name(const String & name) {
+}
+
+void TDis::PushGPReg(int reg) {
+}
+
+void TDis::PushCPReg(int reg) {
+}
+
+void TDis::PushImm(Uint32 imm) {
+}
+
+void TDis::PushTarget(Uint32 target) {
+ new refto_t(target, memdata::getmem(pc, getmem()));
+}
+
+void TDis::PushSa(Uint32 sa) {
+}
+
+void TDis::PushOfB(int reg, Uint32 offset, int width) {
+}
+
+void TDis::PushOffset(Uint32 offset) {
+ new refto_t(offset, memdata::getmem(pc, getmem()));
+}
+
+void TDis::PushFull(Uint32 full) {
+ if ((full >= 0x80000000) && (full < (0x80000000 + PSXMEM)))
+ new refto_t(full, memdata::getmem(pc, getmem()));
+}
+
+void TDis::Invalid() {
+ invalid = true;
+}
+
+void TDis::Suspect() {
+}
+
+void TDis::Comment(const String & c) {
+}
+
+Disassembler::Disassembler(mipsmem * _mm) : mm(_mm), dis(new TDis(mm)), started(false), infunction(false) {
+}
+
+Disassembler::~Disassembler() {
+ delete dis;
+}
+
+void Disassembler::crawl_code(Uint32 pc) {
+ Uint32 branched, ipc;
+
+ if (pc == 0xffffffff) {
+ pc = mm->GetPC();
+ }
+
+ dis->bheap.push(pc);
+
+ while (dis->bheap.size()) {
+ branched = pc = dis->bheap.top();
+ dis->bheap.pop();
+ printm(M_STATUS, "Crawling to branch %8.8lX\n", pc);
+ do {
+ if (pc >= (0x80000000 + PSXMEM)) {
+ dis->invalid = true;
+ break;
+ }
+ if (mm->GetTag(pc, CODE) || mm->GetTag(pc, INVALID)) {
+ pc += 4;
+ continue;
+ }
+ mm->SetTag(pc, CODE, true);
+
+ printm(M_STATUS, "Working at %8.8lX\n", pc);
+ decode(dis, pc);
+
+ pc += 4;
+ dis->reset();
+ } while (!mm->GetTag(pc, STOP) && !dis->invalid);
+
+ if (dis->invalid) {
+ for (ipc = branched; ipc <= pc; ipc += 4) {
+ mm->SetTag(ipc, CODE, false);
+ mm->SetTag(ipc, INVALID, true);
+ }
+ }
+
+ if (dis->invalid && infunction) {
+ }
+ }
+}
+
+void Disassembler::mainloop(void) {
+ Uint32 pc;
+
+ infunction = false;
+
+ // Crawl the start part.
+ printm(M_STATUS, "Starting crawl at %8.8lX\n", mm->GetPC());
+ if (!started)
+ crawl_code();
+
+ started = true;
+
+ // Work out all the functions.
+ printm(M_STATUS, "Crawling all detected functions\n");
+ infunction = true;
+ while (dis->fheap.size()) {
+ pc = dis->fheap.top();
+ dis->fheap.pop();
+ printm(M_STATUS, "Crawling function %8.8lX\n", pc);
+ if (mm->GetTag(pc, CODE))
+ continue;
+ crawl_code(pc);
+ }
+
+ // Complete functions and all the detected jumps.
+ printm(M_STATUS, "Fixing all the remaining jumps\n");
+#if 0
+ infunction = false;
+ while (dis->jheap.size()) {
+ pc = dis->jheap.top();
+ dis->jheap.pop();
+ if (mm->GetTag(pc, CODE))
+ continue;
+ crawl_code(pc);
+ }
+#endif
+}
diff --git a/lib/mipsdump.cpp b/lib/mipsdump.cpp
index 1eb59f7..1e427e1 100644
--- a/lib/mipsdump.cpp
+++ b/lib/mipsdump.cpp
@@ -1,207 +1,207 @@
-/*
- * 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: mipsdump.cpp,v 1.2 2004-11-27 21:44:48 pixel Exp $ */
-
-#include "mipsdump.h"
-#include "mips.h"
-
-TDump::TDump(mipsmem * mm) : TDis(mm) {
- reset();
-}
-
-void TDump::reset() {
- invalid = false;
- hasbr = false;
- hastg = false;
- hasfc = false;
- name = "";
- comments = "";
- args.clear();
-}
-
-void TDump::add_branch(Uint32 _tg) {
- tg = _tg;
- hasbr = true;
-}
-
-void TDump::add_jump(Uint32 _tg) {
- tg = _tg;
- hastg = true;
-}
-
-void TDump::add_function(Uint32 _tg) {
- tg = _tg;
- hasfc = true;
-}
-
-void TDump::SetTag(Uint32 a, int t, bool v) {
-}
-
-void TDump::Name(const String & _name) {
- name = _name;
-}
-
-void TDump::PushGPReg(int r) {
- pairarg p;
-
- p.left = T_GPREGISTER;
- p.right.v = r;
-
- args.push_back(p);
-}
-
-void TDump::PushCPReg(int r) {
- pairarg p;
-
- p.left = T_CPREGISTER;
- p.right.v = r;
-
- args.push_back(p);
-}
-
-void TDump::PushImm(Uint32 imm) {
- pairarg p;
-
- p.left = T_IMM16;
- p.right.v = imm;
-
- args.push_back(p);
-}
-
-void TDump::PushTarget(Uint32 target) {
- pairarg p;
-
- p.left = T_IMM32;
- p.right.v = target;
-
- args.push_back(p);
-}
-
-void TDump::PushSa(Uint32 sa) {
- pairarg p;
-
- p.left = T_IMM8;
- p.right.v = sa;
-
- args.push_back(p);
-}
-
-void TDump::PushOfB(int reg, Uint32 offset, int width) {
- pairarg p;
-
- p.left = T_OFB;
- p.right.OfB.o = offset;
- p.right.OfB.r = reg;
- p.right.OfB.w = width;
-
- args.push_back(p);
-}
-
-void TDump::PushOffset(Uint32 offset) {
- pairarg p;
-
- p.left = T_IMM32;
- p.right.v = offset;
-
- args.push_back(p);
-}
-
-void TDump::PushFull(Uint32 full) {
- pairarg p;
-
- p.left = T_IMM32;
- p.right.v = full;
-
- args.push_back(p);
-}
-
-void TDump::Invalid() {
- invalid = true;
-}
-
-void TDump::Suspect() {
-}
-
-void TDump::Comment(const String & c) {
- comments = c;
-}
-
-Dumper::Dumper(mipsmem * _mm) : dump(new TDump(_mm)), mm(_mm) {
-}
-
-void Dumper::process() {
- Uint32 pc, code;
- memdata * mem;
-
- for (pc = 0x80000000; pc < (0x80000000 + PSXMEM); pc++) {
- if (mm->GetTag(pc, CODE)) {
- decode(dump, pc);
- code = mm->Read32(pc);
- printm(M_STATUS, "%8.8lX %8.8lX: " + dump->name + "\t", pc, code);
- for (std::vector<pairarg>::iterator i = dump->args.begin(); i != dump->args.end(); i++) {
- switch(i->left) {
- case T_GPREGISTER:
- printm(M_BARE, "$%s", registers[i->right.v]);
- break;
- case T_CPREGISTER:
- printm(M_BARE, "$%s", CP0registers[i->right.v]);
- break;
- case T_IMM8:
- printm(M_BARE, "0x%2.2lX", i->right.v);
- break;
- case T_IMM16:
- printm(M_BARE, "0x%4.4lX", i->right.v);
- break;
- case T_IMM32:
- printm(M_BARE, "0x%8.8lX", i->right.v);
- break;
- case T_OFB:
- printm(M_BARE, "0x%4.4lX($%s)", i->right.OfB.o, registers[i->right.OfB.r]);
- break;
- }
- if ((i + 1) != dump->args.end()) {
- printm(M_BARE, ", ");
- }
- }
- if (dump->comments != "") {
- printm(M_BARE, "\t; " + dump->comments);
- }
- printm(M_BARE, "\n");
- mem = mm->GetDatas(pc);
- if (mem) {
- reffrom_t * from;
- refto_t * to;
-
- from = mem->getreffrom();
- to = mem->getrefto();
-
- for (from = mem->getreffrom(); from; from = from->getnext()) {
- printm(M_STATUS, " Reference from 0x%8.8lX\n", from->getref()->getaddress());
- }
-
- if (to) {
- printm(M_STATUS, " Reference to 0x%8.8lX\n", to->getref()->getaddress());
- }
- }
- pc += 3;
- dump->reset();
- }
- }
-}
+/*
+ * 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: mipsdump.cpp,v 1.3 2004-11-27 21:47:56 pixel Exp $ */
+
+#include "mipsdump.h"
+#include "mips.h"
+
+TDump::TDump(mipsmem * mm) : TDis(mm) {
+ reset();
+}
+
+void TDump::reset() {
+ invalid = false;
+ hasbr = false;
+ hastg = false;
+ hasfc = false;
+ name = "";
+ comments = "";
+ args.clear();
+}
+
+void TDump::add_branch(Uint32 _tg) {
+ tg = _tg;
+ hasbr = true;
+}
+
+void TDump::add_jump(Uint32 _tg) {
+ tg = _tg;
+ hastg = true;
+}
+
+void TDump::add_function(Uint32 _tg) {
+ tg = _tg;
+ hasfc = true;
+}
+
+void TDump::SetTag(Uint32 a, int t, bool v) {
+}
+
+void TDump::Name(const String & _name) {
+ name = _name;
+}
+
+void TDump::PushGPReg(int r) {
+ pairarg p;
+
+ p.left = T_GPREGISTER;
+ p.right.v = r;
+
+ args.push_back(p);
+}
+
+void TDump::PushCPReg(int r) {
+ pairarg p;
+
+ p.left = T_CPREGISTER;
+ p.right.v = r;
+
+ args.push_back(p);
+}
+
+void TDump::PushImm(Uint32 imm) {
+ pairarg p;
+
+ p.left = T_IMM16;
+ p.right.v = imm;
+
+ args.push_back(p);
+}
+
+void TDump::PushTarget(Uint32 target) {
+ pairarg p;
+
+ p.left = T_IMM32;
+ p.right.v = target;
+
+ args.push_back(p);
+}
+
+void TDump::PushSa(Uint32 sa) {
+ pairarg p;
+
+ p.left = T_IMM8;
+ p.right.v = sa;
+
+ args.push_back(p);
+}
+
+void TDump::PushOfB(int reg, Uint32 offset, int width) {
+ pairarg p;
+
+ p.left = T_OFB;
+ p.right.OfB.o = offset;
+ p.right.OfB.r = reg;
+ p.right.OfB.w = width;
+
+ args.push_back(p);
+}
+
+void TDump::PushOffset(Uint32 offset) {
+ pairarg p;
+
+ p.left = T_IMM32;
+ p.right.v = offset;
+
+ args.push_back(p);
+}
+
+void TDump::PushFull(Uint32 full) {
+ pairarg p;
+
+ p.left = T_IMM32;
+ p.right.v = full;
+
+ args.push_back(p);
+}
+
+void TDump::Invalid() {
+ invalid = true;
+}
+
+void TDump::Suspect() {
+}
+
+void TDump::Comment(const String & c) {
+ comments = c;
+}
+
+Dumper::Dumper(mipsmem * _mm) : dump(new TDump(_mm)), mm(_mm) {
+}
+
+void Dumper::process() {
+ Uint32 pc, code;
+ memdata * mem;
+
+ for (pc = 0x80000000; pc < (0x80000000 + PSXMEM); pc++) {
+ if (mm->GetTag(pc, CODE)) {
+ decode(dump, pc);
+ code = mm->Read32(pc);
+ printm(M_STATUS, "%8.8lX %8.8lX: " + dump->name + "\t", pc, code);
+ for (std::vector<pairarg>::iterator i = dump->args.begin(); i != dump->args.end(); i++) {
+ switch(i->left) {
+ case T_GPREGISTER:
+ printm(M_BARE, "$%s", registers[i->right.v]);
+ break;
+ case T_CPREGISTER:
+ printm(M_BARE, "$%s", CP0registers[i->right.v]);
+ break;
+ case T_IMM8:
+ printm(M_BARE, "0x%2.2lX", i->right.v);
+ break;
+ case T_IMM16:
+ printm(M_BARE, "0x%4.4lX", i->right.v);
+ break;
+ case T_IMM32:
+ printm(M_BARE, "0x%8.8lX", i->right.v);
+ break;
+ case T_OFB:
+ printm(M_BARE, "0x%4.4lX($%s)", i->right.OfB.o, registers[i->right.OfB.r]);
+ break;
+ }
+ if ((i + 1) != dump->args.end()) {
+ printm(M_BARE, ", ");
+ }
+ }
+ if (dump->comments != "") {
+ printm(M_BARE, "\t; " + dump->comments);
+ }
+ printm(M_BARE, "\n");
+ mem = mm->GetDatas(pc);
+ if (mem) {
+ reffrom_t * from;
+ refto_t * to;
+
+ from = mem->getreffrom();
+ to = mem->getrefto();
+
+ for (from = mem->getreffrom(); from; from = from->getnext()) {
+ printm(M_STATUS, " Reference from 0x%8.8lX\n", from->getref()->getaddress());
+ }
+
+ if (to) {
+ printm(M_STATUS, " Reference to 0x%8.8lX\n", to->getref()->getaddress());
+ }
+ }
+ pc += 3;
+ dump->reset();
+ }
+ }
+}
diff --git a/lib/mipsmem.cpp b/lib/mipsmem.cpp
index 660c3fc..3f5bd71 100644
--- a/lib/mipsmem.cpp
+++ b/lib/mipsmem.cpp
@@ -1,349 +1,349 @@
-/*
- * 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: mipsmem.cpp,v 1.2 2004-11-27 21:44:48 pixel Exp $ */
-
-#include "mipsmem.h"
-
-refto_t::refto_t(Uint32 to, memdata * _m) : reffrom(new reffrom_t(this, _m->getmem(to))), mem(_m) {
- refto_t * t = mem->getrefto();
- if (t)
- delete t;
- mem->setrefto(this);
-}
-
-refto_t::~refto_t() {
- mem->setrefto(0);
- delete reffrom;
-}
-
-memdata * refto_t::getmem() {
- return mem;
-}
-
-memdata * refto_t::getref() {
- return reffrom->getmem();
-}
-
-reffrom_t::reffrom_t(refto_t * _refto, memdata * _m) : refto(_refto), header(_m) {
- next = header->getreffrom();
- prev = 0;
- header->setreffrom(this);
- if (next)
- next->prev = this;
-}
-
-reffrom_t::~reffrom_t() {
- if (next)
- next->prev = prev;
- if (prev)
- prev->next = next;
- else
- header->setreffrom(next);
-}
-
-memdata * reffrom_t::getmem() {
- return header;
-}
-
-memdata * reffrom_t::getref() {
- return refto->getmem();
-}
-
-reffrom_t * reffrom_t::getnext() {
- return next;
-}
-
-memdata::memdata(Uint32 _address, mipsmem * _mm) : address(_address), mm(_mm), func(0), refto(0), reffrom(0) {
- mm->SetDatas(address, this);
-}
-
-memdata::~memdata() {
- mm->SetDatas(address, 0);
-}
-
-Uint32 memdata::getaddress() {
- return address;
-}
-
-memdata * memdata::getmem(Uint32 addr) {
- return getmem(addr, mm);
-}
-
-memdata * memdata::getmem(Uint32 addr, mipsmem * mm) {
- memdata * t = mm->GetDatas(addr);
-
- if (!t) {
- t = new memdata(addr, mm);
- }
- return t;
-}
-
-func_t * memdata::getfunc() {
- return func;
-}
-
-refto_t * memdata::getrefto() {
- return refto;
-}
-
-reffrom_t * memdata::getreffrom() {
- return reffrom;
-}
-
-void memdata::setfunc(func_t * f) {
- func = f;
- checkdestroy();
-}
-
-void memdata::setrefto(refto_t * r) {
- refto = r;
- checkdestroy();
-}
-
-void memdata::setreffrom(reffrom_t * r) {
- reffrom = r;
- checkdestroy();
-}
-
-void memdata::checkdestroy() {
- if (!func && !refto && !reffrom) {
- delete this;
- }
-}
-
-
-mipsmem::mipsmem() {
- memset(psyqhead, 0, 0x800);
- memset(plainmemory, 0, PSXMEM);
- memset(patches, 0, PSXMEM);
- memset(patchesmap, 0, PSXMEM / 8);
- memset(tags, 0, PSXMEM);
- memset(datas, 0, PSXMEM * sizeof(memdata *));
-}
-
-Uint8 mipsmem::Read8(Uint32 mem) {
- if ((mem < 0x80000000) || (mem >= (0x80000000 + PSXMEM))) {
- printm(M_WARNING, "Reading at out of bound of memory: 0x%08x\n", mem);
- return 0xff;
- }
-
- mem -= 0x80000000;
-
- if (IsPatched(mem)) {
- return patches[mem];
- } else {
- return plainmemory[mem];
- }
-}
-
-Uint16 mipsmem::Read16(Uint32 mem) {
- Uint8 a, b;
-
- if (mem & 1) {
- printm(M_WARNING, "Read16 at a non 16-bits boundary: 0x%08x\n", mem);
- }
-
- a = Read8(mem);
- b = Read8(mem + 1);
-
- return a | (b << 8);
-}
-
-Uint32 mipsmem::Read32(Uint32 mem) {
- Uint8 a, b, c, d;
-
- if (mem & 3) {
- printm(M_WARNING, "Read32 at a non 32-bits boundary: 0x%08x\n", mem);
- }
-
- a = Read8(mem);
- b = Read8(mem + 1);
- c = Read8(mem + 2);
- d = Read8(mem + 3);
-
- return a | (b << 8) | (c << 16) | (d << 24);
-}
-
-void mipsmem::Write8(Uint32 mem, Uint8 value) {
- if ((mem < 0x80000000) || (mem > (0x80000000 + PSXMEM - 1))) {
- printm(M_WARNING, "Writing at out of bound of memory: 0x%08x\n", mem);
- return;
- }
-
- mem -= 0x80000000;
-
- patch(mem, 1);
- patches[mem] = value;
-}
-
-void mipsmem::Write16(Uint32 mem, Uint16 value) {
- if ((mem < 0x80000000) || (mem > (0x80000000 + PSXMEM - 2))) {
- printm(M_WARNING, "Writing at out of bound of memory: 0x%08x\n", mem);
- return;
- }
-
- mem -= 0x80000000;
-
- patch(mem, 2);
- patches[mem] = value & 0xff;
- patches[mem + 1] = (value >> 8) & 0xff;
-}
-
-void mipsmem::Write32(Uint32 mem, Uint32 value) {
- if ((mem < 0x80000000) || (mem > (0x80000000 + PSXMEM - 4))) {
- printm(M_WARNING, "Writing at out of bound of memory: 0x%08x\n", mem);
- return;
- }
-
- mem -= 0x80000000;
-
- patch(mem, 4);
- patches[mem] = value & 0xff;
- patches[mem + 1] = (value >> 8) & 0xff;
- patches[mem + 2] = (value >> 16) & 0xff;
- patches[mem + 3] = (value >> 24) & 0xff;
-}
-
-void mipsmem::unpatch8(Uint32 mem) {
- unpatch(mem, 1);
-}
-
-void mipsmem::unpatch16(Uint32 mem) {
- unpatch(mem, 2);
-}
-
-void mipsmem::unpatch32(Uint32 mem) {
- unpatch(mem, 4);
-}
-
-bool mipsmem::IsPatched(Uint32 mem) {
- int mask, pos;
-
- pos = mem / 8;
- mask = 1 << (mem % 8);
-
- return patchesmap[pos] & mask;
-}
-
-void mipsmem::LoadPSYQ(Handle * h) {
- h->read(psyqhead, 0x800);
- memset(plainmemory, 0, PSXMEM);
- paddr = ((psyq*)psyqhead)->t_addr;
- psize = ((psyq*)psyqhead)->t_size;
- startpc = ((psyq*)psyqhead)->pc0;
-
- printm(M_INFO, "Loading %i (%08x) bytes of data at %i (%08x).\n", psize, psize, paddr - 0x80000000, paddr);
-
- h->read(plainmemory + paddr - 0x80000000, psize);
-}
-
-void mipsmem::SavePSYQ(Handle * h) {\
- Uint32 i;
-
- if (!*((Uint32 *)psyqhead))
- return;
- h->write(psyqhead, 0x800);
- paddr = ((psyq*)psyqhead)->t_addr;
- psize = ((psyq*)psyqhead)->t_size;
-
- printm(M_INFO, "Writing %i (%08x) bytes of data from %i (%08x).\n", psize, psize, paddr - 0x80000000, paddr);
-
- for (i = paddr - 0x80000000; i < psize; i++) {
- h->writeU8(Read8(i));
- }
-}
-
-bool mipsmem::GetTag(Uint32 addr, char tag) {
- int mask;
-
- if ((addr < 0x80000000) || (addr >= (0x80000000 + PSXMEM))) {
- printm(M_WARNING, "Reading tag at out of bound of memory: 0x%08x\n", addr);
- return false;
- }
-
- mask = 1 << tag;
- addr -= 0x80000000;
-
- return tags[addr] & mask;
-}
-
-void mipsmem::SetTag(Uint32 addr, char tag, bool t) {
- int mask;
-
- if ((addr < 0x80000000) || (addr >= (0x80000000 + PSXMEM))) {
- printm(M_WARNING, "Setting tag at out of bound of memory: 0x%08x\n", addr);
- return;
- }
-
- mask = 1 << tag;
- addr -= 0x80000000;
-
- if (t) {
- tags[addr] |= mask;
- } else {
- tags[addr] &= ~mask;
- }
-}
-
-memdata * mipsmem::GetDatas(Uint32 addr) {
- return datas[addr];
-}
-
-void mipsmem::SetDatas(Uint32 addr, memdata * p) {
- datas[addr] = p;
-}
-
-Uint32 mipsmem::GetPC() {
- return startpc;
-}
-
-Uint32 mipsmem::GetLower() {
- return paddr;
-}
-
-Uint32 mipsmem::GetUpper() {
- return paddr + psize;
-}
-
-void mipsmem::patch(Uint32 mem, int size) {
- int mask, pos;
-
- pos = mem / 8;
- mask = 1 << (mem % 8);
-
- patchesmap[pos] |= mask;
-
- if (size != 1) {
- patch(mem + 1, size - 1);
- }
-}
-
-void mipsmem::unpatch(Uint32 mem, int size) {
- int mask, pos;
-
- pos = mem / 8;
- mask = ~(1 << (mem % 8));
-
- patchesmap[pos] &= mask;
-
- if (size != 1) {
- unpatch(mem + 1, size - 1);
- }
-}
+/*
+ * 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: mipsmem.cpp,v 1.3 2004-11-27 21:47:56 pixel Exp $ */
+
+#include "mipsmem.h"
+
+refto_t::refto_t(Uint32 to, memdata * _m) : reffrom(new reffrom_t(this, _m->getmem(to))), mem(_m) {
+ refto_t * t = mem->getrefto();
+ if (t)
+ delete t;
+ mem->setrefto(this);
+}
+
+refto_t::~refto_t() {
+ mem->setrefto(0);
+ delete reffrom;
+}
+
+memdata * refto_t::getmem() {
+ return mem;
+}
+
+memdata * refto_t::getref() {
+ return reffrom->getmem();
+}
+
+reffrom_t::reffrom_t(refto_t * _refto, memdata * _m) : refto(_refto), header(_m) {
+ next = header->getreffrom();
+ prev = 0;
+ header->setreffrom(this);
+ if (next)
+ next->prev = this;
+}
+
+reffrom_t::~reffrom_t() {
+ if (next)
+ next->prev = prev;
+ if (prev)
+ prev->next = next;
+ else
+ header->setreffrom(next);
+}
+
+memdata * reffrom_t::getmem() {
+ return header;
+}
+
+memdata * reffrom_t::getref() {
+ return refto->getmem();
+}
+
+reffrom_t * reffrom_t::getnext() {
+ return next;
+}
+
+memdata::memdata(Uint32 _address, mipsmem * _mm) : address(_address), mm(_mm), func(0), refto(0), reffrom(0) {
+ mm->SetDatas(address, this);
+}
+
+memdata::~memdata() {
+ mm->SetDatas(address, 0);
+}
+
+Uint32 memdata::getaddress() {
+ return address;
+}
+
+memdata * memdata::getmem(Uint32 addr) {
+ return getmem(addr, mm);
+}
+
+memdata * memdata::getmem(Uint32 addr, mipsmem * mm) {
+ memdata * t = mm->GetDatas(addr);
+
+ if (!t) {
+ t = new memdata(addr, mm);
+ }
+ return t;
+}
+
+func_t * memdata::getfunc() {
+ return func;
+}
+
+refto_t * memdata::getrefto() {
+ return refto;
+}
+
+reffrom_t * memdata::getreffrom() {
+ return reffrom;
+}
+
+void memdata::setfunc(func_t * f) {
+ func = f;
+ checkdestroy();
+}
+
+void memdata::setrefto(refto_t * r) {
+ refto = r;
+ checkdestroy();
+}
+
+void memdata::setreffrom(reffrom_t * r) {
+ reffrom = r;
+ checkdestroy();
+}
+
+void memdata::checkdestroy() {
+ if (!func && !refto && !reffrom) {
+ delete this;
+ }
+}
+
+
+mipsmem::mipsmem() {
+ memset(psyqhead, 0, 0x800);
+ memset(plainmemory, 0, PSXMEM);
+ memset(patches, 0, PSXMEM);
+ memset(patchesmap, 0, PSXMEM / 8);
+ memset(tags, 0, PSXMEM);
+ memset(datas, 0, PSXMEM * sizeof(memdata *));
+}
+
+Uint8 mipsmem::Read8(Uint32 mem) {
+ if ((mem < 0x80000000) || (mem >= (0x80000000 + PSXMEM))) {
+ printm(M_WARNING, "Reading at out of bound of memory: 0x%08x\n", mem);
+ return 0xff;
+ }
+
+ mem -= 0x80000000;
+
+ if (IsPatched(mem)) {
+ return patches[mem];
+ } else {
+ return plainmemory[mem];
+ }
+}
+
+Uint16 mipsmem::Read16(Uint32 mem) {
+ Uint8 a, b;
+
+ if (mem & 1) {
+ printm(M_WARNING, "Read16 at a non 16-bits boundary: 0x%08x\n", mem);
+ }
+
+ a = Read8(mem);
+ b = Read8(mem + 1);
+
+ return a | (b << 8);
+}
+
+Uint32 mipsmem::Read32(Uint32 mem) {
+ Uint8 a, b, c, d;
+
+ if (mem & 3) {
+ printm(M_WARNING, "Read32 at a non 32-bits boundary: 0x%08x\n", mem);
+ }
+
+ a = Read8(mem);
+ b = Read8(mem + 1);
+ c = Read8(mem + 2);
+ d = Read8(mem + 3);
+
+ return a | (b << 8) | (c << 16) | (d << 24);
+}
+
+void mipsmem::Write8(Uint32 mem, Uint8 value) {
+ if ((mem < 0x80000000) || (mem > (0x80000000 + PSXMEM - 1))) {
+ printm(M_WARNING, "Writing at out of bound of memory: 0x%08x\n", mem);
+ return;
+ }
+
+ mem -= 0x80000000;
+
+ patch(mem, 1);
+ patches[mem] = value;
+}
+
+void mipsmem::Write16(Uint32 mem, Uint16 value) {
+ if ((mem < 0x80000000) || (mem > (0x80000000 + PSXMEM - 2))) {
+ printm(M_WARNING, "Writing at out of bound of memory: 0x%08x\n", mem);
+ return;
+ }
+
+ mem -= 0x80000000;
+
+ patch(mem, 2);
+ patches[mem] = value & 0xff;
+ patches[mem + 1] = (value >> 8) & 0xff;
+}
+
+void mipsmem::Write32(Uint32 mem, Uint32 value) {
+ if ((mem < 0x80000000) || (mem > (0x80000000 + PSXMEM - 4))) {
+ printm(M_WARNING, "Writing at out of bound of memory: 0x%08x\n", mem);
+ return;
+ }
+
+ mem -= 0x80000000;
+
+ patch(mem, 4);
+ patches[mem] = value & 0xff;
+ patches[mem + 1] = (value >> 8) & 0xff;
+ patches[mem + 2] = (value >> 16) & 0xff;
+ patches[mem + 3] = (value >> 24) & 0xff;
+}
+
+void mipsmem::unpatch8(Uint32 mem) {
+ unpatch(mem, 1);
+}
+
+void mipsmem::unpatch16(Uint32 mem) {
+ unpatch(mem, 2);
+}
+
+void mipsmem::unpatch32(Uint32 mem) {
+ unpatch(mem, 4);
+}
+
+bool mipsmem::IsPatched(Uint32 mem) {
+ int mask, pos;
+
+ pos = mem / 8;
+ mask = 1 << (mem % 8);
+
+ return patchesmap[pos] & mask;
+}
+
+void mipsmem::LoadPSYQ(Handle * h) {
+ h->read(psyqhead, 0x800);
+ memset(plainmemory, 0, PSXMEM);
+ paddr = ((psyq*)psyqhead)->t_addr;
+ psize = ((psyq*)psyqhead)->t_size;
+ startpc = ((psyq*)psyqhead)->pc0;
+
+ printm(M_INFO, "Loading %i (%08x) bytes of data at %i (%08x).\n", psize, psize, paddr - 0x80000000, paddr);
+
+ h->read(plainmemory + paddr - 0x80000000, psize);
+}
+
+void mipsmem::SavePSYQ(Handle * h) {\
+ Uint32 i;
+
+ if (!*((Uint32 *)psyqhead))
+ return;
+ h->write(psyqhead, 0x800);
+ paddr = ((psyq*)psyqhead)->t_addr;
+ psize = ((psyq*)psyqhead)->t_size;
+
+ printm(M_INFO, "Writing %i (%08x) bytes of data from %i (%08x).\n", psize, psize, paddr - 0x80000000, paddr);
+
+ for (i = paddr - 0x80000000; i < psize; i++) {
+ h->writeU8(Read8(i));
+ }
+}
+
+bool mipsmem::GetTag(Uint32 addr, char tag) {
+ int mask;
+
+ if ((addr < 0x80000000) || (addr >= (0x80000000 + PSXMEM))) {
+ printm(M_WARNING, "Reading tag at out of bound of memory: 0x%08x\n", addr);
+ return false;
+ }
+
+ mask = 1 << tag;
+ addr -= 0x80000000;
+
+ return tags[addr] & mask;
+}
+
+void mipsmem::SetTag(Uint32 addr, char tag, bool t) {
+ int mask;
+
+ if ((addr < 0x80000000) || (addr >= (0x80000000 + PSXMEM))) {
+ printm(M_WARNING, "Setting tag at out of bound of memory: 0x%08x\n", addr);
+ return;
+ }
+
+ mask = 1 << tag;
+ addr -= 0x80000000;
+
+ if (t) {
+ tags[addr] |= mask;
+ } else {
+ tags[addr] &= ~mask;
+ }
+}
+
+memdata * mipsmem::GetDatas(Uint32 addr) {
+ return datas[addr];
+}
+
+void mipsmem::SetDatas(Uint32 addr, memdata * p) {
+ datas[addr] = p;
+}
+
+Uint32 mipsmem::GetPC() {
+ return startpc;
+}
+
+Uint32 mipsmem::GetLower() {
+ return paddr;
+}
+
+Uint32 mipsmem::GetUpper() {
+ return paddr + psize;
+}
+
+void mipsmem::patch(Uint32 mem, int size) {
+ int mask, pos;
+
+ pos = mem / 8;
+ mask = 1 << (mem % 8);
+
+ patchesmap[pos] |= mask;
+
+ if (size != 1) {
+ patch(mem + 1, size - 1);
+ }
+}
+
+void mipsmem::unpatch(Uint32 mem, int size) {
+ int mask, pos;
+
+ pos = mem / 8;
+ mask = ~(1 << (mem % 8));
+
+ patchesmap[pos] &= mask;
+
+ if (size != 1) {
+ unpatch(mem + 1, size - 1);
+ }
+}
diff --git a/lib/mipsobj.cpp b/lib/mipsobj.cpp
index 233c5c5..97663e6 100644
--- a/lib/mipsobj.cpp
+++ b/lib/mipsobj.cpp
@@ -1,269 +1,269 @@
-#include "mipsobj.h"
-
-section::section(const String & _name, int _type) : name(_name), type(_type), datas(0), length(0) { }
-section::section() : name(""), type(-1), datas(0), length(0) { }
-
-section::~section() {
- if (datas)
- free(datas);
-}
-
-void section::setname(const String & _name) {
- name = _name;
-}
-
-void section::settype(int _type) {
- type = _type;
-}
-
-void section::putdatas(const Uint8 * _datas, int _length) {
- if (type != BSS) {
- datas = (Uint8 *) realloc(datas, length + _length);
- memcpy(datas + length, _datas, _length);
- }
- length += _length;
-}
-
-int section::gettype() {
- return type;
-}
-
-int section::getsize() {
- return length;
-}
-
-const Uint8 * section::getdatas() {
- return datas;
-}
-
-void section::putreloc(const String & _symbol, int _type, Uint32 _offset) {
- struct reloc_t r;
-
- r.symbol = _symbol;
- r.type = _type;
- r.offset = _offset;
-
- putreloc(r);
-}
-
-void section::putreloc(const struct reloc_t & r) {
- relocs.push_back(r);
-}
-
-mipsobj::mipsobj() : loaded(false) { }
-
-mipsobj::~mipsobj() { }
-
-void loadELF(Handle * elf) throw (GeneralException) {
-}
-
-#define OBJSIG 0x024b4e4c
-
-#define READNAME(_str, _file) { \
- char _name[256]; \
- int _len; \
- \
- _len = _file->readU8(); \
- _file->read(_name, _len); \
- _name[_len] = 0; \
- _str = _name; \
-}
-
-void mipsobj::loadOBJ(Handle * obj) throw (GeneralException) {
- int cursec, len, reloctype, relocexpr, id;
- bool eof = false;
- std::map<int, String> secnames;
- std::map<int, String> symbolnames;
- Uint8 * datas;
- struct reloc_t reloc;
- struct symbol_t symbol;
- String name;
-
- while (!eof) {
- int entryid = obj->readU8();
-
- switch (entryid) {
- case 0x00:
- eof = true;
- break;
-
- case 0x02:
- len = obj->readU16();
- datas = (Uint8 *) malloc(len);
-
- obj->read(datas, len);
- sections[secnames[cursec]].putdatas(datas, len);
-
- free(datas);
- break;
-
- case 0x06:
- cursec = obj->readU16();
- break;
-
- case 0x08:
- len = obj->readU32();
-
- sections[secnames[cursec]].putdatas(0, len);
- break;
-
- case 0x0a:
- reloctype = obj->readU8();
- reloc.offset = obj->readU16();
-
- switch (reloctype) {
- case 0x10:
- reloc.type = R_MIPS_32;
- break;
- case 0x4a:
- reloc.type = R_MIPS_26;
- break;
- case 0x52:
- reloc.type = R_MIPS_HI16;
- break;
- case 0x54:
- reloc.type = R_MIPS_LO16;
- break;
- case 0x0a:
- case 0x26:
- case 0x28:
- case 0x64:
- printm(M_ERROR, "Relocation type %02x not supported.\n", reloctype);
- exit(-1);
- break;
- default:
- printm(M_ERROR, "Relocation type %02x UNKNOWN! Please send the object to the author.\n", reloctype);
- exit(-1);
- }
-
- relocexpr = obj->readU8();
-
- switch (relocexpr) {
- case 0x02:
- reloc.symbol = symbolnames[obj->readU16()];
- break;
- case 0x04:
- reloc.symbol = secnames[obj->readU16()];
- break;
- case 0x00:
- case 0x0c:
- case 0x16:
- case 0x2c:
- case 0x2e:
- case 0x30:
- case 0x32:
- case 0x36:
- printm(M_ERROR, "Relocation expression %02x not supported.\n", relocexpr);
- exit(-1);
- break;
- default:
- printm(M_ERROR, "Relocation expression %02x UNKNOWN! Please mail the author.\n", relocexpr);
- exit(-1);
- break;
- }
-
- sections[secnames[cursec]].relocs.push_back(reloc);
-
- break;
-
- case 0x0c:
- id = obj->readU16();
- symbol.section = obj->readU16();
- symbol.offset = obj->readU32();
- READNAME(symbol.name, obj);
- symbol.type = GLOBAL;
-
- symbolnames[id] = symbol.name;
-
- break;
-
- case 0x0e:
- id = obj->readU16();
- READNAME(symbol.name, obj);
- symbol.type = EXTERN;
-
- symbolnames[id] = symbol.name;
-
- break;
-
- case 0x10:
- id = obj->readU16();
- obj->readU8();
- obj->readU16();
- READNAME(name, obj);
-
- secnames[id] = name;
-
- break;
-
- case 0x12:
- printm(M_WARNING, "Local symbol not supported.\n");
- obj->readU16();
- obj->readU32();
- READNAME(name, obj);
- break;
-
- case 0x1c:
- printm(M_WARNING, "File number and name not supported.\n");
- obj->readU16();
- READNAME(name, obj);
- break;
-
- case 0x2e:
- if ((id = obj->readU8()) != 7) {
- printm(M_ERROR, "CPU type %i not supported.\n", id);
- exit(-1);
- }
- break;
-
- case 0x30:
- printm(M_ERROR, "Constant not supported.\n");
- exit(-1);
- break;
-
- default:
- printm(M_ERROR, "Object entry type %i UNKNOWN! Please send the object to the author.\n", entryid);
- exit(-1);
- break;
- }
- }
-}
-
-#define LIBSIG 0x0142494c
-
-void mipsobj::loadLIB(Handle * lib, const String & objname) throw (GeneralException) {
- char _name[9];
- String name;
- int hsize, size, ptr;
- bool found = false;
-
- lib->seek(0);
-
- if (lib->readU32() != LIBSIG) {
- throw GeneralException("Not a Psy-Q lib file");
- }
-
- while (lib->tell() != lib->GetSize()) {
- ptr = lib->tell();
-
- lib->read(_name, 8);
- name = _name;
- lib->seek(4, SEEK_CUR);
- hsize = lib->readU32();
- size = lib->readU32();
-
- if (objname == name.trim()) {
- lib->seek(ptr + hsize);
- found = true;
- break;
- }
-
- lib->seek(ptr + size);
- }
-
- if (!found) {
- throw GeneralException("Object `" + objname + "' not found in archive " + lib->GetName());
- }
-
- loadOBJ(lib);
-}
+#include "mipsobj.h"
+
+section::section(const String & _name, int _type) : name(_name), type(_type), datas(0), length(0) { }
+section::section() : name(""), type(-1), datas(0), length(0) { }
+
+section::~section() {
+ if (datas)
+ free(datas);
+}
+
+void section::setname(const String & _name) {
+ name = _name;
+}
+
+void section::settype(int _type) {
+ type = _type;
+}
+
+void section::putdatas(const Uint8 * _datas, int _length) {
+ if (type != BSS) {
+ datas = (Uint8 *) realloc(datas, length + _length);
+ memcpy(datas + length, _datas, _length);
+ }
+ length += _length;
+}
+
+int section::gettype() {
+ return type;
+}
+
+int section::getsize() {
+ return length;
+}
+
+const Uint8 * section::getdatas() {
+ return datas;
+}
+
+void section::putreloc(const String & _symbol, int _type, Uint32 _offset) {
+ struct reloc_t r;
+
+ r.symbol = _symbol;
+ r.type = _type;
+ r.offset = _offset;
+
+ putreloc(r);
+}
+
+void section::putreloc(const struct reloc_t & r) {
+ relocs.push_back(r);
+}
+
+mipsobj::mipsobj() : loaded(false) { }
+
+mipsobj::~mipsobj() { }
+
+void loadELF(Handle * elf) throw (GeneralException) {
+}
+
+#define OBJSIG 0x024b4e4c
+
+#define READNAME(_str, _file) { \
+ char _name[256]; \
+ int _len; \
+ \
+ _len = _file->readU8(); \
+ _file->read(_name, _len); \
+ _name[_len] = 0; \
+ _str = _name; \
+}
+
+void mipsobj::loadOBJ(Handle * obj) throw (GeneralException) {
+ int cursec, len, reloctype, relocexpr, id;
+ bool eof = false;
+ std::map<int, String> secnames;
+ std::map<int, String> symbolnames;
+ Uint8 * datas;
+ struct reloc_t reloc;
+ struct symbol_t symbol;
+ String name;
+
+ while (!eof) {
+ int entryid = obj->readU8();
+
+ switch (entryid) {
+ case 0x00:
+ eof = true;
+ break;
+
+ case 0x02:
+ len = obj->readU16();
+ datas = (Uint8 *) malloc(len);
+
+ obj->read(datas, len);
+ sections[secnames[cursec]].putdatas(datas, len);
+
+ free(datas);
+ break;
+
+ case 0x06:
+ cursec = obj->readU16();
+ break;
+
+ case 0x08:
+ len = obj->readU32();
+
+ sections[secnames[cursec]].putdatas(0, len);
+ break;
+
+ case 0x0a:
+ reloctype = obj->readU8();
+ reloc.offset = obj->readU16();
+
+ switch (reloctype) {
+ case 0x10:
+ reloc.type = R_MIPS_32;
+ break;
+ case 0x4a:
+ reloc.type = R_MIPS_26;
+ break;
+ case 0x52:
+ reloc.type = R_MIPS_HI16;
+ break;
+ case 0x54:
+ reloc.type = R_MIPS_LO16;
+ break;
+ case 0x0a:
+ case 0x26:
+ case 0x28:
+ case 0x64:
+ printm(M_ERROR, "Relocation type %02x not supported.\n", reloctype);
+ exit(-1);
+ break;
+ default:
+ printm(M_ERROR, "Relocation type %02x UNKNOWN! Please send the object to the author.\n", reloctype);
+ exit(-1);
+ }
+
+ relocexpr = obj->readU8();
+
+ switch (relocexpr) {
+ case 0x02:
+ reloc.symbol = symbolnames[obj->readU16()];
+ break;
+ case 0x04:
+ reloc.symbol = secnames[obj->readU16()];
+ break;
+ case 0x00:
+ case 0x0c:
+ case 0x16:
+ case 0x2c:
+ case 0x2e:
+ case 0x30:
+ case 0x32:
+ case 0x36:
+ printm(M_ERROR, "Relocation expression %02x not supported.\n", relocexpr);
+ exit(-1);
+ break;
+ default:
+ printm(M_ERROR, "Relocation expression %02x UNKNOWN! Please mail the author.\n", relocexpr);
+ exit(-1);
+ break;
+ }
+
+ sections[secnames[cursec]].relocs.push_back(reloc);
+
+ break;
+
+ case 0x0c:
+ id = obj->readU16();
+ symbol.section = obj->readU16();
+ symbol.offset = obj->readU32();
+ READNAME(symbol.name, obj);
+ symbol.type = GLOBAL;
+
+ symbolnames[id] = symbol.name;
+
+ break;
+
+ case 0x0e:
+ id = obj->readU16();
+ READNAME(symbol.name, obj);
+ symbol.type = EXTERN;
+
+ symbolnames[id] = symbol.name;
+
+ break;
+
+ case 0x10:
+ id = obj->readU16();
+ obj->readU8();
+ obj->readU16();
+ READNAME(name, obj);
+
+ secnames[id] = name;
+
+ break;
+
+ case 0x12:
+ printm(M_WARNING, "Local symbol not supported.\n");
+ obj->readU16();
+ obj->readU32();
+ READNAME(name, obj);
+ break;
+
+ case 0x1c:
+ printm(M_WARNING, "File number and name not supported.\n");
+ obj->readU16();
+ READNAME(name, obj);
+ break;
+
+ case 0x2e:
+ if ((id = obj->readU8()) != 7) {
+ printm(M_ERROR, "CPU type %i not supported.\n", id);
+ exit(-1);
+ }
+ break;
+
+ case 0x30:
+ printm(M_ERROR, "Constant not supported.\n");
+ exit(-1);
+ break;
+
+ default:
+ printm(M_ERROR, "Object entry type %i UNKNOWN! Please send the object to the author.\n", entryid);
+ exit(-1);
+ break;
+ }
+ }
+}
+
+#define LIBSIG 0x0142494c
+
+void mipsobj::loadLIB(Handle * lib, const String & objname) throw (GeneralException) {
+ char _name[9];
+ String name;
+ int hsize, size, ptr;
+ bool found = false;
+
+ lib->seek(0);
+
+ if (lib->readU32() != LIBSIG) {
+ throw GeneralException("Not a Psy-Q lib file");
+ }
+
+ while (lib->tell() != lib->GetSize()) {
+ ptr = lib->tell();
+
+ lib->read(_name, 8);
+ name = _name;
+ lib->seek(4, SEEK_CUR);
+ hsize = lib->readU32();
+ size = lib->readU32();
+
+ if (objname == name.trim()) {
+ lib->seek(ptr + hsize);
+ found = true;
+ break;
+ }
+
+ lib->seek(ptr + size);
+ }
+
+ if (!found) {
+ throw GeneralException("Object `" + objname + "' not found in archive " + lib->GetName());
+ }
+
+ loadOBJ(lib);
+}
diff --git a/lib/yazedc.cpp b/lib/yazedc.cpp
index 100cd38..c9ee1b2 100644
--- a/lib/yazedc.cpp
+++ b/lib/yazedc.cpp
@@ -1,273 +1,273 @@
-/*
- * PSX-Tools Bundle Pack
- * Copyright (C) 1998 Heiko Eissfeldt
- * portions used& Chris Smith
- * Modified by Yazoo, then by
- * 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: yazedc.cpp,v 1.4 2004-11-27 21:44:48 pixel Exp $ */
-
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "yazedc.h"
-
-yazedc::yazedc() : minute(0), second(2), frame(0), sectortype(0) {}
-
-/* ------------- tables generated by gen_encodes --------------*/
-
-#include "crctables"
-
-static int encode_L2_Q(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q])
-{
- unsigned char *Q;
- int i,j;
-
- Q = inout + 4 + L2_RAW + 4 + 8 + L2_P;
- memset(Q, 0, L2_Q);
- for (j = 0; j < 26; j++) {
- for (i = 0; i < 43; i++) {
- unsigned char data;
-
- /* LSB */
- data = inout[(j*43*2+i*2*44) % (4 + L2_RAW + 4 + 8 + L2_P)];
- if (data != 0) {
- unsigned int base = rs_l12_log[data];
-
- unsigned int sum = base + DQ[0][i];
- if (sum >= ((1 << RS_L12_BITS)-1))
- sum -= (1 << RS_L12_BITS)-1;
-
- Q[0] ^= rs_l12_alog[sum];
-
- sum = base + DQ[1][i];
- if (sum >= ((1 << RS_L12_BITS)-1))
- sum -= (1 << RS_L12_BITS)-1;
-
- Q[26*2] ^= rs_l12_alog[sum];
- }
- /* MSB */
- data = inout[(j*43*2+i*2*44+1) % (4 + L2_RAW + 4 + 8 + L2_P)];
- if (data != 0) {
- unsigned int base = rs_l12_log[data];
-
- unsigned int sum = base+DQ[0][i];
- if (sum >= ((1 << RS_L12_BITS)-1))
- sum -= (1 << RS_L12_BITS)-1;
-
- Q[1] ^= rs_l12_alog[sum];
-
- sum = base + DQ[1][i];
- if (sum >= ((1 << RS_L12_BITS)-1))
- sum -= (1 << RS_L12_BITS)-1;
-
- Q[26*2+1] ^= rs_l12_alog[sum];
- }
- }
- Q += 2;
- }
- return 0;
-}
-
-static int encode_L2_P(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P])
-{
- unsigned char *P;
- int i,j;
-
- P = inout + 4 + L2_RAW + 4 + 8;
- memset(P, 0, L2_P);
- for (j = 0; j < 43; j++) {
- for (i = 0; i < 24; i++) {
- unsigned char data;
-
- /* LSB */
- data = inout[i*2*43];
- if (data != 0) {
- unsigned int base = rs_l12_log[data];
-
- unsigned int sum = base + DP[0][i];
- if (sum >= ((1 << RS_L12_BITS)-1))
- sum -= (1 << RS_L12_BITS)-1;
-
- P[0] ^= rs_l12_alog[sum];
-
- sum = base + DP[1][i];
- if (sum >= ((1 << RS_L12_BITS)-1))
- sum -= (1 << RS_L12_BITS)-1;
-
- P[43*2] ^= rs_l12_alog[sum];
- }
- /* MSB */
- data = inout[i*2*43+1];
- if (data != 0) {
- unsigned int base = rs_l12_log[data];
-
- unsigned int sum = base + DP[0][i];
- if (sum >= ((1 << RS_L12_BITS)-1))
- sum -= (1 << RS_L12_BITS)-1;
-
- P[1] ^= rs_l12_alog[sum];
-
- sum = base + DP[1][i];
- if (sum >= ((1 << RS_L12_BITS)-1))
- sum -= (1 << RS_L12_BITS)-1;
-
- P[43*2+1] ^= rs_l12_alog[sum];
- }
- }
- P += 2;
- inout += 2;
- }
- return 0;
-}
-
-int yazedc::scramble_L2(unsigned char *inout)
-{
- unsigned char *r = inout + 12;
- const unsigned char *s = yellowbook_scrambler;
- unsigned int i;
- unsigned int *f = (unsigned int *)inout;
-
- for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof(unsigned char); i; i--) {
- *r++ ^= *s++;
- }
-
- /* generate F1 frames */
- for (i = (2352/sizeof(unsigned int)); i; i--) {
- *f++ = ((*f & 0xff00ff00UL) >> 8) | ((*f & 0x00ff00ffUL) << 8);
- }
-
- return 0;
-}
-
-int yazedc::build_address(unsigned char inout[], int sectortype, unsigned address)
-{
- inout[12] = minute;
- inout[13] = second;
- inout[14] = frame;
- if (sectortype == MODE_0)
- inout[15] = 0;
- else if (sectortype == MODE_1)
- inout[15] = 1;
- else if (sectortype == MODE_2)
- inout[15] = 2;
- else if (sectortype == MODE_2_FORM_1)
- inout[15] = 2;
- else if (sectortype == MODE_2_FORM_2)
- inout[15] = 2;
- else
- return -1;
- return 0;
-}
-
-#include "crctable.out"
-unsigned long int build_edc(unsigned char inout[], int from, int upto)
-{
- unsigned char *p = inout+from;
- unsigned long result = 0;
-
- for (; from <= upto; from++)
- result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
-
- return result;
-}
-
-/* Layer 2 Product code en/decoder */
-int yazedc::do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)], int sectortype, unsigned address)
-{
- unsigned long int result;
-
-#define SYNCPATTERN "\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
-
- /* supply initial sync pattern */
- memcpy(inout, SYNCPATTERN, sizeof(SYNCPATTERN));
-
- if (sectortype == MODE_0) {
- memset(inout + sizeof(SYNCPATTERN), 0, 4 + L2_RAW + 12 + L2_P + L2_Q);
- build_address(inout, sectortype, address);
- return 0;
- }
-
- switch (sectortype) {
- case MODE_1:
- build_address(inout, sectortype, address);
- result = build_edc(inout, 0, 16+2048-1);
- inout[2064+0] = result >> 0L;
- inout[2064+1] = result >> 8L;
- inout[2064+2] = result >> 16L;
- inout[2064+3] = result >> 24L;
- memset(inout+2064+4, 0, 8);
- encode_L2_P(inout+12);
- encode_L2_Q(inout+12);
- break;
- case MODE_2:
- build_address(inout, sectortype, address);
- break;
- case MODE_2_FORM_1:
- result = build_edc(inout, 16, 16+8+2048-1);
- inout[2072+0] = result >> 0L;
- inout[2072+1] = result >> 8L;
- inout[2072+2] = result >> 16L;
- inout[2072+3] = result >> 24L;
-
- /* clear header for P/Q parity calculation */
- inout[12] = 0;
- inout[12+1] = 0;
- inout[12+2] = 0;
- inout[12+3] = 0;
- encode_L2_P(inout+12);
- encode_L2_Q(inout+12);
- build_address(inout, sectortype, address);
- break;
- case MODE_2_FORM_2:
- build_address(inout, sectortype, address);
- result = build_edc(inout, 16, 16+8+2324-1);
- inout[2348+0] = result >> 0L;
- inout[2348+1] = result >> 8L;
- inout[2348+2] = result >> 16L;
- inout[2348+3] = result >> 24L;
- break;
- default:
- return -1;
- }
-
- return 0;
-}
-
-int yazedc::get_sector_type(void)
-{
- return sectortype;
-}
-
-int yazedc::set_sector_type(int st)
-{
- switch(st) {
- case MODE_0:
- case MODE_1:
- case MODE_2:
- case MODE_2_FORM_1:
- case MODE_2_FORM_2:
- sectortype = st;
- default:
- return -1;
- }
- return 0;
-}
+/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 1998 Heiko Eissfeldt
+ * portions used& Chris Smith
+ * Modified by Yazoo, then by
+ * 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: yazedc.cpp,v 1.5 2004-11-27 21:47:56 pixel Exp $ */
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "yazedc.h"
+
+yazedc::yazedc() : minute(0), second(2), frame(0), sectortype(0) {}
+
+/* ------------- tables generated by gen_encodes --------------*/
+
+#include "crctables"
+
+static int encode_L2_Q(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q])
+{
+ unsigned char *Q;
+ int i,j;
+
+ Q = inout + 4 + L2_RAW + 4 + 8 + L2_P;
+ memset(Q, 0, L2_Q);
+ for (j = 0; j < 26; j++) {
+ for (i = 0; i < 43; i++) {
+ unsigned char data;
+
+ /* LSB */
+ data = inout[(j*43*2+i*2*44) % (4 + L2_RAW + 4 + 8 + L2_P)];
+ if (data != 0) {
+ unsigned int base = rs_l12_log[data];
+
+ unsigned int sum = base + DQ[0][i];
+ if (sum >= ((1 << RS_L12_BITS)-1))
+ sum -= (1 << RS_L12_BITS)-1;
+
+ Q[0] ^= rs_l12_alog[sum];
+
+ sum = base + DQ[1][i];
+ if (sum >= ((1 << RS_L12_BITS)-1))
+ sum -= (1 << RS_L12_BITS)-1;
+
+ Q[26*2] ^= rs_l12_alog[sum];
+ }
+ /* MSB */
+ data = inout[(j*43*2+i*2*44+1) % (4 + L2_RAW + 4 + 8 + L2_P)];
+ if (data != 0) {
+ unsigned int base = rs_l12_log[data];
+
+ unsigned int sum = base+DQ[0][i];
+ if (sum >= ((1 << RS_L12_BITS)-1))
+ sum -= (1 << RS_L12_BITS)-1;
+
+ Q[1] ^= rs_l12_alog[sum];
+
+ sum = base + DQ[1][i];
+ if (sum >= ((1 << RS_L12_BITS)-1))
+ sum -= (1 << RS_L12_BITS)-1;
+
+ Q[26*2+1] ^= rs_l12_alog[sum];
+ }
+ }
+ Q += 2;
+ }
+ return 0;
+}
+
+static int encode_L2_P(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P])
+{
+ unsigned char *P;
+ int i,j;
+
+ P = inout + 4 + L2_RAW + 4 + 8;
+ memset(P, 0, L2_P);
+ for (j = 0; j < 43; j++) {
+ for (i = 0; i < 24; i++) {
+ unsigned char data;
+
+ /* LSB */
+ data = inout[i*2*43];
+ if (data != 0) {
+ unsigned int base = rs_l12_log[data];
+
+ unsigned int sum = base + DP[0][i];
+ if (sum >= ((1 << RS_L12_BITS)-1))
+ sum -= (1 << RS_L12_BITS)-1;
+
+ P[0] ^= rs_l12_alog[sum];
+
+ sum = base + DP[1][i];
+ if (sum >= ((1 << RS_L12_BITS)-1))
+ sum -= (1 << RS_L12_BITS)-1;
+
+ P[43*2] ^= rs_l12_alog[sum];
+ }
+ /* MSB */
+ data = inout[i*2*43+1];
+ if (data != 0) {
+ unsigned int base = rs_l12_log[data];
+
+ unsigned int sum = base + DP[0][i];
+ if (sum >= ((1 << RS_L12_BITS)-1))
+ sum -= (1 << RS_L12_BITS)-1;
+
+ P[1] ^= rs_l12_alog[sum];
+
+ sum = base + DP[1][i];
+ if (sum >= ((1 << RS_L12_BITS)-1))
+ sum -= (1 << RS_L12_BITS)-1;
+
+ P[43*2+1] ^= rs_l12_alog[sum];
+ }
+ }
+ P += 2;
+ inout += 2;
+ }
+ return 0;
+}
+
+int yazedc::scramble_L2(unsigned char *inout)
+{
+ unsigned char *r = inout + 12;
+ const unsigned char *s = yellowbook_scrambler;
+ unsigned int i;
+ unsigned int *f = (unsigned int *)inout;
+
+ for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof(unsigned char); i; i--) {
+ *r++ ^= *s++;
+ }
+
+ /* generate F1 frames */
+ for (i = (2352/sizeof(unsigned int)); i; i--) {
+ *f++ = ((*f & 0xff00ff00UL) >> 8) | ((*f & 0x00ff00ffUL) << 8);
+ }
+
+ return 0;
+}
+
+int yazedc::build_address(unsigned char inout[], int sectortype, unsigned address)
+{
+ inout[12] = minute;
+ inout[13] = second;
+ inout[14] = frame;
+ if (sectortype == MODE_0)
+ inout[15] = 0;
+ else if (sectortype == MODE_1)
+ inout[15] = 1;
+ else if (sectortype == MODE_2)
+ inout[15] = 2;
+ else if (sectortype == MODE_2_FORM_1)
+ inout[15] = 2;
+ else if (sectortype == MODE_2_FORM_2)
+ inout[15] = 2;
+ else
+ return -1;
+ return 0;
+}
+
+#include "crctable.out"
+unsigned long int build_edc(unsigned char inout[], int from, int upto)
+{
+ unsigned char *p = inout+from;
+ unsigned long result = 0;
+
+ for (; from <= upto; from++)
+ result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
+
+ return result;
+}
+
+/* Layer 2 Product code en/decoder */
+int yazedc::do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)], int sectortype, unsigned address)
+{
+ unsigned long int result;
+
+#define SYNCPATTERN "\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+
+ /* supply initial sync pattern */
+ memcpy(inout, SYNCPATTERN, sizeof(SYNCPATTERN));
+
+ if (sectortype == MODE_0) {
+ memset(inout + sizeof(SYNCPATTERN), 0, 4 + L2_RAW + 12 + L2_P + L2_Q);
+ build_address(inout, sectortype, address);
+ return 0;
+ }
+
+ switch (sectortype) {
+ case MODE_1:
+ build_address(inout, sectortype, address);
+ result = build_edc(inout, 0, 16+2048-1);
+ inout[2064+0] = result >> 0L;
+ inout[2064+1] = result >> 8L;
+ inout[2064+2] = result >> 16L;
+ inout[2064+3] = result >> 24L;
+ memset(inout+2064+4, 0, 8);
+ encode_L2_P(inout+12);
+ encode_L2_Q(inout+12);
+ break;
+ case MODE_2:
+ build_address(inout, sectortype, address);
+ break;
+ case MODE_2_FORM_1:
+ result = build_edc(inout, 16, 16+8+2048-1);
+ inout[2072+0] = result >> 0L;
+ inout[2072+1] = result >> 8L;
+ inout[2072+2] = result >> 16L;
+ inout[2072+3] = result >> 24L;
+
+ /* clear header for P/Q parity calculation */
+ inout[12] = 0;
+ inout[12+1] = 0;
+ inout[12+2] = 0;
+ inout[12+3] = 0;
+ encode_L2_P(inout+12);
+ encode_L2_Q(inout+12);
+ build_address(inout, sectortype, address);
+ break;
+ case MODE_2_FORM_2:
+ build_address(inout, sectortype, address);
+ result = build_edc(inout, 16, 16+8+2324-1);
+ inout[2348+0] = result >> 0L;
+ inout[2348+1] = result >> 8L;
+ inout[2348+2] = result >> 16L;
+ inout[2348+3] = result >> 24L;
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+int yazedc::get_sector_type(void)
+{
+ return sectortype;
+}
+
+int yazedc::set_sector_type(int st)
+{
+ switch(st) {
+ case MODE_0:
+ case MODE_1:
+ case MODE_2:
+ case MODE_2_FORM_1:
+ case MODE_2_FORM_2:
+ sectortype = st;
+ default:
+ return -1;
+ }
+ return 0;
+}