void WriteLevel(qboolean qbAutosave) { if (!qbAutosave) //-always save the client { // write out one client - us! // assert(level.maxclients == 1); // I'll need to know if this changes, otherwise I'll need to change the way ReadGame works gclient_t client = level.clients[0]; EnumerateFields(savefields_gClient, (byte *)&client, 'GCLI', sizeof(client)); WriteLevelLocals(); // level_locals_t level } OBJ_SaveObjectiveData(); FX_Write(); ///////////// WriteGEntities(qbAutosave); Quake3Game()->VariableSave(); G_LoadSave_WriteMiscData(); extern void CG_WriteTheEvilCGHackStuff(void); CG_WriteTheEvilCGHackStuff(); // (Do NOT put any write-code below this line) // // put out an end-marker so that the load code can check everything was read in... // static int iDONE = 1234; gi.AppendToSaveGame('DONE', &iDONE, sizeof(iDONE)); }
/* ============== WriteLevelLocals All pointer variables (except function pointers) must be handled specially. ============== */ static void WriteLevelLocals () { level_locals_t *temp = (level_locals_t *)gi.Malloc(sizeof(level_locals_t), TAG_TEMP_WORKSPACE, qfalse); *temp = level; // copy out all data into a temp space EnumerateFields(savefields_LevelLocals, (byte *)temp, 'LVLC', LLOFS(LEVEL_LOCALS_T_SAVESTOP)); // sizeof(temp)); gi.Free(temp); }
/* ============== WriteLevelLocals All pointer variables (except function pointers) must be handled specially. ============== */ static void WriteLevelLocals () { level_locals_t *temp = (level_locals_t *)gi.Malloc(sizeof(level_locals_t), TAG_TEMP_WORKSPACE, qfalse); *temp = level; // copy out all data into a temp space EnumerateFields(savefields_LevelLocals, temp, INT_ID('L','V','L','C')); gi.Free(temp); }
void WriteLevel(qboolean qbAutosave) { if (!qbAutosave) //-always save the client { // write out one client - us! // assert(level.maxclients == 1); // I'll need to know if this changes, otherwise I'll need to change the way ReadGame works gclient_t client = level.clients[0]; EnumerateFields(savefields_gClient, &client, INT_ID('G','C','L','I')); WriteLevelLocals(); // level_locals_t level } OBJ_SaveObjectiveData(); FX_Write(); ///////////// WriteGEntities(qbAutosave); Quake3Game()->VariableSave(); G_LoadSave_WriteMiscData(); extern void CG_WriteTheEvilCGHackStuff(void); CG_WriteTheEvilCGHackStuff(); // (Do NOT put any write-code below this line) // // put out an end-marker so that the load code can check everything was read in... // static int iDONE = 1234; ojk::SavedGameHelper saved_game( ::gi.saved_game); saved_game.write_chunk<int32_t>( INT_ID('D', 'O', 'N', 'E'), iDONE); }
static void WriteGEntities(qboolean qbAutosave) { int iCount = 0; int i; for (i=0; i<(qbAutosave?1:globals.num_entities); i++) { gentity_t* ent = &g_entities[i]; if ( ent->inuse ) { iCount++; } } gi.AppendToSaveGame('NMED', &iCount, sizeof(iCount)); for (i=0; i<(qbAutosave?1:globals.num_entities); i++) { gentity_t* ent = &g_entities[i]; if ( ent->inuse) { gi.AppendToSaveGame('EDNM', (void *)&i, sizeof(i)); qboolean qbLinked = ent->linked; gi.unlinkentity( ent ); gentity_t tempEnt = *ent; // make local copy tempEnt.linked = qbLinked; if (qbLinked) { gi.linkentity( ent ); } EnumerateFields(savefields_gEntity, (byte *)&tempEnt, 'GENT', sizeof(tempEnt)); // now for any fiddly bits that would be rather awkward to build into the enumerator... // if (tempEnt.NPC) { gNPC_t npc = *ent->NPC; // NOT *tempEnt.NPC; !! :-) EnumerateFields(savefields_gNPC, (byte *)&npc, 'GNPC', sizeof(npc)); } if (tempEnt.client == (gclient_t *)-2) // I know, I know... { gclient_t client = *ent->client; // NOT *tempEnt.client!! EnumerateFields(savefields_gClient, (byte *)&client, 'GCLI', sizeof(client)); } if (tempEnt.parms) { gi.AppendToSaveGame('PARM', ent->parms, sizeof(*ent->parms)); } if (tempEnt.m_pVehicle) { Vehicle_t vehicle = *ent->m_pVehicle; // NOT *tempEnt.m_pVehicle!! EnumerateFields(savefields_gVHIC, (byte *)&vehicle, 'VHIC', sizeof(vehicle)); } // the scary ghoul2 saver stuff... (fingers crossed) // gi.G2API_SaveGhoul2Models(tempEnt.ghoul2); tempEnt.ghoul2.kill(); // this handle was shallow copied from an ent. We don't want it destroyed } } //Write out all entity timers TIMER_Save();//WriteEntityTimers(); if (!qbAutosave) { //Save out ICARUS information IIcarusInterface::GetIcarus()->Save(); // this marker needs to be here, it lets me know if Icarus doesn't load everything back later, // which has happened, and doesn't always show up onscreen until certain game situations. // This saves time debugging, and makes things easier to track. // static int iBlah = 1234; gi.AppendToSaveGame('ICOK', &iBlah, sizeof(iBlah)); } if (!qbAutosave )//really shouldn't need to write these bits at all, just restore them from the ents... { WriteInUseBits(); } }
static void WriteGEntities(qboolean qbAutosave) { int iCount = 0; int i; for (i=0; i<(qbAutosave?1:globals.num_entities); i++) { gentity_t* ent = &g_entities[i]; if ( ent->inuse ) { iCount++; } } ojk::SavedGameHelper saved_game( ::gi.saved_game); saved_game.write_chunk<int32_t>( INT_ID('N', 'M', 'E', 'D'), iCount); for (i=0; i<(qbAutosave?1:globals.num_entities); i++) { gentity_t* ent = &g_entities[i]; if ( ent->inuse) { saved_game.write_chunk<int32_t>( INT_ID('E', 'D', 'N', 'M'), i); qboolean qbLinked = ent->linked; gi.unlinkentity( ent ); gentity_t tempEnt = *ent; // make local copy tempEnt.linked = qbLinked; if (qbLinked) { gi.linkentity( ent ); } EnumerateFields(savefields_gEntity, &tempEnt, INT_ID('G','E','N','T')); // now for any fiddly bits that would be rather awkward to build into the enumerator... // if (tempEnt.NPC) { gNPC_t npc = *ent->NPC; // NOT *tempEnt.NPC; !! :-) EnumerateFields(savefields_gNPC, &npc, INT_ID('G','N','P','C')); } if (tempEnt.client == (gclient_t *)-2) // I know, I know... { gclient_t client = *ent->client; // NOT *tempEnt.client!! EnumerateFields(savefields_gClient, &client, INT_ID('G','C','L','I')); } if (tempEnt.parms) { saved_game.write_chunk( INT_ID('P', 'A', 'R', 'M'), *ent->parms); } if (tempEnt.m_pVehicle) { Vehicle_t vehicle = *ent->m_pVehicle; // NOT *tempEnt.m_pVehicle!! EnumerateFields(savefields_gVHIC, &vehicle, INT_ID('V','H','I','C')); } // the scary ghoul2 saver stuff... (fingers crossed) // gi.G2API_SaveGhoul2Models(tempEnt.ghoul2); tempEnt.ghoul2.kill(); // this handle was shallow copied from an ent. We don't want it destroyed } } //Write out all entity timers TIMER_Save();//WriteEntityTimers(); if (!qbAutosave) { //Save out ICARUS information IIcarusInterface::GetIcarus()->Save(); // this marker needs to be here, it lets me know if Icarus doesn't load everything back later, // which has happened, and doesn't always show up onscreen until certain game situations. // This saves time debugging, and makes things easier to track. // static int iBlah = 1234; saved_game.write_chunk<int32_t>( INT_ID('I', 'C', 'O', 'K'), iBlah); } if (!qbAutosave )//really shouldn't need to write these bits at all, just restore them from the ents... { WriteInUseBits(); } }
/* ============== WriteLevelLocals All pointer variables (except function pointers) must be handled specially. ============== */ void WriteLevelLocals () { level_locals_t temp = level; // copy out all data into a temp space EnumerateFields(savefields_LevelLocals, (byte *)&temp, 'LVLC', LLOFS(LEVEL_LOCALS_T_SAVESTOP)); // sizeof(temp)); }