This is an automated email from the git hooks/post-receive script. smcv pushed a commit to branch debian/master in repository openjk.
commit 3dcf239041df17b181ef6872b11824ff293cd51a Author: bibendovsky <[email protected]> Date: Mon Jul 25 19:08:34 2016 +0300 Clean up saved game code leftovers --- code/game/g_savegame.cpp | 297 ++----------------- code/server/sv_savegame.cpp | 674 +------------------------------------------- codeJK2/game/g_savegame.cpp | 90 ++---- 3 files changed, 35 insertions(+), 1026 deletions(-) diff --git a/code/game/g_savegame.cpp b/code/game/g_savegame.cpp index 4ca5aec..d31cbfb 100644 --- a/code/game/g_savegame.cpp +++ b/code/game/g_savegame.cpp @@ -508,8 +508,7 @@ template<typename T> static void EnumerateFields( const save_field_t* pFields, const T* src_instance, - unsigned int ulChid, - size_t iLen) + unsigned int ulChid) { strList.clear(); @@ -520,7 +519,7 @@ static void EnumerateFields( // if (pFields) { for (auto pField = pFields; pField->psName; ++pField) { - assert(pField->iOffset < iLen); + assert(pField->iOffset < sizeof(T)); ::EnumerateField(pField, pbData); } } @@ -666,78 +665,6 @@ static const char *SG_GetChidText( unsigned int chid ) { } extern void WP_SaberSetDefaults( saberInfo_t *saber, qboolean setColors); -static void SG_ConvertRetailSaberinfoToNewSaberinfo( void *sabData, saberInfo_t *saberNew ) -{ - saberInfoRetail_t *saberRetail = ((saberInfoRetail_t *)(sabData)); - - for ( int saberNum = 0; saberNum < 2; saberNum++ ) - { - WP_SaberSetDefaults( &saberNew[saberNum], qfalse ); - if ( !saberRetail[saberNum].activeBlocking ) - { - saberNew[saberNum].saberFlags |= SFL_NOT_ACTIVE_BLOCKING; - } - memcpy( saberNew[saberNum].blade, saberRetail[saberNum].blade, sizeof( saberRetail[saberNum].blade ) ); - saberNew[saberNum].breakParryBonus = saberRetail[saberNum].breakParryBonus; - saberNew[saberNum].brokenSaber1 = saberRetail[saberNum].brokenSaber1; - saberNew[saberNum].brokenSaber2 = saberRetail[saberNum].brokenSaber2; - if ( !saberRetail[saberNum].disarmable ) - { - saberNew[saberNum].saberFlags |= SFL_NOT_DISARMABLE; - } - saberNew[saberNum].disarmBonus = saberRetail[saberNum].disarmBonus; - saberNew[saberNum].forceRestrictions = saberRetail[saberNum].forceRestrictions; - saberNew[saberNum].fullName = saberRetail[saberNum].fullName; - if ( !saberRetail[saberNum].lockable ) - { - saberNew[saberNum].saberFlags |= SFL_NOT_LOCKABLE; - } - saberNew[saberNum].lockBonus = saberRetail[saberNum].lockBonus; - saberNew[saberNum].maxChain = saberRetail[saberNum].maxChain; - saberNew[saberNum].model = saberRetail[saberNum].model; - saberNew[saberNum].name = saberRetail[saberNum].name; - saberNew[saberNum].numBlades = saberRetail[saberNum].numBlades; - saberNew[saberNum].parryBonus = saberRetail[saberNum].parryBonus; - if ( saberRetail[saberNum].returnDamage ) - { - saberNew[saberNum].saberFlags |= SFL_RETURN_DAMAGE; - } - saberNew[saberNum].singleBladeStyle = saberRetail[saberNum].singleBladeStyle; - if ( saberRetail[saberNum].singleBladeThrowable ) - { - saberNew[saberNum].saberFlags |= SFL_SINGLE_BLADE_THROWABLE; - } - saberNew[saberNum].skin = saberRetail[saberNum].skin; - saberNew[saberNum].soundLoop = saberRetail[saberNum].soundLoop; - saberNew[saberNum].soundOff = saberRetail[saberNum].soundOff; - saberNew[saberNum].soundOn = saberRetail[saberNum].soundOn; - if ( saberRetail[saberNum].style != SS_NONE - && saberRetail[saberNum].style < SS_NUM_SABER_STYLES ) - {//OLD WAY: only allowed ONE style - //learn only this style - saberNew[saberNum].stylesLearned = (1<<saberRetail[saberNum].style); - //forbid all other styles - saberNew[saberNum].stylesForbidden = 0; - for ( int styleNum = SS_NONE+1; styleNum < SS_NUM_SABER_STYLES; styleNum++ ) - { - if ( styleNum != saberRetail[saberNum].style ) - { - saberNew[saberNum].stylesForbidden |= (1<<styleNum); - } - } - } - if ( !saberRetail[saberNum].throwable ) - { - saberNew[saberNum].saberFlags |= SFL_NOT_THROWABLE; - } - if ( saberRetail[saberNum].twoHanded ) - { - saberNew[saberNum].saberFlags |= SFL_TWO_HANDED; - } - saberNew[saberNum].type = saberRetail[saberNum].type; - } -} - void saberInfoRetail_t::sg_export( saberInfo_t& dst) const @@ -858,72 +785,12 @@ static void copy_retail_gclient_to_current( src_post_size); } -#if 0 -template<typename T> -static void EvaluateFields(const save_field_t *pFields, T *pbData, byte *pbOriginalRefData, unsigned int ulChid, int iSize, qboolean bOkToSizeMisMatch) -{ - using SgType = typename T::SgType; - - iSize = static_cast<int>(sizeof(SgType)); - - auto& sg_buffer = ::sg_get_buffer(iSize); - - auto sg_object = reinterpret_cast<SgType*>(sg_buffer.data()); - - int iReadSize = ::gi.ReadFromSaveGame(ulChid, sg_object, bOkToSizeMisMatch?0:iSize, NULL); - - if (iReadSize != iSize) - { - // handle any chunks that are ok to change length (typically this is a last minute hack, - // so hopefully we won't need it any more... ;-) - // - switch (ulChid) - { - // example chunk handler... - // - case INT_ID('G','C','L','I'): - if ( iSize == (int)(iReadSize+((sizeof(saberInfo_t)-sizeof(saberInfoRetail_t))*2)) ) - { - gclient_t newClient; - const int preSaberDataSize = ((intptr_t)&newClient.ps.saber[0]-(intptr_t)&newClient); - memcpy( &newClient, pbData, preSaberDataSize ); - SG_ConvertRetailSaberinfoToNewSaberinfo( ((void *)(&((gclient_t *)(pbData))->ps.saber[0])), &newClient.ps.saber[0] ); - memcpy( &newClient.ps.dualSabers, pbData+preSaberDataSize+(sizeof(saberInfoRetail_t)*2), sizeof(newClient)-(preSaberDataSize+(sizeof(saberInfo_t)*2)) ); - memcpy( pbData, &newClient, sizeof(gclient_t) ); - } - else - {//opps, not a saberInfo size mismatch, some other FUBAR-ness... - G_Error(va("EvaluateFields(): variable-sized chunk '%s' without handler!",SG_GetChidText(ulChid))); - } - break; - - default: - // won't return... - // - G_Error(va("EvaluateFields(): variable-sized chunk '%s' without handler!",SG_GetChidText(ulChid))); - break; - } - } - - ::sg_import(*sg_object, *pbData); - - if (pFields) - { - for (const save_field_t *pField = pFields; pField->psName; pField++) - { - EvaluateField(pField, reinterpret_cast<byte*>(pbData), pbOriginalRefData); - } - } -} -#else template<typename T> static void EvaluateFields( const save_field_t* pFields, T* pbData, byte* pbOriginalRefData, - unsigned int ulChid, - int iSize, - qboolean bOkToSizeMisMatch) + unsigned int ulChid) { auto& instance = *pbData; @@ -975,7 +842,6 @@ static void EvaluateFields( } } } -#endif /* ============== @@ -989,7 +855,7 @@ 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'), LLOFS(LEVEL_LOCALS_T_SAVESTOP)); // sizeof(temp)); + EnumerateFields(savefields_LevelLocals, temp, INT_ID('L','V','L','C')); gi.Free(temp); } @@ -1008,7 +874,7 @@ static void ReadLevelLocals () level_locals_t *temp = (level_locals_t *)gi.Malloc(sizeof(level_locals_t), TAG_TEMP_WORKSPACE, qfalse); *temp = level; // struct copy - EvaluateFields(savefields_LevelLocals, temp, (byte *)&level, INT_ID('L','V','L','C'), LLOFS(LEVEL_LOCALS_T_SAVESTOP),qfalse); // sizeof(level_locals_t)); + EvaluateFields(savefields_LevelLocals, temp, (byte *)&level, INT_ID('L','V','L','C')); level = *temp; // struct copy level.clients = pClients; // restore clients @@ -1054,7 +920,7 @@ static void WriteGEntities(qboolean qbAutosave) gi.linkentity( ent ); } - EnumerateFields(savefields_gEntity, &tempEnt, INT_ID('G','E','N','T'), sizeof(tempEnt)); + 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... // @@ -1062,13 +928,13 @@ static void WriteGEntities(qboolean qbAutosave) { gNPC_t npc = *ent->NPC; // NOT *tempEnt.NPC; !! :-) - EnumerateFields(savefields_gNPC, &npc, INT_ID('G','N','P','C'), sizeof(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'), sizeof(client)); + EnumerateFields(savefields_gClient, &client, INT_ID('G','C','L','I')); } if (tempEnt.parms) @@ -1081,7 +947,7 @@ static void WriteGEntities(qboolean qbAutosave) if (tempEnt.m_pVehicle) { Vehicle_t vehicle = *ent->m_pVehicle; // NOT *tempEnt.m_pVehicle!! - EnumerateFields(savefields_gVHIC, &vehicle, INT_ID('V','H','I','C'), sizeof(vehicle)); + EnumerateFields(savefields_gVHIC, &vehicle, INT_ID('V','H','I','C')); } // the scary ghoul2 saver stuff... (fingers crossed) @@ -1166,7 +1032,7 @@ static void ReadGEntities(qboolean qbAutosave) // gi.G2API_LoadSaveCodeDestructGhoul2Info(pEnt->ghoul2); pEnt->ghoul2.kill(); - EvaluateFields(savefields_gEntity, pEnt, (byte *)pEntOriginal, INT_ID('G','E','N','T'), sizeof(*pEnt),qfalse); + EvaluateFields(savefields_gEntity, pEnt, (byte *)pEntOriginal, INT_ID('G','E','N','T')); pEnt->ghoul2.kill(); // now for any fiddly bits... @@ -1175,7 +1041,7 @@ static void ReadGEntities(qboolean qbAutosave) { gNPC_t tempNPC; - EvaluateFields(savefields_gNPC, &tempNPC,(byte *)pEntOriginal->NPC, INT_ID('G','N','P','C'), sizeof (*pEnt->NPC),qfalse); + EvaluateFields(savefields_gNPC, &tempNPC,(byte *)pEntOriginal->NPC, INT_ID('G','N','P','C')); // so can we pinch the original's one or do we have to alloc a new one?... // @@ -1211,7 +1077,7 @@ static void ReadGEntities(qboolean qbAutosave) { gclient_t tempGClient; - EvaluateFields(savefields_gClient, &tempGClient, (byte *)pEntOriginal->client, INT_ID('G','C','L','I'), sizeof(*pEnt->client),qtrue);//qfalse); + EvaluateFields(savefields_gClient, &tempGClient, (byte *)pEntOriginal->client, INT_ID('G','C','L','I')); // can we pinch the original's client handle or do we have to alloc a new one?... // @@ -1272,7 +1138,7 @@ static void ReadGEntities(qboolean qbAutosave) { Vehicle_t tempVehicle; - EvaluateFields(savefields_gVHIC, &tempVehicle,(byte *)pEntOriginal->m_pVehicle, INT_ID('V','H','I','C'), sizeof (*pEnt->m_pVehicle),qfalse); + EvaluateFields(savefields_gVHIC, &tempVehicle,(byte *)pEntOriginal->m_pVehicle, INT_ID('V','H','I','C')); // so can we pinch the original's one or do we have to alloc a new one?... // @@ -1300,14 +1166,6 @@ static void ReadGEntities(qboolean qbAutosave) ::gi.saved_game->read_chunk( INT_ID('G','H','L','2')); -// FIXME Remove -#if 0 - auto buffer = ::gi.saved_game->get_buffer(); - auto pGhoul2Data = reinterpret_cast<char*>(buffer.data()); - - gi.G2API_LoadGhoul2Models(pEnt->ghoul2, pGhoul2Data); // if it's going to crash anywhere... <g> -#endif - gi.G2API_LoadGhoul2Models(pEnt->ghoul2, nullptr); } @@ -1391,7 +1249,7 @@ void WriteLevel(qboolean qbAutosave) // 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'), sizeof(client)); + EnumerateFields(savefields_gClient, &client, INT_ID('G','C','L','I')); WriteLevelLocals(); // level_locals_t level } @@ -1440,7 +1298,7 @@ void ReadLevel(qboolean qbAutosave, qboolean qbLoadTransition) //Read & throw away gclient info gclient_t junkClient; - EvaluateFields(savefields_gClient, &junkClient, (byte *)&level.clients[0], INT_ID('G','C','L','I'), sizeof(*level.clients), qtrue);//qfalse); + EvaluateFields(savefields_gClient, &junkClient, (byte *)&level.clients[0], INT_ID('G','C','L','I')); ReadLevelLocals(); // level_locals_t level @@ -1455,7 +1313,7 @@ void ReadLevel(qboolean qbAutosave, qboolean qbLoadTransition) assert(level.maxclients == 1); // I'll need to know if this changes, otherwise I'll need to change the way things work gclient_t GClient; - EvaluateFields(savefields_gClient, &GClient, (byte *)&level.clients[0], INT_ID('G','C','L','I'), sizeof(*level.clients), qtrue);//qfalse); + EvaluateFields(savefields_gClient, &GClient, (byte *)&level.clients[0], INT_ID('G','C','L','I')); level.clients[0] = GClient; // struct copy ReadLevelLocals(); // level_locals_t level } @@ -1492,126 +1350,3 @@ qboolean GameAllowedToSaveHere(void) } //////////////////// eof ///////////////////// - -#if 0 -// !!!!!!!!!!!!!!!!!! loadsave affecting structure !!!!!!!!!!!!!!!!!!!!!!! -struct Vehicle_t -{ - // The entity who pilots/drives this vehicle. - // NOTE: This is redundant (since m_pParentEntity->owner _should_ be the pilot). This makes things clearer though. - gentity_t *m_pPilot; - - int m_iPilotTime; //if spawnflag to die without pilot and this < level.time then die. - qboolean m_bHasHadPilot; //qtrue once the vehicle gets its first pilot - - // The passengers of this vehicle. - gentity_t **m_ppPassengers; - - // The number of passengers currently in this vehicle. - int m_iNumPassengers; - - //the droid unit NPC for this vehicle, if any - gentity_t *m_pDroidUnit; - - // The entity from which this NPC comes from. - gentity_t *m_pParentEntity; - - // If not zero, how long to wait before we can do anything with the vehicle (we're getting on still). - // -1 = board from left, -2 = board from right, -3 = jump/quick board. -4 & -5 = throw off existing pilot - int m_iBoarding; - - // Used to check if we've just started the boarding process - bool m_bWasBoarding; - - // The speed the vehicle maintains while boarding occurs (often zero) - vec3_t m_vBoardingVelocity; - - // Time modifier (must only be used in ProcessMoveCommands() and ProcessOrientCommands() and is updated in Update()). - float m_fTimeModifier; - - // Ghoul2 Animation info. - // NOTE: Since each vehicle has their own model instance, these bolts must be local to each vehicle as well. - int m_iLeftWingBone; - int m_iRightWingBone; - //int m_iDriverTag; - int m_iExhaustTag[MAX_VEHICLE_EXHAUSTS]; - int m_iMuzzleTag[MAX_VEHICLE_MUZZLES]; - int m_iDroidUnitTag; - int m_iGunnerViewTag[MAX_VEHICLE_TURRETS];//Where to put the view origin of the gunner (index) - - // This vehicles weapon muzzles. - Muzzle m_Muzzles[MAX_VEHICLE_MUZZLES]; - - // The user commands structure. - usercmd_t m_ucmd; - - // The direction an entity will eject from the vehicle towards. - int m_EjectDir; - - // Flags that describe the vehicles behavior. - unsigned int m_ulFlags; - - // NOTE: Vehicle Type ID, Orientation, and Armor MUST be transmitted over the net. - - // Current angles of this vehicle. - vec3_t m_vOrientation; - - // How long you have strafed left or right (increments every frame that you strafe to right, decrements every frame you strafe left) - int m_fStrafeTime; - - // Previous angles of this vehicle. - vec3_t m_vPrevOrientation; - - // When control is lost on a speeder, current angular velocity is stored here and applied until landing - float m_vAngularVelocity; - - vec3_t m_vFullAngleVelocity; - - // Current armor and shields of your vehicle (explodes if armor to 0). - int m_iArmor; //hull strength - STAT_HEALTH on NPC - int m_iShields; //energy shielding - STAT_ARMOR on NPC - - // Timer for all cgame-FX...? ex: exhaust? - int m_iLastFXTime; - - // When to die. - int m_iDieTime; - - // This pointer is to a valid VehicleInfo (which could be an animal, speeder, fighter, whatever). This - // contains the functions actually used to do things to this specific kind of vehicle as well as shared - // information (max speed, type, etc...). - vehicleInfo_t *m_pVehicleInfo; - - // This trace tells us if we're within landing height. - trace_t m_LandTrace; - - //bitflag of surfaces that have broken off - int m_iRemovedSurfaces; - - // the last time this vehicle fired a turbo burst - int m_iTurboTime; - - //how long it should drop like a rock for after freed from SUSPEND - int m_iDropTime; - - int m_iSoundDebounceTimer; - - //last time we incremented the shields - int lastShieldInc; - - //so we don't hold it down and toggle it back and forth - qboolean linkWeaponToggleHeld; - - //info about our weapons (linked, ammo, etc.) - vehWeaponStatus_t weaponStatus[MAX_VEHICLE_WEAPONS]; - vehTurretStatus_t turretStatus[MAX_VEHICLE_TURRETS]; - - //the guy who was previously the pilot - gentity_t* m_pOldPilot; - - // don't need these in mp - int m_safeJumpMountTime; - float m_safeJumpMountRightDot; -}; - -#endif diff --git a/code/server/sv_savegame.cpp b/code/server/sv_savegame.cpp index 2ae7b43..8ee4b85 100644 --- a/code/server/sv_savegame.cpp +++ b/code/server/sv_savegame.cpp @@ -46,16 +46,8 @@ static char saveGameComment[iSG_COMMENT_SIZE]; int giSaveGameVersion; // filled in when a savegame file is opened -#if 0 -fileHandle_t fhSaveGame = 0; -#endif - SavedGameJustLoaded_e eSavedGameJustLoaded = eNO; -#if 0 -qboolean qbSGReadIsTestOnly = qfalse; // this MUST be left in this state -#endif - char sLastSaveFileLoaded[MAX_QPATH]={0}; #define iSG_MAPCMD_SIZE MAX_QPATH @@ -96,17 +88,6 @@ typedef map<unsigned int, CChid> CChidInfo_t; CChidInfo_t save_info; #endif -#if 0 -const char *SG_GetChidText(unsigned int chid) -{ - static union { char c[5]; int i; } chidtext; - - chidtext.i = BigLong(chid); - - return chidtext.c; -} -#endif - static const char *GetString_FailedToOpenSaveGame(const char *psFilename, qboolean bOpen) { static char sTemp[256]; @@ -123,34 +104,6 @@ static const char *GetString_FailedToOpenSaveGame(const char *psFilename, qboole return sTemp; } -#if 0 -// (copes with up to 8 ptr returns at once) -// -static const char *SG_AddSavePath( const char *psPathlessBaseName ) -{ - static char sSaveName[8][MAX_OSPATH]; - static int i=0; - - int next = i = (i + 1) & 7; - i = next; - - if(psPathlessBaseName) - { - char *p = const_cast<char*>(strchr(psPathlessBaseName,'/')); - if (p) - { - while (p) - { - *p = '_'; - p = strchr(p,'/'); - } - } - } - Com_sprintf( sSaveName[i], MAX_OSPATH, "saves/%s.sav", psPathlessBaseName ); - return sSaveName[i]; -} -#endif - void SG_WipeSavegame( const char* psPathlessBaseName) { @@ -158,74 +111,9 @@ void SG_WipeSavegame( psPathlessBaseName); } -#if 0 -static qboolean SG_Move( const char *psPathlessBaseName_Src, const char *psPathlessBaseName_Dst ) -{ - const char *psLocalFilename_Src = SG_AddSavePath( psPathlessBaseName_Src ); - const char *psLocalFilename_Dst = SG_AddSavePath( psPathlessBaseName_Dst ); - - qboolean qbCopyWentOk = FS_MoveUserGenFile( psLocalFilename_Src, psLocalFilename_Dst ); - - if (!qbCopyWentOk) - { - Com_Printf(S_COLOR_RED "Error during savegame-rename. Check \"%s\" for write-protect or disk full!\n", psLocalFilename_Dst ); - return qfalse; - } - - return qtrue; -} -#endif - -#if 0 -qboolean gbSGWriteFailed = qfalse; - -static qboolean SG_Create( const char *psPathlessBaseName ) -{ - gbSGWriteFailed = qfalse; - - SG_WipeSavegame( psPathlessBaseName ); - const char *psLocalFilename = SG_AddSavePath( psPathlessBaseName ); - fhSaveGame = FS_FOpenFileWrite( psLocalFilename ); - - if(!fhSaveGame) - { - Com_Printf(GetString_FailedToOpenSaveGame(psLocalFilename,qfalse));//S_COLOR_RED "Failed to create new savegame file \"%s\"\n", psLocalFilename ); - return qfalse; - } - - auto saved_game = &ojk::SavedGame::get_instance(); - - giSaveGameVersion = iSAVEGAME_VERSION; - - saved_game->write_chunk<int32_t>( - INT_ID('_','V','E','R'), - ::giSaveGameVersion); - - return qtrue; -} -#endif - // called from the ERR_DROP stuff just in case the error occured during loading of a saved game, because if // we didn't do this then we'd run out of quake file handles after the 8th load fail... // -#if 0 -void SG_Shutdown() -{ - if (fhSaveGame ) - { - FS_FCloseFile( fhSaveGame ); - fhSaveGame = NULL_FILE; - } - - eSavedGameJustLoaded = eNO; // important to do this if we ERR_DROP during loading, else next map you load after - // a bad save-file you'll arrive at dead :-) - - // and this bit stops people messing up the laoder by repeatedly stabbing at the load key during loads... - // - extern qboolean gbAlreadyDoingLoad; - gbAlreadyDoingLoad = qfalse; -} -#else void SG_Shutdown() { auto saved_game = &ojk::SavedGame::get_instance(); @@ -241,91 +129,6 @@ void SG_Shutdown() extern qboolean gbAlreadyDoingLoad; gbAlreadyDoingLoad = qfalse; } -#endif - -#if 0 -qboolean SG_Close() -{ - assert( fhSaveGame ); - FS_FCloseFile( fhSaveGame ); - fhSaveGame = NULL_FILE; - -#ifdef SG_PROFILE - if (!sv_testsave->integer) - { - CChidInfo_t::iterator it; - int iCount = 0, iSize = 0; - - Com_DPrintf(S_COLOR_CYAN "================================\n"); - Com_DPrintf(S_COLOR_WHITE "CHID Count Size\n\n"); - for(it = save_info.begin(); it != save_info.end(); ++it) - { - Com_DPrintf("%s %5d %8d\n", SG_GetChidText((*it).first), (*it).second.GetCount(), (*it).second.GetSize()); - iCount += (*it).second.GetCount(); - iSize += (*it).second.GetSize(); - } - Com_DPrintf("\n" S_COLOR_WHITE "%d chunks making %d bytes\n", iCount, iSize); - Com_DPrintf(S_COLOR_CYAN "================================\n"); - save_info.clear(); - } -#endif - - CompressMem_FreeScratchBuffer(); - return qtrue; -} -#endif - -#if 0 -qboolean SG_Open( const char *psPathlessBaseName ) -{ -// if ( fhSaveGame ) // hmmm... -// { // -// SG_Close(); // -// } // - assert( !fhSaveGame); // I'd rather know about this - if(!psPathlessBaseName) - { - return qfalse; - } -//JLFSAVEGAME - - const char *psLocalFilename = SG_AddSavePath( psPathlessBaseName ); - FS_FOpenFileRead( psLocalFilename, &fhSaveGame, qtrue ); //qtrue = dup handle, so I can close it ok later - if (!fhSaveGame) - { -// Com_Printf(S_COLOR_RED "Failed to open savegame file %s\n", psLocalFilename); - Com_DPrintf(GetString_FailedToOpenSaveGame(psLocalFilename, qtrue)); - - return qfalse; - } - giSaveGameVersion=-1;//jic - - auto saved_game = &ojk::SavedGame::get_instance(); - - saved_game->read_chunk<int32_t>( - INT_ID('_','V','E','R'), - ::giSaveGameVersion); - - if (giSaveGameVersion != iSAVEGAME_VERSION) - { - SG_Close(); - Com_Printf (S_COLOR_RED "File \"%s\" has version # %d (expecting %d)\n",psPathlessBaseName, giSaveGameVersion, iSAVEGAME_VERSION); - return qfalse; - } - - return qtrue; -} -#endif - -#if 0 -// you should only call this when you know you've successfully opened a savegame, and you want to query for -// whether it's an old (street-copy) version, or a new (expansion-pack) version -// -int SG_Version(void) -{ - return giSaveGameVersion; -} -#endif void SV_WipeGame_f(void) { @@ -1027,14 +830,14 @@ static qboolean SG_ReadScreenshot(qboolean qbSetAsLoadingScreen, void *pvDest) // // alloc enough space plus extra 4K for sloppy JPG-decode reader to not do memory access violation... // - byte *pJPGData = (byte *) Z_Malloc(iScreenShotLength + 4096,TAG_TEMP_WORKSPACE, qfalse); + byte *pJPGData = (byte *) Z_Malloc(static_cast<int>(iScreenShotLength + 4096),TAG_TEMP_WORKSPACE, qfalse); // // now read the JPG data... // saved_game->read_chunk( INT_ID('S','H','O','T'), pJPGData, - iScreenShotLength); + static_cast<int>(iScreenShotLength)); // // decompress JPG data... @@ -1140,7 +943,7 @@ static void SG_WriteScreenshot(qboolean qbAutosave, const char *psMapName) size_t iJPGDataSize = 0; size_t bufSize = SG_SCR_WIDTH * SG_SCR_HEIGHT * 3; - byte *pJPGData = (byte *)Z_Malloc( bufSize, TAG_TEMP_WORKSPACE, qfalse, 4 ); + byte *pJPGData = (byte *)Z_Malloc( static_cast<int>(bufSize), TAG_TEMP_WORKSPACE, qfalse, 4 ); iJPGDataSize = re.SaveJPGToBuffer(pJPGData, bufSize, JPEG_IMAGE_QUALITY, SG_SCR_WIDTH, SG_SCR_HEIGHT, pbRawScreenShot, 0 ); if ( qbAutosave ) delete[] byBlank; @@ -1403,477 +1206,9 @@ qboolean SG_ReadSavegame( ex.what()); } -#if 0 - if (!SG_Close()) - { - Com_Printf(GetString_FailedToOpenSaveGame(psPathlessBaseName, qfalse));//S_COLOR_RED "Failed to close savegame\n"); - sv_testsave->integer = iPrevTestSave; - return qfalse; - } -#endif - return true; } -#if 0 -int Compress_RLE(const byte *pIn, int iLength, byte *pOut) -{ - int iCount=0,iOutIndex=0; - - while (iCount < iLength) - { - int iIndex = iCount; - byte b = pIn[iIndex++]; - - while (iIndex<iLength && iIndex-iCount<127 && pIn[iIndex]==b) - { - iIndex++; - } - - if (iIndex-iCount == 1) - { - while (iIndex<iLength && iIndex-iCount<127 && (pIn[iIndex]!=pIn[iIndex-1] || (iIndex>1 && pIn[iIndex]!=pIn[iIndex-2]))){ - iIndex++; - } - while (iIndex<iLength && pIn[iIndex]==pIn[iIndex-1]){ - iIndex--; - } - pOut[iOutIndex++] = (unsigned char)(iCount-iIndex); - for (int i=iCount; i<iIndex; i++){ - pOut[iOutIndex++] = pIn[i]; - } - } - else - { - pOut[iOutIndex++] = (unsigned char)(iIndex-iCount); - pOut[iOutIndex++] = b; - } - iCount=iIndex; - } - return iOutIndex; -} -#endif - -#if 0 -void DeCompress_RLE(byte *pOut, const byte *pIn, int iDecompressedBytesRemaining) -{ - signed char count; - - while (iDecompressedBytesRemaining > 0) - { - count = (signed char) *pIn++; - if (count>0) - { - memset(pOut,*pIn++,count); - } - else - if (count<0) - { - count = (signed char) -count; - memcpy(pOut,pIn,count); - pIn += count; - } - pOut += count; - iDecompressedBytesRemaining -= count; - } -} -#endif - -#if 0 -// simulate decompression over original data (but don't actually do it), to test de/compress validity... -// -qboolean Verify_RLE(const byte *pOut, const byte *pIn, int iDecompressedBytesRemaining) -{ - signed char count; - const byte *pOutEnd = &pOut[iDecompressedBytesRemaining]; - - while (iDecompressedBytesRemaining > 0) - { - if (pOut >= pOutEnd) - return qfalse; - count = (signed char) *pIn++; - if (count>0) - { - //memset(pOut,*pIn++,count); - int iMemSetByte = *pIn++; - for (int i=0; i<count; i++) - { - if (pOut[i] != iMemSetByte) - return qfalse; - } - } - else - if (count<0) - { - count = (signed char) -count; -// memcpy(pOut,pIn,count); - if (memcmp(pOut,pIn,count)) - return qfalse; - pIn += count; - } - pOut += count; - iDecompressedBytesRemaining -= count; - } - - if (pOut != pOutEnd) - return qfalse; - - return qtrue; -} -#endif - -#if 0 -byte *gpbCompBlock = NULL; -int giCompBlockSize = 0; -static void CompressMem_FreeScratchBuffer(void) -{ - if ( gpbCompBlock ) - { - Z_Free( gpbCompBlock); - gpbCompBlock = NULL; - } - giCompBlockSize = 0; -} -#endif - -#if 0 -static byte *CompressMem_AllocScratchBuffer(int iSize) -{ - // only alloc new buffer if we need more than the existing one... - // - if (giCompBlockSize < iSize) - { - CompressMem_FreeScratchBuffer(); - - gpbCompBlock = (byte *) Z_Malloc(iSize, TAG_TEMP_WORKSPACE, qfalse); - giCompBlockSize = iSize; - } - - return gpbCompBlock; -} -#endif - -#if 0 -// returns -1 for compression-not-worth-it, else compressed length... -// -int CompressMem(byte *pbData, int iLength, byte *&pbOut) -{ - if (!sv_compress_saved_games->integer) - return -1; - - // malloc enough to cope with uncompressable data (it'll never grow to 2* size, so)... - // - pbOut = CompressMem_AllocScratchBuffer(iLength*2); - // - // compress it... - // - int iOutputLength = Compress_RLE(pbData, iLength, pbOut); - // - // worth compressing?... - // - if (iOutputLength >= iLength) - return -1; - // - // compression code works? (I'd hope this is always the case, but for safety)... - // - if (!Verify_RLE(pbData, pbOut, iLength)) - return -1; - - return iOutputLength; -} -#endif - -#if 0 -//pass through function -int SG_Write(const void * chid, const int bytesize, fileHandle_t fhSaveGame) -{ - return FS_Write( chid, bytesize, fhSaveGame); -} -#endif - -#if 0 -qboolean SG_Append(unsigned int chid, const void *pvData, int iLength) -{ - unsigned int uiCksum; - unsigned int uiSaved; - -#ifdef _DEBUG - int i; - unsigned int *pTest; - - pTest = (unsigned int *) pvData; - for (i=0; i<iLength/4; i++, pTest++) - { - assert(*pTest != 0xfeeefeee); - assert(*pTest != 0xcdcdcdcd); - assert(*pTest != 0xdddddddd); - } -#endif - - Com_DPrintf("Attempting write of chunk %s length %d\n", SG_GetChidText(chid), iLength); - - // only write data out if we're not in test mode.... - // - if (!sv_testsave->integer) - { - uiCksum = Com_BlockChecksum (pvData, iLength); - - uiSaved = SG_Write(&chid, sizeof(chid), fhSaveGame); - - byte *pbCompressedData = NULL; - int iCompressedLength = CompressMem((byte*)pvData, iLength, pbCompressedData); - if (iCompressedLength != -1) - { - // compressed... (write length field out as -ve) - // - iLength = -iLength; - uiSaved += SG_Write(&iLength, sizeof(iLength), fhSaveGame); - iLength = -iLength; - // - // [compressed length] - // - uiSaved += SG_Write(&iCompressedLength, sizeof(iCompressedLength), fhSaveGame); - // - // compressed data... - // - uiSaved += SG_Write(pbCompressedData, iCompressedLength, fhSaveGame); - // - // CRC... - // - uiSaved += SG_Write(&uiCksum, sizeof(uiCksum), fhSaveGame); - - if (uiSaved != sizeof(chid) + sizeof(iLength) + sizeof(uiCksum) + sizeof(iCompressedLength) + iCompressedLength) - { - Com_Printf(S_COLOR_RED "Failed to write %s chunk\n", SG_GetChidText(chid)); - gbSGWriteFailed = qtrue; - return qfalse; - } - } - else - { - // uncompressed... - // - uiSaved += SG_Write(&iLength, sizeof(iLength), fhSaveGame); - // - // uncompressed data... - // - uiSaved += SG_Write( pvData, iLength, fhSaveGame); - // - // CRC... - // - uiSaved += SG_Write(&uiCksum, sizeof(uiCksum), fhSaveGame); - - if (uiSaved != sizeof(chid) + sizeof(iLength) + sizeof(uiCksum) + iLength) - { - Com_Printf(S_COLOR_RED "Failed to write %s chunk\n", SG_GetChidText(chid)); - gbSGWriteFailed = qtrue; - return qfalse; - } - } - - #ifdef SG_PROFILE - save_info[chid].Add(iLength); - #endif - } - - return qtrue; -} -#endif - -#if 0 -//pass through function -int SG_ReadBytes(void * chid, int bytesize, fileHandle_t fhSaveGame) -{ - return FS_Read( chid, bytesize, fhSaveGame); -} -#endif - -#if 0 -int SG_Seek( fileHandle_t fhSaveGame, long offset, int origin ) -{ - return FS_Seek(fhSaveGame, offset, origin); -} -#endif - -#if 0 -// Pass in pvAddress (or NULL if you want memory to be allocated) -// if pvAddress==NULL && ppvAddressPtr == NULL then the block is discarded/skipped. -// -// If iLength==0 then it counts as a query, else it must match the size found in the file -// -// function doesn't return if error (uses ERR_DROP), unless "qbSGReadIsTestOnly == qtrue", then NZ return = success -// -static int SG_Read_Actual(unsigned int chid, void *pvAddress, int iLength, void **ppvAddressPtr, qboolean bChunkIsOptional) -{ - unsigned int uiLoadedCksum, uiCksum; - unsigned int uiLoadedLength; - unsigned int ulLoadedChid; - unsigned int uiLoaded; - char sChidText1[MAX_QPATH]; - char sChidText2[MAX_QPATH]; - qboolean qbTransient = qfalse; - - Com_DPrintf("Attempting read of chunk %s length %d\n", SG_GetChidText(chid), iLength); - - // Load in chid and length... - // - uiLoaded = SG_ReadBytes( &ulLoadedChid, sizeof(ulLoadedChid), fhSaveGame); - uiLoaded+= SG_ReadBytes( &uiLoadedLength, sizeof(uiLoadedLength),fhSaveGame); - - qboolean bBlockIsCompressed = ((int)uiLoadedLength < 0); - if ( bBlockIsCompressed) - { - uiLoadedLength = -((int)uiLoadedLength); - } - - // Make sure we are loading the correct chunk... - // - if( ulLoadedChid != chid) - { - if (bChunkIsOptional) - { - SG_Seek( fhSaveGame, -(int)uiLoaded, FS_SEEK_CUR ); - return 0; - } - - strcpy(sChidText1, SG_GetChidText(ulLoadedChid)); - strcpy(sChidText2, SG_GetChidText(chid)); - if (!qbSGReadIsTestOnly) - { - Com_Error(ERR_DROP, "Loaded chunk ID (%s) does not match requested chunk ID (%s)", sChidText1, sChidText2); - } - return 0; - } - - // Find length of chunk and make sure it matches the requested length... - // - if( iLength ) // .. but only if there was one specified - { - if(iLength != (int)uiLoadedLength) - { - if (!qbSGReadIsTestOnly) - { - Com_Error(ERR_DROP, "Loaded chunk (%s) has different length than requested", SG_GetChidText(chid)); - } - return 0; - } - } - iLength = uiLoadedLength; // for retval - - // alloc?... - // - if ( !pvAddress ) - { - pvAddress = Z_Malloc(iLength, TAG_SAVEGAME, qfalse); - // - // Pass load address back... - // - if( ppvAddressPtr ) - { - *ppvAddressPtr = pvAddress; - } - else - { - qbTransient = qtrue; // if no passback addr, mark block for skipping - } - } - - // Load in data and magic number... - // - unsigned int uiCompressedLength=0; - if (bBlockIsCompressed) - { - // - // read compressed data length... - // - uiLoaded += SG_ReadBytes( &uiCompressedLength, sizeof(uiCompressedLength),fhSaveGame); - // - // alloc space... - // - byte *pTempRLEData = (byte *)Z_Malloc(uiCompressedLength, TAG_SAVEGAME, qfalse); - // - // read compressed data... - // - uiLoaded += SG_ReadBytes( pTempRLEData, uiCompressedLength, fhSaveGame ); - // - // decompress it... - // - DeCompress_RLE((byte *)pvAddress, pTempRLEData, iLength); - // - // free workspace... - // - Z_Free( pTempRLEData ); - } - else - { - uiLoaded += SG_ReadBytes( pvAddress, iLength, fhSaveGame ); - } - // Get checksum... - // - uiLoaded += SG_ReadBytes( &uiLoadedCksum, sizeof(uiLoadedCksum), fhSaveGame ); - - // Make sure the checksums match... - // - uiCksum = Com_BlockChecksum( pvAddress, iLength ); - if ( uiLoadedCksum != uiCksum) - { - if (!qbSGReadIsTestOnly) - { - Com_Error(ERR_DROP, "Failed checksum check for chunk", SG_GetChidText(chid)); - } - else - { - if ( qbTransient ) - { - Z_Free( pvAddress ); - } - } - return 0; - } - - // Make sure we didn't encounter any read errors... - //size_t - if ( uiLoaded != sizeof(ulLoadedChid) + sizeof(uiLoadedLength) + sizeof(uiLoadedCksum) + (bBlockIsCompressed?sizeof(uiCompressedLength):0) + (bBlockIsCompressed?uiCompressedLength:iLength)) - { - if (!qbSGReadIsTestOnly) - { - Com_Error(ERR_DROP, "Error during loading chunk %s", SG_GetChidText(chid)); - } - else - { - if ( qbTransient ) - { - Z_Free( pvAddress ); - } - } - return 0; - } - - // If we are skipping the chunk, then free the memory... - // - if ( qbTransient ) - { - Z_Free( pvAddress ); - } - - return iLength; -} -#endif - -#if 0 -int SG_Read(unsigned int chid, void *pvAddress, int iLength, void **ppvAddressPtr /* = NULL */) -{ - return SG_Read_Actual(chid, pvAddress, iLength, ppvAddressPtr, qfalse ); // qboolean bChunkIsOptional -} -#endif - -#if 0 -int SG_ReadOptional(unsigned int chid, void *pvAddress, int iLength, void **ppvAddressPtr /* = NULL */) -{ - return SG_Read_Actual(chid, pvAddress, iLength, ppvAddressPtr, qtrue); // qboolean bChunkIsOptional -} -#endif - void SG_TestSave(void) { if (sv_testsave->integer && sv.state == SS_GAME) @@ -1882,6 +1217,3 @@ void SG_TestSave(void) ge->WriteLevel(false); } } - -////////////////// eof //////////////////// - diff --git a/codeJK2/game/g_savegame.cpp b/codeJK2/game/g_savegame.cpp index 530ab2a..34b6279 100644 --- a/codeJK2/game/g_savegame.cpp +++ b/codeJK2/game/g_savegame.cpp @@ -449,18 +449,18 @@ template<typename T> static void EnumerateFields( const field_t* pFields, T* src_instance, - unsigned int ulChid, - size_t iLen) + unsigned int ulChid) { strList.clear(); - auto pbData = reinterpret_cast<byte*>(src_instance); + auto pbData = reinterpret_cast<byte*>( + src_instance); // enumerate all the fields... // if (pFields) { for (auto pField = pFields; pField->psName; ++pField) { - assert(pField->iOffset < iLen); + assert(pField->iOffset < sizeof(T)); ::EnumerateField(pField, pbData); } } @@ -585,61 +585,12 @@ static const char *SG_GetChidText(unsigned int chid) return chidtext; } -#if 0 -template<typename T> -static void EvaluateFields(const field_t *pFields, T* pbData, T* pbOriginalRefData, unsigned int ulChid, int iSize, qboolean bOkToSizeMisMatch) -{ - using SgType = typename T::SgType; - - iSize = static_cast<int>(sizeof(SgType)); - - auto& sg_buffer = ::sg_get_buffer(iSize); - - auto sg_object = reinterpret_cast<SgType*>(sg_buffer.data()); - - int iReadSize = ::gi.ReadFromSaveGame(ulChid, sg_object, bOkToSizeMisMatch?0:iSize, NULL); - - if (iReadSize != iSize) - { - // handle any chunks that are ok to change length (typically this is a last minute hack, - // so hopefully we won't need it any more... ;-) - // - switch (ulChid) - { - // example chunk handler... - // - case INT_ID('G','C','L','I'): -/* assert(iSize>iReadSize); - memset(&pbData[iReadSize], 0, iSize-iReadSize); // zero out new objectives that weren't in old-format save file - break; -*/ - default: - // won't return... - // - G_Error(va("EvaluateFields(): variable-sized chunk '%s' without handler!",SG_GetChidText(ulChid))); - break; - } - } - - ::sg_import(*sg_object, *pbData); - - if (pFields) - { - for (const field_t *pField = pFields; pField->psName; pField++) - { - EvaluateField(pField, reinterpret_cast<byte*>(pbData), reinterpret_cast<byte*>(pbOriginalRefData)); - } - } -} -#else template<typename T> static void EvaluateFields( const field_t* pFields, T* pbData, T* pbOriginalRefData, - unsigned int ulChid, - int iSize, - qboolean bOkToSizeMisMatch) + unsigned int ulChid) { ::gi.saved_game->read_chunk( ulChid); @@ -663,7 +614,6 @@ static void EvaluateFields( } } } -#endif /* ============== @@ -677,7 +627,7 @@ 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'), LLOFS(LEVEL_LOCALS_T_SAVESTOP)); + EnumerateFields(savefields_LevelLocals, temp, INT_ID('L','V','L','C')); gi.Free(temp); } @@ -696,7 +646,7 @@ static void ReadLevelLocals () level_locals_t *temp = (level_locals_t *)gi.Malloc(sizeof(level_locals_t), TAG_TEMP_WORKSPACE, qfalse); *temp = level; - EvaluateFields(savefields_LevelLocals, temp, &level, INT_ID('L','V','L','C'), LLOFS(LEVEL_LOCALS_T_SAVESTOP),qfalse); // sizeof(level_locals_t)); + EvaluateFields(savefields_LevelLocals, temp, &level, INT_ID('L','V','L','C')); level = *temp; // struct copy level.clients = pClients; // restore clients @@ -742,7 +692,7 @@ static void WriteGEntities(qboolean qbAutosave) gi.linkentity( ent ); } - EnumerateFields(savefields_gEntity, &tempEnt, INT_ID('G','E','N','T'), sizeof(tempEnt)); + 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... // @@ -750,13 +700,13 @@ static void WriteGEntities(qboolean qbAutosave) { gNPC_t npc = *ent->NPC; // NOT *tempEnt.NPC; !! :-) - EnumerateFields(savefields_gNPC, &npc, INT_ID('G','N','P','C'), sizeof(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'), sizeof(client)); + EnumerateFields(savefields_gClient, &client, INT_ID('G','C','L','I')); } if (tempEnt.parms) @@ -847,7 +797,7 @@ static void ReadGEntities(qboolean qbAutosave) // gi.G2API_LoadSaveCodeDestructGhoul2Info(pEnt->ghoul2); pEnt->ghoul2.kill(); - EvaluateFields(savefields_gEntity, pEnt, pEntOriginal, INT_ID('G','E','N','T'), sizeof(*pEnt),qfalse); + EvaluateFields(savefields_gEntity, pEnt, pEntOriginal, INT_ID('G','E','N','T')); pEnt->ghoul2.kill(); // now for any fiddly bits... @@ -856,7 +806,7 @@ static void ReadGEntities(qboolean qbAutosave) { gNPC_t tempNPC; - EvaluateFields(savefields_gNPC, &tempNPC,pEntOriginal->NPC, INT_ID('G','N','P','C'), sizeof (*pEnt->NPC),qfalse); + EvaluateFields(savefields_gNPC, &tempNPC,pEntOriginal->NPC, INT_ID('G','N','P','C')); // so can we pinch the original's one or do we have to alloc a new one?... // @@ -884,7 +834,7 @@ static void ReadGEntities(qboolean qbAutosave) { gclient_t tempGClient; - EvaluateFields(savefields_gClient, &tempGClient, pEntOriginal->client, INT_ID('G','C','L','I'), sizeof(*pEnt->client),qfalse); + EvaluateFields(savefields_gClient, &tempGClient, pEntOriginal->client, INT_ID('G','C','L','I')); // can we pinch the original's client handle or do we have to alloc a new one?... // @@ -942,14 +892,6 @@ static void ReadGEntities(qboolean qbAutosave) ::gi.saved_game->read_chunk( INT_ID('G','H','L','2')); -// FIXME Remove -#if 0 - auto buffer = ::gi.saved_game->get_buffer(); - auto pGhoul2Data = reinterpret_cast<char*>(buffer.data()); - - gi.G2API_LoadGhoul2Models(pEnt->ghoul2, pGhoul2Data); // if it's going to crash anywhere... <g> -#endif - gi.G2API_LoadGhoul2Models(pEnt->ghoul2, nullptr); } @@ -1029,7 +971,7 @@ void WriteLevel(qboolean qbAutosave) // 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'), sizeof(client)); + EnumerateFields(savefields_gClient, &client, INT_ID('G','C','L','I')); WriteLevelLocals(); // level_locals_t level } @@ -1071,7 +1013,7 @@ void ReadLevel(qboolean qbAutosave, qboolean qbLoadTransition) //Read & throw away gclient info gclient_t junkClient; - EvaluateFields(savefields_gClient, &junkClient, &level.clients[0], INT_ID('G','C','L','I'), sizeof(*level.clients), qfalse); + EvaluateFields(savefields_gClient, &junkClient, &level.clients[0], INT_ID('G','C','L','I')); //Read & throw away objective info ::gi.saved_game->read_chunk( @@ -1086,7 +1028,7 @@ void ReadLevel(qboolean qbAutosave, qboolean qbLoadTransition) assert(level.maxclients == 1); // I'll need to know if this changes, otherwise I'll need to change the way things work gclient_t GClient; - EvaluateFields(savefields_gClient, &GClient, &level.clients[0], INT_ID('G','C','L','I'), sizeof(*level.clients), qfalse); + EvaluateFields(savefields_gClient, &GClient, &level.clients[0], INT_ID('G','C','L','I')); level.clients[0] = GClient; // struct copy ReadLevelLocals(); // level_locals_t level } -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/openjk.git _______________________________________________ Pkg-games-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits

