home *** CD-ROM | disk | FTP | other *** search
/ Quake 'em / QUAKEEM.BIN / doom_i / program / reject10.exe / SOURCE.ZIP / PWAD.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-01  |  7.1 KB  |  202 lines

  1. //**********************************************************************************
  2. //    REJECT.EXE - Reject data table builder for DOOM
  3. //    Copyright (C) 1994 L.M.WITEK 
  4. //
  5. //    This program is free software; you can redistribute it and/or modify
  6. //    it under the terms of the GNU General Public License as published by
  7. //    the Free Software Foundation; either version 1, or (at your option)
  8. //    any later version.
  9. //
  10. //    This program is distributed in the hope that it will be useful,
  11. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. //    GNU General Public License for more details.
  14. //
  15. //    You should have received a copy of the GNU General Public License
  16. //    along with this program; if not, write to the Free Software
  17. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. //**********************************************************************************
  19.  
  20.  
  21. #include <iostream.h>
  22. #include <iomanip.h>
  23. #include <string.h>
  24. #include "debug.hpp"
  25. #include "pwad.hpp"
  26.  
  27.  
  28. /*********************************************************************************
  29. **
  30. **  AUTHOR: L.M.Witek   DATE:26-May-1994
  31. **
  32. **  FUNCTION: CTOR for PWAD class. Opens the PWAD and builds an internal
  33. **             dirctory for records in the PWAD.
  34. **
  35. **  ENTRY:   name of the pwad to open.
  36. **
  37. *********************************************************************************/
  38.  
  39. CPWad::CPWad (XString name)
  40.       : file (name, O_RDWR | O_BINARY), currentmap(0)
  41. {
  42.      if (file.IsOpen())
  43.      {
  44.           // -=- read the pwad header -=-
  45.           cout << "Opened '" << name << "'" << endl;
  46.           cdebug.out << "Opened '" << name << "'" << endl;
  47.           file.Read (&header, sizeof(PWAD_HEADER));
  48.           if (memcmp ("PWAD", header.signature, 4) != 0)
  49.           {
  50.                cout << "Not a PWAD!" << "\n";
  51.                cdebug.out << "Not a PWAD!" << "\n";
  52.                Fail ();
  53.                return;
  54.           }
  55.           else
  56.           {
  57.                cdebug.out << "File size: " << file.Size() << endl;
  58.                cdebug.out << "Directory Offset: " << header.dir_offset << endl;
  59.                cdebug.out << "Directory Entries: " << header.dir_entries << endl;
  60.           }
  61.  
  62.           // -=- read the directory -=-
  63.           file.Seek (header.dir_offset);
  64.           MemHandle dirbuff = file.Read (header.dir_entries * sizeof(DIR_ENTRY));
  65.           if (dirbuff.Size () != (header.dir_entries * sizeof(DIR_ENTRY)))
  66.           {
  67.                cout << "Error Reading PWAD Directory." << endl;
  68.                cdebug.out << "Error Reading PWAD Directory." << endl;
  69.                Fail ();
  70.           }
  71.           else
  72.           {
  73.                cout << "Building directory...." << flush;
  74.                // -=- go through each dir entry and add it to our internal dir -=-
  75.                DIR_ENTRY *entry_ptr = (DIR_ENTRY *)dirbuff.Buffer();
  76.                
  77.                for (int n = 0; n < header.dir_entries; n++)
  78.                {
  79.                     AddEntry (entry_ptr[n]);
  80.                }
  81.                cout << "Done." << endl;
  82.  
  83. // -=- print out directory used for debugging -=- 
  84.                CDirEntry *de;
  85.                CDirEntry *sde;
  86.                de = (CDirEntry *)directory.FirstItem ();
  87.                while (de)
  88.                {
  89.                     cdebug.out << de->GetKey() << "  " << de->Size() << " bytes\t  @" << de->Offset() << endl;
  90.                     sde = (CDirEntry *)de->subdir.FirstItem ();
  91.                     while (sde)
  92.                     {
  93.                          cdebug.out << "  " << sde->GetKey() << "  "  << sde->Size() << " bytes\t  @" << sde->Offset() << endl;
  94.                          sde = (CDirEntry *)sde->Next();
  95.                     }
  96.  
  97.                     de = (CDirEntry *)de->Next();
  98.                }
  99. // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  100.           }
  101.      }
  102.      else
  103.      {
  104.           cout << "Cannot open '" << name << "'" << endl;
  105.           cdebug.out << "Cannot open '" << name << "'" << endl;
  106.           Fail ();
  107.      }
  108. }
  109.  
  110. void CPWad::AddEntry (DIR_ENTRY &entry)
  111. {
  112.      char namebuf[9];
  113.      namebuf[8] = 0;
  114.      memcpy (namebuf, entry.resource_name, 8);
  115.      
  116.      XString name (namebuf);
  117.  
  118.      // -=- test for map level marker -=- 
  119.      if ((name[0] == 'E') && (name[2] == 'M') && (entry.resource_size == 0))
  120.      {
  121.           // -=- add map header entry to dir and set up current map -=-
  122.           directory.AddItem (currentmap = new CDirEntry (name, 0, 0));
  123.      }
  124.      else
  125.      {
  126.           // -=- put all map related records in the list in the sub dir of the map -=-
  127.           // -=- all other items go in the main dir -=-
  128.           if  ((name == "THINGS") || (name == "LINEDEFS") || (name == "SIDEDEFS") || (name == "VERTEXES") ||    
  129.                (name == "SEGS"  ) || (name == "SSECTORS") || (name == "NODES"   ) || (name == "SECTORS" ) ||    
  130.                (name == "REJECT") || (name == "BLOCKMAP"))
  131.           {
  132.                currentmap->subdir.AddItem (new CDirEntry (name, entry.resource_offset, entry.resource_size)); 
  133.           }
  134.           else
  135.           {
  136.                directory.AddItem (new CDirEntry (name, entry.resource_offset, entry.resource_size)); 
  137.                currentmap = 0;
  138.           }
  139.      }
  140. }
  141.  
  142. MemHandle CPWad::Read (XString map, XString item)
  143. {
  144.  
  145.      CDirEntry *entry = (CDirEntry *)directory[map];
  146.      if (entry)
  147.      {
  148.           entry = (CDirEntry *)entry->subdir[item];
  149.           if (entry)
  150.           {
  151.                file.Seek (entry->Offset());
  152.                MemHandle data = file.Read (entry->Size());
  153.                if (data.Size() == entry->Size())
  154.                {
  155.                     cdebug.out << "Read From PWAD " << map << " " << item << " " << data.Size() << " bytes" << endl;
  156.                     return data;
  157.                }
  158.           }
  159.      }
  160.      cerr << "Read From PWAD " << map << " " << item << " FAILED!! " << endl;
  161.      cdebug.out << "Read From PWAD " << map << " " << item << " FAILED!! " << endl;
  162.      return 0;
  163. }
  164.  
  165. int CPWad::Write (MemHandle data, XString map, XString item)
  166. {
  167.  
  168.      CDirEntry *entry = (CDirEntry *)directory[map];
  169.      if (entry)
  170.      {
  171.           entry = (CDirEntry *)entry->subdir[item];
  172.           if (entry)
  173.           {
  174.                file.Seek (entry->Offset());
  175.                if (data.Size() == entry->Size())
  176.                {
  177.                     int status = file.Write (data);
  178.  
  179.                     cdebug.out << "Write to PWAD " << map << " " << item << " " << data.Size() << " bytes" << endl;
  180.                     return status;
  181.                }
  182.           }
  183.      }
  184.      cerr << "Write to PWAD " << map << " " << item << " FAILED!! " << endl;
  185.      cdebug.out << "Write to PWAD " << map << " " << item << " FAILED!! " << endl;
  186.      return -1;
  187. }
  188.  
  189.  
  190. MemHandle CPWad::Read (XString item)
  191. {
  192.      CDirEntry *entry = (CDirEntry *)directory[item];
  193.      if (entry)
  194.      {
  195.           file.Seek (entry->Offset());
  196.           MemHandle data = file.Read (entry->Size());
  197.           if (data.Size() == entry->Size())
  198.                return data;
  199.      }
  200.      return 0;
  201. }
  202.