DEADSOFTWARE

network: it should find correct files on POSIX now (and substitute extensions too)
[d2df-sdl.git] / src / shared / WADEDITOR.pas
index 903922fccda3b90be88aa5efd675d0f9dacf6650..d41acfaa8a83a67b96b9d2f3f1ff5ab0cbf7345d 100644 (file)
@@ -1,12 +1,6 @@
 unit WADEDITOR;
 
-{
------------------------------------
-WADEDITOR.PAS ÂÅÐÑÈß ÎÒ 26.08.08
-
-Ïîääåðæêà âàäîâ âåðñèè 1
------------------------------------
-}
+{$DEFINE SFS_DWFAD_DEBUG}
 
 interface
 
@@ -55,11 +49,49 @@ const
 procedure g_ProcessResourceStr (ResourceStr: String; var FileName, SectionName, ResourceName: String); overload;
 procedure g_ProcessResourceStr (ResourceStr: String; FileName, SectionName, ResourceName: PString); overload;
 
+// return fixed string or empty string
+function findDiskWad (fname: string): string;
+
 
 implementation
 
 uses
-  SysUtils, Classes, BinEditor, e_log;
+  SysUtils, Classes, BinEditor, e_log, g_options;
+
+
+function findDiskWad (fname: string): string;
+var
+  path, rfn: string;
+begin
+  result := '';
+  path := ExtractFilePath(fname);
+  rfn := ExtractFileName(fname);
+  if not sfsFindFileCI(path, rfn) then
+  begin
+    //e_WriteLog(Format('TWADEditor_1.ReadFile: error looking for [%s] [%s]', [path, ExtractFileName(fname)]), MSG_NOTIFY);
+    if SFSStrEqu(ExtractFileExt(fname), '.wad') then
+    begin
+      rfn := ChangeFileExt(ExtractFileName(fname), '.pk3');
+      //e_WriteLog(Format('  looking for [%s] [%s]', [path, rfn]), MSG_NOTIFY);
+      if not sfsFindFileCI(path, rfn) then
+      begin
+        //e_WriteLog(Format('  looking for [%s] [%s]', [path, rfn]), MSG_NOTIFY);
+        rfn := ChangeFileExt(ExtractFileName(fname), '.zip');
+        if not sfsFindFileCI(path, rfn) then exit;
+      end;
+    end
+    else
+    begin
+      exit;
+    end;
+    //e_WriteLog(Format('TWADEditor_1.ReadFile: FOUND [%s]', [rfn]), MSG_NOTIFY);
+  end
+  else
+  begin
+    //if rfn <> ExtractFileName(FileName) then e_WriteLog(Format('TWADEditor_1.ReadFile: FOUND [%s]', [rfn]), MSG_NOTIFY);
+  end;
+  result := path+rfn;
+end;
 
 
 procedure g_ProcessResourceStr (ResourceStr: String; var FileName, SectionName, ResourceName: String);
@@ -139,42 +171,78 @@ end;
 procedure TWADEditor_1.FreeWAD();
 begin
   if fIter <> nil then FreeAndNil(fIter);
-  if fFileName <> '' then e_WriteLog(Format('TWADEditor_1.ReadFile: [%s] closed', [fFileName]), MSG_NOTIFY);
+  //if fFileName <> '' then e_WriteLog(Format('TWADEditor_1.ReadFile: [%s] closed', [fFileName]), MSG_NOTIFY);
   fFileName := '';
 end;
 
 
+function removeExt (s: string): string;
+var
+  i: Integer;
+begin
+  i := length(s)+1;
+  while (i > 1) and (s[i-1] <> '.') and (s[i-1] <> '/') do Dec(i);
+  if (i > 1) and (s[i-1] = '.') then
+  begin
+    //writeln('[', s, '] -> [', Copy(s, 1, i-2), ']');
+    s := Copy(s, 1, i-2);
+  end;
+  result := s;
+end;
+
 function TWADEditor_1.GetResource (Section, Resource: string; var pData: Pointer; var Len: Integer): Boolean;
 var
   f: Integer;
   fi: TSFSFileInfo;
   fs: TStream;
-  fn: string;
+  fpp: Pointer;
+  //fn: string;
 begin
   Result := False;
   if not isOpen or (fIter = nil) then Exit;
+  if length(Resource) = 0 then Exit; // just in case
   if (length(Section) <> 0) and (Section[length(Section)] <> '/') then Section := Section+'/';
-  for f := 0 to fIter.Count-1 do
+  // 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;
-    //e_WriteLog(Format('DFWAD: searching for [%s : %s] in [%s]; current is [%s : %s] (%d, %d)', [Section, Resource, fFileName, fi.path, fi.name, SFSStrComp(fi.path, Section), SFSStrComp(fi.name, Resource)]), MSG_NOTIFY);
-    if (SFSStrComp(fi.path, Section) = 0) and (SFSStrComp(fi.name, Resource) = 0) then
+    //e_WriteLog(Format('DFWAD: searching for [%s : %s] in [%s]; current is [%s : %s]', [Section, Resource, fFileName, fi.path, fi.name]), MSG_NOTIFY);
+    if SFSStrEqu(fi.path, Section) and SFSStrEqu(removeExt(fi.name), Resource) then
     begin
       // i found her!
-      fn := fFileName+'::'+fi.path+fi.name;
-      fs := SFSFileOpen(fn);
+      //fn := fFileName+'::'+fi.path+fi.name;
+      //fs := SFSFileOpen(fn);
+      try
+        fs := fIter.volume.OpenFileByIndex(f);
+      except
+        fs := nil;
+      end;
       if fs = nil then
       begin
-        e_WriteLog(Format('DFWAD: can''t open file [%s]', [fn]), MSG_NOTIFY);
+        e_WriteLog(Format('DFWAD: can''t open file [%s%s] in [%s]', [Section, Resource, fFileName]), MSG_WARNING);
         break;
       end;
       Len := Integer(fs.size);
       GetMem(pData, Len);
-      fs.ReadBuffer(pData^, Len);
-      fs.Free;
+      fpp := pData;
+      try
+        fs.ReadBuffer(pData^, Len);
+        fpp := nil;
+      finally
+        if fpp <> nil then
+        begin
+          FreeMem(fpp);
+          pData := nil;
+          Len := 0;
+        end;
+        fs.Free;
+      end;
       result := true;
-      e_WriteLog(Format('DFWAD: file [%s%s] FOUND in [%s]; size is %d bytes', [Section, Resource, fFileName, Len]), MSG_NOTIFY);
+      {$IFDEF SFS_DWFAD_DEBUG}
+      if gSFSDebug then
+        e_WriteLog(Format('DFWAD: file [%s%s] FOUND in [%s]; size is %d bytes', [Section, Resource, fFileName, Len]), MSG_NOTIFY);
+      {$ENDIF}
       exit;
     end;
   end;
@@ -194,25 +262,53 @@ begin
   begin
     fi := fIter.Files[f];
     if fi = nil then continue;
-    if SFSStrComp(fi.path, Section) = 0 then
+    if length(fi.name) = 0 then continue;
+    if SFSStrEqu(fi.path, Section) then
     begin
       SetLength(result, Length(result)+1);
-      result[high(result)] := fi.name;
+      result[high(result)] := removeExt(fi.name);
     end;
   end;
 end;
 
 
 function TWADEditor_1.ReadFile (FileName: string): Boolean;
+var
+  rfn: string;
+  //f: Integer;
+  //fi: TSFSFileInfo;
 begin
   Result := False;
-  e_WriteLog(Format('TWADEditor_1.ReadFile: [%s]', [FileName]), MSG_NOTIFY);
+  //e_WriteLog(Format('TWADEditor_1.ReadFile: [%s]', [FileName]), MSG_NOTIFY);
   FreeWAD();
