summaryrefslogtreecommitdiffhomepage
path: root/Datafile
diff options
context:
space:
mode:
authorFWoltermann@gmail.com <FWoltermann@gmail.com@076cb2c4-205e-83fd-5cf3-1be9aa105544>2011-12-08 14:53:40 +0000
committerFWoltermann@gmail.com <FWoltermann@gmail.com@076cb2c4-205e-83fd-5cf3-1be9aa105544>2011-12-08 14:53:40 +0000
commite33e19d0587146859d48a134ec9fd94e7b7ba5cd (patch)
tree69d048c8801858d2756ab3a487090a7a1b74bf14 /Datafile
downloadstarshatter-e33e19d0587146859d48a134ec9fd94e7b7ba5cd.zip
starshatter-e33e19d0587146859d48a134ec9fd94e7b7ba5cd.tar.gz
starshatter-e33e19d0587146859d48a134ec9fd94e7b7ba5cd.tar.bz2
Initial upload
Diffstat (limited to 'Datafile')
-rw-r--r--Datafile/Archive.cpp460
-rw-r--r--Datafile/Archive.h83
-rw-r--r--Datafile/DataFile.dsp112
-rw-r--r--Datafile/DataFile.dsw29
-rw-r--r--Datafile/DataFile.mak231
-rw-r--r--Datafile/DataFile.mdpbin0 -> 34816 bytes
-rw-r--r--Datafile/Main.cpp453
7 files changed, 1368 insertions, 0 deletions
diff --git a/Datafile/Archive.cpp b/Datafile/Archive.cpp
new file mode 100644
index 0000000..d9f9088
--- /dev/null
+++ b/Datafile/Archive.cpp
@@ -0,0 +1,460 @@
+/* Project nGen
+ John DiCamillo Software Consulting
+ Copyright © 1997. All Rights Reserved.
+
+ SUBSYSTEM: DataFile.exe
+ FILE: Archive.cpp
+ AUTHOR: John DiCamillo
+
+*/
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <io.h>
+#include <stdio.h>
+#include <math.h>
+#include <time.h>
+#include <windows.h>
+#include <windowsx.h>
+
+#include "zlib.h"
+#include <mmsystem.h>
+#include "Archive.h"
+
+int verbose = 1;
+int err;
+
+#define CHECK_ERR(err, msg) { \
+ if (err != Z_OK) { \
+ fprintf(stderr, "%s error: %d\n", msg, err); \
+ exit(1); \
+ } \
+}
+
+// +--------------------------------------------------------------------+
+
+DataArchive::DataArchive(const char* name)
+{
+ ZeroMemory(this, sizeof(DataArchive));
+
+ if (name)
+ LoadDatafile(name);
+}
+
+DataArchive::~DataArchive()
+{
+ delete [] block_map;
+}
+
+// +--------------------------------------------------------------------+
+
+void DataArchive::WriteEntry(int index, BYTE* buf)
+{
+ int f = _open(datafile, _O_RDWR|_O_CREAT|_O_BINARY, _S_IREAD|_S_IWRITE);
+
+ if (f != -1) {
+ header.dir_size_comp = DirBlocks() * BLOCK_SIZE;
+ dirbuf = new BYTE[header.dir_size_comp];
+
+ err = compress(dirbuf, &header.dir_size_comp,
+ (BYTE*) directory, header.nfiles * sizeof(DataEntry));
+ CHECK_ERR(err, "compress");
+
+ header.dir_blocks = Blocks(header.dir_size_comp) * BLOCK_SIZE;
+
+ _lseek(f, 0, SEEK_SET);
+ _write(f, &header, sizeof(DataHeader));
+ _lseek(f, sizeof(DataHeader) + header.dir_offset, SEEK_SET);
+ _write(f, dirbuf, header.dir_blocks);
+
+ delete [] dirbuf;
+
+ if (buf && directory[index].size_comp) {
+ _lseek(f, sizeof(DataHeader) + directory[index].offset, SEEK_SET);
+ _write(f, buf, directory[index].size_comp);
+ }
+ _close(f);
+ }
+ else
+ perror("WriteEntry");
+}
+
+// +--------------------------------------------------------------------+
+
+DWORD DataArchive::Blocks(DWORD raw_size)
+{
+ int full_blocks = raw_size / BLOCK_SIZE;
+ int part_blocks = (raw_size % BLOCK_SIZE) > 0;
+
+ return full_blocks + part_blocks;
+}
+
+DWORD DataArchive::DirBlocks()
+{
+ DWORD result = Blocks(header.nfiles * sizeof(DataEntry));
+ if (result == 0) result = 1;
+ return result;
+}
+
+DWORD DataArchive::FileBlocks(int index)
+{
+ return Blocks(directory[index].size_comp);
+}
+
+// +--------------------------------------------------------------------+
+
+void DataArchive::CreateBlockMap()
+{
+ delete [] block_map;
+ block_map = 0;
+
+ if (header.nfiles == 0) return;
+
+ DWORD i,j;
+ DWORD dir_usage = header.dir_offset + DirBlocks() * BLOCK_SIZE;
+ DWORD max_usage = dir_usage;
+
+ for (i = 0; i < header.nfiles; i++) {
+ DWORD last_block = directory[i].offset + FileBlocks(i) * BLOCK_SIZE;
+ if (last_block > max_usage)
+ max_usage = last_block;
+ }
+
+ nblocks = max_usage/BLOCK_SIZE;
+ block_map = new DWORD[nblocks];
+ ZeroMemory(block_map, nblocks*sizeof(DWORD));
+
+ DWORD first_block = header.dir_offset/BLOCK_SIZE +
+ (header.dir_offset%BLOCK_SIZE > 0);
+
+ for (j = 0; j < DirBlocks(); j++)
+ block_map[first_block+j] = 1;
+
+ for (i = 0; i < header.nfiles; i++) {
+ DWORD first_block = directory[i].offset/BLOCK_SIZE +
+ (directory[i].offset%BLOCK_SIZE > 0);
+
+ for (j = 0; j < FileBlocks(i); j++)
+ block_map[first_block+j] = i+2;
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+int DataArchive::FindDataBlocks(int need)
+{
+ if ((int) (nblocks)-need > 0) {
+ DWORD start;
+ int i;
+
+ for (start = 0; start < nblocks-need; start++) {
+ for (i = 0; block_map[start+i] == 0 && i < need; i++);
+
+ if (i == need) return start*BLOCK_SIZE;
+
+ start += i;
+ }
+ }
+
+ return nblocks*BLOCK_SIZE;
+}
+
+// +--------------------------------------------------------------------+
+
+void DataArchive::LoadDatafile(const char* name)
+{
+ strncpy(datafile, name, NAMELEN-1);
+ header.nfiles = 0;
+
+ FILE* f = fopen(datafile, "rb");
+ if (f) {
+ fread(&header, sizeof(DataHeader), 1, f);
+
+ if (header.version != VERSION) {
+ printf("ERROR: datafile '%s' invalid version '%d'\n",
+ datafile, header.version);
+ fclose(f);
+ exit(-2);
+ }
+
+ DWORD len = DirBlocks() * BLOCK_SIZE;
+
+ dirbuf = new BYTE[len];
+ fseek(f, sizeof(DataHeader) + header.dir_offset, SEEK_SET);
+ fread(dirbuf, header.dir_size_comp, 1, f);
+
+ int err = uncompress((BYTE*) directory, &len,
+ dirbuf, header.dir_size_comp);
+ if (err != Z_OK)
+ ZeroMemory(directory, sizeof(directory));
+
+ delete [] dirbuf;
+ CreateBlockMap();
+ }
+ else {
+ printf("Creating Archive '%s'...\n", datafile);
+
+ header.version = VERSION;
+ header.nfiles = 0;
+ header.dir_blocks = 0;
+ header.dir_size_comp = 0;
+ header.dir_offset = 0;
+
+ nblocks = DirBlocks();
+
+ delete [] block_map;
+ block_map = 0;
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+int DataArchive::FindEntry(const char* req_name)
+{
+ int entry = -1;
+
+ for (DWORD i = 0; i < header.nfiles; i++)
+ if (!stricmp(directory[i].name, req_name))
+ return i;
+
+ return entry;
+}
+
+// +--------------------------------------------------------------------+
+
+BYTE* DataArchive::CompressEntry(int i)
+{
+ char* name = directory[i].name;
+
+ FILE* f = fopen(name, "rb");
+
+ if (f) {
+ fseek(f, 0, SEEK_END);
+ DWORD len = ftell(f);
+ fseek(f, 0, SEEK_SET);
+
+ BYTE* buf = new BYTE[len];
+
+ fread(buf, len, 1, f);
+ fclose(f);
+
+ directory[i].size_orig = len;
+
+ directory[i].size_comp = (int) (len * 1.1);
+ BYTE* cbuf = new BYTE[directory[i].size_comp];
+
+ err = compress(cbuf, &directory[i].size_comp, buf, len);
+ CHECK_ERR(err, "compress");
+
+ delete [] buf;
+ return cbuf;
+ }
+
+ return 0;
+}
+
+// +--------------------------------------------------------------------+
+
+int DataArchive::ExpandEntry(int i, BYTE*& buf)
+{
+ DWORD len = 0;
+
+ FILE* f = fopen(datafile, "rb");
+
+ if (f) {
+ DWORD clen = directory[i].size_comp;
+ BYTE* cbuf = new BYTE[clen];
+
+ fseek(f, sizeof(DataHeader) + directory[i].offset, SEEK_SET);
+ fread(cbuf, clen, 1, f);
+
+ len = directory[i].size_orig;
+ buf = new BYTE[len];
+
+ int err = uncompress(buf, &len, cbuf, clen);
+ if (err != Z_OK) {
+ delete [] buf;
+ buf = 0;
+ }
+
+ delete [] cbuf;
+ fclose(f);
+ }
+
+ return len;
+}
+
+// +--------------------------------------------------------------------+
+
+int DataArchive::InsertEntry(const char* name)
+{
+ if (!name) return -1;
+
+ DWORD len = strlen(name);
+
+ for (int i = 0; i < MAX_FILES; i++) {
+ if (directory[i].size_orig == 0) {
+ strncpy(directory[i].name, name, NAMELEN);
+ directory[i].name[NAMELEN-1] = '\0';
+ directory[i].size_orig = 1;
+
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+// +--------------------------------------------------------------------+
+
+void DataArchive::RemoveEntry(int index)
+{
+ ZeroMemory(&directory[index], sizeof(DataEntry));
+}
+
+// +--------------------------------------------------------------------+
+
+void DataArchive::Insert(const char* name)
+{
+ DWORD old_blocks = 0, old_offset = 0, new_blocks = 0;
+ DWORD old_dir_blocks = 0, old_dir_offset = 0, new_dir_blocks = 0;
+ int added = 0;
+
+ int index = FindEntry(name);
+
+ if (index < 0) {
+ old_dir_blocks = DirBlocks();
+ old_dir_offset = header.dir_offset;
+
+ index = InsertEntry(name);
+
+ if (index >= (int) header.nfiles) {
+ header.nfiles = index+1;
+ added = 1;
+ }
+
+ new_dir_blocks = DirBlocks();
+
+ if (new_dir_blocks > old_dir_blocks) {
+ header.dir_offset = FindDataBlocks(new_dir_blocks);
+ CreateBlockMap();
+ }
+ }
+ else {
+ old_blocks = FileBlocks(index);
+ old_offset = directory[index].offset;
+ }
+
+ if (index >= 0) {
+ DataEntry& e = directory[index];
+
+ if (verbose) printf(" Inserting: %-48s ", e.name);
+
+ BYTE* buf = CompressEntry(index);
+
+ if (!buf) {
+ // this is (almost) unrecoverable,
+ // so we quit before screwing things up:
+ printf("ERROR: Could not compress %d:%s\n", index, directory[index].name);
+ exit(1);
+ }
+
+ new_blocks = FileBlocks(index);
+
+ // the file is new, or got bigger,
+ // need to find room for the data:
+ if (new_blocks > old_blocks) {
+ directory[index].offset = FindDataBlocks(new_blocks);
+ CreateBlockMap();
+ }
+
+ WriteEntry(index, buf);
+ delete [] buf;
+
+ if (verbose) {
+ int ratio = (int) (100.0 * (double) e.size_comp / (double) e.size_orig);
+ printf("%9d => %9d (%2d%%)\n", e.size_orig, e.size_comp, ratio);
+ }
+ }
+ else if (added)
+ header.nfiles--;
+}
+
+// +--------------------------------------------------------------------+
+
+void DataArchive::Extract(const char* name)
+{
+ int index = FindEntry(name);
+
+ if (index < 0) {
+ printf("Could not extract '%s', not found\n", name);
+ return;
+ }
+
+ BYTE* buf;
+ ExpandEntry(index, buf);
+
+ FILE* f = fopen(directory[index].name, "wb");
+ if (f) {
+ fwrite(buf, directory[index].size_orig, 1, f);
+ fclose(f);
+ }
+ else
+ printf("Could not extract '%s', could not open file for writing\n", name);
+
+ delete [] buf;
+
+ if (verbose) printf(" Extracted: %s\n", name);
+}
+
+// +--------------------------------------------------------------------+
+
+void DataArchive::Remove(const char* name)
+{
+ int index = FindEntry(name);
+
+ if (index < 0) {
+ printf("Could not remove '%s', not found\n", name);
+ return;
+ }
+
+ RemoveEntry(index);
+ WriteEntry(index, 0);
+
+ if (verbose) printf(" Removed: %s\n", name);
+}
+
+// +--------------------------------------------------------------------+
+
+void DataArchive::List()
+{
+ int total_orig = 0;
+ int total_comp = 0;
+
+ printf("DATAFILE: %s\n", datafile);
+ printf("Files: %d\n", header.nfiles);
+ printf("\n");
+ printf("Index Orig Size Comp Size Ratio Name\n");
+ printf("----- --------- --------- ----- ----------------\n");
+
+ for (DWORD i = 0; i < header.nfiles; i++) {
+ DataEntry& e = directory[i];
+ int ratio = (int) (100.0 * (double) e.size_comp / (double) e.size_orig);
+
+ printf("%5d %9d %9d %2d%% %s\n", i+1, e.size_orig, e.size_comp, ratio, e.name);
+
+ total_orig += e.size_orig;
+ total_comp += e.size_comp;
+ }
+
+ int total_ratio = (int) (100.0 * (double) total_comp / (double) total_orig);
+
+ printf("----- --------- --------- -----\n");
+ printf("TOTAL %9d %9d %2d%%\n\n", total_orig, total_comp, total_ratio);
+}
+
+
+// +--------------------------------------------------------------------+
+
diff --git a/Datafile/Archive.h b/Datafile/Archive.h
new file mode 100644
index 0000000..f3ec099
--- /dev/null
+++ b/Datafile/Archive.h
@@ -0,0 +1,83 @@
+/* Project nGen
+ John DiCamillo Software Consulting
+ Copyright © 1997. All Rights Reserved.
+
+ SUBSYSTEM: DataFile.exe
+ FILE: Archive.hpp
+ AUTHOR: John DiCamillo
+
+*/
+
+#ifndef ARCHIVE_HPP
+#define ARCHIVE_HPP
+
+// +------------------------------------------------------------------+
+
+#define VERSION 0x0010
+#define BLOCK_SIZE 1024
+#define MAX_FILES 4096
+#define FILE_BLOCK 1024
+#define NAMELEN 64
+
+// +------------------------------------------------------------------+
+
+struct DataHeader
+{
+ DWORD version;
+ DWORD nfiles;
+ DWORD dir_blocks;
+ DWORD dir_size_comp;
+ DWORD dir_offset;
+};
+
+struct DataEntry
+{
+ char name[NAMELEN];
+ DWORD size_orig;
+ DWORD size_comp;
+ DWORD offset;
+};
+
+class DataArchive
+{
+public:
+ // ctor:
+ DataArchive(const char* name = 0);
+ ~DataArchive();
+
+ // operations:
+ void LoadDatafile(const char* name);
+ void Insert(const char* name);
+ void Extract(const char* name);
+ void Remove(const char* name);
+ void List();
+
+ void WriteEntry(int index, BYTE* buf);
+ int FindEntry(const char* req_name);
+ int ExpandEntry(int index, BYTE*& buf);
+ BYTE* CompressEntry(int index);
+ int InsertEntry(const char* name);
+ void RemoveEntry(int index);
+ DWORD Blocks(DWORD raw_size);
+ DWORD DirBlocks();
+ DWORD FileBlocks(int index);
+ int FindDataBlocks(int blocks_needed);
+ void CreateBlockMap();
+
+ DWORD NumFiles() { return header.nfiles; }
+ DataEntry* GetFile(int i) { if (i>=0 && i<(int)header.nfiles) return &directory[i]; return 0; }
+
+private:
+ // persistent data members:
+ DataHeader header;
+ DataEntry directory[MAX_FILES];
+ BYTE* dirbuf;
+
+ // transient members:
+ char datafile[NAMELEN];
+
+ DWORD* block_map;
+ DWORD nblocks;
+};
+
+#endif
diff --git a/Datafile/DataFile.dsp b/Datafile/DataFile.dsp
new file mode 100644
index 0000000..66afdf9
--- /dev/null
+++ b/Datafile/DataFile.dsp
@@ -0,0 +1,112 @@
+# Microsoft Developer Studio Project File - Name="DataFile" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=DataFile - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "DataFile.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "DataFile.mak" CFG="DataFile - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "DataFile - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "DataFile - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "DataFile - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir ".\Release"
+# PROP BASE Intermediate_Dir ".\Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ".\Release"
+# PROP Intermediate_Dir ".\Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\zlib" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "DataFile - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir ".\Debug"
+# PROP BASE Intermediate_Dir ".\Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ".\Debug"
+# PROP Intermediate_Dir ".\Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\zlib" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
+
+!ENDIF
+
+# Begin Target
+
+# Name "DataFile - Win32 Release"
+# Name "DataFile - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
+# Begin Source File
+
+SOURCE=.\Archive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\main.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=\USERS\MILO\GameDev\zlib\Release\zlib.lib
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
+# Begin Source File
+
+SOURCE=.\Archive.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/Datafile/DataFile.dsw b/Datafile/DataFile.dsw
new file mode 100644
index 0000000..8a0f764
--- /dev/null
+++ b/Datafile/DataFile.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "DataFile"=.\DataFile.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/Datafile/DataFile.mak b/Datafile/DataFile.mak
new file mode 100644
index 0000000..765d647
--- /dev/null
+++ b/Datafile/DataFile.mak
@@ -0,0 +1,231 @@
+# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+!IF "$(CFG)" == ""
+CFG=DataFile - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to DataFile - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "DataFile - Win32 Release" && "$(CFG)" !=\
+ "DataFile - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE on this makefile
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "DataFile.mak" CFG="DataFile - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "DataFile - Win32 Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "DataFile - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+################################################################################
+# Begin Project
+# PROP Target_Last_Scanned "DataFile - Win32 Debug"
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "DataFile - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+OUTDIR=.\Release
+INTDIR=.\Release
+
+ALL : "$(OUTDIR)\DataFile.exe"
+
+CLEAN :
+ -@erase "$(INTDIR)\Archive.obj"
+ -@erase "$(INTDIR)\main.obj"
+ -@erase "$(OUTDIR)\DataFile.exe"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /W3 /GX /O2 /I "../zlib" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+CPP_PROJ=/nologo /ML /W3 /GX /O2 /I "../zlib" /D "WIN32" /D "NDEBUG" /D\
+ "_CONSOLE" /Fp"$(INTDIR)/DataFile.pch" /YX /Fo"$(INTDIR)/" /c
+CPP_OBJS=.\Release/
+CPP_SBRS=.\.
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/DataFile.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
+ odbccp32.lib /nologo /subsystem:console /incremental:no\
+ /pdb:"$(OUTDIR)/DataFile.pdb" /machine:I386 /out:"$(OUTDIR)/DataFile.exe"
+LINK32_OBJS= \
+ "$(INTDIR)\Archive.obj" \
+ "$(INTDIR)\main.obj" \
+ "..\zlib\Release\zlib.lib"
+
+"$(OUTDIR)\DataFile.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "DataFile - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+OUTDIR=.\Debug
+INTDIR=.\Debug
+
+ALL : "$(OUTDIR)\DataFile.exe"
+
+CLEAN :
+ -@erase "$(INTDIR)\Archive.obj"
+ -@erase "$(INTDIR)\main.obj"
+ -@erase "$(INTDIR)\vc40.idb"
+ -@erase "$(INTDIR)\vc40.pdb"
+ -@erase "$(OUTDIR)\DataFile.exe"
+ -@erase "$(OUTDIR)\DataFile.ilk"
+ -@erase "$(OUTDIR)\DataFile.pdb"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "../zlib" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
+CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /I "../zlib" /D "WIN32" /D "_DEBUG"\
+ /D "_CONSOLE" /Fp"$(INTDIR)/DataFile.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/"\
+ /c
+CPP_OBJS=.\Debug/
+CPP_SBRS=.\.
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/DataFile.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
+ odbccp32.lib /nologo /subsystem:console /incremental:yes\
+ /pdb:"$(OUTDIR)/DataFile.pdb" /debug /machine:I386\
+ /out:"$(OUTDIR)/DataFile.exe"
+LINK32_OBJS= \
+ "$(INTDIR)\Archive.obj" \
+ "$(INTDIR)\main.obj" \
+ "..\zlib\Release\zlib.lib"
+
+"$(OUTDIR)\DataFile.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ENDIF
+
+.c{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cpp{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cxx{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.c{$(CPP_SBRS)}.sbr:
+ $(CPP) $(CPP_PROJ) $<
+
+.cpp{$(CPP_SBRS)}.sbr:
+ $(CPP) $(CPP_PROJ) $<
+
+.cxx{$(CPP_SBRS)}.sbr:
+ $(CPP) $(CPP_PROJ) $<
+
+################################################################################
+# Begin Target
+
+# Name "DataFile - Win32 Release"
+# Name "DataFile - Win32 Debug"
+
+!IF "$(CFG)" == "DataFile - Win32 Release"
+
+!ELSEIF "$(CFG)" == "DataFile - Win32 Debug"
+
+!ENDIF
+
+################################################################################
+# Begin Source File
+
+SOURCE=.\main.cpp
+DEP_CPP_MAIN_=\
+ ".\Archive.hpp"\
+
+
+"$(INTDIR)\main.obj" : $(SOURCE) $(DEP_CPP_MAIN_) "$(INTDIR)"
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=\USERS\MILO\GameDev\zlib\Release\zlib.lib
+
+!IF "$(CFG)" == "DataFile - Win32 Release"
+
+!ELSEIF "$(CFG)" == "DataFile - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\Archive.cpp
+DEP_CPP_ARCHI=\
+ "..\zlib\zconf.h"\
+ ".\../zlib\zlib.h"\
+ ".\Archive.hpp"\
+ {$(INCLUDE)}"\sys\stat.h"\
+ {$(INCLUDE)}"\sys\types.h"\
+
+
+"$(INTDIR)\Archive.obj" : $(SOURCE) $(DEP_CPP_ARCHI) "$(INTDIR)"
+
+
+# End Source File
+# End Target
+# End Project
+################################################################################
diff --git a/Datafile/DataFile.mdp b/Datafile/DataFile.mdp
new file mode 100644
index 0000000..25c0627
--- /dev/null
+++ b/Datafile/DataFile.mdp
Binary files differ
diff --git a/Datafile/Main.cpp b/Datafile/Main.cpp
new file mode 100644
index 0000000..dd4370b
--- /dev/null
+++ b/Datafile/Main.cpp
@@ -0,0 +1,453 @@
+/* Project nGen
+ John DiCamillo Software Consulting
+ Copyright © 1997. All Rights Reserved.
+
+ SUBSYSTEM: DataFile.exe
+ FILE: main.cpp
+ AUTHOR: John DiCamillo
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <time.h>
+#include <windows.h>
+#include <windowsx.h>
+#include "Archive.h"
+
+//#define MOD_MAKER 1
+
+// +------------------------------------------------------------------+
+
+void insertFile(DataArchive& a, const char* sPath, WIN32_FIND_DATA* find)
+{
+ char sFile[256];
+ char sFlat[256];
+ DWORD find_attrib_forbidden =
+ FILE_ATTRIBUTE_DIRECTORY |
+ FILE_ATTRIBUTE_HIDDEN |
+ FILE_ATTRIBUTE_SYSTEM |
+ FILE_ATTRIBUTE_OFFLINE;
+
+ if (sPath && *sPath)
+ sprintf(sFile, "%s/%s", sPath, find->cFileName);
+ else
+ strcpy(sFile, find->cFileName);
+
+ if (find->dwFileAttributes & find_attrib_forbidden) {
+ printf(" Skipping: %-48s \n", sFile);
+ return;
+ }
+
+ int n = strlen(sFile);
+
+ if (n >= NAMELEN) {
+ printf(" Skipping: %-48s (NAME TOO LONG!)\n", sFile);
+ return;
+ }
+
+ for (int i = 0; i < n; i++)
+ sFlat[i] = tolower(sFile[i]);
+
+ if (strstr(sFlat, ".exe")) {
+ printf(" Skipping: %-48s (executable file)\n", sFile);
+ }
+ else if (strstr(sFlat, ".cmd")) {
+ printf(" Skipping: %-48s (executable file)\n", sFile);
+ }
+ else if (strstr(sFlat, ".bat")) {
+ printf(" Skipping: %-48s (executable file)\n", sFile);
+ }
+ else if (strstr(sFlat, ".bin")) {
+ printf(" Skipping: %-48s (unknown file)\n", sFile);
+ }
+ else if (strstr(sFlat, ".db")) {
+ printf(" Skipping: %-48s (unknown file)\n", sFile);
+ }
+ else if (strstr(sFlat, ".dat")) {
+ printf(" Skipping: %-48s (data file)\n", sFile);
+ }
+ else if (strstr(sFlat, ".zip")) {
+ printf(" Skipping: %-48s (zip file)\n", sFile);
+ }
+ else if (strstr(sFlat, ".arc")) {
+ printf(" Skipping: %-48s (archive file)\n", sFile);
+ }
+ else if (strstr(sFlat, ".psd")) {
+ printf(" Skipping: %-48s (PSD file)\n", sFile);
+ }
+ else {
+ a.Insert(sFile);
+ }
+}
+
+// +------------------------------------------------------------------+
+
+void ins(DataArchive& a, int argc, char* argv[])
+{
+ char sPath[256];
+ char* pDirSep = 0;
+
+ for (int i = 0; i < argc; i++) {
+ if (strchr(argv[i], '*')) {
+ strcpy(sPath, argv[i]);
+
+ if ((pDirSep = strrchr(sPath, '\\')) != 0)
+ *pDirSep = 0;
+
+ else if ((pDirSep = strrchr(sPath, '/')) != 0)
+ *pDirSep = 0;
+
+ else
+ sPath[0] = 0;
+
+ WIN32_FIND_DATA find;
+ HANDLE h = FindFirstFile(argv[i], &find);
+ if (h != INVALID_HANDLE_VALUE) {
+ insertFile(a, sPath, &find);
+
+ while (FindNextFile(h,&find)) {
+ insertFile(a, sPath, &find);
+ }
+
+ FindClose(h);
+ }
+ }
+ else {
+ a.Insert(argv[i]);
+ }
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void build(DataArchive& a, const char* sBasePath);
+
+void buildFile(DataArchive& a, const char* sPath, WIN32_FIND_DATA& find)
+{
+ if (find.cFileName[0] == '.') {
+ }
+
+ else if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ char subdir[256];
+ if (sPath && *sPath)
+ sprintf(subdir, "%s/%s", sPath, find.cFileName);
+ else
+ sprintf(subdir, "%s", find.cFileName);
+
+ build(a, subdir);
+ }
+
+ else {
+ insertFile(a, sPath, &find);
+ }
+}
+
+void build(DataArchive& a, const char* sBasePath)
+{
+ char sPath[256];
+ char sFind[256];
+
+ if (sBasePath && *sBasePath) {
+ strcpy(sPath, sBasePath);
+ sprintf(sFind, "%s\\*.*", sPath);
+ }
+ else {
+ sPath[0] = 0;
+ strcpy(sFind, "*.*");
+ }
+
+ WIN32_FIND_DATA find;
+ HANDLE h = FindFirstFile(sFind, &find);
+ if (h != INVALID_HANDLE_VALUE) {
+ do
+ buildFile(a, sPath, find);
+
+ while (FindNextFile(h, &find));
+
+ FindClose(h);
+ }
+}
+
+void mak(DataArchive& a)
+{
+ build(a, 0);
+}
+
+// +--------------------------------------------------------------------+
+// for now, pattern must be either "*" or "*.???"
+
+int match(const char* sFile, const char* sPattern)
+{
+ int nPatternType = 0;
+ char* sExt = 0;
+
+ const int PATTERN_NOWILD = 0;
+ const int PATTERN_STAR = 1;
+ const int PATTERN_STAR_DOT_STAR = 2;
+ const int PATTERN_STAR_DOT_EXT = 3;
+
+ // what kind of pattern matching?
+ if (strchr(sPattern, '*')) {
+ if (strchr(sPattern, '.')) {
+ if (strcmp(sPattern, "*.*") == 0) {
+ nPatternType = PATTERN_STAR_DOT_STAR;
+ }
+ else {
+ nPatternType = PATTERN_STAR_DOT_EXT;
+ sExt = strchr(sPattern, '.');
+ }
+ }
+
+ else {
+ nPatternType = PATTERN_STAR;
+ }
+ }
+
+ int file_matches_pattern = 0;
+
+ switch (nPatternType) {
+ case PATTERN_NOWILD:
+ default:
+ file_matches_pattern = (stricmp(sFile, sPattern) == 0);
+ break;
+
+
+ case PATTERN_STAR:
+ case PATTERN_STAR_DOT_STAR:
+ file_matches_pattern = 1;
+ break;
+
+ case PATTERN_STAR_DOT_EXT:
+ file_matches_pattern = (strstr(sFile, sExt) != 0);
+ break;
+ }
+
+ return file_matches_pattern;
+}
+
+void ext(DataArchive& a, int argc, char* argv[])
+{
+ if (argc) {
+ char sPath[256];
+ char sPatt[256];
+ char* pDirSep;
+ int nPath;
+
+ for (int i = 0; i < argc; i++) {
+ if (strchr(argv[i], '*')) {
+ strcpy(sPath, argv[i]);
+
+ if ((pDirSep = strrchr(sPath, '\\')) != 0) {
+ strcpy(sPatt, pDirSep+1);
+ *pDirSep = 0;
+ nPath = strlen(sPath);
+ }
+
+ else if ((pDirSep = strrchr(sPath, '/')) != 0) {
+ strcpy(sPatt, pDirSep+1);
+ *pDirSep = 0;
+ nPath = strlen(sPath);
+ }
+
+ else {
+ strcpy(sPatt, sPath);
+ sPath[0] = 0;
+ nPath = 0;
+ }
+
+ // for each file in the archive:
+ for (unsigned j = 0; j < a.NumFiles(); j++) {
+ DataEntry* pde = a.GetFile(j);
+
+ if (pde) {
+ // if we are extracting from a sub-directory,
+ if (nPath) {
+ // and this file is in the sub-directory,
+ if (strnicmp(pde->name, sPath, nPath) == 0) {
+ // and this file matches the pattern:
+ if (match(pde->name+nPath+1, sPatt)) {
+ char sName[256];
+ strcpy(sName, pde->name);
+ a.Extract(sName);
+ }
+ }
+ }
+
+ // if we are extracting from the main directory,
+ else {
+ // and this file is in the main directory,
+ if (strchr(pde->name, '/') == 0) {
+ // and this file matches the pattern:
+ if (match(pde->name, sPatt)) {
+ char sName[256];
+ strcpy(sName, pde->name);
+ a.Extract(sName);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ else {
+ // for each file in the archive:
+ for (unsigned j = 0; j < a.NumFiles(); j++) {
+ DataEntry* pde = a.GetFile(j);
+
+ if (pde) {
+ if (stricmp(pde->name, argv[i]) == 0) {
+ a.Extract(argv[i]);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // full archive extraction:
+ else {
+ for (int i = 0; i < (int)a.NumFiles(); i++)
+ a.Extract(a.GetFile(i)->name);
+ }
+}
+
+void del(DataArchive& a, int argc, char* argv[])
+{
+ char sPath[256];
+ char sPatt[256];
+ char* pDirSep;
+ int nPath;
+
+ for (int i = 0; i < argc; i++) {
+ if (strchr(argv[i], '*')) {
+ strcpy(sPath, argv[i]);
+
+ if ((pDirSep = strrchr(sPath, '\\')) != 0) {
+ strcpy(sPatt, pDirSep+1);
+ *pDirSep = 0;
+ nPath = strlen(sPath);
+ }
+
+ else if ((pDirSep = strrchr(sPath, '/')) != 0) {
+ strcpy(sPatt, pDirSep+1);
+ *pDirSep = 0;
+ nPath = strlen(sPath);
+ }
+
+ else {
+ strcpy(sPatt, sPath);
+ sPath[0] = 0;
+ nPath = 0;
+ }
+
+ // for each file in the archive:
+ for (unsigned j = 0; j < a.NumFiles(); j++) {
+ DataEntry* pde = a.GetFile(j);
+
+ if (pde) {
+ // if we are deleting from a sub-directory,
+ if (nPath) {
+ // and this file is in the sub-directory,
+ if (strnicmp(pde->name, sPath, nPath) == 0) {
+ // and this file matches the pattern:
+ if (match(pde->name+nPath+1, sPatt)) {
+ char sName[256];
+ strcpy(sName, pde->name);
+ a.Remove(sName);
+ }
+ }
+ }
+
+ // if we are deleting from the main directory,
+ else {
+ // and this file is in the main directory,
+ if (strchr(pde->name, '/') == 0) {
+ // and this file matches the pattern:
+ if (match(pde->name, sPatt)) {
+ char sName[256];
+ strcpy(sName, pde->name);
+ a.Remove(sName);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ else {
+ a.Remove(argv[i]);
+ }
+ }
+}
+
+
+// +--------------------------------------------------------------------+
+
+void Usage()
+{
+ printf("Usage: datafile <dat-file> -option <file list>\n");
+ printf("options: -ins (insert files into datafile)\n");
+ printf(" -ext (extract files from datafile)\n");
+ printf(" -del (delete files from datafile)\n");
+ printf(" -mak (insert all files in current directory and all subdirectories)\n");
+ printf(" -list (display list of entries in datafile)\n");
+
+ exit(-1);
+}
+
+#define OPT_NONE 0
+#define OPT_INS 1
+#define OPT_EXT 2
+#define OPT_DEL 3
+#define OPT_MAK 4
+#define OPT_LIST 5
+
+int main(int argc, char* argv[])
+{
+#ifdef MOD_MAKER
+ printf("MODFILE\n");
+
+ if (argc < 2) {
+ printf("Usage: modfile <dat-file>\n");
+ return 0;
+ }
+
+ ::unlink(argv[1]);
+ DataArchive a(argv[1]);
+ mak(a);
+
+ return 0;
+#else
+ printf("DATAFILE\n");
+
+ if (argc < 3)
+ Usage();
+
+ DataArchive a(argv[1]);
+ int option = OPT_NONE;
+
+ if (!stricmp(argv[2], "-ins")) option = OPT_INS;
+ else if (!stricmp(argv[2], "-ext")) option = OPT_EXT;
+ else if (!stricmp(argv[2], "-del")) option = OPT_DEL;
+ else if (!stricmp(argv[2], "-mak")) option = OPT_MAK;
+ else if (!stricmp(argv[2], "-list")) option = OPT_LIST;
+
+ argc -= 3;
+ argv += 3;
+
+ switch (option) {
+ default:
+ case OPT_NONE: Usage(); break;
+ case OPT_INS: ins(a, argc, argv); break;
+ case OPT_EXT: ext(a, argc, argv); break;
+ case OPT_DEL: del(a, argc, argv); break;
+ case OPT_MAK: mak(a); break;
+ case OPT_LIST: a.List(); break;
+ }
+#endif
+
+ return 0;
+}
+