static id0_boolean_t LoadObject(BE_FILE_T file, objtype *o) { id0_int_t dummy; // for active enum (anonymous type) id0_int_t activeint; // BACKWARD COMPATIBILITY id0_word_t statedosoffset; // Just tells if "o->next" is zero or not id0_int_t isnext; // Now reading size_t BE_Cross_read_classtype_From16LE(BE_FILE_T fp, classtype *ptr); size_t BE_Cross_read_dirtype_From16LE(BE_FILE_T fp, dirtype *ptr); if ((BE_Cross_readInt16LE(file, &activeint) != 2) || (BE_Cross_readInt16LE(file, &o->ticcount) != 2) || (BE_Cross_read_classtype_From16LE(file, &o->obclass) != 2) || (BE_Cross_readInt16LE(file, &statedosoffset) != 2) // BACKWARD COMPATIBILITY || (BE_Cross_read_boolean_From16LE(file, &o->shootable) != 2) || (BE_Cross_read_boolean_From16LE(file, &o->tileobject) != 2) || (BE_Cross_readInt32LE(file, &o->distance) != 4) || (BE_Cross_read_dirtype_From16LE(file, &o->dir) != 2) || (BE_Cross_readInt32LE(file, &o->x) != 4) || (BE_Cross_readInt32LE(file, &o->y) != 4) || (BE_Cross_readInt16LE(file, &o->tilex) != 2) || (BE_Cross_readInt16LE(file, &o->tiley) != 2) || (BE_Cross_readInt16LE(file, &o->viewx) != 2) || (BE_Cross_readInt16LE(file, &o->viewheight) != 2) || (BE_Cross_readInt16LE(file, &o->angle) != 2) || (BE_Cross_readInt16LE(file, &o->hitpoints) != 2) || (BE_Cross_readInt32LE(file, &o->speed) != 4) || (BE_Cross_readInt16LE(file, &o->size) != 2) || (BE_Cross_readInt32LE(file, &o->xl) != 4) || (BE_Cross_readInt32LE(file, &o->xh) != 4) || (BE_Cross_readInt32LE(file, &o->yl) != 4) || (BE_Cross_readInt32LE(file, &o->yh) != 4) || (BE_Cross_readInt16LE(file, &o->temp1) != 2) || (BE_Cross_readInt16LE(file, &o->temp2) != 2) // No need to read prev pointer as-is, // this is ignored on loading. So read dummy value. // Furthermore, all we need to know about next on loading is // if it's zero or not. || (BE_Cross_readInt16LE(file, &isnext) != 2) // next || (BE_Cross_readInt8LEBuffer(file, &dummy, 2) != 2) // prev ) { return false; } o->active = (activetype)activeint; o->state = RefKeen_GetObjStatePtrFromDOSPointer(statedosoffset); // HACK: All we need to know is if next was originally NULL or not o->next = isnext ? o : NULL; return true; }
static id0_boolean_t LoadObject(BE_FILE_T file, objtype *o) { id0_int_t dummy; // for active enum (anonymous type) id0_int_t activeint; // BACKWARD COMPATIBILITY id0_word_t statedosoffset; // Just tells if "o->next" is zero or not id0_int_t isnext; // Now reading size_t BE_Cross_read_classtype_From16LE(BE_FILE_T fp, classtype *ptr); if ((BE_Cross_read_classtype_From16LE(file, &o->obclass) != 2) || (BE_Cross_readInt16LE(file, &activeint) != 2) || (BE_Cross_read_boolean_From16LE(file, &o->needtoreact) != 2) || (BE_Cross_read_boolean_From16LE(file, &o->needtoclip) != 2) || (BE_Cross_readInt16LE(file, &o->nothink) != 2) || (BE_Cross_readInt16LE(file, &o->x) != 2) || (BE_Cross_readInt16LE(file, &o->y) != 2) || (BE_Cross_readInt16LE(file, &o->xdir) != 2) || (BE_Cross_readInt16LE(file, &o->ydir) != 2) || (BE_Cross_readInt16LE(file, &o->xmove) != 2) || (BE_Cross_readInt16LE(file, &o->ymove) != 2) || (BE_Cross_readInt16LE(file, &o->xspeed) != 2) || (BE_Cross_readInt16LE(file, &o->yspeed) != 2) || (BE_Cross_readInt16LE(file, &o->ticcount) != 2) || (BE_Cross_readInt16LE(file, &o->ticadjust) != 2) || (BE_Cross_readInt16LE(file, &statedosoffset) != 2) // BACKWARD COMPATIBILITY || (BE_Cross_readInt16LE(file, &o->shapenum) != 2) || (BE_Cross_readInt16LE(file, &o->left) != 2) || (BE_Cross_readInt16LE(file, &o->top) != 2) || (BE_Cross_readInt16LE(file, &o->right) != 2) || (BE_Cross_readInt16LE(file, &o->bottom) != 2) || (BE_Cross_readInt16LE(file, &o->midx) != 2) || (BE_Cross_readInt16LE(file, &o->tileleft) != 2) || (BE_Cross_readInt16LE(file, &o->tiletop) != 2) || (BE_Cross_readInt16LE(file, &o->tileright) != 2) || (BE_Cross_readInt16LE(file, &o->tilebottom) != 2) || (BE_Cross_readInt16LE(file, &o->tilemidx) != 2) || (BE_Cross_readInt16LE(file, &o->hitnorth) != 2) || (BE_Cross_readInt16LE(file, &o->hiteast) != 2) || (BE_Cross_readInt16LE(file, &o->hitsouth) != 2) || (BE_Cross_readInt16LE(file, &o->hitwest) != 2) || (BE_Cross_readInt16LE(file, &o->temp1) != 2) || (BE_Cross_readInt16LE(file, &o->temp2) != 2) || (BE_Cross_readInt16LE(file, &o->temp3) != 2) || (BE_Cross_readInt16LE(file, &o->temp4) != 2) // No need to read sprite, prev pointers as-is, // these are ignored on loading. So read dummy value. // Furthermore, all we need to know about next on loading is // if it's zero or not. || (BE_Cross_readInt16LE(file, &dummy) != 2) // sprite || (BE_Cross_readInt16LE(file, &isnext) != 2) // next || (BE_Cross_readInt16LE(file, &dummy) != 2) // prev ) { return false; } o->active = (activetype)activeint; o->state = RefKeen_GetObjStatePtrFromDOSPointer(statedosoffset); // ANOTHER SPECIAL CASE (for almost all creatures as flowers) o->temp2stateptr = RefKeen_GetObjStatePtrFromDOSPointer(o->temp2); // HACK: All we need to know is if next was originally NULL or not o->next = isnext ? o : NULL; return true; }
id0_boolean_t LoadTheGame(BE_FILE_T file) { id0_unsigned_t i,x,y; objtype /**obj,*/*prev,*next,*followed; id0_unsigned_t compressed,expanded; id0_unsigned_t id0_far *map,tile; memptr bigbuffer; screenpage = 0; FreeUpMemory(); playstate = ex_loadedgame; // load the sky and ground colors // REFKEEN - But not before converting from original 16-bit pointers (reusing i variable) if (BE_Cross_readInt16LE(file, &i) != 2) //if (!CA_FarRead(file,(void id0_far *)&skycolor,sizeof(skycolor))) return(false); skycolor = GetSkyGndColorPtrFromDOSPointer(i); if (BE_Cross_readInt16LE(file, &i) != 2) //if (!CA_FarRead(file,(void id0_far *)&groundcolor,sizeof(groundcolor))) return(false); groundcolor = GetSkyGndColorPtrFromDOSPointer(i); if (BE_Cross_readInt16LE(file, &FreezeTime) != 2) //if (!CA_FarRead(file,(void id0_far *)&FreezeTime,sizeof(FreezeTime))) return(false); // (REFKEEN) Reading fields one-by-one in a cross-platform manner if (!LoadGameState(file, &gamestate)) //if (!CA_FarRead(file,(void id0_far *)&gamestate,sizeof(gamestate))) return(false); if (BE_Cross_read_boolean_From16LE(file, &EASYMODEON) != 2) //if (!CA_FarRead(file,(void id0_far *)&EASYMODEON,sizeof(EASYMODEON))) return(false); SetupGameLevel (); // load in and cache the base old level // (REFKEEN) DIFFERENCE FROM VANILLA CATACOMB ADVENTURES: // Don't do this check, we've already opened the file anyway // and this can lead to unexpected behaviors! #if 0 if (!FindRewritableFile(Filename,"SAVE GAME",-1)) Quit("Error: Can't find saved game file!"); #endif expanded = mapwidth * mapheight * 2; MM_GetPtr (&bigbuffer,expanded); for (i = 0;i < 3;i+=2) // Read planes 0 and 2 { if (BE_Cross_readInt16LE(file, &compressed) != 2) //if (!CA_FarRead(file,(id0_byte_t id0_far *)&compressed,sizeof(compressed)) ) { MM_FreePtr (&bigbuffer); return(false); } if (BE_Cross_readInt16LEBuffer(file, bigbuffer, compressed) != compressed) //if (!CA_FarRead(file,(id0_byte_t id0_far *)bigbuffer,compressed) ) { MM_FreePtr (&bigbuffer); return(false); } CA_RLEWexpand ((id0_unsigned_t id0_huge *)bigbuffer, (id0_unsigned_t id0_huge *)mapsegs[i],expanded,RLETAG); } MM_FreePtr (&bigbuffer); // // copy the wall data to a data segment array again, to handle doors and // bomb walls that are allready opened // memset (tilemap,0,sizeof(tilemap)); memset (actorat,0,sizeof(actorat)); map = mapsegs[0]; for (y=0;y<mapheight;y++) for (x=0;x<mapwidth;x++) { tile = *map++; if (tile<NUMFLOORS) { if (tile != INVISIBLEWALL) tilemap[x][y] = tile; if (tile>0) actorat[x][y] = tile; //(id0_unsigned_t)actorat[x][y] = tile; } } // Read the object list back in - assumes at least one object in list InitObjList (); newobj = player; while (true) { prev = newobj->prev; next = newobj->next; // (REFKEEN) Reading fields one-by-one in a cross-platform manner if (!LoadObject(file, newobj)) //if (!CA_FarRead(file,(void id0_far *)newobj,sizeof(objtype))) return(false); followed = newobj->next; newobj->prev = prev; newobj->next = next; actorat[newobj->tilex][newobj->tiley] = COMPAT_OBJ_CONVERT_OBJ_PTR_TO_DOS_PTR(newobj); // drop a new marker //actorat[newobj->tilex][newobj->tiley] = newobj; // drop a new marker if (followed) GetNewObj (false); else break; } return(true); }