home *** CD-ROM | disk | FTP | other *** search
- //**********************************************************************************
- // REJECT.EXE - Reject data table builder for DOOM
- // Copyright (C) 1994 L.M.WITEK
- //
- // 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- //**********************************************************************************
-
-
- #include <iostream.h>
- #include <iomanip.h>
- #include <string.h>
- #include "debug.hpp"
- #include "pwad.hpp"
-
-
- /*********************************************************************************
- **
- ** AUTHOR: L.M.Witek DATE:26-May-1994
- **
- ** FUNCTION: CTOR for PWAD class. Opens the PWAD and builds an internal
- ** dirctory for records in the PWAD.
- **
- ** ENTRY: name of the pwad to open.
- **
- *********************************************************************************/
-
- CPWad::CPWad (XString name)
- : file (name, O_RDWR | O_BINARY), currentmap(0)
- {
- if (file.IsOpen())
- {
- // -=- read the pwad header -=-
- cout << "Opened '" << name << "'" << endl;
- cdebug.out << "Opened '" << name << "'" << endl;
- file.Read (&header, sizeof(PWAD_HEADER));
- if (memcmp ("PWAD", header.signature, 4) != 0)
- {
- cout << "Not a PWAD!" << "\n";
- cdebug.out << "Not a PWAD!" << "\n";
- Fail ();
- return;
- }
- else
- {
- cdebug.out << "File size: " << file.Size() << endl;
- cdebug.out << "Directory Offset: " << header.dir_offset << endl;
- cdebug.out << "Directory Entries: " << header.dir_entries << endl;
- }
-
- // -=- read the directory -=-
- file.Seek (header.dir_offset);
- MemHandle dirbuff = file.Read (header.dir_entries * sizeof(DIR_ENTRY));
- if (dirbuff.Size () != (header.dir_entries * sizeof(DIR_ENTRY)))
- {
- cout << "Error Reading PWAD Directory." << endl;
- cdebug.out << "Error Reading PWAD Directory." << endl;
- Fail ();
- }
- else
- {
- cout << "Building directory...." << flush;
- // -=- go through each dir entry and add it to our internal dir -=-
- DIR_ENTRY *entry_ptr = (DIR_ENTRY *)dirbuff.Buffer();
-
- for (int n = 0; n < header.dir_entries; n++)
- {
- AddEntry (entry_ptr[n]);
- }
- cout << "Done." << endl;
-
- // -=- print out directory used for debugging -=-
- CDirEntry *de;
- CDirEntry *sde;
- de = (CDirEntry *)directory.FirstItem ();
- while (de)
- {
- cdebug.out << de->GetKey() << " " << de->Size() << " bytes\t @" << de->Offset() << endl;
- sde = (CDirEntry *)de->subdir.FirstItem ();
- while (sde)
- {
- cdebug.out << " " << sde->GetKey() << " " << sde->Size() << " bytes\t @" << sde->Offset() << endl;
- sde = (CDirEntry *)sde->Next();
- }
-
- de = (CDirEntry *)de->Next();
- }
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- }
- }
- else
- {
- cout << "Cannot open '" << name << "'" << endl;
- cdebug.out << "Cannot open '" << name << "'" << endl;
- Fail ();
- }
- }
-
- void CPWad::AddEntry (DIR_ENTRY &entry)
- {
- char namebuf[9];
- namebuf[8] = 0;
- memcpy (namebuf, entry.resource_name, 8);
-
- XString name (namebuf);
-
- // -=- test for map level marker -=-
- if ((name[0] == 'E') && (name[2] == 'M') && (entry.resource_size == 0))
- {
- // -=- add map header entry to dir and set up current map -=-
- directory.AddItem (currentmap = new CDirEntry (name, 0, 0));
- }
- else
- {
- // -=- put all map related records in the list in the sub dir of the map -=-
- // -=- all other items go in the main dir -=-
- if ((name == "THINGS") || (name == "LINEDEFS") || (name == "SIDEDEFS") || (name == "VERTEXES") ||
- (name == "SEGS" ) || (name == "SSECTORS") || (name == "NODES" ) || (name == "SECTORS" ) ||
- (name == "REJECT") || (name == "BLOCKMAP"))
- {
- currentmap->subdir.AddItem (new CDirEntry (name, entry.resource_offset, entry.resource_size));
- }
- else
- {
- directory.AddItem (new CDirEntry (name, entry.resource_offset, entry.resource_size));
- currentmap = 0;
- }
- }
- }
-
- MemHandle CPWad::Read (XString map, XString item)
- {
-
- CDirEntry *entry = (CDirEntry *)directory[map];
- if (entry)
- {
- entry = (CDirEntry *)entry->subdir[item];
- if (entry)
- {
- file.Seek (entry->Offset());
- MemHandle data = file.Read (entry->Size());
- if (data.Size() == entry->Size())
- {
- cdebug.out << "Read From PWAD " << map << " " << item << " " << data.Size() << " bytes" << endl;
- return data;
- }
- }
- }
- cerr << "Read From PWAD " << map << " " << item << " FAILED!! " << endl;
- cdebug.out << "Read From PWAD " << map << " " << item << " FAILED!! " << endl;
- return 0;
- }
-
- int CPWad::Write (MemHandle data, XString map, XString item)
- {
-
- CDirEntry *entry = (CDirEntry *)directory[map];
- if (entry)
- {
- entry = (CDirEntry *)entry->subdir[item];
- if (entry)
- {
- file.Seek (entry->Offset());
- if (data.Size() == entry->Size())
- {
- int status = file.Write (data);
-
- cdebug.out << "Write to PWAD " << map << " " << item << " " << data.Size() << " bytes" << endl;
- return status;
- }
- }
- }
- cerr << "Write to PWAD " << map << " " << item << " FAILED!! " << endl;
- cdebug.out << "Write to PWAD " << map << " " << item << " FAILED!! " << endl;
- return -1;
- }
-
-
- MemHandle CPWad::Read (XString item)
- {
- CDirEntry *entry = (CDirEntry *)directory[item];
- if (entry)
- {
- file.Seek (entry->Offset());
- MemHandle data = file.Read (entry->Size());
- if (data.Size() == entry->Size())
- return data;
- }
- return 0;
- }
-