X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_saveload.pas;h=5bf8974ae6aca186ffcc7e71f4bf078c7f1443ba;hb=refs%2Fheads%2Frenders_updated;hp=dee199260879344aab173bd924a2a88af89631b7;hpb=20114d602d19e4e913ea1a7c22f2031bd7f54677;p=d2df-sdl.git diff --git a/src/game/g_saveload.pas b/src/game/g_saveload.pas index dee1992..5bf8974 100644 --- a/src/game/g_saveload.pas +++ b/src/game/g_saveload.pas @@ -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 @@ -19,8 +18,7 @@ unit g_saveload; interface uses - SysUtils, Classes, - e_graphics, g_phys, g_textures; + SysUtils, Classes, g_phys; function g_GetSaveName (n: Integer; out valid: Boolean): AnsiString; @@ -38,11 +36,20 @@ procedure Obj_LoadState (o: PObj; st: TStream); implementation uses + {$IFDEF ENABLE_GIBS} + g_gibs, + {$ENDIF} + {$IFDEF ENABLE_CORPSES} + g_corpses, + {$ENDIF} + {$IFDEF ENABLE_SHELLS} + g_shells, + {$ENDIF} MAPDEF, utils, xstreams, 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; + g_basic, Math, wadreader, + g_weapons, g_player, g_console, g_window, + e_log, e_res, g_language, g_options; const SAVE_SIGNATURE = $56534644; // 'DFSV' @@ -102,9 +109,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,11 +126,11 @@ begin try // Îòêðûâàåì ôàéë ñîõðàíåíèé filename := buildSaveName(n); - st := openDiskFileRO(filename); + st := e_OpenResourceRO(SaveDirs, filename); try if not utils.checkSign(st, 'DFSV') then begin - e_LogWritefln('GetSaveName: not a save file: ''%s''', [st], MSG_WARNING); + e_LogWritefln('GetSaveName: not a save file: ''%s''', [st], TMsgType.Warning); //raise XStreamError.Create('invalid save game signature'); exit; end; @@ -136,7 +141,7 @@ begin stlen := utils.readWord(st); if (stlen < 1) or (stlen > 64) then begin - e_LogWritefln('GetSaveName: not a save file: ''%s''', [st], MSG_WARNING); + e_LogWritefln('GetSaveName: not a save file: ''%s''', [st], TMsgType.Warning); //raise XStreamError.Create('invalid save game version'); exit; end; @@ -164,6 +169,70 @@ begin end; end; +procedure g_Player_Corpses_SaveState (st: TStream); + {$IFDEF ENABLE_CORPSES} + var i: Integer; + {$ENDIF} + var count: Integer; +begin + count := 0; + {$IFDEF ENABLE_CORPSES} + for i := 0 to High(gCorpses) do + if (gCorpses[i] <> nil) then + Inc(count); + {$ENDIF} + utils.writeInt(st, LongInt(count)); + {$IFDEF ENABLE_CORPSES} + if count > 0 then + begin + for i := 0 to High(gCorpses) do + begin + if gCorpses[i] <> nil then + begin + utils.writeStr(st, gCorpses[i].Model.GetName()); + utils.writeBool(st, gCorpses[i].Mess); + gCorpses[i].SaveState(st); + end; + end; + end; + {$ENDIF} +end; + +procedure g_Player_Corpses_LoadState (st: TStream); + {$IFDEF ENABLE_CORPSES} + var str: String; b: Boolean; i: Integer; + {$ENDIF} + var count: Integer; +begin + assert(st <> nil); + + {$IFDEF ENABLE_GIBS} + g_Gibs_RemoveAll; + {$ENDIF} + {$IFDEF ENABLE_SHELLS} + g_Shells_RemoveAll; // ??? + {$ENDIF} + {$IFDEF ENABLE_CORPSES} + g_Corpses_RemoveAll; + {$ENDIF} + + count := utils.readLongInt(st); + + {$IFDEF ENABLE_CORPSES} + if (count < 0) or (count > Length(gCorpses)) then + raise XStreamError.Create('invalid number of corpses'); + for i := 0 to count - 1 do + begin + str := utils.readStr(st); + b := utils.readBool(st); + gCorpses[i] := TCorpse.Create(0, 0, str, b); + gCorpses[i].LoadState(st); + end; + {$ELSE} + if count <> 0 then + raise XStreamError.Create('corpses not supported in this version'); + {$ENDIF} +end; function g_SaveGameTo (const filename: AnsiString; const aname: AnsiString; deleteOnError: Boolean=true): Boolean; var @@ -173,7 +242,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 +252,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 +266,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)); // Èãðîâûå îïöèè @@ -278,9 +347,10 @@ begin begin st.Free(); g_Console_Add(_lc[I_GAME_ERROR_SAVE]); - e_WriteLog('SaveState Error: '+e.message, MSG_WARNING); + 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 +363,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 +382,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...', MSG_NOTIFY); + 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 +425,7 @@ begin // Ëèìèò âðåìåíè Game_TimeLimit := utils.readWord(st); // Ëèìèò î÷êîâ - Game_GoalLimit := utils.readWord(st); + Game_ScoreLimit := utils.readWord(st); // Ëèìèò æèçíåé Game_MaxLives := utils.readByte(st); // Èãðîâûå îïöèè @@ -395,21 +467,16 @@ begin gGameSettings.GameMode := Game_Mode; gSwitchGameMode := Game_Mode; gGameSettings.TimeLimit := Game_TimeLimit; - gGameSettings.GoalLimit := Game_GoalLimit; + gGameSettings.ScoreLimit := Game_ScoreLimit; gGameSettings.MaxLives := IfThen(Game_Mode = GM_CTF, 0, Game_MaxLives); gGameSettings.Options := Game_Options; end; 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 +556,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]); - e_WriteLog('LoadState Error: '+e.message, MSG_WARNING); - {$IF DEFINED(D2F_DEBUG)}e_LogWritefln('stream error position: 0x%08x', [errpos], MSG_WARNING);{$ENDIF} + 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 +596,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;