DEADSOFTWARE

Game: Use proper syntax of sets for game options instead of raw bitwise operations
[d2df-sdl.git] / src / game / g_saveload.pas
index ad438f89174172171fa0d05b6b174cc982c5cd20..2d91494b1e50b13806bb4c193b319b0ed7e7c2af 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
@@ -42,7 +41,7 @@ uses
   g_game, g_items, g_map, g_monsters, g_triggers,
   g_basic, g_main, Math, wadreader,
   g_weapons, g_player, g_console,
-  e_log, g_language;
+  e_log, e_res, g_language;
 
 const
   SAVE_SIGNATURE = $56534644; // 'DFSV'
@@ -102,9 +101,7 @@ end;
 
 function buildSaveName (n: Integer): AnsiString;
 begin
-  result := '';
-  if (n < 0) or (n > 65535) then exit;
-  result := formatstrf('%sSAVGAME%s.DAT', [DataDir, n]);
+  result := 'SAVGAME' + IntToStr(n) + '.DAT'
 end;
 
 
@@ -121,7 +118,7 @@ begin
   try
     // Îòêðûâàåì ôàéë ñîõðàíåíèé
     filename := buildSaveName(n);
-    st := openDiskFileRO(filename);
+    st := e_OpenResourceRO(SaveDirs, filename);
     try
       if not utils.checkSign(st, 'DFSV') then
       begin
@@ -173,7 +170,7 @@ var
 begin
   result := false;
   try
-    st := createDiskFile(filename);
+    st := e_CreateResource(SaveDirs, filename);
     try
       utils.writeSign(st, 'DFSV');
       utils.writeInt(st, Byte(SAVE_VERSION));
@@ -183,7 +180,7 @@ begin
       //if (Length(gCurrentMapFileName) <> 0) then e_LogWritefln('SAVE: current map is ''%s''...', [gCurrentMapFileName]);
       utils.writeStr(st, gCurrentMapFileName);
       // Ïóòü ê êàðòå
-      utils.writeStr(st, gGameSettings.WAD);
+      utils.writeStr(st, ExtractFileName(gGameSettings.WAD));
       // Èìÿ êàðòû
       utils.writeStr(st, g_ExtractFileName(gMapInfo.Map));
       // Êîëè÷åñòâî èãðîêîâ
@@ -197,7 +194,7 @@ begin
       // Ëèìèò âðåìåíè
       utils.writeInt(st, Word(gGameSettings.TimeLimit));
       // Ëèìèò î÷êîâ
-      utils.writeInt(st, Word(gGameSettings.GoalLimit));
+      utils.writeInt(st, Word(gGameSettings.ScoreLimit));
       // Ëèìèò æèçíåé
       utils.writeInt(st, Byte(gGameSettings.MaxLives));
       // Èãðîâûå îïöèè
@@ -281,6 +278,7 @@ begin
         e_WriteLog('SaveState Error: '+e.message, TMsgType.Warning);
         if deleteOnError then DeleteFile(filename);
         {$IF DEFINED(D2F_DEBUG)}e_WriteStackTrace(e.message);{$ENDIF}
+e_WriteStackTrace(e.message);
         result := false;
       end;
   end;
@@ -293,7 +291,7 @@ var
   WAD_Path, Map_Name: AnsiString;
   nPlayers: Integer;
   Game_Type, Game_Mode, Game_MaxLives: Byte;
-  Game_TimeLimit, Game_GoalLimit: Word;
+  Game_TimeLimit, Game_ScoreLimit: Word;
   Game_Time, Game_Options: Cardinal;
   Game_CoopMonstersKilled,
   Game_CoopSecretsFound,
@@ -312,14 +310,16 @@ begin
   result := false;
 
   try
-    st := openDiskFileRO(filename);
+    st := e_OpenResourceRO(SaveDirs, filename);
     try
       if not utils.checkSign(st, 'DFSV') then raise XStreamError.Create('invalid save game signature');
       if (utils.readByte(st) <> SAVE_VERSION) then raise XStreamError.Create('invalid save game version');
 
       e_WriteLog('Loading saved game...', TMsgType.Notify);
 
-      {$IF DEFINED(D2F_DEBUG)}try{$ENDIF}
+{$IF DEFINED(D2F_DEBUG)}
+      try
+{$ENDIF}
         //g_Game_Free(false); // don't free textures for the same map
         g_Game_ClearLoading();
         g_Game_SetLoadingText(_lc[I_LOAD_SAVE_FILE], 0, False);
@@ -353,7 +353,7 @@ begin
         // Ëèìèò âðåìåíè
         Game_TimeLimit := utils.readWord(st);
         // Ëèìèò î÷êîâ
-        Game_GoalLimit := utils.readWord(st);
+        Game_ScoreLimit := utils.readWord(st);
         // Ëèìèò æèçíåé
         Game_MaxLives := utils.readByte(st);
         // Èãðîâûå îïöèè