-  if not FileExists(FileName) then Exit;
-  fIter := SFSFileList(FileName);
+  rfn := findDiskWad(FileName);
+  if length(rfn) = 0 then
+  begin
+    e_WriteLog(Format('TWADEditor_1.ReadFile: error looking for [%s]', [FileName]), MSG_NOTIFY);
+    exit;
+  end;
+  {$IFDEF SFS_DWFAD_DEBUG}
+  if gSFSDebug then e_WriteLog(Format('TWADEditor_1.ReadFile: FOUND [%s]', [rfn]), MSG_NOTIFY);
+  {$ENDIF}
+  // cache this wad
+  try
+    if gSFSFastMode then
+    begin
+      if not SFSAddDataFile(rfn, true) then exit;
+    end
+    else
+    begin
+      if not SFSAddDataFileTemp(rfn, true) then exit;
+    end;
+  except
+    exit;
+  end;
+  fIter := SFSFileList(rfn);
   if fIter = nil then Exit;
-  fFileName := FileName;
-  e_WriteLog(Format('TWADEditor_1.ReadFile: [%s] opened', [fFileName]), MSG_NOTIFY);
+  fFileName := rfn;
+  {$IFDEF SFS_DWFAD_DEBUG}
+  if gSFSDebug then e_WriteLog(Format('TWADEditor_1.ReadFile: [%s] opened', [fFileName]), MSG_NOTIFY);
+  {$ENDIF}
   Result := True;
 end;
 
@@ -222,22 +318,28 @@ var
 
 function TWADEditor_1.ReadMemory (Data: Pointer; Len: LongWord): Boolean;
 var
-  Signature: array[0..4] of Char;
-  a: Integer;
   fn: string;
   st: TStream = nil;
+  //f: Integer;
+  //fi: TSFSFileInfo;
 begin
   Result := False;
   FreeWAD();
-  if (Data = nil) or (Len = 0) then Exit;
+  if (Data = nil) or (Len = 0) then
+  begin
+    e_WriteLog('TWADEditor_1.ReadMemory: EMPTY SUBWAD!', MSG_WARNING);
+    Exit;
+  end;
 
   fn := Format(' -- memwad %d -- ', [uniqueCounter]);
   Inc(uniqueCounter);
-  e_WriteLog(Format('TWADEditor_1.ReadMemory: [%s]', [fn]), MSG_NOTIFY);
+  {$IFDEF SFS_DWFAD_DEBUG}
+    e_WriteLog(Format('TWADEditor_1.ReadMemory: [%s]', [fn]), MSG_NOTIFY);
+  {$ENDIF}
 
   try
     st := TSFSMemoryStreamRO.Create(Data, Len);
-    if not SFSAddSubDataFile(fn, st) then
+    if not SFSAddSubDataFile(fn, st, true) then
     begin
       st.Free;
       Exit;
@@ -251,7 +353,28 @@ begin
   if fIter = nil then Exit;
 
   fFileName := fn;
-  e_WriteLog(Format('TWADEditor_1.ReadMemory: [%s] opened', [fFileName]), MSG_NOTIFY);
+  {$IFDEF SFS_DWFAD_DEBUG}
+    e_WriteLog(Format('TWADEditor_1.ReadMemory: [%s] opened', [fFileName]), MSG_NOTIFY);
+  {$ENDIF}
+
+  {
+  for f := 0 to fIter.Count-1 do
+  begin
+    fi := fIter.Files[f];
+    if fi = nil then continue;
+    st := fIter.volume.OpenFileByIndex(f);
+    if st = nil then
+    begin
+      e_WriteLog(Format('[%s]: [%s : %s] CAN''T OPEN', [fFileName, fi.path, fi.name]), MSG_NOTIFY);
+    end
+    else
+    begin
+      e_WriteLog(Format('[%s]: [%s : %s] %u', [fFileName, fi.path, fi.name, st.size]), MSG_NOTIFY);
+      st.Free;
+    end;
+  end;
+  //fIter.volume.OpenFileByIndex(0);
+  }
 
   Result := True;
 end;