DEADSOFTWARE

add cvar d_eres
[d2df-sdl.git] / src / shared / wadreader.pas
index 69d04394ceaeacd10c077c149852d82dd8a210a7..1419f264faf6876b54adfe1d0b3f4dfa076bf713 100644 (file)
@@ -1,9 +1,8 @@
-(* Copyright (C)  DooM 2D:Forever Developers
+(* 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.
+ * the Free Software Foundation, version 3 of the License ONLY.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -22,13 +21,13 @@ unit wadreader;
 interface
 
 uses
-  sfs, xstreams, Classes;
+  Classes,
+  {$IFDEF USE_MEMPOOL}mempool,{$ENDIF}
+  sfs, xstreams, utils;
 
 
 type
-  SArray = array of ShortString;
-
-  TWADFile = class
+  TWADFile = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
   private
     fFileName: AnsiString; // empty: not opened
     fIter: TSFSFileList;
@@ -49,7 +48,7 @@ type
 
     function GetResource (name: AnsiString; var pData: Pointer; var Len: Integer; logError: Boolean=true): Boolean;
     function GetMapResource (name: AnsiString; var pData: Pointer; var Len: Integer; logError: Boolean=true): Boolean;
-    function GetMapResources (): SArray;
+    function GetMapResources (): SSArray;
 
     // returns `nil` if file wasn't found
     function openFileStream (name: AnsiString): TStream;
@@ -57,15 +56,20 @@ type
     property isOpen: Boolean read getIsOpen;
   end;
 
-
+// g_ExtractWadName C:\svr\shit.wad:\MAPS\MAP01 -> C:/svr/shit.wad
 function g_ExtractWadName (resourceStr: AnsiString): AnsiString;
+
+// g_ExtractWadNameNoPath C:\svr\shit.wad:\MAPS\MAP01 -> shit.wad
 function g_ExtractWadNameNoPath (resourceStr: AnsiString): AnsiString;
+
+// g_ExtractFilePath C:\svr\shit.wad:\MAPS\MAP01 -> :/MAPS
 function g_ExtractFilePath (resourceStr: AnsiString): AnsiString;
+
+// g_ExtractFileName C:\svr\shit.wad:\MAPS\MAP01 -> MAP01
 function g_ExtractFileName (resourceStr: AnsiString): AnsiString; // without path
-function g_ExtractFilePathName (resourceStr: AnsiString): AnsiString;
 
-// return fixed AnsiString or empty AnsiString
-function findDiskWad (fname: AnsiString): AnsiString;
+// g_ExtractFilePathName C:\svr\shit.wad:\MAPS\MAP01 -> MAPS/MAP01
+function g_ExtractFilePathName (resourceStr: AnsiString): AnsiString;
 
 
 var
@@ -76,34 +80,7 @@ var
 implementation
 
 uses
-  SysUtils, e_log, utils, MAPDEF;
-
-
-function findDiskWad (fname: AnsiString): AnsiString;
-begin
-  result := '';
-  if not findFileCI(fname) then
-  begin
-    //e_WriteLog(Format('findDiskWad: error looking for [%s]', [fname]), MSG_NOTIFY);
-    if StrEquCI1251(ExtractFileExt(fname), '.wad') then
-    begin
-      fname := ChangeFileExt(fname, '.pk3');
-      //e_WriteLog(Format('  looking for [%s]', [fname]), MSG_NOTIFY);
-      if not findFileCI(fname) then
-      begin
-        fname := ChangeFileExt(fname, '.zip');
-        //e_WriteLog(Format('  looking for [%s]', [fname]), MSG_NOTIFY);
-        if not findFileCI(fname) then exit;
-      end;
-    end
-    else
-    begin
-      exit;
-    end;
-  end;
-  //e_WriteLog(Format('findDiskWad: FOUND [%s]', [fname]), MSG_NOTIFY);
-  result := fname;
-end;
+  SysUtils, e_log, MAPDEF, xdynrec;
 
 
 function normSlashes (s: AnsiString): AnsiString;
@@ -238,7 +215,7 @@ end;
 //FIXME: detect text maps properly here
 function TWADFile.isMapResource (idx: Integer): Boolean;
 var
-  sign: packed array [0..2] of Char;
+  //sign: packed array [0..2] of Char;
   fs: TStream = nil;
 begin
   result := false;
@@ -246,11 +223,15 @@ begin
   if (idx < 0) or (idx >= fIter.Count) then exit;
   try
     fs := fIter.volume.OpenFileByIndex(idx);
+    result := TDynMapDef.canBeMap(fs);
+    (*
     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();
+    fs.Free();
+    result := false; // just in case
     exit;
   end;
   fs.Free();
@@ -304,8 +285,11 @@ var
   fs: TStream;
   fpp: Pointer;
   rpath, rname: AnsiString;
-  sign: packed array [0..2] of Char;
+  //sign: packed array [0..2] of Char;
   goodMap: Boolean;
+  {$IFNDEF SFS_MAPDETECT_FX}
+  wst: TSFSMemoryChunkStream;
+  {$ENDIF}
 begin
   Result := False;
   if not isOpen or (fIter = nil) then Exit;
@@ -355,7 +339,7 @@ begin
       if fs = nil then
       begin
         if wantMap then continue;
-        if logError then e_WriteLog(Format('DFWAD: can''t open file [%s] in [%s]', [name, fFileName]), MSG_WARNING);
+        if logError then e_WriteLog(Format('DFWAD: can''t open file [%s] in [%s]', [name, fFileName]), TMsgType.Warning);
         break;
       end;
       // if we want only maps, check if this is map
@@ -367,9 +351,10 @@ begin
         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');
+          //fs.readBuffer(sign, 3);
+          //goodMap := (sign = MAP_SIGNATURE);
+          //if not goodMap then goodMap := (sign[0] = 'm') and (sign[1] = 'a') and (sign[2] = 'p');
+          goodMap := TDynMapDef.canBeMap(fs);
           {$IF DEFINED(D2D_NEW_MAP_READER_DBG)}
           if goodMap then
             e_LogWritefln('  GOOD map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f])
@@ -410,8 +395,15 @@ begin
         goodMap := false;
         if Len >= 3 then
         begin
-          Move(pData^, sign, 3);
-          goodMap := (sign = MAP_SIGNATURE);
+          //Move(pData^, sign, 3);
+          //goodMap := (sign = MAP_SIGNATURE);
+          wst := TSFSMemoryChunkStream.Create(pData, Len);
+          try
+            goodMap := TDynMapDef.canBeMap(wst);
+          except
+            goodMap := false;
+          end;
+          wst.Free();
         end;
         if not goodMap then
         begin
@@ -426,12 +418,12 @@ begin
       result := true;
       {$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);
+        e_WriteLog(Format('DFWAD: file [%s] FOUND in [%s]; size is %d bytes', [name, fFileName, Len]), TMsgType.Notify);
       {$ENDIF}
       exit;
     end;
   end;
-  if logError then e_WriteLog(Format('DFWAD: file [%s] not found in [%s]', [name, fFileName]), MSG_WARNING);
+  if logError then e_WriteLog(Format('DFWAD: file [%s] not found in [%s]', [name, fFileName]), TMsgType.Warning);
 end;
 
 function TWADFile.GetResource (name: AnsiString; var pData: Pointer; var Len: Integer; logError: Boolean=true): Boolean;
@@ -444,7 +436,7 @@ begin
   result := GetResourceEx(name, true, pData, Len, logError);
 end;
 
-function TWADFile.GetMapResources (): SArray;
+function TWADFile.GetMapResources (): SSArray;
 var
   f, c: Integer;
   fi: TSFSFileInfo;
@@ -491,11 +483,11 @@ begin
   rfn := findDiskWad(FileName);
   if length(rfn) = 0 then
   begin
-    e_WriteLog(Format('TWADFile.ReadFile: error looking for [%s]', [FileName]), MSG_NOTIFY);
+    e_WriteLog(Format('TWADFile.ReadFile: error looking for [%s]', [FileName]), TMsgType.Notify);
     exit;
   end;
   {$IFDEF SFS_DFWAD_DEBUG}
-  if wadoptDebug then e_WriteLog(Format('TWADFile.ReadFile: FOUND [%s]', [rfn]), MSG_NOTIFY);
+  if wadoptDebug then e_WriteLog(Format('TWADFile.ReadFile: FOUND [%s]', [rfn]), TMsgType.Notify);
   {$ENDIF}
   // cache this wad
   try
@@ -514,7 +506,7 @@ begin
   if fIter = nil then Exit;
   fFileName := rfn;
   {$IFDEF SFS_DFWAD_DEBUG}
-  if wadoptDebug then e_WriteLog(Format('TWADFile.ReadFile: [%s] opened', [fFileName]), MSG_NOTIFY);
+  if wadoptDebug then e_WriteLog(Format('TWADFile.ReadFile: [%s] opened', [fFileName]), TMsgType.Notify);
   {$ENDIF}
   Result := True;
 end;
@@ -534,14 +526,14 @@ begin
   FreeWAD();
   if (Data = nil) or (Len = 0) then
   begin
-    e_WriteLog('TWADFile.ReadMemory: EMPTY SUBWAD!', MSG_WARNING);
+    e_WriteLog('TWADFile.ReadMemory: EMPTY SUBWAD!', TMsgType.Warning);
     Exit;
   end;
 
   fn := Format(' -- memwad %d -- ', [uniqueCounter]);
   Inc(uniqueCounter);
   {$IFDEF SFS_DFWAD_DEBUG}
-  if wadoptDebug then e_WriteLog(Format('TWADFile.ReadMemory: [%s]', [fn]), MSG_NOTIFY);
+  if wadoptDebug then e_WriteLog(Format('TWADFile.ReadMemory: [%s]', [fn]), TMsgType.Notify);
   {$ENDIF}
 
   try
@@ -561,7 +553,7 @@ begin
 
   fFileName := fn;
   {$IFDEF SFS_DFWAD_DEBUG}
-  if wadoptDebug then e_WriteLog(Format('TWADFile.ReadMemory: [%s] opened', [fFileName]), MSG_NOTIFY);
+  if wadoptDebug then e_WriteLog(Format('TWADFile.ReadMemory: [%s] opened', [fFileName]), TMsgType.Notify);
   {$ENDIF}
 
   {