diff --git a/core/imgread/chd.cpp b/core/imgread/chd.cpp
index 7cf58017f..f2eb8ff18 100644
--- a/core/imgread/chd.cpp
+++ b/core/imgread/chd.cpp
@@ -141,7 +141,9 @@ bool CHDDisc::TryOpen(wchar* file)
if (total_frames!=549300 || tracks.size()<3)
{
printf("WARNING: chd: Total frames is wrong: %d frames in %d tracks\n",total_frames,tracks.size());
+#ifndef NOT_REICAST
msgboxf("This is an improper dump!",MBX_ICONEXCLAMATION);
+#endif
return false;
}
diff --git a/core/imgread/common.cpp b/core/imgread/common.cpp
index f1e130ad5..46980e1e8 100644
--- a/core/imgread/common.cpp
+++ b/core/imgread/common.cpp
@@ -25,8 +25,12 @@ u8 q_subchannel[96];
void PatchRegion_0(u8* sector,int size)
{
+#ifndef NOT_REICAST
if (settings.imgread.PatchRegion==0)
return;
+#else
+ return;
+#endif
u8* usersect=sector;
@@ -41,8 +45,12 @@ void PatchRegion_0(u8* sector,int size)
}
void PatchRegion_6(u8* sector,int size)
{
+#ifndef NOT_REICAST
if (settings.imgread.PatchRegion==0)
return;
+#else
+ return;
+#endif
u8* usersect=sector;
@@ -121,18 +129,29 @@ bool ConvertSector(u8* in_buff , u8* out_buff , int from , int to,int sector)
return true;
}
+Disc* OpenDisc(wchar* fn)
+{
+ Disc* rv;
+
+ for (int i=0;drivers[i] && !(rv=drivers[i](fn));i++) ;
+
+ return rv;
+}
+
bool InitDrive_(wchar* fn)
{
TermDrive();
//try all drivers
- for (int i=0;drivers[i] && !(disc=drivers[i](fn));i++) ;
+ disc = OpenDisc(fn);
if (disc!=0)
{
printf("gdrom: Opened image \"%s\"\n",fn);
NullDriveDiscType=Busy;
+#ifndef NOT_REICAST
libCore_gdrom_disc_change();
+#endif
// Sleep(400); //busy for a bit // what, really ?
return true;
}
@@ -144,6 +163,7 @@ bool InitDrive_(wchar* fn)
return false;
}
+#ifndef NOT_REICAST
bool InitDrive(u32 fileflags)
{
if (settings.imgread.LoadDefaultImage)
@@ -185,11 +205,11 @@ bool InitDrive(u32 fileflags)
if (!InitDrive_(fn))
{
//msgboxf("Selected image failed to load",MBX_ICONERROR);
- NullDriveDiscType=NoDisk;
- gd_setdisc();
- sns_asc=0x29;
- sns_ascq=0x00;
- sns_key=0x6;
+ NullDriveDiscType=NoDisk;
+ gd_setdisc();
+ sns_asc=0x29;
+ sns_ascq=0x00;
+ sns_key=0x6;
return true;
}
else
@@ -257,6 +277,7 @@ bool DiscSwap(u32 fileflags)
return true;
}
}
+#endif
void TermDrive()
{
diff --git a/core/imgread/common.h b/core/imgread/common.h
index aecdc4a17..fd55d4d50 100644
--- a/core/imgread/common.h
+++ b/core/imgread/common.h
@@ -240,7 +240,7 @@ struct Disc
{
u32 fmt=tracks[i].CTRL==4?2048:2352;
char fsto[1024];
- sprintf(fsto,"%s%s%d.img",path.c_str(),"track",i);
+ sprintf(fsto,"%s%s%d.img",path.c_str(),".track",i);
FILE* fo=fopen(fsto,"wb");
@@ -257,6 +257,8 @@ struct Disc
extern Disc* disc;
+Disc* OpenDisc(wchar* fn);
+
struct RawTrackFile : TrackFile
{
FILE* file;
diff --git a/gdtool/gdtool.sln b/gdtool/gdtool.sln
new file mode 100644
index 000000000..1a462d5df
--- /dev/null
+++ b/gdtool/gdtool.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gdtool", "gdtool.vcxproj", "{D56D49D9-3FA6-4463-8C96-925956E21FB0}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D56D49D9-3FA6-4463-8C96-925956E21FB0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D56D49D9-3FA6-4463-8C96-925956E21FB0}.Debug|Win32.Build.0 = Debug|Win32
+ {D56D49D9-3FA6-4463-8C96-925956E21FB0}.Release|Win32.ActiveCfg = Release|Win32
+ {D56D49D9-3FA6-4463-8C96-925956E21FB0}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/gdtool/gdtool.vcxproj b/gdtool/gdtool.vcxproj
new file mode 100644
index 000000000..f48b31941
--- /dev/null
+++ b/gdtool/gdtool.vcxproj
@@ -0,0 +1,140 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {D56D49D9-3FA6-4463-8C96-925956E21FB0}
+ gdtool
+
+
+
+ Application
+ true
+ MultiByte
+
+
+ Application
+ false
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Level3
+ Disabled
+ $(ProjectDir)..\core\;$(ProjectDir)..\core\deps\;$(ProjectDir)src\;%(AdditionalIncludeDirectories)
+ NOT_REICAST;%(PreprocessorDefinitions)
+
+
+ true
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ $(ProjectDir)..\core\;$(ProjectDir)..\core\deps\;$(ProjectDir)src\;%(AdditionalIncludeDirectories)
+ NOT_REICAST;%(PreprocessorDefinitions)
+
+
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/gdtool/gdtool.vcxproj.filters b/gdtool/gdtool.vcxproj.filters
new file mode 100644
index 000000000..4b1fafb3b
--- /dev/null
+++ b/gdtool/gdtool.vcxproj.filters
@@ -0,0 +1,225 @@
+
+
+
+
+ imgread
+
+
+ imgread
+
+
+ imgread
+
+
+ imgread
+
+
+ imgread
+
+
+ imgread
+
+
+ deps\chdpsr
+
+
+ deps\chdr
+
+
+ deps\libpng
+
+
+ deps\libpng
+
+
+ deps\libpng
+
+
+ deps\libpng
+
+
+ deps\libpng
+
+
+ deps\libpng
+
+
+ deps\libpng
+
+
+ deps\libpng
+
+
+ deps\libpng
+
+
+ deps\libpng
+
+
+ deps\libpng
+
+
+ deps\libpng
+
+
+ deps\libpng
+
+
+ deps\libpng
+
+
+ deps\libpng
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\crypto
+
+
+ deps\crypto
+
+
+ src
+
+
+ src
+
+
+
+
+ imgread
+
+
+ imgread
+
+
+ imgread
+
+
+ imgread
+
+
+ deps\chdpsr
+
+
+ deps\chdr
+
+
+ deps\chdr
+
+
+ deps\libpng
+
+
+ deps\libpng
+
+
+ deps\libpng
+
+
+ deps\libpng
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\zlib
+
+
+ deps\crypto
+
+
+ deps\crypto
+
+
+ src
+
+
+ src
+
+
+
+
+ {c4ea89a6-8345-4dfd-a0c0-13353b12ba06}
+
+
+ {03cf0701-ea11-401c-aed7-53fa207cc55f}
+
+
+ {c7643803-9308-49d9-a780-30671edc007c}
+
+
+ {bac3e17f-8d1c-4aca-99cc-5735b171ca60}
+
+
+ {d369171a-5aed-4b64-b4ed-f76525f508ad}
+
+
+ {51b1b4a5-1788-411d-b879-4ccd78be8a35}
+
+
+ {777115e4-4c86-4a7e-92e4-ebe90918e09e}
+
+
+ {a78ba9fb-70ba-4319-89e7-926abca0794c}
+
+
+
\ No newline at end of file
diff --git a/gdtool/gdtool.vcxproj.user b/gdtool/gdtool.vcxproj.user
new file mode 100644
index 000000000..b14130af6
--- /dev/null
+++ b/gdtool/gdtool.vcxproj.user
@@ -0,0 +1,7 @@
+
+
+
+ c:\ika.chd
+ WindowsLocalDebugger
+
+
\ No newline at end of file
diff --git a/gdtool/src/cdromfs.cpp b/gdtool/src/cdromfs.cpp
new file mode 100644
index 000000000..4c2d3f49f
--- /dev/null
+++ b/gdtool/src/cdromfs.cpp
@@ -0,0 +1,573 @@
+/*
+ hacked from http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/DDJ/1992/9212/9212i/9212i.htm
+ Is this bsd + adv license?
+
+*/
+
+#include "types.h"
+#include "cdromfs_imp.h"
+
+
+/* cdromcat -- A simple program to interpret the CDROM filesystem, and return.
+ * the contents of the file (directories are formatted and printed, files are
+ * returned untranslated). */
+
+#include
+#include
+#include
+#include
+#include "cdromfs.h"
+
+/* volume descriptor types -- type field of each descriptor */
+ #define VD_PRIMARY 1
+ #define VD_END 255
+
+ /* ISO 9660 primary descriptor */
+ #define ISODCL(from, to) (to - from + 1)
+
+ #define ISO_STANDARD_ID "CD001"
+
+ struct iso_primary_descriptor {
+ char type [ISODCL ( 1, 1)];
+ char id [ISODCL ( 2, 6)];
+ char version [ISODCL ( 7, 7)];
+ char reserved1 [ISODCL ( 8, 8)];
+ char system_id [ISODCL ( 9, 40)]; /* achars */
+ char volume_id [ISODCL ( 41, 72)]; /* dchars */
+ char reserved2 [ISODCL ( 73, 80)];
+ char volume_space_size [ISODCL ( 81, 88)];
+ char reserved3 [ISODCL ( 89, 120)];
+ char volume_set_size [ISODCL (121, 124)];
+ char volume_sequence_number [ISODCL (125, 128)];
+ char logical_block_size [ISODCL (129, 132)];
+ char path_table_size [ISODCL (133, 140)];
+ char type_1_path_table [ISODCL (141, 144)];
+ char opt_type_1_path_table [ISODCL (145, 148)];
+ char type_m_path_table [ISODCL (149, 152)];
+ char opt_type_m_path_table [ISODCL (153, 156)];
+ char root_directory_record [ISODCL (157, 190)];
+ char volume_set_id [ISODCL (191, 318)]; /* dchars */
+ char publisher_id [ISODCL (319, 446)]; /* achars */
+ char preparer_id [ISODCL (447, 574)]; /* achars */
+ char application_id [ISODCL (575, 702)]; /* achars */
+ char copyright_file_id [ISODCL (703, 739)]; /* dchars */
+ char abstract_file_id [ISODCL (740, 776)]; /* dchars */
+ char bibliographic_file_id [ISODCL (777, 813)]; /* dchars */
+ char creation_date [ISODCL (814, 830)];
+ char modification_date [ISODCL (831, 847)];
+ char expiration_date [ISODCL (848, 864)];
+ char effective_date [ISODCL (865, 881)];
+ char file_structure_version [ISODCL (882, 882)];
+ char reserved4 [ISODCL (883, 883)];
+ char application_data [ISODCL (884, 1395)];
+ char reserved5 [ISODCL (1396, 2048)];
+
+ };
+
+
+ /* High Sierra format primary descriptor */
+ #define HSFDCL(from, to) (to - from + 1)
+
+ #define HSF_STANDARD_ID "CDROM"
+
+ struct hsf_primary_descriptor {
+ char volume_lbn [HSFDCL ( 1, 8)];
+ char type [HSFDCL ( 9, 9)];
+ char id [HSFDCL ( 10, 14)];
+ char version [HSFDCL ( 15, 15)];
+ char reserved1 [HSFDCL ( 16, 16)];
+ char system_id [HSFDCL ( 17, 48)]; /* achars */
+ char volume_id [HSFDCL ( 49, 80)]; /* dchars */
+ char reserved2 [HSFDCL ( 81, 88)];
+ char volume_space_size [HSFDCL ( 89, 96)];
+ char reserved3 [HSFDCL ( 97, 128)];
+ char volume_set_size [HSFDCL (129, 132)];
+ char volume_sequence_number [HSFDCL (133, 136)];
+ char logical_block_size [HSFDCL (137, 140)];
+ char path_table_size [HSFDCL (141, 148)];
+ char manditory_path_table_lsb [HSFDCL (149, 152)];
+ char opt_path_table_lsb_1 [HSFDCL (153, 156)];
+ char opt_path_table_lsb_2 [HSFDCL (157, 160)];
+ char opt_path_table_lsb_3 [HSFDCL (161, 164)];
+ char manditory_path_table_msb [HSFDCL (165, 168)];
+ char opt_path_table_msb_1 [HSFDCL (169, 172)];
+ char opt_path_table_msb_2 [HSFDCL (173, 176)];
+ char opt_path_table_msb_3 [HSFDCL (177, 180)];
+ char root_directory_record [HSFDCL (181, 214)];
+ char volume_set_id [HSFDCL (215, 342)]; /* dchars */
+ char publisher_id [HSFDCL (343, 470)]; /* achars */
+ char preparer_id [HSFDCL (471, 598)]; /* achars */
+ char application_id [HSFDCL (599, 726)]; /* achars */
+ char copyright_file_id [HSFDCL (727, 758)]; /* dchars */
+ char abstract_file_id [HSFDCL (759, 790)]; /* dchars */
+ char creation_date [HSFDCL (791, 806)];
+ char modification_date [HSFDCL (807, 822)];
+ char expiration_date [HSFDCL (823, 838)];
+ char effective_date [HSFDCL (839, 854)];
+ char file_structure_version [HSFDCL (855, 855)];
+ char reserved4 [HSFDCL (856, 856)];
+ char application_data [HSFDCL (857, 1368)];
+ char reserved5 [HSFDCL (1369, 2048)];
+ };
+
+ /* CDROM file system directory entries */
+
+ /* file flags: */
+ #define CD_VISABLE 0x01 /* file name is hidden or visable to user */
+ #define CD_DIRECTORY 0x02 /* file is a directory and contains entries */
+ #define CD_ASSOCIATED 0x04/* file is opaque to filesystem, visable
+ to system implementation */
+ #define CD_EAHSFRECORD 0x04 /* file has HSF extended attribute record
+ fmt */
+ #define CD_PROTECTION 0x04 /* used extended attributes for protection */
+ #define CD_ANOTHEREXTNT 0x80 /* file has at least one more extent */
+
+ struct iso_directory_record {
+ char length [ISODCL (1, 1)];
+ char ext_attr_length [ISODCL (2, 2)];
+ char extent [ISODCL (3, 10)];
+ char size [ISODCL (11, 18)];
+ char date [ISODCL (19, 25)];
+ char flags [ISODCL (26, 26)];
+ char file_unit_size [ISODCL (27, 27)];
+ char interleave [ISODCL (28, 28)];
+ char volume_sequence_number [ISODCL (29, 32)];
+ char name_len [ISODCL (33, 33)];
+ /*char name [0];*/
+ char* name() { return (char*)this+sizeof(*this); }
+
+ };
+
+struct hsf_directory_record {
+
+ char length [HSFDCL (1, 1)];
+ char ext_attr_length [HSFDCL (2, 2)];
+ char extent [HSFDCL (3, 10)];
+ char size [HSFDCL (11, 18)];
+ char date [HSFDCL (19, 24)];
+ char flags [HSFDCL (25, 25)];
+ char reserved1 [HSFDCL (26, 26)];
+ char interleave_size [HSFDCL (27, 27)];
+ char interleave [HSFDCL (28, 28)];
+ char volume_sequence_number [HSFDCL (29, 32)];
+ char name_len [HSFDCL (33, 33)];
+ /*char name [0];*/
+ char* name() { return (char*)this+sizeof(*this); }
+};
+
+/* per filesystem information */
+struct fs {
+ char *name; /* kind of cdrom filesystem */
+ cdimage* fd; /* open file descriptor */
+ int lbs; /* logical block size */
+ int type; /* which flavor */
+};
+
+union fsdir {
+ struct iso_directory_record iso_dir;
+ struct hsf_directory_record hsf_dir;
+};
+
+/* filesystem directory entry */
+struct directent {
+ union {
+ struct iso_directory_record iso_dir;
+ struct hsf_directory_record hsf_dir;
+ } fsd;
+ /* actually, name contains name, reserved field, and extensions area */
+ char name[255 - sizeof(union fsdir)/*32*/];
+};
+
+/* filesystem volume descriptors */
+union voldesc {
+ struct iso_primary_descriptor iso_desc;
+ struct hsf_primary_descriptor hsf_desc;
+};
+
+char *iso_astring(char *, int len);
+char *cdrom_time(struct cdromtime *, int);
+void printdirent(struct directent *, struct fs *);
+void printdirents(struct directent *, struct fs *);
+void printdirentheader(char *p);
+int searchdirent(struct directent *, struct directent *, struct directent *,
+ struct fs *);
+ void extractdirent(struct directent *, struct fs *, data_callback* dcb, void* dcbctx);
+int lookup(struct directent *, struct directent *, char *, struct fs *);
+/* "fetch directory value" */
+#define FDV(b, f, t) (((t) == ISO) ? (b)->fsd.iso_dir.##f \
+ : (b)->fsd.hsf_dir.##f)
+/* "fetch primary descriptor value" */
+#define FPDV(b, f, t) (((t) == ISO) ? (b)->iso_desc.##f \
+ : (b)->hsf_desc.##f)
+
+/* ----------- Filesystem primatives ------------------- */
+/* Check for the presence of a cdrom filesystem. If present, pass back
+ * parameters for initialization, otherwise, pass back error. */
+int
+iscdromfs(struct directent *dp, struct fs *fs, int scan_from) {
+ char buffer[CDROM_LSECSZ];
+ union voldesc *vdp = (union voldesc *) buffer;
+ /* locate at the beginning of the descriptor table */
+ fs->fd->seek((scan_from + VD_LSN)*CDROM_LSECSZ);
+ /* walk descriptor table */
+ for(;;) {
+ unsigned char type;
+ /* obtain a descriptor */
+ fs->fd->read(buffer, sizeof(buffer));
+ /* determine ISO or HSF format of CDROM */
+ if (fs->type == 0) {
+ if (strncmp (vdp->iso_desc.id, ISO_STANDARD_ID,
+ sizeof(vdp->iso_desc.id)) == 0)
+ fs->type = ISO;
+ if (strncmp (vdp->hsf_desc.id, HSF_STANDARD_ID,
+ sizeof(vdp->hsf_desc.id)) == 0)
+ fs->type = HSF;
+ }
+ /* if determined, obtain root directory entry */
+ if (fs->type) {
+ type = ISO_BY(FPDV(vdp, type, fs->type));
+ if (type == VD_PRIMARY) {
+ memcpy (
+ dp,FPDV(vdp, root_directory_record, fs->type),
+ sizeof (union fsdir));
+ fs->lbs =
+ ISO_HWD(FPDV(vdp, logical_block_size, fs->type));
+ }
+ }
+ /* terminating volume */
+ if (type == VD_END)
+ break;
+ }
+ fs->name = cdromfmtnames[fs->type];
+ return (fs->type);
+}
+/* Obtain a "logical", i.e. relative to the directory entries beginning
+ * (or extent), block from the CDROM. */
+int
+getblkdirent(struct directent *dp, char *contents, long lbn, struct fs *fs) {
+ long filesize = ISO_WD(FDV(dp, size, fs->type)),
+ extent = ISO_WD(FDV(dp, extent, fs->type));
+ if (lbntob(fs, lbn) > roundup(filesize, fs->lbs))
+ return (0);
+ /* perform logical to physical translation */
+ (void) fs->fd->seek(lbntob(fs, extent + lbn));
+ /* obtain block */
+ return (fs->fd->read(contents, fs->lbs) == fs->lbs);
+}
+/* Search the contents of this directory entry, known to be a directory itself,
+ * looking for a component. If found, return directory entry associated with
+ * the component. */
+int
+searchdirent(struct directent *dp, struct directent *fdp,
+ struct directent *compdp, struct fs *fs) {
+ struct directent *ldp;
+ long filesize = ISO_WD(FDV(dp, size, fs->type)),
+ comp_namelen = ISO_BY(FDV(compdp, name_len, fs->type)),
+ lbn = 0, cnt;
+ char *buffer = (char *) malloc(fs->lbs);
+ while (getblkdirent(dp, buffer, lbn, fs)) {
+ cnt = filesize > fs->lbs ? fs->lbs : filesize;
+ filesize -= cnt;
+ ldp = (struct directent *) buffer;
+ /* have we a record to match? */
+ while (cnt > sizeof (union fsdir)) {
+ long entlen, namelen;
+ /* match against component's name and name length */
+ entlen = ISO_BY(FDV(ldp, length, fs->type));
+ namelen = ISO_BY(FDV(ldp, name_len, fs->type));
+ if (entlen >= comp_namelen + sizeof(union fsdir) && namelen == comp_namelen
+ && strncmp(FDV(ldp,name(),fs->type),
+ FDV(compdp,name(),fs->type), namelen) == 0) {
+ memcpy (fdp, ldp, entlen);
+ memcpy (compdp, ldp, entlen);
+ free(buffer);
+ return 1;
+ } else {
+ cnt -= entlen;
+ ldp = (struct directent *)
+ (((char *) ldp) + entlen);
+ }
+ }
+ if (filesize == 0) break;
+ lbn++;
+ }
+ free(buffer);
+ return 0;
+}
+/* Lookup the pathname by interpreting the directory structure of the CDROM
+ * element by element, returning a directory entry if found. Name translation
+ * occurs here, out of the null terminated path name string. This routine
+ * works by recursion. */
+int
+lookup(struct directent *dp, struct directent *fdp, char *pathname,
+ struct fs *fs) {
+ struct directent *ldp;
+ struct directent thiscomp;
+ char *nextcomp;
+ unsigned len;
+ /* break off the next component of the pathname */
+ if ((nextcomp = strrchr(pathname, '/')) == NULL)
+ nextcomp = strrchr(pathname, '\0');
+ /* construct an entry for this component to match */
+ ISO_BY(FDV(&thiscomp, name_len, fs->type)) = len = nextcomp - pathname;
+ memcpy(thiscomp.name, pathname, len);
+ /* attempt a match, returning component if found */
+ if (searchdirent(dp, fdp, &thiscomp, fs)){
+ /* if no more components, return found value */
+ if (*nextcomp == '\0')
+ return 1;
+ /* otherwise, if this component is a directory,
+ * recursively satisfy lookup */
+ else if (ISO_BY(FDV(dp, flags, fs->type)) & CD_DIRECTORY)
+ return (lookup(&thiscomp, fdp, nextcomp + 1, fs));
+ }
+ /* if no match return fail */
+ else
+ return(0);
+}
+/* --------------- object output routines for application ------------ */
+/* Extract the entire contents of a directory entry and write this on
+ * standard output. */
+void
+extractdirent(struct directent *dp, struct fs *fs, data_callback* dcb, void* dcbctx) {
+ long filesize = ISO_WD(FDV(dp, size, fs->type)),
+ lbn = 0, cnt;
+ char *buffer = (char *) malloc(fs->lbs);
+ /* iterate over all contents of the directory entry */
+ while (getblkdirent(dp, buffer, lbn, fs)) {
+ /* write out the valid portion of this logical block */
+ cnt = filesize > fs->lbs ? fs->lbs : filesize;
+ dcb(dcbctx, buffer, cnt);
+ /* next one? */
+ lbn++;
+ filesize -= cnt;
+ if (filesize == 0) break;
+ }
+ free(buffer);
+}
+/* Print directory header */
+void
+printdirentheader(char *path) {
+ printf("Directory(%s):\n", path);
+ printf("Flags:\tsize date sysa name\n");
+}
+/* Print all entries in the directory. */
+void
+printdirents(struct directent *dp, struct fs *fs) {
+ struct directent *ldp;
+ long filesize = ISO_WD(FDV(dp, size, fs->type)),
+ lbn = 0, cnt;
+ char *buffer = (char *) malloc(fs->lbs);
+ while (getblkdirent(dp, buffer, lbn, fs)) {
+ long entlen, namelen;
+ cnt = filesize > fs->lbs ? fs->lbs : filesize;
+ filesize -= cnt;
+ ldp = (struct directent *) buffer;
+ entlen = ISO_BY(FDV(ldp, length, fs->type));
+ namelen = ISO_BY(FDV(ldp, name_len, fs->type));
+ /* have we a record to match? */
+ while (cnt > sizeof (union fsdir) && entlen && namelen) {
+ printdirent(ldp, fs);
+ /* next entry? */
+ cnt -= entlen;
+ ldp = (struct directent *) (((char *) ldp) + entlen);
+ entlen = ISO_BY(FDV(ldp, length, fs->type));
+ namelen = ISO_BY(FDV(ldp, name_len, fs->type));
+ }
+ if (filesize == 0) break;
+ lbn++;
+ }
+ free(buffer);
+}
+
+/* print CDROM file modes */
+void prmodes(int f) {
+ int i;
+ for(i=0; i < 8; i++) {
+ if(CD_FLAGBITS[i] == ' ')
+ continue;
+ if(f & (1<type)));
+/* Note: this feature of HSF is not used because of lack of semantic def. */
+#ifdef whybother
+ extattlen = ISO_BY(FDV(dp, ext_attr_length, fs->type));
+ if (extattlen)
+ printf(" E%3d", extattlen);
+ else
+ printf(" ");
+#endif
+ /* size */
+ printf("\t%6d", ISO_WD(FDV(dp, size, fs->type)));
+ /* time */
+ printf(" %s",
+ cdrom_time((struct cdromtime *) FDV(dp, date, fs->type),fs->type));
+ /* compensate for reserved field used to word align directory entry */
+ entlen = ISO_BY(FDV(dp, length, fs->type));
+ name_len = ISO_BY(FDV(dp, name_len, fs->type));
+ enttaken = sizeof(union fsdir) + name_len;
+ if (enttaken & 1)
+ enttaken++;
+ fbname = ISO_BY(FDV(dp, name(), fs->type));
+ entlen -= enttaken;
+ /* print size of CDROM Extensions field if present */
+ if (entlen)
+ printf(" %3d", entlen);
+ else
+ printf(" ");
+ /* finally print name. compensate for unprintable names */
+ if (name_len == 1 && fbname <= 1) {
+ printf("\t%s\n", (fbname == 0) ? "." : "..");
+ } else
+ printf("\t%s\n",
+ iso_astring(FDV(dp, name(), fs->type), name_len));
+};
+/* attempt to print a CDROM file's creation time */
+char *
+cdrom_time(struct cdromtime *crt, int type) {
+ struct tm tm;
+ static char buf[32];
+ char *fmt;
+ /* step 1. convert into a ANSI C time description */
+ tm.tm_sec = min(crt->sec,60);
+ tm.tm_min = min(crt->min,60);
+ tm.tm_hour = min(crt->hour,23);
+ tm.tm_mday = min(crt->day, 31);
+ /* month starts with 1 */
+ tm.tm_mon = crt->month - 1;
+ tm.tm_year = crt->years;
+ tm.tm_isdst = 0;
+/* Note: not all ISO-9660 disks have correct timezone field */
+#ifdef whybother
+ /* ISO has time zone as 7th octet, HSF does not */
+ if (type == ISO) {
+ tm.tm_gmtoff = crt->tz*15*60;
+ tm.tm_zone = timezone(crt->tz*15, 0);
+ fmt = "%b %e %H:%M:%S %Z %Y";
+ } else
+#endif
+ fmt = "%b %d %H:%M:%S %Y";
+ /* step 2. use ANSI C standard function to format time properly */
+ (void)strftime(buf, sizeof(buf), fmt, &tm);
+ return (buf);
+}
+static char __strbuf[200];
+/* turn a blank padded character field into the null terminated strings
+ that POSIX/UNIX/WHATSIX likes so much */
+char *iso_astring(char *sp, int len) {
+ memcpy(__strbuf, sp, len);
+ __strbuf[len] = 0;
+ for (sp = __strbuf + len - 1; sp > __strbuf ; sp--)
+ if (*sp == ' ')
+ *sp = 0;
+ return(__strbuf);
+}
+
+
+
+
+
+#if 0
+
+
+
+/* user "application" program */
+int
+mainy(int argc, char *argv[])
+{
+ struct directent openfile;
+ char pathname[80];
+ /* open the CDROM device */
+ if ((fsd.fd = open("/dev/ras2d", 0)) < 0) {
+ perror("cdromcat");
+ exit(1);
+ }
+ /* is there a filesystem we can understand here? */
+ if (iscdromfs(&rootent, &fsd) == 0) {
+ fprintf(stderr, "cdromcat: %s\n", fsd.name);
+ exit(1);
+ }
+ /* print the contents of the root directory to give user a start */
+ printf("Root Directory Listing:\n");
+ printdirentheader("/");
+ printdirents(&rootent, &fsd);
+ /* print files on demand from user */
+ for(;;){
+ /* prompt user for name to locate */
+ printf("Pathname to open? : ");
+ fflush(stdout);
+ /* obtain, if none, exit, else trim newline off */
+ if (fgets(pathname, sizeof(pathname), stdin) == NULL)
+ exit(0);
+ pathname[strlen(pathname) - 1] = '\0';
+ if (strlen(pathname) == 0)
+ exit(0);
+ /* lookup filename on CDROM */
+ if (lookup(&rootent, &openfile, pathname, &fsd)){
+ /* if a directory, format and list it */
+ if (ISO_BY(FDV(&openfile, flags, fsd.type))
+ & CD_DIRECTORY) {
+ printdirentheader(pathname);
+ printdirents(&openfile, &fsd);
+ }
+ /* if a file, print it on standard output */
+ else
+ extractdirent(&openfile, &fsd, 0);
+ } else
+ printf("Not found.\n");
+ }
+ /* NOTREACHED */
+}
+
+#endif
+
+
+void find(directent* rootent, fs* fsd, char* pathname) {
+ struct directent openfile;
+
+ if (lookup(rootent, &openfile, pathname, fsd)) {
+ /* if a directory, format and list it */
+ if (ISO_BY(FDV(&openfile, flags, fsd->type)) & CD_DIRECTORY) {
+ printdirentheader(pathname);
+ printdirents(&openfile, fsd);
+ }
+ /* if a file, print it on standard output */
+ else
+ extractdirent(&openfile, fsd, 0, 0);
+ }
+ else
+ printf("Not found.\n");
+}
+
+
+void parse_cdfs(cdimage* cdio, int offs) {
+ //im
+ fs fsd;
+ directent rootent;
+
+ memset(&fsd, 0, sizeof(fsd));
+ memset(&rootent, 0, sizeof(rootent));
+
+ fsd.fd = cdio;
+
+
+ /* is there a filesystem we can understand here? */
+ if (iscdromfs(&rootent, &fsd, offs) ) {
+ /* print the contents of the root directory to give user a start */
+ printf("Root Directory Listing:\n");
+ printdirentheader("/");
+ printdirents(&rootent, &fsd);
+
+ }
+}
\ No newline at end of file
diff --git a/gdtool/src/cdromfs.h b/gdtool/src/cdromfs.h
new file mode 100644
index 000000000..6749a0531
--- /dev/null
+++ b/gdtool/src/cdromfs.h
@@ -0,0 +1,25 @@
+#pragma once
+
+struct cdromtime {
+ unsigned char years; /* number of years since 1900 */
+ unsigned char month; /* month of the year */
+ unsigned char day; /* day of month */
+ unsigned char hour; /* hour of day */
+ unsigned char min; /* minute of the hour */
+ unsigned char sec; /* second of the minute */
+ unsigned char tz; /* timezones, in quarter hour increments */
+ /* or, longitude in 3.75 of a degree */
+};
+
+
+typedef void data_callback(void* ctx, void* data, int size);
+
+struct cdimage {
+ virtual void seek(int to) = 0;
+
+ virtual int read(void* to, int count) = 0 ;
+ virtual ~cdimage() { }
+};
+
+
+void parse_cdfs(cdimage* cdio, int offs);
\ No newline at end of file
diff --git a/gdtool/src/cdromfs_imp.h b/gdtool/src/cdromfs_imp.h
new file mode 100644
index 000000000..d4f0b30fa
--- /dev/null
+++ b/gdtool/src/cdromfs_imp.h
@@ -0,0 +1,37 @@
+#pragma once
+#include "cdromfs.h"
+
+
+/* cdromfs.h: various definitions for CDROM filesystems. */
+
+#define VD_LSN 16 /* first logical sector of volume descriptor table */
+#define CDROM_LSECSZ 2048 /* initial logical sector size of a CDROM */
+
+#define HSF 1
+#define ISO 2
+
+char *cdromfmtnames[] = {
+ "unknown format",
+ "High Sierra",
+ "ISO - 9660"
+};
+char *voltypenames[] = {
+ "Boot Record",
+ "Standard File Structure",
+ "Coded Character Set File Structure",
+ "Unspecified File Structure",
+};
+/* rude translation routines for interpreting strings, words, halfwords */
+#define ISO_AS(s) (iso_astring(s, sizeof(s)))
+#define ISO_WD(s) (*(unsigned *)(s))
+#define ISO_HWD(s) (*(unsigned short *)(s))
+#define ISO_BY(s) (*(unsigned char *)(s))
+
+#define NVOLTYPENAMES (sizeof(voltypenames)/sizeof(char *))
+
+#define CD_FLAGBITS "vdaEp m" /* file flag bits */
+/* Handy macro's for block calculation */
+#define lbntob(fs, n) ((fs)->lbs * (n))
+#define btolbn(fs, n) ((fs)->lbs * (n))
+#define trunc_lbn(fs, n) ((n) - ((n) % (fs)->lbs)
+#define roundup(n, d) ((((n) + (d)) / (d)) * (d))
\ No newline at end of file
diff --git a/gdtool/src/main.cpp b/gdtool/src/main.cpp
new file mode 100644
index 000000000..3306a003f
--- /dev/null
+++ b/gdtool/src/main.cpp
@@ -0,0 +1,156 @@
+/*
+
+
+*/
+
+#include "types.h"
+#include "imgread/common.h"
+#include "cdromfs.h"
+
+int msgboxf(const wchar* text,unsigned int type,...) {
+ return MBX_OK;
+}
+
+
+void data_head() {
+ printf("---\nrv=\n");
+}
+
+void data_tail() {
+ printf("===\n");
+}
+
+void data_string(const char* s) {
+ data_head();
+ puts(s);
+ data_tail();
+}
+
+void data_kvp(const char* k, const char* v) {
+ printf("\t\"%s\":\"%s\",\n", k, v);
+}
+
+void parse_ip_meta(u8* ip_meta)
+{
+ char temp[256];
+
+ const char* chm = (const char*)ip_meta;
+
+ #define HH(ofs, len, name) { strncpy(temp, chm+ofs, len); temp[len]=0; for (int i=len-1; i>=0; i--) if(temp[i]==' ') temp[i]=0; else break; data_kvp(#name, temp); }
+
+ data_head();
+ printf("{\n");
+
+ data_kvp("type", "\"meta-info\"");
+
+ HH(0x00, 16, hardwareId);
+ HH(0x10, 16, makerId);
+
+ HH(0x80, 128, productName);
+ HH(0x4A, 6, productVersion);
+ HH(0x50, 16, releaseDate);
+ HH(0x40, 10, productId);
+ HH(0x20, 16, discId);
+
+
+ HH(0x30, 8, areas);
+ HH(0x38, 8, peripherals);
+
+ HH(0x60, 16, bootfile);
+ HH(0x70, 16, publisher);
+
+ printf("}\n");
+
+ data_tail();
+}
+
+
+struct gdio : cdimage {
+ Disc* disc;
+
+ int pos;
+ int offs;
+
+ void seek(int to) {
+ pos = to;
+ }
+
+ int read(void* to, int count) {
+ u8 tmp[2048];
+
+ verify(count != 0);
+ int rem = count;
+
+ while (rem >= 2048) {
+ disc->ReadSectors( (pos/2048) + offs, 1, tmp, 2048);
+
+ int toread = min(2048, rem) - pos%2048;
+
+ memcpy(to, &tmp[pos%2048], toread),
+
+ (char*&)to += rem;
+ pos += toread;
+ rem -= toread;
+ }
+
+ return count;
+ }
+
+ gdio(Disc* d) {
+ pos = 0;
+ offs = 150; //FAD vs LBN
+ disc = d;
+ }
+};
+
+
+int main(int argc, char** argv)
+{
+ for (int i=1; itype == GdRom) {
+ printf("This is a gdrom image\n");
+ start_fad = d->tracks[2].StartFAD;
+ }
+ else {
+ printf("This is a cdrom image\n");
+
+ if (d->sessions.size() < 2) {
+ printf("Not a selfboot cd\n");
+ //data_string("-2");
+ continue;
+ }
+ start_fad = d->sessions[1].StartFAD;
+ }
+
+ u8 ip_meta[2048];
+ d->ReadSectors(start_fad,1,ip_meta,2048);
+ //d->Dump(argv[1]);
+
+ parse_ip_meta(ip_meta);
+
+ //im
+ gdio* image = new gdio(d);
+
+
+ if (d->type == GdRom) {
+ parse_cdfs(image, d->tracks[0].StartFAD-image->offs);
+ }
+
+ parse_cdfs(image, start_fad-image->offs);
+
+ delete image;
+
+ delete d;
+ }
+}