#include "diablo.h" unsigned char *tbuff; void LoadGame(BOOL firstflag) { int i, j; int dwLen; char szName[MAX_PATH]; FreeGameMem(); pfile_remove_temp_files(); pfile_get_game_name(szName); unsigned char *LoadBuff = (unsigned char *)pfile_read(szName, &dwLen); tbuff = LoadBuff; if(ILoad() != 'RETL') app_fatal("Invalid save file"); setlevel = OLoad(); setlvlnum = WLoad(); currlevel = WLoad(); leveltype = WLoad(); int _ViewX = WLoad(); int _ViewY = WLoad(); invflag = OLoad(); chrflag = OLoad(); int _nummonsters = WLoad(); int _numitems = WLoad(); int _nummissiles = WLoad(); int _nobjects = WLoad(); for(i = 0; i < NUMLEVELS; i++) { glSeedTbl[i] = ILoad(); gnLevelTypeTbl[i] = WLoad(); } LoadPlayer(myplr); for(i = 0; i < MAXQUESTS; i++) LoadQuest(i); for(i = 0; i < MAXPORTAL; i++) LoadPortal(i); LoadGameLevel(firstflag, 4); SyncInitPlr(myplr); SyncPlrAnim(myplr); ViewX = _ViewX; ViewY = _ViewY; nummonsters = _nummonsters; numitems = _numitems; nummissiles = _nummissiles; nobjects = _nobjects; for(i = 0; i < MAXMONSTERS; i++) monstkills[i] = ILoad(); if(leveltype) { for(i = 0; i < MAXMONSTERS; i++) monstactive[i] = WLoad(); for(i = 0; i < nummonsters; i++) LoadMonster(monstactive[i]); for(i = 0; i < MAXMISSILES; i++) missileactive[i] = BLoad(); for(i = 0; i < MAXMISSILES; i++) missileavail[i] = BLoad(); for(i = 0; i < nummissiles; i++) LoadMissile(missileactive[i]); for(i = 0; i < MAXOBJECTS; i++) objectactive[i] = BLoad(); for(i = 0; i < MAXOBJECTS; i++) objectavail[i] = BLoad(); for(i = 0; i < nobjects; i++) LoadObject(objectactive[i]); for(i = 0; i < nobjects; i++) SyncObjectAnim(objectactive[i]); numlights = WLoad(); for(i = 0; i < MAXLIGHTS; i++) lightactive[i] = BLoad(); for(i = 0; i < numlights; i++) LoadLighting(lightactive[i]); visionid = WLoad(); numvision = WLoad(); for(i = 0; i < numvision; i++) LoadVision(i); } for(i = 0; i < MAXITEMS; i++) itemactive[i] = BLoad(); for(i = 0; i < MAXITEMS; i++) itemavail[i] = BLoad(); for(i = 0; i < numitems; i++) LoadItem(itemactive[i]); for(i = 0; i < 128; i++) UniqueItemFlag[i] = OLoad(); for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dLight[i][j] = BLoad(); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dFlags[i][j] = BLoad(); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dPlayer[i][j] = BLoad(); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dItem[i][j] = BLoad(); } if(leveltype) { for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dMonster[i][j] = WLoad(); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dDead[i][j] = BLoad(); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dObject[i][j] = BLoad(); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dLight[i][j] = BLoad(); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dPreLight[i][j] = BLoad(); } for(j = 0; j < DMAXY; j++) { for(i = 0; i < DMAXX; i++) automapview[i][j] = OLoad(); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dMissile[i][j] = BLoad(); } } numpremium = WLoad(); premiumlevel = WLoad(); for(i = 0; i < 6; i++) LoadPremium(i); automapflag = OLoad(); AutoMapScale = WLoad(); mem_free_dbg(LoadBuff); AutomapZoomReset(); ResyncQuests(); if(leveltype) ProcessLightList(); RedoPlayerVision(); ProcessVisionList(); missiles_process_charge(); ResetPal(); SetCursor_(1); gbProcessPlayers = 1; } char BLoad() { return *tbuff++; } int WLoad() { int rv = *tbuff++ << 24; rv |= *tbuff++ << 16; rv |= *tbuff++ << 8; rv |= *tbuff++; return rv; } int ILoad() { int rv = *tbuff++ << 24; rv |= *tbuff++ << 16; rv |= *tbuff++ << 8; rv |= *tbuff++; return rv; } BOOL OLoad() { if(*tbuff++ == TRUE) return TRUE; else return FALSE; } void LoadPlayer(int i) { memcpy(&plr[i], tbuff, sizeof(*plr) - (10 * sizeof(void *))); tbuff += sizeof(*plr) - (10 * sizeof(void *)); // omit last 10 pointers } void LoadMonster(int i) { memcpy(&monster[i], tbuff, sizeof(*monster) - (3 * sizeof(void *))); tbuff += sizeof(*monster) - (3 * sizeof(void *)); // omit last 3 pointers SyncMonsterAnim(i); } void LoadMissile(int i) { memcpy(&missile[i], tbuff, sizeof(*missile)); tbuff += sizeof(*missile); } void LoadObject(int i) { memcpy(&object[i], tbuff, sizeof(*object)); tbuff += sizeof(*object); } void LoadItem(int i) { memcpy(&item[i], tbuff, sizeof(*item)); tbuff += sizeof(*item); GetItemFrm(i); } void LoadPremium(int i) { memcpy(&premiumitem[i], tbuff, sizeof(*premiumitem)); tbuff += sizeof(*premiumitem); } void LoadQuest(int i) { memcpy(&quests[i], tbuff, sizeof(*quests)); tbuff += sizeof(*quests); ReturnLvlX = WLoad(); ReturnLvlY = WLoad(); ReturnLvl = WLoad(); ReturnLvlT = WLoad(); DoomQuestState = WLoad(); } void LoadLighting(int i) { memcpy(&LightList[i], tbuff, sizeof(*LightList)); tbuff += sizeof(*LightList); } void LoadVision(int i) { memcpy(&VisionList[i], tbuff, sizeof(*VisionList)); tbuff += sizeof(*VisionList); } void LoadPortal(int i) { memcpy(&portal[i], tbuff, sizeof(*portal)); tbuff += sizeof(*portal); } void SaveGame() { int i, j; char szName[MAX_PATH]; int dwLen = codec_get_encoded_len(FILEBUFF); unsigned char *SaveBuff = DiabloAllocPtr(dwLen); tbuff = SaveBuff; ISave('RETL'); OSave((unsigned char)setlevel); WSave((unsigned char)setlvlnum); WSave(currlevel); WSave((unsigned char)leveltype); WSave(ViewX); WSave(ViewY); OSave(invflag); OSave(chrflag); WSave(nummonsters); WSave(numitems); WSave(nummissiles); WSave(nobjects); for(i = 0; i < NUMLEVELS; i++) { ISave(glSeedTbl[i]); WSave(gnLevelTypeTbl[i]); } SavePlayer(myplr); for(i = 0; i < MAXQUESTS; i++) SaveQuest(i); for(i = 0; i < MAXPORTAL; i++) SavePortal(i); for(i = 0; i < MAXMONSTERS; i++) ISave(monstkills[i]); if(leveltype) { for(i = 0; i < MAXMONSTERS; i++) WSave(monstactive[i]); for(i = 0; i < nummonsters; i++) SaveMonster(monstactive[i]); for(i = 0; i < MAXMISSILES; i++) BSave(missileactive[i]); for(i = 0; i < MAXMISSILES; i++) BSave(missileavail[i]); for(i = 0; i < nummissiles; i++) SaveMissile(missileactive[i]); for(i = 0; i < MAXOBJECTS; i++) BSave(objectactive[i]); for(i = 0; i < MAXOBJECTS; i++) BSave(objectavail[i]); for(i = 0; i < nobjects; i++) SaveObject(objectactive[i]); WSave(numlights); for(i = 0; i < MAXLIGHTS; i++) BSave(lightactive[i]); for(i = 0; i < numlights; i++) SaveLighting(lightactive[i]); WSave(visionid); WSave(numvision); for(i = 0; i < numvision; i++) SaveVision(i); } for(i = 0; i < MAXITEMS; i++) BSave(itemactive[i]); for(i = 0; i < MAXITEMS; i++) BSave(itemavail[i]); for(i = 0; i < numitems; i++) SaveItem(itemactive[i]); for(i = 0; i < 128; i++) OSave(UniqueItemFlag[i]); for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) BSave(dLight[i][j]); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) BSave(dFlags[i][j] & 0xF8); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) BSave(dPlayer[i][j]); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) BSave(dItem[i][j]); } if(leveltype) { for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) WSave(dMonster[i][j]); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) BSave(dDead[i][j]); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) BSave(dObject[i][j]); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) BSave(dLight[i][j]); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) BSave(dPreLight[i][j]); } for(j = 0; j < DMAXY; j++) { for(i = 0; i < DMAXX; i++) OSave(automapview[i][j]); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) BSave(dMissile[i][j]); } } WSave(numpremium); WSave(premiumlevel); for(i = 0; i < 6; i++) SavePremium(i); OSave(automapflag); WSave(AutoMapScale); pfile_get_game_name(szName); dwLen = codec_get_encoded_len(tbuff - SaveBuff); pfile_write_save_file(szName, SaveBuff, tbuff - SaveBuff, dwLen); mem_free_dbg(SaveBuff); gbValidSaveFile = TRUE; pfile_rename_temp_to_perm(); pfile_write_hero(); } void BSave(char v) { *tbuff++ = v; } void WSave(int v) { *tbuff++ = v >> 24; *tbuff++ = v >> 16; *tbuff++ = v >> 8; *tbuff++ = v; } void ISave(int v) { *tbuff++ = v >> 24; *tbuff++ = v >> 16; *tbuff++ = v >> 8; *tbuff++ = v; } void OSave(BOOL v) { if(v != FALSE) *tbuff++ = TRUE; else *tbuff++ = FALSE; } void SavePlayer(int i) { memcpy(tbuff, &plr[i], sizeof(*plr) - (10 * sizeof(void *))); tbuff += sizeof(*plr) - (10 * sizeof(void *)); // omit last 10 pointers } void SaveMonster(int i) { memcpy(tbuff, &monster[i], sizeof(*monster) - (3 * sizeof(void *))); tbuff += sizeof(*monster) - (3 * sizeof(void *)); // omit last 3 pointers } void SaveMissile(int i) { memcpy(tbuff, &missile[i], sizeof(*missile)); tbuff += sizeof(*missile); } void SaveObject(int i) { memcpy(tbuff, &object[i], sizeof(*object)); tbuff += sizeof(*object); } void SaveItem(int i) { memcpy(tbuff, &item[i], sizeof(*item)); tbuff += sizeof(*item); } void SavePremium(int i) { memcpy(tbuff, &premiumitem[i], sizeof(*premiumitem)); tbuff += sizeof(*premiumitem); } void SaveQuest(int i) { memcpy(tbuff, &quests[i], sizeof(*quests)); tbuff += sizeof(*quests); WSave(ReturnLvlX); WSave(ReturnLvlY); WSave(ReturnLvl); WSave(ReturnLvlT); WSave(DoomQuestState); } void SaveLighting(int i) { memcpy(tbuff, &LightList[i], sizeof(*LightList)); tbuff += sizeof(*LightList); } void SaveVision(int i) { memcpy(tbuff, &VisionList[i], sizeof(*VisionList)); tbuff += sizeof(*VisionList); } void SavePortal(int i) { memcpy(tbuff, &portal[i], sizeof(*portal)); tbuff += sizeof(*portal); } void SaveLevel() { int i, j; char szName[MAX_PATH]; if(!currlevel) glSeedTbl[0] = GetRndSeed(); int dwLen = codec_get_encoded_len(FILEBUFF); unsigned char *SaveBuff = DiabloAllocPtr(dwLen); tbuff = SaveBuff; if(leveltype) { for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) BSave(dDead[i][j]); } } WSave(nummonsters); WSave(numitems); WSave(nobjects); if(leveltype) { for(i = 0; i < MAXMONSTERS; i++) WSave(monstactive[i]); for(i = 0; i < nummonsters; i++) SaveMonster(monstactive[i]); for(i = 0; i < MAXOBJECTS; i++) BSave(objectactive[i]); for(i = 0; i < MAXOBJECTS; i++) BSave(objectavail[i]); for(i = 0; i < nobjects; i++) SaveObject(objectactive[i]); } for(i = 0; i < MAXITEMS; i++) BSave(itemactive[i]); for(i = 0; i < MAXITEMS; i++) BSave(itemavail[i]); for(i = 0; i < numitems; i++) SaveItem(itemactive[i]); for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) BSave(dFlags[i][j] & 0xF8); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) BSave(dItem[i][j]); } if(leveltype) { for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) WSave(dMonster[i][j]); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) BSave(dObject[i][j]); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) BSave(dLight[i][j]); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) BSave(dPreLight[i][j]); } for(j = 0; j < DMAXY; j++) { for(i = 0; i < DMAXX; i++) OSave(automapview[i][j]); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) BSave(dMissile[i][j]); } } GetTempLevelNames(szName); dwLen = codec_get_encoded_len(tbuff - SaveBuff); pfile_write_save_file(szName, SaveBuff, tbuff - SaveBuff, dwLen); mem_free_dbg(SaveBuff); if(setlevel == 0) plr[myplr]._pLvlVisited[currlevel] = 1; else plr[myplr]._pSLvlVisited[(unsigned char)setlvlnum] = 1; } void LoadLevel() { int i, j; int dwLen; char szName[MAX_PATH]; GetPermLevelNames(szName); unsigned char *LoadBuff = (unsigned char *)pfile_read(szName, &dwLen); tbuff = LoadBuff; if(leveltype) { for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dDead[i][j] = BLoad(); } SetDead(); } nummonsters = WLoad(); numitems = WLoad(); nobjects = WLoad(); if(leveltype) { for(i = 0; i < MAXMONSTERS; i++) monstactive[i] = WLoad(); for(i = 0; i < nummonsters; i++) LoadMonster(monstactive[i]); for(i = 0; i < MAXOBJECTS; i++) objectactive[i] = BLoad(); for(i = 0; i < MAXOBJECTS; i++) objectavail[i] = BLoad(); for(i = 0; i < nobjects; i++) LoadObject(objectactive[i]); for(i = 0; i < nobjects; i++) SyncObjectAnim(objectactive[i]); } for(i = 0; i < MAXITEMS; i++) itemactive[i] = BLoad(); for(i = 0; i < MAXITEMS; i++) itemavail[i] = BLoad(); for(i = 0; i < numitems; i++) LoadItem(itemactive[i]); for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dFlags[i][j] = BLoad(); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dItem[i][j] = BLoad(); } if(leveltype) { for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dMonster[i][j] = WLoad(); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dObject[i][j] = BLoad(); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dLight[i][j] = BLoad(); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dPreLight[i][j] = BLoad(); } for(j = 0; j < DMAXY; j++) { for(i = 0; i < DMAXX; i++) automapview[i][j] = OLoad(); } for(j = 0; j < MAXDUNY; j++) { for(i = 0; i < MAXDUNX; i++) dMissile[i][j] = 0; /// BUGFIX: supposed to load saved missiles with "BLoad()"? } } AutomapZoomReset(); ResyncQuests(); SyncPortals(); dolighting = 1; for(i = 0; i < MAX_PLRS; i++) { if(plr[i].plractive && currlevel == plr[i].plrlevel) LightList[plr[i]._plid]._lunflag = 1; } mem_free_dbg(LoadBuff); }