@@ -375,41 +375,26 @@ begin
         ///// /////
 
         // Çàãðóæàåì êàðòó:
-        ZeroMemory(@gGameSettings, sizeof(TGameSettings));
+        gGameSettings := Default(TGameSettings);
         gAimLine := false;
         gShowMap := false;
-        if (Game_Type = GT_NONE) or (Game_Type = GT_SINGLE) then
-        begin
-          // Íàñòðîéêè èãðû
-          gGameSettings.GameType := GT_SINGLE;
-          gGameSettings.MaxLives := 0;
-          gGameSettings.Options := gGameSettings.Options+GAME_OPTION_ALLOWEXIT;
-          gGameSettings.Options := gGameSettings.Options+GAME_OPTION_MONSTERS;
-          gGameSettings.Options := gGameSettings.Options+GAME_OPTION_BOTVSMONSTER;
-          gSwitchGameMode := GM_SINGLE;
-        end
-        else
-        begin
-          // Íàñòðîéêè èãðû
-          gGameSettings.GameType := GT_CUSTOM;
-          gGameSettings.GameMode := Game_Mode;
-          gSwitchGameMode := Game_Mode;
-          gGameSettings.TimeLimit := Game_TimeLimit;
-          gGameSettings.GoalLimit := Game_GoalLimit;
-          gGameSettings.MaxLives := IfThen(Game_Mode = GM_CTF, 0, Game_MaxLives);
-          gGameSettings.Options := Game_Options;
-        end;
+        // Íàñòðîéêè èãðû
+        gGameSettings.GameType := Game_Type;
+        gGameSettings.GameMode := Game_Mode;
+        gGameSettings.TimeLimit := Game_TimeLimit;
+        gGameSettings.ScoreLimit := Game_ScoreLimit;
+        gGameSettings.MaxLives := Game_MaxLives;
+        gGameSettings.Options := TGameOptions(Game_Options);
+        gSwitchGameMode := Game_Mode;
         g_Game_ExecuteEvent('ongamestart');
 
         // Óñòàíîâêà ðàçìåðîâ îêîí èãðîêîâ
         g_Game_SetupScreenSize();
 
         // Çàãðóçêà è çàïóñê êàðòû
-        if not g_Game_StartMap(WAD_Path+':\'+Map_Name, True, curmapfile) then
-        begin
-          g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [WAD_Path + ':\' + Map_Name]));
-          exit;
-        end;
+        //FIXME: save/load `asMegawad`
+        if not g_Game_StartMap(false{asMegawad}, WAD_Path+':\'+Map_Name, True, curmapfile) then
+          raise Exception.Create(Format(_lc[I_GAME_ERROR_MAP_LOAD], [WAD_Path + ':\' + Map_Name]));
 
         // Íàñòðîéêè èãðîêîâ è áîòîâ
         g_Player_Init();
@@ -489,26 +474,38 @@ begin
         // done
         gLoadGameMode := false;
         result := true;
-      {$IF DEFINED(D2F_DEBUG)}
+{$IF DEFINED(D2F_DEBUG)}
       except
         begin
           errpos := LongWord(st.position);
           raise;
         end;
       end;
-      {$ENDIF}
+{$ENDIF}
     finally
       st.Free();
     end;
   except
+    on e: EFileNotFoundException do
+      begin
+        g_Console_Add(_lc[I_GAME_ERROR_LOAD]);
+        g_Console_Add('LoadState Error: '+e.message);
+        e_WriteLog('LoadState Error: '+e.message, TMsgType.Warning);
+        gLoadGameMode := false;
+        result := false;
+      end;
     on e: Exception do
       begin
         g_Console_Add(_lc[I_GAME_ERROR_LOAD]);
+        g_Console_Add('LoadState Error: '+e.message);
         e_WriteLog('LoadState Error: '+e.message, TMsgType.Warning);
         {$IF DEFINED(D2F_DEBUG)}e_LogWritefln('stream error position: 0x%08x', [errpos], TMsgType.Warning);{$ENDIF}
         gLoadGameMode := false;
-        result := true;
-        if not gameCleared then g_Game_Free();
+        result := false;
+        if gState <> STATE_MENU then
+          g_FatalError(_lc[I_GAME_ERROR_LOAD])
+        else if not gameCleared then
+          g_Game_Free();
         {$IF DEFINED(D2F_DEBUG)}e_WriteStackTrace(e.message);{$ENDIF}
       end;
   end;
@@ -517,16 +514,12 @@ end;
 
 function g_SaveGame (n: Integer; const aname: AnsiString): Boolean;
 begin
-  result := false;
-  if (n < 0) or (n > 65535) then exit;
   result := g_SaveGameTo(buildSaveName(n), aname, true);
 end;
 
 
 function g_LoadGame (n: Integer): Boolean;
 begin
-  result := false;
-  if (n < 0) or (n > 65535) then exit;
   result := g_LoadGameFrom(buildSaveName(n));
 end;