DEADSOFTWARE

the game is able to read text maps now (WARNING! the feature is still experimental!)
[d2df-sdl.git] / src / shared / wadreader.pas
index 7aeef80aeb1d3e9069814a1c883fd64094fe3286..3830af240f6f924519c5704f81f1dc9683ab0dc5 100644 (file)
@@ -1,13 +1,28 @@
-{$MODE DELPHI}
+(* Copyright (C)  DooM 2D:Forever Developers
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *)
+{$INCLUDE a_modes.inc}
 unit wadreader;
 
-{$DEFINE SFS_DWFAD_DEBUG}
+{$DEFINE SFS_DFWAD_DEBUG}
 {$DEFINE SFS_MAPDETECT_FX}
 
 interface
 
 uses
-  sfs, xstreams;
+  sfs, xstreams, Classes;
 
 
 type
@@ -36,6 +51,9 @@ type
     function GetMapResource (name: AnsiString; var pData: Pointer; var Len: Integer): Boolean;
     function GetMapResources (): SArray;
 
+    // returns `nil` if file wasn't found
+    function openFileStream (name: AnsiString): TStream;
+
     property isOpen: Boolean read getIsOpen;
   end;
 
@@ -58,7 +76,7 @@ var
 implementation
 
 uses
-  SysUtils, Classes{, BinEditor}, e_log{, g_options}, utils, MAPSTRUCT;
+  SysUtils, e_log, utils, MAPSTRUCT;
 
 
 function findDiskWad (fname: AnsiString): AnsiString;
@@ -216,19 +234,21 @@ begin
   fFileName := '';
 end;
 
+
+//FIXME: detect text maps properly here
 function TWADFile.isMapResource (idx: Integer): Boolean;
 var
   sign: packed array [0..2] of Char;
-  fs: TStream;
+  fs: TStream = nil;
 begin
   result := false;
   if not isOpen or (fIter = nil) then exit;
   if (idx < 0) or (idx >= fIter.Count) then exit;
-  fs := nil;
   try
     fs := fIter.volume.OpenFileByIndex(idx);
     fs.readBuffer(sign, 3);
     result := (sign = MAP_SIGNATURE);
+    if not result then result := (sign[0] = 'm') and (sign[1] = 'a') and (sign[2] = 'p');
   except
     if fs <> nil then fs.Free();
     exit;
@@ -236,6 +256,32 @@ begin
   fs.Free();
 end;
 
+
+// returns `nil` if file wasn't found
+function TWADFile.openFileStream (name: AnsiString): TStream;
+var
+  f: Integer;
+  fi: TSFSFileInfo;
+begin
+  result := nil;
+  // backwards, due to possible similar names and such
+  for f := fIter.Count-1 downto 0 do
+  begin
+    fi := fIter.Files[f];
+    if fi = nil then continue;
+    if StrEquCI1251(fi.name, name) then
+    begin
+      try
+        result := fIter.volume.OpenFileByIndex(f);
+      except
+        result := nil;
+      end;
+      if (result <> nil) then exit;
+    end;
+  end;
+end;
+
+
 function removeExt (s: AnsiString): AnsiString;
 var
   i: Integer;
@@ -250,6 +296,7 @@ begin
   result := s;
 end;
 
+
 function TWADFile.GetResourceEx (name: AnsiString; wantMap: Boolean; var pData: Pointer; var Len: Integer): Boolean;
 var
   f, lastSlash: Integer;
@@ -257,7 +304,7 @@ var
   fs: TStream;
   fpp: Pointer;
   rpath, rname: AnsiString;
-  sign: array [0..2] of Char;
+  sign: packed array [0..2] of Char;
   goodMap: Boolean;
 begin
   Result := False;
@@ -316,21 +363,26 @@ begin
       if wantMap then
       begin
         goodMap := false;
