DEADSOFTWARE

autodetect portable installation. --cwd -> --like-windoze
[d2df-sdl.git] / src / engine / e_res.pas
index e2f888955076063cf022a58d1c3bda40b2be01ce..e48cc32ed5746264150eb419cbf14ee36db99135 100644 (file)
@@ -48,7 +48,11 @@ interface
   function e_FindResource (dirs: SSArray; var name: AnsiString; nameIsDir: Boolean = false): Boolean;
   function e_FindWad (dirs: SSArray; name: AnsiString): AnsiString;
 
-  {--- append dirs to 'path.wad:\file'. if disk is void, append defWad ---}
+  {--- returns relative wad name; never empty string ---}
+  function e_FindWadRel (dirs: SSArray; name: AnsiString): AnsiString;
+
+  {--- prepend dirs to 'disk.wad:\file'. if empty disk string then prepend defWad  ---}
+  {--- return empty string if error occured or 'path/to/disk.wad:\file' on success ---}
   function e_GetResourcePath (dirs: SSArray; path: AnsiString; defWad: AnsiString): AnsiString;
 
   {--- same as SysUtils.FinFirst ---}
@@ -59,6 +63,8 @@ interface
   {--- creates all necessary subdirs, if it can ---}
   function e_GetWriteableDir (dirs: SSArray; required: Boolean=true): AnsiString;
 
+  function e_CanCreateFilesAt (dir: AnsiString): Boolean;
+
 implementation
 
   uses WadReader, e_log, hashtable;
@@ -215,19 +221,44 @@ implementation
     end
   end;
 
+  function e_FindWadRel (dirs: SSArray; name: AnsiString): AnsiString;
+  var
+    s: AnsiString;
+    maxpfx: AnsiString = '';
+    pfx: AnsiString;
+  begin
+    result := name;
+    if not findFileCI(name) then exit;
+    for s in dirs do
+    begin
+      if (length(s) = 0) then continue;
+      if (length(name) <= length(s)) then continue;
+      if (length(s) < length(maxpfx)) then continue;
+      pfx := s;
+      if not findFileCI(pfx, true) then continue;
+      if (pfx[length(pfx)] <> '/') and (pfx[length(pfx)] <> '\') then pfx := pfx+'/';
+      if (length(pfx)+1 > length(name)) then continue;
+      if (strEquCI1251(copy(name, 1, length(pfx)), pfx)) then maxpfx := pfx;
+    end;
+    if (length(maxpfx) > 0) then
+    begin
+      result := name;
+      Delete(result, 1, length(maxpfx));
+    end;
+  end;
+
   function e_GetResourcePath (dirs: SSArray; path: AnsiString; defWad: AnsiString): AnsiString;
     var diskName, fileName: AnsiString;
   begin
     if debug_e_res then
-      e_LogWritefln('e_GetResourcePath0 %s (%s)', [path, defWad]);
+      e_LogWritefln('e_GetResourcePath %s (%s)', [path, defWad]);
     assert(length(dirs) > 0);
     assert(path <> '');
     assert(defWad <> '');
     diskName := g_ExtractWadName(path);
     fileName := g_ExtractFilePathName(path);
     if diskName = '' then diskName := defWad else diskName := e_FindWad(dirs, diskName);
-    assert(diskName <> '', 'oh fuck, wad "' + diskName + '" not founded');
-    result := diskName + ':\' + fileName;
+    if diskName = '' then result := '' else result := diskName + ':\' + fileName;
     if debug_e_res then
       e_LogWritefln('  this>>> %s', [result]);
   end;
@@ -251,7 +282,7 @@ implementation
   end;
 
   // k8: sorry. i know that this sux, but checking directory access rights is unreliable (unportable).
-  function canCreateFiles (dir: AnsiString): Boolean;
+  function e_CanCreateFilesAt (dir: AnsiString): Boolean;
   var
     f: Integer;
     st: TStream = nil;
@@ -308,7 +339,7 @@ implementation
           result := dirs[f];
           if (findFileCI(result, true)) then
           begin
-            if canCreateFiles(result) then
+            if e_CanCreateFilesAt(result) then
             begin
               if not assigned(writeableDirs) then writeableDirs := THashStrCIStr.Create();
               writeableDirs.put(dirs[f], result);