DEADSOFTWARE

allow resources in non current directory (warning: res downloader are broken)
[d2df-sdl.git] / src / game / g_map.pas
index 392d45b328918d865718815ad1daff07c0889db1..95bb1a02fd813f82536e759ee6a2b0cfa1f86f8c 100644 (file)
@@ -226,7 +226,7 @@ var
   gLiftMap: array of array of DWORD;
   gWADHash: TMD5Digest;
   BackID:  DWORD = DWORD(-1);
-  gExternalResources: TStringList;
+  gExternalResources: array of TDiskFileInfo = nil;
   gMovingWallIds: array of Integer = nil;
 
   gdbg_map_use_accel_render: Boolean = true;
@@ -253,7 +253,7 @@ implementation
 
 uses
   {$INCLUDE ../nogl/noGLuses.inc}
-  e_input, g_main, e_log, e_texture, g_items, g_gfx, g_console,
+  e_input, g_main, e_log, e_texture, e_res, g_items, g_gfx, g_console,
   g_weapons, g_game, g_sound, e_sound, CONFIG,
   g_options, g_triggers, g_player,
   Math, g_monsters, g_saveload, g_language, g_netmsg,
@@ -345,8 +345,8 @@ begin
 
   try
     e_LogWritefln('parsing "mapdef.txt"...', []);
-    st := openDiskFileRO(DataDir+'mapdef.txt');
-    e_LogWritefln('found local "%smapdef.txt"', [DataDir]);
+    st := e_OpenResourceRO(DataDirs, 'mapdef.txt');
+    e_LogWritefln('found local "mapdef.txt"', []);
   except
     st := nil;
   end;
@@ -902,20 +902,14 @@ end;
 
 function GetReplacementWad (WadName: AnsiString): AnsiString;
 begin
-  if (length(WadName) = 0) then
+  result := '';
+  if WadName <> '' then
   begin
-    result := '';
-  end
-  else
-  begin
-    //e_LogWritefln('GetReplacementWad: 000: old=%s', [WadName]);
-    result := g_Res_FindReplacementWad(WadName);
-    //e_LogWritefln('GetReplacementWad: 001: old=%s; new=%s', [WadName, result]);
+    result := WadName;
+    if g_Game_IsClient then
+      result := g_Res_FindReplacementWad(WadName);
     if (result = WadName) then
-    begin
-      result := GameDir+'/wads/'+result;
-      //e_LogWritefln('GetReplacementWad: 002: old=%s; new=%s', [WadName, result]);
-    end;
+      result := e_FindWad(WadDirs, result)
   end;
 end;
 
@@ -1466,55 +1460,66 @@ begin
     Result := '';
 end;
 
-procedure addResToExternalResList(res: string);
+
+procedure addResToExternalResList (res: AnsiString);
+var
+  uname: AnsiString;
+  f: Integer;
+  fi: TDiskFileInfo;
 begin
-  //e_LogWritefln('DBG: ***trying external resource %s', [res]);
-  res := toLowerCase1251(extractWadName(res));
-  // ignore "standart.wad"
-  if (res <> '') {and (res <> 'standart.wad')} and (gExternalResources.IndexOf(res) = -1) then
+  if g_Game_IsClient or not g_Game_IsNet then exit;
+  if (length(res) = 0) then exit; // map wad
+  res := extractWadName(res);
+  if (length(res) = 0) then exit; // map wad
+  uname := toLowerCase1251(res);
+  // do not add duplicates
+  for f := 0 to High(gExternalResources) do
   begin
-    //e_LogWritefln('DBG: added external resource %s', [res]);
-    gExternalResources.Add(res);
+    if (gExternalResources[f].userName = uname) then exit;
   end;
