// Similar new methods for writing/reading game state static id0_boolean_t SaveGameState(BE_FILE_T file, gametype *state) { return ((BE_Cross_writeInt16LE(file, &state->worldx) == 2) && (BE_Cross_writeInt16LE(file, &state->worldy) == 2) && (BE_Cross_write_booleans_To16LEBuffer(file, state->leveldone, 2*sizeof(state->leveldone)/sizeof(id0_boolean_t)) == 2*sizeof(state->leveldone)/sizeof(id0_boolean_t)) && (BE_Cross_writeInt32LE(file, &state->score) == 4) && (BE_Cross_writeInt32LE(file, &state->nextextra) == 4) && (BE_Cross_writeInt16LE(file, &state->flowerpowers) == 2) && (BE_Cross_writeInt16LE(file, &state->boobusbombs) == 2) && (BE_Cross_writeInt16LE(file, &state->bombsthislevel) == 2) && (BE_Cross_writeInt16LE(file, &state->keys) == 2) && (BE_Cross_writeInt16LE(file, &state->mapon) == 2) && (BE_Cross_writeInt16LE(file, &state->lives) == 2) && (BE_Cross_writeInt16LE(file, &state->difficulty) == 2) ); }
// Similar new methods for writing/reading game state static id0_boolean_t SaveGameState(BE_FILE_T file, gametype *state) { id0_word_t padding; // Two bytes of struct tail padding for 2015 port return ((BE_Cross_writeInt16LE(file, &state->worldx) == 2) && (BE_Cross_writeInt16LE(file, &state->worldy) == 2) && (((refkeen_current_gamever != BE_GAMEVER_KDREAMS2015) && (BE_Cross_write_booleans_To16LEBuffer(file, state->leveldone, 2*sizeof(state->leveldone)/sizeof(id0_boolean_t)) == 2*sizeof(state->leveldone)/sizeof(id0_boolean_t))) || ((refkeen_current_gamever == BE_GAMEVER_KDREAMS2015) && (BE_Cross_write_booleans_To32LEBuffer(file, state->leveldone, 4*sizeof(state->leveldone)/sizeof(id0_boolean_t)) == 4*sizeof(state->leveldone)/sizeof(id0_boolean_t))) ) && (BE_Cross_writeInt32LE(file, &state->score) == 4) && (BE_Cross_writeInt32LE(file, &state->nextextra) == 4) && (BE_Cross_writeInt16LE(file, &state->flowerpowers) == 2) && (BE_Cross_writeInt16LE(file, &state->boobusbombs) == 2) && (BE_Cross_writeInt16LE(file, &state->bombsthislevel) == 2) && (BE_Cross_writeInt16LE(file, &state->keys) == 2) && (BE_Cross_writeInt16LE(file, &state->mapon) == 2) && (BE_Cross_writeInt16LE(file, &state->lives) == 2) && (BE_Cross_writeInt16LE(file, &state->difficulty) == 2) && (((refkeen_current_gamever != BE_GAMEVER_KDREAMS2015) || (BE_Cross_writeInt16LE(file, &padding) == 2))) ); }
// Similar new methods for writing/reading game state static id0_boolean_t SaveGameState(BE_FILE_T file, gametype *state) { return ((BE_Cross_writeInt16LE(file, &state->difficulty) == 2) && (BE_Cross_writeInt16LE(file, &state->mapon) == 2) && (BE_Cross_writeInt16LE(file, &state->bolts) == 2) && (BE_Cross_writeInt16LE(file, &state->nukes) == 2) && (BE_Cross_writeInt16LE(file, &state->potions) == 2) && (BE_Cross_writeInt16LEBuffer(file, state->keys, sizeof(state->keys)) == sizeof(state->keys)) && (BE_Cross_writeInt16LEBuffer(file, state->scrolls, sizeof(state->scrolls)) == sizeof(state->scrolls)) && (BE_Cross_writeInt16LEBuffer(file, state->gems, sizeof(state->gems)) == sizeof(state->gems)) && (BE_Cross_writeInt32LE(file, &state->score) == 4) && (BE_Cross_writeInt16LE(file, &state->body) == 2) && (BE_Cross_writeInt16LE(file, &state->shotpower) == 2) && (BE_Cross_writeInt16LE(file, &state->mapwidth) == 2) && (BE_Cross_writeInt16LE(file, &state->mapheight) == 2) ); }
id0_boolean_t SaveTheGame(BE_FILE_T file) { id0_word_t i,compressed,expanded; objtype *o; memptr bigbuffer; if (BE_Cross_writeInt16LE(file, &FreezeTime) != 2) //if (!CA_FarWrite(file,(void id0_far *)&FreezeTime,sizeof(FreezeTime))) return(false); // (REFKEEN) Writing fields one-by-one in a cross-platform manner if (!SaveGameState(file, &gamestate)) //if (!CA_FarWrite(file,(void id0_far *)&gamestate,sizeof(gamestate))) return(false); if (BE_Cross_write_boolean_To16LE(file, &EASYMODEON) != 2) //if (!CA_FarWrite(file,(void id0_far *)&EASYMODEON,sizeof(EASYMODEON))) return(false); expanded = mapwidth * mapheight * 2; MM_GetPtr (&bigbuffer,expanded); for (i = 0;i < 3;i+=2) // Write planes 0 and 2 { // // leave a word at start of compressed data for compressed length // compressed = (id0_unsigned_t)CA_RLEWCompress ((id0_unsigned_t id0_huge *)mapsegs[i] ,expanded,((id0_unsigned_t id0_huge *)bigbuffer)+1,RLETAG); *(id0_unsigned_t id0_huge *)bigbuffer = compressed; if (BE_Cross_writeInt16LEBuffer(file, bigbuffer, compressed+2) != (id0_word_t)(compressed+2)) //if (!CA_FarWrite(file,(id0_byte_t id0_far *)bigbuffer,compressed+2) ) { MM_FreePtr (&bigbuffer); return(false); } } for (o = player;o;o = o->next) // (REFKEEN) Writing fields one-by-one in a cross-platform manner if (!SaveObject(file, o)) //if (!CA_FarWrite(file,(void id0_far *)o,sizeof(objtype))) { MM_FreePtr (&bigbuffer); return(false); } MM_FreePtr (&bigbuffer); return(true); }
// REFKEEN - New cross-platform methods for reading/writing objects from/to saved games static id0_boolean_t SaveObject(BE_FILE_T file, objtype *o) { id0_int_t dummy = 0; // for active enum (anonymous type) id0_int_t activeint = (id0_int_t)(o->active); // BACKWARD COMPATIBILITY id0_word_t statedosoffset = o->state ? o->state->compatdospointer : 0; // Just tells if "o->next" is zero or not id0_int_t isnext = o->next ? 1 : 0; // Now writing size_t BE_Cross_write_classtype_To16LE(BE_FILE_T fp, const classtype *ptr); size_t BE_Cross_write_dirtype_To16LE(BE_FILE_T fp, const dirtype *ptr); return ((BE_Cross_writeInt16LE(file, &activeint) == 2) && (BE_Cross_writeInt16LE(file, &o->ticcount) == 2) && (BE_Cross_write_classtype_To16LE(file, &o->obclass) == 2) && (BE_Cross_writeInt16LE(file, &statedosoffset) == 2) // BACKWARD COMPATIBILITY && (BE_Cross_write_boolean_To16LE(file, &o->shootable) == 2) && (BE_Cross_write_boolean_To16LE(file, &o->tileobject) == 2) && (BE_Cross_writeInt32LE(file, &o->distance) == 4) && (BE_Cross_write_dirtype_To16LE(file, &o->dir) == 2) && (BE_Cross_writeInt32LE(file, &o->x) == 4) && (BE_Cross_writeInt32LE(file, &o->y) == 4) && (BE_Cross_writeInt16LE(file, &o->tilex) == 2) && (BE_Cross_writeInt16LE(file, &o->tiley) == 2) && (BE_Cross_writeInt16LE(file, &o->viewx) == 2) && (BE_Cross_writeInt16LE(file, &o->viewheight) == 2) && (BE_Cross_writeInt16LE(file, &o->angle) == 2) && (BE_Cross_writeInt16LE(file, &o->hitpoints) == 2) && (BE_Cross_writeInt32LE(file, &o->speed) == 4) && (BE_Cross_writeInt16LE(file, &o->size) == 2) && (BE_Cross_writeInt32LE(file, &o->xl) == 4) && (BE_Cross_writeInt32LE(file, &o->xh) == 4) && (BE_Cross_writeInt32LE(file, &o->yl) == 4) && (BE_Cross_writeInt32LE(file, &o->yh) == 4) && (BE_Cross_writeInt16LE(file, &o->temp1) == 2) && (BE_Cross_writeInt16LE(file, &o->temp2) == 2) // No need to write prev pointer as-is, // this is ignored on loading. So write dummy value. // Furthermore, all we need to know about next on loading is // if it's zero or not. && (BE_Cross_writeInt16LE(file, &isnext) == 2) // next && (BE_Cross_writeInt8LEBuffer(file, &dummy, 2) == 2) // prev ); }
// REFKEEN - New cross-platform methods for reading/writing objects from/to saved games static id0_boolean_t SaveObject(BE_FILE_T file, objtype *o) { id0_int_t dummy = 0; // for active enum (anonymous type) id0_int_t activeint = (id0_int_t)(o->active); // BACKWARD COMPATIBILITY id0_word_t statedosoffset = o->state ? o->state->compatdospointer : 0; // Just tells if "o->next" is zero or not id0_int_t isnext = o->next ? 1 : 0; // Now writing size_t BE_Cross_write_classtype_To16LE(BE_FILE_T fp, const classtype *ptr); return ((BE_Cross_write_classtype_To16LE(file, &o->obclass) == 2) && (BE_Cross_writeInt16LE(file, &activeint) == 2) && (BE_Cross_write_boolean_To16LE(file, &o->needtoreact) == 2) && (BE_Cross_write_boolean_To16LE(file, &o->needtoclip) == 2) && (BE_Cross_writeInt16LE(file, &o->nothink) == 2) && (BE_Cross_writeInt16LE(file, &o->x) == 2) && (BE_Cross_writeInt16LE(file, &o->y) == 2) && (BE_Cross_writeInt16LE(file, &o->xdir) == 2) && (BE_Cross_writeInt16LE(file, &o->ydir) == 2) && (BE_Cross_writeInt16LE(file, &o->xmove) == 2) && (BE_Cross_writeInt16LE(file, &o->ymove) == 2) && (BE_Cross_writeInt16LE(file, &o->xspeed) == 2) && (BE_Cross_writeInt16LE(file, &o->yspeed) == 2) && (BE_Cross_writeInt16LE(file, &o->ticcount) == 2) && (BE_Cross_writeInt16LE(file, &o->ticadjust) == 2) && (BE_Cross_writeInt16LE(file, &statedosoffset) == 2) // BACKWARD COMPATIBILITY && (BE_Cross_writeInt16LE(file, &o->shapenum) == 2) && (BE_Cross_writeInt16LE(file, &o->left) == 2) && (BE_Cross_writeInt16LE(file, &o->top) == 2) && (BE_Cross_writeInt16LE(file, &o->right) == 2) && (BE_Cross_writeInt16LE(file, &o->bottom) == 2) && (BE_Cross_writeInt16LE(file, &o->midx) == 2) && (BE_Cross_writeInt16LE(file, &o->tileleft) == 2) && (BE_Cross_writeInt16LE(file, &o->tiletop) == 2) && (BE_Cross_writeInt16LE(file, &o->tileright) == 2) && (BE_Cross_writeInt16LE(file, &o->tilebottom) == 2) && (BE_Cross_writeInt16LE(file, &o->tilemidx) == 2) && (BE_Cross_writeInt16LE(file, &o->hitnorth) == 2) && (BE_Cross_writeInt16LE(file, &o->hiteast) == 2) && (BE_Cross_writeInt16LE(file, &o->hitsouth) == 2) && (BE_Cross_writeInt16LE(file, &o->hitwest) == 2) && (BE_Cross_writeInt16LE(file, &o->temp1) == 2) && (BE_Cross_writeInt16LE(file, &o->temp2) == 2) && (BE_Cross_writeInt16LE(file, &o->temp3) == 2) && (BE_Cross_writeInt16LE(file, &o->temp4) == 2) // No need to write sprite, prev pointers as-is, // these are ignored on loading. So write dummy value. // Furthermore, all we need to know about next on loading is // if it's zero or not. && (BE_Cross_writeInt16LE(file, &dummy) == 2) // sprite && (BE_Cross_writeInt16LE(file, &isnext) == 2) // next && (BE_Cross_writeInt16LE(file, &dummy) == 2) // prev ); }
id0_boolean_t SaveTheGame(BE_FILE_T file) { id0_word_t i,compressed,expanded; objtype *o; memptr bigbuffer; // save the sky and ground colors // REFKEEN - But not before converting to original 16-bit pointers (reusing i variable) i = GetSkyGndColorDOSPtrFromNativePointer(skycolor); if (BE_Cross_writeInt16LE(file, &i) != 2) //if (!CA_FarWrite(file,(void id0_far *)&skycolor,sizeof(skycolor))) return(false); i = GetSkyGndColorDOSPtrFromNativePointer(groundcolor); if (BE_Cross_writeInt16LE(file, &i) != 2) //if (!CA_FarWrite(file,(void id0_far *)&groundcolor,sizeof(groundcolor))) return(false); if (BE_Cross_writeInt16LE(file, &FreezeTime) != 2) //if (!CA_FarWrite(file,(void id0_far *)&FreezeTime,sizeof(FreezeTime))) return(false); // (REFKEEN) Writing fields one-by-one in a cross-platform manner if (!SaveGameState(file, &gamestate)) //if (!CA_FarWrite(file,(void id0_far *)&gamestate,sizeof(gamestate))) return(false); if (BE_Cross_write_boolean_To16LE(file, &EASYMODEON) != 2) //if (!CA_FarWrite(file,(void id0_far *)&EASYMODEON,sizeof(EASYMODEON))) return(false); expanded = mapwidth * mapheight * 2; MM_GetPtr (&bigbuffer,expanded); for (i = 0;i < 3;i+=2) // Write planes 0 and 2 { // // leave a word at start of compressed data for compressed length // compressed = (id0_unsigned_t)CA_RLEWCompress ((id0_unsigned_t id0_huge *)mapsegs[i] ,expanded,((id0_unsigned_t id0_huge *)bigbuffer)+1,RLETAG); *(id0_unsigned_t id0_huge *)bigbuffer = compressed; if (BE_Cross_writeInt16LEBuffer(file, bigbuffer, compressed+2) != (id0_word_t)(compressed+2)) //if (!CA_FarWrite(file,(id0_byte_t id0_far *)bigbuffer,compressed+2) ) { MM_FreePtr (&bigbuffer); return(false); } } for (o = player;o;o = o->next) // (REFKEEN) Writing fields one-by-one in a cross-platform manner if (!SaveObject(file, o)) //if (!CA_FarWrite(file,(void id0_far *)o,sizeof(objtype))) { MM_FreePtr (&bigbuffer); return(false); } MM_FreePtr (&bigbuffer); return(true); }