-        //e_WriteLog(Format('DFWAD: checking for good map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]), MSG_NOTIFY);
+        {$IF DEFINED(D2D_NEW_MAP_READER_DBG)}
+        e_LogWritefln('DFWAD: checking for good map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]);
+        {$ENDIF}
         try
           fs.readBuffer(sign, 3);
           goodMap := (sign = MAP_SIGNATURE);
-          {
+          if not goodMap then goodMap := (sign[0] = 'm') and (sign[1] = 'a') and (sign[2] = 'p');
+          {$IF DEFINED(D2D_NEW_MAP_READER_DBG)}
           if goodMap then
-            e_WriteLog(Format('  GOOD map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]), MSG_NOTIFY)
+            e_LogWritefln('  GOOD map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f])
           else
-            e_WriteLog(Format('  BAD map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]), MSG_NOTIFY);
-          }
+            e_LogWritefln('  BAD map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]);
+          {$ENDIF}
         except
         end;
         if not goodMap then
         begin
-          //e_WriteLog(Format('  not a map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]), MSG_NOTIFY);
+          {$IF DEFINED(D2D_NEW_MAP_READER_DBG)}
+          e_LogWritefln('  not a map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]);
+          {$ENDIF}
           fs.Free();
           continue;
         end;
@@ -372,7 +424,7 @@ begin
       end;
 {$ENDIF}
       result := true;
-      {$IFDEF SFS_DWFAD_DEBUG}
+      {$IFDEF SFS_DFWAD_DEBUG}
       if wadoptDebug then
         e_WriteLog(Format('DFWAD: file [%s] FOUND in [%s]; size is %d bytes', [name, fFileName, Len]), MSG_NOTIFY);
       {$ENDIF}
@@ -405,7 +457,9 @@ begin
     fi := fIter.Files[f];
     if fi = nil then continue;
     if length(fi.name) = 0 then continue;
-    //e_WriteLog(Format('DFWAD: checking for map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]), MSG_NOTIFY);
+    {$IF DEFINED(D2D_NEW_MAP_READER)}
+    //e_LogWritefln('DFWAD: checking for map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]);
+    {$ENDIF}
     if isMapResource(f) then
     begin
       s := removeExt(fi.name);
@@ -440,7 +494,7 @@ begin
     e_WriteLog(Format('TWADFile.ReadFile: error looking for [%s]', [FileName]), MSG_NOTIFY);
     exit;
   end;
-  {$IFDEF SFS_DWFAD_DEBUG}
+  {$IFDEF SFS_DFWAD_DEBUG}
   if wadoptDebug then e_WriteLog(Format('TWADFile.ReadFile: FOUND [%s]', [rfn]), MSG_NOTIFY);
   {$ENDIF}
   // cache this wad
@@ -459,7 +513,7 @@ begin
   fIter := SFSFileList(rfn);
   if fIter = nil then Exit;
   fFileName := rfn;
-  {$IFDEF SFS_DWFAD_DEBUG}
+  {$IFDEF SFS_DFWAD_DEBUG}
   if wadoptDebug then e_WriteLog(Format('TWADFile.ReadFile: [%s] opened', [fFileName]), MSG_NOTIFY);
   {$ENDIF}
   Result := True;
@@ -486,8 +540,8 @@ begin
 
   fn := Format(' -- memwad %d -- ', [uniqueCounter]);
   Inc(uniqueCounter);
-  {$IFDEF SFS_DWFAD_DEBUG}
-    e_WriteLog(Format('TWADFile.ReadMemory: [%s]', [fn]), MSG_NOTIFY);
+  {$IFDEF SFS_DFWAD_DEBUG}
+  if wadoptDebug then e_WriteLog(Format('TWADFile.ReadMemory: [%s]', [fn]), MSG_NOTIFY);
   {$ENDIF}
 
   try
@@ -506,8 +560,8 @@ begin
   if fIter = nil then Exit;
 
   fFileName := fn;
-  {$IFDEF SFS_DWFAD_DEBUG}
-    e_WriteLog(Format('TWADFile.ReadMemory: [%s] opened', [fFileName]), MSG_NOTIFY);
+  {$IFDEF SFS_DFWAD_DEBUG}
+  if wadoptDebug then e_WriteLog(Format('TWADFile.ReadMemory: [%s] opened', [fFileName]), MSG_NOTIFY);
   {$ENDIF}
 
   {