-end;
-
-procedure generateExternalResourcesList({mapReader: TMapReader_1}map: TDynRecord);
-//var
-  //textures: TTexturesRec1Array;
-  //textures: TDynField;
-  //trec: TDynRecord;
-  //mapHeader: TMapHeaderRec_1;
-  //i: integer;
-  //resFile: String = '';
-begin
-  if gExternalResources = nil then
-    gExternalResources := TStringList.Create;
-
-  gExternalResources.Clear;
-
-  (*
-  {
-  textures := GetTextures(map);
-  for i := 0 to High(textures) do
+  // add new resource
+  fi.userName := uname;
+  if (not GetDiskFileInfo(GameDir+'/wads/'+res, fi)) then
   begin
-    addResToExternalResList(resFile);
+    fi.tag := -1;
+  end
+  else
+  begin
+    fi.tag := 0; // non-zero means "cannot caclucate hash"
+    try
+      fi.hash := MD5File(fi.diskName);
+    except
+      fi.tag := -1;
+    end;
   end;
-  }
+  //e_LogWritefln('addext: res=[%s]; uname=[%s]; diskName=[%s]', [res, fi.userName, fi.diskName]);
+  SetLength(gExternalResources, length(gExternalResources)+1);
+  gExternalResources[High(gExternalResources)] := fi;
+end;
+
 
-  textures := map['texture'];
-  if (textures <> nil) then
+procedure compactExtResList ();
+var
+  src, dest: Integer;
+begin
+  src := 0;
+  dest := 0;
+  for src := 0 to High(gExternalResources) do
   begin
-    for trec in textures do
+    if (gExternalResources[src].tag = 0) then
     begin
-      addResToExternalResList(resFile);
+      // copy it
+      if (dest <> src) then gExternalResources[dest] := gExternalResources[src];
+      Inc(dest);
     end;
   end;
+  if (dest <> length(gExternalResources)) then SetLength(gExternalResources, dest);
+end;
 
-  textures := nil;
-  *)
-
-  //mapHeader := GetMapHeader(map);
 
+procedure generateExternalResourcesList (map: TDynRecord);
+begin
+  SetLength(gExternalResources, 0);
   addResToExternalResList(map.MusicName);
   addResToExternalResList(map.SkyName);
 end;
@@ -2212,21 +2217,13 @@ begin
     begin
       e_WriteLog('  Loading sky: ' + gMapInfo.SkyName, TMsgType.Notify);
       g_Game_SetLoadingText(_lc[I_LOAD_SKY], 0, False);
-      FileName := g_ExtractWadName(gMapInfo.SkyName);
-
-      if (FileName <> '') then FileName := GameDir+'/wads/'+FileName else FileName := g_ExtractWadName(Res);
-
       if gTextureFilter then TEXTUREFILTER := GL_LINEAR else TEXTUREFILTER := GL_NEAREST;
       try
-        s := FileName+':'+g_ExtractFilePathName(gMapInfo.SkyName);
+        s := e_GetResourcePath(WadDirs, gMapInfo.SkyName, g_ExtractWadName(Res));
         if g_Texture_CreateWAD(BackID, s) then
-        begin
-          g_Game_SetupScreenSize();
-        end
+          g_Game_SetupScreenSize
         else
-        begin
-          g_FatalError(Format(_lc[I_GAME_ERROR_SKY], [s]));
-        end;
+          g_FatalError(Format(_lc[I_GAME_ERROR_SKY], [s]))
       finally
         TEXTUREFILTER := GL_NEAREST;
       end;
@@ -2238,16 +2235,8 @@ begin
     begin
       e_WriteLog('  Loading music: ' + gMapInfo.MusicName, TMsgType.Notify);
       g_Game_SetLoadingText(_lc[I_LOAD_MUSIC], 0, False);
-      FileName := g_ExtractWadName(gMapInfo.MusicName);
-
-      if FileName <> '' then
-        FileName := GameDir+'/wads/'+FileName
-      else
-        begin
-          FileName := g_ExtractWadName(Res);
-        end;
 
-      s := FileName+':'+g_ExtractFilePathName(gMapInfo.MusicName);
+      s := e_GetResourcePath(WadDirs, gMapInfo.MusicName, g_ExtractWadName(Res));
       if g_Sound_CreateWADEx(gMapInfo.MusicName, s, True) then
         ok := True
       else
@@ -2300,6 +2289,7 @@ begin
     end;
   end;
 
+  compactExtResList();
   e_WriteLog('Done loading map.', TMsgType.Notify);
   Result := True;
 end;