boolean LoadTheGame(FILE *file,int x,int y) { int32_t oldchecksum; objtype nullobj; statobj_t nullstat; int actnum=0, i, j; int32_t checksum = 0; DiskFlopAnim(x,y); fread (&gamestate,sizeof(gamestate),1,file); checksum = DoChecksum((byte *)&gamestate,sizeof(gamestate),checksum); DiskFlopAnim(x,y); fread (&LevelRatios[0],sizeof(LRstruct)*LRpack,1,file); checksum = DoChecksum((byte *)&LevelRatios[0],sizeof(LRstruct)*LRpack,checksum); DiskFlopAnim(x,y); SetupGameLevel (); DiskFlopAnim(x,y); fread (tilemap,sizeof(tilemap),1,file); checksum = DoChecksum((byte *)tilemap,sizeof(tilemap),checksum); DiskFlopAnim(x,y); for(i=0; i<MAPSIZE; i++) { for(j=0; j<MAPSIZE; j++) { fread (&actnum,sizeof(word),1,file); checksum = DoChecksum((byte *) &actnum,sizeof(word),checksum); if(actnum&0x8000) actorat[i][j]=objlist+(actnum&0x7fff); else actorat[i][j]=(objtype *)(uintptr_t) actnum; } } fread (areaconnect,sizeof(areaconnect),1,file); fread (areabyplayer,sizeof(areabyplayer),1,file); InitActorList (); DiskFlopAnim(x,y); fread (player,sizeof(*player),1,file); player->state=(statetype *) ((uintptr_t)player->state+(uintptr_t)&s_player); /* Load all actors ? */ while (1) { DiskFlopAnim(x,y); fread (&nullobj,sizeof(nullobj),1,file); if (nullobj.active == ac_badobject) break; GetNewActor (); nullobj.state=(statetype *) ((uintptr_t)nullobj.state+(uintptr_t)&s_grdstand); /* don't copy over the links */ memcpy (newobj,&nullobj,sizeof(nullobj)-8); } DiskFlopAnim(x,y); word laststatobjnum; fread (&laststatobjnum,sizeof(laststatobjnum),1,file); laststatobj=statobjlist+laststatobjnum; checksum = DoChecksum((byte *)&laststatobjnum,sizeof(laststatobjnum),checksum); DiskFlopAnim(x,y); for(i=0; i<MAXSTATS; i++) { fread(&nullstat,sizeof(nullstat),1,file); checksum = DoChecksum((byte *)&nullstat,sizeof(nullstat),checksum); nullstat.visspot=(byte *) ((uintptr_t)nullstat.visspot+(uintptr_t)spotvis); memcpy(statobjlist+i,&nullstat,sizeof(nullstat)); } DiskFlopAnim(x,y); fread (doorposition,sizeof(doorposition),1,file); checksum = DoChecksum((byte *)doorposition,sizeof(doorposition),checksum); DiskFlopAnim(x,y); fread (doorobjlist,sizeof(doorobjlist),1,file); checksum = DoChecksum((byte *)doorobjlist,sizeof(doorobjlist),checksum); DiskFlopAnim(x,y); fread (&pwallstate,sizeof(pwallstate),1,file); checksum = DoChecksum((byte *)&pwallstate,sizeof(pwallstate),checksum); fread (&pwalltile,sizeof(pwalltile),1,file); checksum = DoChecksum((byte *)&pwalltile,sizeof(pwalltile),checksum); fread (&pwallx,sizeof(pwallx),1,file); checksum = DoChecksum((byte *)&pwallx,sizeof(pwallx),checksum); fread (&pwally,sizeof(pwally),1,file); checksum = DoChecksum((byte *)&pwally,sizeof(pwally),checksum); fread (&pwalldir,sizeof(pwalldir),1,file); checksum = DoChecksum((byte *)&pwalldir,sizeof(pwalldir),checksum); fread (&pwallpos,sizeof(pwallpos),1,file); checksum = DoChecksum((byte *)&pwallpos,sizeof(pwallpos),checksum); /* assign valid floorcodes under moved pushwalls */ if (gamestate.secretcount) { word *map, *obj; word tile, sprite; map = mapsegs[0]; obj = mapsegs[1]; for (y=0; y<mapheight; y++) for (x=0; x<mapwidth; x++) { tile = *map++; sprite = *obj++; if (sprite == PUSHABLETILE && !tilemap[x][y] && (tile < AREATILE || tile >= (AREATILE+NUMMAPS))) { if (*map >= AREATILE) tile = *map; if (*(map-1-mapwidth) >= AREATILE) tile = *(map-1-mapwidth); if (*(map-1+mapwidth) >= AREATILE) tile = *(map-1+mapwidth); if ( *(map-2) >= AREATILE) tile = *(map-2); *(map-1) = tile; *(obj-1) = 0; } } } /* set player->areanumber to the floortile you're standing on */ Thrust(0,0); fread (&oldchecksum,sizeof(oldchecksum),1,file); fread (&lastgamemusicoffset,sizeof(lastgamemusicoffset),1,file); if(lastgamemusicoffset<0) lastgamemusicoffset=0; if (oldchecksum != checksum) { Message(STR_SAVECHT1"\n" STR_SAVECHT2"\n" STR_SAVECHT3"\n" STR_SAVECHT4); IN_ClearKeysDown(); IN_Ack(); gamestate.oldscore = gamestate.score = 0; gamestate.lives = 1; gamestate.weapon = gamestate.chosenweapon = gamestate.bestweapon = wp_pistol; gamestate.ammo = 8; } return true; }
myint SaveTheGame(const char *fn, const char *tag, myint dx, myint dy) { objtype *ob; myint fd, i, x, y; int32_t cs; fd = OpenWrite(fn); if (fd != -1) { WriteBytes(fd, (byte *)GAMEHDR, 8); WriteBytes(fd, (byte *)SAVTYPE, 4); WriteInt32(fd, 0x00000000); /* write version */ WriteBytes(fd, (byte *)GAMETYPE, 4); WriteInt32(fd, time(NULL)); WriteInt32(fd, 0x00000000); WriteInt32(fd, 0x00000000); /* write checksum (placeholder) */ WriteBytes(fd, (byte *)tag, 32); /* write savegame name */ DiskFlopAnim(dx, dy); WriteInt32(fd, gamestate_difficulty); WriteInt32(fd, gamestate.mapon); WriteInt32(fd, gamestate.oldscore); WriteInt32(fd, gamestate.score); WriteInt32(fd, gamestate.nextextra); WriteInt32(fd, gamestate.lives); WriteInt32(fd, gamestate.health); WriteInt32(fd, gamestate.ammo); WriteInt32(fd, gamestate.keys); WriteInt32(fd, gamestate.bestweapon); WriteInt32(fd, gamestate.weapon); WriteInt32(fd, gamestate.chosenweapon); WriteInt32(fd, gamestate.faceframe); WriteInt32(fd, gamestate.attackframe); WriteInt32(fd, gamestate.attackcount); WriteInt32(fd, gamestate.weaponframe); WriteInt32(fd, gamestate_episode); WriteInt32(fd, gamestate.secretcount); WriteInt32(fd, gamestate.treasurecount); WriteInt32(fd, gamestate.killcount); WriteInt32(fd, gamestate.secrettotal); WriteInt32(fd, gamestate.treasuretotal); WriteInt32(fd, gamestate.killtotal); WriteInt32(fd, gamestate.TimeCount); WriteInt32(fd, gamestate.killx); WriteInt32(fd, gamestate.killy); WriteInt8(fd, gamestate.victoryflag); DiskFlopAnim(dx, dy); #ifdef SPEAR for (i = 0; i < 20; i++) { #else for (i = 0; i < 8; i++) { #endif WriteInt32(fd, LevelRatios[i].kill); WriteInt32(fd, LevelRatios[i].secret); WriteInt32(fd, LevelRatios[i].treasure); WriteInt32(fd, LevelRatios[i].time); } DiskFlopAnim(dx, dy); WriteBytes(fd, (byte *)tilemap, 64*64); /* MAPSIZE * MAPSIZE */ DiskFlopAnim(dx, dy); for (x = 0; x < 64; x++) for (y = 0; y < 64; y++) WriteInt32(fd, actorat[x][y]); DiskFlopAnim(dx, dy); WriteBytes(fd, (byte *)&areabyplayer, 8); for (ob = player; ob; ob = obj_next(ob)) { DiskFlopAnim(dx, dy); WriteInt32(fd, obj_id(ob)); WriteInt32(fd, ob->active); WriteInt32(fd, ob->ticcount); WriteInt32(fd, ob->obclass); WriteInt32(fd, ob->state); WriteInt8(fd, ob->flags); WriteInt32(fd, ob->distance); WriteInt32(fd, ob->dir); WriteInt32(fd, ob->x); WriteInt32(fd, ob->y); WriteInt32(fd, ob->tilex); WriteInt32(fd, ob->tiley); WriteInt8(fd, ob->areanumber); WriteInt32(fd, ob->viewx); WriteInt32(fd, ob->viewheight); WriteInt32(fd, ob->transx); WriteInt32(fd, ob->transy); WriteInt32(fd, ob->angle); WriteInt32(fd, ob->hitpoints); WriteInt32(fd, ob->speed); WriteInt32(fd, ob->temp1); WriteInt32(fd, ob->temp2); //WriteInt32(fd, ob->temp3); } WriteInt32(fd, 0xFFFFFFFF); /* end of actor list */ DiskFlopAnim(dx, dy); WriteInt32(fd, laststatobj - statobjlist); /* ptr offset */ for (i = 0; i < 400; i++) { /* MAXSTATS */ WriteInt8(fd, statobjlist[i].tilex); WriteInt8(fd, statobjlist[i].tiley); WriteInt32(fd, statobjlist[i].shapenum); WriteInt8(fd, statobjlist[i].is_bonus); WriteInt8(fd, statobjlist[i].itemnumber); } DiskFlopAnim(dx, dy); for (i = 0; i < 64; i++) { /* MAXDOORS */ WriteInt32(fd, doorposition[i]); } DiskFlopAnim(dx, dy); for (i = 0; i < 64; i++) { /* MAXDOORS */ WriteInt8(fd, doorobjlist[i].tilex); WriteInt8(fd, doorobjlist[i].tiley); WriteInt8(fd, doorobjlist[i].vertical); WriteInt8(fd, doorobjlist[i].lock); WriteInt8(fd, doorobjlist[i].action); WriteInt32(fd, doorobjlist[i].ticcount); } DiskFlopAnim(dx, dy); WriteInt32(fd, pwallstate); WriteInt32(fd, pwallx); WriteInt32(fd, pwally); WriteInt32(fd, pwalldir); WriteInt32(fd, pwallpos); DiskFlopAnim(dx, dy); CloseWrite(fd); fd = OpenRead(fn); ReadSeek(fd, 64, SEEK_SET); cs = CalcFileChecksum(fd, ReadLength(fd) - 64); CloseRead(fd); fd = OpenWriteAppend(fn); WriteSeek(fd, 28, SEEK_SET); WriteInt32(fd, cs); CloseWrite(fd); } else {
boolean SaveTheGame(FILE *file,int x,int y) { objtype *ob; objtype nullobj; statobj_t nullstat; unsigned i, j; int checksum = 0; DiskFlopAnim(x,y); fwrite(&gamestate,sizeof(gamestate),1,file); checksum = DoChecksum((byte *)&gamestate,sizeof(gamestate),checksum); DiskFlopAnim(x,y); fwrite(&LevelRatios[0],sizeof(LRstruct)*LRpack,1,file); checksum = DoChecksum((byte *)&LevelRatios[0],sizeof(LRstruct)*LRpack,checksum); DiskFlopAnim(x,y); fwrite(tilemap,sizeof(tilemap),1,file); checksum = DoChecksum((byte *)tilemap,sizeof(tilemap),checksum); DiskFlopAnim(x,y); for(i = 0; i < MAPSIZE; i++) { for(j = 0; j < MAPSIZE; j++) { word actnum; objtype *objptr=actorat[i][j]; if(ISPOINTER(objptr)) actnum=0x8000 | (word)(objptr-objlist); else actnum=(word)(uintptr_t)objptr; fwrite(&actnum,sizeof(actnum),1,file); checksum = DoChecksum((byte *)&actnum,sizeof(actnum),checksum); } } fwrite (areaconnect,sizeof(areaconnect),1,file); fwrite (areabyplayer,sizeof(areabyplayer),1,file); // player object needs special treatment as it's in WL_AGENT.CPP and not in // WL_ACT2.CPP which could cause problems for the relative addressing ob = player; DiskFlopAnim(x,y); memcpy(&nullobj,ob,sizeof(nullobj)); nullobj.state=(statetype *) ((uintptr_t)nullobj.state-(uintptr_t)&s_player); fwrite(&nullobj,sizeof(nullobj),1,file); ob = ob->next; DiskFlopAnim(x,y); for (; ob ; ob=ob->next) { memcpy(&nullobj,ob,sizeof(nullobj)); nullobj.state=(statetype *) ((uintptr_t)nullobj.state-(uintptr_t)&s_grdstand); fwrite(&nullobj,sizeof(nullobj),1,file); } nullobj.active = ac_badobject; // end of file marker DiskFlopAnim(x,y); fwrite(&nullobj,sizeof(nullobj),1,file); DiskFlopAnim(x,y); word laststatobjnum=(word) (laststatobj-statobjlist); fwrite(&laststatobjnum,sizeof(laststatobjnum),1,file); checksum = DoChecksum((byte *)&laststatobjnum,sizeof(laststatobjnum),checksum); DiskFlopAnim(x,y); for(i = 0; i < MAXSTATS; i++) { memcpy(&nullstat,statobjlist+i,sizeof(nullstat)); nullstat.visspot=(byte *) ((uintptr_t) nullstat.visspot-(uintptr_t)spotvis); fwrite(&nullstat,sizeof(nullstat),1,file); checksum = DoChecksum((byte *)&nullstat,sizeof(nullstat),checksum); } DiskFlopAnim(x,y); fwrite (doorposition,sizeof(doorposition),1,file); checksum = DoChecksum((byte *)doorposition,sizeof(doorposition),checksum); DiskFlopAnim(x,y); fwrite (doorobjlist,sizeof(doorobjlist),1,file); checksum = DoChecksum((byte *)doorobjlist,sizeof(doorobjlist),checksum); DiskFlopAnim(x,y); fwrite (&pwallstate,sizeof(pwallstate),1,file); checksum = DoChecksum((byte *)&pwallstate,sizeof(pwallstate),checksum); fwrite (&pwalltile,sizeof(pwalltile),1,file); checksum = DoChecksum((byte *)&pwalltile,sizeof(pwalltile),checksum); fwrite (&pwallx,sizeof(pwallx),1,file); checksum = DoChecksum((byte *)&pwallx,sizeof(pwallx),checksum); fwrite (&pwally,sizeof(pwally),1,file); checksum = DoChecksum((byte *)&pwally,sizeof(pwally),checksum); fwrite (&pwalldir,sizeof(pwalldir),1,file); checksum = DoChecksum((byte *)&pwalldir,sizeof(pwalldir),checksum); fwrite (&pwallpos,sizeof(pwallpos),1,file); checksum = DoChecksum((byte *)&pwallpos,sizeof(pwallpos),checksum); /* WRITE OUT CHECKSUM */ fwrite (&checksum,sizeof(checksum),1,file); fwrite (&lastgamemusicoffset,sizeof(lastgamemusicoffset),1,file); return(true); }
boolean SaveTheGame(FILE *file,int x,int y) { // struct diskfree_t dfree; // int32_t avail,size,checksum; int checksum; objtype *ob; objtype nullobj; statobj_t nullstat; /* if (_dos_getdiskfree(0,&dfree)) Quit("Error in _dos_getdiskfree call"); avail = (int32_t)dfree.avail_clusters * dfree.bytes_per_sector * dfree.sectors_per_cluster; size = 0; for (ob = player; ob ; ob=ob->next) size += sizeof(*ob); size += sizeof(nullobj); size += sizeof(gamestate) + sizeof(LRstruct)*LRpack + sizeof(tilemap) + sizeof(actorat) + sizeof(laststatobj) + sizeof(statobjlist) + sizeof(doorposition) + sizeof(pwallstate) + sizeof(pwalltile) + sizeof(pwallx) + sizeof(pwally) + sizeof(pwalldir) + sizeof(pwallpos); if (avail < size) { Message(STR_NOSPACE1"\n"STR_NOSPACE2); return false; }*/ checksum = 0; DiskFlopAnim(x,y); fwrite(&gamestate,sizeof(gamestate),1,file); checksum = DoChecksum((byte *)&gamestate,sizeof(gamestate),checksum); DiskFlopAnim(x,y); fwrite(&LevelRatios[0],sizeof(LRstruct)*LRpack,1,file); checksum = DoChecksum((byte *)&LevelRatios[0],sizeof(LRstruct)*LRpack,checksum); DiskFlopAnim(x,y); fwrite(tilemap,sizeof(tilemap),1,file); checksum = DoChecksum((byte *)tilemap,sizeof(tilemap),checksum); DiskFlopAnim(x,y); int i; for(i=0;i<MAPSIZE;i++) { for(int j=0;j<MAPSIZE;j++) { word actnum; objtype *objptr=actorat[i][j]; if(ISPOINTER(objptr)) actnum=0x8000 | (word)(objptr-objlist); else actnum=(word)(uintptr_t)objptr; fwrite(&actnum,sizeof(actnum),1,file); checksum = DoChecksum((byte *)&actnum,sizeof(actnum),checksum); } } fwrite (areaconnect,sizeof(areaconnect),1,file); fwrite (areabyplayer,sizeof(areabyplayer),1,file); // player object needs special treatment as it's in WL_AGENT.CPP and not in // WL_ACT2.CPP which could cause problems for the relative addressing ob = player; DiskFlopAnim(x,y); memcpy(&nullobj,ob,sizeof(nullobj)); nullobj.state=(statetype *) ((uintptr_t)nullobj.state-(uintptr_t)&s_player); fwrite(&nullobj,sizeof(nullobj),1,file); ob = ob->next; DiskFlopAnim(x,y); for (; ob ; ob=ob->next) { memcpy(&nullobj,ob,sizeof(nullobj)); nullobj.state=(statetype *) ((uintptr_t)nullobj.state-(uintptr_t)&s_grdstand); fwrite(&nullobj,sizeof(nullobj),1,file); } nullobj.active = ac_badobject; // end of file marker DiskFlopAnim(x,y); fwrite(&nullobj,sizeof(nullobj),1,file); DiskFlopAnim(x,y); word laststatobjnum=(word) (laststatobj-statobjlist); fwrite(&laststatobjnum,sizeof(laststatobjnum),1,file); checksum = DoChecksum((byte *)&laststatobjnum,sizeof(laststatobjnum),checksum); DiskFlopAnim(x,y); for(i=0;i<MAXSTATS;i++) { memcpy(&nullstat,statobjlist+i,sizeof(nullstat)); nullstat.visspot=(byte *) ((uintptr_t) nullstat.visspot-(uintptr_t)spotvis); fwrite(&nullstat,sizeof(nullstat),1,file); checksum = DoChecksum((byte *)&nullstat,sizeof(nullstat),checksum); } DiskFlopAnim(x,y); fwrite (doorposition,sizeof(doorposition),1,file); checksum = DoChecksum((byte *)doorposition,sizeof(doorposition),checksum); DiskFlopAnim(x,y); fwrite (doorobjlist,sizeof(doorobjlist),1,file); checksum = DoChecksum((byte *)doorobjlist,sizeof(doorobjlist),checksum); DiskFlopAnim(x,y); fwrite (&pwallstate,sizeof(pwallstate),1,file); checksum = DoChecksum((byte *)&pwallstate,sizeof(pwallstate),checksum); fwrite (&pwalltile,sizeof(pwalltile),1,file); checksum = DoChecksum((byte *)&pwalltile,sizeof(pwalltile),checksum); fwrite (&pwallx,sizeof(pwallx),1,file); checksum = DoChecksum((byte *)&pwallx,sizeof(pwallx),checksum); fwrite (&pwally,sizeof(pwally),1,file); checksum = DoChecksum((byte *)&pwally,sizeof(pwally),checksum); fwrite (&pwalldir,sizeof(pwalldir),1,file); checksum = DoChecksum((byte *)&pwalldir,sizeof(pwalldir),checksum); fwrite (&pwallpos,sizeof(pwallpos),1,file); checksum = DoChecksum((byte *)&pwallpos,sizeof(pwallpos),checksum); // // WRITE OUT CHECKSUM // fwrite (&checksum,sizeof(checksum),1,file); fwrite (&lastgamemusicoffset,sizeof(lastgamemusicoffset),1,file); return(true); }