1 //-------------------------------------------------------------------------
2 /*
3 Copyright (C) 2010-2019 EDuke32 developers and contributors
4 Copyright (C) 2019 Nuke.YKT
5 
6 This file is part of NBlood.
7 
8 NBlood is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License version 2
10 as published by the Free Software Foundation.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 
16 See the GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 */
22 //-------------------------------------------------------------------------
23 #include <stdio.h>
24 #include "build.h"
25 #include "compat.h"
26 #include "mmulti.h"
27 #include "common_game.h"
28 #include "config.h"
29 #include "ai.h"
30 #include "asound.h"
31 #include "blood.h"
32 #include "demo.h"
33 #include "globals.h"
34 #include "db.h"
35 #include "messages.h"
36 #include "menu.h"
37 #include "network.h"
38 #include "loadsave.h"
39 #include "resource.h"
40 #include "screen.h"
41 #include "sectorfx.h"
42 #include "seq.h"
43 #include "sfx.h"
44 #include "sound.h"
45 #include "view.h"
46 #ifdef NOONE_EXTENSIONS
47 #include "nnexts.h"
48 #endif
49 
50 GAMEOPTIONS gSaveGameOptions[10];
51 char *gSaveGamePic[10];
52 unsigned int gSavedOffset = 0;
53 
54 unsigned int dword_27AA38 = 0;
55 unsigned int dword_27AA3C = 0;
56 unsigned int dword_27AA40 = 0;
57 void *dword_27AA44 = NULL;
58 
59 LoadSave LoadSave::head(123);
60 FILE *LoadSave::hSFile = NULL;
61 int LoadSave::hLFile = -1;
62 
63 short word_27AA54 = 0;
64 
sub_76FD4(void)65 void sub_76FD4(void)
66 {
67     if (!dword_27AA44)
68         dword_27AA44 = Resource::Alloc(0x186a0);
69 }
70 
Save(void)71 void LoadSave::Save(void)
72 {
73     ThrowError("Pure virtual function called");
74 }
75 
Load(void)76 void LoadSave::Load(void)
77 {
78     ThrowError("Pure virtual function called");
79 }
80 
Read(void * pData,int nSize)81 void LoadSave::Read(void *pData, int nSize)
82 {
83     dword_27AA38 += nSize;
84     dassert(hLFile != -1);
85     if (kread(hLFile, pData, nSize) != nSize)
86         ThrowError("Error reading save file.");
87 }
88 
Write(void * pData,int nSize)89 void LoadSave::Write(void *pData, int nSize)
90 {
91     dword_27AA38 += nSize;
92     dword_27AA3C += nSize;
93     dassert(hSFile != NULL);
94     if (fwrite(pData, 1, nSize, hSFile) != (size_t)nSize)
95         ThrowError("File error #%d writing save file.", errno);
96 }
97 
LoadGame(char * pzFile)98 void LoadSave::LoadGame(char *pzFile)
99 {
100     bool demoWasPlayed = gDemo.at1;
101     if (gDemo.at1)
102         gDemo.Close();
103 
104     sndKillAllSounds();
105     sfxKillAllSounds();
106     ambKillAll();
107     seqKillAll();
108     if (!gGameStarted)
109     {
110         memset(xsprite, 0, sizeof(xsprite));
111         memset(sprite, 0, sizeof(spritetype)*kMaxSprites);
112         automapping = 1;
113     }
114     hLFile = kopen4load(pzFile, 0);
115     if (hLFile == -1)
116         ThrowError("Error loading save file.");
117     LoadSave *rover = head.next;
118     while (rover != &head)
119     {
120         rover->Load();
121         rover = rover->next;
122     }
123     kclose(hLFile);
124     hLFile = -1;
125     if (!gGameStarted)
126         scrLoadPLUs();
127     InitSectorFX();
128     viewInitializePrediction();
129     PreloadCache();
130     if (!bVanilla && !gMe->packSlots[1].isActive) // if diving suit is not active, turn off reverb sound effect
131         sfxSetReverb(0);
132     ambInit();
133 #ifdef YAX_ENABLE
134     yax_update(numyaxbunches > 0 ? 2 : 1);
135 #endif
136     memset(myMinLag, 0, sizeof(myMinLag));
137     otherMinLag = 0;
138     myMaxLag = 0;
139     gNetFifoClock = 0;
140     gNetFifoTail = 0;
141     memset(gNetFifoHead, 0, sizeof(gNetFifoHead));
142     gPredictTail = 0;
143     gNetFifoMasterTail = 0;
144     memset(gFifoInput, 0, sizeof(gFifoInput));
145     memset(gChecksum, 0, sizeof(gChecksum));
146     memset(gCheckFifo, 0, sizeof(gCheckFifo));
147     memset(gCheckHead, 0, sizeof(gCheckHead));
148     gSendCheckTail = 0;
149     gCheckTail = 0;
150     gBufferJitter = 0;
151     bOutOfSync = 0;
152     for (int i = 0; i < gNetPlayers; i++)
153         playerSetRace(&gPlayer[i], gPlayer[i].lifeMode);
154     if (VanillaMode())
155         viewSetMessage("");
156     else
157         gGameMessageMgr.Clear();
158     viewSetErrorMessage("");
159     if (!gGameStarted)
160     {
161         netWaitForEveryone(0);
162         memset(gPlayerReady, 0, sizeof(gPlayerReady));
163     }
164     gFrameTicks = 0;
165     gFrame = 0;
166     gCacheMiss = 0;
167     gFrameRate = 0;
168     totalclock = 0;
169     gPaused = 0;
170     gGameStarted = 1;
171     bVanilla = false;
172 
173 
174 #ifdef USE_STRUCT_TRACKERS
175     Bmemset(sectorchanged, 0, sizeof(sectorchanged));
176     Bmemset(spritechanged, 0, sizeof(spritechanged));
177     Bmemset(wallchanged, 0, sizeof(wallchanged));
178 #endif
179 
180 #ifdef USE_OPENGL
181     Polymost_prepare_loadboard();
182 #endif
183 
184 #ifdef POLYMER
185     if (videoGetRenderMode() == REND_POLYMER)
186         polymer_loadboard();
187 
188     // this light pointer nulling needs to be outside the videoGetRenderMode check
189     // because we might be loading the savegame using another renderer but
190     // change to Polymer later
191     for (int i=0; i<kMaxSprites; i++)
192     {
193         gPolymerLight[i].lightptr = NULL;
194         gPolymerLight[i].lightId = -1;
195     }
196 #endif
197 
198     if ((unsigned)gGameOptions.nEpisode >= gEpisodeCount || (unsigned)gGameOptions.nLevel >= gEpisodeInfo[gGameOptions.nEpisode].nLevels
199         || Bstrcasecmp(gEpisodeInfo[gGameOptions.nEpisode].levelsInfo[gGameOptions.nLevel].Filename, gGameOptions.zLevelName) != 0)
200     {
201         if (!gSysRes.Lookup(gGameOptions.zLevelName, "MAP"))
202         {
203             gGameOptions.nEpisode = 0;
204             gGameOptions.nLevel = 0;
205         }
206         else
207         {
208             levelAddUserMap(gGameOptions.zLevelName);
209         }
210     }
211 
212     if (MusicRestartsOnLoadToggle
213         || demoWasPlayed
214         || (gMusicPrevLoadedEpisode != gGameOptions.nEpisode || gMusicPrevLoadedLevel != gGameOptions.nLevel))
215     {
216         levelTryPlayMusicOrNothing(gGameOptions.nEpisode, gGameOptions.nLevel);
217     }
218     gMusicPrevLoadedEpisode = gGameOptions.nEpisode;
219     gMusicPrevLoadedLevel = gGameOptions.nLevel;
220 
221     netBroadcastPlayerInfo(myconnectindex);
222     //sndPlaySong(gGameOptions.zLevelSong, 1);
223 }
224 
SaveGame(char * pzFile)225 void LoadSave::SaveGame(char *pzFile)
226 {
227     hSFile = fopen(pzFile, "wb");
228     if (hSFile == NULL)
229         ThrowError("File error #%d creating save file.", errno);
230     dword_27AA38 = 0;
231     dword_27AA40 = 0;
232     LoadSave *rover = head.next;
233     while (rover != &head)
234     {
235         rover->Save();
236         if (dword_27AA38 > dword_27AA40)
237             dword_27AA40 = dword_27AA38;
238         dword_27AA38 = 0;
239         rover = rover->next;
240     }
241     fclose(hSFile);
242     hSFile = NULL;
243 }
244 
245 class MyLoadSave : public LoadSave
246 {
247 public:
248     virtual void Load(void);
249     virtual void Save(void);
250 };
251 
Load(void)252 void MyLoadSave::Load(void)
253 {
254     psky_t *pSky = tileSetupSky(0);
255     int id;
256     Read(&id, sizeof(id));
257     if (id != 0x5653424e/*'VSBN'*/)
258         ThrowError("Old saved game found");
259     short version;
260     Read(&version, sizeof(version));
261     if (version != BYTEVERSION)
262         ThrowError("Incompatible version of saved game found!");
263     Read(&gGameOptions, sizeof(gGameOptions));
264     Read(&numsectors, sizeof(numsectors));
265     Read(&numwalls, sizeof(numwalls));
266     Read(&numsectors, sizeof(numsectors));
267     int nNumSprites;
268     Read(&nNumSprites, sizeof(nNumSprites));
269     memset(sector, 0, sizeof(sector[0])*kMaxSectors);
270     memset(wall, 0, sizeof(wall[0])*kMaxWalls);
271     memset(sprite, 0, sizeof(sprite[0])*kMaxSprites);
272     Read(sector, sizeof(sector[0])*numsectors);
273     Read(wall, sizeof(wall[0])*numwalls);
274     Read(sprite, sizeof(sprite[0])*kMaxSprites);
275     Read(qsector_filler, sizeof(qsector_filler[0])*numsectors);
276     Read(qsprite_filler, sizeof(qsprite_filler[0])*kMaxSprites);
277     Read(&randomseed, sizeof(randomseed));
278     Read(&parallaxtype, sizeof(parallaxtype));
279     Read(&showinvisibility, sizeof(showinvisibility));
280     Read(&pSky->horizfrac, sizeof(pSky->horizfrac));
281     Read(&pSky->yoffs, sizeof(pSky->yoffs));
282     Read(&pSky->yscale, sizeof(pSky->yscale));
283     Read(&gVisibility, sizeof(gVisibility));
284     Read(&g_visibility, sizeof(g_visibility));
285     Read(&parallaxvisibility, sizeof(parallaxvisibility));
286     Read(pSky->tileofs, sizeof(pSky->tileofs));
287     Read(&pSky->lognumtiles, sizeof(pSky->lognumtiles));
288     Read(headspritesect, sizeof(headspritesect));
289     Read(headspritestat, sizeof(headspritestat));
290     Read(prevspritesect, sizeof(prevspritesect));
291     Read(prevspritestat, sizeof(prevspritestat));
292     Read(nextspritesect, sizeof(nextspritesect));
293     Read(nextspritestat, sizeof(nextspritestat));
294     Read(show2dsector, sizeof(show2dsector));
295     Read(show2dwall, sizeof(show2dwall));
296     Read(show2dsprite, sizeof(show2dsprite));
297     Read(&automapping, sizeof(automapping));
298     Read(gotpic, sizeof(gotpic));
299     Read(gotsector, sizeof(gotsector));
300     Read(&gFrameClock, sizeof(gFrameClock));
301     Read(&gFrameTicks, sizeof(gFrameTicks));
302     Read(&gFrame, sizeof(gFrame));
303     ClockTicks nGameClock;
304     Read(&totalclock, sizeof(totalclock));
305     totalclock = nGameClock;
306     Read(&gLevelTime, sizeof(gLevelTime));
307     Read(&gPaused, sizeof(gPaused));
308     Read(&gbAdultContent, sizeof(gbAdultContent));
309     Read(baseWall, sizeof(baseWall[0])*numwalls);
310     Read(baseSprite, sizeof(baseSprite[0])*nNumSprites);
311     Read(baseFloor, sizeof(baseFloor[0])*numsectors);
312     Read(baseCeil, sizeof(baseCeil[0])*numsectors);
313     Read(velFloor, sizeof(velFloor[0])*numsectors);
314     Read(velCeil, sizeof(velCeil[0])*numsectors);
315     Read(&gHitInfo, sizeof(gHitInfo));
316     Read(&byte_1A76C6, sizeof(byte_1A76C6));
317     Read(&byte_1A76C8, sizeof(byte_1A76C8));
318     Read(&byte_1A76C7, sizeof(byte_1A76C7));
319     Read(&byte_19AE44, sizeof(byte_19AE44));
320     Read(gStatCount, sizeof(gStatCount));
321     Read(nextXSprite, sizeof(nextXSprite));
322     Read(nextXWall, sizeof(nextXWall));
323     Read(nextXSector, sizeof(nextXSector));
324     memset(xsprite, 0, sizeof(xsprite));
325     for (int nSprite = 0; nSprite < kMaxSprites; nSprite++)
326     {
327         if (sprite[nSprite].statnum < kMaxStatus)
328         {
329             int nXSprite = sprite[nSprite].extra;
330             if (nXSprite > 0)
331                 Read(&xsprite[nXSprite], sizeof(XSPRITE));
332         }
333     }
334     memset(xwall, 0, sizeof(xwall));
335     for (int nWall = 0; nWall < numwalls; nWall++)
336     {
337         int nXWall = wall[nWall].extra;
338         if (nXWall > 0)
339             Read(&xwall[nXWall], sizeof(XWALL));
340     }
341     memset(xsector, 0, sizeof(xsector));
342     for (int nSector = 0; nSector < numsectors; nSector++)
343     {
344         int nXSector = sector[nSector].extra;
345         if (nXSector > 0)
346             Read(&xsector[nXSector], sizeof(XSECTOR));
347     }
348     Read(xvel, nNumSprites*sizeof(xvel[0]));
349     Read(yvel, nNumSprites*sizeof(yvel[0]));
350     Read(zvel, nNumSprites*sizeof(zvel[0]));
351     Read(&gMapRev, sizeof(gMapRev));
352     Read(&gSongId, sizeof(gSkyCount));
353     Read(&gFogMode, sizeof(gFogMode));
354 #ifdef NOONE_EXTENSIONS
355     Read(&gModernMap, sizeof(gModernMap));
356 #endif
357 #ifdef YAX_ENABLE
358     Read(&numyaxbunches, sizeof(numyaxbunches));
359 #endif
360     psky_t skyInfo;
361     Read(&skyInfo, sizeof(skyInfo));
362 
363     *tileSetupSky(0) = skyInfo;
364     gCheatMgr.sub_5BCF4();
365 
366 }
367 
Save(void)368 void MyLoadSave::Save(void)
369 {
370     psky_t *pSky = tileSetupSky(0);
371     int nNumSprites = 0;
372     int id = 0x5653424e/*'VSBN'*/;
373     Write(&id, sizeof(id));
374     short version = BYTEVERSION;
375     Write(&version, sizeof(version));
376     for (int nSprite = 0; nSprite < kMaxSprites; nSprite++)
377     {
378         if (sprite[nSprite].statnum < kMaxStatus && nSprite > nNumSprites)
379             nNumSprites = nSprite;
380     }
381     //nNumSprites += 2;
382     nNumSprites++;
383     Write(&gGameOptions, sizeof(gGameOptions));
384     Write(&numsectors, sizeof(numsectors));
385     Write(&numwalls, sizeof(numwalls));
386     Write(&numsectors, sizeof(numsectors));
387     Write(&nNumSprites, sizeof(nNumSprites));
388     Write(sector, sizeof(sector[0])*numsectors);
389     Write(wall, sizeof(wall[0])*numwalls);
390     Write(sprite, sizeof(sprite[0])*kMaxSprites);
391     Write(qsector_filler, sizeof(qsector_filler[0])*numsectors);
392     Write(qsprite_filler, sizeof(qsprite_filler[0])*kMaxSprites);
393     Write(&randomseed, sizeof(randomseed));
394     Write(&parallaxtype, sizeof(parallaxtype));
395     Write(&showinvisibility, sizeof(showinvisibility));
396     Write(&pSky->horizfrac, sizeof(pSky->horizfrac));
397     Write(&pSky->yoffs, sizeof(pSky->yoffs));
398     Write(&pSky->yscale, sizeof(pSky->yscale));
399     Write(&gVisibility, sizeof(gVisibility));
400     Write(&g_visibility, sizeof(g_visibility));
401     Write(&parallaxvisibility, sizeof(parallaxvisibility));
402     Write(pSky->tileofs, sizeof(pSky->tileofs));
403     Write(&pSky->lognumtiles, sizeof(pSky->lognumtiles));
404     Write(headspritesect, sizeof(headspritesect));
405     Write(headspritestat, sizeof(headspritestat));
406     Write(prevspritesect, sizeof(prevspritesect));
407     Write(prevspritestat, sizeof(prevspritestat));
408     Write(nextspritesect, sizeof(nextspritesect));
409     Write(nextspritestat, sizeof(nextspritestat));
410     Write(show2dsector, sizeof(show2dsector));
411     Write(show2dwall, sizeof(show2dwall));
412     Write(show2dsprite, sizeof(show2dsprite));
413     Write(&automapping, sizeof(automapping));
414     Write(gotpic, sizeof(gotpic));
415     Write(gotsector, sizeof(gotsector));
416     Write(&gFrameClock, sizeof(gFrameClock));
417     Write(&gFrameTicks, sizeof(gFrameTicks));
418     Write(&gFrame, sizeof(gFrame));
419     ClockTicks nGameClock = totalclock;
420     Write(&nGameClock, sizeof(nGameClock));
421     Write(&gLevelTime, sizeof(gLevelTime));
422     Write(&gPaused, sizeof(gPaused));
423     Write(&gbAdultContent, sizeof(gbAdultContent));
424     Write(baseWall, sizeof(baseWall[0])*numwalls);
425     Write(baseSprite, sizeof(baseSprite[0])*nNumSprites);
426     Write(baseFloor, sizeof(baseFloor[0])*numsectors);
427     Write(baseCeil, sizeof(baseCeil[0])*numsectors);
428     Write(velFloor, sizeof(velFloor[0])*numsectors);
429     Write(velCeil, sizeof(velCeil[0])*numsectors);
430     Write(&gHitInfo, sizeof(gHitInfo));
431     Write(&byte_1A76C6, sizeof(byte_1A76C6));
432     Write(&byte_1A76C8, sizeof(byte_1A76C8));
433     Write(&byte_1A76C7, sizeof(byte_1A76C7));
434     Write(&byte_19AE44, sizeof(byte_19AE44));
435     Write(gStatCount, sizeof(gStatCount));
436     Write(nextXSprite, sizeof(nextXSprite));
437     Write(nextXWall, sizeof(nextXWall));
438     Write(nextXSector, sizeof(nextXSector));
439     for (int nSprite = 0; nSprite < kMaxSprites; nSprite++)
440     {
441         if (sprite[nSprite].statnum < kMaxStatus)
442         {
443             int nXSprite = sprite[nSprite].extra;
444             if (nXSprite > 0)
445                 Write(&xsprite[nXSprite], sizeof(XSPRITE));
446         }
447     }
448     for (int nWall = 0; nWall < numwalls; nWall++)
449     {
450         int nXWall = wall[nWall].extra;
451         if (nXWall > 0)
452             Write(&xwall[nXWall], sizeof(XWALL));
453     }
454     for (int nSector = 0; nSector < numsectors; nSector++)
455     {
456         int nXSector = sector[nSector].extra;
457         if (nXSector > 0)
458             Write(&xsector[nXSector], sizeof(XSECTOR));
459     }
460     Write(xvel, nNumSprites*sizeof(xvel[0]));
461     Write(yvel, nNumSprites*sizeof(yvel[0]));
462     Write(zvel, nNumSprites*sizeof(zvel[0]));
463     Write(&gMapRev, sizeof(gMapRev));
464     Write(&gSongId, sizeof(gSkyCount));
465     Write(&gFogMode, sizeof(gFogMode));
466 #ifdef NOONE_EXTENSIONS
467     Write(&gModernMap, sizeof(gModernMap));
468 #endif
469 #ifdef YAX_ENABLE
470     Write(&numyaxbunches, sizeof(numyaxbunches));
471 #endif
472     psky_t skyInfo = *tileSetupSky(0);
473     Write(&skyInfo, sizeof(skyInfo));
474 }
475 
LoadSavedInfo(void)476 void LoadSavedInfo(void)
477 {
478     auto pList = klistpath("./", "game*.sav", BUILDVFS_FIND_FILE);
479     int nCount = 0;
480     for (auto pIterator = pList; pIterator != NULL && nCount < 10; pIterator = pIterator->next, nCount++)
481     {
482         int hFile = kopen4loadfrommod(pIterator->name, 0);
483         if (hFile == -1)
484             ThrowError("Error loading save file header.");
485         int vc;
486         short v4;
487         vc = 0;
488         v4 = word_27AA54;
489         if ((uint32_t)kread(hFile, &vc, sizeof(vc)) != sizeof(vc))
490         {
491             kclose(hFile);
492             continue;
493         }
494         if (vc != 0x5653424e/*'VSBN'*/)
495         {
496             kclose(hFile);
497             continue;
498         }
499         kread(hFile, &v4, sizeof(v4));
500         if (v4 != BYTEVERSION)
501         {
502             kclose(hFile);
503             continue;
504         }
505         if ((uint32_t)kread(hFile, &gSaveGameOptions[nCount], sizeof(gSaveGameOptions[0])) != sizeof(gSaveGameOptions[0]))
506             ThrowError("Error reading save file.");
507         UpdateSavedInfo(nCount);
508         kclose(hFile);
509     }
510     klistfree(pList);
511 }
512 
UpdateSavedInfo(int nSlot)513 void UpdateSavedInfo(int nSlot)
514 {
515     strcpy(strRestoreGameStrings[gSaveGameOptions[nSlot].nSaveGameSlot], gSaveGameOptions[nSlot].szUserGameName);
516     restoreGameDifficulty[gSaveGameOptions[nSlot].nSaveGameSlot] = gSaveGameOptions[nSlot].nDifficulty;
517 }
518 
519 static MyLoadSave *myLoadSave;
520 
521 
LoadSaveSetup(void)522 void LoadSaveSetup(void)
523 {
524     void ActorLoadSaveConstruct(void);
525     void AILoadSaveConstruct(void);
526     void EndGameLoadSaveConstruct(void);
527     void EventQLoadSaveConstruct(void);
528     void LevelsLoadSaveConstruct(void);
529     void MessagesLoadSaveConstruct(void);
530     void MirrorLoadSaveConstruct(void);
531     void PlayerLoadSaveConstruct(void);
532     void SeqLoadSaveConstruct(void);
533     void TriggersLoadSaveConstruct(void);
534     void ViewLoadSaveConstruct(void);
535     void WarpLoadSaveConstruct(void);
536     void WeaponLoadSaveConstruct(void);
537 
538     myLoadSave = new MyLoadSave();
539 
540     ActorLoadSaveConstruct();
541     AILoadSaveConstruct();
542     EndGameLoadSaveConstruct();
543     EventQLoadSaveConstruct();
544     LevelsLoadSaveConstruct();
545     MessagesLoadSaveConstruct();
546     MirrorLoadSaveConstruct();
547     PlayerLoadSaveConstruct();
548     SeqLoadSaveConstruct();
549     TriggersLoadSaveConstruct();
550     ViewLoadSaveConstruct();
551     WarpLoadSaveConstruct();
552     WeaponLoadSaveConstruct();
553 }