From 296bacb4a00db8ceec148589ee5727772ebbef5b Mon Sep 17 00:00:00 2001 From: danij Date: Wed, 29 Jan 2014 12:53:20 +0000 Subject: [PATCH 001/106] API|Uri: Added new Uri constructor Uri_NewWithPath3 A default scheme is set for the new Uri before then parsing a cstring representation of a Uri, bypassing the resource class mechanism. This provides a convenient method of constructing a Uri with a default scheme that may be overridden with the cstring argument. --- doomsday/api/api_uri.h | 7 +++++-- doomsday/api/apis.h | 3 ++- doomsday/client/src/api_uri.cpp | 9 +++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/doomsday/api/api_uri.h b/doomsday/api/api_uri.h index 2bde82f59d..7b42c149f3 100644 --- a/doomsday/api/api_uri.h +++ b/doomsday/api/api_uri.h @@ -84,6 +84,8 @@ DENG_API_TYPEDEF(Uri) // v1 */ Uri* (*New)(void); + Uri* (*NewWithPath3)(char const *defaultScheme, char const *path); + /** * Constructs a Uri instance from @a path. The uri should be destroyed with * Uri_Delete() once it is no longer needed. @@ -92,9 +94,9 @@ DENG_API_TYPEDEF(Uri) // v1 * @param defaultResourceClass If no scheme is defined in @a path and this is not @c FC_NULL, * look for an appropriate default scheme for this class of resource. */ - Uri* (*NewWithPath2)(char const* path, resourceclassid_t defaultResourceClass); + Uri* (*NewWithPath2)(char const *path, resourceclassid_t defaultResourceClass); - Uri* (*NewWithPath)(char const* path); + Uri* (*NewWithPath)(char const *path); /** * Constructs a Uri instance by duplicating @a other. The uri should be destroyed @@ -259,6 +261,7 @@ DENG_API_TYPEDEF(Uri) // v1 // Macros for accessing exported functions. #ifndef DENG_NO_API_MACROS_URI #define Uri_New _api_Uri.New +#define Uri_NewWithPath3 _api_Uri.NewWithPath3 #define Uri_NewWithPath2 _api_Uri.NewWithPath2 #define Uri_NewWithPath _api_Uri.NewWithPath #define Uri_Dup _api_Uri.Dup diff --git a/doomsday/api/apis.h b/doomsday/api/apis.h index f71067324e..a0bff85b7e 100644 --- a/doomsday/api/apis.h +++ b/doomsday/api/apis.h @@ -137,7 +137,8 @@ enum { DE_API_THINKER = DE_API_THINKER_v1, DE_API_URI_v1 = 2300, // 1.10 - DE_API_URI = DE_API_URI_v1, + DE_API_URI_v2 = 2301, // 1.14 + DE_API_URI = DE_API_URI_v2, DE_API_WAD_v1 = 2400, // 1.10 DE_API_WAD_v2 = 2401, // 1.14 diff --git a/doomsday/client/src/api_uri.cpp b/doomsday/client/src/api_uri.cpp index a7ff900023..2fd99ed0ae 100644 --- a/doomsday/client/src/api_uri.cpp +++ b/doomsday/client/src/api_uri.cpp @@ -97,6 +97,14 @@ static void readUri(Uri* uri, Reader* reader, de::String defaultScheme = "") Uri_SetPath (uri, Str_Text(&path )); } +#undef Uri_NewWithPath3 +Uri* Uri_NewWithPath3(char const *defaultScheme, char const *path) +{ + de::Uri *uri = new de::Uri(defaultScheme); + uri->setUri(path, RC_NULL); + return reinterpret_cast(uri); +} + #undef Uri_NewWithPath2 Uri* Uri_NewWithPath2(char const* path, resourceclassid_t defaultResourceClass) { @@ -286,6 +294,7 @@ DENG_DECLARE_API(Uri) = { { DE_API_URI }, Uri_New, + Uri_NewWithPath3, Uri_NewWithPath2, Uri_NewWithPath, Uri_Dup, From cefbff4e761c952ad61d39077e9b5da89c3ca93b Mon Sep 17 00:00:00 2001 From: danij Date: Wed, 29 Jan 2014 12:59:49 +0000 Subject: [PATCH 002/106] ACS|Cleanup: Use Uri_NewWithPath3 --- doomsday/plugins/hexen/src/acscript.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index 4f3774cea3..d029b28746 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -83,7 +83,7 @@ struct BytecodeScriptInfo int argCount; // Current state: - /// @todo Move to a separate array, in Interpreter + /// @todo Move to a separate array, in ACScriptInterpreter ACScriptState state; int waitValue; }; @@ -1142,8 +1142,8 @@ ACS_COMMAND(PolyWaitDirect) ACS_COMMAND(ChangeFloor) { - Uri *uri = Uri_NewWithPath2("Flats:", RC_NULL); - Uri_SetPath(uri, Str_Text(Str_PercentEncode(Str_Copy(AutoStr_New(), S_INTERPRETER().string(S_POP()))))); + AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), S_INTERPRETER().string(S_POP()))); + Uri *uri = Uri_NewWithPath3("Flats", Str_Text(path)); Material *mat = (Material *) P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); Uri_Delete(uri); @@ -1169,8 +1169,8 @@ ACS_COMMAND(ChangeFloorDirect) { int tag = LONG(*S_PCODEPTR++); - Uri *uri = Uri_NewWithPath2("Flats:", RC_NULL); - Uri_SetPath(uri, Str_Text(Str_PercentEncode(Str_Copy(AutoStr_New(), S_INTERPRETER().string(LONG(*S_PCODEPTR++)))))); + AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), S_INTERPRETER().string(LONG(*S_PCODEPTR++)))); + Uri *uri = Uri_NewWithPath3("Flats", Str_Text(path)); Material *mat = (Material *) P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); Uri_Delete(uri); @@ -1192,8 +1192,8 @@ ACS_COMMAND(ChangeFloorDirect) ACS_COMMAND(ChangeCeiling) { - Uri *uri = Uri_NewWithPath2("Flats:", RC_NULL); - Uri_SetPath(uri, Str_Text(Str_PercentEncode(Str_Copy(AutoStr_New(), S_INTERPRETER().string(S_POP()))))); + AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), S_INTERPRETER().string(S_POP()))); + Uri *uri = Uri_NewWithPath3("Flats", Str_Text(path)); Material *mat = (Material *) P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); Uri_Delete(uri); @@ -1219,8 +1219,8 @@ ACS_COMMAND(ChangeCeilingDirect) { int tag = LONG(*S_PCODEPTR++); - Uri *uri = Uri_NewWithPath2("Flats:", RC_NULL); - Uri_SetPath(uri, Str_Text(Str_PercentEncode(Str_Copy(AutoStr_New(), S_INTERPRETER().string(LONG(*S_PCODEPTR++)))))); + AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), S_INTERPRETER().string(LONG(*S_PCODEPTR++)))); + Uri *uri = Uri_NewWithPath3("Flats", Str_Text(path)); Material *mat = (Material *) P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); Uri_Delete(uri); @@ -1540,8 +1540,8 @@ ACS_COMMAND(SetLineTexture) #define TEXTURE_MIDDLE 1 #define TEXTURE_BOTTOM 2 - Uri *uri = Uri_NewWithPath2("Textures:", RC_NULL); - Uri_SetPath(uri, Str_Text(Str_PercentEncode(Str_Copy(AutoStr_New(), S_INTERPRETER().string(S_POP()))))); + AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), S_INTERPRETER().string(S_POP()))); + Uri *uri = Uri_NewWithPath3("Textures", Str_Text(path)); Material *mat = (Material *) P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); Uri_Delete(uri); From 28a20547ed6b23de618af4cbee2ecf6546f6514d Mon Sep 17 00:00:00 2001 From: danij Date: Wed, 29 Jan 2014 13:07:21 +0000 Subject: [PATCH 003/106] libcommon: Provide a Reader/Writer to all save state (de)serialization routines --- doomsday/plugins/common/include/p_saveg.h | 4 +- doomsday/plugins/common/src/p_saveg.cpp | 163 +++++++++++--------- doomsday/plugins/hexen/include/s_sequence.h | 4 +- doomsday/plugins/hexen/src/acscript.cpp | 26 ++-- doomsday/plugins/hexen/src/sn_sonix.cpp | 4 +- 5 files changed, 111 insertions(+), 90 deletions(-) diff --git a/doomsday/plugins/common/include/p_saveg.h b/doomsday/plugins/common/include/p_saveg.h index 78f490d013..e4f3bf4a8f 100644 --- a/doomsday/plugins/common/include/p_saveg.h +++ b/doomsday/plugins/common/include/p_saveg.h @@ -67,8 +67,8 @@ typedef enum thinkclass_e { extern "C" { #endif -typedef void (*WriteThinkerFunc)(thinker_t *); -typedef int (*ReadThinkerFunc)(thinker_t *, int mapVersion); +typedef void (*WriteThinkerFunc)(thinker_t *, Writer *writer); +typedef int (*ReadThinkerFunc)(thinker_t *, Reader *reader, int mapVersion); /// Register the console commands and variables of this module. void SV_Register(void); diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index 2251356a4e..fad5c83887 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -166,9 +166,9 @@ static void SV_WriteScroll(scroll_t const *scroll); static int SV_ReadScroll(scroll_t *scroll, int mapVersion); #if __JHEXEN__ -static void readMapState(Str const *path); +static void readMapState(Reader *reader, Str const *path); #else -static void readMapState(); +static void readMapState(Reader *reader); #endif static bool inited = false; @@ -667,26 +667,24 @@ dd_bool SV_IsUserWritableSlot(int slot) return SV_IsValidSlot(slot); } -static void SV_SaveInfo_Read(SaveInfo *info) +static void SV_SaveInfo_Read(SaveInfo *info, Reader *reader) { - Reader *svReader = SV_NewReader(); #if __JHEXEN__ // Read the magic byte to determine the high-level format. - int magic = Reader_ReadInt32(svReader); + int magic = Reader_ReadInt32(reader); SV_HxSavePtr()->b -= 4; // Rewind the stream. if((!IS_NETWORK_CLIENT && magic != MY_SAVE_MAGIC) || ( IS_NETWORK_CLIENT && magic != MY_CLIENT_SAVE_MAGIC)) { // Perhaps the old v9 format? - SaveInfo_Read_Hx_v9(info, svReader); + SaveInfo_Read_Hx_v9(info, reader); } else #endif { - SaveInfo_Read(info, svReader); + SaveInfo_Read(info, reader); } - Reader_Delete(svReader); } static bool recogniseNativeState(Str const *path, SaveInfo *info) @@ -708,7 +706,9 @@ static bool recogniseNativeState(Str const *path, SaveInfo *info) return false; #endif - SV_SaveInfo_Read(info); + Reader *reader = SV_NewReader(); + SV_SaveInfo_Read(info, reader); + Reader_Delete(reader); #if __JHEXEN__ Z_Free(saveBuffer); @@ -2899,39 +2899,45 @@ static int SV_ReadPolyObj() } #endif -static void writeMapElements() +static void writeMapElements(Writer *writer) { - Writer *svWriter = SV_NewWriter(); - MaterialArchive_Write(materialArchive, svWriter); - Writer_Delete(svWriter); - SV_BeginSegment(ASEG_MAP_ELEMENTS); for(int i = 0; i < numsectors; ++i) + { SV_WriteSector((Sector *)P_ToPtr(DMU_SECTOR, i)); + } for(int i = 0; i < numlines; ++i) + { SV_WriteLine((Line *)P_ToPtr(DMU_LINE, i)); + } #if __JHEXEN__ SV_BeginSegment(ASEG_POLYOBJS); SV_WriteLong(numpolyobjs); for(int i = 0; i < numpolyobjs; ++i) + { SV_WritePolyObj(Polyobj_ById(i)); + } #endif } -static void readMapElements() +static void readMapElements(Reader *reader) { SV_AssertSegment(ASEG_MAP_ELEMENTS); // Load sectors. for(int i = 0; i < numsectors; ++i) + { SV_ReadSector((Sector *)P_ToPtr(DMU_SECTOR, i)); + } // Load lines. for(int i = 0; i < numlines; ++i) + { SV_ReadLine((Line *)P_ToPtr(DMU_LINE, i)); + } #if __JHEXEN__ // Load polyobjects. @@ -2940,7 +2946,9 @@ static void readMapElements() long const writtenPolyobjCount = SV_ReadLong(); DENG_ASSERT(writtenPolyobjCount == numpolyobjs); for(int i = 0; i < writtenPolyobjCount; ++i) + { SV_ReadPolyObj(); + } #endif } @@ -4169,8 +4177,8 @@ static int SV_ReadScroll(scroll_t *scroll, int /*mapVersion*/) */ static int writeThinker(thinker_t *th, void *context) { - DENG_ASSERT(th != 0); - DENG_UNUSED(context); + DENG_ASSERT(th != 0 && context != 0); + Writer *writer = (Writer *) context; // We are only concerned with thinkers we have save info for. ThinkerClassInfo *thInfo = infoForThinker(*th); @@ -4192,7 +4200,7 @@ static int writeThinker(thinker_t *th, void *context) SV_WriteByte(th->inStasis? 1 : 0); // In stasis? // Write the thinker data. - thInfo->writeFunc(th); + thInfo->writeFunc(th, writer); return false; // Continue iteration. } @@ -4205,7 +4213,7 @@ static int writeThinker(thinker_t *th, void *context) * * @note Some thinker classes are NEVER saved by clients. */ -static void writeThinkers() +static void writeThinkers(Writer *writer) { SV_BeginSegment(ASEG_THINKERS); { @@ -4214,7 +4222,7 @@ static void writeThinkers() #endif // Serialize qualifying thinkers. - Thinker_Iterate(0/*all thinkers*/, writeThinker, 0/*no parameters*/); + Thinker_Iterate(0/*all thinkers*/, writeThinker, writer); } SV_WriteByte(TC_END); } @@ -4406,7 +4414,7 @@ static void relinkThinkers() /** * Deserializes and then spawns thinkers for both client and server. */ -static void readThinkers() +static void readThinkers(Reader *reader) { #if __JHEXEN__ int const arcMapVersion = mapVersion; @@ -4516,7 +4524,7 @@ static void readThinkers() bool putThinkerInStasis = (formatHasStasisInfo? CPP_BOOL(SV_ReadByte()) : false); - if(thInfo->readFunc(th, arcMapVersion)) + if(thInfo->readFunc(th, reader, arcMapVersion)) { Thinker_Add(th); } @@ -4536,7 +4544,7 @@ static void readThinkers() relinkThinkers(); } -static void writeBrain() +static void writeBrain(Writer *writer) { #if __JDOOM__ // Not for us? @@ -4550,11 +4558,13 @@ static void writeBrain() // Write the mobj references using the mobj archive. for(int i = 0; i < brain.numTargets; ++i) + { SV_WriteShort(SV_ThingArchiveId(brain.targets[i])); + } #endif } -static void readBrain() +static void readBrain(Reader *reader) { #if __JDOOM__ // Not for us? @@ -4587,7 +4597,7 @@ static void readBrain() #endif } -static void writeSoundTargets() +static void writeSoundTargets(Writer *writer) { #if !__JHEXEN__ // Not for us? @@ -4610,7 +4620,7 @@ static void writeSoundTargets() #endif } -static void readSoundTargets() +static void readSoundTargets(Reader *reader) { #if !__JHEXEN__ // Not for us? @@ -4640,7 +4650,7 @@ static void readSoundTargets() #endif } -static void writeMisc() +static void writeMisc(Writer *writer) { #if __JHEXEN__ SV_BeginSegment(ASEG_MISC); @@ -4652,7 +4662,7 @@ static void writeMisc() #endif } -static void readMisc() +static void readMisc(Reader *reader) { #if __JHEXEN__ SV_AssertSegment(ASEG_MISC); @@ -4664,7 +4674,7 @@ static void readMisc() #endif } -static void writeMap() +static void writeMap(Writer *writer) { #if !__JHEXEN__ // Clear the sound target count (determined while saving sectors). @@ -4680,20 +4690,21 @@ static void writeMap() SV_WriteLong(mapTime); #endif - writeMapElements(); - writeThinkers(); + MaterialArchive_Write(materialArchive, writer); + writeMapElements(writer); + writeThinkers(writer); #if __JHEXEN__ - P_WriteMapACScriptData(); - SN_WriteSequences(); + P_WriteMapACScriptData(writer); + SN_WriteSequences(writer); #endif - writeMisc(); - writeBrain(); - writeSoundTargets(); + writeMisc(writer); + writeBrain(writer); + writeSoundTargets(writer); } SV_EndSegment(); } -static void readMap() +static void readMap(Reader *reader) { sideArchive = new SideArchive; @@ -4711,21 +4722,17 @@ static void readMap() #if !__JHEXEN__ if(hdr->version >= 4) #endif - { - Reader *svReader = SV_NewReader(); - MaterialArchive_Read(materialArchive, svReader, materialArchiveVersion()); - Reader_Delete(svReader); - } - readMapElements(); - readThinkers(); + MaterialArchive_Read(materialArchive, reader, materialArchiveVersion()); + readMapElements(reader); + readThinkers(reader); #if __JHEXEN__ - P_ReadMapACScriptData(); - SN_ReadSequences(mapVersion); + P_ReadMapACScriptData(reader); + SN_ReadSequences(reader, mapVersion); #endif - readMisc(); - readBrain(); - readSoundTargets(); + readMisc(reader); + readBrain(reader); + readSoundTargets(reader); } SV_AssertSegment(ASEG_END); @@ -4816,11 +4823,13 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) if(!openGameSaveFile(path, false)) return 1; // Failed? + Reader *reader = SV_NewReader(); + // Read the header again. /// @todo Seek past the header straight to the game state. { SaveInfo *tmp = SaveInfo_New(); - SV_SaveInfo_Read(tmp); + SV_SaveInfo_Read(tmp, reader); SaveInfo_Delete(tmp); } @@ -4848,7 +4857,7 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) #endif #if __JHEXEN__ - P_ReadGlobalACScriptData(hdr->version); + P_ReadGlobalACScriptData(reader, hdr->version); #endif /* @@ -4892,9 +4901,9 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) // Load the current map state. #if __JHEXEN__ - readMapState(composeGameSavePathForSlot2(BASE_SLOT, gameMap+1)); + readMapState(reader, composeGameSavePathForSlot2(BASE_SLOT, gameMap+1)); #else - readMapState(); + readMapState(reader); #endif #if !__JHEXEN__ @@ -4972,6 +4981,8 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) NetSv_LoadGame(SaveInfo_GameId(saveInfo)); #endif + Reader_Delete(reader); + return 0; } @@ -5102,11 +5113,8 @@ void SV_SaveGameClient(uint gameId) SaveInfo_SetGameId(saveInfo, gameId); SaveInfo_Configure(saveInfo); - { - Writer *svWriter = SV_NewWriter(); - SaveInfo_Write(saveInfo, svWriter); - Writer_Delete(svWriter); - } + Writer *writer = SV_NewWriter(); + SaveInfo_Write(saveInfo, writer); // Some important information. // Our position and look angles. @@ -5123,12 +5131,13 @@ void SV_SaveGameClient(uint gameId) // Create and populate the MaterialArchive. materialArchive = MaterialArchive_New(false); - writeMap(); + writeMap(writer); /// @todo No consistency bytes in client saves? clearMaterialArchive(); SV_CloseFile(); + Writer_Delete(writer); SaveInfo_Delete(saveInfo); #else DENG_UNUSED(gameId); @@ -5158,11 +5167,13 @@ void SV_LoadGameClient(uint gameId) } saveInfo = SaveInfo_New(); - SV_SaveInfo_Read(saveInfo); + Reader *reader = SV_NewReader(); + SV_SaveInfo_Read(saveInfo, reader); hdr = SaveInfo_Header(saveInfo); if(hdr->magic != MY_CLIENT_SAVE_MAGIC) { + Reader_Delete(reader); SaveInfo_Delete(saveInfo); SV_CloseFile(); App_Log(DE2_RES_ERROR, "Client save file format not recognized"); @@ -5206,11 +5217,12 @@ void SV_LoadGameClient(uint gameId) */ materialArchive = MaterialArchive_New(false); - readMap(); + readMap(reader); clearMaterialArchive(); SV_CloseFile(); + Reader_Delete(reader); SaveInfo_Delete(saveInfo); #else DENG_UNUSED(gameId); @@ -5218,9 +5230,9 @@ void SV_LoadGameClient(uint gameId) } #if __JHEXEN__ -static void readMapState(Str const *path) +static void readMapState(Reader *reader, Str const *path) #else -static void readMapState() +static void readMapState(Reader *reader) #endif { #if __JHEXEN__ @@ -5240,7 +5252,7 @@ static void readMapState() SV_HxSetSaveEndPtr(saveBuffer + bufferSize); #endif - readMap(); + readMap(reader); #if __JHEXEN__ clearThingArchive(); @@ -5267,12 +5279,11 @@ static int saveStateWorker(Str const *path, SaveInfo *saveInfo) /* * Write the game session header. */ - Writer *svWriter = SV_NewWriter(); - SaveInfo_Write(saveInfo, svWriter); - Writer_Delete(svWriter); svWriter = 0; + Writer *writer = SV_NewWriter(); + SaveInfo_Write(saveInfo, writer); #if __JHEXEN__ - P_WriteGlobalACScriptData(); + P_WriteGlobalACScriptData(writer); #endif // Set the mobj archive numbers. @@ -5305,7 +5316,7 @@ static int saveStateWorker(Str const *path, SaveInfo *saveInfo) SV_OpenFile(composeGameSavePathForSlot2(BASE_SLOT, gameMap+1), "wp"); #endif - writeMap(); + writeMap(writer); SV_WriteConsistencyBytes(); // To be absolutely sure... SV_CloseFile(); @@ -5315,6 +5326,8 @@ static int saveStateWorker(Str const *path, SaveInfo *saveInfo) clearThingArchive(); #endif + Writer_Delete(writer); + return SV_OK; } @@ -5400,15 +5413,19 @@ void SV_HxSaveClusterMap() // Set the mobj archive numbers initThingArchiveForSave(true /*exclude players*/); + Writer *writer = SV_NewWriter(); + // Create and populate the MaterialArchive. materialArchive = MaterialArchive_New(true); - writeMap(); + writeMap(writer); clearMaterialArchive(); // Close the output file SV_CloseFile(); + + Writer_Delete(writer); } void SV_HxLoadClusterMap() @@ -5422,10 +5439,14 @@ void SV_HxLoadClusterMap() // Create the MaterialArchive. materialArchive = MaterialArchive_NewEmpty(true); + Reader *reader = SV_NewReader(); + // Been here before, load the previous map state. - readMapState(composeGameSavePathForSlot2(BASE_SLOT, gameMap+1)); + readMapState(reader, composeGameSavePathForSlot2(BASE_SLOT, gameMap+1)); clearMaterialArchive(); + + Reader_Delete(reader); } void SV_HxBackupPlayersInCluster(playerbackup_t playerBackup[MAXPLAYERS]) diff --git a/doomsday/plugins/hexen/include/s_sequence.h b/doomsday/plugins/hexen/include/s_sequence.h index c5be2aca9b..39f5050b7e 100644 --- a/doomsday/plugins/hexen/include/s_sequence.h +++ b/doomsday/plugins/hexen/include/s_sequence.h @@ -91,8 +91,8 @@ int SN_GetSequenceOffset(int sequence, int *sequencePtr); */ void SN_ChangeNodeData(int nodeNum, int seqOffset, int delayTics, int volume, int currentSoundID); -void SN_WriteSequences(); -void SN_ReadSequences(int mapVersion); +void SN_WriteSequences(Writer *writer); +void SN_ReadSequences(Reader *reader, int mapVersion); #ifdef __cplusplus } // extern "C" diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index d029b28746..6e8b1774a7 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -470,7 +470,7 @@ void ACScriptInterpreter::scriptFinished(ACScript *script) Thinker_Remove(&script->thinker); } -void ACScriptInterpreter::writeWorldScriptData() +void ACScriptInterpreter::writeWorldScriptData(Writer *writer) { SV_BeginSegment(ASEG_GLOBALSCRIPTDATA); @@ -495,7 +495,7 @@ void ACScriptInterpreter::writeWorldScriptData() } } -void ACScriptInterpreter::readWorldScriptData(int saveVersion) +void ACScriptInterpreter::readWorldScriptData(Reader *reader, int saveVersion) { int ver = 1; @@ -575,7 +575,7 @@ void ACScriptInterpreter::readWorldScriptData(int saveVersion) } } -void ACScriptInterpreter::writeMapScriptData() +void ACScriptInterpreter::writeMapScriptData(Writer *writer) { SV_BeginSegment(ASEG_SCRIPTS); @@ -592,7 +592,7 @@ void ACScriptInterpreter::writeMapScriptData() } } -void ACScriptInterpreter::readMapScriptData() +void ACScriptInterpreter::readMapScriptData(Reader *reader) { SV_AssertSegment(ASEG_SCRIPTS); @@ -1634,7 +1634,7 @@ ACS_COMMAND(SetLineSpecial) return Continue; } -static CommandFunc PCodeCmds[] = +static CommandFunc pcodeCmds[] = { cmdNOP, cmdTerminate, cmdSuspend, cmdPushNumber, cmdLSpec1, cmdLSpec2, cmdLSpec3, cmdLSpec4, cmdLSpec5, cmdLSpec1Direct, cmdLSpec2Direct, @@ -1712,24 +1712,24 @@ void P_ACScriptPolyobjFinished(int tag) interp.polyobjFinished(tag); } -void P_WriteGlobalACScriptData() +void P_WriteGlobalACScriptData(Writer *writer) { - interp.writeWorldScriptData(); + interp.writeWorldScriptData(writer); } -void P_ReadGlobalACScriptData(int saveVersion) +void P_ReadGlobalACScriptData(Reader *reader, int saveVersion) { - interp.readWorldScriptData(saveVersion); + interp.readWorldScriptData(reader, saveVersion); } -void P_WriteMapACScriptData() +void P_WriteMapACScriptData(Writer *writer) { - interp.writeMapScriptData(); + interp.writeMapScriptData(writer); } -void P_ReadMapACScriptData() +void P_ReadMapACScriptData(Reader *reader) { - interp.readMapScriptData(); + interp.readMapScriptData(reader); } ACScriptInterpreter &ACScript::interpreter() const diff --git a/doomsday/plugins/hexen/src/sn_sonix.cpp b/doomsday/plugins/hexen/src/sn_sonix.cpp index 9fe9d09c3f..83f3f00359 100644 --- a/doomsday/plugins/hexen/src/sn_sonix.cpp +++ b/doomsday/plugins/hexen/src/sn_sonix.cpp @@ -490,7 +490,7 @@ void SN_ChangeNodeData(int nodeNum, int seqOffset, int delayTics, int volume, node->currentSoundID = currentSoundID; } -void SN_WriteSequences() +void SN_WriteSequences(Writer *writer) { SV_BeginSegment(ASEG_SOUNDS); @@ -534,7 +534,7 @@ void SN_WriteSequences() } } -void SN_ReadSequences(int mapVersion) +void SN_ReadSequences(Reader *reader, int mapVersion) { SV_AssertSegment(ASEG_SOUNDS); From 2b495a61870af16caeb44ead00a9749a43cc9b92 Mon Sep 17 00:00:00 2001 From: danij Date: Wed, 29 Jan 2014 13:11:53 +0000 Subject: [PATCH 004/106] Refactor|ACS: Implement ACScript (de)serialization in C++ with Reader/Writer Also, ACScript_Thinker() now calls the C++ method ACScript::runTick() --- doomsday/plugins/common/src/p_saveg.cpp | 22 ++- doomsday/plugins/hexen/include/acscript.h | 108 ++++++++------- doomsday/plugins/hexen/src/acscript.cpp | 155 +++++++++++----------- 3 files changed, 156 insertions(+), 129 deletions(-) diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index fad5c83887..0e55ef0cfb 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -53,7 +53,9 @@ #include "p_savedef.h" #include "dmu_archiveindex.h" #include "polyobjs.h" - +#if __JHEXEN__ +# include "acscript.h" +#endif #include "p_saveg.h" using namespace dmu_lib; @@ -206,6 +208,20 @@ static int numSoundTargets; static MaterialArchive *materialArchive; static SideArchive *sideArchive; +#if __JHEXEN__ +static void writeACScript(thinker_t *th, Writer *writer) +{ + ACScript *script = (ACScript *)th; + script->write(writer); +} + +static int readACScript(thinker_t *th, Reader *reader, int mapVersion) +{ + ACScript *script = (ACScript *)th; + return script->read(reader, mapVersion); +} +#endif + static ThinkerClassInfo thinkerInfo[] = { { TC_MOBJ, @@ -262,8 +278,8 @@ static ThinkerClassInfo thinkerInfo[] = { TC_INTERPRET_ACS, (thinkfunc_t) ACScript_Thinker, 0, - (WriteThinkerFunc)ACScript_Write, - (ReadThinkerFunc)ACScript_Read, + (WriteThinkerFunc)writeACScript, + (ReadThinkerFunc)readACScript, sizeof(ACScript) }, { diff --git a/doomsday/plugins/hexen/include/acscript.h b/doomsday/plugins/hexen/include/acscript.h index a2fa3f461d..994782bd74 100644 --- a/doomsday/plugins/hexen/include/acscript.h +++ b/doomsday/plugins/hexen/include/acscript.h @@ -19,8 +19,8 @@ * 02110-1301 USA */ -#ifndef LIBHEXEN_PLAY_ACS_H -#define LIBHEXEN_PLAY_ACS_H +#ifndef LIBHEXEN_PLAY_ACSCRIPT_H +#define LIBHEXEN_PLAY_ACSCRIPT_H #ifndef __JHEXEN__ # error "Using jHexen headers without __JHEXEN__" @@ -28,6 +28,8 @@ #include "jhexen.h" #include "p_mobj.h" +#include +#include #define MAX_ACS_SCRIPT_VARS 10 #define MAX_ACS_MAP_VARS 32 @@ -35,37 +37,6 @@ #define ACS_STACK_DEPTH 32 #ifdef __cplusplus -extern "C" { -#endif - -/** - * To be called when a new game session begins to initialize ACS scripting. - */ -void P_InitACScript(void); - -void P_LoadACScripts(lumpnum_t lump); - -dd_bool P_StartACScript(int number, uint map, byte *args, mobj_t *activator, Line *line, int side); - -dd_bool P_TerminateACScript(int number, uint map); - -dd_bool P_SuspendACScript(int number, uint map); - -void P_ACScriptTagFinished(int tag); - -void P_ACScriptPolyobjFinished(int tag); - -void P_ACScriptRunDeferredTasks(uint map/*Uri const *map*/); - -void P_WriteGlobalACScriptData(void); -void P_ReadGlobalACScriptData(int saveVersion); - -void P_WriteMapACScriptData(void); -void P_ReadMapACScriptData(void); - -#ifdef __cplusplus -} // extern "C" - class ACScriptInterpreter; #endif @@ -88,11 +59,25 @@ typedef struct acscript_s { #ifdef __cplusplus ACScriptInterpreter &interpreter() const; + void runTick(); + + /** + * Serialize the thinker to the currently open save file. + */ + void write(Writer *writer) const; + + /** + * Deserialize the thinker from the currently open save file. + */ + int read(Reader *reader, int mapVersion); + +public: /// @todo make private: void push(int value); int pop(); int top() const; void drop(); -#endif + +#endif // __cplusplus } ACScript; #ifdef __cplusplus @@ -101,19 +86,11 @@ extern "C" { void ACScript_Thinker(ACScript *script); -/** - * Serialize the thinker to the currently open save file. - */ -void ACScript_Write(ACScript const *script); - -/** - * Deserialize the thinker from the currently open save file. - */ -int ACScript_Read(ACScript *script, int mapVersion); - #ifdef __cplusplus } // extern "C" +#endif +#ifdef __cplusplus struct BytecodeScriptInfo; /** @@ -202,11 +179,11 @@ class ACScriptInterpreter */ void scriptFinished(ACScript *script); - void writeWorldScriptData(); - void readWorldScriptData(int saveVersion); + void writeWorldScriptData(Writer *writer); + void readWorldScriptData(Reader *reader, int saveVersion); - void writeMapScriptData(); - void readMapScriptData(); + void writeMapScriptData(Writer *writer); + void readMapScriptData(Reader *reader); public: /// @todo make private: BytecodeScriptInfo &scriptInfoByIndex(int index); @@ -246,4 +223,37 @@ class ACScriptInterpreter }; #endif -#endif // LIBHEXEN_PLAY_ACS_H +#ifdef __cplusplus +extern "C" { +#endif + +/** + * To be called when a new game session begins to initialize ACS scripting. + */ +void P_InitACScript(void); + +void P_LoadACScripts(lumpnum_t lump); + +dd_bool P_StartACScript(int number, uint map, byte *args, mobj_t *activator, Line *line, int side); + +dd_bool P_TerminateACScript(int number, uint map); + +dd_bool P_SuspendACScript(int number, uint map); + +void P_ACScriptTagFinished(int tag); + +void P_ACScriptPolyobjFinished(int tag); + +void P_ACScriptRunDeferredTasks(uint map/*Uri const *map*/); + +void P_WriteGlobalACScriptData(Writer *writer); +void P_ReadGlobalACScriptData(Reader *reader, int saveVersion); + +void P_WriteMapACScriptData(Writer *writer); +void P_ReadMapACScriptData(Reader *reader); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // LIBHEXEN_PLAY_ACSCRIPT_H diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index 6e8b1774a7..43612aaf80 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -1737,34 +1737,13 @@ ACScriptInterpreter &ACScript::interpreter() const return interp; } -void ACScript::push(int value) +void ACScript::runTick() { - stack[stackPtr++] = value; -} - -int ACScript::pop() -{ - return stack[--stackPtr]; -} - -int ACScript::top() const -{ - return stack[stackPtr - 1]; -} - -void ACScript::drop() -{ - stackPtr--; -} - -void ACScript_Thinker(ACScript *script) -{ - DENG_ASSERT(script != 0); - - BytecodeScriptInfo &info = interp.scriptInfoFor(script); + ACScriptInterpreter &interp = interpreter(); + BytecodeScriptInfo &info = interp.scriptInfoFor(this); if(info.state == Terminating) { - interp.scriptFinished(script); + interp.scriptFinished(this); return; } @@ -1773,135 +1752,157 @@ void ACScript_Thinker(ACScript *script) return; } - if(script->delayCount) + if(delayCount) { - script->delayCount--; + delayCount--; return; } CommandArgs args; - args.script = script; + args.script = this; args.scriptInfo = &info; int action; - while((action = PCodeCmds[LONG(*script->pcodePtr++)](args)) == Continue) + while((action = pcodeCmds[LONG(*pcodePtr++)](args)) == Continue) {} if(action == Terminate) { - interp.scriptFinished(script); + interp.scriptFinished(this); } } -void ACScript_Write(ACScript const *th) +void ACScript::push(int value) { - DENG_ASSERT(th != 0); + stack[stackPtr++] = value; +} + +int ACScript::pop() +{ + return stack[--stackPtr]; +} + +int ACScript::top() const +{ + return stack[stackPtr - 1]; +} + +void ACScript::drop() +{ + stackPtr--; +} + +void ACScript_Thinker(ACScript *script) +{ + DENG_ASSERT(script != 0); + script->runTick(); +} - SV_WriteByte(1); // Write a version byte. +void ACScript::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. - SV_WriteLong(SV_ThingArchiveId(th->activator)); - SV_WriteLong(P_ToIndex(th->line)); - SV_WriteLong(th->side); - SV_WriteLong(th->number); - SV_WriteLong(th->infoIndex); - SV_WriteLong(th->delayCount); + Writer_WriteInt32(writer, SV_ThingArchiveId(activator)); + Writer_WriteInt32(writer, P_ToIndex(line)); + Writer_WriteInt32(writer, side); + Writer_WriteInt32(writer, number); + Writer_WriteInt32(writer, infoIndex); + Writer_WriteInt32(writer, delayCount); for(uint i = 0; i < ACS_STACK_DEPTH; ++i) { - SV_WriteLong(th->stack[i]); + Writer_WriteInt32(writer, stack[i]); } - SV_WriteLong(th->stackPtr); + Writer_WriteInt32(writer, stackPtr); for(uint i = 0; i < MAX_ACS_SCRIPT_VARS; ++i) { - SV_WriteLong(th->vars[i]); + Writer_WriteInt32(writer, vars[i]); } - SV_WriteLong(((byte const *)th->pcodePtr) - interp.bytecode()); + Writer_WriteInt32(writer, ((byte const *)pcodePtr) - interpreter().bytecode()); } -int ACScript_Read(ACScript *th, int mapVersion) +int ACScript::read(Reader *reader, int mapVersion) { - DENG_ASSERT(th != 0); - if(mapVersion >= 4) { // Note: the thinker class byte has already been read. - /*int ver =*/ SV_ReadByte(); // version byte. + /*int ver =*/ Reader_ReadByte(reader); // version byte. - th->activator = (mobj_t *) SV_ReadLong(); - th->activator = SV_GetArchiveThing(PTR2INT(th->activator), &th->activator); + activator = (mobj_t *) Reader_ReadInt32(reader); + activator = SV_GetArchiveThing(PTR2INT(activator), &activator); int temp = SV_ReadLong(); if(temp >= 0) { - th->line = (Line *)P_ToPtr(DMU_LINE, temp); - DENG_ASSERT(th->line != 0); + line = (Line *)P_ToPtr(DMU_LINE, temp); + DENG_ASSERT(line != 0); } else { - th->line = 0; + line = 0; } - th->side = SV_ReadLong(); - th->number = SV_ReadLong(); - th->infoIndex = SV_ReadLong(); - th->delayCount = SV_ReadLong(); + side = Reader_ReadInt32(reader); + number = Reader_ReadInt32(reader); + infoIndex = Reader_ReadInt32(reader); + delayCount = Reader_ReadInt32(reader); for(uint i = 0; i < ACS_STACK_DEPTH; ++i) { - th->stack[i] = SV_ReadLong(); + stack[i] = Reader_ReadInt32(reader); } - th->stackPtr = SV_ReadLong(); + stackPtr = Reader_ReadInt32(reader); for(uint i = 0; i < MAX_ACS_SCRIPT_VARS; ++i) { - th->vars[i] = SV_ReadLong(); + vars[i] = Reader_ReadInt32(reader); } - th->pcodePtr = (int *) (interp.bytecode() + SV_ReadLong()); + pcodePtr = (int *) (interpreter().bytecode() + Reader_ReadInt32(reader)); } else { // Its in the old pre V4 format which serialized acs_t // Padding at the start (an old thinker_t struct) - thinker_t junk; - SV_Read(&junk, (size_t) 16); + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); // Start of used data members. - th->activator = (mobj_t*) SV_ReadLong(); - th->activator = SV_GetArchiveThing(PTR2INT(th->activator), &th->activator); + activator = (mobj_t *) Reader_ReadInt32(reader); + activator = SV_GetArchiveThing(PTR2INT(activator), &activator); - int temp = SV_ReadLong(); + int temp = Reader_ReadInt32(reader); if(temp >= 0) { - th->line = (Line *)P_ToPtr(DMU_LINE, temp); - DENG_ASSERT(th->line != 0); + line = (Line *)P_ToPtr(DMU_LINE, temp); + DENG_ASSERT(line != 0); } else { - th->line = 0; + line = 0; } - th->side = SV_ReadLong(); - th->number = SV_ReadLong(); - th->infoIndex = SV_ReadLong(); - th->delayCount = SV_ReadLong(); + side = Reader_ReadInt32(reader); + number = Reader_ReadInt32(reader); + infoIndex = Reader_ReadInt32(reader); + delayCount = Reader_ReadInt32(reader); for(uint i = 0; i < ACS_STACK_DEPTH; ++i) { - th->stack[i] = SV_ReadLong(); + stack[i] = Reader_ReadInt32(reader); } - th->stackPtr = SV_ReadLong(); + stackPtr = Reader_ReadInt32(reader); for(uint i = 0; i < MAX_ACS_SCRIPT_VARS; ++i) { - th->vars[i] = SV_ReadLong(); + vars[i] = Reader_ReadInt32(reader); } - th->pcodePtr = (int *) (interp.bytecode() + SV_ReadLong()); + pcodePtr = (int *) (interpreter().bytecode() + Reader_ReadInt32(reader)); } - th->thinker.function = (thinkfunc_t) ACScript_Thinker; + thinker.function = (thinkfunc_t) ACScript_Thinker; return true; // Add this thinker. } From d9f4cc5020ad461105670212aa786eaeedee623c Mon Sep 17 00:00:00 2001 From: danij Date: Wed, 29 Jan 2014 14:51:48 +0000 Subject: [PATCH 005/106] Refactor|libcommon: Switched more libcommon source files to C++ --- doomsday/plugins/common/common.pri | 10 +- doomsday/plugins/common/include/p_ceiling.h | 68 +-- doomsday/plugins/common/include/p_floor.h | 100 ++--- doomsday/plugins/common/include/p_plat.h | 119 ++--- doomsday/plugins/common/include/p_scroll.h | 26 +- doomsday/plugins/common/include/p_switch.h | 26 +- .../common/src/{p_ceiling.c => p_ceiling.cpp} | 192 +++----- .../common/src/{p_floor.c => p_floor.cpp} | 425 ++++++++---------- .../common/src/{p_plat.c => p_plat.cpp} | 232 ++++------ .../common/src/{p_scroll.c => p_scroll.cpp} | 76 ++-- .../common/src/{p_switch.c => p_switch.cpp} | 151 +++---- 11 files changed, 632 insertions(+), 793 deletions(-) rename doomsday/plugins/common/src/{p_ceiling.c => p_ceiling.cpp} (68%) rename doomsday/plugins/common/src/{p_floor.c => p_floor.cpp} (79%) rename doomsday/plugins/common/src/{p_plat.c => p_plat.cpp} (64%) rename doomsday/plugins/common/src/{p_scroll.c => p_scroll.cpp} (83%) rename doomsday/plugins/common/src/{p_switch.c => p_switch.cpp} (71%) diff --git a/doomsday/plugins/common/common.pri b/doomsday/plugins/common/common.pri index 6d7d295525..a0730979f8 100644 --- a/doomsday/plugins/common/common.pri +++ b/doomsday/plugins/common/common.pri @@ -96,22 +96,22 @@ SOURCES += \ $$common_src/mobj.c \ $$common_src/pause.c \ $$common_src/p_actor.cpp \ - $$common_src/p_ceiling.c \ + $$common_src/p_ceiling.cpp \ $$common_src/p_door.c \ - $$common_src/p_floor.c \ + $$common_src/p_floor.cpp \ $$common_src/p_inventory.c \ $$common_src/p_iterlist.c \ $$common_src/p_map.cpp \ $$common_src/p_mapsetup.cpp \ $$common_src/p_mapspec.c \ - $$common_src/p_plat.c \ + $$common_src/p_plat.cpp \ $$common_src/p_player.c \ $$common_src/p_saveg.cpp \ $$common_src/p_saveio.c \ - $$common_src/p_scroll.c \ + $$common_src/p_scroll.cpp \ $$common_src/p_sound.cpp \ $$common_src/p_start.cpp \ - $$common_src/p_switch.c \ + $$common_src/p_switch.cpp \ $$common_src/p_terraintype.c \ $$common_src/p_tick.c \ $$common_src/p_user.c \ diff --git a/doomsday/plugins/common/include/p_ceiling.h b/doomsday/plugins/common/include/p_ceiling.h index 475e235560..ba09790054 100644 --- a/doomsday/plugins/common/include/p_ceiling.h +++ b/doomsday/plugins/common/include/p_ceiling.h @@ -1,38 +1,29 @@ -/**\file p_ceiling.h - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_ceiling.h Moving ceilings (lowering, crushing, raising). * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2005-2013 Daniel Swanson - *\author Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 1993-1996 id Software, Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * Common playsim routines relating to ceilings. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifndef LIBCOMMON_THINKER_CEILING_H #define LIBCOMMON_THINKER_CEILING_H -#ifdef __cplusplus -extern "C" { -#endif +#define CEILSPEED (1) +#define CEILWAIT (150) typedef enum { CS_DOWN, @@ -75,20 +66,39 @@ typedef struct { int tag; // id. } ceiling_t; -#define CEILSPEED (1) -#define CEILWAIT (150) +#ifdef __cplusplus +extern "C" { +#endif void T_MoveCeiling(void *ceilingThinkerPtr); +/** + * Move a ceiling up/down. + */ #if __JHEXEN__ int EV_DoCeiling(Line* line, byte* args, ceilingtype_e type); #else int EV_DoCeiling(Line* li, ceilingtype_e type); #endif +/** + * Reactivates all stopped crushers with the right tag. + * + * @param tag Tag of ceilings to activate. + * + * @return @c true, if a ceiling is activated. + */ #if __JDOOM__ || __JDOOM64__ || __JHERETIC__ int P_CeilingActivate(short tag); #endif + +/** + * Stops all active ceilings with the right tag. + * + * @param tag Tag of ceilings to stop. + * + * @return @c true, if a ceiling put in stasis. + */ int P_CeilingDeactivate(short tag); #ifdef __cplusplus diff --git a/doomsday/plugins/common/include/p_floor.h b/doomsday/plugins/common/include/p_floor.h index 53348f46f3..a1fd1b010e 100644 --- a/doomsday/plugins/common/include/p_floor.h +++ b/doomsday/plugins/common/include/p_floor.h @@ -1,38 +1,28 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_floor.h Common playsim routines relating to moving floors. * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2005-2013 Daniel Swanson - *\author Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 1993-1996 id Software, Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * p_floor.h: Common playsim routines relating to moving floors. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -#ifndef __COMMON_THINKER_FLOOR_H__ -#define __COMMON_THINKER_FLOOR_H__ +#ifndef LIBCOMMON_THINKER_FLOOR_H +#define LIBCOMMON_THINKER_FLOOR_H -#ifdef __cplusplus -extern "C" { -#endif +#define FLOORSPEED (1) typedef enum { FS_DOWN = -1, // Moving down. @@ -92,43 +82,49 @@ typedef enum { } floortype_e; typedef struct { - thinker_t thinker; - floortype_e type; - dd_bool crush; - Sector* sector; - floorstate_e state; - int newSpecial; - Material* material; - coord_t floorDestHeight; - float speed; + thinker_t thinker; + floortype_e type; + dd_bool crush; + Sector *sector; + floorstate_e state; + int newSpecial; + Material *material; + coord_t floorDestHeight; + float speed; #if __JHEXEN__ - int delayCount; - int delayTotal; - coord_t stairsDelayHeight; - coord_t stairsDelayHeightDelta; - coord_t resetHeight; - short resetDelay; - short resetDelayCount; + int delayCount; + int delayTotal; + coord_t stairsDelayHeight; + coord_t stairsDelayHeightDelta; + coord_t resetHeight; + short resetDelay; + short resetDelayCount; #endif } floor_t; -#define FLOORSPEED (1) +#ifdef __cplusplus +extern "C" { +#endif -void T_MoveFloor(void *floorThinker); +void T_MoveFloor(void *floorThinker); + +/** + * Handle moving floors. + */ #if __JHEXEN__ -int EV_DoFloor(Line* li, byte* args, floortype_e type); +int EV_DoFloor(Line *li, byte *args, floortype_e type); #else -int EV_DoFloor(Line* li, floortype_e type); +int EV_DoFloor(Line *li, floortype_e type); #endif #if __JHEXEN__ -int EV_DoFloorAndCeiling(Line* li, byte* args, int ftype, int ctype); +int EV_DoFloorAndCeiling(Line *li, byte *args, int ftype, int ctype); #elif __JDOOM64__ -int EV_DoFloorAndCeiling(Line* li, int ftype, int ctype); +int EV_DoFloorAndCeiling(Line *li, int ftype, int ctype); #endif #ifdef __cplusplus } // extern "C" #endif -#endif +#endif // LIBCOMMON_THINKER_FLOOR_H diff --git a/doomsday/plugins/common/include/p_plat.h b/doomsday/plugins/common/include/p_plat.h index 97713431fb..332e2cbebe 100644 --- a/doomsday/plugins/common/include/p_plat.h +++ b/doomsday/plugins/common/include/p_plat.h @@ -1,38 +1,29 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_plat.h Common playsim routines relating to moving platforms. * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2005-2013 Daniel Swanson - *\author Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 1993-1996 id Software, Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * p_plat.h: Common playsim routines relating to moving platforms. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -#ifndef __COMMON_THINKER_PLAT_H__ -#define __COMMON_THINKER_PLAT_H__ +#ifndef LIBCOMMON_THINKER_PLAT_H +#define LIBCOMMON_THINKER_PLAT_H -#ifdef __cplusplus -extern "C" { -#endif +#define PLATWAIT (3) +#define PLATSPEED (1) typedef enum { PS_UP, // Moving up. @@ -65,37 +56,63 @@ typedef enum { } plattype_e; typedef struct plat_s { - thinker_t thinker; - Sector* sector; - float speed; - coord_t low; - coord_t high; - int wait; - int count; - platstate_e state; - platstate_e oldState; - dd_bool crush; - int tag; - plattype_e type; + thinker_t thinker; + Sector *sector; + float speed; + coord_t low; + coord_t high; + int wait; + int count; + platstate_e state; + platstate_e oldState; + dd_bool crush; + int tag; + plattype_e type; } plat_t; -#define PLATWAIT (3) -#define PLATSPEED (1) +#ifdef __cplusplus +extern "C" { +#endif -void T_PlatRaise(void *platThinkerPtr); +/** + * Move a plat up and down. + * + * @param plat Ptr to the plat to be moved. + */ +void T_PlatRaise(void *platThinkerPtr); +/** + * Do Platforms. + * + * @param amount: is only used for SOME platforms. + */ #if __JHEXEN__ -int EV_DoPlat(Line* li, byte* args, plattype_e type, - int amount); -int P_PlatDeactivate(short tag); +int EV_DoPlat(Line *li, byte *args, plattype_e type, int amount); #else -int EV_DoPlat(Line* li, plattype_e type, int amount); -int P_PlatActivate(short tag); -int P_PlatDeactivate(short tag); +int EV_DoPlat(Line* li, plattype_e type, int amount); #endif +#if !__JHEXEN__ +/** + * Activate a plat that has been put in stasis + * (stopped perpetual floor, instant floor/ceil toggle) + * + * @param tag Tag of plats that should be reactivated. + */ +int P_PlatActivate(short tag); +#endif + +/** + * Handler for "stop perpetual floor" line type. + * + * @param tag Tag of plats to put into stasis. + * + * @return Number of plats put into stasis. + */ +int P_PlatDeactivate(short tag); + #ifdef __cplusplus } // extern "C" #endif -#endif +#endif // LIBCOMMON_THINKER_PLAT_H diff --git a/doomsday/plugins/common/include/p_scroll.h b/doomsday/plugins/common/include/p_scroll.h index b31ad91568..a26235746d 100644 --- a/doomsday/plugins/common/include/p_scroll.h +++ b/doomsday/plugins/common/include/p_scroll.h @@ -1,10 +1,8 @@ -/** - * @file p_scroll.h - * Common surface material scroll thinker. @ingroup libcommon +/** @file p_scroll.h Common surface material scroll thinker. * - * @authors Copyright © 2003-2013 Jaakko Keränen - * @authors Copyright © 2005-2013 Daniel Swanson - * @authors Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 1993-1996 id Software, Inc. * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -26,22 +24,22 @@ #include "doomsday.h" -#ifdef __cplusplus -extern "C" { -#endif - typedef struct { thinker_t thinker; - void* dmuObject; ///< Affected DMU object (either a sector or a side). + void *dmuObject; ///< Affected DMU object (either a sector or a side). int elementBits; ///< Identifies which subelements of the dmuObject are affected. float offset[2]; ///< [x, y] scroll vector delta. } scroll_t; -void T_Scroll(scroll_t* scroll); +#ifdef __cplusplus +extern "C" { +#endif + +void T_Scroll(scroll_t *scroll); -scroll_t* P_SpawnSideMaterialOriginScroller(Side* side, short special); +scroll_t *P_SpawnSideMaterialOriginScroller(Side *side, short special); -scroll_t* P_SpawnSectorMaterialOriginScroller(Sector* sector, uint planeId, short special); +scroll_t *P_SpawnSectorMaterialOriginScroller(Sector *sector, uint planeId, short special); #ifdef __cplusplus } // extern "C" diff --git a/doomsday/plugins/common/include/p_switch.h b/doomsday/plugins/common/include/p_switch.h index 4b06b11e67..21d024d48b 100644 --- a/doomsday/plugins/common/include/p_switch.h +++ b/doomsday/plugins/common/include/p_switch.h @@ -1,10 +1,8 @@ -/** - * @file p_switch.h - * Common playsim routines relating to switches. +/** @file p_switch.h Common playsim routines relating to switches. * - * @authors Copyright © 2003-2013 Jaakko Keränen - * @authors Copyright © 2005-2013 Daniel Swanson - * @authors Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 1993-1996 id Software, Inc. * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -28,10 +26,6 @@ #include "p_mobj.h" #include "dmu_lib.h" -#ifdef __cplusplus -extern "C" { -#endif - #define BUTTONTIME (TICSPERSEC) // 1 second, in ticks. typedef struct { @@ -39,9 +33,13 @@ typedef struct { int timer; Side* side; SideSection section; - Material* material; + Material *material; } materialchanger_t; +#ifdef __cplusplus +extern "C" { +#endif + /** * Called at game initialization or when the engine's state must be updated * (eg a new WAD is loaded at runtime). This routine will populate the list @@ -61,7 +59,7 @@ void P_InitSwitchList(void); * @param tics @c <= 0 = A permanent change. * @c > 0 = Change back after this many tics. */ -dd_bool P_ToggleSwitch2(Side* side, SideSection ssurfaceID, int sound, +dd_bool P_ToggleSwitch2(Side *side, SideSection ssurfaceID, int sound, dd_bool silent, int tics); /** @@ -74,13 +72,13 @@ dd_bool P_ToggleSwitch2(Side* side, SideSection ssurfaceID, int sound, * @param tics @c <= 0 = A permanent change. * @c > 0 = Change back after this many tics. */ -dd_bool P_ToggleSwitch(Side* side, int sound, dd_bool silent, int tics); +dd_bool P_ToggleSwitch(Side *side, int sound, dd_bool silent, int tics); /** * To be called to execute any action(s) assigned to the specified Line's * special. */ -dd_bool P_UseSpecialLine(mobj_t* activator, Line* line, int side); +dd_bool P_UseSpecialLine(mobj_t *activator, Line *line, int side); void T_MaterialChanger(void *materialChangedThinker); diff --git a/doomsday/plugins/common/src/p_ceiling.c b/doomsday/plugins/common/src/p_ceiling.cpp similarity index 68% rename from doomsday/plugins/common/src/p_ceiling.c rename to doomsday/plugins/common/src/p_ceiling.cpp index f7c16b0930..392039c9e6 100644 --- a/doomsday/plugins/common/src/p_ceiling.c +++ b/doomsday/plugins/common/src/p_ceiling.cpp @@ -1,56 +1,36 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_ceiling.cpp Moving ceilings (lowering, crushing, raising). * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2005-2013 Daniel Swanson - *\author Copyright © 2006 Martin Eyre - *\author Copyright © 2003-2005 Samuel Villarreal - *\author Copyright © 1999 by Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman (PrBoom 2.2.6) - *\author Copyright © 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze (PrBoom 2.2.6) - *\author Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 2006 Martin Eyre + * @authors Copyright © 2003-2005 Samuel Villarreal + * @authors Copyright © 1999 Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman (PrBoom 2.2.6) + * @authors Copyright © 1999-2000 Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze (PrBoom 2.2.6) + * @authors Copyright © 1993-1996 id Software, Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -/** - * p_ceilings.c : Moving ceilings (lowering, crushing, raising). - */ - -// HEADER FILES ------------------------------------------------------------ - -#if __JDOOM__ -# include "jdoom.h" -#elif __JDOOM64__ -# include "jdoom64.h" -#elif __JHERETIC__ -# include "jheretic.h" -#elif __JHEXEN__ -# include "jhexen.h" -#endif +#include "common.h" +#include "p_ceiling.h" #include "dmu_lib.h" #include "p_mapspec.h" #include "p_sound.h" #include "p_start.h" #include "p_tick.h" -#include "p_ceiling.h" - -// MACROS ------------------------------------------------------------------ // Sounds played by the ceilings when changing state or moving. // jHexen uses sound sequences, so it's are defined as 'SFX_NONE'. @@ -68,30 +48,14 @@ # define SFX_CEILINGSTOP (SFX_NONE) #endif -// TYPES ------------------------------------------------------------------- - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -// CODE -------------------------------------------------------------------- - /** * Called when a moving ceiling needs to be removed. * * @param ceiling Ptr to the ceiling to be stopped. */ -static void stopCeiling(ceiling_t* ceiling) +static void stopCeiling(ceiling_t *ceiling) { - P_ToXSector(ceiling->sector)->specialData = NULL; + P_ToXSector(ceiling->sector)->specialData = 0; #if __JHEXEN__ P_ACScriptTagFinished(P_ToXSector(ceiling->sector)->tag); #endif @@ -100,8 +64,8 @@ static void stopCeiling(ceiling_t* ceiling) void T_MoveCeiling(void *ceilingThinkerPtr) { - ceiling_t* ceiling = ceilingThinkerPtr; - result_e res; + ceiling_t *ceiling = (ceiling_t *)ceilingThinkerPtr; + result_e res; switch(ceiling->state) { @@ -115,14 +79,14 @@ void T_MoveCeiling(void *ceilingThinkerPtr) if(!(mapTime & 7)) { # if __JHERETIC__ - S_PlaneSound(P_GetPtrp(ceiling->sector, DMU_CEILING_PLANE), SFX_CEILINGMOVE); + S_PlaneSound((Plane *)P_GetPtrp(ceiling->sector, DMU_CEILING_PLANE), SFX_CEILINGMOVE); # else switch(ceiling->type) { case CT_SILENTCRUSHANDRAISE: break; default: - S_PlaneSound(P_GetPtrp(ceiling->sector, DMU_CEILING_PLANE), SFX_CEILINGMOVE); + S_PlaneSound((Plane *)P_GetPtrp(ceiling->sector, DMU_CEILING_PLANE), SFX_CEILINGMOVE); break; } # endif @@ -132,7 +96,7 @@ void T_MoveCeiling(void *ceilingThinkerPtr) if(res == pastdest) { #if __JHEXEN__ - SN_StopSequence(P_GetPtrp(ceiling->sector, DMU_EMITTER)); + SN_StopSequence((mobj_t *)P_GetPtrp(ceiling->sector, DMU_EMITTER)); #endif switch(ceiling->type) { @@ -145,7 +109,7 @@ void T_MoveCeiling(void *ceilingThinkerPtr) break; # if !__JHERETIC__ case CT_SILENTCRUSHANDRAISE: - S_PlaneSound(P_GetPtrp(ceiling->sector, DMU_CEILING_PLANE), SFX_CEILINGSTOP); + S_PlaneSound((Plane *)P_GetPtrp(ceiling->sector, DMU_CEILING_PLANE), SFX_CEILINGSTOP); # endif case CT_CRUSHANDRAISEFAST: #endif @@ -176,14 +140,14 @@ void T_MoveCeiling(void *ceilingThinkerPtr) if(!(mapTime & 7)) { # if __JHERETIC__ - S_PlaneSound(P_GetPtrp(ceiling->sector, DMU_CEILING_PLANE), SFX_CEILINGMOVE); + S_PlaneSound((Plane *)P_GetPtrp(ceiling->sector, DMU_CEILING_PLANE), SFX_CEILINGMOVE); # else switch(ceiling->type) { case CT_SILENTCRUSHANDRAISE: break; default: - S_PlaneSound(P_GetPtrp(ceiling->sector, DMU_CEILING_PLANE), SFX_CEILINGMOVE); + S_PlaneSound((Plane *)P_GetPtrp(ceiling->sector, DMU_CEILING_PLANE), SFX_CEILINGMOVE); } # endif } @@ -192,13 +156,13 @@ void T_MoveCeiling(void *ceilingThinkerPtr) if(res == pastdest) { #if __JHEXEN__ - SN_StopSequence(P_GetPtrp(ceiling->sector, DMU_EMITTER)); + SN_StopSequence((mobj_t *)P_GetPtrp(ceiling->sector, DMU_EMITTER)); #endif switch(ceiling->type) { #if __JDOOM__ || __JDOOM64__ case CT_SILENTCRUSHANDRAISE: - S_PlaneSound(P_GetPtrp(ceiling->sector, DMU_CEILING_PLANE), SFX_CEILINGSTOP); + S_PlaneSound((Plane *)P_GetPtrp(ceiling->sector, DMU_CEILING_PLANE), SFX_CEILINGSTOP); ceiling->speed = CEILSPEED; ceiling->state = CS_UP; break; @@ -265,36 +229,32 @@ void T_MoveCeiling(void *ceilingThinkerPtr) } #if __JDOOM64__ -static int EV_DoCeiling2(Line* line, int tag, float basespeed, - ceilingtype_e type) +static int EV_DoCeiling2(Line *line, int tag, float basespeed, ceilingtype_e type) #elif __JHEXEN__ -static int EV_DoCeiling2(byte* arg, int tag, float basespeed, ceilingtype_e type) +static int EV_DoCeiling2(byte *arg, int tag, float basespeed, ceilingtype_e type) #else static int EV_DoCeiling2(int tag, float basespeed, ceilingtype_e type) #endif { - int rtn = 0; - xsector_t* xsec; - Sector* sec = NULL; - ceiling_t* ceiling; - iterlist_t* list; + iterlist_t *list = P_GetSectorIterListForTag(tag, false); + if(!list) return 0; - list = P_GetSectorIterListForTag(tag, false); - if(!list) - return rtn; + int rtn = 0; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec = 0; + while((sec = (Sector *)IterList_MoveIterator(list))) { - xsec = P_ToXSector(sec); + xsector_t *xsec = P_ToXSector(sec); if(xsec->specialData) continue; // new door thinker rtn = 1; - ceiling = Z_Calloc(sizeof(*ceiling), PU_MAP, 0); + ceiling_t *ceiling = (ceiling_t *)Z_Calloc(sizeof(*ceiling), PU_MAP, 0); ceiling->thinker.function = T_MoveCeiling; Thinker_Add(&ceiling->thinker); @@ -359,8 +319,8 @@ static int EV_DoCeiling2(int tag, float basespeed, ceilingtype_e type) case CT_CUSTOM: // jd64 { //bitmip? wha? - Side* front = P_GetPtrp(line, DMU_FRONT); - Side* back = P_GetPtrp(line, DMU_BACK); + Side *front = (Side *)P_GetPtrp(line, DMU_FRONT); + Side *back = (Side *)P_GetPtrp(line, DMU_BACK); coord_t bitmipL = 0, bitmipR = 0; bitmipL = P_GetDoublep(front, DMU_MIDDLE_MATERIAL_OFFSET_X); @@ -431,7 +391,7 @@ static int EV_DoCeiling2(int tag, float basespeed, ceilingtype_e type) #if __JHEXEN__ if(rtn) { - SN_StartSequence(P_GetPtrp(ceiling->sector, DMU_EMITTER), + SN_StartSequence((mobj_t *)P_GetPtrp(ceiling->sector, DMU_EMITTER), SEQ_PLATFORM + P_ToXSector(ceiling->sector)->seqType); } #endif @@ -439,9 +399,6 @@ static int EV_DoCeiling2(int tag, float basespeed, ceilingtype_e type) return rtn; } -/** - * Move a ceiling up/down. - */ #if __JHEXEN__ int EV_DoCeiling(Line *line, byte *args, ceilingtype_e type) #else @@ -452,7 +409,7 @@ int EV_DoCeiling(Line *line, ceilingtype_e type) return EV_DoCeiling2(args, (int) args[0], (float) args[1] * (1.0 / 8), type); #else - int rtn = 0; + int rtn = 0; // Reactivate in-stasis ceilings...for certain types. switch(type) { @@ -476,15 +433,16 @@ int EV_DoCeiling(Line *line, ceilingtype_e type) } #if !__JHEXEN__ -typedef struct { - short tag; - int count; -} activateceilingparams_t; +struct activateceilingparams_t +{ + short tag; + int count; +}; -static int activateCeiling(thinker_t* th, void* context) +static int activateCeiling(thinker_t *th, void *context) { - ceiling_t* ceiling = (ceiling_t*) th; - activateceilingparams_t* params = (activateceilingparams_t*) context; + ceiling_t *ceiling = (ceiling_t *) th; + activateceilingparams_t *params = (activateceilingparams_t *) context; if(ceiling->tag == (int) params->tag && ceiling->thinker.inStasis) { @@ -496,13 +454,6 @@ static int activateCeiling(thinker_t* th, void* context) return false; // Continue iteration. } -/** - * Reactivates all stopped crushers with the right tag. - * - * @param tag Tag of ceilings to activate. - * - * @return @c true, if a ceiling is activated. - */ int P_CeilingActivate(short tag) { activateceilingparams_t params; @@ -515,28 +466,30 @@ int P_CeilingActivate(short tag) } #endif -typedef struct { - short tag; - int count; -} deactivateceilingparams_t; +struct deactivateceilingparams_t +{ + short tag; + int count; +}; -static int deactivateCeiling(thinker_t* th, void* context) +static int deactivateCeiling(thinker_t *th, void *context) { - ceiling_t* ceiling = (ceiling_t*) th; - deactivateceilingparams_t* params = - (deactivateceilingparams_t*) context; + ceiling_t *ceiling = (ceiling_t *) th; + deactivateceilingparams_t *params = (deactivateceilingparams_t *) context; #if __JHEXEN__ if(ceiling->tag == (int) params->tag) - { // Destroy it. - SN_StopSequence(P_GetPtrp(ceiling->sector, DMU_EMITTER)); + { + // Destroy it. + SN_StopSequence((mobj_t *)P_GetPtrp(ceiling->sector, DMU_EMITTER)); stopCeiling(ceiling); params->count++; return true; // Stop iteration. } #else if(!ceiling->thinker.inStasis && ceiling->tag == (int) params->tag) - { // Put it into stasis. + { + // Put it into stasis. ceiling->oldState = ceiling->state; Thinker_SetStasis(&ceiling->thinker, true); params->count++; @@ -545,13 +498,6 @@ static int deactivateCeiling(thinker_t* th, void* context) return false; // Continue iteration. } -/** - * Stops all active ceilings with the right tag. - * - * @param tag Tag of ceilings to stop. - * - * @return @c true, if a ceiling put in stasis. - */ int P_CeilingDeactivate(short tag) { deactivateceilingparams_t params; diff --git a/doomsday/plugins/common/src/p_floor.c b/doomsday/plugins/common/src/p_floor.cpp similarity index 79% rename from doomsday/plugins/common/src/p_floor.c rename to doomsday/plugins/common/src/p_floor.cpp index 5ee4601a8b..c60c440b7b 100644 --- a/doomsday/plugins/common/src/p_floor.c +++ b/doomsday/plugins/common/src/p_floor.cpp @@ -1,60 +1,40 @@ -/**\file p_floor.c - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_floor.cpp Common playsim routines relating to moving floors. * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2006-2013 Daniel Swanson - *\author Copyright © 2006 Martin Eyre - *\author Copyright © 2003-2005 Samuel Villarreal - *\author Copyright © 1999 by Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman (PrBoom 2.2.6) - *\author Copyright © 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze (PrBoom 2.2.6) - *\author Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2006-2013 Daniel Swanson + * @authors Copyright © 2006 Martin Eyre + * @authors Copyright © 2003-2005 Samuel Villarreal + * @authors Copyright © 1999 Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman (PrBoom 2.2.6) + * @authors Copyright © 1999-2000 Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze (PrBoom 2.2.6) + * @authors Copyright © 1993-1996 id Software, Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -/** - * Moving floors. - */ - -// HEADER FILES ------------------------------------------------------------ - -#if __JDOOM__ -# include "jdoom.h" -#elif __JDOOM64__ -# include "jdoom64.h" -#elif __JHERETIC__ -# include "jheretic.h" -#elif __JHEXEN__ -# include "jhexen.h" -#endif +#include "common.h" +#include "p_floor.h" #include "dmu_lib.h" #include "p_map.h" #include "p_mapspec.h" #include "p_tick.h" -#include "p_floor.h" #if __JHEXEN__ || __JDOOM64__ #include "p_ceiling.h" #endif #include "p_sound.h" -// MACROS ------------------------------------------------------------------ - #if __JHERETIC__ # define SFX_FLOORMOVE (SFX_DORMOV) #else @@ -66,44 +46,30 @@ #define STAIR_QUEUE_SIZE 32 #endif -// TYPES ------------------------------------------------------------------- - #if __JHEXEN__ typedef struct stairqueue_s { - Sector* sector; - int type; - coord_t height; + Sector *sector; + int type; + coord_t height; } stairqueue_t; // Global vars for stair building, in a struct for neatness. typedef struct stairdata_s { - coord_t stepDelta; - int direction; - float speed; - Material* material; - int startDelay; - int startDelayDelta; - int textureChange; - coord_t startHeight; + coord_t stepDelta; + int direction; + float speed; + Material *material; + int startDelay; + int startDelayDelta; + int textureChange; + coord_t startHeight; } stairdata_t; #endif -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - #if __JHEXEN__ -static void enqueueStairSector(Sector* sec, int type, coord_t height); +static void enqueueStairSector(Sector *sec, int type, coord_t height); #endif -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - #if __JHEXEN__ stairdata_t stairData; stairqueue_t stairQueue[STAIR_QUEUE_SIZE]; @@ -111,13 +77,11 @@ static int stairQueueHead; static int stairQueueTail; #endif -// CODE -------------------------------------------------------------------- - /** * Move a plane (floor or ceiling) and check for crushing. */ -result_e T_MovePlane(Sector* sector, float speed, coord_t dest, - int crush, int isCeiling, int direction) +result_e T_MovePlane(Sector *sector, float speed, coord_t dest, int crush, + int isCeiling, int direction) { dd_bool flag; coord_t lastpos; @@ -146,7 +110,7 @@ result_e T_MovePlane(Sector* sector, float speed, coord_t dest, lastpos = floorheight; P_SetDoublep(sector, DMU_FLOOR_HEIGHT, dest); flag = P_ChangeSector(sector, crush); - if(flag == true) + if(flag) { // Oh no, the move failed. P_SetDoublep(sector, DMU_FLOOR_HEIGHT, lastpos); @@ -163,7 +127,7 @@ result_e T_MovePlane(Sector* sector, float speed, coord_t dest, lastpos = floorheight; P_SetDoublep(sector, DMU_FLOOR_HEIGHT, floorheight - speed); flag = P_ChangeSector(sector, crush); - if(flag == true) + if(flag) { P_SetDoublep(sector, DMU_FLOOR_HEIGHT, lastpos); P_SetDoublep(sector, ptarget, lastpos); @@ -184,7 +148,7 @@ result_e T_MovePlane(Sector* sector, float speed, coord_t dest, lastpos = floorheight; P_SetDoublep(sector, DMU_FLOOR_HEIGHT, dest); flag = P_ChangeSector(sector, crush); - if(flag == true) + if(flag) { // Oh no, the move failed. P_SetDoublep(sector, DMU_FLOOR_HEIGHT, lastpos); @@ -202,7 +166,7 @@ result_e T_MovePlane(Sector* sector, float speed, coord_t dest, lastpos = floorheight; P_SetDoublep(sector, DMU_FLOOR_HEIGHT, floorheight + speed); flag = P_ChangeSector(sector, crush); - if(flag == true) + if(flag) { #if !__JHEXEN__ if(crush) @@ -236,7 +200,7 @@ result_e T_MovePlane(Sector* sector, float speed, coord_t dest, lastpos = ceilingheight; P_SetDoublep(sector, DMU_CEILING_HEIGHT, dest); flag = P_ChangeSector(sector, crush); - if(flag == true) + if(flag) { P_SetDoublep(sector, DMU_CEILING_HEIGHT, lastpos); P_SetDoublep(sector, ptarget, lastpos); @@ -253,7 +217,7 @@ result_e T_MovePlane(Sector* sector, float speed, coord_t dest, lastpos = ceilingheight; P_SetDoublep(sector, DMU_CEILING_HEIGHT, ceilingheight - speed); flag = P_ChangeSector(sector, crush); - if(flag == true) + if(flag) { #if !__JHEXEN__ if(crush) @@ -278,7 +242,7 @@ result_e T_MovePlane(Sector* sector, float speed, coord_t dest, lastpos = ceilingheight; P_SetDoublep(sector, DMU_CEILING_HEIGHT, dest); flag = P_ChangeSector(sector, crush); - if(flag == true) + if(flag) { P_SetDoublep(sector, DMU_CEILING_HEIGHT, lastpos); P_SetDoublep(sector, ptarget, lastpos); @@ -314,7 +278,7 @@ result_e T_MovePlane(Sector* sector, float speed, coord_t dest, */ void T_MoveFloor(void *floorThinkerPtr) { - floor_t* floor = floorThinkerPtr; + floor_t *floor = (floor_t *)floorThinkerPtr; result_e res; #if __JHEXEN__ @@ -361,7 +325,7 @@ void T_MoveFloor(void *floorThinkerPtr) #if !__JHEXEN__ if(!(mapTime & 7)) - S_PlaneSound(P_GetPtrp(floor->sector, DMU_FLOOR_PLANE), SFX_FLOORMOVE); + S_PlaneSound((Plane *)P_GetPtrp(floor->sector, DMU_FLOOR_PLANE), SFX_FLOORMOVE); #endif if(res == pastdest) @@ -370,12 +334,12 @@ void T_MoveFloor(void *floorThinkerPtr) P_SetFloatp(floor->sector, DMU_FLOOR_SPEED, 0); #if __JHEXEN__ - SN_StopSequence(P_GetPtrp(floor->sector, DMU_EMITTER)); + SN_StopSequence((mobj_t *)P_GetPtrp(floor->sector, DMU_EMITTER)); #else # if __JHERETIC__ if(floor->type == FT_RAISEBUILDSTEP) # endif - S_PlaneSound(P_GetPtrp(floor->sector, DMU_FLOOR_PLANE), SFX_PSTOP); + S_PlaneSound((Plane *)P_GetPtrp(floor->sector, DMU_FLOOR_PLANE), SFX_PSTOP); #endif #if __JHEXEN__ @@ -430,29 +394,25 @@ void T_MoveFloor(void *floorThinkerPtr) } } -typedef struct findlineinsectorsmallestbottommaterialparams_s { - Sector *baseSec; - int minSize; - Line *foundLine; -} findlineinsectorsmallestbottommaterialparams_t; +struct findlineinsectorsmallestbottommaterialparams_t +{ + Sector *baseSec; + int minSize; + Line *foundLine; +}; int findLineInSectorSmallestBottomMaterial(void *ptr, void *context) { - Line* li = (Line*) ptr; - findlineinsectorsmallestbottommaterialparams_t* params = - (findlineinsectorsmallestbottommaterialparams_t*) context; - Sector* frontSec, *backSec; + Line *li = (Line *) ptr; + findlineinsectorsmallestbottommaterialparams_t *params = (findlineinsectorsmallestbottommaterialparams_t *) context; - frontSec = P_GetPtrp(li, DMU_FRONT_SECTOR); - backSec = P_GetPtrp(li, DMU_BACK_SECTOR); + Sector *frontSec = (Sector *)P_GetPtrp(li, DMU_FRONT_SECTOR); + Sector *backSec = (Sector *)P_GetPtrp(li, DMU_BACK_SECTOR); if(frontSec && backSec) { - Side* side; - Material* mat; - - side = P_GetPtrp(li, DMU_FRONT); - mat = P_GetPtrp(side, DMU_BOTTOM_MATERIAL); + Side *side = (Side *)P_GetPtrp(li, DMU_FRONT); + Material *mat = (Material *)P_GetPtrp(side, DMU_BOTTOM_MATERIAL); /** * Emulate DOOM.exe behaviour. In the instance where no material is @@ -476,8 +436,8 @@ int findLineInSectorSmallestBottomMaterial(void *ptr, void *context) } } - side = P_GetPtrp(li, DMU_BACK); - mat = P_GetPtrp(side, DMU_BOTTOM_MATERIAL); + side = (Side *)P_GetPtrp(li, DMU_BACK); + mat = (Material *)P_GetPtrp(side, DMU_BOTTOM_MATERIAL); if(!mat) { Uri *textureUrn = Uri_NewWithPath2("urn:Textures:0", RC_NULL); @@ -567,9 +527,6 @@ static Sector *findSectorSurroundingAtFloorHeight(Sector *sec, coord_t height) } #endif -/** - * Handle moving floors. - */ #if __JHEXEN__ int EV_DoFloor(Line* line, byte* args, floortype_e floortype) #else @@ -577,13 +534,8 @@ int EV_DoFloor(Line* line, floortype_e floortype) #endif { #if !__JHEXEN__ - Sector* frontsector; + Sector *frontsector; #endif - int rtn = 0; - xsector_t* xsec; - Sector* sec = NULL; - floor_t* floor = NULL; - iterlist_t* list; #if __JHEXEN__ int tag = (int) args[0]; #else @@ -593,8 +545,8 @@ int EV_DoFloor(Line* line, floortype_e floortype) #if __JDOOM64__ // jd64 > bitmip? wha? coord_t bitmipL = 0, bitmipR = 0; - Side *front = P_GetPtrp(line, DMU_FRONT); - Side *back = P_GetPtrp(line, DMU_BACK); + Side *front = (Side *)P_GetPtrp(line, DMU_FRONT); + Side *back = (Side *)P_GetPtrp(line, DMU_BACK); bitmipL = P_GetDoublep(front, DMU_MIDDLE_MATERIAL_OFFSET_X); if(back) @@ -602,22 +554,26 @@ int EV_DoFloor(Line* line, floortype_e floortype) // < d64tc #endif - list = P_GetSectorIterListForTag(tag, false); - if(!list) - return rtn; + iterlist_t *list = P_GetSectorIterListForTag(tag, false); + if(!list) return 0; + + int rtn = 0; + floor_t *floor = 0; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) { - xsec = P_ToXSector(sec); + xsector_t *xsec = P_ToXSector(sec); // If already moving, keep going... if(xsec->specialData) continue; rtn = 1; // New floor thinker. - floor = Z_Calloc(sizeof(*floor), PU_MAP, 0); + floor = (floor_t *)Z_Calloc(sizeof(*floor), PU_MAP, 0); floor->thinker.function = T_MoveFloor; Thinker_Add(&floor->thinker); xsec->specialData = floor; @@ -868,7 +824,7 @@ int EV_DoFloor(Line* line, floortype_e floortype) floor->floorDestHeight = P_GetDoublep(floor->sector, DMU_FLOOR_HEIGHT) + 24; - frontsector = P_GetPtrp(line, DMU_FRONT_SECTOR); + frontsector = (Sector *)P_GetPtrp(line, DMU_FRONT_SECTOR); P_SetPtrp(sec, DMU_FLOOR_MATERIAL, P_GetPtrp(frontsector, DMU_FLOOR_MATERIAL)); @@ -915,7 +871,7 @@ int EV_DoFloor(Line* line, floortype_e floortype) floor->speed = FLOORSPEED; P_FindSectorSurroundingLowestFloor(sec, P_GetDoublep(sec, DMU_FLOOR_HEIGHT), &floor->floorDestHeight); - floor->material = P_GetPtrp(sec, DMU_FLOOR_MATERIAL); + floor->material = (Material *)P_GetPtrp(sec, DMU_FLOOR_MATERIAL); { Sector* otherSec = findSectorSurroundingAtFloorHeight(sec, @@ -923,7 +879,7 @@ int EV_DoFloor(Line* line, floortype_e floortype) if(otherSec) { - floor->material = P_GetPtrp(otherSec, DMU_FLOOR_MATERIAL); + floor->material = (Material *)P_GetPtrp(otherSec, DMU_FLOOR_MATERIAL); floor->newSpecial = P_ToXSector(otherSec)->special; } } @@ -940,36 +896,34 @@ int EV_DoFloor(Line* line, floortype_e floortype) #if __JHEXEN__ if(rtn && floor) { - SN_StartSequence(P_GetPtrp(floor->sector, DMU_EMITTER), + SN_StartSequence((mobj_t *)P_GetPtrp(floor->sector, DMU_EMITTER), SEQ_PLATFORM + P_ToXSector(floor->sector)->seqType); } #endif + return rtn; } #if __JHEXEN__ -typedef struct { +struct findsectorneighborsforstairbuildparams_t +{ int type; coord_t height; -} findsectorneighborsforstairbuildparams_t; +}; -static int findSectorNeighborsForStairBuild(void* ptr, void* context) +/// @return @c 0= Continue iteration. +static int findSectorNeighborsForStairBuild(void *ptr, void *context) { - Line* li = (Line*) ptr; - findsectorneighborsforstairbuildparams_t* params = - (findsectorneighborsforstairbuildparams_t*) context; - Sector* frontSec, *backSec; - xsector_t* xsec; + Line *li = (Line *) ptr; + findsectorneighborsforstairbuildparams_t *params = (findsectorneighborsforstairbuildparams_t *) context; - frontSec = P_GetPtrp(li, DMU_FRONT_SECTOR); - if(!frontSec) - return false; // Continue iteration. + Sector *frontSec = (Sector *)P_GetPtrp(li, DMU_FRONT_SECTOR); + if(!frontSec) return false; - backSec = P_GetPtrp(li, DMU_BACK_SECTOR); - if(!backSec) - return false; // Continue iteration. + Sector *backSec = (Sector *)P_GetPtrp(li, DMU_BACK_SECTOR); + if(!backSec) return false; - xsec = P_ToXSector(frontSec); + xsector_t *xsec = P_ToXSector(frontSec); if(xsec->special == params->type + STAIR_SECTOR_TYPE && !xsec->specialData && P_GetPtrp(frontSec, DMU_FLOOR_MATERIAL) == stairData.material && P_GetIntp(frontSec, DMU_VALID_COUNT) != VALIDCOUNT) @@ -987,7 +941,7 @@ static int findSectorNeighborsForStairBuild(void* ptr, void* context) P_SetIntp(backSec, DMU_VALID_COUNT, VALIDCOUNT); } - return false; // Continue iteration. + return false; } #endif @@ -1000,31 +954,30 @@ static int findSectorNeighborsForStairBuild(void* ptr, void* context) * * @warning DO NOT USE THIS ANYWHERE ELSE! */ -typedef struct spreadsectorparams_s { +struct spreadsectorparams_t +{ Sector *baseSec; Material *material; Sector *foundSec; coord_t height, stairSize; -} spreadsectorparams_t; +}; /// @return 0= continue iteration; otherwise stop. static int findAdjacentSectorForSpread(void *ptr, void *context) { Line *li = (Line *) ptr; spreadsectorparams_t *params = (spreadsectorparams_t *) context; - Sector *frontSec, *backSec; - xsector_t *xsec; if(!(P_ToXLine(li)->flags & ML_TWOSIDED)) return false; - frontSec = P_GetPtrp(li, DMU_FRONT_SECTOR); + Sector *frontSec = (Sector *)P_GetPtrp(li, DMU_FRONT_SECTOR); if(!frontSec) return false; if(params->baseSec != frontSec) return false; - backSec = P_GetPtrp(li, DMU_BACK_SECTOR); + Sector *backSec = (Sector *)P_GetPtrp(li, DMU_BACK_SECTOR); if(!backSec) return false; if(P_GetPtrp(backSec, DMU_FLOOR_MATERIAL) != params->material) @@ -1037,7 +990,7 @@ static int findAdjacentSectorForSpread(void *ptr, void *context) */ params->height += params->stairSize; - xsec = P_ToXSector(backSec); + xsector_t *xsec = P_ToXSector(backSec); if(xsec->specialData) return false; @@ -1048,24 +1001,23 @@ static int findAdjacentSectorForSpread(void *ptr, void *context) #endif #if __JDOOM__ || __JDOOM64__ || __JHERETIC__ -int EV_BuildStairs(Line* line, stair_e type) +int EV_BuildStairs(Line *line, stair_e type) { - int rtn = 0; - xsector_t* xsec; - Sector* sec = NULL; - floor_t* floor; + xsector_t *xsec; coord_t height = 0, stairsize = 0; float speed = 0; - iterlist_t* list; - spreadsectorparams_t params; - list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); - if(!list) - return rtn; + iterlist_t *list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); + if(!list) return 0; + + int rtn = 0; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + spreadsectorparams_t params; + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) { xsec = P_ToXSector(sec); @@ -1075,7 +1027,7 @@ int EV_BuildStairs(Line* line, stair_e type) // New floor thinker. rtn = 1; - floor = Z_Calloc(sizeof(*floor), PU_MAP, 0); + floor_t *floor = (floor_t *)Z_Calloc(sizeof(*floor), PU_MAP, 0); floor->thinker.function = T_MoveFloor; Thinker_Add(&floor->thinker); @@ -1117,16 +1069,16 @@ int EV_BuildStairs(Line* line, stair_e type) // Find next sector to raise. // 1. Find 2-sided line with a front side in the same sector. // 2. Other side is the next sector to raise. - params.baseSec = sec; - params.material = P_GetPtrp(sec, DMU_FLOOR_MATERIAL); - params.foundSec = NULL; - params.height = height; + params.baseSec = sec; + params.material = (Material *)P_GetPtrp(sec, DMU_FLOOR_MATERIAL); + params.foundSec = 0; + params.height = height; params.stairSize = stairsize; while(P_Iteratep(params.baseSec, DMU_LINE, findAdjacentSectorForSpread, ¶ms)) { // We found another sector to spread to. - floor = Z_Calloc(sizeof(*floor), PU_MAP, 0); + floor = (floor_t *)Z_Calloc(sizeof(*floor), PU_MAP, 0); floor->thinker.function = T_MoveFloor; Thinker_Add(&floor->thinker); @@ -1181,15 +1133,14 @@ static Sector* dequeueStairSector(int* type, coord_t* height) return sec; } -static void processStairSector(Sector* sec, int type, coord_t height, +static void processStairSector(Sector *sec, int type, coord_t height, stairs_e stairsType, int delay, int resetDelay) { - floor_t* floor; findsectorneighborsforstairbuildparams_t params; height += stairData.stepDelta; - floor = Z_Calloc(sizeof(*floor), PU_MAP, 0); + floor_t *floor = (floor_t *)Z_Calloc(sizeof(*floor), PU_MAP, 0); floor->thinker.function = T_MoveFloor; Thinker_Add(&floor->thinker); P_ToXSector(sec)->specialData = floor; @@ -1224,10 +1175,10 @@ static void processStairSector(Sector* sec, int type, coord_t height, break; } - SN_StartSequence(P_GetPtrp(sec, DMU_EMITTER), + SN_StartSequence((mobj_t *)P_GetPtrp(sec, DMU_EMITTER), SEQ_PLATFORM + P_ToXSector(sec)->seqType); - params.type = type; + params.type = type; params.height = height; // Find all neigboring sectors with sector special equal to type and add @@ -1240,27 +1191,19 @@ static void processStairSector(Sector* sec, int type, coord_t height, * @param direction Positive = up. Negative = down. */ #if __JHEXEN__ -int EV_BuildStairs(Line* line, byte* args, int direction, - stairs_e stairsType) +int EV_BuildStairs(Line *line, byte *args, int direction, stairs_e stairsType) { - coord_t height; - int delay; - int type; - int resetDelay; - Sector* sec = NULL, *qSec; - iterlist_t* list; - // Set global stairs variables stairData.textureChange = 0; stairData.direction = direction; stairData.stepDelta = stairData.direction * (coord_t) args[2]; stairData.speed = (float) args[1] * (1.0 / 8); - resetDelay = (int) args[4]; - delay = (int) args[3]; + + int resetDelay = (int) args[4]; + int delay = (int) args[3]; if(stairsType == STAIRS_PHASED) { - stairData.startDelay = - stairData.startDelayDelta = (int) args[3]; + stairData.startDelay = stairData.startDelayDelta = (int) args[3]; resetDelay = stairData.startDelayDelta; delay = 0; stairData.textureChange = (int) args[4]; @@ -1268,15 +1211,16 @@ int EV_BuildStairs(Line* line, byte* args, int direction, VALIDCOUNT++; - list = P_GetSectorIterListForTag((int) args[0], false); - if(!list) - return 0; + iterlist_t *list = P_GetSectorIterListForTag((int) args[0], false); + if(!list) return 0; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) { - stairData.material = P_GetPtrp(sec, DMU_FLOOR_MATERIAL); + stairData.material = (Material *)P_GetPtrp(sec, DMU_FLOOR_MATERIAL); stairData.startHeight = P_GetDoublep(sec, DMU_FLOOR_HEIGHT); // ALREADY MOVING? IF SO, KEEP GOING... @@ -1287,9 +1231,11 @@ int EV_BuildStairs(Line* line, byte* args, int direction, P_ToXSector(sec)->special = 0; } - while((qSec = dequeueStairSector(&type, &height)) != NULL) + int type; + coord_t height; + while((sec = dequeueStairSector(&type, &height))) { - processStairSector(qSec, type, height, stairsType, delay, resetDelay); + processStairSector(sec, type, height, stairsType, delay, resetDelay); } return 1; @@ -1297,16 +1243,18 @@ int EV_BuildStairs(Line* line, byte* args, int direction, #endif #if __JDOOM__ || __JDOOM64__ || __JHERETIC__ -typedef struct { +struct findfirsttwosidedparams_t +{ Sector *sector; Line *foundLine; -} findfirsttwosidedparams_t; +}; static int findFirstTwosided(void *ptr, void *context) { Line *li = (Line *) ptr; findfirsttwosidedparams_t *params = (findfirsttwosidedparams_t *) context; - Sector *backSec = P_GetPtrp(li, DMU_BACK_SECTOR); + + Sector *backSec = (Sector *)P_GetPtrp(li, DMU_BACK_SECTOR); if(!(P_ToXLine(li)->flags & ML_TWOSIDED)) return false; @@ -1324,16 +1272,16 @@ static int findFirstTwosided(void *ptr, void *context) #if __JDOOM__ || __JDOOM64__ || __JHERETIC__ int EV_DoDonut(Line *line) { - int rtn = 0; - Sector *sec, *outer, *ring; - iterlist_t *list; + iterlist_t *list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); + if(!list) return 0; - list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); - if(!list) return rtn; + int rtn = 0; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) { findfirsttwosidedparams_t params; @@ -1342,56 +1290,59 @@ int EV_DoDonut(Line *line) continue; rtn = 1; - outer = ring = NULL; + Sector *outer = 0, *ring = 0; - params.sector = NULL; - params.foundLine = NULL; + params.sector = 0; + params.foundLine = 0; if(P_Iteratep(sec, DMU_LINE, findFirstTwosided, ¶ms)) { - ring = P_GetPtrp(params.foundLine, DMU_BACK_SECTOR); + ring = (Sector *)P_GetPtrp(params.foundLine, DMU_BACK_SECTOR); if(ring == sec) - ring = P_GetPtrp(params.foundLine, DMU_FRONT_SECTOR); + { + ring = (Sector *)P_GetPtrp(params.foundLine, DMU_FRONT_SECTOR); + } params.sector = sec; params.foundLine = NULL; if(P_Iteratep(ring, DMU_LINE, findFirstTwosided, ¶ms)) - outer = P_GetPtrp(params.foundLine, DMU_BACK_SECTOR); + { + outer = (Sector *)P_GetPtrp(params.foundLine, DMU_BACK_SECTOR); + } } if(outer && ring) { // Found both parts of the donut. - floor_t* floor; coord_t destHeight = P_GetDoublep(outer, DMU_FLOOR_HEIGHT); // Spawn rising slime. - floor = Z_Calloc(sizeof(*floor), PU_MAP, 0); + floor_t *floor = (floor_t *)Z_Calloc(sizeof(*floor), PU_MAP, 0); floor->thinker.function = T_MoveFloor; Thinker_Add(&floor->thinker); P_ToXSector(ring)->specialData = floor; - floor->type = FT_RAISEDONUT; - floor->crush = false; - floor->state = FS_UP; - floor->sector = ring; - floor->speed = FLOORSPEED * .5; - floor->material = P_GetPtrp(outer, DMU_FLOOR_MATERIAL); - floor->newSpecial = 0; + floor->type = FT_RAISEDONUT; + floor->crush = false; + floor->state = FS_UP; + floor->sector = ring; + floor->speed = FLOORSPEED * .5; + floor->material = (Material *)P_GetPtrp(outer, DMU_FLOOR_MATERIAL); + floor->newSpecial = 0; floor->floorDestHeight = destHeight; // Spawn lowering donut-hole. - floor = Z_Calloc(sizeof(*floor), PU_MAP, 0); + floor = (floor_t *)Z_Calloc(sizeof(*floor), PU_MAP, 0); floor->thinker.function = T_MoveFloor; Thinker_Add(&floor->thinker); P_ToXSector(sec)->specialData = floor; - floor->type = FT_LOWER; - floor->crush = false; - floor->state = FS_DOWN; - floor->sector = sec; - floor->speed = FLOORSPEED * .5; + floor->type = FT_LOWER; + floor->crush = false; + floor->state = FS_DOWN; + floor->sector = sec; + floor->speed = FLOORSPEED * .5; floor->floorDestHeight = destHeight; } } @@ -1401,15 +1352,15 @@ int EV_DoDonut(Line *line) #endif #if __JHEXEN__ -static int stopFloorCrush(thinker_t* th, void* context) +static int stopFloorCrush(thinker_t *th, void *context) { - dd_bool* found = (dd_bool*) context; - floor_t* floor = (floor_t *) th; + dd_bool *found = (dd_bool *) context; + floor_t *floor = (floor_t *) th; if(floor->type == FT_RAISEFLOORCRUSH) { // Completely remove the crushing floor - SN_StopSequence(P_GetPtrp(floor->sector, DMU_EMITTER)); + SN_StopSequence((mobj_t *)P_GetPtrp(floor->sector, DMU_EMITTER)); P_ToXSector(floor->sector)->specialData = NULL; P_ACScriptTagFinished(P_ToXSector(floor->sector)->tag); Thinker_Remove(&floor->thinker); @@ -1419,9 +1370,9 @@ static int stopFloorCrush(thinker_t* th, void* context) return false; // Continue iteration. } -int EV_FloorCrushStop(Line* line, byte* args) +int EV_FloorCrushStop(Line *line, byte *args) { - dd_bool found = false; + dd_bool found = false; Thinker_Iterate(T_MoveFloor, stopFloorCrush, &found); @@ -1437,17 +1388,13 @@ int EV_DoFloorAndCeiling(Line* line, int ftype, int ctype) # endif { # if __JHEXEN__ - int tag = (int) args[0]; + int tag = (int) args[0]; # else - int tag = P_ToXLine(line)->tag; + int tag = P_ToXLine(line)->tag; # endif - dd_bool floor, ceiling; - Sector* sec = NULL; - iterlist_t* list; - list = P_GetSectorIterListForTag(tag, false); - if(!list) - return 0; + iterlist_t *list = P_GetSectorIterListForTag(tag, false); + if(!list) return 0; /** * @attention Kludge: @@ -1464,20 +1411,24 @@ int EV_DoFloorAndCeiling(Line* line, int ftype, int ctype) */ # if __JHEXEN__ - floor = EV_DoFloor(line, args, ftype); + dd_bool floor = EV_DoFloor(line, args, floortype_e(ftype)); # else - floor = EV_DoFloor(line, ftype); + dd_bool floor = EV_DoFloor(line, floortype_e(ftype)); # endif + IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) { - P_ToXSector(sec)->specialData = NULL; + P_ToXSector(sec)->specialData = 0; } + # if __JHEXEN__ - ceiling = EV_DoCeiling(line, args, ctype); + dd_bool ceiling = EV_DoCeiling(line, args, ceilingtype_e(ctype)); # else - ceiling = EV_DoCeiling(line, ctype); + dd_bool ceiling = EV_DoCeiling(line, ceilingtype_e(ctype)); # endif // < KLUDGE diff --git a/doomsday/plugins/common/src/p_plat.c b/doomsday/plugins/common/src/p_plat.cpp similarity index 64% rename from doomsday/plugins/common/src/p_plat.c rename to doomsday/plugins/common/src/p_plat.cpp index ab7d7f82de..2696b73dfd 100644 --- a/doomsday/plugins/common/src/p_plat.c +++ b/doomsday/plugins/common/src/p_plat.cpp @@ -1,56 +1,36 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_plat.cpp Common playsim routines relating to moving platforms. * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2005-2013 Daniel Swanson - *\author Copyright © 2006 Martin Eyre - *\author Copyright © 2003-2005 Samuel Villarreal - *\author Copyright © 1999 by Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman (PrBoom 2.2.6) - *\author Copyright © 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze (PrBoom 2.2.6) - *\author Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 2006 Martin Eyre + * @authors Copyright © 2003-2005 Samuel Villarreal + * @authors Copyright © 1999 Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman (PrBoom 2.2.6) + * @authors Copyright © 1999-2000 Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze (PrBoom 2.2.6) + * @authors Copyright © 1993-1996 id Software, Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * p_plats.c : Elevators and platforms, raising/lowering. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -// HEADER FILES ------------------------------------------------------------ - -#if __JDOOM__ -# include "jdoom.h" -#elif __JDOOM64__ -# include "jdoom64.h" -#elif __JHERETIC__ -# include "jheretic.h" -#elif __JHEXEN__ -# include "jhexen.h" -#endif +#include "common.h" +#include "p_plat.h" #include "dmu_lib.h" #include "p_mapspec.h" #include "p_tick.h" -#include "p_plat.h" #include "p_sound.h" -// MACROS ------------------------------------------------------------------ - // Sounds played by the platforms when changing state or moving. // jHexen uses sound sequences, so it's are defined as 'SFX_NONE'. #if __JDOOM__ @@ -71,45 +51,24 @@ # define SFX_PLATFORMSTOP (SFX_NONE) #endif -// TYPES ------------------------------------------------------------------- - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -// CODE -------------------------------------------------------------------- - /** * Called when a moving plat needs to be removed. * - * @param plat Ptr to the plat to remove. + * @param plat Ptr to the plat to remove. */ -static void stopPlat(plat_t* plat) +static void stopPlat(plat_t *plat) { - P_ToXSector(plat->sector)->specialData = NULL; + P_ToXSector(plat->sector)->specialData = 0; #if __JHEXEN__ P_ACScriptTagFinished(P_ToXSector(plat->sector)->tag); #endif Thinker_Remove(&plat->thinker); } -/** - * Move a plat up and down. - * - * @param plat Ptr to the plat to be moved. - */ void T_PlatRaise(void *platThinkerPtr) { - plat_t* plat = platThinkerPtr; - result_e res; + plat_t *plat = (plat_t *)platThinkerPtr; + result_e res; switch(plat->state) { @@ -120,14 +79,14 @@ void T_PlatRaise(void *platThinkerPtr) // Play a "while-moving" sound? #if __JHERETIC__ if(!(mapTime & 31)) - S_PlaneSound(P_GetPtrp(plat->sector, DMU_FLOOR_PLANE), SFX_PLATFORMMOVE); + S_PlaneSound((Plane *)P_GetPtrp(plat->sector, DMU_FLOOR_PLANE), SFX_PLATFORMMOVE); #endif #if __JDOOM__ || __JDOOM64__ if(plat->type == PT_RAISEANDCHANGE || plat->type == PT_RAISETONEARESTANDCHANGE) { if(!(mapTime & 7)) - S_PlaneSound(P_GetPtrp(plat->sector, DMU_FLOOR_PLANE), SFX_PLATFORMMOVE); + S_PlaneSound((Plane *)P_GetPtrp(plat->sector, DMU_FLOOR_PLANE), SFX_PLATFORMMOVE); } #endif if(res == crushed && (!plat->crush)) @@ -140,7 +99,7 @@ void T_PlatRaise(void *platThinkerPtr) # if __JDOOM64__ if(plat->type != PT_DOWNWAITUPDOOR) // jd64 added test # endif - S_PlaneSound(P_GetPtrp(plat->sector, DMU_FLOOR_PLANE), SFX_PLATFORMSTART); + S_PlaneSound((Plane *)P_GetPtrp(plat->sector, DMU_FLOOR_PLANE), SFX_PLATFORMSTART); #endif } else @@ -152,7 +111,7 @@ void T_PlatRaise(void *platThinkerPtr) #if __JHEXEN__ SN_StopSequenceInSec(plat->sector); #else - S_PlaneSound(P_GetPtrp(plat->sector, DMU_FLOOR_PLANE), SFX_PLATFORMSTOP); + S_PlaneSound((Plane *)P_GetPtrp(plat->sector, DMU_FLOOR_PLANE), SFX_PLATFORMSTOP); #endif switch(plat->type) { @@ -207,7 +166,7 @@ void T_PlatRaise(void *platThinkerPtr) #if __JHEXEN__ SN_StopSequenceInSec(plat->sector); #else - S_PlaneSound(P_GetPtrp(plat->sector, DMU_FLOOR_PLANE), SFX_PLATFORMSTOP); + S_PlaneSound((Plane *)P_GetPtrp(plat->sector, DMU_FLOOR_PLANE), SFX_PLATFORMSTOP); #endif } else @@ -215,7 +174,7 @@ void T_PlatRaise(void *platThinkerPtr) // Play a "while-moving" sound? #if __JHERETIC__ if(!(mapTime & 31)) - S_PlaneSound(P_GetPtrp(plat->sector, DMU_FLOOR_PLANE), SFX_PLATFORMMOVE); + S_PlaneSound((Plane *)P_GetPtrp(plat->sector, DMU_FLOOR_PLANE), SFX_PLATFORMMOVE); #endif } break; @@ -230,7 +189,7 @@ void T_PlatRaise(void *platThinkerPtr) #if __JHEXEN__ SN_StartSequenceInSec(plat->sector, SEQ_PLATFORM); #else - S_PlaneSound(P_GetPtrp(plat->sector, DMU_FLOOR_PLANE), SFX_PLATFORMSTART); + S_PlaneSound((Plane *)P_GetPtrp(plat->sector, DMU_FLOOR_PLANE), SFX_PLATFORMSTART); #endif } break; @@ -246,24 +205,22 @@ static int doPlat(Line* line, int tag, byte* args, plattype_e type, int amount) static int doPlat(Line* line, int tag, plattype_e type, int amount) #endif { - int rtn = 0; - coord_t floorHeight; - plat_t* plat; - Sector* sec = NULL; #if !__JHEXEN__ - Sector* frontSector = P_GetPtrp(line, DMU_FRONT_SECTOR); + Sector *frontSector = (Sector *)P_GetPtrp(line, DMU_FRONT_SECTOR); #endif - xsector_t* xsec; - iterlist_t* list; - list = P_GetSectorIterListForTag(tag, false); - if(!list) return rtn; + iterlist_t *list = P_GetSectorIterListForTag(tag, false); + if(!list) return 0; + + int rtn = 0; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) { - xsec = P_ToXSector(sec); + xsector_t *xsec = P_ToXSector(sec); if(xsec->specialData) continue; @@ -271,21 +228,22 @@ static int doPlat(Line* line, int tag, plattype_e type, int amount) // Find lowest & highest floors around sector rtn = 1; - plat = Z_Calloc(sizeof(*plat), PU_MAP, 0); + plat_t *plat = (plat_t *) Z_Calloc(sizeof(*plat), PU_MAP, 0); plat->thinker.function = T_PlatRaise; Thinker_Add(&plat->thinker); - plat->type = type; - plat->sector = sec; - xsec->specialData = plat; - plat->crush = false; - plat->tag = tag; + plat->type = type; + plat->sector = sec; + plat->crush = false; + plat->tag = tag; #if __JHEXEN__ - plat->speed = (float) args[1] * (1.0 / 8); + plat->speed = (float) args[1] * (1.0 / 8); #endif - floorHeight = P_GetDoublep(sec, DMU_FLOOR_HEIGHT); + + coord_t floorHeight = P_GetDoublep(sec, DMU_FLOOR_HEIGHT); + switch(type) { #if !__JHEXEN__ @@ -307,7 +265,7 @@ static int doPlat(Line* line, int tag, plattype_e type, int amount) plat->state = PS_UP; // No more damage if applicable. xsec->special = 0; - S_PlaneSound(P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMMOVE); + S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMMOVE); break; case PT_RAISEANDCHANGE: @@ -319,7 +277,7 @@ static int doPlat(Line* line, int tag, plattype_e type, int amount) plat->high = floorHeight + amount; plat->wait = 0; plat->state = PS_UP; - S_PlaneSound(P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMMOVE); + S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMMOVE); break; #endif case PT_DOWNWAITUPSTAY: @@ -341,7 +299,7 @@ static int doPlat(Line* line, int tag, plattype_e type, int amount) plat->wait = PLATWAIT * TICSPERSEC; #endif #if !__JHEXEN__ - S_PlaneSound(P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMSTART); + S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMSTART); #endif break; @@ -361,7 +319,7 @@ static int doPlat(Line* line, int tag, plattype_e type, int amount) # endif # if __JDOOM64__ plat->speed = PLATSPEED * 8; - S_PlaneSound(P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMSTART); + S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMSTART); # endif break; #endif @@ -412,7 +370,7 @@ static int doPlat(Line* line, int tag, plattype_e type, int amount) plat->high = floorHeight; plat->wait = PLATWAIT * TICSPERSEC; plat->state = PS_DOWN; - S_PlaneSound(P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMSTART); + S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMSTART); break; #endif case PT_PERPETUALRAISE: @@ -431,14 +389,14 @@ static int doPlat(Line* line, int tag, plattype_e type, int amount) if(plat->high < floorHeight) plat->high = floorHeight; - plat->state = P_Random() & 1; + plat->state = platstate_e(P_Random() & 1); #if __JHEXEN__ plat->wait = (int) args[2]; #else plat->wait = PLATWAIT * TICSPERSEC; #endif #if !__JHEXEN__ - S_PlaneSound(P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMSTART); + S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMSTART); #endif break; @@ -454,11 +412,6 @@ static int doPlat(Line* line, int tag, plattype_e type, int amount) return rtn; } -/** - * Do Platforms. - * - * @param amount: is only used for SOME platforms. - */ #if __JHEXEN__ int EV_DoPlat(Line *line, byte *args, plattype_e type, int amount) #else @@ -468,8 +421,8 @@ int EV_DoPlat(Line *line, plattype_e type, int amount) #if __JHEXEN__ return doPlat(line, (int) args[0], args, type, amount); #else - int rtn = 0; - xline_t* xline = P_ToXLine(line); + int rtn = 0; + xline_t *xline = P_ToXLine(line); // Activate all plats that are in stasis. switch(type) @@ -487,15 +440,16 @@ int EV_DoPlat(Line *line, plattype_e type, int amount) } #if !__JHEXEN__ -typedef struct { - short tag; - int count; -} activateplatparams_t; +struct activateplatparams_t +{ + short tag; + int count; +}; -static int activatePlat(thinker_t* th, void* context) +static int activatePlat(thinker_t *th, void *context) { - plat_t* plat = (plat_t*) th; - activateplatparams_t* params = (activateplatparams_t*) context; + plat_t *plat = (plat_t *) th; + activateplatparams_t *params = (activateplatparams_t *) context; if(plat->tag == (int) params->tag && plat->thinker.inStasis) { @@ -507,33 +461,28 @@ static int activatePlat(thinker_t* th, void* context) return false; // Contiue iteration. } -/** - * Activate a plat that has been put in stasis - * (stopped perpetual floor, instant floor/ceil toggle) - * - * @param tag Tag of plats that should be reactivated. - */ int P_PlatActivate(short tag) { - activateplatparams_t params; + activateplatparams_t parm; - params.tag = tag; - params.count = 0; - Thinker_Iterate(T_PlatRaise, activatePlat, ¶ms); + parm.tag = tag; + parm.count = 0; + Thinker_Iterate(T_PlatRaise, activatePlat, &parm); - return params.count; + return parm.count; } #endif -typedef struct { - short tag; - int count; -} deactivateplatparams_t; +struct deactivateplatparams_t +{ + short tag; + int count; +}; -static int deactivatePlat(thinker_t* th, void* context) +static int deactivatePlat(thinker_t *th, void *context) { - plat_t* plat = (plat_t*) th; - deactivateplatparams_t* params = (deactivateplatparams_t*) context; + plat_t *plat = (plat_t *) th; + deactivateplatparams_t *params = (deactivateplatparams_t *) context; #if __JHEXEN__ // For THE one with the tag. @@ -558,20 +507,13 @@ static int deactivatePlat(thinker_t* th, void* context) return false; // Continue iteration. } -/** - * Handler for "stop perpetual floor" line type. - * - * @param tag Tag of plats to put into stasis. - * - * @return Number of plats put into stasis. - */ int P_PlatDeactivate(short tag) { - deactivateplatparams_t params; + deactivateplatparams_t parm; - params.tag = tag; - params.count = 0; - Thinker_Iterate(T_PlatRaise, deactivatePlat, ¶ms); + parm.tag = tag; + parm.count = 0; + Thinker_Iterate(T_PlatRaise, deactivatePlat, &parm); - return params.count; + return parm.count; } diff --git a/doomsday/plugins/common/src/p_scroll.c b/doomsday/plugins/common/src/p_scroll.cpp similarity index 83% rename from doomsday/plugins/common/src/p_scroll.c rename to doomsday/plugins/common/src/p_scroll.cpp index edfd71e931..52ba6d41e4 100644 --- a/doomsday/plugins/common/src/p_scroll.c +++ b/doomsday/plugins/common/src/p_scroll.cpp @@ -1,10 +1,8 @@ -/** - * @file p_scroll.c - * Common surface material scroll thinker. @ingroup libcommon +/** @file p_scroll.cpp Common surface material scroll thinker. * - * @authors Copyright © 2003-2013 Jaakko Keränen - * @authors Copyright © 2005-2013 Daniel Swanson - * @authors Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 1993-1996 id Software, Inc. * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -22,20 +20,19 @@ */ #include "common.h" -#include "dmu_lib.h" - #include "p_scroll.h" +#include "dmu_lib.h" -void T_Scroll(scroll_t* s) +void T_Scroll(scroll_t *s) { - DENG_ASSERT(s); + DENG_ASSERT(s != 0); if(FEQUAL(s->offset[0], 0) && FEQUAL(s->offset[1], 0)) return; // Side surface(s)? if(DMU_GetType(s->dmuObject) == DMU_SIDE) { - Side* side = s->dmuObject; + Side *side = (Side *)s->dmuObject; if(s->elementBits & (1 << SS_TOP)) { @@ -52,52 +49,53 @@ void T_Scroll(scroll_t* s) } else // Sector plane-surface(s). { - Sector* sector = s->dmuObject; + Sector *sector = (Sector *)s->dmuObject; if(s->elementBits & (1 << PLN_FLOOR)) { - Plane* plane = P_GetPtrp(sector, DMU_FLOOR_PLANE); + Plane *plane = (Plane *)P_GetPtrp(sector, DMU_FLOOR_PLANE); P_TranslatePlaneMaterialOrigin(plane, s->offset); } if(s->elementBits & (1 << PLN_CEILING)) { - Plane* plane = P_GetPtrp(sector, DMU_CEILING_PLANE); + Plane *plane = (Plane *)P_GetPtrp(sector, DMU_CEILING_PLANE); P_TranslatePlaneMaterialOrigin(plane, s->offset); } } } -static scroll_t* spawnMaterialOriginScroller(void* dmuObject, int elementBits, float offsetXY[2]) +static scroll_t *spawnMaterialOriginScroller(void *dmuObject, int elementBits, float offsetXY[2]) { - scroll_t* scroll; - // Don't spawn a scroller with an invalid map object reference. - if(!dmuObject || elementBits <= 0) return NULL; + if(!dmuObject || elementBits <= 0) return 0; // Don't spawn a scroller with a zero-length offset vector. - if(FEQUAL(offsetXY[0], 0) && FEQUAL(offsetXY[1], 0)) return NULL; + if(FEQUAL(offsetXY[0], 0) && FEQUAL(offsetXY[1], 0)) + { + return 0; + } - scroll = Z_Calloc(sizeof(*scroll), PU_MAP, 0); + scroll_t *scroll = (scroll_t *)Z_Calloc(sizeof(*scroll), PU_MAP, 0); scroll->thinker.function = (thinkfunc_t) T_Scroll; Thinker_Add(&scroll->thinker); - scroll->dmuObject = dmuObject; + scroll->dmuObject = dmuObject; scroll->elementBits = elementBits; - scroll->offset[0] = offsetXY[0]; - scroll->offset[1] = offsetXY[1]; + scroll->offset[0] = offsetXY[0]; + scroll->offset[1] = offsetXY[1]; return scroll; } -scroll_t* P_SpawnSideMaterialOriginScroller(Side* side, short special) +scroll_t *P_SpawnSideMaterialOriginScroller(Side *side, short special) { int elementBits; float offset[2]; - if(!side) return NULL; + if(!side) return 0; switch(special) { - default: return NULL; // Not a scroller. + default: return 0; // Not a scroller. #if __JDOOM__ || __JDOOM64__ || __JHERETIC__ case 48: ///< Tagless, scroll left. @@ -130,7 +128,7 @@ scroll_t* P_SpawnSideMaterialOriginScroller(Side* side, short special) #if __JHEXEN__ case 100: ///< Tagless, scroll left at speed. case 101: { ///< Tagless, scroll right at speed. - xline_t* xline = P_ToXLine(P_GetPtrp(side, DMU_LINE)); + xline_t *xline = P_ToXLine((Line *)P_GetPtrp(side, DMU_LINE)); float speed = FIX2FLT(xline->arg1 << 10); offset[0] = (special == 100? speed : -speed); offset[1] = 0; @@ -138,7 +136,7 @@ scroll_t* P_SpawnSideMaterialOriginScroller(Side* side, short special) case 102: ///< Tagless, scroll up at speed. case 103: { ///< Tagless, scroll down speed. - xline_t* xline = P_ToXLine(P_GetPtrp(side, DMU_LINE)); + xline_t *xline = P_ToXLine((Line *)P_GetPtrp(side, DMU_LINE)); float speed = FIX2FLT(xline->arg1 << 10); offset[0] = 0; offset[1] = (special == 102? speed : -speed); @@ -153,27 +151,29 @@ scroll_t* P_SpawnSideMaterialOriginScroller(Side* side, short special) #endif } - elementBits = (1 << SS_MIDDLE) | (1 << SS_BOTTOM) | (1 << SS_TOP); + elementBits = (1 << SS_MIDDLE) | (1 << SS_BOTTOM) | (1 << SS_TOP); return spawnMaterialOriginScroller(side, elementBits, offset); } -scroll_t* P_SpawnSectorMaterialOriginScroller(Sector* sector, uint planeId, short special) +scroll_t *P_SpawnSectorMaterialOriginScroller(Sector *sector, uint planeId, short special) { #define SCROLLUNIT (8.f/35*2) - int elementBits; - float offset[2]; - // Don't spawn a scroller with an invalid surface reference. - if(!sector || !(planeId == PLN_FLOOR || planeId == PLN_CEILING)) return NULL; + if(!sector || !(planeId == PLN_FLOOR || planeId == PLN_CEILING)) + { + return 0; + } /// @todo $nplanes +#if __JHERETIC__ || __JHEXEN__ + int elementBits; + float offset[2]; switch(special) { - default: return NULL; // Not a scroller. + default: return 0; // Not a scroller. -#if __JHERETIC__ || __JHEXEN__ # if __JHERETIC__ case 25: ///< Scroll north. case 26: @@ -263,7 +263,6 @@ scroll_t* P_SpawnSectorMaterialOriginScroller(Sector* sector, uint planeId, shor # endif offset[1] = 0; break; -#endif // __JHERETIC__ || __JHEXEN__ #if __JHERETIC__ case 4: ///< Scroll east (lava damage). @@ -305,6 +304,9 @@ scroll_t* P_SpawnSectorMaterialOriginScroller(Sector* sector, uint planeId, shor elementBits = 1 << planeId; return spawnMaterialOriginScroller(sector, elementBits, offset); +#endif // __JHERETIC__ || __JHEXEN__ + + return 0; #undef SCROLLUNIT } diff --git a/doomsday/plugins/common/src/p_switch.c b/doomsday/plugins/common/src/p_switch.cpp similarity index 71% rename from doomsday/plugins/common/src/p_switch.c rename to doomsday/plugins/common/src/p_switch.cpp index c49103cc4a..bde13becf2 100644 --- a/doomsday/plugins/common/src/p_switch.c +++ b/doomsday/plugins/common/src/p_switch.cpp @@ -1,12 +1,10 @@ -/** - * @file p_switch.c - * Common playsim routines relating to switches. +/** @file p_switch.cpp Common playsim routines relating to switches. * - * @authors Copyright © 2003-2013 Jaakko Keränen - * @authors Copyright © 2005-2013 Daniel Swanson - * @authors Copyright © 1999 Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman (PrBoom 2.2.6) - * @authors Copyright © 1999-2000 Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze (PrBoom 2.2.6) - * @authors Copyright © 1993-1996 id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 1999 Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman (PrBoom 2.2.6) + * @authors Copyright © 1999-2000 Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze (PrBoom 2.2.6) + * @authors Copyright © 1993-1996 id Software, Inc. * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -23,21 +21,14 @@ * 02110-1301 USA */ -#if __JDOOM__ -# include "jdoom.h" -#elif __JDOOM64__ -# include "jdoom64.h" -#elif __JHERETIC__ -# include "jheretic.h" -#elif __JHEXEN__ -# include "jhexen.h" -#endif +#include "common.h" +#include "p_switch.h" #include "d_net.h" #include "dmu_lib.h" #include "p_plat.h" #include "p_sound.h" -#include "p_switch.h" +#include /** * This struct is used to provide byte offsets when reading a custom @@ -142,39 +133,36 @@ switchlist_t switchInfo[] = { }; #endif -static Material** switchlist; +static Material **switchlist; /// @todo fixme: Never free'd! static int max_numswitches; static int numswitches; #if __JHEXEN__ -void P_InitSwitchList(void) +void P_InitSwitchList() { - int i, index; - ddstring_t path; - Uri* uri = Uri_New(); - Uri_SetScheme(uri, "Textures"); + Uri *uri = Uri_NewWithPath2("Textures:", RC_NULL); - Str_Init(&path); + AutoStr *path = AutoStr_NewStd(); - for(index = 0, i = 0; ; ++i) + int index = 0; + for(int i = 0; ; ++i) { if(index+1 >= max_numswitches) { - switchlist = realloc(switchlist, sizeof(*switchlist) * + switchlist = (Material **) M_Realloc(switchlist, sizeof(*switchlist) * (max_numswitches = max_numswitches ? max_numswitches*2 : 8)); } if(!switchInfo[i].soundID) break; - Str_PercentEncode(Str_StripRight(Str_Set(&path, switchInfo[i].name1))); - Uri_SetPath(uri, Str_Text(&path)); - switchlist[index++] = P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); + Str_PercentEncode(Str_StripRight(Str_Set(path, switchInfo[i].name1))); + Uri_SetPath(uri, Str_Text(path)); + switchlist[index++] = (Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); - Str_PercentEncode(Str_StripRight(Str_Set(&path, switchInfo[i].name2))); - Uri_SetPath(uri, Str_Text(&path)); - switchlist[index++] = P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); + Str_PercentEncode(Str_StripRight(Str_Set(path, switchInfo[i].name2))); + Uri_SetPath(uri, Str_Text(path)); + switchlist[index++] = (Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); } - Str_Free(&path); Uri_Delete(uri); numswitches = index / 2; @@ -194,13 +182,13 @@ void P_InitSwitchList(void) * * @todo Implement a better method for creating new switches. */ -void P_InitSwitchList(void) +void P_InitSwitchList() { int i, index, episode; lumpnum_t lumpNum = W_CheckLumpNumForName("SWITCHES"); - switchlist_t* sList = switchInfo; + switchlist_t *sList = switchInfo; ddstring_t path; - Uri* uri; + Uri *uri; # if __JHERETIC__ if(gameMode == heretic_shareware) @@ -237,7 +225,7 @@ void P_InitSwitchList(void) { if(index+1 >= max_numswitches) { - switchlist = realloc(switchlist, sizeof(*switchlist) * (max_numswitches = max_numswitches ? max_numswitches*2 : 8)); + switchlist = (Material **) M_Realloc(switchlist, sizeof(*switchlist) * (max_numswitches = max_numswitches ? max_numswitches*2 : 8)); } if(SHORT(sList[i].episode) <= episode) @@ -246,11 +234,11 @@ void P_InitSwitchList(void) Str_PercentEncode(Str_StripRight(Str_Set(&path, sList[i].name1))); Uri_SetPath(uri, Str_Text(&path)); - switchlist[index++] = P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); + switchlist[index++] = (Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); Str_PercentEncode(Str_StripRight(Str_Set(&path, sList[i].name2))); Uri_SetPath(uri, Str_Text(&path)); - switchlist[index++] = P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); + switchlist[index++] = (Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); App_Log(lumpNum >= 0? DE2_RES_VERBOSE : DE2_RES_XVERBOSE, " %d: Epi:%d A:\"%s\" B:\"%s\"", i, SHORT(sList[i].episode), @@ -269,12 +257,11 @@ void P_InitSwitchList(void) } #endif -static Material* findSwitch(Material* mat, const switchlist_t** info) +static Material* findSwitch(Material *mat, const switchlist_t** info) { - int i; - if(!mat) return NULL; + if(!mat) return 0; - for(i = 0; i < numswitches * 2; ++i) + for(int i = 0; i < numswitches * 2; ++i) { if(switchlist[i] == mat) { @@ -286,53 +273,51 @@ static Material* findSwitch(Material* mat, const switchlist_t** info) } } - return NULL; + return 0; } void T_MaterialChanger(void *materialChangerThinker) { - materialchanger_t* mchanger = materialChangerThinker; + materialchanger_t *mchanger = (materialchanger_t *)materialChangerThinker; if(!(--mchanger->timer)) { - const int sectionFlags = DMU_FLAG_FOR_SIDESECTION(mchanger->section); + int const sectionFlags = DMU_FLAG_FOR_SIDESECTION(mchanger->section); P_SetPtrp(mchanger->side, sectionFlags | DMU_MATERIAL, mchanger->material); #if __JDOOM__ || __JDOOM64__ - S_SectorSound(P_GetPtrp(mchanger->side, DMU_SECTOR), SFX_SWTCHN); + S_SectorSound((Sector *)P_GetPtrp(mchanger->side, DMU_SECTOR), SFX_SWTCHN); #elif __JHERETIC__ - S_SectorSound(P_GetPtrp(mchanger->side, DMU_SECTOR), SFX_SWITCH); + S_SectorSound((Sector *)P_GetPtrp(mchanger->side, DMU_SECTOR), SFX_SWITCH); #endif Thinker_Remove(&mchanger->thinker); } } -static void spawnMaterialChanger(Side* side, SideSection section, - Material* mat, int tics) +static void spawnMaterialChanger(Side *side, SideSection section, Material *mat, int tics) { - materialchanger_t* mchanger; - - mchanger = Z_Calloc(sizeof(*mchanger), PU_MAP, 0); + materialchanger_t *mchanger = (materialchanger_t *)Z_Calloc(sizeof(*mchanger), PU_MAP, 0); mchanger->thinker.function = T_MaterialChanger; Thinker_Add(&mchanger->thinker); - mchanger->side = side; - mchanger->section = section; + mchanger->side = side; + mchanger->section = section; mchanger->material = mat; - mchanger->timer = tics; + mchanger->timer = tics; } -typedef struct { - Side* side; +struct findmaterialchangerparams_t +{ + Side *side; SideSection section; -} findmaterialchangerparams_t; +}; -static int findMaterialChanger(thinker_t* th, void* parameters) +static int findMaterialChanger(thinker_t *th, void *context) { - materialchanger_t* mchanger = (materialchanger_t*) th; - findmaterialchangerparams_t* params = (findmaterialchangerparams_t*) parameters; + materialchanger_t *mchanger = (materialchanger_t *) th; + findmaterialchangerparams_t *params = (findmaterialchangerparams_t *) context; if(mchanger->side == params->side && mchanger->section == params->section) @@ -341,22 +326,20 @@ static int findMaterialChanger(thinker_t* th, void* parameters) return false; // Keep looking. } -static void startButton(Side* side, SideSection section, - Material* mat, int tics) +static void startButton(Side *side, SideSection section, Material *mat, int tics) { - findmaterialchangerparams_t params; - - params.side = side; - params.section = section; + findmaterialchangerparams_t parm; + parm.side = side; + parm.section = section; // See if a material change has already been queued. - if(Thinker_Iterate(T_MaterialChanger, findMaterialChanger, ¶ms)) - return; - - spawnMaterialChanger(side, section, mat, tics); + if(!Thinker_Iterate(T_MaterialChanger, findMaterialChanger, &parm)) + { + spawnMaterialChanger(side, section, mat, tics); + } } -static int chooseDefaultSound(switchlist_t const* info) +static int chooseDefaultSound(switchlist_t const *info) { /// @todo Get these defaults from switchinfo. #if __JHEXEN__ @@ -368,17 +351,13 @@ static int chooseDefaultSound(switchlist_t const* info) #endif } -dd_bool P_ToggleSwitch2(Side* side, SideSection section, int sound, - dd_bool silent, int tics) +dd_bool P_ToggleSwitch2(Side *side, SideSection section, int sound, dd_bool silent, int tics) { - const int sectionFlags = DMU_FLAG_FOR_SIDESECTION(section); - Material* mat, *current; - const switchlist_t* info; - - current = P_GetPtrp(side, sectionFlags | DMU_MATERIAL); + int const sectionFlags = DMU_FLAG_FOR_SIDESECTION(section); + Material *current = (Material *)P_GetPtrp(side, sectionFlags | DMU_MATERIAL); - mat = findSwitch(current, &info); - if(mat) + switchlist_t const *info; + if(Material *mat = findSwitch(current, &info)) { if(!silent) { @@ -387,7 +366,7 @@ dd_bool P_ToggleSwitch2(Side* side, SideSection section, int sound, sound = chooseDefaultSound(info); } - S_SectorSound(P_GetPtrp(side, DMU_SECTOR), sound); + S_SectorSound((Sector *)P_GetPtrp(side, DMU_SECTOR), sound); } P_SetPtrp(side, sectionFlags | DMU_MATERIAL, mat); @@ -405,7 +384,7 @@ dd_bool P_ToggleSwitch2(Side* side, SideSection section, int sound, return false; } -dd_bool P_ToggleSwitch(Side* side, int sound, dd_bool silent, int tics) +dd_bool P_ToggleSwitch(Side *side, int sound, dd_bool silent, int tics) { if(P_ToggleSwitch2(side, SS_TOP, sound, silent, tics)) return true; @@ -420,7 +399,7 @@ dd_bool P_ToggleSwitch(Side* side, int sound, dd_bool silent, int tics) } #if __JDOOM__ || __JDOOM64__ || __JHERETIC__ -dd_bool P_UseSpecialLine(mobj_t* activator, Line* line, int side) +dd_bool P_UseSpecialLine(mobj_t *activator, Line *line, int side) { // Extended functionality overrides old. if(XL_UseLine(line, side, activator)) From a015765d3983a060789ccb1c9a352b80a000053c Mon Sep 17 00:00:00 2001 From: danij Date: Wed, 29 Jan 2014 16:48:43 +0000 Subject: [PATCH 006/106] Refactor|libhexen: Switched p_pillar.c and p_waggle.c to C++ --- doomsday/plugins/hexen/hexen.pro | 4 +- doomsday/plugins/hexen/include/p_pillar.h | 46 +++--- doomsday/plugins/hexen/include/p_waggle.h | 40 +++-- .../hexen/src/{p_pillar.c => p_pillar.cpp} | 116 ++++++-------- doomsday/plugins/hexen/src/p_waggle.c | 142 ------------------ doomsday/plugins/hexen/src/p_waggle.cpp | 115 ++++++++++++++ 6 files changed, 201 insertions(+), 262 deletions(-) rename doomsday/plugins/hexen/src/{p_pillar.c => p_pillar.cpp} (59%) delete mode 100644 doomsday/plugins/hexen/src/p_waggle.c create mode 100644 doomsday/plugins/hexen/src/p_waggle.cpp diff --git a/doomsday/plugins/hexen/hexen.pro b/doomsday/plugins/hexen/hexen.pro index b4ba3db222..a0da71a23f 100644 --- a/doomsday/plugins/hexen/hexen.pro +++ b/doomsday/plugins/hexen/hexen.pro @@ -89,13 +89,13 @@ SOURCES += \ src/p_mapinfo.cpp \ src/p_maputl.c \ src/p_mobj.c \ - src/p_pillar.c \ + src/p_pillar.cpp \ src/p_pspr.c \ src/p_setup.c \ src/p_spec.c \ src/p_telept.c \ src/p_things.c \ - src/p_waggle.c \ + src/p_waggle.cpp \ src/sn_sonix.cpp \ src/st_stuff.c \ src/tables.c \ diff --git a/doomsday/plugins/hexen/include/p_pillar.h b/doomsday/plugins/hexen/include/p_pillar.h index 319520fc47..0749bdefeb 100644 --- a/doomsday/plugins/hexen/include/p_pillar.h +++ b/doomsday/plugins/hexen/include/p_pillar.h @@ -1,26 +1,22 @@ -/**\file p_pillar.h - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_pillar.h * - *\author Copyright © 2004-2013 Jaakko Keränen - *\author Copyright © 2005-2013 Daniel Swanson - *\author Copyright © 1999 Activision + * @authors Copyright © 2004-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 1999 Activision * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifndef LIBHEXEN_P_PILLAR_H @@ -32,7 +28,7 @@ typedef struct { thinker_t thinker; - Sector* sector; + Sector *sector; float ceilingSpeed; float floorSpeed; coord_t floorDest; @@ -45,9 +41,11 @@ typedef struct { extern "C" { #endif -void T_BuildPillar(pillar_t* pillar); -int EV_BuildPillar(Line* line, byte* args, dd_bool crush); -int EV_OpenPillar(Line* line, byte* args); +void T_BuildPillar(pillar_t *pillar); + +int EV_BuildPillar(Line *line, byte *args, dd_bool crush); + +int EV_OpenPillar(Line *line, byte *args); #ifdef __cplusplus } // extern "C" diff --git a/doomsday/plugins/hexen/include/p_waggle.h b/doomsday/plugins/hexen/include/p_waggle.h index 7388f7dfe2..2cc6e28554 100644 --- a/doomsday/plugins/hexen/include/p_waggle.h +++ b/doomsday/plugins/hexen/include/p_waggle.h @@ -1,26 +1,22 @@ -/**\file p_waggle.h - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_waggle.h * - *\author Copyright © 2004-2013 Jaakko Keränen - *\author Copyright © 2005-2013 Daniel Swanson - *\author Copyright © 1999 Activision + * @authors Copyright © 2004-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 1999 Activision * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifndef LIBHEXEN_P_WAGGLE_H @@ -38,7 +34,7 @@ typedef enum { typedef struct { thinker_t thinker; - Sector* sector; + Sector *sector; coord_t originalHeight; coord_t accumulator; coord_t accDelta; @@ -53,7 +49,7 @@ typedef struct { extern "C" { #endif -void T_FloorWaggle(waggle_t* waggle); +void T_FloorWaggle(waggle_t *waggle); dd_bool EV_StartFloorWaggle(int tag, int height, int speed, int offset, int timer); #ifdef __cplusplus diff --git a/doomsday/plugins/hexen/src/p_pillar.c b/doomsday/plugins/hexen/src/p_pillar.cpp similarity index 59% rename from doomsday/plugins/hexen/src/p_pillar.c rename to doomsday/plugins/hexen/src/p_pillar.cpp index 6fe3a92a4f..06b7de1ba4 100644 --- a/doomsday/plugins/hexen/src/p_pillar.c +++ b/doomsday/plugins/hexen/src/p_pillar.cpp @@ -1,99 +1,71 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_pillar.cpp * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2006-2013 Daniel Swanson - *\author Copyright © 1999 Activision + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2006-2013 Daniel Swanson + * @authors Copyright © 1999 Activision * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * p_pillar.c: + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -// HEADER FILES ------------------------------------------------------------ - #include "jhexen.h" +#include "p_pillar.h" #include "dmu_lib.h" #include "p_mapspec.h" #include "p_iterlist.h" -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -// CODE -------------------------------------------------------------------- - void T_BuildPillar(pillar_t *pillar) { - result_e res1; - result_e res2; + DENG_ASSERT(pillar != 0); // First, raise the floor - res1 = T_MovePlane(pillar->sector, pillar->floorSpeed, pillar->floorDest, pillar->crush, 0, pillar->direction); // floorOrCeiling, direction + result_e res1 = T_MovePlane(pillar->sector, pillar->floorSpeed, pillar->floorDest, pillar->crush, 0, pillar->direction); // floorOrCeiling, direction // Then, lower the ceiling - res2 = T_MovePlane(pillar->sector, pillar->ceilingSpeed, pillar->ceilingDest, pillar->crush, 1, -pillar->direction); + result_e res2 = T_MovePlane(pillar->sector, pillar->ceilingSpeed, pillar->ceilingDest, pillar->crush, 1, -pillar->direction); if(res1 == pastdest && res2 == pastdest) { - P_ToXSector(pillar->sector)->specialData = NULL; + P_ToXSector(pillar->sector)->specialData = 0; SN_StopSequenceInSec(pillar->sector); P_ACScriptTagFinished(P_ToXSector(pillar->sector)->tag); Thinker_Remove(&pillar->thinker); } } -int EV_BuildPillar(Line* line, byte* args, dd_bool crush) +int EV_BuildPillar(Line *line, byte *args, dd_bool crush) { - int rtn = 0; - coord_t newHeight; - Sector* sec = NULL; - pillar_t* pillar; - iterlist_t* list; + iterlist_t *list = P_GetSectorIterListForTag((int) args[0], false); + if(!list) return 0; - list = P_GetSectorIterListForTag((int) args[0], false); - if(!list) return rtn; + int rtn = 0; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) { + // If already moving keep going... if(P_ToXSector(sec)->specialData) - continue; // Already moving, so keep going. + continue; if(FEQUAL(P_GetDoublep(sec, DMU_FLOOR_HEIGHT), P_GetDoublep(sec, DMU_CEILING_HEIGHT))) continue; // Pillar is already closed. rtn = 1; + coord_t newHeight = 0; if(!args[2]) { newHeight = P_GetDoublep(sec, DMU_FLOOR_HEIGHT) + @@ -105,7 +77,7 @@ int EV_BuildPillar(Line* line, byte* args, dd_bool crush) newHeight = P_GetDoublep(sec, DMU_FLOOR_HEIGHT) + (coord_t) args[2]; } - pillar = Z_Calloc(sizeof(*pillar), PU_MAP, 0); + pillar_t *pillar = (pillar_t *)Z_Calloc(sizeof(*pillar), PU_MAP, 0); pillar->thinker.function = (thinkfunc_t) T_BuildPillar; Thinker_Add(&pillar->thinker); @@ -137,28 +109,28 @@ int EV_BuildPillar(Line* line, byte* args, dd_bool crush) pillar->ceilingDest = newHeight; pillar->direction = 1; pillar->crush = crush * (int) args[3]; - SN_StartSequence(P_GetPtrp(pillar->sector, DMU_EMITTER), + SN_StartSequence((mobj_t *)P_GetPtrp(pillar->sector, DMU_EMITTER), SEQ_PLATFORM + P_ToXSector(pillar->sector)->seqType); } return rtn; } -int EV_OpenPillar(Line* line, byte* args) +int EV_OpenPillar(Line *line, byte *args) { - int rtn = 0; - Sector* sec = NULL; - pillar_t* pillar; - iterlist_t* list; + iterlist_t *list = P_GetSectorIterListForTag((int) args[0], false); + if(!list) return 0; - list = P_GetSectorIterListForTag((int) args[0], false); - if(!list) return rtn; + int rtn = 0; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) { + // If already moving keep going... if(P_ToXSector(sec)->specialData) - continue; // Already moving, so keep going... + continue; if(!FEQUAL(P_GetDoublep(sec, DMU_FLOOR_HEIGHT), P_GetDoublep(sec, DMU_CEILING_HEIGHT))) @@ -166,7 +138,7 @@ int EV_OpenPillar(Line* line, byte* args) rtn = 1; - pillar = Z_Calloc(sizeof(*pillar), PU_MAP, 0); + pillar_t *pillar = (pillar_t *)Z_Calloc(sizeof(*pillar), PU_MAP, 0); pillar->thinker.function = (thinkfunc_t) T_BuildPillar; Thinker_Add(&pillar->thinker); @@ -210,7 +182,7 @@ int EV_OpenPillar(Line* line, byte* args) } pillar->direction = -1; // Open the pillar. - SN_StartSequence(P_GetPtrp(pillar->sector, DMU_EMITTER), + SN_StartSequence((mobj_t *)P_GetPtrp(pillar->sector, DMU_EMITTER), SEQ_PLATFORM + P_ToXSector(pillar->sector)->seqType); } diff --git a/doomsday/plugins/hexen/src/p_waggle.c b/doomsday/plugins/hexen/src/p_waggle.c deleted file mode 100644 index a3eb8fb422..0000000000 --- a/doomsday/plugins/hexen/src/p_waggle.c +++ /dev/null @@ -1,142 +0,0 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html - * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2006-2013 Daniel Swanson - *\author Copyright © 1999 Activision - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * p_waggle.c: - */ - -// HEADER FILES ------------------------------------------------------------ - -#include "jhexen.h" - -#include "dmu_lib.h" -#include "p_map.h" -#include "p_mapspec.h" -#include "p_iterlist.h" - -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -// CODE -------------------------------------------------------------------- - -void T_FloorWaggle(waggle_t* waggle) -{ - coord_t fh; - - switch(waggle->state) - { - default: - case WS_STABLE: - if(waggle->ticker != -1) - { - if(!--waggle->ticker) - { - waggle->state = WS_REDUCE; - } - } - break; - - case WS_EXPAND: - if((waggle->scale += waggle->scaleDelta) >= waggle->targetScale) - { - waggle->scale = waggle->targetScale; - waggle->state = WS_STABLE; - } - break; - - case WS_REDUCE: - if((waggle->scale -= waggle->scaleDelta) <= 0) - { - // Remove. - P_SetDoublep(waggle->sector, DMU_FLOOR_HEIGHT, waggle->originalHeight); - P_ChangeSector(waggle->sector, 1 /*crush damage*/); - P_ToXSector(waggle->sector)->specialData = NULL; - P_ACScriptTagFinished(P_ToXSector(waggle->sector)->tag); - Thinker_Remove(&waggle->thinker); - return; - } - break; - } - - waggle->accumulator += waggle->accDelta; - fh = waggle->originalHeight + - FLOATBOBOFFSET(((int) waggle->accumulator) & 63) * waggle->scale; - P_SetDoublep(waggle->sector, DMU_FLOOR_HEIGHT, fh); - P_SetDoublep(waggle->sector, DMU_FLOOR_TARGET_HEIGHT, fh); - P_SetFloatp(waggle->sector, DMU_FLOOR_SPEED, 0); - P_ChangeSector(waggle->sector, 1 /*crush damage*/); -} - -dd_bool EV_StartFloorWaggle(int tag, int height, int speed, int offset, int timer) -{ - dd_bool retCode = false; - Sector* sec = NULL; - waggle_t* waggle; - iterlist_t* list; - - list = P_GetSectorIterListForTag(tag, false); - if(!list) return retCode; - - IterList_SetIteratorDirection(list, ITERLIST_FORWARD); - IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) - { - if(P_ToXSector(sec)->specialData) - continue; // Already moving, so keep going... - - retCode = true; - - waggle = Z_Calloc(sizeof(*waggle), PU_MAP, 0); - waggle->thinker.function = (thinkfunc_t) T_FloorWaggle; - Thinker_Add(&waggle->thinker); - - P_ToXSector(sec)->specialData = waggle; - waggle->sector = sec; - waggle->originalHeight = P_GetDoublep(sec, DMU_FLOOR_HEIGHT); - waggle->accumulator = offset; - waggle->accDelta = FIX2FLT(speed << 10); - waggle->scale = 0; - waggle->targetScale = FIX2FLT(height << 10); - waggle->scaleDelta = - FIX2FLT(FLT2FIX(waggle->targetScale) / (TICSPERSEC + ((3 * TICSPERSEC) * height) / 255)); - waggle->ticker = timer ? timer * 35 : -1; - waggle->state = WS_EXPAND; - } - - return retCode; -} diff --git a/doomsday/plugins/hexen/src/p_waggle.cpp b/doomsday/plugins/hexen/src/p_waggle.cpp new file mode 100644 index 0000000000..11a1bd5600 --- /dev/null +++ b/doomsday/plugins/hexen/src/p_waggle.cpp @@ -0,0 +1,115 @@ +/** @file p_waggle.cpp + * + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2006-2013 Daniel Swanson + * @authors Copyright © 1999 Activision + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include "jhexen.h" +#include "p_waggle.h" + +#include "dmu_lib.h" +#include "p_map.h" +#include "p_mapspec.h" +#include "p_iterlist.h" + +void T_FloorWaggle(waggle_t *waggle) +{ + DENG_ASSERT(waggle != 0); + + switch(waggle->state) + { + default: + case WS_STABLE: + if(waggle->ticker != -1) + { + if(!--waggle->ticker) + { + waggle->state = WS_REDUCE; + } + } + break; + + case WS_EXPAND: + if((waggle->scale += waggle->scaleDelta) >= waggle->targetScale) + { + waggle->scale = waggle->targetScale; + waggle->state = WS_STABLE; + } + break; + + case WS_REDUCE: + if((waggle->scale -= waggle->scaleDelta) <= 0) + { + // Remove. + P_SetDoublep(waggle->sector, DMU_FLOOR_HEIGHT, waggle->originalHeight); + P_ChangeSector(waggle->sector, 1 /*crush damage*/); + P_ToXSector(waggle->sector)->specialData = NULL; + P_ACScriptTagFinished(P_ToXSector(waggle->sector)->tag); + Thinker_Remove(&waggle->thinker); + return; + } + break; + } + + waggle->accumulator += waggle->accDelta; + coord_t fh = waggle->originalHeight + + FLOATBOBOFFSET(((int) waggle->accumulator) & 63) * waggle->scale; + P_SetDoublep(waggle->sector, DMU_FLOOR_HEIGHT, fh); + P_SetDoublep(waggle->sector, DMU_FLOOR_TARGET_HEIGHT, fh); + P_SetFloatp(waggle->sector, DMU_FLOOR_SPEED, 0); + P_ChangeSector(waggle->sector, 1 /*crush damage*/); +} + +dd_bool EV_StartFloorWaggle(int tag, int height, int speed, int offset, int timer) +{ + iterlist_t *list = P_GetSectorIterListForTag(tag, false); + if(!list) return false; + + dd_bool retCode = false; + + IterList_SetIteratorDirection(list, ITERLIST_FORWARD); + IterList_RewindIterator(list); + + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) + { + if(P_ToXSector(sec)->specialData) + continue; // Already moving, so keep going... + + retCode = true; + + waggle_t *waggle = (waggle_t *)Z_Calloc(sizeof(*waggle), PU_MAP, 0); + waggle->thinker.function = (thinkfunc_t) T_FloorWaggle; + Thinker_Add(&waggle->thinker); + + P_ToXSector(sec)->specialData = waggle; + waggle->sector = sec; + waggle->originalHeight = P_GetDoublep(sec, DMU_FLOOR_HEIGHT); + waggle->accumulator = offset; + waggle->accDelta = FIX2FLT(speed << 10); + waggle->scale = 0; + waggle->targetScale = FIX2FLT(height << 10); + waggle->scaleDelta = + FIX2FLT(FLT2FIX(waggle->targetScale) / + (TICSPERSEC + ((3 * TICSPERSEC) * height) / 255)); + waggle->ticker = timer ? timer * 35 : -1; + waggle->state = WS_EXPAND; + } + + return retCode; +} From 844c07b23fc215ec24e0f75b9ecbeabae50884cf Mon Sep 17 00:00:00 2001 From: danij Date: Wed, 29 Jan 2014 16:49:18 +0000 Subject: [PATCH 007/106] Refactor|libcommon: Switched p_door.c to C++ --- doomsday/plugins/common/common.pri | 2 +- doomsday/plugins/common/include/p_door.h | 67 +++-- .../common/src/{p_door.c => p_door.cpp} | 239 +++++++----------- 3 files changed, 127 insertions(+), 181 deletions(-) rename doomsday/plugins/common/src/{p_door.c => p_door.cpp} (75%) diff --git a/doomsday/plugins/common/common.pri b/doomsday/plugins/common/common.pri index a0730979f8..c1f6018d74 100644 --- a/doomsday/plugins/common/common.pri +++ b/doomsday/plugins/common/common.pri @@ -97,7 +97,7 @@ SOURCES += \ $$common_src/pause.c \ $$common_src/p_actor.cpp \ $$common_src/p_ceiling.cpp \ - $$common_src/p_door.c \ + $$common_src/p_door.cpp \ $$common_src/p_floor.cpp \ $$common_src/p_inventory.c \ $$common_src/p_iterlist.c \ diff --git a/doomsday/plugins/common/include/p_door.h b/doomsday/plugins/common/include/p_door.h index 31ab2e1764..0742d5e81d 100644 --- a/doomsday/plugins/common/include/p_door.h +++ b/doomsday/plugins/common/include/p_door.h @@ -1,38 +1,29 @@ -/**\file p_door.h - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_door.h Vertical door (opening/closing) thinker. * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2005-2013 Daniel Swanson - *\author Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 1999 id Software, Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * Common playsim routines relating to doors. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ #ifndef LIBCOMMON_THINKER_DOOR_H #define LIBCOMMON_THINKER_DOOR_H -#ifdef __cplusplus -extern "C" { -#endif +#define DOORSPEED (2) +#define DOORWAIT (150) typedef enum { DS_DOWN = -1, @@ -67,7 +58,7 @@ typedef enum { typedef struct { thinker_t thinker; doortype_e type; - Sector* sector; + Sector *sector; coord_t topHeight; float speed; doorstate_e state; @@ -75,30 +66,32 @@ typedef struct { int topCountDown; } door_t; -#define DOORSPEED (2) -#define DOORWAIT (150) +#ifdef __cplusplus +extern "C" { +#endif void T_Door(void *doorThinkerPtr); -dd_bool EV_VerticalDoor(Line* li, mobj_t* mo); +dd_bool EV_VerticalDoor(Line *li, mobj_t *mo); #if __JHEXEN__ -int EV_DoDoor(Line* li, byte* args, doortype_e type); +int EV_DoDoor(Line *li, byte *args, doortype_e type); #else -int EV_DoDoor(Line* li, doortype_e type); +int EV_DoDoor(Line *li, doortype_e type); #endif #if __JDOOM__ || __JDOOM64__ -int EV_DoLockedDoor(Line* li, doortype_e type, mobj_t* mo); +int EV_DoLockedDoor(Line *li, doortype_e type, mobj_t *mo); #endif #if __JDOOM__ || __JDOOM64__ || __JHERETIC__ -void P_SpawnDoorCloseIn30(Sector* sec); -void P_SpawnDoorRaiseIn5Mins(Sector* sec); +void P_SpawnDoorCloseIn30(Sector *sec); + +void P_SpawnDoorRaiseIn5Mins(Sector *sec); #endif #if __JDOOM64__ -int EV_AnimateDoor(Line* li, mobj_t* mo); +int EV_AnimateDoor(Line* li, mobj_t *mo); #endif #ifdef __cplusplus diff --git a/doomsday/plugins/common/src/p_door.c b/doomsday/plugins/common/src/p_door.cpp similarity index 75% rename from doomsday/plugins/common/src/p_door.c rename to doomsday/plugins/common/src/p_door.cpp index e4c0885314..0e4e59f94c 100644 --- a/doomsday/plugins/common/src/p_door.c +++ b/doomsday/plugins/common/src/p_door.cpp @@ -1,62 +1,43 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_door.cpp Vertical door (opening/closing) thinker. * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2005-2013 Daniel Swanson - *\author Copyright © 2006 Martin Eyre - *\author Copyright © 2003-2005 Samuel Villarreal - *\author Copyright © 1999 by Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman (PrBoom 2.2.6) - *\author Copyright © 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze (PrBoom 2.2.6) - *\author Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 2006 Martin Eyre + * @authors Copyright © 2003-2005 Samuel Villarreal + * @authors Copyright © 1999 Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman (PrBoom 2.2.6) + * @authors Copyright © 1999-2000 Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze (PrBoom 2.2.6) + * @authors Copyright © 1993-1996 id Software, Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * p_doors.c : Vertical doors (opening/closing). + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -// HEADER FILES ------------------------------------------------------------ - -#include - -#if __JDOOM__ -# include "jdoom.h" -#elif __JDOOM64__ -# include "jdoom64.h" -#elif __JHERETIC__ -# include "jheretic.h" -#elif __JHEXEN__ -# include "jhexen.h" -#endif +#include "common.h" +#include "p_door.h" #include "dmu_lib.h" #include "p_player.h" #include "p_mapspec.h" -#include "p_door.h" #if __JDOOM64__ # include "p_ceiling.h" # include "p_floor.h" # include "p_inventory.h" #endif #include "p_sound.h" - -// MACROS ------------------------------------------------------------------ +#include // Sounds played by the doors when changing state. // jHexen uses sound sequences, so it's are defined as 'SFX_NONE'. @@ -90,29 +71,14 @@ # define SFX_DOORLOCKED (SFX_NONE) #endif -// TYPES ------------------------------------------------------------------- - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -// CODE -------------------------------------------------------------------- - void T_Door(void *doorThinkerPtr) { - door_t* door = doorThinkerPtr; - xsector_t* xsec; - result_e res; + door_t *door = (door_t *)doorThinkerPtr; + DENG_ASSERT(door != 0); - xsec = P_ToXSector(door->sector); + xsector_t *xsec = P_ToXSector(door->sector); + + result_e res; switch(door->state) { @@ -133,23 +99,23 @@ void T_Door(void *doorThinkerPtr) case DT_BLAZERAISE: # endif door->state = DS_DOWN; // Time to go back down. - S_PlaneSound(P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOORBLAZECLOSE); + S_PlaneSound((Plane *)P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOORBLAZECLOSE); break; #endif case DT_NORMAL: door->state = DS_DOWN; // Time to go back down. #if __JHEXEN__ - SN_StartSequence(P_GetPtrp(door->sector, DMU_EMITTER), + SN_StartSequence((mobj_t *)P_GetPtrp(door->sector, DMU_EMITTER), SEQ_DOOR_STONE + xsec->seqType); #else - S_PlaneSound(P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOORCLOSING); + S_PlaneSound((Plane *)P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOORCLOSING); #endif break; case DT_CLOSE30THENOPEN: door->state = DS_UP; #if !__JHEXEN__ - S_PlaneSound(P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOOROPEN); + S_PlaneSound((Plane *)P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOOROPEN); #endif break; @@ -168,7 +134,7 @@ void T_Door(void *doorThinkerPtr) door->state = DS_UP; door->type = DT_NORMAL; #if !__JHEXEN__ - S_PlaneSound(P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOOROPEN); + S_PlaneSound((Plane *)P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOOROPEN); #endif break; @@ -187,14 +153,14 @@ void T_Door(void *doorThinkerPtr) if(res == pastdest) { #if __JHEXEN__ - SN_StopSequence(P_GetPtrp(door->sector, DMU_EMITTER)); + SN_StopSequence((mobj_t *)P_GetPtrp(door->sector, DMU_EMITTER)); #endif switch(door->type) { #if __JDOOM64__ case DT_INSTANTRAISE: //jd64 case DT_INSTANTCLOSE: //jd64 - P_ToXSector(door->sector)->specialData = NULL; + P_ToXSector(door->sector)->specialData = 0; Thinker_Remove(&door->thinker); // Unlink and free. break; #endif @@ -205,25 +171,25 @@ void T_Door(void *doorThinkerPtr) case DT_BLAZERAISE: case DT_BLAZECLOSE: # endif - xsec->specialData = NULL; + xsec->specialData = 0; Thinker_Remove(&door->thinker); // Unlink and free. // DOOMII BUG: // This is what causes blazing doors to produce two closing // sounds as one has already been played when the door starts // to close (above) - S_PlaneSound(P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOORBLAZECLOSE); + S_PlaneSound((Plane *)P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOORBLAZECLOSE); break; #endif case DT_NORMAL: case DT_CLOSE: - xsec->specialData = NULL; + xsec->specialData = 0; #if __JHEXEN__ P_ACScriptTagFinished(P_ToXSector(door->sector)->tag); #endif Thinker_Remove(&door->thinker); // Unlink and free. #if __JHERETIC__ - S_PlaneSound(P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOORCLOSED); + S_PlaneSound((Plane *)P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOORCLOSED); #endif break; @@ -252,7 +218,7 @@ void T_Door(void *doorThinkerPtr) default: door->state = DS_UP; #if !__JHEXEN__ - S_PlaneSound(P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOOROPEN); + S_PlaneSound((Plane *)P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOOROPEN); #endif break; } @@ -267,7 +233,7 @@ void T_Door(void *doorThinkerPtr) if(res == pastdest) { #if __JHEXEN__ - SN_StopSequence(P_GetPtrp(door->sector, DMU_EMITTER)); + SN_StopSequence((mobj_t *)P_GetPtrp(door->sector, DMU_EMITTER)); #endif switch(door->type) { @@ -289,7 +255,7 @@ void T_Door(void *doorThinkerPtr) case DT_BLAZEOPEN: #endif case DT_NORMAL: - door->state = DS_WAIT; // Wait at top. + door->state = DS_WAIT; // Wait at top. door->topCountDown = door->topWait; break; @@ -298,13 +264,13 @@ void T_Door(void *doorThinkerPtr) #endif case DT_CLOSE30THENOPEN: case DT_OPEN: - xsec->specialData = NULL; + xsec->specialData = 0; #if __JHEXEN__ P_ACScriptTagFinished(P_ToXSector(door->sector)->tag); #endif Thinker_Remove(&door->thinker); // Unlink and free. #if __JHERETIC__ - S_StopSound(0, (mobj_t*) P_GetPtrp(door->sector, DMU_CEILING_EMITTER)); + S_StopSound(0, (mobj_t *) P_GetPtrp(door->sector, DMU_CEILING_EMITTER)); #endif break; @@ -321,41 +287,38 @@ void T_Door(void *doorThinkerPtr) static int EV_DoDoor2(int tag, float speed, int topwait, doortype_e type) { - int rtn = 0, sound; - xsector_t *xsec; - Sector *sec = NULL; - door_t *door; - iterlist_t *list; + iterlist_t *list = P_GetSectorIterListForTag(tag, false); + if(!list) return 0; - list = P_GetSectorIterListForTag(tag, false); - if(!list) - return rtn; + int rtn = 0; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec; + while((sec = (Sector *) IterList_MoveIterator(list))) { - xsec = P_ToXSector(sec); + xsector_t *xsec = P_ToXSector(sec); if(xsec->specialData) continue; // new door thinker rtn = 1; - door = Z_Calloc(sizeof(*door), PU_MAP, 0); + door_t *door = (door_t *)Z_Calloc(sizeof(*door), PU_MAP, 0); door->thinker.function = T_Door; Thinker_Add(&door->thinker); xsec->specialData = door; - door->sector = sec; - door->type = type; + door->sector = sec; + door->type = type; door->topWait = topwait; - door->speed = speed; + door->speed = speed; #if __JHEXEN__ - sound = SEQ_DOOR_STONE + P_ToXSector(door->sector)->seqType; + int sound = SEQ_DOOR_STONE + P_ToXSector(door->sector)->seqType; #else - sound = 0; + int sound = 0; #endif switch(type) @@ -422,10 +385,10 @@ static int EV_DoDoor2(int tag, float speed, int topwait, doortype_e type) // Play a sound? #if __JHEXEN__ - SN_StartSequence(P_GetPtrp(door->sector, DMU_EMITTER), sound); + SN_StartSequence((mobj_t *)P_GetPtrp(door->sector, DMU_EMITTER), sound); #else if(sound) - S_PlaneSound(P_GetPtrp(door->sector, DMU_CEILING_PLANE), sound); + S_PlaneSound((Plane *)P_GetPtrp(door->sector, DMU_CEILING_PLANE), sound); #endif } return rtn; @@ -445,7 +408,7 @@ int EV_DoDoor(Line *line, doortype_e type) #endif #if __JDOOM__ || __JDOOM64__ || __JHERETIC__ -static void sendNeedKeyMessage(player_t* p, textenum_t msgTxt, int keyNum) +static void sendNeedKeyMessage(player_t *p, textenum_t msgTxt, int keyNum) { char buf[160], *in, tmp[2]; @@ -567,22 +530,21 @@ static dd_bool tryLockedDoor(Line *line, player_t *p) * message and play a sound before returning @c false. * Else, NOT a locked door and can be opened, return @c true. */ -static dd_bool tryLockedManualDoor(Line* line, mobj_t* mo) +static dd_bool tryLockedManualDoor(Line *line, mobj_t *mo) { - xline_t* xline = P_ToXLine(line); - player_t* p; + xline_t *xline = P_ToXLine(line); #if !__JHEXEN__ - int keyNum = -1; - textenum_t msgTxt = 0; - sfxenum_t sfxNum = 0; + int keyNum = -1; + textenum_t msgTxt = NUMTEXT; + sfxenum_t sfxNum = SFX_NONE; #endif if(!mo || !xline) return false; - p = mo->player; - #if !__JHEXEN__ + player_t *p = mo->player; + switch(xline->special) { case 26: @@ -695,22 +657,16 @@ int EV_DoLockedDoor(Line *line, doortype_e type, mobj_t *thing) /** * Open a door manually, no tag value. */ -dd_bool EV_VerticalDoor(Line* line, mobj_t* mo) +dd_bool EV_VerticalDoor(Line *line, mobj_t *mo) { - xline_t* xline; - xsector_t* xsec; - Sector* sec; - door_t* door; - - sec = P_GetPtrp(line, DMU_BACK_SECTOR); - if(!sec) - return false; + Sector *sec = (Sector *)P_GetPtrp(line, DMU_BACK_SECTOR); + if(!sec) return false; if(!tryLockedManualDoor(line, mo)) return false; // Mobj cannot open this door. - xsec = P_ToXSector(sec); - xline = P_ToXLine(line); + xsector_t *xsec = P_ToXSector(sec); + xline_t *xline = P_ToXLine(line); // If the sector has an active thinker, use it. if(xsec->specialData) @@ -718,7 +674,7 @@ dd_bool EV_VerticalDoor(Line* line, mobj_t* mo) #if __JHEXEN__ return false; #else - door = xsec->specialData; + door_t *door = (door_t *)xsec->specialData; switch(xline->special) { case 1: @@ -752,16 +708,17 @@ dd_bool EV_VerticalDoor(Line* line, mobj_t* mo) } // New door thinker. - door = Z_Calloc(sizeof(*door), PU_MAP, 0); + door_t *door = (door_t *) Z_Calloc(sizeof(*door), PU_MAP, 0); door->thinker.function = T_Door; Thinker_Add(&door->thinker); + xsec->specialData = door; - door->sector = sec; - door->state = DS_UP; + door->sector = sec; + door->state = DS_UP; // Play a sound? #if __JHEXEN__ - SN_StartSequence(P_GetPtrp(door->sector, DMU_EMITTER), + SN_StartSequence((mobj_t *)P_GetPtrp(door->sector, DMU_EMITTER), SEQ_DOOR_STONE + P_ToXSector(door->sector)->seqType); #else switch(xline->special) @@ -775,19 +732,19 @@ dd_bool EV_VerticalDoor(Line* line, mobj_t* mo) case 527: // jd64 # endif // BLAZING DOOR RAISE/OPEN - S_PlaneSound(P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOORBLAZEOPEN); + S_PlaneSound((Plane *)P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOORBLAZEOPEN); break; # endif case 1: case 31: // NORMAL DOOR SOUND - S_PlaneSound(P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOOROPEN); + S_PlaneSound((Plane *)P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOOROPEN); break; default: // LOCKED DOOR SOUND - S_PlaneSound(P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOOROPEN); + S_PlaneSound((Plane *)P_GetPtrp(door->sector, DMU_CEILING_PLANE), SFX_DOOROPEN); break; } #endif @@ -872,41 +829,37 @@ dd_bool EV_VerticalDoor(Line* line, mobj_t* mo) #if __JDOOM__ || __JHERETIC__ || __JDOOM64__ void P_SpawnDoorCloseIn30(Sector *sec) { - door_t *door; - - door = Z_Calloc(sizeof(*door), PU_MAP, 0); + door_t *door = (door_t *)Z_Calloc(sizeof(*door), PU_MAP, 0); door->thinker.function = T_Door; Thinker_Add(&door->thinker); P_ToXSector(sec)->specialData = door; P_ToXSector(sec)->special = 0; - door->sector = sec; - door->state = DS_WAIT; - door->type = DT_NORMAL; - door->speed = DOORSPEED; + door->sector = sec; + door->state = DS_WAIT; + door->type = DT_NORMAL; + door->speed = DOORSPEED; door->topCountDown = 30 * TICSPERSEC; - door->topHeight = P_GetDoublep(sec, DMU_CEILING_HEIGHT); + door->topHeight = P_GetDoublep(sec, DMU_CEILING_HEIGHT); } void P_SpawnDoorRaiseIn5Mins(Sector *sec) { - door_t *door; - - door = Z_Calloc(sizeof(*door), PU_MAP, 0); + door_t *door = (door_t *)Z_Calloc(sizeof(*door), PU_MAP, 0); door->thinker.function = T_Door; Thinker_Add(&door->thinker); P_ToXSector(sec)->specialData = door; P_ToXSector(sec)->special = 0; - door->sector = sec; - door->state = DS_INITIALWAIT; - door->type = DT_RAISEIN5MINS; - door->speed = DOORSPEED; + door->sector = sec; + door->state = DS_INITIALWAIT; + door->type = DT_RAISEIN5MINS; + door->speed = DOORSPEED; P_FindSectorSurroundingLowestCeiling(sec, (coord_t) MAXINT, &door->topHeight); - door->topHeight -= 4; - door->topWait = DOORWAIT; + door->topHeight -= 4; + door->topWait = DOORWAIT; door->topCountDown = 5 * 60 * TICSPERSEC; } #endif From c23425fe6ae735b4a50fcb3d2cc128d7fea28ef8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Wed, 29 Jan 2014 19:21:09 +0200 Subject: [PATCH 008/106] Fixed|UI|Log: Update filter after reseting to defaults IssueID #1722 --- doomsday/client/src/ui/dialogs/logsettingsdialog.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doomsday/client/src/ui/dialogs/logsettingsdialog.cpp b/doomsday/client/src/ui/dialogs/logsettingsdialog.cpp index 57b3ce3225..96e0c0ef78 100644 --- a/doomsday/client/src/ui/dialogs/logsettingsdialog.cpp +++ b/doomsday/client/src/ui/dialogs/logsettingsdialog.cpp @@ -204,8 +204,12 @@ DENG2_PIMPL(LogSettingsDialog) { overrideWithGeneric(); } - // Re-read from Config, which has been changed via the widgets. + applyFilterFromConfig(); + } + + void applyFilterFromConfig() + { App::logFilter().read(App::config().names().subrecord("log.filter")); } }; @@ -249,6 +253,8 @@ LogSettingsDialog::LogSettingsDialog(String const &name) void LogSettingsDialog::resetToDefaults() { ClientApp::logSettings().resetToDefaults(); + + d->applyFilterFromConfig(); } void LogSettingsDialog::updateLogFilter() From 8834b4a6a26d43f230de42c4a8542b157fda9867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Wed, 29 Jan 2014 19:37:33 +0200 Subject: [PATCH 009/106] OS X|Fixed|libgui: Use Qt fonts in the 10.6 Snow Leopard build The Core Graphics API is not available in 10.6. --- doomsday/libgui/src/font.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doomsday/libgui/src/font.cpp b/doomsday/libgui/src/font.cpp index 019689e5ba..8b3394c646 100644 --- a/doomsday/libgui/src/font.cpp +++ b/doomsday/libgui/src/font.cpp @@ -24,7 +24,7 @@ #include #include -#ifdef MACOSX +#if defined(MACOSX) && defined(MACOS_10_7) # include "coretextnativefont_macx.h" namespace de { typedef CoreTextNativeFont PlatformFont; } #else From 7ec77ab0abd8bfe5eff2d79da1f4ec59c11c573c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Wed, 29 Jan 2014 21:10:32 +0200 Subject: [PATCH 010/106] UI|Task Bar: Show the MP menu when connected to a server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Multiplayer menu has its own class. The task bar’s layout is now updated using a SequentialLayout which makes it easier to manage dynamically changing content. --- doomsday/client/client.pro | 2 + doomsday/client/include/network/serverlink.h | 3 + .../ui/widgets/multiplayermenuwidget.h | 38 ++++++ .../client/include/ui/widgets/taskbarwidget.h | 1 + doomsday/client/src/network/serverlink.cpp | 4 + .../src/ui/widgets/multiplayermenuwidget.cpp | 50 ++++++++ .../client/src/ui/widgets/taskbarwidget.cpp | 110 ++++++++++++------ doomsday/libappfw/src/widgets/popupwidget.cpp | 1 + 8 files changed, 171 insertions(+), 38 deletions(-) create mode 100644 doomsday/client/include/ui/widgets/multiplayermenuwidget.h create mode 100644 doomsday/client/src/ui/widgets/multiplayermenuwidget.cpp diff --git a/doomsday/client/client.pro b/doomsday/client/client.pro index b394b49d7d..f504c2280c 100644 --- a/doomsday/client/client.pro +++ b/doomsday/client/client.pro @@ -396,6 +396,7 @@ DENG_HEADERS += \ include/ui/widgets/gamewidget.h \ include/ui/widgets/icvarwidget.h \ include/ui/widgets/keygrabberwidget.h \ + include/ui/widgets/multiplayermenuwidget.h \ include/ui/widgets/profilepickerwidget.h \ include/ui/widgets/taskbarwidget.h \ include/ui/fi_main.h \ @@ -730,6 +731,7 @@ SOURCES += \ src/ui/widgets/gamewidget.cpp \ src/ui/widgets/gameuiwidget.cpp \ src/ui/widgets/keygrabberwidget.cpp \ + src/ui/widgets/multiplayermenuwidget.cpp \ src/ui/widgets/profilepickerwidget.cpp \ src/ui/widgets/taskbarwidget.cpp \ src/ui/windowsystem.cpp \ diff --git a/doomsday/client/include/network/serverlink.h b/doomsday/client/include/network/serverlink.h index 3e01ebdea0..9202d3896d 100644 --- a/doomsday/client/include/network/serverlink.h +++ b/doomsday/client/include/network/serverlink.h @@ -37,6 +37,9 @@ class ServerLink : public de::shell::AbstractLink public: DENG2_DEFINE_AUDIENCE(DiscoveryUpdate, void linkDiscoveryUpdate(ServerLink const &link)) + DENG2_DEFINE_AUDIENCE(Join, void networkGameJoined()) + DENG2_DEFINE_AUDIENCE(Leave, void networkGameLeft()) + public: ServerLink(); diff --git a/doomsday/client/include/ui/widgets/multiplayermenuwidget.h b/doomsday/client/include/ui/widgets/multiplayermenuwidget.h new file mode 100644 index 0000000000..93a22f9ecb --- /dev/null +++ b/doomsday/client/include/ui/widgets/multiplayermenuwidget.h @@ -0,0 +1,38 @@ +/** @file multiplayermenuwidget.h + * + * @authors Copyright (c) 2014 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, see: + * http://www.gnu.org/licenses + */ + +#ifndef DENG_CLIENT_MULTIPLAYERMENUWIDGET_H +#define DENG_CLIENT_MULTIPLAYERMENUWIDGET_H + +#include + +/** + * Popup menu that appears in the task bar when joined to a multiplayer game. + * + * @ingroup ui + */ +class MultiplayerMenuWidget : public de::PopupMenuWidget +{ +public: + MultiplayerMenuWidget(); + +private: + DENG2_PRIVATE(d) +}; + +#endif // DENG_CLIENT_MULTIPLAYERMENUWIDGET_H diff --git a/doomsday/client/include/ui/widgets/taskbarwidget.h b/doomsday/client/include/ui/widgets/taskbarwidget.h index 7b89e633b9..d5d264e8f7 100644 --- a/doomsday/client/include/ui/widgets/taskbarwidget.h +++ b/doomsday/client/include/ui/widgets/taskbarwidget.h @@ -59,6 +59,7 @@ public slots: void closeConfigMenu(); void openMainMenu(); void closeMainMenu(); + void openMultiplayerMenu(); void unloadGame(); void showAbout(); void showUpdaterSettings(); diff --git a/doomsday/client/src/network/serverlink.cpp b/doomsday/client/src/network/serverlink.cpp index f95cb1b8a1..59283e0bcd 100644 --- a/doomsday/client/src/network/serverlink.cpp +++ b/doomsday/client/src/network/serverlink.cpp @@ -157,6 +157,8 @@ DENG2_PIMPL(ServerLink) // Call game's NetConnect. gx.NetConnect(false); + DENG2_FOR_PUBLIC_AUDIENCE(Join, i) i->networkGameJoined(); + // G'day mate! The client is responsible for beginning the // handshake. Cl_SendHello(); @@ -240,6 +242,8 @@ void ServerLink::disconnect() if(gx.NetDisconnect) gx.NetDisconnect(true); + DENG2_FOR_AUDIENCE(Leave, i) i->networkGameLeft(); + LOG_NET_NOTE("Link to server %s disconnected") << address(); AbstractLink::disconnect(); diff --git a/doomsday/client/src/ui/widgets/multiplayermenuwidget.cpp b/doomsday/client/src/ui/widgets/multiplayermenuwidget.cpp new file mode 100644 index 0000000000..54494192aa --- /dev/null +++ b/doomsday/client/src/ui/widgets/multiplayermenuwidget.cpp @@ -0,0 +1,50 @@ +/** @file multiplayermenuwidget.cpp + * + * @authors Copyright (c) 2014 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, see: + * http://www.gnu.org/licenses + */ + +#include "ui/widgets/multiplayermenuwidget.h" +#include "network/serverlink.h" +#include "CommandAction" + +#include + +using namespace de; + +DENG_GUI_PIMPL(MultiplayerMenuWidget) +, DENG2_OBSERVES(ServerLink, Join) +, DENG2_OBSERVES(ServerLink, Leave) +{ + Instance(Public *i) : Base(i) + {} + + void networkGameJoined() + { + + } + + void networkGameLeft() + { + + } +}; + +MultiplayerMenuWidget::MultiplayerMenuWidget() + : PopupMenuWidget("multiplayer-menu"), d(new Instance(this)) +{ + items() + << new ui::ActionItem(tr("Disconnect"), new CommandAction("net disconnect")); +} diff --git a/doomsday/client/src/ui/widgets/taskbarwidget.cpp b/doomsday/client/src/ui/widgets/taskbarwidget.cpp index 47f2542ca2..84c03dcc6f 100644 --- a/doomsday/client/src/ui/widgets/taskbarwidget.cpp +++ b/doomsday/client/src/ui/widgets/taskbarwidget.cpp @@ -18,6 +18,7 @@ #include "ui/widgets/taskbarwidget.h" #include "ui/widgets/consolecommandwidget.h" +#include "ui/widgets/multiplayermenuwidget.h" #include "ui/dialogs/aboutdialog.h" #include "ui/dialogs/videosettingsdialog.h" #include "ui/dialogs/audiosettingsdialog.h" @@ -29,13 +30,13 @@ #include "updater/updatersettingsdialog.h" #include "ui/clientwindow.h" #include "ui/clientrootwidget.h" +#include "clientapp.h" #include "CommandAction" #include "client/cl_def.h" // clientPaused #include "ui/ui_main.h" #include "con_main.h" -#include #include #include #include @@ -71,6 +72,8 @@ enum MenuItemPositions DENG_GUI_PIMPL(TaskBarWidget) , DENG2_OBSERVES(App, GameChange) +, DENG2_OBSERVES(ServerLink, Join) +, DENG2_OBSERVES(ServerLink, Leave) { typedef DefaultVertexBuf VertexBuf; @@ -86,9 +89,11 @@ DENG_GUI_PIMPL(TaskBarWidget) ConsoleWidget *console; ButtonWidget *logo; ButtonWidget *conf; + ButtonWidget *multi; LabelWidget *status; PopupMenuWidget *mainMenu; PopupMenuWidget *configMenu; + MultiplayerMenuWidget *multiMenu; ScalarRule *vertShift; bool mouseWasTrappedWhenOpening; @@ -102,17 +107,18 @@ DENG_GUI_PIMPL(TaskBarWidget) Matrix4f projMatrix; Instance(Public *i) - : Base(i), - layoutMode(NormalLayout), - opened(true), - logo(0), - conf(0), - status(0), - mainMenu(0), - configMenu(0), - mouseWasTrappedWhenOpening(false), - uMvpMatrix("uMvpMatrix", GLUniform::Mat4), - uColor ("uColor", GLUniform::Vec4) + : Base(i) + , layoutMode(NormalLayout) + , opened(true) + , logo(0) + , conf(0) + , status(0) + , mainMenu(0) + , configMenu(0) + , multiMenu(0) + , mouseWasTrappedWhenOpening(false) + , uMvpMatrix("uMvpMatrix", GLUniform::Mat4) + , uColor ("uColor", GLUniform::Vec4) { uColor = Vector4f(1, 1, 1, 1); self.set(Background(style().colors().colorf("background"))); @@ -120,6 +126,8 @@ DENG_GUI_PIMPL(TaskBarWidget) vertShift = new ScalarRule(0); App::app().audienceForGameChange += this; + ClientApp::serverLink().audienceForJoin += this; + ClientApp::serverLink().audienceForLeave += this; updateStyle(); } @@ -127,6 +135,9 @@ DENG_GUI_PIMPL(TaskBarWidget) ~Instance() { App::app().audienceForGameChange -= this; + ClientApp::serverLink().audienceForJoin -= this; + ClientApp::serverLink().audienceForLeave -= this; + releaseRef(vertShift); } @@ -258,6 +269,18 @@ DENG_GUI_PIMPL(TaskBarWidget) mainMenu->menu().updateLayout(); // Include/exclude shown/hidden menu items. } + void networkGameJoined() + { + multi->show(); + self.updateCommandLineLayout(); + } + + void networkGameLeft() + { + multi->hide(); + self.updateCommandLineLayout(); + } + void updateStatus() { if(App_GameLoaded()) @@ -312,10 +335,7 @@ TaskBarWidget::TaskBarWidget() : GuiWidget("taskbar"), d(new Instance(this)) d->logo->setWidthPolicy(ui::Expand); d->logo->setTextAlignment(AlignLeft); - d->logo->rule() - .setInput(Rule::Height, rule().height()) - .setInput(Rule::Right, rule().right()) - .setInput(Rule::Bottom, rule().bottom()); + d->logo->rule().setInput(Rule::Height, rule().height()); add(d->logo); // Settings. @@ -323,33 +343,42 @@ TaskBarWidget::TaskBarWidget() : GuiWidget("taskbar"), d(new Instance(this)) d->conf = conf; conf->setImage(style().images().image("gear")); conf->setSizePolicy(ui::Expand, ui::Filled); - conf->rule() - .setInput(Rule::Height, rule().height()) - .setInput(Rule::Right, d->logo->rule().left()) - .setInput(Rule::Bottom, rule().bottom()); + conf->rule().setInput(Rule::Height, rule().height()); add(conf); // Currently loaded game. d->status = new LabelWidget; d->status->set(bg); d->status->setWidthPolicy(ui::Expand); - d->status->rule() - .setInput(Rule::Height, rule().height()) - .setInput(Rule::Bottom, rule().bottom()) - .setInput(Rule::Right, conf->rule().left()); + d->status->rule().setInput(Rule::Height, rule().height()); add(d->status); d->updateStatus(); + // Multiplayer. + d->multi = new ButtonWidget; + d->multi->hide(); // hidden when not connected + d->multi->setAction(new SignalAction(this, SLOT(openMultiplayerMenu()))); + d->multi->setImage(style().images().image("network")); + d->multi->setTextAlignment(ui::AlignRight); + d->multi->setText(tr("MP")); + d->multi->setSizePolicy(ui::Expand, ui::Filled); + d->multi->rule().setInput(Rule::Height, rule().height()); + add(d->multi); + // Taskbar height depends on the font size. rule().setInput(Rule::Height, style().fonts().font("default").height() + gap * 2); // Settings menu. - d->configMenu = new PopupMenuWidget("conf-menu"); + add(d->configMenu = new PopupMenuWidget("conf-menu")); d->configMenu->setAnchorAndOpeningDirection(conf->rule(), ui::Up); + // Multiplayer menu. + add(d->multiMenu = new MultiplayerMenuWidget); + d->multiMenu->setAnchorAndOpeningDirection(d->multi->rule(), ui::Up); + // The DE menu. - d->mainMenu = new PopupMenuWidget("de-menu"); + add(d->mainMenu = new PopupMenuWidget("de-menu")); d->mainMenu->setAnchorAndOpeningDirection(d->logo->rule(), ui::Up); // Game unloading confirmation submenu. @@ -382,9 +411,6 @@ TaskBarWidget::TaskBarWidget() : GuiWidget("taskbar"), d(new Instance(this)) << unloadMenu // hidden with null-game << new ui::ActionItem(tr("Quit Doomsday"), new CommandAction("quit")); - add(d->configMenu); - add(d->mainMenu); - d->itemWidget(d->mainMenu, POS_UNLOAD).hide(); //d->itemWidget(d->mainMenu, POS_GAME_SEPARATOR).hide(); @@ -641,6 +667,11 @@ void TaskBarWidget::closeMainMenu() d->mainMenu->close(); } +void TaskBarWidget::openMultiplayerMenu() +{ + d->multiMenu->open(); +} + void TaskBarWidget::unloadGame() { Con_Execute(CMDS_DDAY, "unload", false, false); @@ -666,18 +697,21 @@ void TaskBarWidget::showUpdaterSettings() void TaskBarWidget::updateCommandLineLayout() { - RuleRectangle &cmdRule = d->console->commandLine().rule(); - - // The command line extends all the way to the status indicator. - cmdRule.setInput(Rule::Left, d->console->button().rule().right()) - .setInput(Rule::Bottom, rule().bottom()); + SequentialLayout layout(rule().right(), rule().top(), ui::Left); + layout << *d->logo << *d->conf; - if(!d->status->behavior().testFlag(Hidden)) + if(!d->multi->behavior().testFlag(Hidden)) { - cmdRule.setInput(Rule::Right, d->status->rule().left()); + layout << *d->multi; } - else + if(!d->status->behavior().testFlag(Hidden)) { - cmdRule.setInput(Rule::Right, d->conf->rule().left()); + layout << *d->status; } + + // The command line extends the rest of the way. + RuleRectangle &cmdRule = d->console->commandLine().rule(); + cmdRule.setInput(Rule::Left, d->console->button().rule().right()) + .setInput(Rule::Bottom, rule().bottom()) + .setInput(Rule::Right, layout.widgets().last()->as().rule().left()); } diff --git a/doomsday/libappfw/src/widgets/popupwidget.cpp b/doomsday/libappfw/src/widgets/popupwidget.cpp index 14dd667e08..a703299c05 100644 --- a/doomsday/libappfw/src/widgets/popupwidget.cpp +++ b/doomsday/libappfw/src/widgets/popupwidget.cpp @@ -406,6 +406,7 @@ void PopupWidget::preparePanelForOpening() // Reparent the popup into the root widget, on top of everything else. d->realParent = Widget::parent(); + DENG2_ASSERT(d->realParent != 0); d->realParent->audienceForDeletion += d; d->realParent->remove(*this); d->realParent->root().as().addOnTop(this); From ce5f6a33bd20e204144df405686430073ca0f8d7 Mon Sep 17 00:00:00 2001 From: danij Date: Thu, 30 Jan 2014 11:46:37 +0000 Subject: [PATCH 011/106] Refactor: Switched each games' p_lights.c to C++ --- doomsday/plugins/doom/doom.pro | 2 +- doomsday/plugins/doom/include/p_lights.h | 134 +++++++------ .../doom/src/{p_lights.c => p_lights.cpp} | 149 ++++++-------- doomsday/plugins/doom64/doom64.pro | 2 +- doomsday/plugins/doom64/include/p_lights.h | 163 +++++++++------- .../doom64/src/{p_lights.c => p_lights.cpp} | 181 +++++++----------- doomsday/plugins/heretic/heretic.pro | 2 +- doomsday/plugins/heretic/include/p_lights.h | 115 ++++++----- .../heretic/src/{p_lights.c => p_lights.cpp} | 146 ++++++-------- doomsday/plugins/hexen/hexen.pro | 2 +- doomsday/plugins/hexen/include/p_lights.h | 90 ++++----- .../hexen/src/{p_lights.c => p_lights.cpp} | 141 ++++++-------- 12 files changed, 511 insertions(+), 616 deletions(-) rename doomsday/plugins/doom/src/{p_lights.c => p_lights.cpp} (61%) rename doomsday/plugins/doom64/src/{p_lights.c => p_lights.cpp} (56%) rename doomsday/plugins/heretic/src/{p_lights.c => p_lights.cpp} (55%) rename doomsday/plugins/hexen/src/{p_lights.c => p_lights.cpp} (70%) diff --git a/doomsday/plugins/doom/doom.pro b/doomsday/plugins/doom/doom.pro index 138a7cba8a..0fad8a1a4a 100644 --- a/doomsday/plugins/doom/doom.pro +++ b/doomsday/plugins/doom/doom.pro @@ -79,7 +79,7 @@ SOURCES += \ src/m_random.c \ src/p_enemy.c \ src/p_inter.c \ - src/p_lights.c \ + src/p_lights.cpp \ src/p_maputl.c \ src/p_mobj.c \ src/p_oldsvg.c \ diff --git a/doomsday/plugins/doom/include/p_lights.h b/doomsday/plugins/doom/include/p_lights.h index a2293543af..e360fd6180 100644 --- a/doomsday/plugins/doom/include/p_lights.h +++ b/doomsday/plugins/doom/include/p_lights.h @@ -1,32 +1,26 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_lights.h Handle Sector base lighting effects. * - *\author Copyright © 2009-2013 Daniel Swanson + * @authors Copyright © 2009-2013 Daniel Swanson * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -/** - * p_lights.h: Handle Sector base lighting effects. - */ +#ifndef LIBDOOM_PLAY_LIGHTS_H +#define LIBDOOM_PLAY_LIGHTS_H -#ifndef __P_LIGHTS_H__ -#define __P_LIGHTS_H__ +#include "doomsday.h" #ifndef __JDOOM__ # error "Using jDoom headers without __JDOOM__" @@ -38,63 +32,83 @@ #define SLOWDARK (35) typedef struct { - thinker_t thinker; - Sector* sector; - int count; - float maxLight; - float minLight; + thinker_t thinker; + Sector *sector; + int count; + float maxLight; + float minLight; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } fireflicker_t; typedef struct { - thinker_t thinker; - Sector* sector; - int count; - float maxLight; - float minLight; - int maxTime; - int minTime; + thinker_t thinker; + Sector *sector; + int count; + float maxLight; + float minLight; + int maxTime; + int minTime; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } lightflash_t; typedef struct { - thinker_t thinker; - Sector* sector; - int count; - float minLight; - float maxLight; - int darkTime; - int brightTime; + thinker_t thinker; + Sector *sector; + int count; + float minLight; + float maxLight; + int darkTime; + int brightTime; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } strobe_t; typedef struct { - thinker_t thinker; - Sector* sector; - float minLight; - float maxLight; - int direction; + thinker_t thinker; + Sector *sector; + float minLight; + float maxLight; + int direction; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } glow_t; #ifdef __cplusplus extern "C" { #endif -void T_FireFlicker(void *flickPtr); -void P_SpawnFireFlicker(Sector* sector); +void T_FireFlicker(void *flickPtr); +void P_SpawnFireFlicker(Sector *sector); -void T_LightFlash(lightflash_t* flash); -void P_SpawnLightFlash(Sector* sector); +void T_LightFlash(lightflash_t *flash); +void P_SpawnLightFlash(Sector *sector); -void T_StrobeFlash(strobe_t* flash); -void P_SpawnStrobeFlash(Sector* sector, int fastOrSlow, - int inSync); -void T_Glow(glow_t* g); -void P_SpawnGlowingLight(Sector* sector); +void T_StrobeFlash(strobe_t *flash); +void P_SpawnStrobeFlash(Sector *sector, int fastOrSlow, int inSync); -void EV_StartLightStrobing(Line* line); -void EV_TurnTagLightsOff(Line* line); -void EV_LightTurnOn(Line* line, float bright); +void T_Glow(glow_t* g); +void P_SpawnGlowingLight(Sector *sector); + +void EV_StartLightStrobing(Line *line); +void EV_TurnTagLightsOff(Line *line); +void EV_LightTurnOn(Line *line, float bright); #ifdef __cplusplus } // extern "C" #endif -#endif +#endif // LIBDOOM_PLAY_LIGHTS_H diff --git a/doomsday/plugins/doom/src/p_lights.c b/doomsday/plugins/doom/src/p_lights.cpp similarity index 61% rename from doomsday/plugins/doom/src/p_lights.c rename to doomsday/plugins/doom/src/p_lights.cpp index d360d8740f..9e8d7aaef7 100644 --- a/doomsday/plugins/doom/src/p_lights.c +++ b/doomsday/plugins/doom/src/p_lights.cpp @@ -1,64 +1,37 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_lights.cpp Handle Sector base lighting effects. * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2006-2013 Daniel Swanson - *\author Copyright © 1999 by Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman (PrBoom 2.2.6) - *\author Copyright © 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze (PrBoom 2.2.6) - *\author Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2006-2013 Daniel Swanson + * @authors Copyright © 1999 Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman (PrBoom 2.2.6) + * @authors Copyright © 1999-2000 Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze (PrBoom 2.2.6) + * @authors Copyright © 1993-1996 id Software, Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * p_lights.c: Handle Sector base lighting effects. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -// HEADER FILES ------------------------------------------------------------ - #include "jdoom.h" +#include "p_lights.h" #include "dmu_lib.h" #include "p_mapsetup.h" #include "p_mapspec.h" -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -// CODE -------------------------------------------------------------------- - void T_FireFlicker(void *flickPtr) { - fireflicker_t *flick = flickPtr; - float amount, lightLevel; + fireflicker_t *flick = (fireflicker_t *)flickPtr; + float amount, lightLevel; if(--flick->count) return; @@ -77,15 +50,14 @@ void T_FireFlicker(void *flickPtr) void P_SpawnFireFlicker(Sector *sector) { - float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); - float otherLevel = DDMAXFLOAT; - fireflicker_t *flick; + float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); + float otherLevel = DDMAXFLOAT; // Note that we are resetting sector attributes. // Nothing special about it during gameplay. P_ToXSector(sector)->special = 0; - flick = Z_Calloc(sizeof(*flick), PU_MAP, 0); + fireflicker_t *flick = (fireflicker_t *)Z_Calloc(sizeof(*flick), PU_MAP, 0); flick->thinker.function = T_FireFlicker; Thinker_Add(&flick->thinker); @@ -106,7 +78,7 @@ void P_SpawnFireFlicker(Sector *sector) */ void T_LightFlash(lightflash_t *flash) { - float lightLevel; + float lightLevel; if(--flash->count) return; @@ -130,15 +102,14 @@ void T_LightFlash(lightflash_t *flash) */ void P_SpawnLightFlash(Sector *sector) { - float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); - float otherLevel = DDMAXFLOAT; - lightflash_t *flash; + float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); + float otherLevel = DDMAXFLOAT; // Note that we are resetting sector attributes. // Nothing special about it during gameplay. P_ToXSector(sector)->special = 0; - flash = Z_Calloc(sizeof(*flash), PU_MAP, 0); + lightflash_t *flash = (lightflash_t *)Z_Calloc(sizeof(*flash), PU_MAP, 0); flash->thinker.function = (thinkfunc_t) T_LightFlash; Thinker_Add(&flash->thinker); @@ -160,7 +131,7 @@ void P_SpawnLightFlash(Sector *sector) */ void T_StrobeFlash(strobe_t *flash) { - float lightLevel; + float lightLevel; if(--flash->count) return; @@ -182,13 +153,12 @@ void T_StrobeFlash(strobe_t *flash) * After the map has been loaded, scan each sector for specials that spawn * thinkers. */ -void P_SpawnStrobeFlash(Sector* sector, int fastOrSlow, int inSync) +void P_SpawnStrobeFlash(Sector *sector, int fastOrSlow, int inSync) { - strobe_t* flash; float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); float otherLevel = DDMAXFLOAT; - flash = Z_Calloc(sizeof(*flash), PU_MAP, 0); + strobe_t *flash = (strobe_t *)Z_Calloc(sizeof(*flash), PU_MAP, 0); flash->thinker.function = (thinkfunc_t) T_StrobeFlash; Thinker_Add(&flash->thinker); @@ -224,16 +194,14 @@ void P_SpawnStrobeFlash(Sector* sector, int fastOrSlow, int inSync) */ void EV_StartLightStrobing(Line *line) { - Sector *sec = NULL; - iterlist_t *list; - - list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); - if(!list) - return; + iterlist_t *list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); + if(!list) return; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) { if(P_ToXSector(sec)->specialData) continue; @@ -244,21 +212,17 @@ void EV_StartLightStrobing(Line *line) void EV_TurnTagLightsOff(Line *line) { - Sector *sec = NULL; - iterlist_t *list; - float lightLevel; - float otherLevel; - - list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); - if(!list) - return; + iterlist_t *list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); + if(!list) return; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) { - lightLevel = P_GetFloatp(sec, DMU_LIGHT_LEVEL); - otherLevel = DDMAXFLOAT; + float lightLevel = P_GetFloatp(sec, DMU_LIGHT_LEVEL); + float otherLevel = DDMAXFLOAT; P_FindSectorSurroundingLowestLight(sec, &otherLevel); if(otherLevel < lightLevel) lightLevel = otherLevel; @@ -269,27 +233,25 @@ void EV_TurnTagLightsOff(Line *line) void EV_LightTurnOn(Line *line, float max) { - Sector *sec = NULL; - iterlist_t *list; - float lightLevel = 0, otherLevel; - - list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); - if(!list) - return; + iterlist_t *list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); + if(!list) return; + float lightLevel = 0; if(!FEQUAL(max, 0)) lightLevel = max; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) { // If Max = 0 means to search for the highest light level in the // surrounding sector. if(FEQUAL(max, 0)) { lightLevel = P_GetFloatp(sec, DMU_LIGHT_LEVEL); - otherLevel = DDMINFLOAT; + float otherLevel = DDMINFLOAT; P_FindSectorSurroundingHighestLight(sec, &otherLevel); if(otherLevel > lightLevel) lightLevel = otherLevel; @@ -301,8 +263,8 @@ void EV_LightTurnOn(Line *line, float max) void T_Glow(glow_t *g) { - float lightLevel = P_GetFloatp(g->sector, DMU_LIGHT_LEVEL); - float glowDelta = (1.0f / 255.0f) * (float) GLOWSPEED; + float lightLevel = P_GetFloatp(g->sector, DMU_LIGHT_LEVEL); + float glowDelta = (1.0f / 255.0f) * (float) GLOWSPEED; switch(g->direction) { @@ -334,11 +296,10 @@ void T_Glow(glow_t *g) void P_SpawnGlowingLight(Sector *sector) { - float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); - float otherLevel = DDMAXFLOAT; - glow_t *g; + float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); + float otherLevel = DDMAXFLOAT; - g = Z_Calloc(sizeof(*g), PU_MAP, 0); + glow_t *g = (glow_t *)Z_Calloc(sizeof(*g), PU_MAP, 0); g->thinker.function = (thinkfunc_t) T_Glow; Thinker_Add(&g->thinker); diff --git a/doomsday/plugins/doom64/doom64.pro b/doomsday/plugins/doom64/doom64.pro index 4241b906e1..2d2db4ba3b 100644 --- a/doomsday/plugins/doom64/doom64.pro +++ b/doomsday/plugins/doom64/doom64.pro @@ -74,7 +74,7 @@ SOURCES += \ src/m_random.c \ src/p_enemy.c \ src/p_inter.c \ - src/p_lights.c \ + src/p_lights.cpp \ src/p_maputl.c \ src/p_mobj.c \ src/p_pspr.c \ diff --git a/doomsday/plugins/doom64/include/p_lights.h b/doomsday/plugins/doom64/include/p_lights.h index db52ec2999..09598f58bd 100644 --- a/doomsday/plugins/doom64/include/p_lights.h +++ b/doomsday/plugins/doom64/include/p_lights.h @@ -1,35 +1,29 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_lights.h Handle sector base lighting effects. * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2005-2013 Daniel Swanson - *\author Copyright © 2003-2005 Samuel Villarreal - *\author Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 2003-2005 Samuel Villarreal + * @authors Copyright © 1993-1996 id Software, Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -/** - * p_lights.c: Handle Sector base lighting effects. - */ +#ifndef LIBDOOM64_PLAY_LIGHTS_H +#define LIBDOOM64_PLAY_LIGHTS_H -#ifndef __P_LIGHTS_H__ -#define __P_LIGHTS_H__ +#include "doomsday.h" #ifndef __JDOOM64__ # error "Using jDoom64 headers without __JDOOM64__" @@ -41,76 +35,101 @@ #define SLOWDARK (35) typedef struct { - thinker_t thinker; - Sector* sector; - int count; - float maxLight; - float minLight; + thinker_t thinker; + Sector *sector; + int count; + float maxLight; + float minLight; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } fireflicker_t; typedef struct { - thinker_t thinker; - Sector* sector; - int count; - float maxLight; - float minLight; - int maxTime; - int minTime; + thinker_t thinker; + Sector *sector; + int count; + float maxLight; + float minLight; + int maxTime; + int minTime; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } lightflash_t; typedef struct { - thinker_t thinker; - Sector* sector; - int count; - float maxLight; - float minLight; - int maxTime; - int minTime; + thinker_t thinker; + Sector *sector; + int count; + float maxLight; + float minLight; + int maxTime; + int minTime; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } lightblink_t; typedef struct { - thinker_t thinker; - Sector* sector; - int count; - float minLight; - float maxLight; - int darkTime; - int brightTime; + thinker_t thinker; + Sector *sector; + int count; + float minLight; + float maxLight; + int darkTime; + int brightTime; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } strobe_t; typedef struct { - thinker_t thinker; - Sector* sector; - float minLight; - float maxLight; - int direction; + thinker_t thinker; + Sector *sector; + float minLight; + float maxLight; + int direction; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } glow_t; #ifdef __cplusplus extern "C" { #endif -void T_FireFlicker(fireflicker_t* flick); -void P_SpawnFireFlicker(Sector* sector); +void T_FireFlicker(fireflicker_t *flick); +void P_SpawnFireFlicker(Sector *sector); -void T_LightFlash(lightflash_t* flash); -void P_SpawnLightFlash(Sector* sector); +void T_LightFlash(lightflash_t *flash); +void P_SpawnLightFlash(Sector *sector); -void T_LightBlink(lightblink_t* flash); -void P_SpawnLightBlink(Sector* sector); +void T_LightBlink(lightblink_t *flash); +void P_SpawnLightBlink(Sector *sector); -void T_StrobeFlash(strobe_t* flash); -void P_SpawnStrobeFlash(Sector* sector, int fastOrSlow, - int inSync); -void T_Glow(glow_t* g); -void P_SpawnGlowingLight(Sector* sector); +void T_StrobeFlash(strobe_t *flash); +void P_SpawnStrobeFlash(Sector *sector, int fastOrSlow, int inSync); -void EV_StartLightStrobing(Line* line); -void EV_TurnTagLightsOff(Line* line); -void EV_LightTurnOn(Line* line, float max); +void T_Glow(glow_t *g); +void P_SpawnGlowingLight(Sector *sector); + +void EV_StartLightStrobing(Line *line); +void EV_TurnTagLightsOff(Line *line); +void EV_LightTurnOn(Line *line, float max); #ifdef __cplusplus } // extern "C" #endif -#endif +#endif // LIBDOOM64_PLAY_LIGHTS_H diff --git a/doomsday/plugins/doom64/src/p_lights.c b/doomsday/plugins/doom64/src/p_lights.cpp similarity index 56% rename from doomsday/plugins/doom64/src/p_lights.c rename to doomsday/plugins/doom64/src/p_lights.cpp index 21f23c5be9..8591bcc902 100644 --- a/doomsday/plugins/doom64/src/p_lights.c +++ b/doomsday/plugins/doom64/src/p_lights.cpp @@ -1,97 +1,65 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_lights.cpp Handle Sector base lighting effects. * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2006-2013 Daniel Swanson - *\author Copyright © 2003-2005 Samuel Villarreal - *\author Copyright © 1999 by Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman (PrBoom 2.2.6) - *\author Copyright © 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze (PrBoom 2.2.6) - *\author Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2006-2013 Daniel Swanson + * @authors Copyright © 2003-2005 Samuel Villarreal + * @authors Copyright © 1999 Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman (PrBoom 2.2.6) + * @authors Copyright © 1999-2000 Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze (PrBoom 2.2.6) + * @authors Copyright © 1993-1996 id Software, Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * p_lights.c: Handle Sector base lighting effects. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -// HEADER FILES ------------------------------------------------------------ - #include "jdoom64.h" +#include "p_lights.h" #include "dmu_lib.h" #include "p_mapsetup.h" #include "p_mapspec.h" -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -// CODE -------------------------------------------------------------------- - void T_FireFlicker(fireflicker_t *flick) { - float lightLevel; - float amount; - if(--flick->count) return; - amount = ((P_Random() & 3) * 16) / 255.0f; + float amount = ((P_Random() & 3) * 16) / 255.0f; - lightLevel = P_GetFloatp(flick->sector, DMU_LIGHT_LEVEL); + float lightLevel = P_GetFloatp(flick->sector, DMU_LIGHT_LEVEL); if(lightLevel - amount < flick->minLight) P_SetFloatp(flick->sector, DMU_LIGHT_LEVEL, flick->minLight); else - P_SetFloatp(flick->sector, DMU_LIGHT_LEVEL, - flick->maxLight - amount); + P_SetFloatp(flick->sector, DMU_LIGHT_LEVEL, flick->maxLight - amount); flick->count = 4; } void P_SpawnFireFlicker(Sector *sector) { - float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); - float otherLevel = DDMAXFLOAT; - fireflicker_t *flick; + float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); + float otherLevel = DDMAXFLOAT; // Note that we are resetting sector attributes. // Nothing special about it during gameplay. //P_ToXSector(sector)->special = 0; // jd64 - flick = Z_Calloc(sizeof(*flick), PU_MAP, 0); + fireflicker_t *flick = (fireflicker_t *)Z_Calloc(sizeof(*flick), PU_MAP, 0); flick->thinker.function = (thinkfunc_t) T_FireFlicker; Thinker_Add(&flick->thinker); - flick->sector = sector; - flick->count = 4; + flick->sector = sector; + flick->count = 4; flick->maxLight = lightLevel; P_FindSectorSurroundingLowestLight(sector, &otherLevel); @@ -107,7 +75,7 @@ void P_SpawnFireFlicker(Sector *sector) */ void T_LightFlash(lightflash_t *flash) { - float lightLevel; + float lightLevel; if(--flash->count) return; @@ -131,15 +99,14 @@ void T_LightFlash(lightflash_t *flash) */ void P_SpawnLightFlash(Sector *sector) { - float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); - float otherLevel = DDMAXFLOAT; - lightflash_t *flash; + float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); + float otherLevel = DDMAXFLOAT; // Note that we are resetting sector attributes. // Nothing special about it during gameplay. //P_ToXSector(sector)->special = 0; // jd64 - flash = Z_Calloc(sizeof(*flash), PU_MAP, 0); + lightflash_t *flash = (lightflash_t *)Z_Calloc(sizeof(*flash), PU_MAP, 0); flash->thinker.function = (thinkfunc_t) T_LightFlash; Thinker_Add(&flash->thinker); @@ -161,7 +128,7 @@ void P_SpawnLightFlash(Sector *sector) */ void T_LightBlink(lightblink_t *flash) { - float lightlevel = P_GetFloatp(flash->sector, DMU_LIGHT_LEVEL); + float lightlevel = P_GetFloatp(flash->sector, DMU_LIGHT_LEVEL); if(--flash->count) return; @@ -183,9 +150,7 @@ void T_LightBlink(lightblink_t *flash) */ void P_SpawnLightBlink(Sector *sector) { - lightblink_t *blink; - - blink = Z_Calloc(sizeof(*blink), PU_MAP, 0); + lightblink_t *blink = (lightblink_t *)Z_Calloc(sizeof(*blink), PU_MAP, 0); blink->thinker.function = (thinkfunc_t) T_LightBlink; Thinker_Add(&blink->thinker); @@ -201,7 +166,7 @@ void P_SpawnLightBlink(Sector *sector) */ void T_StrobeFlash(strobe_t *flash) { - float lightLevel; + float lightLevel; if(--flash->count) return; @@ -225,18 +190,17 @@ void T_StrobeFlash(strobe_t *flash) */ void P_SpawnStrobeFlash(Sector *sector, int fastOrSlow, int inSync) { - strobe_t *flash; - float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); - float otherLevel = DDMAXFLOAT; + float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); + float otherLevel = DDMAXFLOAT; - flash = Z_Calloc(sizeof(*flash), PU_MAP, 0); + strobe_t *flash = (strobe_t *)Z_Calloc(sizeof(*flash), PU_MAP, 0); flash->thinker.function = (thinkfunc_t) T_StrobeFlash; Thinker_Add(&flash->thinker); - flash->sector = sector; - flash->darkTime = fastOrSlow; + flash->sector = sector; + flash->darkTime = fastOrSlow; flash->brightTime = STROBEBRIGHT; - flash->maxLight = lightLevel; + flash->maxLight = lightLevel; P_FindSectorSurroundingLowestLight(sector, &otherLevel); if(otherLevel < lightLevel) flash->minLight = otherLevel; @@ -260,16 +224,14 @@ void P_SpawnStrobeFlash(Sector *sector, int fastOrSlow, int inSync) */ void EV_StartLightStrobing(Line *line) { - Sector *sec = NULL; - iterlist_t *list; - - list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); - if(!list) - return; + iterlist_t *list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); + if(!list) return; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) { if(P_ToXSector(sec)->specialData) continue; @@ -280,21 +242,17 @@ void EV_StartLightStrobing(Line *line) void EV_TurnTagLightsOff(Line *line) { - Sector *sec = NULL; - iterlist_t *list; - float lightLevel; - float otherLevel; - - list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); - if(!list) - return; + iterlist_t *list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); + if(!list) return; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) { - lightLevel = P_GetFloatp(sec, DMU_LIGHT_LEVEL); - otherLevel = DDMAXFLOAT; + float lightLevel = P_GetFloatp(sec, DMU_LIGHT_LEVEL); + float otherLevel = DDMAXFLOAT; P_FindSectorSurroundingLowestLight(sec, &otherLevel); if(otherLevel < lightLevel) lightLevel = otherLevel; @@ -305,27 +263,25 @@ void EV_TurnTagLightsOff(Line *line) void EV_LightTurnOn(Line *line, float max) { - Sector *sec = NULL; - iterlist_t *list; - float lightLevel, otherLevel; - - list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); - if(!list) - return; + iterlist_t *list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); + if(!list) return; + float lightLevel = 0; if(max != 0) lightLevel = max; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) { // If Max = 0 means to search for the highest light level in the // surrounding sector. if(max == 0) { lightLevel = P_GetFloatp(sec, DMU_LIGHT_LEVEL); - otherLevel = DDMINFLOAT; + float otherLevel = DDMINFLOAT; P_FindSectorSurroundingHighestLight(sec, &otherLevel); if(otherLevel > lightLevel) lightLevel = otherLevel; @@ -337,8 +293,8 @@ void EV_LightTurnOn(Line *line, float max) void T_Glow(glow_t *g) { - float lightLevel = P_GetFloatp(g->sector, DMU_LIGHT_LEVEL); - float glowDelta = (1.0f / 255.0f) * (float) GLOWSPEED; + float lightLevel = P_GetFloatp(g->sector, DMU_LIGHT_LEVEL); + float glowDelta = (1.0f / 255.0f) * (float) GLOWSPEED; switch(g->direction) { @@ -364,22 +320,21 @@ void T_Glow(glow_t *g) P_SetFloatp(g->sector, DMU_LIGHT_LEVEL, lightLevel); } -void P_SpawnGlowingLight(Sector* sector) +void P_SpawnGlowingLight(Sector *sector) { - float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); - float otherLevel = DDMAXFLOAT; - glow_t* g; + float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); + float otherLevel = DDMAXFLOAT; - g = Z_Calloc(sizeof(*g), PU_MAP, 0); + glow_t *g = (glow_t *)Z_Calloc(sizeof(*g), PU_MAP, 0); g->thinker.function = (thinkfunc_t) T_Glow; Thinker_Add(&g->thinker); - g->sector = sector; + g->sector = sector; P_FindSectorSurroundingLowestLight(sector, &otherLevel); if(otherLevel < lightLevel) g->minLight = otherLevel; else g->minLight = lightLevel; - g->maxLight = lightLevel; + g->maxLight = lightLevel; g->direction = -1; } diff --git a/doomsday/plugins/heretic/heretic.pro b/doomsday/plugins/heretic/heretic.pro index 1d895a9059..b2266bb9ce 100644 --- a/doomsday/plugins/heretic/heretic.pro +++ b/doomsday/plugins/heretic/heretic.pro @@ -81,7 +81,7 @@ SOURCES += \ src/m_random.c \ src/p_enemy.c \ src/p_inter.c \ - src/p_lights.c \ + src/p_lights.cpp \ src/p_maputl.c \ src/p_mobj.c \ src/p_oldsvg.c \ diff --git a/doomsday/plugins/heretic/include/p_lights.h b/doomsday/plugins/heretic/include/p_lights.h index 683f6d7b7a..a55e23d921 100644 --- a/doomsday/plugins/heretic/include/p_lights.h +++ b/doomsday/plugins/heretic/include/p_lights.h @@ -1,32 +1,26 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_lights.h Handle Sector base lighting effects. * - *\author Copyright © 2006-2013 Daniel Swanson + * @authors Copyright © 2006-2013 Daniel Swanson * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -/** - * p_lights.h: Per-sector lighting effects - jHeretic specific. - */ +#ifndef LIBHERETIC_PLAY_LIGHTS_H +#define LIBHERETIC_PLAY_LIGHTS_H -#ifndef __P_LIGHTS_H__ -#define __P_LIGHTS_H__ +#include "doomsday.h" #ifndef __JHERETIC__ # error "Using jHeretic headers without __JHERETIC__" @@ -38,52 +32,67 @@ #define SLOWDARK (35) typedef struct { - thinker_t thinker; - Sector* sector; - int count; - float maxLight; - float minLight; - int maxTime; - int minTime; + thinker_t thinker; + Sector *sector; + int count; + float maxLight; + float minLight; + int maxTime; + int minTime; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } lightflash_t; typedef struct { - thinker_t thinker; - Sector* sector; - int count; - float minLight; - float maxLight; - int darkTime; - int brightTime; + thinker_t thinker; + Sector *sector; + int count; + float minLight; + float maxLight; + int darkTime; + int brightTime; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } strobe_t; typedef struct { - thinker_t thinker; - Sector* sector; - float minLight; - float maxLight; - int direction; + thinker_t thinker; + Sector *sector; + float minLight; + float maxLight; + int direction; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } glow_t; #ifdef __cplusplus extern "C" { #endif -void T_LightFlash(lightflash_t* flash); -void P_SpawnLightFlash(Sector* sector); +void T_LightFlash(lightflash_t *flash); +void P_SpawnLightFlash(Sector *sector); + +void T_StrobeFlash(strobe_t *flash); +void P_SpawnStrobeFlash(Sector *sector, int fastOrSlow, int inSync); -void T_StrobeFlash(strobe_t* flash); -void P_SpawnStrobeFlash(Sector* sector, int fastOrSlow, - int inSync); -void T_Glow(glow_t* g); -void P_SpawnGlowingLight(Sector* sector); +void T_Glow(glow_t *g); +void P_SpawnGlowingLight(Sector *sector); -void EV_StartLightStrobing(Line* line); -void EV_TurnTagLightsOff(Line* line); -void EV_LightTurnOn(Line* line, float bright); +void EV_StartLightStrobing(Line *line); +void EV_TurnTagLightsOff(Line *line); +void EV_LightTurnOn(Line *line, float bright); #ifdef __cplusplus } // extern "C" #endif -#endif +#endif // LIBHERETIC_PLAY_LIGHTS_H diff --git a/doomsday/plugins/heretic/src/p_lights.c b/doomsday/plugins/heretic/src/p_lights.cpp similarity index 55% rename from doomsday/plugins/heretic/src/p_lights.c rename to doomsday/plugins/heretic/src/p_lights.cpp index db1f23b34b..fe85ab2535 100644 --- a/doomsday/plugins/heretic/src/p_lights.c +++ b/doomsday/plugins/heretic/src/p_lights.cpp @@ -1,66 +1,38 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_lights.cpp Handle Sector base lighting effects. * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2006-2013 Daniel Swanson - *\author Copyright © 1999 by Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman (PrBoom 2.2.6) - *\author Copyright © 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze (PrBoom 2.2.6) - *\author Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2006-2013 Daniel Swanson + * @authors Copyright © 1999 Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman (PrBoom 2.2.6) + * @authors Copyright © 1999-2000 Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze (PrBoom 2.2.6) + * @authors Copyright © 1993-1996 id Software, Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * p_lights.c: Per-sector lighting effects - jHeretic specific. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -// HEADER FILES ------------------------------------------------------------ - #include "jheretic.h" #include "dmu_lib.h" #include "p_mapsetup.h" #include "p_mapspec.h" -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -// CODE -------------------------------------------------------------------- - /** * Broken light flashing. */ void T_LightFlash(lightflash_t *flash) { - float lightlevel = P_GetFloatp(flash->sector, DMU_LIGHT_LEVEL); + float lightlevel = P_GetFloatp(flash->sector, DMU_LIGHT_LEVEL); if(--flash->count) return; @@ -83,14 +55,13 @@ void T_LightFlash(lightflash_t *flash) */ void P_SpawnLightFlash(Sector *sector) { - float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); - float otherLevel = DDMAXFLOAT; - lightflash_t *flash; + float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); + float otherLevel = DDMAXFLOAT; // Nothing special about it during gameplay. P_ToXSector(sector)->special = 0; - flash = Z_Calloc(sizeof(*flash), PU_MAP, 0); + lightflash_t *flash = (lightflash_t *)Z_Calloc(sizeof(*flash), PU_MAP, 0); flash->thinker.function = (thinkfunc_t) T_LightFlash; Thinker_Add(&flash->thinker); @@ -112,7 +83,7 @@ void P_SpawnLightFlash(Sector *sector) */ void T_StrobeFlash(strobe_t *flash) { - float lightLevel; + float lightLevel; if(--flash->count) return; @@ -134,20 +105,19 @@ void T_StrobeFlash(strobe_t *flash) * After the map has been loaded, scan each sector for specials that spawn * thinkers. */ -void P_SpawnStrobeFlash(Sector* sector, int fastOrSlow, int inSync) +void P_SpawnStrobeFlash(Sector *sector, int fastOrSlow, int inSync) { float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); float otherLevel = DDMAXFLOAT; - strobe_t* flash; - flash = Z_Calloc(sizeof(*flash), PU_MAP, 0); + strobe_t *flash = (strobe_t *)Z_Calloc(sizeof(*flash), PU_MAP, 0); flash->thinker.function = (thinkfunc_t) T_StrobeFlash; Thinker_Add(&flash->thinker); - flash->sector = sector; - flash->darkTime = fastOrSlow; + flash->sector = sector; + flash->darkTime = fastOrSlow; flash->brightTime = STROBEBRIGHT; - flash->maxLight = lightLevel; + flash->maxLight = lightLevel; P_FindSectorSurroundingLowestLight(sector, &otherLevel); if(otherLevel < lightLevel) flash->minLight = otherLevel; @@ -175,16 +145,14 @@ void P_SpawnStrobeFlash(Sector* sector, int fastOrSlow, int inSync) */ void EV_StartLightStrobing(Line *line) { - Sector *sec = NULL; - iterlist_t *list; - - list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); - if(!list) - return; + iterlist_t *list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); + if(!list) return; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) { if(P_ToXSector(sec)->specialData) continue; @@ -195,21 +163,17 @@ void EV_StartLightStrobing(Line *line) void EV_TurnTagLightsOff(Line *line) { - Sector *sec = NULL; - iterlist_t *list; - float lightLevel; - float otherLevel; - - list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); - if(!list) - return; + iterlist_t *list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); + if(!list) return; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) { - lightLevel = P_GetFloatp(sec, DMU_LIGHT_LEVEL); - otherLevel = DDMAXFLOAT; + float lightLevel = P_GetFloatp(sec, DMU_LIGHT_LEVEL); + float otherLevel = DDMAXFLOAT; P_FindSectorSurroundingLowestLight(sec, &otherLevel); if(otherLevel < lightLevel) lightLevel = otherLevel; @@ -220,27 +184,26 @@ void EV_TurnTagLightsOff(Line *line) void EV_LightTurnOn(Line *line, float max) { - Sector *sec = NULL; - iterlist_t *list; - float lightLevel = 0, otherLevel; + iterlist_t *list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); + if(!list) return; - list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); - if(!list) - return; + float lightLevel = 0; if(max != 0) lightLevel = max; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec = 0; + while((sec = (Sector *)IterList_MoveIterator(list))) { // If Max = 0 means to search for the highest light level in the // surrounding sector. if(max == 0) { lightLevel = P_GetFloatp(sec, DMU_LIGHT_LEVEL); - otherLevel = DDMINFLOAT; + float otherLevel = DDMINFLOAT; P_FindSectorSurroundingHighestLight(sec, &otherLevel); if(otherLevel > lightLevel) lightLevel = otherLevel; @@ -250,10 +213,10 @@ void EV_LightTurnOn(Line *line, float max) } } -void T_Glow(glow_t * g) +void T_Glow(glow_t *g) { - float lightlevel = P_GetFloatp(g->sector, DMU_LIGHT_LEVEL); - float glowdelta = (1.0f / 255.0f) * (float) GLOWSPEED; + float lightlevel = P_GetFloatp(g->sector, DMU_LIGHT_LEVEL); + float glowdelta = (1.0f / 255.0f) * (float) GLOWSPEED; switch(g->direction) { @@ -281,11 +244,10 @@ void T_Glow(glow_t * g) void P_SpawnGlowingLight(Sector *sector) { - float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); - float otherLevel = DDMAXFLOAT; - glow_t *g; + float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); + float otherLevel = DDMAXFLOAT; - g = Z_Calloc(sizeof(*g), PU_MAP, 0); + glow_t *g = (glow_t *)Z_Calloc(sizeof(*g), PU_MAP, 0); g->thinker.function = (thinkfunc_t) T_Glow; Thinker_Add(&g->thinker); @@ -295,7 +257,7 @@ void P_SpawnGlowingLight(Sector *sector) g->minLight = otherLevel; else g->minLight = lightLevel; - g->maxLight = lightLevel; + g->maxLight = lightLevel; g->direction = -1; P_ToXSector(sector)->special = 0; diff --git a/doomsday/plugins/hexen/hexen.pro b/doomsday/plugins/hexen/hexen.pro index a0da71a23f..7e2d2d80fd 100644 --- a/doomsday/plugins/hexen/hexen.pro +++ b/doomsday/plugins/hexen/hexen.pro @@ -85,7 +85,7 @@ SOURCES += \ src/m_random.c \ src/p_enemy.c \ src/p_inter.c \ - src/p_lights.c \ + src/p_lights.cpp \ src/p_mapinfo.cpp \ src/p_maputl.c \ src/p_mobj.c \ diff --git a/doomsday/plugins/hexen/include/p_lights.h b/doomsday/plugins/hexen/include/p_lights.h index 9772cb8c8d..9bc6feede4 100644 --- a/doomsday/plugins/hexen/include/p_lights.h +++ b/doomsday/plugins/hexen/include/p_lights.h @@ -1,34 +1,28 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_lights.h * - *\author Copyright © 2004-2013 Jaakko Keränen - *\author Copyright © 2005-2013 Daniel Swanson - *\author Copyright © 1999 Activision + * @authors Copyright © 2004-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 1999 Activision * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -/** - * p_lights.h: - */ +#ifndef LIBHEXEN_PLAY_LIGHTS_H +#define LIBHEXEN_PLAY_LIGHTS_H -#ifndef __P_LIGHTS_H__ -#define __P_LIGHTS_H__ +#include "doomsday.h" #ifndef __JHEXEN__ # error "Using jHexen headers without __JHEXEN__" @@ -49,37 +43,47 @@ typedef enum { } lighttype_t; typedef struct { - thinker_t thinker; - Sector* sector; - lighttype_t type; - float value1; - float value2; - int tics1; //// \todo Type LITEGLOW uses this as a third light value. As such, it has been left as 0 - 255 for now. - int tics2; - int count; + thinker_t thinker; + Sector *sector; + lighttype_t type; + float value1; + float value2; + int tics1; ///< \todo Type LITEGLOW uses this as a third light value. As such, it has been left as 0 - 255 for now. + int tics2; + int count; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } light_t; typedef struct { - thinker_t thinker; - Sector* sector; - int index; - float baseValue; + thinker_t thinker; + Sector *sector; + int index; + float baseValue; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } phase_t; #ifdef __cplusplus extern "C" { #endif -void T_Phase(phase_t* phase); -void P_SpawnPhasedLight(Sector* sec, float base, int index); +void T_Phase(phase_t *phase); +void P_SpawnPhasedLight(Sector *sec, float base, int index); -void T_Light(light_t* light); -void P_SpawnLightSequence(Sector* sec, int indexStep); +void T_Light(light_t *light); +void P_SpawnLightSequence(Sector *sec, int indexStep); -dd_bool EV_SpawnLight(Line* line, byte* arg, lighttype_t type); +dd_bool EV_SpawnLight(Line *line, byte *arg, lighttype_t type); #ifdef __cplusplus } // extern "C" #endif -#endif +#endif // LIBHEXEN_PLAY_LIGHTS_H diff --git a/doomsday/plugins/hexen/src/p_lights.c b/doomsday/plugins/hexen/src/p_lights.cpp similarity index 70% rename from doomsday/plugins/hexen/src/p_lights.c rename to doomsday/plugins/hexen/src/p_lights.cpp index dfa82f7de7..c76874353a 100644 --- a/doomsday/plugins/hexen/src/p_lights.c +++ b/doomsday/plugins/hexen/src/p_lights.cpp @@ -1,55 +1,30 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_lights.cpp * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2006-2013 Daniel Swanson - *\author Copyright © 1999 Activision + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2006-2013 Daniel Swanson + * @authors Copyright © 1999 Activision * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * p_lights.c: + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -// HEADER FILES ------------------------------------------------------------ - #include "jhexen.h" +#include "p_lights.h" #include "dmu_lib.h" #include "p_mapspec.h" -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - static float phaseTable[64] = { .5, .4375, .375, .3125, .25, .1875, .125, .125, .0625, .0625, .0625, 0, 0, 0, 0, 0, @@ -61,8 +36,6 @@ static float phaseTable[64] = { .125, .125, .1875, .25, .3125, .375, .4375, .5 }; -// CODE -------------------------------------------------------------------- - void T_Light(light_t *light) { if(light->count) @@ -143,33 +116,33 @@ void T_Light(light_t *light) dd_bool EV_SpawnLight(Line *line, byte *arg, lighttype_t type) { - int arg1, arg2, arg3, arg4; - dd_bool think = false; - dd_bool rtn = false; - light_t *light; - Sector *sec = NULL; - iterlist_t *list; + int arg1, arg2, arg3, arg4; arg1 = (int) arg[1]; arg2 = (int) arg[2]; arg3 = (int) arg[3]; arg4 = (int) arg[4]; - list = P_GetSectorIterListForTag((int) arg[0], false); - if(!list) - return rtn; + iterlist_t *list = P_GetSectorIterListForTag((int) arg[0], false); + if(!list) return false; + + dd_bool rtn = false; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); - while((sec = IterList_MoveIterator(list)) != NULL) + + Sector *sec; + while((sec = (Sector *)IterList_MoveIterator(list))) { - think = false; rtn = true; - light = Z_Calloc(sizeof(*light), PU_MAP, 0); - light->type = type; + dd_bool think = false; + + light_t *light = (light_t *)Z_Calloc(sizeof(*light), PU_MAP, 0); + + light->type = type; light->sector = sec; - light->count = 0; + light->count = 0; switch(type) { @@ -262,17 +235,16 @@ void T_Phase(phase_t *phase) phase->baseValue + phaseTable[phase->index]); } -void P_SpawnPhasedLight(Sector* sector, float base, int index) +void P_SpawnPhasedLight(Sector *sector, float base, int index) { - phase_t* phase; - - phase = Z_Calloc(sizeof(*phase), PU_MAP, 0); + phase_t *phase = (phase_t *)Z_Calloc(sizeof(*phase), PU_MAP, 0); phase->thinker.function = (thinkfunc_t) T_Phase; Thinker_Add(&phase->thinker); phase->sector = sector; if(index == -1) - { // Sector->lightLevel as the index. + { + // Sector->lightLevel as the index. phase->index = (int) (255.0f * P_SectorLight(sector)) & 63; } else @@ -287,17 +259,17 @@ void P_SpawnPhasedLight(Sector* sector, float base, int index) P_ToXSector(sector)->special = 0; } -typedef struct { - int seqSpecial, count; - Sector* sec, *nextSec; -} findlightsequencesectorparams_t; +struct findlightsequencesectorparams_t +{ + int seqSpecial, count; + Sector *sec, *nextSec; +}; -static int findLightSequenceSector(void* p, void* context) +static int findLightSequenceSector(void *p, void *context) { - Line* li = (Line*) p; - findlightsequencesectorparams_t* params = - (findlightsequencesectorparams_t*) context; - Sector* tempSec = P_GetNextSector(li, params->sec); + Line *li = (Line *) p; + findlightsequencesectorparams_t *params = (findlightsequencesectorparams_t *) context; + Sector *tempSec = P_GetNextSector(li, params->sec); if(tempSec) { @@ -316,22 +288,21 @@ static int findLightSequenceSector(void* p, void* context) return false; // Continue iteration. } -typedef struct { - Sector* sec, *nextSec; -} findlightsequencestartsectorparams_t; +struct findlightsequencestartsectorparams_t +{ + Sector *sec, *nextSec; +}; -static int findLightSequenceStartSector(void* p, void* context) +static int findLightSequenceStartSector(void *p, void *context) { - Line* li = (Line*) p; - findlightsequencestartsectorparams_t* params = - (findlightsequencestartsectorparams_t*) context; - Sector* tempSec = P_GetNextSector(li, params->sec); + Line *li = (Line *) p; + findlightsequencestartsectorparams_t *params = (findlightsequencestartsectorparams_t *) context; - if(tempSec) + if(Sector *sector = P_GetNextSector(li, params->sec)) { - if(P_ToXSector(tempSec)->special == LIGHT_SEQUENCE_START) + if(P_ToXSector(sector)->special == LIGHT_SEQUENCE_START) { - params->nextSec = tempSec; + params->nextSec = sector; } } @@ -346,8 +317,8 @@ void P_SpawnLightSequence(Sector *sector, int indexStep) findlightsequencesectorparams_t params; params.seqSpecial = LIGHT_SEQUENCE; // Look for Light_Sequence, first. - params.count = 1; - params.sec = sector; + params.count = 1; + params.sec = sector; do { // Make sure that the search doesn't back up. From 2bee2e234ddffb29ee2a06cc4b72365792dc3da6 Mon Sep 17 00:00:00 2001 From: danij Date: Thu, 30 Jan 2014 12:06:56 +0000 Subject: [PATCH 012/106] Refactor|libcommon: Implement thinker (de)serialization in C++, with Reader/Writer Todo: mobj_t and Hexen's polyevent_t --- doomsday/api/api_thinker.h | 2 + doomsday/plugins/common/include/p_ceiling.h | 7 + doomsday/plugins/common/include/p_door.h | 5 + doomsday/plugins/common/include/p_floor.h | 7 + doomsday/plugins/common/include/p_plat.h | 7 + doomsday/plugins/common/include/p_saveg.h | 5 + doomsday/plugins/common/include/p_scroll.h | 5 + doomsday/plugins/common/include/p_switch.h | 7 +- doomsday/plugins/common/include/polyobjs.h | 44 +- doomsday/plugins/common/src/p_ceiling.cpp | 106 ++ doomsday/plugins/common/src/p_door.cpp | 72 + doomsday/plugins/common/src/p_floor.cpp | 135 ++ doomsday/plugins/common/src/p_plat.cpp | 92 ++ doomsday/plugins/common/src/p_saveg.cpp | 1351 +------------------ doomsday/plugins/common/src/p_scroll.cpp | 53 + doomsday/plugins/common/src/p_switch.cpp | 46 + doomsday/plugins/common/src/polyobjs.cpp | 118 ++ doomsday/plugins/doom/src/p_lights.cpp | 196 +++ doomsday/plugins/doom64/src/p_lights.cpp | 235 ++++ doomsday/plugins/heretic/src/p_lights.cpp | 163 +++ doomsday/plugins/hexen/include/acscript.h | 14 +- doomsday/plugins/hexen/include/p_pillar.h | 7 + doomsday/plugins/hexen/include/p_waggle.h | 7 + doomsday/plugins/hexen/src/acscript.cpp | 10 +- doomsday/plugins/hexen/src/p_lights.cpp | 107 ++ doomsday/plugins/hexen/src/p_pillar.cpp | 62 + doomsday/plugins/hexen/src/p_waggle.cpp | 67 + 27 files changed, 1622 insertions(+), 1308 deletions(-) diff --git a/doomsday/api/api_thinker.h b/doomsday/api/api_thinker.h index a7b972b106..622f163c68 100644 --- a/doomsday/api/api_thinker.h +++ b/doomsday/api/api_thinker.h @@ -23,6 +23,8 @@ #define LIBDENG_THINKER_H #include "api_base.h" +#include +#include #ifdef __DOOMSDAY__ namespace de { diff --git a/doomsday/plugins/common/include/p_ceiling.h b/doomsday/plugins/common/include/p_ceiling.h index ba09790054..a0198013c6 100644 --- a/doomsday/plugins/common/include/p_ceiling.h +++ b/doomsday/plugins/common/include/p_ceiling.h @@ -22,6 +22,8 @@ #ifndef LIBCOMMON_THINKER_CEILING_H #define LIBCOMMON_THINKER_CEILING_H +#include "doomsday.h" + #define CEILSPEED (1) #define CEILWAIT (150) @@ -64,6 +66,11 @@ typedef struct { ceilingstate_e state; ceilingstate_e oldState; int tag; // id. + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } ceiling_t; #ifdef __cplusplus diff --git a/doomsday/plugins/common/include/p_door.h b/doomsday/plugins/common/include/p_door.h index 0742d5e81d..15d6d1354a 100644 --- a/doomsday/plugins/common/include/p_door.h +++ b/doomsday/plugins/common/include/p_door.h @@ -64,6 +64,11 @@ typedef struct { doorstate_e state; int topWait; // Tics to wait at the top. int topCountDown; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } door_t; #ifdef __cplusplus diff --git a/doomsday/plugins/common/include/p_floor.h b/doomsday/plugins/common/include/p_floor.h index a1fd1b010e..e3172e9e08 100644 --- a/doomsday/plugins/common/include/p_floor.h +++ b/doomsday/plugins/common/include/p_floor.h @@ -22,6 +22,8 @@ #ifndef LIBCOMMON_THINKER_FLOOR_H #define LIBCOMMON_THINKER_FLOOR_H +#include "doomsday.h" + #define FLOORSPEED (1) typedef enum { @@ -100,6 +102,11 @@ typedef struct { short resetDelay; short resetDelayCount; #endif + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } floor_t; #ifdef __cplusplus diff --git a/doomsday/plugins/common/include/p_plat.h b/doomsday/plugins/common/include/p_plat.h index 332e2cbebe..13f2871fdf 100644 --- a/doomsday/plugins/common/include/p_plat.h +++ b/doomsday/plugins/common/include/p_plat.h @@ -22,6 +22,8 @@ #ifndef LIBCOMMON_THINKER_PLAT_H #define LIBCOMMON_THINKER_PLAT_H +#include "doomsday.h" + #define PLATWAIT (3) #define PLATSPEED (1) @@ -68,6 +70,11 @@ typedef struct plat_s { dd_bool crush; int tag; plattype_e type; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } plat_t; #ifdef __cplusplus diff --git a/doomsday/plugins/common/include/p_saveg.h b/doomsday/plugins/common/include/p_saveg.h index e4f3bf4a8f..f49324e7fd 100644 --- a/doomsday/plugins/common/include/p_saveg.h +++ b/doomsday/plugins/common/include/p_saveg.h @@ -21,6 +21,9 @@ #ifndef LIBCOMMON_SAVESTATE_H #define LIBCOMMON_SAVESTATE_H +#ifdef __cplusplus +#include "dmu_archiveindex.h" +#endif #include "p_saveio.h" /** @@ -270,6 +273,8 @@ void SV_HxRestorePlayersInCluster(playerbackup_t playerBackup[MAXPLAYERS], uint #ifdef __cplusplus } // extern "C" + +dmu_lib::SideArchive &SV_SideArchive(); #endif #endif // LIBCOMMON_SAVESTATE_H diff --git a/doomsday/plugins/common/include/p_scroll.h b/doomsday/plugins/common/include/p_scroll.h index a26235746d..0c10a13072 100644 --- a/doomsday/plugins/common/include/p_scroll.h +++ b/doomsday/plugins/common/include/p_scroll.h @@ -29,6 +29,11 @@ typedef struct { void *dmuObject; ///< Affected DMU object (either a sector or a side). int elementBits; ///< Identifies which subelements of the dmuObject are affected. float offset[2]; ///< [x, y] scroll vector delta. + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } scroll_t; #ifdef __cplusplus diff --git a/doomsday/plugins/common/include/p_switch.h b/doomsday/plugins/common/include/p_switch.h index 21d024d48b..0c03754f29 100644 --- a/doomsday/plugins/common/include/p_switch.h +++ b/doomsday/plugins/common/include/p_switch.h @@ -31,9 +31,14 @@ typedef struct { thinker_t thinker; int timer; - Side* side; + Side *side; SideSection section; Material *material; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } materialchanger_t; #ifdef __cplusplus diff --git a/doomsday/plugins/common/include/polyobjs.h b/doomsday/plugins/common/include/polyobjs.h index e37192aa74..2f0ab8c240 100644 --- a/doomsday/plugins/common/include/polyobjs.h +++ b/doomsday/plugins/common/include/polyobjs.h @@ -31,26 +31,36 @@ typedef enum { } podoortype_t; typedef struct { - thinker_t thinker; - int polyobj; // tag - int intSpeed; - unsigned int dist; - int fangle; - coord_t speed[2]; // for sliding doors + thinker_t thinker; + int polyobj; // tag + int intSpeed; + unsigned int dist; + int fangle; + coord_t speed[2]; // for sliding doors + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } polyevent_t; typedef struct { - thinker_t thinker; - int polyobj; // tag - int intSpeed; - int dist; - int totalDist; - int direction; - float speed[2]; - int tics; - int waitTics; - podoortype_t type; - dd_bool close; + thinker_t thinker; + int polyobj; // tag + int intSpeed; + int dist; + int totalDist; + int direction; + float speed[2]; + int tics; + int waitTics; + podoortype_t type; + dd_bool close; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } polydoor_t; typedef struct polyobj_s { diff --git a/doomsday/plugins/common/src/p_ceiling.cpp b/doomsday/plugins/common/src/p_ceiling.cpp index 392039c9e6..7b24af233f 100644 --- a/doomsday/plugins/common/src/p_ceiling.cpp +++ b/doomsday/plugins/common/src/p_ceiling.cpp @@ -228,6 +228,112 @@ void T_MoveCeiling(void *ceilingThinkerPtr) } } +void ceiling_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 2); // Write a version byte. + + Writer_WriteByte(writer, (byte) type); + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt16(writer, (int)bottomHeight); + Writer_WriteInt16(writer, (int)topHeight); + Writer_WriteInt32(writer, FLT2FIX(speed)); + + Writer_WriteByte(writer, crush); + + Writer_WriteByte(writer, (byte) state); + Writer_WriteInt32(writer, tag); + Writer_WriteByte(writer, (byte) oldState); +} + +int ceiling_t::read(Reader *reader, int mapVersion) +{ +#if __JHEXEN__ + if(mapVersion >= 4) +#else + if(mapVersion >= 5) +#endif + { + // Note: the thinker class byte has already been read. + int ver = Reader_ReadByte(reader); // version byte. + + thinker.function = T_MoveCeiling; + +#if !__JHEXEN__ + // Should we put this into stasis? + if(mapVersion == 5) + { + if(!Reader_ReadByte(reader)) + Thinker_SetStasis(&thinker, true); + } +#endif + + type = (ceilingtype_e) Reader_ReadByte(reader); + + sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + bottomHeight = (float) Reader_ReadInt16(reader); + topHeight = (float) Reader_ReadInt16(reader); + speed = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + + crush = Reader_ReadByte(reader); + + if(ver == 2) + state = ceilingstate_e(Reader_ReadByte(reader)); + else + state = ceilingstate_e(Reader_ReadInt32(reader) == -1? CS_DOWN : CS_UP); + + tag = Reader_ReadInt32(reader); + + if(ver == 2) + oldState = ceilingstate_e(Reader_ReadByte(reader)); + else + state = (Reader_ReadInt32(reader) == -1? CS_DOWN : CS_UP); + } + else + { + // Its in the old format which serialized ceiling_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. +#if __JHEXEN__ + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + type = ceilingtype_e(Reader_ReadInt32(reader)); +#else + type = ceilingtype_e(Reader_ReadInt32(reader)); + + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); +#endif + + bottomHeight = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + topHeight = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + speed = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + + crush = Reader_ReadInt32(reader); + state = (Reader_ReadInt32(reader) == -1? CS_DOWN : CS_UP); + tag = Reader_ReadInt32(reader); + oldState = (Reader_ReadInt32(reader) == -1? CS_DOWN : CS_UP); + + thinker.function = T_MoveCeiling; +#if !__JHEXEN__ + if(!((thinker_t *)junk)->function) + Thinker_SetStasis(&thinker, true); +#endif + } + + P_ToXSector(sector)->specialData = this; + + return true; // Add this thinker. +} + #if __JDOOM64__ static int EV_DoCeiling2(Line *line, int tag, float basespeed, ceilingtype_e type) #elif __JHEXEN__ diff --git a/doomsday/plugins/common/src/p_door.cpp b/doomsday/plugins/common/src/p_door.cpp index 0e4e59f94c..b4d454b2d0 100644 --- a/doomsday/plugins/common/src/p_door.cpp +++ b/doomsday/plugins/common/src/p_door.cpp @@ -285,6 +285,78 @@ void T_Door(void *doorThinkerPtr) } } +void door_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteByte(writer, (byte) type); + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt16(writer, (int)topHeight); + Writer_WriteInt32(writer, FLT2FIX(speed)); + + Writer_WriteInt32(writer, state); + Writer_WriteInt32(writer, topWait); + Writer_WriteInt32(writer, topCountDown); +} + +int door_t::read(Reader *reader, int mapVersion) +{ +#if __JHEXEN__ + if(mapVersion >= 4) +#else + if(mapVersion >= 5) +#endif + { // Note: the thinker class byte has already been read. + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + type = doortype_e(Reader_ReadByte(reader)); + sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + topHeight = (float) Reader_ReadInt16(reader); + speed = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + + state = doorstate_e(Reader_ReadInt32(reader)); + topWait = Reader_ReadInt32(reader); + topCountDown = Reader_ReadInt32(reader); + } + else + { + // Its in the old format which serialized door_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. +#if __JHEXEN__ + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(reader)); + type = doortype_e(Reader_ReadInt32(reader)); +#else + type = doortype_e(Reader_ReadInt32(reader)); + + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(reader)); +#endif + topHeight = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + speed = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + + state = doorstate_e(Reader_ReadInt32(reader)); + topWait = Reader_ReadInt32(reader); + topCountDown = Reader_ReadInt32(reader); + } + + P_ToXSector(sector)->specialData = this; + thinker.function = T_Door; + + return true; // Add this thinker. +} + static int EV_DoDoor2(int tag, float speed, int topwait, doortype_e type) { iterlist_t *list = P_GetSectorIterListForTag(tag, false); diff --git a/doomsday/plugins/common/src/p_floor.cpp b/doomsday/plugins/common/src/p_floor.cpp index c60c440b7b..0aff9dc42b 100644 --- a/doomsday/plugins/common/src/p_floor.cpp +++ b/doomsday/plugins/common/src/p_floor.cpp @@ -34,6 +34,7 @@ #include "p_ceiling.h" #endif #include "p_sound.h" +#include "p_saveg.h" #if __JHERETIC__ # define SFX_FLOORMOVE (SFX_DORMOV) @@ -394,6 +395,140 @@ void T_MoveFloor(void *floorThinkerPtr) } } +void floor_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 3); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteByte(writer, (byte) type); + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteByte(writer, (byte) crush); + + Writer_WriteInt32(writer, (int) state); + Writer_WriteInt32(writer, newSpecial); + + Writer_WriteInt16(writer, MaterialArchive_FindUniqueSerialId(SV_MaterialArchive(), material)); + + Writer_WriteInt16(writer, (int) floorDestHeight); + Writer_WriteInt32(writer, FLT2FIX(speed)); + +#if __JHEXEN__ + Writer_WriteInt32(writer, delayCount); + Writer_WriteInt32(writer, delayTotal); + Writer_WriteInt32(writer, FLT2FIX(stairsDelayHeight)); + Writer_WriteInt32(writer, FLT2FIX(stairsDelayHeightDelta)); + Writer_WriteInt32(writer, FLT2FIX(resetHeight)); + Writer_WriteInt16(writer, resetDelay); + Writer_WriteInt16(writer, resetDelayCount); +#endif +} + +int floor_t::read(Reader *reader, int mapVersion) +{ +#if __JHEXEN__ + if(mapVersion >= 4) +#else + if(mapVersion >= 5) +#endif + { // Note: the thinker class byte has already been read. + byte ver = SV_ReadByte(); // version byte. + + type = floortype_e(Reader_ReadByte(reader)); + sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + crush = dd_bool(Reader_ReadByte(reader)); + state = floorstate_e(Reader_ReadInt32(reader)); + newSpecial = Reader_ReadInt32(reader); + + if(ver >= 2) + { + material = SV_GetArchiveMaterial(Reader_ReadInt16(reader), 0); + } + else + { + // Flat number is an absolute lump index. + Uri *uri = Uri_NewWithPath2("Flats:", RC_NULL); + ddstring_t name; Str_Init(&name); + F_FileName(&name, Str_Text(W_LumpName(Reader_ReadInt16(reader)))); + Uri_SetPath(uri, Str_Text(&name)); + material = (Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); + Uri_Delete(uri); + Str_Free(&name); + } + + floorDestHeight = (float) Reader_ReadInt16(reader); + speed = FIX2FLT(Reader_ReadInt32(reader)); + +#if __JHEXEN__ + delayCount = Reader_ReadInt32(reader); + delayTotal = Reader_ReadInt32(reader); + stairsDelayHeight = FIX2FLT(Reader_ReadInt32(reader)); + stairsDelayHeightDelta = FIX2FLT(Reader_ReadInt32(reader)); + resetHeight = FIX2FLT(Reader_ReadInt32(reader)); + resetDelay = Reader_ReadInt16(reader); + resetDelayCount = Reader_ReadInt16(reader); +#endif + } + else + { + // Its in the old format which serialized floor_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. +#if __JHEXEN__ + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + type = floortype_e(Reader_ReadInt32(reader)); + crush = Reader_ReadInt32(reader); +#else + type = floortype_e(Reader_ReadInt32(reader)); + crush = Reader_ReadInt32(reader); + + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); +#endif + state = floorstate_e(Reader_ReadInt32(reader)); + newSpecial = Reader_ReadInt32(reader); + + // Flat number is an absolute lump index. + Uri *uri = Uri_NewWithPath2("Flats:", RC_NULL); + ddstring_t name; Str_Init(&name); + F_FileName(&name, Str_Text(W_LumpName(Reader_ReadInt16(reader)))); + Uri_SetPath(uri, Str_Text(&name)); + material = (Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); + Uri_Delete(uri); + Str_Free(&name); + + floorDestHeight = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + speed = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + +#if __JHEXEN__ + delayCount = Reader_ReadInt32(reader); + delayTotal = Reader_ReadInt32(reader); + stairsDelayHeight = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + stairsDelayHeightDelta = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + resetHeight = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + resetDelay = Reader_ReadInt16(reader); + resetDelayCount = Reader_ReadInt16(reader); + /*textureChange =*/ Reader_ReadByte(reader); +#endif + } + + P_ToXSector(sector)->specialData = this; + thinker.function = T_MoveFloor; + + return true; // Add this thinker. +} + struct findlineinsectorsmallestbottommaterialparams_t { Sector *baseSec; diff --git a/doomsday/plugins/common/src/p_plat.cpp b/doomsday/plugins/common/src/p_plat.cpp index 2696b73dfd..72d778772e 100644 --- a/doomsday/plugins/common/src/p_plat.cpp +++ b/doomsday/plugins/common/src/p_plat.cpp @@ -199,6 +199,98 @@ void T_PlatRaise(void *platThinkerPtr) } } +void plat_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + Writer_WriteByte(writer, (byte) type); + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt32(writer, FLT2FIX(speed)); + Writer_WriteInt16(writer, (int)low); + Writer_WriteInt16(writer, (int)high); + + Writer_WriteInt32(writer, wait); + Writer_WriteInt32(writer, count); + + Writer_WriteByte(writer, (byte) state); + Writer_WriteByte(writer, (byte) oldState); + Writer_WriteByte(writer, (byte) crush); + + Writer_WriteInt32(writer, tag); +} + +int plat_t::read(Reader *reader, int mapVersion) +{ +#if __JHEXEN__ + if(mapVersion >= 4) +#else + if(mapVersion >= 5) +#endif + { // Note: the thinker class byte has already been read. + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + thinker.function = T_PlatRaise; + +#if !__JHEXEN__ + // Should we put this into stasis? + if(mapVersion == 5) + { + if(!Reader_ReadByte(reader)) + Thinker_SetStasis(&thinker, true); + } +#endif + + type = plattype_e(Reader_ReadByte(reader)); + sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + speed = FIX2FLT(Reader_ReadInt32(reader)); + low = (float) Reader_ReadInt16(reader); + high = (float) Reader_ReadInt16(reader); + wait = Reader_ReadInt32(reader); + count = Reader_ReadInt32(reader); + state = platstate_e(Reader_ReadByte(reader)); + oldState = platstate_e(Reader_ReadByte(reader)); + crush = (dd_bool) Reader_ReadByte(reader); + tag = Reader_ReadInt32(reader); + } + else + { + // Its in the old format which serialized plat_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + speed = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + low = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + high = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + + wait = Reader_ReadInt32(reader); + count = Reader_ReadInt32(reader); + state = platstate_e(Reader_ReadInt32(reader)); + oldState = platstate_e(Reader_ReadInt32(reader)); + crush = Reader_ReadInt32(reader); + tag = Reader_ReadInt32(reader); + type = plattype_e(Reader_ReadInt32(reader)); + + thinker.function = T_PlatRaise; +#if !__JHEXEN__ + if(!((thinker_t *)junk)->function) + Thinker_SetStasis(&thinker, true); +#endif + } + + P_ToXSector(sector)->specialData = this; + + return true; // Add this thinker. +} + #if __JHEXEN__ static int doPlat(Line* line, int tag, byte* args, plattype_e type, int amount) #else diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index 0e55ef0cfb..a81b40e823 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -115,57 +115,15 @@ typedef enum { NUM_LINECLASSES } lineclass_t; -SideArchive &SV_SideArchive(); - static bool recogniseGameState(Str const *path, SaveInfo *info); static void SV_WriteMobj(mobj_t const *mobj); static int SV_ReadMobj(thinker_t *th, int mapVersion); -static void SV_WriteCeiling(ceiling_t const *ceiling); -static int SV_ReadCeiling(ceiling_t *ceiling, int mapVersion); -static void SV_WriteDoor(door_t const *door); -static int SV_ReadDoor(door_t *door, int mapVersion); -static void SV_WriteFloor(floor_t const *floor); -static int SV_ReadFloor(floor_t *floor, int mapVersion); -static void SV_WritePlat(plat_t const *plat); -static int SV_ReadPlat(plat_t *plat, int mapVersion); -static void SV_WriteMaterialChanger(materialchanger_t const *mchanger); -static int SV_ReadMaterialChanger(materialchanger_t *mchanger, int mapVersion); - -#if __JHEXEN__ -static void SV_WriteLight(light_t const *light); -static int SV_ReadLight(light_t *light, int mapVersion); -static void SV_WritePhase(phase_t const *phase); -static int SV_ReadPhase(phase_t *phase, int mapVersion); -static void SV_WriteDoorPoly(polydoor_t const *polydoor); -static int SV_ReadDoorPoly(polydoor_t *polydoor, int mapVersion); + +#if __JHEXEN__ static void SV_WriteMovePoly(polyevent_t const *movepoly); static int SV_ReadMovePoly(polyevent_t *movepoly, int mapVersion); -static void SV_WriteRotatePoly(polyevent_t const *rotatepoly); -static int SV_ReadRotatePoly(polyevent_t *rotatepoly, int mapVersion); -static void SV_WritePillar(pillar_t const *pillar); -static int SV_ReadPillar(pillar_t *pillar, int mapVersion); -static void SV_WriteFloorWaggle(waggle_t const *floorwaggle); -static int SV_ReadFloorWaggle(waggle_t *floorwaggle, int mapVersion); -#else -static void SV_WriteFlash(lightflash_t const *flash); -static int SV_ReadFlash(lightflash_t *flash, int mapVersion); -static void SV_WriteStrobe(strobe_t const *strobe); -static int SV_ReadStrobe(strobe_t *strobe, int mapVersion); -static void SV_WriteGlow(glow_t const *glow); -static int SV_ReadGlow(glow_t *glow, int mapVersion); -# if __JDOOM__ || __JDOOM64__ -static void SV_WriteFlicker(fireflicker_t const *flicker); -static int SV_ReadFlicker(fireflicker_t *flicker, int mapVersion); -# endif - -# if __JDOOM64__ -static void SV_WriteBlink(lightblink_t const *flicker); -static int SV_ReadBlink(lightblink_t *flicker, int mapVersion); -# endif #endif -static void SV_WriteScroll(scroll_t const *scroll); -static int SV_ReadScroll(scroll_t *scroll, int mapVersion); #if __JHEXEN__ static void readMapState(Reader *reader, Str const *path); @@ -208,19 +166,19 @@ static int numSoundTargets; static MaterialArchive *materialArchive; static SideArchive *sideArchive; -#if __JHEXEN__ -static void writeACScript(thinker_t *th, Writer *writer) +template +static void writeThinkerAs(thinker_t const *th, Writer *writer) { - ACScript *script = (ACScript *)th; - script->write(writer); + Type *t = (Type*)th; + t->write(writer); } -static int readACScript(thinker_t *th, Reader *reader, int mapVersion) +template +static int readThinkerAs(thinker_t *th, Reader *reader, int mapVersion) { - ACScript *script = (ACScript *)th; - return script->read(reader, mapVersion); + Type *t = (Type *)th; + return t->read(reader, mapVersion); } -#endif static ThinkerClassInfo thinkerInfo[] = { { @@ -245,32 +203,32 @@ static ThinkerClassInfo thinkerInfo[] = { TC_CEILING, T_MoveCeiling, 0, - (WriteThinkerFunc) SV_WriteCeiling, - (ReadThinkerFunc) SV_ReadCeiling, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(ceiling_t) }, { TC_DOOR, T_Door, 0, - (WriteThinkerFunc) SV_WriteDoor, - (ReadThinkerFunc) SV_ReadDoor, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(door_t) }, { TC_FLOOR, T_MoveFloor, 0, - (WriteThinkerFunc) SV_WriteFloor, - (ReadThinkerFunc) SV_ReadFloor, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(floor_t) }, { TC_PLAT, T_PlatRaise, 0, - (WriteThinkerFunc) SV_WritePlat, - (ReadThinkerFunc) SV_ReadPlat, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(plat_t) }, #if __JHEXEN__ @@ -278,48 +236,48 @@ static ThinkerClassInfo thinkerInfo[] = { TC_INTERPRET_ACS, (thinkfunc_t) ACScript_Thinker, 0, - (WriteThinkerFunc)writeACScript, - (ReadThinkerFunc)readACScript, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(ACScript) }, { TC_FLOOR_WAGGLE, (thinkfunc_t) T_FloorWaggle, 0, - (WriteThinkerFunc)SV_WriteFloorWaggle, - (ReadThinkerFunc)SV_ReadFloorWaggle, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(waggle_t) }, { TC_LIGHT, (thinkfunc_t) T_Light, 0, - (WriteThinkerFunc)SV_WriteLight, - (ReadThinkerFunc)SV_ReadLight, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(light_t) }, { TC_PHASE, (thinkfunc_t) T_Phase, 0, - (WriteThinkerFunc)SV_WritePhase, - (ReadThinkerFunc)SV_ReadPhase, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(phase_t) }, { TC_BUILD_PILLAR, (thinkfunc_t) T_BuildPillar, 0, - (WriteThinkerFunc)SV_WritePillar, - (ReadThinkerFunc)SV_ReadPillar, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(pillar_t) }, { TC_ROTATE_POLY, T_RotatePoly, 0, - (WriteThinkerFunc)SV_WriteRotatePoly, - (ReadThinkerFunc)SV_ReadRotatePoly, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(polyevent_t) }, { @@ -334,8 +292,8 @@ static ThinkerClassInfo thinkerInfo[] = { TC_POLY_DOOR, T_PolyDoor, 0, - (WriteThinkerFunc)SV_WriteDoorPoly, - (ReadThinkerFunc)SV_ReadDoorPoly, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(polydoor_t) }, #else @@ -343,24 +301,24 @@ static ThinkerClassInfo thinkerInfo[] = { TC_FLASH, (thinkfunc_t) T_LightFlash, 0, - (WriteThinkerFunc) SV_WriteFlash, - (ReadThinkerFunc) SV_ReadFlash, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(lightflash_t) }, { TC_STROBE, (thinkfunc_t) T_StrobeFlash, 0, - (WriteThinkerFunc) SV_WriteStrobe, - (ReadThinkerFunc) SV_ReadStrobe, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(strobe_t) }, { TC_GLOW, (thinkfunc_t) T_Glow, 0, - (WriteThinkerFunc) SV_WriteGlow, - (ReadThinkerFunc) SV_ReadGlow, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(glow_t) }, # if __JDOOM__ || __JDOOM64__ @@ -368,8 +326,8 @@ static ThinkerClassInfo thinkerInfo[] = { TC_FLICKER, (thinkfunc_t) T_FireFlicker, 0, - (WriteThinkerFunc) SV_WriteFlicker, - (ReadThinkerFunc) SV_ReadFlicker, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(fireflicker_t) }, # endif @@ -378,8 +336,8 @@ static ThinkerClassInfo thinkerInfo[] = { TC_BLINK, (thinkfunc_t) T_LightBlink, 0, - (WriteThinkerFunc) SV_WriteBlink, - (ReadThinkerFunc) SV_ReadBlink, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(lightblink_t) }, # endif @@ -388,17 +346,17 @@ static ThinkerClassInfo thinkerInfo[] = { TC_MATERIALCHANGER, T_MaterialChanger, 0, - (WriteThinkerFunc) SV_WriteMaterialChanger, - (ReadThinkerFunc) SV_ReadMaterialChanger, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(materialchanger_t) }, { - TC_SCROLL, - (thinkfunc_t) T_Scroll, - 0, - (WriteThinkerFunc) SV_WriteScroll, - (ReadThinkerFunc) SV_ReadScroll, - sizeof(scroll_t) + TC_SCROLL, + (thinkfunc_t) T_Scroll, + 0, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, + sizeof(scroll_t) }, { TC_NULL, NULL, 0, NULL, NULL, 0 } }; @@ -2968,426 +2926,8 @@ static void readMapElements(Reader *reader) #endif } -static void SV_WriteCeiling(ceiling_t const *ceiling) -{ - SV_WriteByte(2); // Write a version byte. - - SV_WriteByte((byte) ceiling->type); - SV_WriteLong(P_ToIndex(ceiling->sector)); - - SV_WriteShort((int)ceiling->bottomHeight); - SV_WriteShort((int)ceiling->topHeight); - SV_WriteLong(FLT2FIX(ceiling->speed)); - - SV_WriteByte(ceiling->crush); - - SV_WriteByte((byte) ceiling->state); - SV_WriteLong(ceiling->tag); - SV_WriteByte((byte) ceiling->oldState); -} - -static int SV_ReadCeiling(ceiling_t *ceiling, int /*mapVersion*/) -{ -#if __JHEXEN__ - if(mapVersion >= 4) -#else - if(hdr->version >= 5) -#endif - { - // Note: the thinker class byte has already been read. - int ver = SV_ReadByte(); // version byte. - - ceiling->thinker.function = T_MoveCeiling; - -#if !__JHEXEN__ - // Should we put this into stasis? - if(hdr->version == 5) - { - if(!SV_ReadByte()) - Thinker_SetStasis(&ceiling->thinker, true); - } -#endif - - ceiling->type = (ceilingtype_e) SV_ReadByte(); - - ceiling->sector = (Sector *)P_ToPtr(DMU_SECTOR, SV_ReadLong()); - DENG_ASSERT(ceiling->sector != 0); - - ceiling->bottomHeight = (float) SV_ReadShort(); - ceiling->topHeight = (float) SV_ReadShort(); - ceiling->speed = FIX2FLT((fixed_t) SV_ReadLong()); - - ceiling->crush = SV_ReadByte(); - - if(ver == 2) - ceiling->state = ceilingstate_e(SV_ReadByte()); - else - ceiling->state = ceilingstate_e(SV_ReadLong() == -1? CS_DOWN : CS_UP); - - ceiling->tag = SV_ReadLong(); - - if(ver == 2) - ceiling->oldState = ceilingstate_e(SV_ReadByte()); - else - ceiling->state = (SV_ReadLong() == -1? CS_DOWN : CS_UP); - } - else - { - // Its in the old format which serialized ceiling_t - // Padding at the start (an old thinker_t struct) - thinker_t junk; - SV_Read(&junk, (size_t) 16); - - // Start of used data members. -#if __JHEXEN__ - // A 32bit pointer to sector, serialized. - ceiling->sector = (Sector *)P_ToPtr(DMU_SECTOR, SV_ReadLong()); - DENG_ASSERT(ceiling->sector != 0); - - ceiling->type = ceilingtype_e(SV_ReadLong()); -#else - ceiling->type = ceilingtype_e(SV_ReadLong()); - - // A 32bit pointer to sector, serialized. - ceiling->sector = (Sector *)P_ToPtr(DMU_SECTOR, SV_ReadLong()); - DENG_ASSERT(ceiling->sector != 0); -#endif - - ceiling->bottomHeight = FIX2FLT((fixed_t) SV_ReadLong()); - ceiling->topHeight = FIX2FLT((fixed_t) SV_ReadLong()); - ceiling->speed = FIX2FLT((fixed_t) SV_ReadLong()); - - ceiling->crush = SV_ReadLong(); - ceiling->state = (SV_ReadLong() == -1? CS_DOWN : CS_UP); - ceiling->tag = SV_ReadLong(); - ceiling->oldState = (SV_ReadLong() == -1? CS_DOWN : CS_UP); - - ceiling->thinker.function = T_MoveCeiling; -#if !__JHEXEN__ - if(!junk.function) - Thinker_SetStasis(&ceiling->thinker, true); -#endif - } - - P_ToXSector(ceiling->sector)->specialData = ceiling; - return true; // Add this thinker. -} - -static void SV_WriteDoor(door_t const *door) -{ - SV_WriteByte(1); // Write a version byte. - - // Note we don't bother to save a byte to tell if the function - // is present as we ALWAYS add one when loading. - - SV_WriteByte((byte) door->type); - - SV_WriteLong(P_ToIndex(door->sector)); - - SV_WriteShort((int)door->topHeight); - SV_WriteLong(FLT2FIX(door->speed)); - - SV_WriteLong(door->state); - SV_WriteLong(door->topWait); - SV_WriteLong(door->topCountDown); -} - -static int SV_ReadDoor(door_t *door, int /*mapVersion*/) -{ - DENG_ASSERT(door != 0); - -#if __JHEXEN__ - if(mapVersion >= 4) -#else - if(hdr->version >= 5) -#endif - { // Note: the thinker class byte has already been read. - /*int ver =*/ SV_ReadByte(); // version byte. - - door->type = doortype_e(SV_ReadByte()); - door->sector = (Sector *)P_ToPtr(DMU_SECTOR, SV_ReadLong()); - DENG_ASSERT(door->sector != 0); - - door->topHeight = (float) SV_ReadShort(); - door->speed = FIX2FLT((fixed_t) SV_ReadLong()); - - door->state = doorstate_e(SV_ReadLong()); - door->topWait = SV_ReadLong(); - door->topCountDown = SV_ReadLong(); - } - else - { - // Its in the old format which serialized door_t - // Padding at the start (an old thinker_t struct) - SV_Seek(16); - - // Start of used data members. -#if __JHEXEN__ - // A 32bit pointer to sector, serialized. - door->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - door->type = doortype_e(SV_ReadLong()); -#else - door->type = doortype_e(SV_ReadLong()); - - // A 32bit pointer to sector, serialized. - door->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); -#endif - door->topHeight = FIX2FLT((fixed_t) SV_ReadLong()); - door->speed = FIX2FLT((fixed_t) SV_ReadLong()); - - door->state = doorstate_e(SV_ReadLong()); - door->topWait = SV_ReadLong(); - door->topCountDown = SV_ReadLong(); - } - - P_ToXSector(door->sector)->specialData = door; - door->thinker.function = T_Door; - - return true; // Add this thinker. -} - -static void SV_WriteFloor(floor_t const *floor) -{ - DENG_ASSERT(floor != 0); - - SV_WriteByte(3); // Write a version byte. - - // Note we don't bother to save a byte to tell if the function - // is present as we ALWAYS add one when loading. - - SV_WriteByte((byte) floor->type); - - SV_WriteLong(P_ToIndex(floor->sector)); - - SV_WriteByte((byte) floor->crush); - - SV_WriteLong((int) floor->state); - SV_WriteLong(floor->newSpecial); - - SV_WriteShort(MaterialArchive_FindUniqueSerialId(materialArchive, floor->material)); - - SV_WriteShort((int) floor->floorDestHeight); - SV_WriteLong(FLT2FIX(floor->speed)); - -#if __JHEXEN__ - SV_WriteLong(floor->delayCount); - SV_WriteLong(floor->delayTotal); - SV_WriteLong(FLT2FIX(floor->stairsDelayHeight)); - SV_WriteLong(FLT2FIX(floor->stairsDelayHeightDelta)); - SV_WriteLong(FLT2FIX(floor->resetHeight)); - SV_WriteShort(floor->resetDelay); - SV_WriteShort(floor->resetDelayCount); -#endif -} - -static int SV_ReadFloor(floor_t *floor, int /*mapVersion*/) -{ - DENG_ASSERT(floor != 0); - -#if __JHEXEN__ - if(mapVersion >= 4) -#else - if(hdr->version >= 5) -#endif - { // Note: the thinker class byte has already been read. - byte ver = SV_ReadByte(); // version byte. - - floor->type = floortype_e(SV_ReadByte()); - - floor->sector = (Sector *)P_ToPtr(DMU_SECTOR, SV_ReadLong()); - DENG_ASSERT(floor->sector != 0); - - floor->crush = dd_bool(SV_ReadByte()); - floor->state = floorstate_e(SV_ReadLong()); - floor->newSpecial = SV_ReadLong(); - - if(ver >= 2) - { - floor->material = SV_GetArchiveMaterial(SV_ReadShort(), 0); - } - else - { - // Flat number is an absolute lump index. - Uri *uri = Uri_NewWithPath2("Flats:", RC_NULL); - ddstring_t name; - Str_Init(&name); - F_FileName(&name, Str_Text(W_LumpName(SV_ReadShort()))); - Uri_SetPath(uri, Str_Text(&name)); - floor->material = (Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); - Uri_Delete(uri); - Str_Free(&name); - } - - floor->floorDestHeight = (float) SV_ReadShort(); - floor->speed = FIX2FLT(SV_ReadLong()); - -#if __JHEXEN__ - floor->delayCount = SV_ReadLong(); - floor->delayTotal = SV_ReadLong(); - floor->stairsDelayHeight = FIX2FLT(SV_ReadLong()); - floor->stairsDelayHeightDelta = FIX2FLT(SV_ReadLong()); - floor->resetHeight = FIX2FLT(SV_ReadLong()); - floor->resetDelay = SV_ReadShort(); - floor->resetDelayCount = SV_ReadShort(); -#endif - } - else - { - // Its in the old format which serialized floor_t - // Padding at the start (an old thinker_t struct) - SV_Seek(16); - - // Start of used data members. -#if __JHEXEN__ - // A 32bit pointer to sector, serialized. - floor->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(floor->sector != 0); - - floor->type = floortype_e(SV_ReadLong()); - floor->crush = SV_ReadLong(); -#else - floor->type = floortype_e(SV_ReadLong()); - floor->crush = SV_ReadLong(); - - // A 32bit pointer to sector, serialized. - floor->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(floor->sector != 0); -#endif - floor->state = floorstate_e(SV_ReadLong()); - floor->newSpecial = SV_ReadLong(); - - // Flat number is an absolute lump index. - Uri *uri = Uri_NewWithPath2("Flats:", RC_NULL); - ddstring_t name; - Str_Init(&name); - F_FileName(&name, Str_Text(W_LumpName(SV_ReadShort()))); - Uri_SetPath(uri, Str_Text(&name)); - floor->material = (Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); - Uri_Delete(uri); - Str_Free(&name); - - floor->floorDestHeight = FIX2FLT((fixed_t) SV_ReadLong()); - floor->speed = FIX2FLT((fixed_t) SV_ReadLong()); - -#if __JHEXEN__ - floor->delayCount = SV_ReadLong(); - floor->delayTotal = SV_ReadLong(); - floor->stairsDelayHeight = FIX2FLT((fixed_t) SV_ReadLong()); - floor->stairsDelayHeightDelta = FIX2FLT((fixed_t) SV_ReadLong()); - floor->resetHeight = FIX2FLT((fixed_t) SV_ReadLong()); - floor->resetDelay = SV_ReadShort(); - floor->resetDelayCount = SV_ReadShort(); - /*floor->textureChange =*/ SV_ReadByte(); -#endif - } - - P_ToXSector(floor->sector)->specialData = floor; - floor->thinker.function = T_MoveFloor; - - return true; // Add this thinker. -} - -static void SV_WritePlat(plat_t const *plat) -{ - DENG_ASSERT(plat != 0); - - SV_WriteByte(1); // Write a version byte. - - SV_WriteByte((byte) plat->type); - - SV_WriteLong(P_ToIndex(plat->sector)); - - SV_WriteLong(FLT2FIX(plat->speed)); - SV_WriteShort((int)plat->low); - SV_WriteShort((int)plat->high); - - SV_WriteLong(plat->wait); - SV_WriteLong(plat->count); - - SV_WriteByte((byte) plat->state); - SV_WriteByte((byte) plat->oldState); - SV_WriteByte((byte) plat->crush); - - SV_WriteLong(plat->tag); -} - -static int SV_ReadPlat(plat_t *plat, int /*mapVersion*/) -{ - DENG_ASSERT(plat != 0); - -#if __JHEXEN__ - if(mapVersion >= 4) -#else - if(hdr->version >= 5) -#endif - { // Note: the thinker class byte has already been read. - /*int ver =*/ SV_ReadByte(); // version byte. - - plat->thinker.function = T_PlatRaise; - -#if !__JHEXEN__ - // Should we put this into stasis? - if(hdr->version == 5) - { - if(!SV_ReadByte()) - Thinker_SetStasis(&plat->thinker, true); - } -#endif - - plat->type = plattype_e(SV_ReadByte()); - plat->sector = (Sector *)P_ToPtr(DMU_SECTOR, SV_ReadLong()); - DENG_ASSERT(plat->sector != 0); - - plat->speed = FIX2FLT(SV_ReadLong()); - plat->low = (float) SV_ReadShort(); - plat->high = (float) SV_ReadShort(); - - plat->wait = SV_ReadLong(); - plat->count = SV_ReadLong(); - - plat->state = platstate_e(SV_ReadByte()); - plat->oldState = platstate_e(SV_ReadByte()); - plat->crush = (dd_bool) SV_ReadByte(); - - plat->tag = SV_ReadLong(); - } - else - { - // Its in the old format which serialized plat_t - // Padding at the start (an old thinker_t struct) - thinker_t junk; - SV_Read(&junk, (size_t) 16); - - // Start of used data members. - // A 32bit pointer to sector, serialized. - plat->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(plat->sector != 0); - - plat->speed = FIX2FLT((fixed_t) SV_ReadLong()); - plat->low = FIX2FLT((fixed_t) SV_ReadLong()); - plat->high = FIX2FLT((fixed_t) SV_ReadLong()); - - plat->wait = SV_ReadLong(); - plat->count = SV_ReadLong(); - plat->state = platstate_e(SV_ReadLong()); - plat->oldState = platstate_e(SV_ReadLong()); - plat->crush = SV_ReadLong(); - plat->tag = SV_ReadLong(); - plat->type = plattype_e(SV_ReadLong()); - - plat->thinker.function = T_PlatRaise; -#if !__JHEXEN__ - if(!junk.function) - Thinker_SetStasis(&plat->thinker, true); -#endif - } - - P_ToXSector(plat->sector)->specialData = plat; - return true; // Add this thinker. -} - #if __JHEXEN__ -static void SV_WriteLight(light_t const *th) +static void SV_WriteMovePoly(polyevent_t const *th) { DENG_ASSERT(th != 0); @@ -3396,796 +2936,53 @@ static void SV_WriteLight(light_t const *th) // Note we don't bother to save a byte to tell if the function // is present as we ALWAYS add one when loading. - SV_WriteByte((byte) th->type); - - SV_WriteLong(P_ToIndex(th->sector)); - - SV_WriteLong((int) (255.0f * th->value1)); - SV_WriteLong((int) (255.0f * th->value2)); - SV_WriteLong(th->tics1); - SV_WriteLong(th->tics2); - SV_WriteLong(th->count); + SV_WriteLong(th->polyobj); + SV_WriteLong(th->intSpeed); + SV_WriteLong(th->dist); + SV_WriteLong(th->fangle); + SV_WriteLong(FLT2FIX(th->speed[VX])); + SV_WriteLong(FLT2FIX(th->speed[VY])); } -static int SV_ReadLight(light_t *th, int /*mapVersion*/) +static int SV_ReadMovePoly(polyevent_t *th, int /*mapVersion*/) { DENG_ASSERT(th != 0); if(mapVersion >= 4) { + // Note: the thinker class byte has already been read. /*int ver =*/ SV_ReadByte(); // version byte. - th->type = (lighttype_t) SV_ReadByte(); - - th->sector = (Sector *)P_ToPtr(DMU_SECTOR, SV_ReadLong()); - DENG_ASSERT(th->sector != 0); - - th->value1 = (float) SV_ReadLong() / 255.0f; - th->value2 = (float) SV_ReadLong() / 255.0f; - th->tics1 = SV_ReadLong(); - th->tics2 = SV_ReadLong(); - th->count = SV_ReadLong(); + // Start of used data members. + th->polyobj = SV_ReadLong(); + th->intSpeed = SV_ReadLong(); + th->dist = SV_ReadLong(); + th->fangle = SV_ReadLong(); + th->speed[VX] = FIX2FLT(SV_ReadLong()); + th->speed[VY] = FIX2FLT(SV_ReadLong()); } else { - // Its in the old pre V4 format which serialized light_t + // Its in the old pre V4 format which serialized polyevent_t // Padding at the start (an old thinker_t struct) thinker_t junk; SV_Read(&junk, (size_t) 16); // Start of used data members. - // A 32bit pointer to sector, serialized. - th->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(th->sector != 0); - - th->type = lighttype_t(SV_ReadLong()); - th->value1 = (float) SV_ReadLong() / 255.0f; - th->value2 = (float) SV_ReadLong() / 255.0f; - th->tics1 = SV_ReadLong(); - th->tics2 = SV_ReadLong(); - th->count = SV_ReadLong(); + th->polyobj = SV_ReadLong(); + th->intSpeed = SV_ReadLong(); + th->dist = SV_ReadLong(); + th->fangle = SV_ReadLong(); + th->speed[VX] = FIX2FLT(SV_ReadLong()); + th->speed[VY] = FIX2FLT(SV_ReadLong()); } - th->thinker.function = (thinkfunc_t) T_Light; + th->thinker.function = T_MovePoly; return true; // Add this thinker. } - -static void SV_WritePhase(phase_t const *th) -{ - DENG_ASSERT(th != 0); - - SV_WriteByte(1); // Write a version byte. - - // Note we don't bother to save a byte to tell if the function - // is present as we ALWAYS add one when loading. - - SV_WriteLong(P_ToIndex(th->sector)); - - SV_WriteLong(th->index); - SV_WriteLong((int) (255.0f * th->baseValue)); -} - -static int SV_ReadPhase(phase_t *th, int /*mapVersion*/) -{ - DENG_ASSERT(th != 0); - - if(mapVersion >= 4) - { - // Note: the thinker class byte has already been read. - /*int ver =*/ SV_ReadByte(); // version byte. - - th->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(th->sector != 0); - - th->index = SV_ReadLong(); - th->baseValue = (float) SV_ReadLong() / 255.0f; - } - else - { - // Its in the old pre V4 format which serialized phase_t - // Padding at the start (an old thinker_t struct) - thinker_t junk; - SV_Read(&junk, (size_t) 16); - - // Start of used data members. - // A 32bit pointer to sector, serialized. - th->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(th->sector != 0); - - th->index = SV_ReadLong(); - th->baseValue = (float) SV_ReadLong() / 255.0f; - } - - th->thinker.function = (thinkfunc_t) T_Phase; - - return true; // Add this thinker. -} - -static void SV_WriteDoorPoly(polydoor_t const *th) -{ - DENG_ASSERT(th != 0); - - SV_WriteByte(1); // Write a version byte. - - SV_WriteByte(th->type); - - // Note we don't bother to save a byte to tell if the function - // is present as we ALWAYS add one when loading. - - SV_WriteLong(th->polyobj); - SV_WriteLong(th->intSpeed); - SV_WriteLong(th->dist); - SV_WriteLong(th->totalDist); - SV_WriteLong(th->direction); - SV_WriteLong(FLT2FIX(th->speed[VX])); - SV_WriteLong(FLT2FIX(th->speed[VY])); - SV_WriteLong(th->tics); - SV_WriteLong(th->waitTics); - SV_WriteByte(th->close); -} - -static int SV_ReadDoorPoly(polydoor_t *th, int /*mapVersion*/) -{ - DENG_ASSERT(th != 0); - - if(mapVersion >= 4) - { - // Note: the thinker class byte has already been read. - /*int ver =*/ SV_ReadByte(); // version byte. - - // Start of used data members. - th->type = podoortype_t(SV_ReadByte()); - th->polyobj = SV_ReadLong(); - th->intSpeed = SV_ReadLong(); - th->dist = SV_ReadLong(); - th->totalDist = SV_ReadLong(); - th->direction = SV_ReadLong(); - th->speed[VX] = FIX2FLT(SV_ReadLong()); - th->speed[VY] = FIX2FLT(SV_ReadLong()); - th->tics = SV_ReadLong(); - th->waitTics = SV_ReadLong(); - th->close = SV_ReadByte(); - } - else - { - // Its in the old pre V4 format which serialized polydoor_t - // Padding at the start (an old thinker_t struct) - thinker_t junk; - SV_Read(&junk, (size_t) 16); - - // Start of used data members. - th->polyobj = SV_ReadLong(); - th->intSpeed = SV_ReadLong(); - th->dist = SV_ReadLong(); - th->totalDist = SV_ReadLong(); - th->direction = SV_ReadLong(); - th->speed[VX] = FIX2FLT(SV_ReadLong()); - th->speed[VY] = FIX2FLT(SV_ReadLong()); - th->tics = SV_ReadLong(); - th->waitTics = SV_ReadLong(); - th->type = podoortype_t(SV_ReadByte()); - th->close = SV_ReadByte(); - } - - th->thinker.function = T_PolyDoor; - - return true; // Add this thinker. -} - -static void SV_WriteMovePoly(polyevent_t const *th) -{ - DENG_ASSERT(th != 0); - - SV_WriteByte(1); // Write a version byte. - - // Note we don't bother to save a byte to tell if the function - // is present as we ALWAYS add one when loading. - - SV_WriteLong(th->polyobj); - SV_WriteLong(th->intSpeed); - SV_WriteLong(th->dist); - SV_WriteLong(th->fangle); - SV_WriteLong(FLT2FIX(th->speed[VX])); - SV_WriteLong(FLT2FIX(th->speed[VY])); -} - -static int SV_ReadMovePoly(polyevent_t *th, int /*mapVersion*/) -{ - DENG_ASSERT(th != 0); - - if(mapVersion >= 4) - { - // Note: the thinker class byte has already been read. - /*int ver =*/ SV_ReadByte(); // version byte. - - // Start of used data members. - th->polyobj = SV_ReadLong(); - th->intSpeed = SV_ReadLong(); - th->dist = SV_ReadLong(); - th->fangle = SV_ReadLong(); - th->speed[VX] = FIX2FLT(SV_ReadLong()); - th->speed[VY] = FIX2FLT(SV_ReadLong()); - } - else - { - // Its in the old pre V4 format which serialized polyevent_t - // Padding at the start (an old thinker_t struct) - thinker_t junk; - SV_Read(&junk, (size_t) 16); - - // Start of used data members. - th->polyobj = SV_ReadLong(); - th->intSpeed = SV_ReadLong(); - th->dist = SV_ReadLong(); - th->fangle = SV_ReadLong(); - th->speed[VX] = FIX2FLT(SV_ReadLong()); - th->speed[VY] = FIX2FLT(SV_ReadLong()); - } - - th->thinker.function = T_MovePoly; - - return true; // Add this thinker. -} - -static void SV_WriteRotatePoly(polyevent_t const *th) -{ - DENG_ASSERT(th != 0); - - SV_WriteByte(1); // Write a version byte. - - // Note we don't bother to save a byte to tell if the function - // is present as we ALWAYS add one when loading. - - SV_WriteLong(th->polyobj); - SV_WriteLong(th->intSpeed); - SV_WriteLong(th->dist); - SV_WriteLong(th->fangle); - SV_WriteLong(FLT2FIX(th->speed[VX])); - SV_WriteLong(FLT2FIX(th->speed[VY])); -} - -static int SV_ReadRotatePoly(polyevent_t *th, int /*mapVersion*/) -{ - DENG_ASSERT(th != 0); - - if(mapVersion >= 4) - { - // Note: the thinker class byte has already been read. - /*int ver =*/ SV_ReadByte(); // version byte. - - // Start of used data members. - th->polyobj = SV_ReadLong(); - th->intSpeed = SV_ReadLong(); - th->dist = SV_ReadLong(); - th->fangle = SV_ReadLong(); - th->speed[VX] = FIX2FLT(SV_ReadLong()); - th->speed[VY] = FIX2FLT(SV_ReadLong()); - } - else - { - // Its in the old pre V4 format which serialized polyevent_t - // Padding at the start (an old thinker_t struct) - thinker_t junk; - SV_Read(&junk, (size_t) 16); - - // Start of used data members. - th->polyobj = SV_ReadLong(); - th->intSpeed = SV_ReadLong(); - th->dist = SV_ReadLong(); - th->fangle = SV_ReadLong(); - th->speed[VX] = FIX2FLT(SV_ReadLong()); - th->speed[VY] = FIX2FLT(SV_ReadLong()); - } - - th->thinker.function = T_RotatePoly; - return true; // Add this thinker. -} - -static void SV_WritePillar(pillar_t const *th) -{ - DENG_ASSERT(th != 0); - - SV_WriteByte(1); // Write a version byte. - - // Note we don't bother to save a byte to tell if the function - // is present as we ALWAYS add one when loading. - - SV_WriteLong(P_ToIndex(th->sector)); - - SV_WriteLong(FLT2FIX(th->ceilingSpeed)); - SV_WriteLong(FLT2FIX(th->floorSpeed)); - SV_WriteLong(FLT2FIX(th->floorDest)); - SV_WriteLong(FLT2FIX(th->ceilingDest)); - SV_WriteLong(th->direction); - SV_WriteLong(th->crush); -} - -static int SV_ReadPillar(pillar_t *th, int /*mapVersion*/) -{ - DENG_ASSERT(th != 0); - - if(mapVersion >= 4) - { - // Note: the thinker class byte has already been read. - /*int ver =*/ SV_ReadByte(); // version byte. - - // Start of used data members. - th->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(th->sector != 0); - - th->ceilingSpeed = FIX2FLT((fixed_t) SV_ReadLong()); - th->floorSpeed = FIX2FLT((fixed_t) SV_ReadLong()); - th->floorDest = FIX2FLT((fixed_t) SV_ReadLong()); - th->ceilingDest = FIX2FLT((fixed_t) SV_ReadLong()); - th->direction = SV_ReadLong(); - th->crush = SV_ReadLong(); - } - else - { - // Its in the old pre V4 format which serialized pillar_t - // Padding at the start (an old thinker_t struct) - thinker_t junk; - SV_Read(&junk, (size_t) 16); - - // Start of used data members. - // A 32bit pointer to sector, serialized. - th->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(th->sector != 0); - - th->ceilingSpeed = FIX2FLT((fixed_t) SV_ReadLong()); - th->floorSpeed = FIX2FLT((fixed_t) SV_ReadLong()); - th->floorDest = FIX2FLT((fixed_t) SV_ReadLong()); - th->ceilingDest = FIX2FLT((fixed_t) SV_ReadLong()); - th->direction = SV_ReadLong(); - th->crush = SV_ReadLong(); - } - - th->thinker.function = (thinkfunc_t) T_BuildPillar; - - P_ToXSector(th->sector)->specialData = th; - return true; // Add this thinker. -} - -static void SV_WriteFloorWaggle(waggle_t const *th) -{ - DENG_ASSERT(th != 0); - - SV_WriteByte(1); // Write a version byte. - - // Note we don't bother to save a byte to tell if the function - // is present as we ALWAYS add one when loading. - - SV_WriteLong(P_ToIndex(th->sector)); - - SV_WriteLong(FLT2FIX(th->originalHeight)); - SV_WriteLong(FLT2FIX(th->accumulator)); - SV_WriteLong(FLT2FIX(th->accDelta)); - SV_WriteLong(FLT2FIX(th->targetScale)); - SV_WriteLong(FLT2FIX(th->scale)); - SV_WriteLong(FLT2FIX(th->scaleDelta)); - SV_WriteLong(th->ticker); - SV_WriteLong(th->state); -} - -static int SV_ReadFloorWaggle(waggle_t *th, int /*mapVersion*/) -{ - DENG_ASSERT(th != 0); - - if(mapVersion >= 4) - { - /*int ver =*/ SV_ReadByte(); // version byte. - - // Start of used data members. - th->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(th->sector != 0); - - th->originalHeight = FIX2FLT((fixed_t) SV_ReadLong()); - th->accumulator = FIX2FLT((fixed_t) SV_ReadLong()); - th->accDelta = FIX2FLT((fixed_t) SV_ReadLong()); - th->targetScale = FIX2FLT((fixed_t) SV_ReadLong()); - th->scale = FIX2FLT((fixed_t) SV_ReadLong()); - th->scaleDelta = FIX2FLT((fixed_t) SV_ReadLong()); - th->ticker = SV_ReadLong(); - th->state = wagglestate_e(SV_ReadLong()); - } - else - { - // Its in the old pre V4 format which serialized waggle_t - // Padding at the start (an old thinker_t struct) - thinker_t junk; - SV_Read(&junk, (size_t) 16); - - // Start of used data members. - // A 32bit pointer to sector, serialized. - th->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(th->sector != 0); - - th->originalHeight = FIX2FLT((fixed_t) SV_ReadLong()); - th->accumulator = FIX2FLT((fixed_t) SV_ReadLong()); - th->accDelta = FIX2FLT((fixed_t) SV_ReadLong()); - th->targetScale = FIX2FLT((fixed_t) SV_ReadLong()); - th->scale = FIX2FLT((fixed_t) SV_ReadLong()); - th->scaleDelta = FIX2FLT((fixed_t) SV_ReadLong()); - th->ticker = SV_ReadLong(); - th->state = wagglestate_e(SV_ReadLong()); - } - - th->thinker.function = (thinkfunc_t) T_FloorWaggle; - - P_ToXSector(th->sector)->specialData = th; - return true; // Add this thinker. -} #endif // __JHEXEN__ -#if !__JHEXEN__ -static void SV_WriteFlash(lightflash_t const *flash) -{ - DENG_ASSERT(flash != 0); - - SV_WriteByte(1); // Write a version byte. - - // Note we don't bother to save a byte to tell if the function - // is present as we ALWAYS add one when loading. - - SV_WriteLong(P_ToIndex(flash->sector)); - - SV_WriteLong(flash->count); - SV_WriteLong((int) (255.0f * flash->maxLight)); - SV_WriteLong((int) (255.0f * flash->minLight)); - SV_WriteLong(flash->maxTime); - SV_WriteLong(flash->minTime); -} - -static int SV_ReadFlash(lightflash_t *flash, int /*mapVersion*/) -{ - DENG_ASSERT(flash != 0); - - if(hdr->version >= 5) - { - // Note: the thinker class byte has already been read. - /*int ver =*/ SV_ReadByte(); // version byte. - - // Start of used data members. - flash->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(flash->sector != 0); - - flash->count = SV_ReadLong(); - flash->maxLight = (float) SV_ReadLong() / 255.0f; - flash->minLight = (float) SV_ReadLong() / 255.0f; - flash->maxTime = SV_ReadLong(); - flash->minTime = SV_ReadLong(); - } - else - { - // Its in the old pre V5 format which serialized lightflash_t - // Padding at the start (an old thinker_t struct) - SV_Seek(16); - - // Start of used data members. - // A 32bit pointer to sector, serialized. - flash->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(flash->sector != 0); - - flash->count = SV_ReadLong(); - flash->maxLight = (float) SV_ReadLong() / 255.0f; - flash->minLight = (float) SV_ReadLong() / 255.0f; - flash->maxTime = SV_ReadLong(); - flash->minTime = SV_ReadLong(); - } - - flash->thinker.function = (thinkfunc_t) T_LightFlash; - return true; // Add this thinker. -} - -static void SV_WriteStrobe(strobe_t const *strobe) -{ - DENG_ASSERT(strobe != 0); - - SV_WriteByte(1); // Write a version byte. - - // Note we don't bother to save a byte to tell if the function - // is present as we ALWAYS add one when loading. - - SV_WriteLong(P_ToIndex(strobe->sector)); - - SV_WriteLong(strobe->count); - SV_WriteLong((int) (255.0f * strobe->maxLight)); - SV_WriteLong((int) (255.0f * strobe->minLight)); - SV_WriteLong(strobe->darkTime); - SV_WriteLong(strobe->brightTime); -} - -static int SV_ReadStrobe(strobe_t *strobe, int /*mapVersion*/) -{ - DENG_ASSERT(strobe != 0); - - if(hdr->version >= 5) - { - // Note: the thinker class byte has already been read. - /*int ver =*/ SV_ReadByte(); // version byte. - - strobe->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(strobe->sector != 0); - - strobe->count = SV_ReadLong(); - strobe->maxLight = (float) SV_ReadLong() / 255.0f; - strobe->minLight = (float) SV_ReadLong() / 255.0f; - strobe->darkTime = SV_ReadLong(); - strobe->brightTime = SV_ReadLong(); - } - else - { - // Its in the old pre V5 format which serialized strobe_t - // Padding at the start (an old thinker_t struct) - SV_Seek(16); - - // Start of used data members. - // A 32bit pointer to sector, serialized. - strobe->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(strobe->sector != 0); - - strobe->count = SV_ReadLong(); - strobe->minLight = (float) SV_ReadLong() / 255.0f; - strobe->maxLight = (float) SV_ReadLong() / 255.0f; - strobe->darkTime = SV_ReadLong(); - strobe->brightTime = SV_ReadLong(); - } - - strobe->thinker.function = (thinkfunc_t) T_StrobeFlash; - return true; // Add this thinker. -} - -static void SV_WriteGlow(glow_t const *glow) -{ - DENG_ASSERT(glow != 0); - - SV_WriteByte(1); // Write a version byte. - - // Note we don't bother to save a byte to tell if the function - // is present as we ALWAYS add one when loading. - - SV_WriteLong(P_ToIndex(glow->sector)); - - SV_WriteLong((int) (255.0f * glow->maxLight)); - SV_WriteLong((int) (255.0f * glow->minLight)); - SV_WriteLong(glow->direction); -} - -static int SV_ReadGlow(glow_t *glow, int /*mapVersion*/) -{ - DENG_ASSERT(glow != 0); - - if(hdr->version >= 5) - { - // Note: the thinker class byte has already been read. - /*int ver =*/ SV_ReadByte(); // version byte. - - glow->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(glow->sector != 0); - - glow->maxLight = (float) SV_ReadLong() / 255.0f; - glow->minLight = (float) SV_ReadLong() / 255.0f; - glow->direction = SV_ReadLong(); - } - else - { - // Its in the old pre V5 format which serialized strobe_t - // Padding at the start (an old thinker_t struct) - SV_Seek(16); - - // Start of used data members. - // A 32bit pointer to sector, serialized. - glow->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(glow->sector != 0); - - glow->minLight = (float) SV_ReadLong() / 255.0f; - glow->maxLight = (float) SV_ReadLong() / 255.0f; - glow->direction = SV_ReadLong(); - } - - glow->thinker.function = (thinkfunc_t) T_Glow; - return true; // Add this thinker. -} - -# if __JDOOM__ || __JDOOM64__ -static void SV_WriteFlicker(fireflicker_t const *flicker) -{ - DENG_ASSERT(flicker != 0); - - SV_WriteByte(1); // Write a version byte. - - // Note we don't bother to save a byte to tell if the function - // is present as we ALWAYS add one when loading. - - SV_WriteLong(P_ToIndex(flicker->sector)); - - SV_WriteLong((int) (255.0f * flicker->maxLight)); - SV_WriteLong((int) (255.0f * flicker->minLight)); -} - -/** - * T_FireFlicker was added to save games in ver5, therefore we don't have - * an old format to support. - */ -static int SV_ReadFlicker(fireflicker_t *flicker, int /*mapVersion*/) -{ - DENG_ASSERT(flicker != 0); - - /*int ver =*/ SV_ReadByte(); // version byte. - - // Note: the thinker class byte has already been read. - flicker->sector = (Sector*)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(flicker->sector != 0); - - flicker->maxLight = (float) SV_ReadLong() / 255.0f; - flicker->minLight = (float) SV_ReadLong() / 255.0f; - - flicker->thinker.function = (thinkfunc_t) T_FireFlicker; - return true; // Add this thinker. -} -# endif - -# if __JDOOM64__ -static void SV_WriteBlink(lightblink_t const *blink) -{ - DENG_ASSERT(blink != 0); - - SV_WriteByte(1); // Write a version byte. - - // Note we don't bother to save a byte to tell if the function - // is present as we ALWAYS add one when loading. - - SV_WriteLong(P_ToIndex(blink->sector)); - - SV_WriteLong(blink->count); - SV_WriteLong((int) (255.0f * blink->maxLight)); - SV_WriteLong((int) (255.0f * blink->minLight)); - SV_WriteLong(blink->maxTime); - SV_WriteLong(blink->minTime); -} - -/** - * T_LightBlink was added to save games in ver5, therefore we don't have an - * old format to support - */ -static int SV_ReadBlink(lightblink_t *blink, int /*mapVersion*/) -{ - DENG_ASSERT(blink != 0); - - /*int ver =*/ SV_ReadByte(); // version byte. - - // Note: the thinker class byte has already been read. - blink->sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(blink->sector != 0); - - blink->count = SV_ReadLong(); - blink->maxLight = (float) SV_ReadLong() / 255.0f; - blink->minLight = (float) SV_ReadLong() / 255.0f; - blink->maxTime = SV_ReadLong(); - blink->minTime = SV_ReadLong(); - - blink->thinker.function = (thinkfunc_t) T_LightBlink; - return true; // Add this thinker. -} -# endif -#endif // !__JHEXEN__ - -static void SV_WriteMaterialChanger(materialchanger_t const *mchanger) -{ - DENG_ASSERT(mchanger != 0); - - SV_WriteByte(1); // Write a version byte. - - // Note we don't bother to save a byte to tell if the function - // is present as we ALWAYS add one when loading. - - // Write a type byte. For future use (e.g., changing plane surface - // materials as well as side surface materials). - SV_WriteByte(0); - SV_WriteLong(mchanger->timer); - SV_WriteLong(P_ToIndex(mchanger->side)); - SV_WriteByte((byte) mchanger->section); - SV_WriteShort(MaterialArchive_FindUniqueSerialId(materialArchive, mchanger->material)); -} - -static int SV_ReadMaterialChanger(materialchanger_t *mchanger, int /*mapVersion*/) -{ - DENG_ASSERT(mchanger != 0); - - /*int ver =*/ SV_ReadByte(); - // Note: the thinker class byte has already been read. - - /*byte type =*/ SV_ReadByte(); - - mchanger->timer = SV_ReadLong(); - - int sideIndex = (int) SV_ReadLong(); -#if __JHEXEN__ - if(mapVersion >= 12) - -#else - if(hdr->version >= 12) -#endif - { - mchanger->side = (Side *)P_ToPtr(DMU_SIDE, sideIndex); - } - else - { - // Side index is actually a DMU_ARCHIVE_INDEX. - mchanger->side = (Side *)SV_SideArchive().at(sideIndex); - } - DENG_ASSERT(mchanger->side != 0); - - mchanger->section = (SideSection) SV_ReadByte(); - mchanger->material = SV_GetArchiveMaterial(SV_ReadShort(), 0); - - mchanger->thinker.function = T_MaterialChanger; - - return true; // Add this thinker. -} - -static void SV_WriteScroll(scroll_t const *scroll) -{ - DENG_ASSERT(scroll != 0); - - SV_WriteByte(1); // Write a version byte. - - // Note we don't bother to save a byte to tell if the function - // is present as we ALWAYS add one when loading. - - // Write a type byte. For future use (e.g., scrolling plane surface - // materials as well as side surface materials). - SV_WriteByte(DMU_GetType(scroll->dmuObject)); - SV_WriteLong(P_ToIndex(scroll->dmuObject)); - SV_WriteLong(scroll->elementBits); - SV_WriteLong(FLT2FIX(scroll->offset[0])); - SV_WriteLong(FLT2FIX(scroll->offset[1])); -} - -static int SV_ReadScroll(scroll_t *scroll, int /*mapVersion*/) -{ - DENG_ASSERT(scroll != 0); - - /*int ver =*/ SV_ReadByte(); // version byte. - // Note: the thinker class byte has already been read. - - if(SV_ReadByte() == DMU_SIDE) // Type byte. - { - int sideIndex = (int) SV_ReadLong(); - -#if __JHEXEN__ - if(mapVersion >= 12) - -#else - if(hdr->version >= 12) -#endif - { - scroll->dmuObject = (Side *)P_ToPtr(DMU_SIDE, sideIndex); - } - else - { - // Side index is actually a DMU_ARCHIVE_INDEX. - scroll->dmuObject = (Side *)SV_SideArchive().at(sideIndex); - } - - DENG_ASSERT(scroll->dmuObject != 0); - } - else // Sector plane-surface. - { - scroll->dmuObject = (Sector *)P_ToPtr(DMU_SECTOR, (int) SV_ReadLong()); - DENG_ASSERT(scroll->dmuObject != 0); - } - - scroll->elementBits = SV_ReadLong(); - scroll->offset[0] = FIX2FLT((fixed_t) SV_ReadLong()); - scroll->offset[1] = FIX2FLT((fixed_t) SV_ReadLong()); - - scroll->thinker.function = (thinkfunc_t) T_Scroll; - - return true; // Add this thinker. -} - /** * Serializes the specified thinker and writes it to save state. * diff --git a/doomsday/plugins/common/src/p_scroll.cpp b/doomsday/plugins/common/src/p_scroll.cpp index 52ba6d41e4..1f9deef0a5 100644 --- a/doomsday/plugins/common/src/p_scroll.cpp +++ b/doomsday/plugins/common/src/p_scroll.cpp @@ -22,6 +22,7 @@ #include "common.h" #include "p_scroll.h" #include "dmu_lib.h" +#include "p_saveg.h" void T_Scroll(scroll_t *s) { @@ -63,6 +64,58 @@ void T_Scroll(scroll_t *s) } } +void scroll_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + // Write a type byte. For future use (e.g., scrolling plane surface + // materials as well as side surface materials). + Writer_WriteByte(writer, DMU_GetType(dmuObject)); + Writer_WriteInt32(writer, P_ToIndex(dmuObject)); + Writer_WriteInt32(writer, elementBits); + Writer_WriteInt32(writer, FLT2FIX(offset[0])); + Writer_WriteInt32(writer, FLT2FIX(offset[1])); +} + +int scroll_t::read(Reader *reader, int mapVersion) +{ + /*int ver =*/ Reader_ReadByte(reader); // version byte. + // Note: the thinker class byte has already been read. + + if(Reader_ReadByte(reader) == DMU_SIDE) // Type byte. + { + int sideIndex = (int) Reader_ReadInt32(reader); + + if(mapVersion >= 12) + { + dmuObject = (Side *)P_ToPtr(DMU_SIDE, sideIndex); + } + else + { + // Side index is actually a DMU_ARCHIVE_INDEX. + dmuObject = (Side *)SV_SideArchive().at(sideIndex); + } + + DENG_ASSERT(dmuObject != 0); + } + else // Sector plane-surface. + { + dmuObject = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(dmuObject != 0); + } + + elementBits = Reader_ReadInt32(reader); + offset[0] = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + offset[1] = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + + thinker.function = (thinkfunc_t) T_Scroll; + + return true; // Add this thinker. +} + static scroll_t *spawnMaterialOriginScroller(void *dmuObject, int elementBits, float offsetXY[2]) { // Don't spawn a scroller with an invalid map object reference. diff --git a/doomsday/plugins/common/src/p_switch.cpp b/doomsday/plugins/common/src/p_switch.cpp index bde13becf2..3787a4942a 100644 --- a/doomsday/plugins/common/src/p_switch.cpp +++ b/doomsday/plugins/common/src/p_switch.cpp @@ -28,6 +28,7 @@ #include "dmu_lib.h" #include "p_plat.h" #include "p_sound.h" +#include "p_saveg.h" #include /** @@ -296,6 +297,51 @@ void T_MaterialChanger(void *materialChangerThinker) } } +void materialchanger_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + // Write a type byte. For future use (e.g., changing plane surface + // materials as well as side surface materials). + Writer_WriteByte(writer, 0); + Writer_WriteInt32(writer, timer); + Writer_WriteInt32(writer, P_ToIndex(side)); + Writer_WriteByte(writer, (byte) section); + Writer_WriteInt16(writer, MaterialArchive_FindUniqueSerialId(SV_MaterialArchive(), material)); +} + +int materialchanger_t::read(Reader *reader, int mapVersion) +{ + /*int ver =*/ Reader_ReadByte(reader); + // Note: the thinker class byte has already been read. + + /*byte type =*/ Reader_ReadByte(reader); + + timer = Reader_ReadInt32(reader); + + int sideIndex = (int) Reader_ReadInt32(reader); + if(mapVersion >= 12) + { + side = (Side *)P_ToPtr(DMU_SIDE, sideIndex); + } + else + { + // Side index is actually a DMU_ARCHIVE_INDEX. + side = (Side *)SV_SideArchive().at(sideIndex); + } + DENG_ASSERT(side != 0); + + section = (SideSection) Reader_ReadByte(reader); + material = SV_GetArchiveMaterial(Reader_ReadInt16(reader), 0); + + thinker.function = T_MaterialChanger; + + return true; // Add this thinker. +} + static void spawnMaterialChanger(Side *side, SideSection section, Material *mat, int tics) { materialchanger_t *mchanger = (materialchanger_t *)Z_Calloc(sizeof(*mchanger), PU_MAP, 0); diff --git a/doomsday/plugins/common/src/polyobjs.cpp b/doomsday/plugins/common/src/polyobjs.cpp index 7cbd7a6291..ed44f780da 100644 --- a/doomsday/plugins/common/src/polyobjs.cpp +++ b/doomsday/plugins/common/src/polyobjs.cpp @@ -276,6 +276,57 @@ void T_MovePoly(void *polyThinker) } } +void polyevent_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteInt32(writer, polyobj); + Writer_WriteInt32(writer, intSpeed); + Writer_WriteInt32(writer, dist); + Writer_WriteInt32(writer, fangle); + Writer_WriteInt32(writer, FLT2FIX(speed[VX])); + Writer_WriteInt32(writer, FLT2FIX(speed[VY])); +} + +int polyevent_t::read(Reader *reader, int mapVersion) +{ + if(mapVersion >= 4) + { + // Note: the thinker class byte has already been read. + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + // Start of used data members. + polyobj = Reader_ReadInt32(reader); + intSpeed = Reader_ReadInt32(reader); + dist = Reader_ReadInt32(reader); + fangle = Reader_ReadInt32(reader); + speed[VX] = FIX2FLT(Reader_ReadInt32(reader)); + speed[VY] = FIX2FLT(Reader_ReadInt32(reader)); + } + else + { + // Its in the old pre V4 format which serialized polyevent_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. + polyobj = Reader_ReadInt32(reader); + intSpeed = Reader_ReadInt32(reader); + dist = Reader_ReadInt32(reader); + fangle = Reader_ReadInt32(reader); + speed[VX] = FIX2FLT(Reader_ReadInt32(reader)); + speed[VY] = FIX2FLT(Reader_ReadInt32(reader)); + } + + thinker.function = T_RotatePoly; + + return true; // Add this thinker. +} + dd_bool EV_MovePoly(Line *line, byte *args, dd_bool timesEight, dd_bool override) { DENG_UNUSED(line); @@ -474,6 +525,73 @@ void T_PolyDoor(void *polyDoorThinker) } } +void polydoor_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + Writer_WriteByte(writer, type); + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteInt32(writer, polyobj); + Writer_WriteInt32(writer, intSpeed); + Writer_WriteInt32(writer, dist); + Writer_WriteInt32(writer, totalDist); + Writer_WriteInt32(writer, direction); + Writer_WriteInt32(writer, FLT2FIX(speed[VX])); + Writer_WriteInt32(writer, FLT2FIX(speed[VY])); + Writer_WriteInt32(writer, tics); + Writer_WriteInt32(writer, waitTics); + Writer_WriteByte(writer, close); +} + +int polydoor_t::read(Reader *reader, int mapVersion) +{ + if(mapVersion >= 4) + { + // Note: the thinker class byte has already been read. + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + // Start of used data members. + type = podoortype_t(Reader_ReadByte(reader)); + polyobj = Reader_ReadInt32(reader); + intSpeed = Reader_ReadInt32(reader); + dist = Reader_ReadInt32(reader); + totalDist = Reader_ReadInt32(reader); + direction = Reader_ReadInt32(reader); + speed[VX] = FIX2FLT(Reader_ReadInt32(reader)); + speed[VY] = FIX2FLT(Reader_ReadInt32(reader)); + tics = Reader_ReadInt32(reader); + waitTics = Reader_ReadInt32(reader); + close = Reader_ReadByte(reader); + } + else + { + // Its in the old pre V4 format which serialized polydoor_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. + polyobj = Reader_ReadInt32(reader); + intSpeed = Reader_ReadInt32(reader); + dist = Reader_ReadInt32(reader); + totalDist = Reader_ReadInt32(reader); + direction = Reader_ReadInt32(reader); + speed[VX] = FIX2FLT(Reader_ReadInt32(reader)); + speed[VY] = FIX2FLT(Reader_ReadInt32(reader)); + tics = Reader_ReadInt32(reader); + waitTics = Reader_ReadInt32(reader); + type = podoortype_t(Reader_ReadByte(reader)); + close = Reader_ReadByte(reader); + } + + thinker.function = T_PolyDoor; + + return true; // Add this thinker. +} + dd_bool EV_OpenPolyDoor(Line *line, byte *args, podoortype_t type) { DENG_UNUSED(line); diff --git a/doomsday/plugins/doom/src/p_lights.cpp b/doomsday/plugins/doom/src/p_lights.cpp index 9e8d7aaef7..840b63106b 100644 --- a/doomsday/plugins/doom/src/p_lights.cpp +++ b/doomsday/plugins/doom/src/p_lights.cpp @@ -48,6 +48,39 @@ void T_FireFlicker(void *flickPtr) flick->count = 4; } +void fireflicker_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt32(writer, (int) (255.0f * maxLight)); + Writer_WriteInt32(writer, (int) (255.0f * minLight)); +} + +/** + * T_FireFlicker was added to save games in ver5, therefore we don't have + * an old format to support. + */ +int fireflicker_t::read(Reader *reader, int mapVersion) +{ + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + // Note: the thinker class byte has already been read. + sector = (Sector*)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + + thinker.function = (thinkfunc_t) T_FireFlicker; + + return true; // Add this thinker. +} + void P_SpawnFireFlicker(Sector *sector) { float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); @@ -96,6 +129,63 @@ void T_LightFlash(lightflash_t *flash) } } +void lightflash_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt32(writer, count); + Writer_WriteInt32(writer, (int) (255.0f * maxLight)); + Writer_WriteInt32(writer, (int) (255.0f * minLight)); + Writer_WriteInt32(writer, maxTime); + Writer_WriteInt32(writer, minTime); +} + +int lightflash_t::read(Reader *reader, int mapVersion) +{ + if(mapVersion >= 5) + { + // Note: the thinker class byte has already been read. + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + // Start of used data members. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + count = Reader_ReadInt32(reader); + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + maxTime = Reader_ReadInt32(reader); + minTime = Reader_ReadInt32(reader); + } + else + { + // Its in the old pre V5 format which serialized lightflash_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + count = Reader_ReadInt32(reader); + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + maxTime = Reader_ReadInt32(reader); + minTime = Reader_ReadInt32(reader); + } + + thinker.function = (thinkfunc_t) T_LightFlash; + + return true; // Add this thinker. +} + /** * After the map has been loaded, scan each sector * for specials that spawn thinkers @@ -149,6 +239,62 @@ void T_StrobeFlash(strobe_t *flash) } } +void strobe_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt32(writer, count); + Writer_WriteInt32(writer, (int) (255.0f * maxLight)); + Writer_WriteInt32(writer, (int) (255.0f * minLight)); + Writer_WriteInt32(writer, darkTime); + Writer_WriteInt32(writer, brightTime); +} + +int strobe_t::read(Reader *reader, int mapVersion) +{ + if(mapVersion >= 5) + { + // Note: the thinker class byte has already been read. + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + count = Reader_ReadInt32(reader); + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + darkTime = Reader_ReadInt32(reader); + brightTime = Reader_ReadInt32(reader); + } + else + { + // Its in the old pre V5 format which serialized strobe_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + count = Reader_ReadInt32(reader); + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + darkTime = Reader_ReadInt32(reader); + brightTime = Reader_ReadInt32(reader); + } + + thinker.function = (thinkfunc_t) T_StrobeFlash; + + return true; // Add this thinker. +} + /** * After the map has been loaded, scan each sector for specials that spawn * thinkers. @@ -294,6 +440,56 @@ void T_Glow(glow_t *g) P_SetFloatp(g->sector, DMU_LIGHT_LEVEL, lightLevel); } +void glow_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt32(writer, (int) (255.0f * maxLight)); + Writer_WriteInt32(writer, (int) (255.0f * minLight)); + Writer_WriteInt32(writer, direction); +} + +int glow_t::read(Reader *reader, int mapVersion) +{ + if(mapVersion >= 5) + { + // Note: the thinker class byte has already been read. + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + direction = Reader_ReadInt32(reader); + } + else + { + // Its in the old pre V5 format which serialized strobe_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + direction = Reader_ReadInt32(reader); + } + + thinker.function = (thinkfunc_t) T_Glow; + + return true; // Add this thinker. +} + void P_SpawnGlowingLight(Sector *sector) { float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); diff --git a/doomsday/plugins/doom64/src/p_lights.cpp b/doomsday/plugins/doom64/src/p_lights.cpp index 8591bcc902..3af10dec80 100644 --- a/doomsday/plugins/doom64/src/p_lights.cpp +++ b/doomsday/plugins/doom64/src/p_lights.cpp @@ -45,6 +45,39 @@ void T_FireFlicker(fireflicker_t *flick) flick->count = 4; } +void fireflicker_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt32(writer, (int) (255.0f * maxLight)); + Writer_WriteInt32(writer, (int) (255.0f * minLight)); +} + +/** + * T_FireFlicker was added to save games in ver5, therefore we don't have + * an old format to support. + */ +int fireflicker_t::read(Reader *reader, int mapVersion) +{ + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + // Note: the thinker class byte has already been read. + sector = (Sector*)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + + thinker.function = (thinkfunc_t) T_FireFlicker; + + return true; // Add this thinker. +} + void P_SpawnFireFlicker(Sector *sector) { float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); @@ -93,6 +126,63 @@ void T_LightFlash(lightflash_t *flash) } } +void lightflash_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt32(writer, count); + Writer_WriteInt32(writer, (int) (255.0f * maxLight)); + Writer_WriteInt32(writer, (int) (255.0f * minLight)); + Writer_WriteInt32(writer, maxTime); + Writer_WriteInt32(writer, minTime); +} + +int lightflash_t::read(Reader *reader, int mapVersion) +{ + if(mapVersion >= 5) + { + // Note: the thinker class byte has already been read. + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + // Start of used data members. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + count = Reader_ReadInt32(reader); + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + maxTime = Reader_ReadInt32(reader); + minTime = Reader_ReadInt32(reader); + } + else + { + // Its in the old pre V5 format which serialized lightflash_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + count = Reader_ReadInt32(reader); + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + maxTime = Reader_ReadInt32(reader); + minTime = Reader_ReadInt32(reader); + } + + thinker.function = (thinkfunc_t) T_LightFlash; + + return true; // Add this thinker. +} + /** * After the map has been loaded, scan each sector for specials that spawn * thinkers. @@ -145,6 +235,45 @@ void T_LightBlink(lightblink_t *flash) } } +void lightblink_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt32(writer, count); + Writer_WriteInt32(writer, (int) (255.0f * maxLight)); + Writer_WriteInt32(writer, (int) (255.0f * minLight)); + Writer_WriteInt32(writer, maxTime); + Writer_WriteInt32(writer, minTime); +} + +/** + * T_LightBlink was added to save games in ver5, therefore we don't have an + * old format to support + */ +int lightblink_t::read(Reader *reader, int mapVersion) +{ + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + // Note: the thinker class byte has already been read. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + count = Reader_ReadInt32(reader); + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + maxTime = Reader_ReadInt32(reader); + minTime = Reader_ReadInt32(reader); + + thinker.function = (thinkfunc_t) T_LightBlink; + + return true; // Add this thinker. +} + /** * d64tc */ @@ -184,6 +313,62 @@ void T_StrobeFlash(strobe_t *flash) } } +void strobe_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt32(writer, count); + Writer_WriteInt32(writer, (int) (255.0f * maxLight)); + Writer_WriteInt32(writer, (int) (255.0f * minLight)); + Writer_WriteInt32(writer, darkTime); + Writer_WriteInt32(writer, brightTime); +} + +int strobe_t::read(Reader *reader, int mapVersion) +{ + if(mapVersion >= 5) + { + // Note: the thinker class byte has already been read. + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + count = Reader_ReadInt32(reader); + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + darkTime = Reader_ReadInt32(reader); + brightTime = Reader_ReadInt32(reader); + } + else + { + // Its in the old pre V5 format which serialized strobe_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + count = Reader_ReadInt32(reader); + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + darkTime = Reader_ReadInt32(reader); + brightTime = Reader_ReadInt32(reader); + } + + thinker.function = (thinkfunc_t) T_StrobeFlash; + + return true; // Add this thinker. +} + /** * After the map has been loaded, scan each sector for specials that spawn * thinkers. @@ -320,6 +505,56 @@ void T_Glow(glow_t *g) P_SetFloatp(g->sector, DMU_LIGHT_LEVEL, lightLevel); } +void glow_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt32(writer, (int) (255.0f * maxLight)); + Writer_WriteInt32(writer, (int) (255.0f * minLight)); + Writer_WriteInt32(writer, direction); +} + +int glow_t::read(Reader *reader, int mapVersion) +{ + if(mapVersion >= 5) + { + // Note: the thinker class byte has already been read. + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + direction = Reader_ReadInt32(reader); + } + else + { + // Its in the old pre V5 format which serialized strobe_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + direction = Reader_ReadInt32(reader); + } + + thinker.function = (thinkfunc_t) T_Glow; + + return true; // Add this thinker. +} + void P_SpawnGlowingLight(Sector *sector) { float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); diff --git a/doomsday/plugins/heretic/src/p_lights.cpp b/doomsday/plugins/heretic/src/p_lights.cpp index fe85ab2535..f67dcc1a92 100644 --- a/doomsday/plugins/heretic/src/p_lights.cpp +++ b/doomsday/plugins/heretic/src/p_lights.cpp @@ -49,6 +49,63 @@ void T_LightFlash(lightflash_t *flash) } } +void lightflash_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt32(writer, count); + Writer_WriteInt32(writer, (int) (255.0f * maxLight)); + Writer_WriteInt32(writer, (int) (255.0f * minLight)); + Writer_WriteInt32(writer, maxTime); + Writer_WriteInt32(writer, minTime); +} + +int lightflash_t::read(Reader *reader, int mapVersion) +{ + if(mapVersion >= 5) + { + // Note: the thinker class byte has already been read. + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + // Start of used data members. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + count = Reader_ReadInt32(reader); + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + maxTime = Reader_ReadInt32(reader); + minTime = Reader_ReadInt32(reader); + } + else + { + // Its in the old pre V5 format which serialized lightflash_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + count = Reader_ReadInt32(reader); + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + maxTime = Reader_ReadInt32(reader); + minTime = Reader_ReadInt32(reader); + } + + thinker.function = (thinkfunc_t) T_LightFlash; + + return true; // Add this thinker. +} + /** * After the map has been loaded, scan each sector for specials that spawn * thinkers. @@ -101,6 +158,62 @@ void T_StrobeFlash(strobe_t *flash) } } +void strobe_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt32(writer, count); + Writer_WriteInt32(writer, (int) (255.0f * maxLight)); + Writer_WriteInt32(writer, (int) (255.0f * minLight)); + Writer_WriteInt32(writer, darkTime); + Writer_WriteInt32(writer, brightTime); +} + +int strobe_t::read(Reader *reader, int mapVersion) +{ + if(mapVersion >= 5) + { + // Note: the thinker class byte has already been read. + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + count = Reader_ReadInt32(reader); + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + darkTime = Reader_ReadInt32(reader); + brightTime = Reader_ReadInt32(reader); + } + else + { + // Its in the old pre V5 format which serialized strobe_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + count = Reader_ReadInt32(reader); + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + darkTime = Reader_ReadInt32(reader); + brightTime = Reader_ReadInt32(reader); + } + + thinker.function = (thinkfunc_t) T_StrobeFlash; + + return true; // Add this thinker. +} + /** * After the map has been loaded, scan each sector for specials that spawn * thinkers. @@ -242,6 +355,56 @@ void T_Glow(glow_t *g) P_SetFloatp(g->sector, DMU_LIGHT_LEVEL, lightlevel); } +void glow_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt32(writer, (int) (255.0f * maxLight)); + Writer_WriteInt32(writer, (int) (255.0f * minLight)); + Writer_WriteInt32(writer, direction); +} + +int glow_t::read(Reader *reader, int mapVersion) +{ + if(mapVersion >= 5) + { + // Note: the thinker class byte has already been read. + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + direction = Reader_ReadInt32(reader); + } + else + { + // Its in the old pre V5 format which serialized strobe_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + minLight = (float) Reader_ReadInt32(reader) / 255.0f; + maxLight = (float) Reader_ReadInt32(reader) / 255.0f; + direction = Reader_ReadInt32(reader); + } + + thinker.function = (thinkfunc_t) T_Glow; + + return true; // Add this thinker. +} + void P_SpawnGlowingLight(Sector *sector) { float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); diff --git a/doomsday/plugins/hexen/include/acscript.h b/doomsday/plugins/hexen/include/acscript.h index 994782bd74..0af3b06cb3 100644 --- a/doomsday/plugins/hexen/include/acscript.h +++ b/doomsday/plugins/hexen/include/acscript.h @@ -28,8 +28,6 @@ #include "jhexen.h" #include "p_mobj.h" -#include -#include #define MAX_ACS_SCRIPT_VARS 10 #define MAX_ACS_MAP_VARS 32 @@ -127,8 +125,8 @@ class ACScriptInterpreter * * @return @c true iff a script was newly started (or deferred). */ - bool startScript(int scriptNumber, uint map, byte *args, mobj_t *activator = 0, - Line *line = 0, int side = 0); + bool startScript(int scriptNumber, uint map, byte const args[4], + mobj_t *activator = 0, Line *line = 0, int side = 0); bool suspendScript(int scriptNumber, uint map); @@ -190,13 +188,13 @@ class ACScriptInterpreter BytecodeScriptInfo &scriptInfoFor(ACScript *script); -private: /** * Returns the logical index of a @a scriptNumber; otherwise @c -1. */ int scriptInfoIndex(int scriptNumber); - ACScript *newACScript(BytecodeScriptInfo &info, byte const *args, int delayCount = 0); +private: + ACScript *newACScript(BytecodeScriptInfo &info, byte const args[4], int delayCount = 0); /** * A deferred task is enqueued when a script is started on a map not currently loaded. @@ -208,7 +206,7 @@ class ACScriptInterpreter byte args[4]; }; - bool newDeferredTask(uint map, int scriptNumber, byte const *args); + bool newDeferredTask(uint map, int scriptNumber, byte const args[4]); byte const *_pcode; ///< Start of the loaded bytecode. @@ -234,7 +232,7 @@ void P_InitACScript(void); void P_LoadACScripts(lumpnum_t lump); -dd_bool P_StartACScript(int number, uint map, byte *args, mobj_t *activator, Line *line, int side); +dd_bool P_StartACScript(int number, uint map, byte const args[4], mobj_t *activator, Line *line, int side); dd_bool P_TerminateACScript(int number, uint map); diff --git a/doomsday/plugins/hexen/include/p_pillar.h b/doomsday/plugins/hexen/include/p_pillar.h index 0749bdefeb..3864dc4827 100644 --- a/doomsday/plugins/hexen/include/p_pillar.h +++ b/doomsday/plugins/hexen/include/p_pillar.h @@ -22,6 +22,8 @@ #ifndef LIBHEXEN_P_PILLAR_H #define LIBHEXEN_P_PILLAR_H +#include "doomsday.h" + #ifndef __JHEXEN__ # error "Using jHexen headers without __JHEXEN__" #endif @@ -35,6 +37,11 @@ typedef struct { coord_t ceilingDest; int direction; int crush; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } pillar_t; #ifdef __cplusplus diff --git a/doomsday/plugins/hexen/include/p_waggle.h b/doomsday/plugins/hexen/include/p_waggle.h index 2cc6e28554..be41fcfe80 100644 --- a/doomsday/plugins/hexen/include/p_waggle.h +++ b/doomsday/plugins/hexen/include/p_waggle.h @@ -22,6 +22,8 @@ #ifndef LIBHEXEN_P_WAGGLE_H #define LIBHEXEN_P_WAGGLE_H +#include "doomsday.h" + #ifndef __JHEXEN__ # error "Using jHexen headers without __JHEXEN__" #endif @@ -43,6 +45,11 @@ typedef struct { coord_t scaleDelta; int ticker; wagglestate_e state; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } waggle_t; #ifdef __cplusplus diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index 43612aaf80..df9e4c7e81 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -101,7 +101,7 @@ int ACScriptInterpreter::scriptInfoIndex(int scriptNumber) return -1; } -ACScript *ACScriptInterpreter::newACScript(BytecodeScriptInfo &info, byte const *args, int delayCount) +ACScript *ACScriptInterpreter::newACScript(BytecodeScriptInfo &info, byte const args[], int delayCount) { // Is the script is already executing? if(info.state != Inactive) return 0; @@ -127,7 +127,7 @@ ACScript *ACScriptInterpreter::newACScript(BytecodeScriptInfo &info, byte const return script; } -bool ACScriptInterpreter::newDeferredTask(uint map, int scriptNumber, byte const *args) +bool ACScriptInterpreter::newDeferredTask(uint map, int scriptNumber, byte const args[]) { if(_deferredTasksSize) { @@ -259,8 +259,8 @@ void ACScriptInterpreter::startOpenScripts() } } -bool ACScriptInterpreter::startScript(int scriptNumber, uint map, byte *args, mobj_t *activator, - Line *line, int side) +bool ACScriptInterpreter::startScript(int scriptNumber, uint map, byte const args[], + mobj_t *activator, Line *line, int side) { DENG_ASSERT(!IS_CLIENT); @@ -1686,7 +1686,7 @@ void P_ACScriptRunDeferredTasks(uint map/*Uri const *mapUri*/) interp.runDeferredTasks(map); } -dd_bool P_StartACScript(int scriptNumber, uint map, byte *args, mobj_t *activator, +dd_bool P_StartACScript(int scriptNumber, uint map, byte const args[], mobj_t *activator, Line *line, int side) { return interp.startScript(scriptNumber, map, args, activator, line, side); diff --git a/doomsday/plugins/hexen/src/p_lights.cpp b/doomsday/plugins/hexen/src/p_lights.cpp index c76874353a..a75365e796 100644 --- a/doomsday/plugins/hexen/src/p_lights.cpp +++ b/doomsday/plugins/hexen/src/p_lights.cpp @@ -114,6 +114,66 @@ void T_Light(light_t *light) } } +void light_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteByte(writer, (byte)type); + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt32(writer, (int) (255.0f * value1)); + Writer_WriteInt32(writer, (int) (255.0f * value2)); + Writer_WriteInt32(writer, tics1); + Writer_WriteInt32(writer, tics2); + Writer_WriteInt32(writer, count); +} + +int light_t::read(Reader *reader, int mapVersion) +{ + if(mapVersion >= 4) + { + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + type = (lighttype_t) Reader_ReadByte(reader); + + sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + value1 = (float) Reader_ReadInt32(reader) / 255.0f; + value2 = (float) Reader_ReadInt32(reader) / 255.0f; + tics1 = Reader_ReadInt32(reader); + tics2 = Reader_ReadInt32(reader); + count = Reader_ReadInt32(reader); + } + else + { + // Its in the old pre V4 format which serialized light_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + type = lighttype_t(Reader_ReadInt32(reader)); + value1 = (float) Reader_ReadInt32(reader) / 255.0f; + value2 = (float) Reader_ReadInt32(reader) / 255.0f; + tics1 = Reader_ReadInt32(reader); + tics2 = Reader_ReadInt32(reader); + count = Reader_ReadInt32(reader); + } + + thinker.function = (thinkfunc_t) T_Light; + + return true; // Add this thinker. +} + dd_bool EV_SpawnLight(Line *line, byte *arg, lighttype_t type) { int arg1, arg2, arg3, arg4; @@ -235,6 +295,53 @@ void T_Phase(phase_t *phase) phase->baseValue + phaseTable[phase->index]); } +void phase_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt32(writer, index); + Writer_WriteInt32(writer, (int) (255.0f * baseValue)); +} + +int phase_t::read(Reader *reader, int mapVersion) +{ + if(mapVersion >= 4) + { + // Note: the thinker class byte has already been read. + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + index = Reader_ReadInt32(reader); + baseValue = (float) Reader_ReadInt32(reader) / 255.0f; + } + else + { + // Its in the old pre V4 format which serialized phase_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + index = Reader_ReadInt32(reader); + baseValue = (float) Reader_ReadInt32(reader) / 255.0f; + } + + thinker.function = (thinkfunc_t) T_Phase; + + return true; // Add this thinker. +} + void P_SpawnPhasedLight(Sector *sector, float base, int index) { phase_t *phase = (phase_t *)Z_Calloc(sizeof(*phase), PU_MAP, 0); diff --git a/doomsday/plugins/hexen/src/p_pillar.cpp b/doomsday/plugins/hexen/src/p_pillar.cpp index 06b7de1ba4..89d1b11a8c 100644 --- a/doomsday/plugins/hexen/src/p_pillar.cpp +++ b/doomsday/plugins/hexen/src/p_pillar.cpp @@ -43,6 +43,68 @@ void T_BuildPillar(pillar_t *pillar) } } +void pillar_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt32(writer, FLT2FIX(ceilingSpeed)); + Writer_WriteInt32(writer, FLT2FIX(floorSpeed)); + Writer_WriteInt32(writer, FLT2FIX(floorDest)); + Writer_WriteInt32(writer, FLT2FIX(ceilingDest)); + Writer_WriteInt32(writer, direction); + Writer_WriteInt32(writer, crush); +} + +int pillar_t::read(Reader *reader, int mapVersion) +{ + if(mapVersion >= 4) + { + // Note: the thinker class byte has already been read. + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + // Start of used data members. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + ceilingSpeed = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + floorSpeed = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + floorDest = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + ceilingDest = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + direction = Reader_ReadInt32(reader); + crush = Reader_ReadInt32(reader); + } + else + { + // Its in the old pre V4 format which serialized pillar_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + ceilingSpeed = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + floorSpeed = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + floorDest = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + ceilingDest = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + direction = Reader_ReadInt32(reader); + crush = Reader_ReadInt32(reader); + } + + thinker.function = (thinkfunc_t) T_BuildPillar; + + P_ToXSector(sector)->specialData = this; + + return true; // Add this thinker. +} + int EV_BuildPillar(Line *line, byte *args, dd_bool crush) { iterlist_t *list = P_GetSectorIterListForTag((int) args[0], false); diff --git a/doomsday/plugins/hexen/src/p_waggle.cpp b/doomsday/plugins/hexen/src/p_waggle.cpp index 11a1bd5600..406fc2ffd3 100644 --- a/doomsday/plugins/hexen/src/p_waggle.cpp +++ b/doomsday/plugins/hexen/src/p_waggle.cpp @@ -75,6 +75,73 @@ void T_FloorWaggle(waggle_t *waggle) P_ChangeSector(waggle->sector, 1 /*crush damage*/); } +void waggle_t::write(Writer *writer) const +{ + Writer_WriteByte(writer, 1); // Write a version byte. + + // Note we don't bother to save a byte to tell if the function + // is present as we ALWAYS add one when loading. + + Writer_WriteInt32(writer, P_ToIndex(sector)); + + Writer_WriteInt32(writer, FLT2FIX(originalHeight)); + Writer_WriteInt32(writer, FLT2FIX(accumulator)); + Writer_WriteInt32(writer, FLT2FIX(accDelta)); + Writer_WriteInt32(writer, FLT2FIX(targetScale)); + Writer_WriteInt32(writer, FLT2FIX(scale)); + Writer_WriteInt32(writer, FLT2FIX(scaleDelta)); + Writer_WriteInt32(writer, ticker); + Writer_WriteInt32(writer, state); +} + +int waggle_t::read(Reader *reader, int mapVersion) +{ + if(mapVersion >= 4) + { + /*int ver =*/ Reader_ReadByte(reader); // version byte. + + // Start of used data members. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + originalHeight = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + accumulator = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + accDelta = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + targetScale = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + scale = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + scaleDelta = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + ticker = Reader_ReadInt32(reader); + state = wagglestate_e(Reader_ReadInt32(reader)); + } + else + { + // Its in the old pre V4 format which serialized waggle_t + // Padding at the start (an old thinker_t struct) + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); + + // Start of used data members. + // A 32bit pointer to sector, serialized. + sector = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader)); + DENG_ASSERT(sector != 0); + + originalHeight = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + accumulator = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + accDelta = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + targetScale = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + scale = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + scaleDelta = FIX2FLT((fixed_t) Reader_ReadInt32(reader)); + ticker = Reader_ReadInt32(reader); + state = wagglestate_e(Reader_ReadInt32(reader)); + } + + thinker.function = (thinkfunc_t) T_FloorWaggle; + + P_ToXSector(sector)->specialData = this; + + return true; // Add this thinker. +} + dd_bool EV_StartFloorWaggle(int tag, int height, int speed, int offset, int timer) { iterlist_t *list = P_GetSectorIterListForTag(tag, false); From c9152b1886b491aa3ad78fa67887676c48dc6e96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Thu, 30 Jan 2014 18:40:09 +0200 Subject: [PATCH 013/106] libdeng2|Log: Print log entry timestamp using seconds since start More compact and informative than omitting the hour. --- doomsday/libdeng2/include/de/data/time.h | 2 +- doomsday/libdeng2/src/core/log.cpp | 2 +- doomsday/libdeng2/src/data/time.cpp | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/doomsday/libdeng2/include/de/data/time.h b/doomsday/libdeng2/include/de/data/time.h index d0c3308c60..9992db1f57 100644 --- a/doomsday/libdeng2/include/de/data/time.h +++ b/doomsday/libdeng2/include/de/data/time.h @@ -125,7 +125,7 @@ class DENG2_PUBLIC Time : public ISerializable enum Format { ISOFormat, BuildNumberAndTime, - BuildNumberAndTimeWithoutHour, + BuildNumberAndSecondsSinceStart, FriendlyFormat, ISODateOnly, CompilerDateTime // Oct 7 2013 03:18:36 (__DATE__ __TIME__) diff --git a/doomsday/libdeng2/src/core/log.cpp b/doomsday/libdeng2/src/core/log.cpp index 6d926249c7..628311e731 100644 --- a/doomsday/libdeng2/src/core/log.cpp +++ b/doomsday/libdeng2/src/core/log.cpp @@ -352,7 +352,7 @@ String LogEntry::asText(Flags const &formattingFlags, int shortenSection) const // Begin with the timestamp. if(flags.testFlag(Styled)) output << TEXT_STYLE_LOG_TIME; - output << _when.asText(Date::BuildNumberAndTimeWithoutHour) << " "; + output << _when.asText(Date::BuildNumberAndSecondsSinceStart) << " "; if(!flags.testFlag(OmitDomain)) { diff --git a/doomsday/libdeng2/src/data/time.cpp b/doomsday/libdeng2/src/data/time.cpp index c32e245e4a..b145def1b6 100644 --- a/doomsday/libdeng2/src/data/time.cpp +++ b/doomsday/libdeng2/src/data/time.cpp @@ -306,9 +306,10 @@ String Time::asText(Format format) const { return d->dateTime.toString(Qt::TextDate); } - else if(format == BuildNumberAndTimeWithoutHour) + else if(format == BuildNumberAndSecondsSinceStart) { - return QString("#%1 ").arg(asBuildNumber(), -4) + d->dateTime.toString("mm:ss.zzz"); + return QString("#%1 %2").arg(asBuildNumber(), -4) + .arg(highPerfTimer.elapsed(), 7, 'f', 3, '0'); } else { From 9572fcbd8c3fb0a28e8002009d5260b7dd03d427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Thu, 30 Jan 2014 18:40:27 +0200 Subject: [PATCH 014/106] Fixed|Client|All Games: Busy mode transition when map changes in netgame --- doomsday/plugins/common/src/d_netcl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doomsday/plugins/common/src/d_netcl.c b/doomsday/plugins/common/src/d_netcl.c index 698b100f10..77221b8569 100644 --- a/doomsday/plugins/common/src/d_netcl.c +++ b/doomsday/plugins/common/src/d_netcl.c @@ -54,6 +54,8 @@ void NetCl_UpdateGameState(Reader* msg) byte gsSkill = 0; coord_t gsGravity = 0; + BusyMode_FreezeGameForBusyMode(); + gsFlags = Reader_ReadByte(msg); // Game identity key. From 22c54103511e01cad3c252ba608b3d7d899f2df1 Mon Sep 17 00:00:00 2001 From: danij Date: Thu, 30 Jan 2014 17:14:25 +0000 Subject: [PATCH 015/106] Refactor|libcommon: Switched p_xgsave.c to C++ --- doomsday/plugins/common/common.pri | 2 +- doomsday/plugins/common/include/p_xgsec.h | 195 +++++++++--------- .../common/src/{p_xgsave.c => p_xgsave.cpp} | 150 +++++++------- 3 files changed, 170 insertions(+), 177 deletions(-) rename doomsday/plugins/common/src/{p_xgsave.c => p_xgsave.cpp} (62%) diff --git a/doomsday/plugins/common/common.pri b/doomsday/plugins/common/common.pri index c1f6018d74..e5b219362c 100644 --- a/doomsday/plugins/common/common.pri +++ b/doomsday/plugins/common/common.pri @@ -118,7 +118,7 @@ SOURCES += \ $$common_src/p_view.c \ $$common_src/p_xgfile.c \ $$common_src/p_xgline.c \ - $$common_src/p_xgsave.c \ + $$common_src/p_xgsave.cpp \ $$common_src/p_xgsec.c \ $$common_src/polyobjs.cpp \ $$common_src/r_common.c \ diff --git a/doomsday/plugins/common/include/p_xgsec.h b/doomsday/plugins/common/include/p_xgsec.h index d3cdaf1a82..2d4edeaa00 100644 --- a/doomsday/plugins/common/include/p_xgsec.h +++ b/doomsday/plugins/common/include/p_xgsec.h @@ -1,40 +1,28 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_xgsec.h Extended generalized sector types. * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2006-2013 Daniel Swanson + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2006-2013 Daniel Swanson * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * p_xgsec.c: Extended Generalized Sector Types. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -#ifndef __XG_SECTORTYPE_H__ -#define __XG_SECTORTYPE_H__ +#ifndef LIBCOMMON_XG_SECTORTYPE_H +#define LIBCOMMON_XG_SECTORTYPE_H #include "g_common.h" -#ifdef __cplusplus -extern "C" { -#endif - // Sector chain event types. enum { XSCE_FLOOR, @@ -95,15 +83,15 @@ enum { #define PMF_ONE_SOUND_ONLY 0x100 typedef struct function_s { - struct function_s* link; // Linked to another func? - char* func; - int flags; - int pos; - int repeat; - int timer, maxTimer; - int minInterval, maxInterval; - float scale, offset; - float value, oldValue; + struct function_s *link; // Linked to another func? + char *func; + int flags; + int pos; + int repeat; + int timer, maxTimer; + int minInterval, maxInterval; + float scale, offset; + float value, oldValue; } function_t; enum { @@ -116,80 +104,91 @@ enum { }; typedef struct { - thinker_t thinker; - Sector* sector; + thinker_t thinker; + Sector *sector; } xsthinker_t; typedef struct { - dd_bool disabled; - function_t rgb[3]; // Don't move the functions around in the struct. - function_t plane[2]; - function_t light; - sectortype_t info; - int timer; - int chainTimer[DDLT_MAX_CHAINS]; + dd_bool disabled; + function_t rgb[3]; // Don't move the functions around in the struct. + function_t plane[2]; + function_t light; + sectortype_t info; + int timer; + int chainTimer[DDLT_MAX_CHAINS]; } xgsector_t; typedef struct { - thinker_t thinker; + thinker_t thinker; - Sector* sector; - dd_bool ceiling; // True if operates on the ceiling. + Sector *sector; + dd_bool ceiling; // True if operates on the ceiling. - int flags; - Line* origin; + int flags; + Line *origin; - coord_t destination; - float speed; - float crushSpeed; // Speed to use when crushing. + coord_t destination; + float speed; + float crushSpeed; // Speed to use when crushing. - Material* setMaterial; // Set material when move done. - int setSectorType; // Sector type to set when move done + Material *setMaterial; // Set material when move done. + int setSectorType; // Sector type to set when move done // (-1 if no change). - int startSound; // Played after waiting. - int endSound; // Play when move done. - int moveSound; // Sound to play while moving. - int minInterval, maxInterval; // Sound playing intervals. - int timer; // Counts down to zero. + int startSound; // Played after waiting. + int endSound; // Play when move done. + int moveSound; // Sound to play while moving. + int minInterval, maxInterval; // Sound playing intervals. + int timer; // Counts down to zero. } xgplanemover_t; -void XS_Init(void); -void XS_Update(void); - -void XS_Thinker(xsthinker_t* xs); - -coord_t XS_Gravity(Sector *sector); -coord_t XS_Friction(Sector *sector); -coord_t XS_ThrustMul(Sector *sector); - -void XS_InitMovePlane(Line *line); -int C_DECL XSTrav_MovePlane(Sector *sector, dd_bool ceiling, - void *context, void *context2, struct mobj_s *activator); -int C_DECL XSTrav_SectorType(Sector *sec, dd_bool ceiling, - void *context, void *context2, struct mobj_s *activator); -int C_DECL XSTrav_SectorLight(Sector *sector, dd_bool ceiling, - void *context, void *context2, struct mobj_s *activator); -int C_DECL XSTrav_PlaneMaterial(Sector *sec, dd_bool ceiling, - void *context, void *context2, struct mobj_s *activator); -void XS_InitStairBuilder(Line *line); -int C_DECL XSTrav_BuildStairs(Sector *sector, dd_bool ceiling, - void *context, void *context2, struct mobj_s *activator); -int C_DECL XSTrav_SectorSound(Sector *sec, dd_bool ceiling, - void *context, void *context2, struct mobj_s *activator); -int C_DECL XSTrav_MimicSector(Sector *sector, dd_bool ceiling, - void *context, void *context2, struct mobj_s *activator); -int C_DECL XSTrav_Teleport(Sector *sector, dd_bool ceiling, - void *context, void *context2, struct mobj_s *activator); -void XS_SetSectorType(Sector *sec, int special); -void XS_ChangePlaneMaterial(Sector *sector, dd_bool ceiling, - Material* mat, float *rgb); +#ifdef __cplusplus +extern "C" { +#endif + +void XS_Init(void); +void XS_Update(void); + +void XS_Thinker(xsthinker_t* xs); + +coord_t XS_Gravity(Sector *sector); +coord_t XS_Friction(Sector *sector); +coord_t XS_ThrustMul(Sector *sector); + +void XS_InitMovePlane(Line *line); + +int C_DECL XSTrav_MovePlane(Sector *sector, dd_bool ceiling, void *context, void *context2, struct mobj_s *activator); + +int C_DECL XSTrav_SectorType(Sector *sec, dd_bool ceiling, void *context, void *context2, struct mobj_s *activator); + +int C_DECL XSTrav_SectorLight(Sector *sector, dd_bool ceiling, void *context, void *context2, struct mobj_s *activator); + +int C_DECL XSTrav_PlaneMaterial(Sector *sec, dd_bool ceiling, void *context, void *context2, struct mobj_s *activator); + +void XS_InitStairBuilder(Line *line); + +int C_DECL XSTrav_BuildStairs(Sector *sector, dd_bool ceiling, void *context, void *context2, struct mobj_s *activator); + +int C_DECL XSTrav_SectorSound(Sector *sec, dd_bool ceiling, void *context, void *context2, struct mobj_s *activator); + +int C_DECL XSTrav_MimicSector(Sector *sector, dd_bool ceiling, void *context, void *context2, struct mobj_s *activator); + +int C_DECL XSTrav_Teleport(Sector *sector, dd_bool ceiling, void *context, void *context2, struct mobj_s *activator); + +void XS_SetSectorType(Sector *sec, int special); + +void XS_ChangePlaneMaterial(Sector *sector, dd_bool ceiling, Material* mat, float *rgb); + xgplanemover_t *XS_GetPlaneMover(Sector *sector, dd_bool ceiling); -void XS_PlaneMover(xgplanemover_t *mover); // A thinker for plane movers. -void SV_WriteXGSector(Sector *sec); -void SV_ReadXGSector(Sector *sec); -void SV_WriteXGPlaneMover(thinker_t *th); -int SV_ReadXGPlaneMover(xgplanemover_t* mov, int mapVersion); +void XS_PlaneMover(xgplanemover_t *mover); // A thinker for plane movers. + +void SV_WriteXGSector(Sector *sec); + +void SV_ReadXGSector(Sector *sec); + +void SV_WriteXGPlaneMover(thinker_t *th); + +int SV_ReadXGPlaneMover(xgplanemover_t* mov, int mapVersion); D_CMD(MovePlane); @@ -197,4 +196,4 @@ D_CMD(MovePlane); } // extern "C" #endif -#endif +#endif // LIBCOMMON_XG_SECTORTYPE_H diff --git a/doomsday/plugins/common/src/p_xgsave.c b/doomsday/plugins/common/src/p_xgsave.cpp similarity index 62% rename from doomsday/plugins/common/src/p_xgsave.c rename to doomsday/plugins/common/src/p_xgsave.cpp index 81dfc519c1..a84dc744ef 100644 --- a/doomsday/plugins/common/src/p_xgsave.c +++ b/doomsday/plugins/common/src/p_xgsave.cpp @@ -1,10 +1,7 @@ -/** - * @file p_xgsave.c: Extended Generalized Line Types. - * - * Implements: Saving and loading routines for the XG data/thinkers. +/** @file p_xgsave.cpp XG data/thinker (de)serialization. * - * @authors Copyright © 2003-2013 Jaakko Keränen - * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -29,22 +26,18 @@ #include "p_saveg.h" #include "p_xg.h" -void SV_WriteXGLine(Line* li) +void SV_WriteXGLine(Line *li) { - xgline_t* xg; - linetype_t* info; - - xg = P_ToXLine(li)->xg; - info = &xg->info; + xgline_t *xg = P_ToXLine(li)->xg; + linetype_t *info = &xg->info; // Version byte. SV_WriteByte(1); - /** - * Remember, savegames are applied on top of an initialized map. - * No strings are saved, because they are all const strings - * defined either in the maps's DDXGDATA lump or a DED file. - * During loading, XL_SetLineType is called with the id in the savegame. + /* + * Remember, savegames are applied on top of an initialized map. No strings are saved, + * because they are all const strings defined either in the maps's DDXGDATA lump or a + * DED file. During loading, XL_SetLineType is called with the id in the savegame. */ SV_WriteLong(info->id); @@ -54,17 +47,16 @@ void SV_WriteXGLine(Line* li) SV_WriteByte(xg->disabled); SV_WriteLong(xg->timer); SV_WriteLong(xg->tickerTimer); - SV_WriteShort(SV_ThingArchiveId(xg->activator)); + SV_WriteShort(SV_ThingArchiveId((mobj_t *)xg->activator)); SV_WriteLong(xg->idata); SV_WriteFloat(xg->fdata); SV_WriteLong(xg->chIdx); SV_WriteFloat(xg->chTimer); } -void SV_ReadXGLine(Line* li) +void SV_ReadXGLine(Line *li) { - xgline_t* xg; - xline_t* xline = P_ToXLine(li); + xline_t *xline = P_ToXLine(li); // Read version. SV_ReadByte(); @@ -72,30 +64,31 @@ void SV_ReadXGLine(Line* li) // This'll set all the correct string pointers and other data. XL_SetLineType(li, SV_ReadLong()); - if(!xline || !xline->xg) - Con_Error("SV_ReadXGLine: Bad XG line!\n"); + DENG_ASSERT(xline != 0); + DENG_ASSERT(xline->xg != 0); - xg = xline->xg; + xgline_t *xg = xline->xg; xg->info.actCount = SV_ReadLong(); - xg->active = SV_ReadByte(); - xg->disabled = SV_ReadByte(); - xg->timer = SV_ReadLong(); + + xg->active = SV_ReadByte(); + xg->disabled = SV_ReadByte(); + xg->timer = SV_ReadLong(); xg->tickerTimer = SV_ReadLong(); // Will be updated later. - xg->activator = INT2PTR(void, SV_ReadShort()); + xg->activator = INT2PTR(void, SV_ReadShort()); - xg->idata = SV_ReadLong(); - xg->fdata = SV_ReadFloat(); - xg->chIdx = SV_ReadLong(); - xg->chTimer = SV_ReadFloat(); + xg->idata = SV_ReadLong(); + xg->fdata = SV_ReadFloat(); + xg->chIdx = SV_ReadLong(); + xg->chTimer = SV_ReadFloat(); } /** * @param fn This function must belong to XG sector @a xg. */ -void SV_WriteXGFunction(xgsector_t* xg, function_t* fn) +void SV_WriteXGFunction(xgsector_t *xg, function_t *fn) { // Version byte. SV_WriteByte(1); @@ -112,29 +105,26 @@ void SV_WriteXGFunction(xgsector_t* xg, function_t* fn) /** * @param fn This function must belong to XG sector @a xg. */ -void SV_ReadXGFunction(xgsector_t* xg, function_t* fn) +void SV_ReadXGFunction(xgsector_t *xg, function_t *fn) { // Version byte. SV_ReadByte(); - fn->flags = SV_ReadLong(); - fn->pos = SV_ReadShort(); - fn->repeat = SV_ReadShort(); - fn->timer = SV_ReadShort(); + fn->flags = SV_ReadLong(); + fn->pos = SV_ReadShort(); + fn->repeat = SV_ReadShort(); + fn->timer = SV_ReadShort(); fn->maxTimer = SV_ReadShort(); - fn->value = SV_ReadFloat(); + fn->value = SV_ReadFloat(); fn->oldValue = SV_ReadFloat(); } -void SV_WriteXGSector(Sector* sec) +void SV_WriteXGSector(Sector *sec) { - xgsector_t* xg; - sectortype_t* info; - xsector_t* xsec = P_ToXSector(sec); - int i; + xsector_t *xsec = P_ToXSector(sec); - xg = xsec->xg; - info = &xg->info; + xgsector_t *xg = xsec->xg; + sectortype_t *info = &xg->info; // Version byte. SV_WriteByte(1); @@ -144,40 +134,46 @@ void SV_WriteXGSector(Sector* sec) SV_Write(xg->chainTimer, sizeof(xg->chainTimer)); SV_WriteLong(xg->timer); SV_WriteByte(xg->disabled); - for(i = 0; i < 3; ++i) + for(int i = 0; i < 3; ++i) + { SV_WriteXGFunction(xg, &xg->rgb[i]); - for(i = 0; i < 2; ++i) + } + for(int i = 0; i < 2; ++i) + { SV_WriteXGFunction(xg, &xg->plane[i]); + } SV_WriteXGFunction(xg, &xg->light); } void SV_ReadXGSector(Sector *sec) { - int i; - xgsector_t *xg; - xsector_t *xsec = P_ToXSector(sec); + xsector_t *xsec = P_ToXSector(sec); // Version byte. SV_ReadByte(); // This'll init all the data. XS_SetSectorType(sec, SV_ReadLong()); - xg = xsec->xg; + + xgsector_t *xg = xsec->xg; SV_Read(xg->info.count, sizeof(xg->info.count)); SV_Read(xg->chainTimer, sizeof(xg->chainTimer)); - xg->timer = SV_ReadLong(); + xg->timer = SV_ReadLong(); xg->disabled = SV_ReadByte(); - for(i = 0; i < 3; ++i) + for(int i = 0; i < 3; ++i) + { SV_ReadXGFunction(xg, &xg->rgb[i]); - for(i = 0; i < 2; ++i) + } + for(int i = 0; i < 2; ++i) + { SV_ReadXGFunction(xg, &xg->plane[i]); + } SV_ReadXGFunction(xg, &xg->light); } -void SV_WriteXGPlaneMover(thinker_t* th) +void SV_WriteXGPlaneMover(thinker_t *th) { - xgplanemover_t* mov = (xgplanemover_t*) th; - int i; + xgplanemover_t *mov = (xgplanemover_t *) th; SV_WriteByte(3); // Version. @@ -185,7 +181,7 @@ void SV_WriteXGPlaneMover(thinker_t* th) SV_WriteByte(mov->ceiling); SV_WriteLong(mov->flags); - i = P_ToIndex(mov->origin); + int i = P_ToIndex(mov->origin); if(i >= 0 && i < numlines) // Is it a real line? i++; else // No. @@ -209,23 +205,21 @@ void SV_WriteXGPlaneMover(thinker_t* th) /** * Reads the plane mover thinker. */ -int SV_ReadXGPlaneMover(xgplanemover_t* mov, int mapVersion) +int SV_ReadXGPlaneMover(xgplanemover_t *mov, int mapVersion) { byte ver = SV_ReadByte(); // Version. - mov->sector = P_ToPtr(DMU_SECTOR, SV_ReadLong()); - mov->ceiling = SV_ReadByte(); - mov->flags = SV_ReadLong(); + mov->sector = (Sector *)P_ToPtr(DMU_SECTOR, SV_ReadLong()); + mov->ceiling = SV_ReadByte(); + mov->flags = SV_ReadLong(); - { int lineIndex = SV_ReadLong(); if(lineIndex > 0) - mov->origin = P_ToPtr(DMU_LINE, lineIndex - 1); - } + mov->origin = (Line *)P_ToPtr(DMU_LINE, lineIndex - 1); mov->destination = FIX2FLT(SV_ReadLong()); - mov->speed = FIX2FLT(SV_ReadLong()); - mov->crushSpeed = FIX2FLT(SV_ReadLong()); + mov->speed = FIX2FLT(SV_ReadLong()); + mov->crushSpeed = FIX2FLT(SV_ReadLong()); if(ver >= 3) { @@ -234,25 +228,25 @@ int SV_ReadXGPlaneMover(xgplanemover_t* mov, int mapVersion) else { // Flat number is an absolute lump index. - Uri* uri = Uri_NewWithPath2("Flats:", RC_NULL); - ddstring_t name; - Str_Init(&name); + Uri *uri = Uri_NewWithPath2("Flats:", RC_NULL); + ddstring_t name; Str_Init(&name); F_FileName(&name, Str_Text(W_LumpName(SV_ReadLong()))); Uri_SetPath(uri, Str_Text(&name)); - mov->setMaterial = P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); + mov->setMaterial = (Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); Uri_Delete(uri); Str_Free(&name); } mov->setSectorType = SV_ReadLong(); - mov->startSound = SV_ReadLong(); - mov->endSound = SV_ReadLong(); - mov->moveSound = SV_ReadLong(); - mov->minInterval = SV_ReadLong(); - mov->maxInterval = SV_ReadLong(); - mov->timer = SV_ReadLong(); + mov->startSound = SV_ReadLong(); + mov->endSound = SV_ReadLong(); + mov->moveSound = SV_ReadLong(); + mov->minInterval = SV_ReadLong(); + mov->maxInterval = SV_ReadLong(); + mov->timer = SV_ReadLong(); mov->thinker.function = (thinkfunc_t) XS_PlaneMover; + return true; // Add this thinker. } From cecbd1edbcb402cbb6e63838886cac0b96790ef9 Mon Sep 17 00:00:00 2001 From: danij Date: Thu, 30 Jan 2014 17:16:01 +0000 Subject: [PATCH 016/106] Refactor|ACS|Hexen: Implement ACS state (de)serialization in C++, with Reader/Writer --- doomsday/plugins/hexen/src/acscript.cpp | 42 ++++++++++++------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index df9e4c7e81..44722963d8 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -474,23 +474,23 @@ void ACScriptInterpreter::writeWorldScriptData(Writer *writer) { SV_BeginSegment(ASEG_GLOBALSCRIPTDATA); - SV_WriteByte(3); // version byte + Writer_WriteByte(writer, 3); // version byte for(int i = 0; i < MAX_ACS_WORLD_VARS; ++i) { - SV_WriteLong(worldVars[i]); + Writer_WriteInt32(writer, worldVars[i]); } // Serialize the deferred task queue. - SV_WriteLong(_deferredTasksSize); + Writer_WriteInt32(writer, _deferredTasksSize); for(int i = 0; i < _deferredTasksSize; ++i) { DeferredTask const *task = &_deferredTasks[i]; - SV_WriteLong(task->map); - SV_WriteLong(task->scriptNumber); + Writer_WriteInt32(writer, task->map); + Writer_WriteInt32(writer, task->scriptNumber); for(int k = 0; k < 4; ++k) { - SV_WriteByte(task->args[k]); + Writer_WriteByte(writer, task->args[k]); } } } @@ -502,18 +502,18 @@ void ACScriptInterpreter::readWorldScriptData(Reader *reader, int saveVersion) if(saveVersion >= 7) { SV_AssertSegment(ASEG_GLOBALSCRIPTDATA); - ver = SV_ReadByte(); + ver = Reader_ReadByte(reader); } for(int i = 0; i < MAX_ACS_WORLD_VARS; ++i) { - worldVars[i] = SV_ReadLong(); + worldVars[i] = Reader_ReadInt32(reader); } // Deserialize the deferred task queue. if(ver >= 3) { - _deferredTasksSize = SV_ReadLong(); + _deferredTasksSize = Reader_ReadInt32(reader); if(_deferredTasksSize) { if(_deferredTasks) @@ -525,11 +525,11 @@ void ACScriptInterpreter::readWorldScriptData(Reader *reader, int saveVersion) { DeferredTask *task = &_deferredTasks[i]; - task->map = SV_ReadLong(); - task->scriptNumber = SV_ReadLong(); + task->map = Reader_ReadInt32(reader); + task->scriptNumber = Reader_ReadInt32(reader); for(int k = 0; k < 4; ++k) { - task->args[k] = SV_ReadByte(); + task->args[k] = Reader_ReadByte(reader); } } } @@ -542,14 +542,14 @@ void ACScriptInterpreter::readWorldScriptData(Reader *reader, int saveVersion) _deferredTasksSize = 0; for(int i = 0; i < 20; ++i) { - int map = SV_ReadLong(); + int map = Reader_ReadInt32(reader); DeferredTask *task = &tempTasks[map < 0? 19 : _deferredTasksSize++]; task->map = map < 0? 0 : map-1; - task->scriptNumber = SV_ReadLong(); + task->scriptNumber = Reader_ReadInt32(reader); for(int k = 0; k < 4; ++k) { - task->args[k] = SV_ReadByte(); + task->args[k] = Reader_ReadByte(reader); } } @@ -582,13 +582,13 @@ void ACScriptInterpreter::writeMapScriptData(Writer *writer) for(int i = 0; i < _scriptCount; ++i) { BytecodeScriptInfo &info = _scriptInfo[i]; - SV_WriteShort(info.state); - SV_WriteShort(info.waitValue); + Writer_WriteInt16(writer, info.state); + Writer_WriteInt16(writer, info.waitValue); } for(int i = 0; i < MAX_ACS_MAP_VARS; ++i) { - SV_WriteLong(mapVars[i]); + Writer_WriteInt32(writer, mapVars[i]); } } @@ -600,13 +600,13 @@ void ACScriptInterpreter::readMapScriptData(Reader *reader) { BytecodeScriptInfo &info = _scriptInfo[i]; - info.state = (ACScriptState) SV_ReadShort(); - info.waitValue = SV_ReadShort(); + info.state = ACScriptState( Reader_ReadInt16(reader) ); + info.waitValue = Reader_ReadInt16(reader); } for(int i = 0; i < MAX_ACS_MAP_VARS; ++i) { - mapVars[i] = SV_ReadLong(); + mapVars[i] = Reader_ReadInt32(reader); } } From 09977379307701ec95bbf792ddc8d0cc74e64172 Mon Sep 17 00:00:00 2001 From: danij Date: Thu, 30 Jan 2014 17:16:43 +0000 Subject: [PATCH 017/106] Refactor|Hexen: Implement sound sequence (de)serialization with Reader/Writer --- doomsday/plugins/hexen/src/sn_sonix.cpp | 38 ++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/doomsday/plugins/hexen/src/sn_sonix.cpp b/doomsday/plugins/hexen/src/sn_sonix.cpp index 83f3f00359..c7a2808431 100644 --- a/doomsday/plugins/hexen/src/sn_sonix.cpp +++ b/doomsday/plugins/hexen/src/sn_sonix.cpp @@ -494,16 +494,16 @@ void SN_WriteSequences(Writer *writer) { SV_BeginSegment(ASEG_SOUNDS); - SV_WriteLong(activeSequenceCount); + Writer_WriteInt32(writer, activeSequenceCount); for(seqnode_t *node = sequences; node; node = node->next) { - SV_WriteByte(1); // Write a version byte. + Writer_WriteByte(writer, 1); // Write a version byte. - SV_WriteLong(node->sequence); - SV_WriteLong(node->delayTics); - SV_WriteLong(node->volume); - SV_WriteLong(SN_GetSequenceOffset(node->sequence, node->sequencePtr)); - SV_WriteLong(node->currentSoundID); + Writer_WriteInt32(writer, node->sequence); + Writer_WriteInt32(writer, node->delayTics); + Writer_WriteInt32(writer, node->volume); + Writer_WriteInt32(writer, SN_GetSequenceOffset(node->sequence, node->sequencePtr)); + Writer_WriteInt32(writer, node->currentSoundID); int i = 0; if(node->mobj) @@ -522,15 +522,15 @@ void SN_WriteSequences(Writer *writer) { // The sound's emitter is the sector, not the polyobj itself. difference = P_ToIndex(Sector_AtPoint_FixedPrecision(node->mobj->origin)); - SV_WriteLong(0); // 0 -- sector sound origin. + Writer_WriteInt32(writer, 0); // 0 -- sector sound origin. } else { - SV_WriteLong(1); // 1 -- polyobj sound origin + Writer_WriteInt32(writer, 1); // 1 -- polyobj sound origin difference = i; } - SV_WriteLong(difference); + Writer_WriteInt32(writer, difference); } } @@ -539,20 +539,20 @@ void SN_ReadSequences(Reader *reader, int mapVersion) SV_AssertSegment(ASEG_SOUNDS); // Reload and restart all sound sequences - int numSequences = SV_ReadLong(); + int numSequences = Reader_ReadInt32(reader); for(int i = 0; i < numSequences; ++i) { - /*int ver =*/ (mapVersion >= 3)? SV_ReadByte() : 0; + /*int ver =*/ (mapVersion >= 3)? Reader_ReadByte(reader) : 0; - int sequence = SV_ReadLong(); - int delayTics = SV_ReadLong(); - int volume = SV_ReadLong(); - int seqOffset = SV_ReadLong(); + int sequence = Reader_ReadInt32(reader); + int delayTics = Reader_ReadInt32(reader); + int volume = Reader_ReadInt32(reader); + int seqOffset = Reader_ReadInt32(reader); - int soundID = SV_ReadLong(); - int polySnd = SV_ReadLong(); - int secNum = SV_ReadLong(); + int soundID = Reader_ReadInt32(reader); + int polySnd = Reader_ReadInt32(reader); + int secNum = Reader_ReadInt32(reader); mobj_t *sndMobj = 0; if(!polySnd) From 52a23ffa1713f17f15ea0dad374fc66f251635f7 Mon Sep 17 00:00:00 2001 From: danij Date: Thu, 30 Jan 2014 17:23:21 +0000 Subject: [PATCH 018/106] Refactor|XG|libcommon: Implement XG plane-mover (de)serialization in C++, with Reader/Writer --- doomsday/plugins/common/include/p_xgsec.h | 9 +-- doomsday/plugins/common/src/p_saveg.cpp | 4 +- doomsday/plugins/common/src/p_xgsave.cpp | 83 +++++++++++------------ 3 files changed, 46 insertions(+), 50 deletions(-) diff --git a/doomsday/plugins/common/include/p_xgsec.h b/doomsday/plugins/common/include/p_xgsec.h index 2d4edeaa00..4d5dd1bf53 100644 --- a/doomsday/plugins/common/include/p_xgsec.h +++ b/doomsday/plugins/common/include/p_xgsec.h @@ -139,6 +139,11 @@ typedef struct { int moveSound; // Sound to play while moving. int minInterval, maxInterval; // Sound playing intervals. int timer; // Counts down to zero. + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } xgplanemover_t; #ifdef __cplusplus @@ -186,10 +191,6 @@ void SV_WriteXGSector(Sector *sec); void SV_ReadXGSector(Sector *sec); -void SV_WriteXGPlaneMover(thinker_t *th); - -int SV_ReadXGPlaneMover(xgplanemover_t* mov, int mapVersion); - D_CMD(MovePlane); #ifdef __cplusplus diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index a81b40e823..9c6cf192ae 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -194,8 +194,8 @@ static ThinkerClassInfo thinkerInfo[] = { TC_XGMOVER, (thinkfunc_t) XS_PlaneMover, 0, - (WriteThinkerFunc) SV_WriteXGPlaneMover, - (ReadThinkerFunc) SV_ReadXGPlaneMover, + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, sizeof(xgplanemover_t) }, #endif diff --git a/doomsday/plugins/common/src/p_xgsave.cpp b/doomsday/plugins/common/src/p_xgsave.cpp index a84dc744ef..2b18d8cffe 100644 --- a/doomsday/plugins/common/src/p_xgsave.cpp +++ b/doomsday/plugins/common/src/p_xgsave.cpp @@ -171,81 +171,76 @@ void SV_ReadXGSector(Sector *sec) SV_ReadXGFunction(xg, &xg->light); } -void SV_WriteXGPlaneMover(thinker_t *th) +void xgplanemover_t::write(Writer *writer) const { - xgplanemover_t *mov = (xgplanemover_t *) th; + Writer_WriteByte(writer, 3); // Version. - SV_WriteByte(3); // Version. + Writer_WriteInt32(writer, P_ToIndex(sector)); + Writer_WriteByte(writer, ceiling); + Writer_WriteInt32(writer, flags); - SV_WriteLong(P_ToIndex(mov->sector)); - SV_WriteByte(mov->ceiling); - SV_WriteLong(mov->flags); - - int i = P_ToIndex(mov->origin); + int i = P_ToIndex(origin); if(i >= 0 && i < numlines) // Is it a real line? i++; else // No. i = 0; - SV_WriteLong(i); // Zero means there is no origin. - - SV_WriteLong(FLT2FIX(mov->destination)); - SV_WriteLong(FLT2FIX(mov->speed)); - SV_WriteLong(FLT2FIX(mov->crushSpeed)); - SV_WriteLong(MaterialArchive_FindUniqueSerialId(SV_MaterialArchive(), mov->setMaterial)); - SV_WriteLong(mov->setSectorType); - SV_WriteLong(mov->startSound); - SV_WriteLong(mov->endSound); - SV_WriteLong(mov->moveSound); - SV_WriteLong(mov->minInterval); - SV_WriteLong(mov->maxInterval); - SV_WriteLong(mov->timer); + Writer_WriteInt32(writer, i); // Zero means there is no origin. + + Writer_WriteInt32(writer, FLT2FIX(destination)); + Writer_WriteInt32(writer, FLT2FIX(speed)); + Writer_WriteInt32(writer, FLT2FIX(crushSpeed)); + Writer_WriteInt32(writer, MaterialArchive_FindUniqueSerialId(SV_MaterialArchive(), setMaterial)); + Writer_WriteInt32(writer, setSectorType); + Writer_WriteInt32(writer, startSound); + Writer_WriteInt32(writer, endSound); + Writer_WriteInt32(writer, moveSound); + Writer_WriteInt32(writer, minInterval); + Writer_WriteInt32(writer, maxInterval); + Writer_WriteInt32(writer, timer); } -/** - * Reads the plane mover thinker. - */ -int SV_ReadXGPlaneMover(xgplanemover_t *mov, int mapVersion) +int xgplanemover_t::read(Reader *reader, int mapVersion) { - byte ver = SV_ReadByte(); // Version. + byte ver = Reader_ReadByte(reader); // Version. - mov->sector = (Sector *)P_ToPtr(DMU_SECTOR, SV_ReadLong()); - mov->ceiling = SV_ReadByte(); - mov->flags = SV_ReadLong(); + sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(reader)); + ceiling = Reader_ReadByte(reader); + flags = Reader_ReadInt32(reader); int lineIndex = SV_ReadLong(); if(lineIndex > 0) - mov->origin = (Line *)P_ToPtr(DMU_LINE, lineIndex - 1); + origin = (Line *)P_ToPtr(DMU_LINE, lineIndex - 1); - mov->destination = FIX2FLT(SV_ReadLong()); - mov->speed = FIX2FLT(SV_ReadLong()); - mov->crushSpeed = FIX2FLT(SV_ReadLong()); + destination = FIX2FLT(Reader_ReadInt32(reader)); + speed = FIX2FLT(Reader_ReadInt32(reader)); + crushSpeed = FIX2FLT(Reader_ReadInt32(reader)); if(ver >= 3) { - mov->setMaterial = SV_GetArchiveMaterial(SV_ReadLong(), 0); + setMaterial = SV_GetArchiveMaterial(Reader_ReadInt32(reader), 0); } else { // Flat number is an absolute lump index. Uri *uri = Uri_NewWithPath2("Flats:", RC_NULL); ddstring_t name; Str_Init(&name); - F_FileName(&name, Str_Text(W_LumpName(SV_ReadLong()))); + F_FileName(&name, Str_Text(W_LumpName(Reader_ReadInt32(reader)))); Uri_SetPath(uri, Str_Text(&name)); - mov->setMaterial = (Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); + setMaterial = (Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); Uri_Delete(uri); Str_Free(&name); } - mov->setSectorType = SV_ReadLong(); - mov->startSound = SV_ReadLong(); - mov->endSound = SV_ReadLong(); - mov->moveSound = SV_ReadLong(); - mov->minInterval = SV_ReadLong(); - mov->maxInterval = SV_ReadLong(); - mov->timer = SV_ReadLong(); + setSectorType = Reader_ReadInt32(reader); + startSound = Reader_ReadInt32(reader); + endSound = Reader_ReadInt32(reader); + moveSound = Reader_ReadInt32(reader); + minInterval = Reader_ReadInt32(reader); + maxInterval = Reader_ReadInt32(reader); + timer = Reader_ReadInt32(reader); - mov->thinker.function = (thinkfunc_t) XS_PlaneMover; + thinker.function = (thinkfunc_t) XS_PlaneMover; return true; // Add this thinker. } From 07c52dcb3914334c2217f953a8471c80017c3d08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Thu, 30 Jan 2014 20:46:10 +0200 Subject: [PATCH 019/106] Refactor|Client|Network: Cleaned up server info functions --- doomsday/client/include/network/net_main.h | 10 +++-- doomsday/client/src/network/masterserver.cpp | 2 +- doomsday/client/src/network/net_event.cpp | 4 +- doomsday/client/src/network/net_main.cpp | 38 ++++++++++++++++--- doomsday/client/src/network/serverlink.cpp | 8 ++-- .../src/ui/dialogs/multiplayerdialog.cpp | 27 +------------ .../src/ui/widgets/multiplayermenuwidget.cpp | 1 + .../client/src/ui/widgets/taskbarwidget.cpp | 2 +- 8 files changed, 50 insertions(+), 42 deletions(-) diff --git a/doomsday/client/include/network/net_main.h b/doomsday/client/include/network/net_main.h index fa022a539f..40ef44d39f 100644 --- a/doomsday/client/include/network/net_main.h +++ b/doomsday/client/include/network/net_main.h @@ -255,22 +255,24 @@ void Net_Ticker(timespan_t time); */ void Net_Drawer(void); -dd_bool Net_IsLocalPlayer(int pNum); +dd_bool Net_IsLocalPlayer(int pNum); -void Net_PrintServerInfo(int index, serverinfo_t *info); +void ServerInfo_Print(serverinfo_t const *info, int index); /** * Converts textual data to a serverinfo struct. Returns true if the * label/value pair is recognized. */ -dd_bool Net_StringToServerInfo(char const *valuePair, serverinfo_t *info); +dd_bool ServerInfo_FromString(serverinfo_t *info, char const *valuePair); -void Net_RecordToServerInfo(de::Record const &rec, serverinfo_t *info); +void ServerInfo_FromRecord(serverinfo_t *info, de::Record const &rec); #ifdef __cplusplus } // extern "C" #endif +de::String ServerInfo_AsStyledText(serverinfo_t const *sv); + de::String Net_UserAgent(); #endif /* LIBDENG_NETWORK_H */ diff --git a/doomsday/client/src/network/masterserver.cpp b/doomsday/client/src/network/masterserver.cpp index 3c2123f691..682d3510de 100644 --- a/doomsday/client/src/network/masterserver.cpp +++ b/doomsday/client/src/network/masterserver.cpp @@ -237,7 +237,7 @@ bool MasterWorker::parseResponse(const QByteArray& response) if(info) { - Net_StringToServerInfo(Str_Text(&line), info); + ServerInfo_FromString(info, Str_Text(&line)); } } diff --git a/doomsday/client/src/network/net_event.cpp b/doomsday/client/src/network/net_event.cpp index ad5c7403fa..782fac1c5b 100644 --- a/doomsday/client/src/network/net_event.cpp +++ b/doomsday/client/src/network/net_event.cpp @@ -180,13 +180,13 @@ void N_NETicker(timespan_t time) break; case MAC_LIST: - Net_PrintServerInfo(0, NULL); + ServerInfo_Print(NULL, 0); num = i = N_MasterGet(0, 0); while(--i >= 0) { serverinfo_t info; N_MasterGet(i, &info); - Net_PrintServerInfo(i, &info); + ServerInfo_Print(&info, i); } LOG_NET_VERBOSE("%i server%s found") << num << (num != 1 ? "s were" : " was"); N_MARemove(); diff --git a/doomsday/client/src/network/net_main.cpp b/doomsday/client/src/network/net_main.cpp index 5595b0ed5d..c1e8f3d6bb 100644 --- a/doomsday/client/src/network/net_main.cpp +++ b/doomsday/client/src/network/net_main.cpp @@ -59,6 +59,7 @@ #include #include +#include // MACROS ------------------------------------------------------------------ @@ -802,11 +803,38 @@ void Net_Ticker(timespan_t time) } } +de::String ServerInfo_AsStyledText(serverinfo_t const *sv) +{ +#define TABBED(A, B) _E(Ta)_E(l) " " A _E(.) " " _E(\t) B "\n" + return de::String(_E(b) "%1" _E(.) "\n%2\n" _E(T`) + TABBED("Joinable:", "%5") + TABBED("Players:", "%3 / %4%13") + TABBED("Game:", "%9\n%10\n%12 %11") + TABBED("PWADs:", "%14") + TABBED("Address:", "%6:%7") + TABBED("Ping:", "%8 ms (approx)")) + .arg(sv->name) + .arg(sv->description) + .arg(sv->numPlayers) + .arg(sv->maxPlayers) + .arg(sv->canJoin? "Yes" : "No") // 5 + .arg(sv->address) + .arg(sv->port) + .arg(sv->ping) + .arg(sv->plugin) + .arg(sv->gameIdentityKey) // 10 + .arg(sv->gameConfig) + .arg(sv->map) + .arg(!de::String(sv->clientNames).isEmpty()? de::String(_E(2) " (%1)" _E(.)).arg(sv->clientNames) : "") + .arg(de::String(sv->pwads).isEmpty()? de::String(DENG2_CHAR_MDASH) : de::String(sv->pwads)); // 14 +#undef TABBED +} + /** * Prints server/host information into the console. The header line is * printed if 'info' is NULL. */ -void Net_PrintServerInfo(int index, serverinfo_t *info) +void ServerInfo_Print(serverinfo_t const *info, int index) { /// @todo Update table for de::Log. -jk /// @@ -1256,7 +1284,7 @@ D_CMD(Net) serverinfo_t info; if(Net_ServerLink().foundServerInfo(index, &info)) { - Net_PrintServerInfo(index, &info); + ServerInfo_Print(&info, index); Net_ServerLink().connectDomain(de::String("%1:%2").arg(info.address).arg(info.port), 5); } } @@ -1321,9 +1349,9 @@ static dd_bool tokenize(char const *line, char *label, char *value, int max) return true; } -void Net_RecordToServerInfo(de::Record const &rec, serverinfo_t *info) +void ServerInfo_FromRecord(serverinfo_t *info, de::Record const &rec) { - memset(info, 0, sizeof(*info)); + de::zapPtr(info); info->port = (int) rec["port"].value().asNumber(); info->version = (int) rec["ver" ].value().asNumber(); @@ -1348,7 +1376,7 @@ void Net_RecordToServerInfo(de::Record const &rec, serverinfo_t *info) #undef COPY_STR } -dd_bool Net_StringToServerInfo(const char *valuePair, serverinfo_t *info) +dd_bool ServerInfo_FromString(serverinfo_t *info, char const *valuePair) { char label[SVINFO_TOKEN_LEN], value[SVINFO_TOKEN_LEN]; diff --git a/doomsday/client/src/network/serverlink.cpp b/doomsday/client/src/network/serverlink.cpp index 59283e0bcd..69db720e58 100644 --- a/doomsday/client/src/network/serverlink.cpp +++ b/doomsday/client/src/network/serverlink.cpp @@ -96,7 +96,7 @@ DENG2_PIMPL(ServerLink) do { ch = Str_GetLine(line, ch); - Net_StringToServerInfo(Str_Text(line), &svInfo); + ServerInfo_FromString(&svInfo, Str_Text(line)); } while(*ch); @@ -116,8 +116,8 @@ DENG2_PIMPL(ServerLink) << discovered.size() << (discovered.size() != 1 ? "s have" : " has"); - Net_PrintServerInfo(0, NULL); - Net_PrintServerInfo(0, &svInfo); + ServerInfo_Print(NULL, 0); + ServerInfo_Print(&svInfo, 0); notifyDiscoveryUpdate(); } @@ -174,7 +174,7 @@ DENG2_PIMPL(ServerLink) foreach(Address sv, finder.foundServers()) { serverinfo_t info; - Net_RecordToServerInfo(finder.messageFromServer(sv), &info); + ServerInfo_FromRecord(&info, finder.messageFromServer(sv)); // Update the address in the info, which is missing because this // information didn't come from the master. diff --git a/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp b/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp index 2c4ba07159..91d633699e 100644 --- a/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp +++ b/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp @@ -183,30 +183,7 @@ DENG_GUI_PIMPL(MultiplayerDialog) .arg(sv.map)); // Extra information. -#define TABBED(A, B) _E(Ta)_E(l) " " A _E(.) " " _E(\t) B "\n" - info->document() - .setText(String(_E(b) "%1" _E(.) "\n%2\n" _E(T`) - TABBED("Joinable:", "%5") - TABBED("Players:", "%3 / %4%13") - TABBED("Game:", "%9\n%10\n%12 %11") - TABBED("PWADs:", "%14") - TABBED("Address:", "%6:%7") - TABBED("Ping:", "%8 ms (approx)")) - .arg(sv.name) - .arg(sv.description) - .arg(sv.numPlayers) - .arg(sv.maxPlayers) - .arg(sv.canJoin? "Yes" : "No") // 5 - .arg(sv.address) - .arg(sv.port) - .arg(sv.ping) - .arg(sv.plugin) - .arg(sv.gameIdentityKey) // 10 - .arg(sv.gameConfig) - .arg(sv.map) - .arg(!String(sv.clientNames).isEmpty()? String(_E(2) " (%1)" _E(.)).arg(sv.clientNames) : "") - .arg(String(sv.pwads).isEmpty()? String(DENG2_CHAR_MDASH) : String(sv.pwads))); // 14 -#undef TABBED + info->document().setText(ServerInfo_AsStyledText(&sv)); } catch(Error const &) { @@ -284,7 +261,7 @@ DENG_GUI_PIMPL(MultiplayerDialog) MultiplayerDialog::MultiplayerDialog(String const &name) : DialogWidget(name, WithHeading), d(new Instance(this)) { - heading().setText(tr("Multiplayer")); + heading().setText(tr("Multiplayer Games")); LabelWidget *lab = LabelWidget::newWithText(tr("Games from Master Server and local network:"), &area()); diff --git a/doomsday/client/src/ui/widgets/multiplayermenuwidget.cpp b/doomsday/client/src/ui/widgets/multiplayermenuwidget.cpp index 54494192aa..fb1e94b5a8 100644 --- a/doomsday/client/src/ui/widgets/multiplayermenuwidget.cpp +++ b/doomsday/client/src/ui/widgets/multiplayermenuwidget.cpp @@ -21,6 +21,7 @@ #include "CommandAction" #include +#include using namespace de; diff --git a/doomsday/client/src/ui/widgets/taskbarwidget.cpp b/doomsday/client/src/ui/widgets/taskbarwidget.cpp index 84c03dcc6f..04ab4d2618 100644 --- a/doomsday/client/src/ui/widgets/taskbarwidget.cpp +++ b/doomsday/client/src/ui/widgets/taskbarwidget.cpp @@ -403,7 +403,7 @@ TaskBarWidget::TaskBarWidget() : GuiWidget("taskbar"), d(new Instance(this)) << new ui::SubwidgetItem(style().images().image("updater"), tr("Updater"), ui::Left, makeUpdaterSettings); d->mainMenu->items() - << new ui::SubwidgetItem(tr("Multiplayer..."), ui::Left, makePopup) + << new ui::SubwidgetItem(tr("Multiplayer Games..."), ui::Left, makePopup) << new ui::Item(ui::Item::Separator) << new ui::ActionItem(tr("Check for Updates..."), new CommandAction("updateandnotify")) << new ui::ActionItem(tr("About Doomsday"), new SignalAction(this, SLOT(showAbout()))) From 5af6fefe3886b600af947453c7c132a2b6e42af8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Thu, 30 Jan 2014 21:46:53 +0200 Subject: [PATCH 020/106] Windows|Fixed|libappfw: Missing export --- doomsday/libappfw/include/de/widgets/documentpopupwidget.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doomsday/libappfw/include/de/widgets/documentpopupwidget.h b/doomsday/libappfw/include/de/widgets/documentpopupwidget.h index 6801a6ef90..30080019d7 100644 --- a/doomsday/libappfw/include/de/widgets/documentpopupwidget.h +++ b/doomsday/libappfw/include/de/widgets/documentpopupwidget.h @@ -27,7 +27,7 @@ namespace de { /** * Utility widget that has a document inside a popup. */ -class DocumentPopupWidget : public PopupWidget +class LIBAPPFW_PUBLIC DocumentPopupWidget : public PopupWidget { Q_OBJECT From 3dda1dee0e2bd0d44f54795a5c2ac92cbf3b54ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Thu, 30 Jan 2014 21:48:21 +0200 Subject: [PATCH 021/106] Windows|Fixed|libgui: Accessing main window even if it doesn't exist During a fatal error shutdown, DisplayMode was asked to set the color transfer function after the window had been disposed of. --- doomsday/libgui/src/displaymode_windows.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doomsday/libgui/src/displaymode_windows.cpp b/doomsday/libgui/src/displaymode_windows.cpp index 34e867dbd3..ee85a10c20 100644 --- a/doomsday/libgui/src/displaymode_windows.cpp +++ b/doomsday/libgui/src/displaymode_windows.cpp @@ -116,6 +116,8 @@ int DisplayMode_Native_Change(const DisplayMode* mode, int shouldCapture) void DisplayMode_Native_SetColorTransfer(DisplayColorTransfer const *colors) { + if(!de::CanvasWindow::mainExists()) return; + HWND hWnd = (HWND) de::CanvasWindow::main().nativeHandle(); DENG2_ASSERT(hWnd != 0); From 643114e8488902a642de09e2b8e7cddec559a380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Thu, 30 Jan 2014 22:14:47 +0200 Subject: [PATCH 022/106] Fixed: Build error --- doomsday/plugins/common/src/p_door.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doomsday/plugins/common/src/p_door.cpp b/doomsday/plugins/common/src/p_door.cpp index b4d454b2d0..8bb4375f75 100644 --- a/doomsday/plugins/common/src/p_door.cpp +++ b/doomsday/plugins/common/src/p_door.cpp @@ -482,7 +482,8 @@ int EV_DoDoor(Line *line, doortype_e type) #if __JDOOM__ || __JDOOM64__ || __JHERETIC__ static void sendNeedKeyMessage(player_t *p, textenum_t msgTxt, int keyNum) { - char buf[160], *in, tmp[2]; + char buf[160], tmp[2]; + char const *in; buf[0] = 0; tmp[1] = 0; From 0c9c94ce502781ec21c08e3bae200aff9c9db7f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Thu, 30 Jan 2014 22:15:42 +0200 Subject: [PATCH 023/106] UI|Client: Close MP server info popup when joining the server --- doomsday/client/src/ui/dialogs/multiplayerdialog.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp b/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp index 91d633699e..f7095e9d6a 100644 --- a/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp +++ b/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp @@ -212,7 +212,10 @@ DENG_GUI_PIMPL(MultiplayerDialog) GuiWidget *makeItemWidget(ui::Item const &item, GuiWidget const *) { - return new ServerWidget; + ServerWidget *w = new ServerWidget; + // Automatically close the info popup if the dialog is closed. + QObject::connect(thisPublic, SIGNAL(closed()), w->info, SLOT(close())); + return w; } void updateItemWidget(GuiWidget &widget, ui::Item const &item) From 94de3c9e70a51ec9b520542185505f1c98f5188d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Fri, 31 Jan 2014 09:10:52 +0200 Subject: [PATCH 024/106] OS X|Fixed|libgui: No Core Text font implementation in 10.6 build The qmake project was still including the Core Text based fonts in the 10.6 build. --- doomsday/libgui/libgui.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doomsday/libgui/libgui.pro b/doomsday/libgui/libgui.pro index c3ed1c43c5..a0d21237ea 100644 --- a/doomsday/libgui/libgui.pro +++ b/doomsday/libgui/libgui.pro @@ -153,7 +153,7 @@ SOURCES += \ src/rowatlasallocator.cpp \ src/qtnativefont.cpp -macx: SOURCES += \ +macx:!deng_macx6_32bit_64bit: SOURCES += \ src/coretextnativefont_macx.h \ src/coretextnativefont_macx.cpp From 83b73c718ed5551b46f144b5bfbfb6a40a8f6d4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Fri, 31 Jan 2014 10:05:42 +0200 Subject: [PATCH 025/106] Debug|libdeng1: Added an assert --- doomsday/libdeng1/src/writer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/doomsday/libdeng1/src/writer.c b/doomsday/libdeng1/src/writer.c index af6d691493..d19558fa8a 100644 --- a/doomsday/libdeng1/src/writer.c +++ b/doomsday/libdeng1/src/writer.c @@ -324,6 +324,7 @@ void Writer_Write(Writer *writer, void const *buffer, size_t len) void Writer_WritePackedUInt16(Writer *writer, uint16_t v) { + DENG_ASSERT(!(v & 0x8000)); if(v & 0x8000) { App_Log(DE2_LOG_ERROR, From c11729456915a554e95be792c2d9c1de6082f465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Fri, 31 Jan 2014 19:56:33 +0200 Subject: [PATCH 026/106] UI|Multiplayer: MP menu shows server address and connection duration --- .../ui/widgets/multiplayermenuwidget.h | 9 +++ .../src/ui/widgets/multiplayermenuwidget.cpp | 68 +++++++++++++++++-- .../libappfw/src/widgets/popupmenuwidget.cpp | 6 +- 3 files changed, 78 insertions(+), 5 deletions(-) diff --git a/doomsday/client/include/ui/widgets/multiplayermenuwidget.h b/doomsday/client/include/ui/widgets/multiplayermenuwidget.h index 93a22f9ecb..fadf2dd55a 100644 --- a/doomsday/client/include/ui/widgets/multiplayermenuwidget.h +++ b/doomsday/client/include/ui/widgets/multiplayermenuwidget.h @@ -28,8 +28,17 @@ */ class MultiplayerMenuWidget : public de::PopupMenuWidget { + Q_OBJECT + public: MultiplayerMenuWidget(); + +public slots: + void updateElapsedTime(); + +protected: + void preparePanelForOpening(); + void panelClosing(); private: DENG2_PRIVATE(d) diff --git a/doomsday/client/src/ui/widgets/multiplayermenuwidget.cpp b/doomsday/client/src/ui/widgets/multiplayermenuwidget.cpp index fb1e94b5a8..5dd51a376c 100644 --- a/doomsday/client/src/ui/widgets/multiplayermenuwidget.cpp +++ b/doomsday/client/src/ui/widgets/multiplayermenuwidget.cpp @@ -18,34 +18,94 @@ #include "ui/widgets/multiplayermenuwidget.h" #include "network/serverlink.h" +#include "clientapp.h" #include "CommandAction" #include #include +#include using namespace de; +enum { + POS_STATUS = 1 +}; + DENG_GUI_PIMPL(MultiplayerMenuWidget) , DENG2_OBSERVES(ServerLink, Join) , DENG2_OBSERVES(ServerLink, Leave) { + QTimer timer; + Instance(Public *i) : Base(i) - {} + { + timer.setInterval(1000); - void networkGameJoined() + link().audienceForJoin += this; + link().audienceForLeave += this; + } + + ~Instance() { + link().audienceForJoin -= this; + link().audienceForLeave -= this; + } + void networkGameJoined() + { + /*self.menu().organizer().itemWidget(POS_SERVER_ADDRESS)->as() + .setText(_E(l) + tr("Server:") + _E(.) + + " " + link().address().asText());*/ } void networkGameLeft() { } + + static ServerLink &link() + { + return ClientApp::serverLink(); + } }; MultiplayerMenuWidget::MultiplayerMenuWidget() : PopupMenuWidget("multiplayer-menu"), d(new Instance(this)) -{ +{ + connect(&d->timer, SIGNAL(timeout()), this, SLOT(updateElapsedTime())); + items() - << new ui::ActionItem(tr("Disconnect"), new CommandAction("net disconnect")); + << new ui::ActionItem(tr("Disconnect"), new CommandAction("net disconnect")) + //<< new ui::Item(ui::Item::Separator, tr("Connection:")) + << new ui::Item(ui::Item::ShownAsLabel, ""); // sv address & time +} + +void MultiplayerMenuWidget::updateElapsedTime() +{ + if(d->link().status() != ServerLink::Connected) + return; + + TimeDelta const elapsed = d->link().connectedAt().since(); + + items().at(POS_STATUS).setLabel( + _E(s)_E(l) + tr("Server:") + _E(.) " " + d->link().address().asText() + "\n" + _E(l) + tr("Connected:") + _E(.) + + String(" %1:%2:%3") + .arg(int(elapsed.asHours())) + .arg(int(elapsed.asMinutes()) % 60, 2, 10, QLatin1Char('0')) + .arg(int(elapsed) % 60, 2, 10, QLatin1Char('0'))); +} + +void MultiplayerMenuWidget::preparePanelForOpening() +{ + d->timer.start(); + updateElapsedTime(); + + PopupMenuWidget::preparePanelForOpening(); +} + +void MultiplayerMenuWidget::panelClosing() +{ + d->timer.stop(); + PopupMenuWidget::panelClosing(); } diff --git a/doomsday/libappfw/src/widgets/popupmenuwidget.cpp b/doomsday/libappfw/src/widgets/popupmenuwidget.cpp index 57591e4c3c..76824cd66c 100644 --- a/doomsday/libappfw/src/widgets/popupmenuwidget.cpp +++ b/doomsday/libappfw/src/widgets/popupmenuwidget.cpp @@ -48,6 +48,11 @@ DENG_GUI_PIMPL(PopupMenuWidget) return; } + if(LabelWidget *lab = widget.maybeAs()) + { + lab->margins().set("unit"); + } + // Customize buttons for use in the popup. We will observe the button // state for highlighting and possibly close the popup when an action // gets triggered. @@ -55,7 +60,6 @@ DENG_GUI_PIMPL(PopupMenuWidget) { b->setHoverTextColor("inverted.text"); b->setSizePolicy(ui::Expand, ui::Expand); - b->margins().set("unit"); if(!b->is()) { From 69d5db645880b5519a4cc9cf6353faaca64b753c Mon Sep 17 00:00:00 2001 From: danij Date: Fri, 31 Jan 2014 19:52:17 +0000 Subject: [PATCH 027/106] Fixed|libcommon: Implicit loading when revisited a map in the same cluster (typo) --- doomsday/plugins/common/src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doomsday/plugins/common/src/g_game.c b/doomsday/plugins/common/src/g_game.c index 15bb31a8b6..8e375af4eb 100644 --- a/doomsday/plugins/common/src/g_game.c +++ b/doomsday/plugins/common/src/g_game.c @@ -2617,7 +2617,7 @@ void G_DoLeaveMap(void) { Uri *mapUri = G_ComposeMapUri(gameEpisode, gameMap); Uri *nextMapUri = G_ComposeMapUri(gameEpisode, nextMap); - if(P_MapInfo(mapUri)->cluster != P_MapInfo(nextMapUri)->cluster) + if(P_MapInfo(mapUri)->cluster == P_MapInfo(nextMapUri)->cluster) { if(!deathmatch) { From ed2f90533ae347a708b7121738becf3ffa259537 Mon Sep 17 00:00:00 2001 From: danij Date: Fri, 31 Jan 2014 19:54:10 +0000 Subject: [PATCH 028/106] Fixed|MapInfoParser|Hexen: Incorrect assignment of logical map numbers to map URIs --- doomsday/plugins/hexen/src/p_mapinfo.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/doomsday/plugins/hexen/src/p_mapinfo.cpp b/doomsday/plugins/hexen/src/p_mapinfo.cpp index 405d85e047..0e3e9a2e2d 100644 --- a/doomsday/plugins/hexen/src/p_mapinfo.cpp +++ b/doomsday/plugins/hexen/src/p_mapinfo.cpp @@ -76,8 +76,6 @@ void MapInfoParser(Str const *path) strcpy(defMapInfo.title, "DEVELOPMENT MAP"); // Unknown. strcpy(defMapInfo.songLump, "DEFSONG"); // Unknown. - uint logicalMapIndex = 0; - HexLex lexer(script, path); while(lexer.readToken()) @@ -132,9 +130,9 @@ void MapInfoParser(Str const *path) memcpy(info, &defMapInfo, sizeof(*info)); // Assign a logical map index. - info->map = logicalMapIndex++; + info->map = tmap - 1; - // The warp translation defaults to the map number. + // The warp translation defaults to the logical map index. info->warpTrans = tmap - 1; } Uri_Delete(mapUri); @@ -239,8 +237,8 @@ void MapInfoParser(Str const *path) for(MapInfos::const_iterator i = mapInfos.begin(); i != mapInfos.end(); ++i) { mapinfo_t const &info = i->second; - App_Log(DE2_DEV_RES_MSG, "MAPINFO %s { title: \"%s\" map: %i warp: %i }", - i->first.c_str(), info.title, info.map, info.warpTrans); + App_Log(DE2_DEV_RES_MSG, "MAPINFO %s { title: \"%s\" cluster: %i map: %i warp: %i }", + i->first.c_str(), info.title, info.cluster, info.map, info.warpTrans); } #endif } From 0b11cb31a168a08347b713e8fd22709c79385cae Mon Sep 17 00:00:00 2001 From: danij Date: Fri, 31 Jan 2014 20:02:28 +0000 Subject: [PATCH 029/106] Fixed|libcommon|Hexen DK: Crash during hexen-dk game init (invalid nextMap) Until a game has begun (and a map has been loaded) there is no valid value for the current or next map. In previous versions the default zero-value would resolve to the "default mapinfo" definition. These days there is no default mapinfo in Hexen, leading to the crash. For now we'll simply allow the invalid values to resolve to a zero length URI, meaning no mapinfo will be returned. So, test for this when initializing a finale animation's state condition flags. --- doomsday/plugins/common/src/fi_lib.c | 42 +++++++++++++++------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/doomsday/plugins/common/src/fi_lib.c b/doomsday/plugins/common/src/fi_lib.c index 66dbfcefa2..494a59f0da 100644 --- a/doomsday/plugins/common/src/fi_lib.c +++ b/doomsday/plugins/common/src/fi_lib.c @@ -85,45 +85,49 @@ void FI_StackRegister(void) static void initStateConditions(fi_state_t *s) { + // Set the presets. + s->conditions.secret = false; +#if !__JHEXEN__ + s->conditions.leave_hub = false; +#endif + // Only the server is able to figure out the truth values of all the conditions. - if(IS_CLIENT) - { - // Set the presets. - s->conditions.secret = false; - s->conditions.leave_hub = false; - return; - } + if(IS_CLIENT) return; #if __JHEXEN__ s->conditions.secret = false; +#else + s->conditions.secret = secretExit; +#endif - // Current hub has been completed? +#if __JHEXEN__ + // Leaving the current cluster? { - Uri *currentMapUri = G_ComposeMapUri(gameEpisode, gameMap); - Uri *nextMapUri = G_ComposeMapUri(gameEpisode, nextMap); + Uri *curMapUri = G_ComposeMapUri(gameEpisode, gameMap); + Uri *nextMapUri = G_ComposeMapUri(gameEpisode, nextMap); - s->conditions.leave_hub = (P_MapInfo(currentMapUri)->cluster != P_MapInfo(nextMapUri)->cluster); + mapinfo_t *curMapInfo = P_MapInfo(curMapUri); + mapinfo_t *nextMapInfo = P_MapInfo(nextMapUri); + if(curMapInfo && nextMapInfo) + { + s->conditions.leave_hub = (curMapInfo->cluster != nextMapInfo->cluster); + } Uri_Delete(nextMapUri); - Uri_Delete(currentMapUri); + Uri_Delete(curMapUri); } - App_Log(DE2_DEV_SCR_VERBOSE, "Infine state condition: leave_hub=%i", s->conditions.leave_hub); -#else - s->conditions.secret = secretExit; - // Only Hexen has hubs. - s->conditions.leave_hub = false; #endif } -static fi_state_t* stateForFinaleId(finaleid_t id) +static fi_state_t *stateForFinaleId(finaleid_t id) { if(finaleStackInited) { uint i; for(i = 0; i < finaleStackSize; ++i) { - fi_state_t* s = &finaleStack[i]; + fi_state_t *s = &finaleStack[i]; if(s->finaleId == id) return s; } From 672bbe0ec311233f25794bb14feef285321d5740 Mon Sep 17 00:00:00 2001 From: danij Date: Fri, 31 Jan 2014 20:04:02 +0000 Subject: [PATCH 030/106] Refactor|libcommon: Continued updating save state (de)serialization using Reader/Writer --- doomsday/plugins/common/include/p_xgline.h | 64 +- doomsday/plugins/common/include/p_xgsec.h | 4 +- doomsday/plugins/common/src/p_floor.cpp | 2 +- doomsday/plugins/common/src/p_saveg.cpp | 843 ++++++++++----------- doomsday/plugins/common/src/p_xgsave.cpp | 143 ++-- doomsday/plugins/doom/include/p_mobj.h | 6 + doomsday/plugins/doom64/include/p_mobj.h | 6 + doomsday/plugins/heretic/include/p_mobj.h | 6 + doomsday/plugins/hexen/include/acscript.h | 8 +- doomsday/plugins/hexen/include/p_mobj.h | 6 + doomsday/plugins/hexen/src/acscript.cpp | 18 +- 11 files changed, 562 insertions(+), 544 deletions(-) diff --git a/doomsday/plugins/common/include/p_xgline.h b/doomsday/plugins/common/include/p_xgline.h index 358af288b0..f6d50e4d37 100644 --- a/doomsday/plugins/common/include/p_xgline.h +++ b/doomsday/plugins/common/include/p_xgline.h @@ -30,6 +30,7 @@ #ifndef __XG_LINETYPE_H__ #define __XG_LINETYPE_H__ +#include "doomsday.h" #include "xgclass.h" // Line events. @@ -335,45 +336,40 @@ extern "C" { #endif // Register the XG classnames for XGdev -void XG_Register(void); +void XG_Register(void); // Initialize extended lines for the map. -void XL_Init(void); +void XL_Init(void); // Called when reseting engine state. -void XL_Update(void); - -void XL_Thinker(void *xlThinkerPtr); - -void XL_SetLineType(Line* line, int id); - -linetype_t* XL_GetType(int id); -int XL_LineEvent(int evType, int lineType, Line* line, - int sideNum, void* data); -void XL_ActivateLine(dd_bool activating, linetype_t* info, - Line* line, int sideNum, - struct mobj_s* data, int evType); -int XL_TraverseLines(Line* line, int reftype, int ref, - void* context, void* context2, struct mobj_s* activator, - int (C_DECL *func)()); -int XL_TraversePlanes(Line* line, int reftype, int ref, - void* context, void* context2, dd_bool travSectors, - struct mobj_s* activator, - int (C_DECL *func)()); +void XL_Update(void); + +void XL_Thinker(void *xlThinkerPtr); + +void XL_SetLineType(Line* line, int id); + +linetype_t *XL_GetType(int id); + +int XL_LineEvent(int evType, int lineType, Line *line, int sideNum, void *data); + +void XL_ActivateLine(dd_bool activating, linetype_t *info, Line *line, int sideNum, + struct mobj_s *activator, int evType); + +int XL_TraverseLines(Line *line, int reftype, int ref, void *context, void *context2, + struct mobj_s *activator, int (C_DECL *func)()); + +int XL_TraversePlanes(Line *line, int reftype, int ref, void *context, void *context2, + dd_bool travSectors, struct mobj_s *activator, int (C_DECL *func)()); // Return false if the event was processed. -int XL_CrossLine(Line* line, int sideNum, - struct mobj_s* thing); -int XL_UseLine(Line* line, int sideNum, - struct mobj_s* thing); -int XL_ShootLine(Line* line, int sideNum, - struct mobj_s* thing); -int XL_HitLine(Line* line, int sideNum, - struct mobj_s* thing); - -int XG_RandomInt(int min, int max); - -void SV_WriteXGLine(Line* li); -void SV_ReadXGLine(Line* li); +int XL_CrossLine(Line *line, int sideNum, struct mobj_s *thing); +int XL_UseLine(Line *line, int sideNum, struct mobj_s *thing); +int XL_ShootLine(Line *line, int sideNum, struct mobj_s *thing); +int XL_HitLine(Line *line, int sideNum, struct mobj_s *thing); + +int XG_RandomInt(int min, int max); + +void SV_WriteXGLine(Line *li, Writer *writer); +void SV_ReadXGLine(Line *li, Reader *reader, int mapVersion); #ifdef __cplusplus } // extern "C" diff --git a/doomsday/plugins/common/include/p_xgsec.h b/doomsday/plugins/common/include/p_xgsec.h index 4d5dd1bf53..6b8deaa827 100644 --- a/doomsday/plugins/common/include/p_xgsec.h +++ b/doomsday/plugins/common/include/p_xgsec.h @@ -187,9 +187,9 @@ xgplanemover_t *XS_GetPlaneMover(Sector *sector, dd_bool ceiling); void XS_PlaneMover(xgplanemover_t *mover); // A thinker for plane movers. -void SV_WriteXGSector(Sector *sec); +void SV_WriteXGSector(Sector *sec, Writer *writer); -void SV_ReadXGSector(Sector *sec); +void SV_ReadXGSector(Sector *sec, Reader *reader, int mapVersion); D_CMD(MovePlane); diff --git a/doomsday/plugins/common/src/p_floor.cpp b/doomsday/plugins/common/src/p_floor.cpp index 0aff9dc42b..f371cf7821 100644 --- a/doomsday/plugins/common/src/p_floor.cpp +++ b/doomsday/plugins/common/src/p_floor.cpp @@ -435,7 +435,7 @@ int floor_t::read(Reader *reader, int mapVersion) if(mapVersion >= 5) #endif { // Note: the thinker class byte has already been read. - byte ver = SV_ReadByte(); // version byte. + byte ver = Reader_ReadByte(reader); // version byte. type = floortype_e(Reader_ReadByte(reader)); sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(reader)); diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index 9c6cf192ae..c1768dab32 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -18,13 +18,8 @@ * 02110-1301 USA */ -#include -#include -#include - #include "common.h" - -#include +#include "p_saveg.h" #include "g_common.h" #include "d_net.h" @@ -56,7 +51,10 @@ #if __JHEXEN__ # include "acscript.h" #endif -#include "p_saveg.h" +#include +#include +#include +#include using namespace dmu_lib; @@ -117,12 +115,12 @@ typedef enum { static bool recogniseGameState(Str const *path, SaveInfo *info); -static void SV_WriteMobj(mobj_t const *mobj); -static int SV_ReadMobj(thinker_t *th, int mapVersion); +static void SV_WriteMobj(thinker_t *th, Writer *writer); +static int SV_ReadMobj(thinker_t *th, Reader *reader, int mapVersion); #if __JHEXEN__ static void SV_WriteMovePoly(polyevent_t const *movepoly); -static int SV_ReadMovePoly(polyevent_t *movepoly, int mapVersion); +static int SV_ReadMovePoly(polyevent_t *movepoly, Reader *reader, int mapVersion); #endif #if __JHEXEN__ @@ -1107,7 +1105,7 @@ static inline int materialArchiveVersion() /** * Writes the given player's data (not including the ID number). */ -static void SV_WritePlayer(int playernum) +static void SV_WritePlayer(int playernum, Writer *writer) { int i, numPSprites = getPlayerHeader()->numPSprites; player_t temp, *p = &temp; @@ -1288,214 +1286,214 @@ static void SV_WritePlayer(int playernum) /** * Reads a player's data (not including the ID number). */ -static void SV_ReadPlayer(player_t *p) +static void SV_ReadPlayer(player_t *p, Reader *reader) { int plrnum = p - players; int numPSprites = getPlayerHeader()->numPSprites; ddplayer_t *dp = p->plr; - byte ver = SV_ReadByte(); + byte ver = Reader_ReadByte(reader); #if __JHEXEN__ - cfg.playerClass[plrnum] = playerclass_t(SV_ReadByte()); + cfg.playerClass[plrnum] = playerclass_t(Reader_ReadByte(reader)); memset(p, 0, sizeof(*p)); // Force everything NULL, p->plr = dp; // but restore the ddplayer pointer. #endif - p->playerState = playerstate_t(SV_ReadLong()); + p->playerState = playerstate_t(Reader_ReadInt32(reader)); #if __JHEXEN__ - p->class_ = playerclass_t(SV_ReadLong()); // 2nd class?? (ask Raven...) + p->class_ = playerclass_t(Reader_ReadInt32(reader)); // 2nd class?? (ask Raven...) #endif - p->viewZ = FIX2FLT(SV_ReadLong()); - p->viewHeight = FIX2FLT(SV_ReadLong()); - p->viewHeightDelta = FIX2FLT(SV_ReadLong()); + p->viewZ = FIX2FLT(Reader_ReadInt32(reader)); + p->viewHeight = FIX2FLT(Reader_ReadInt32(reader)); + p->viewHeightDelta = FIX2FLT(Reader_ReadInt32(reader)); #if !__JHEXEN__ - dp->lookDir = SV_ReadFloat(); + dp->lookDir = Reader_ReadFloat(reader); #endif - p->bob = FIX2FLT(SV_ReadLong()); + p->bob = FIX2FLT(Reader_ReadInt32(reader)); #if __JHEXEN__ - p->flyHeight = SV_ReadLong(); - dp->lookDir = SV_ReadFloat(); - p->centering = SV_ReadLong(); + p->flyHeight = Reader_ReadInt32(reader); + dp->lookDir = Reader_ReadFloat(reader); + p->centering = Reader_ReadInt32(reader); #endif - p->health = SV_ReadLong(); + p->health = Reader_ReadInt32(reader); #if __JHEXEN__ for(int i = 0; i < getPlayerHeader()->numArmorTypes; ++i) { - p->armorPoints[i] = SV_ReadLong(); + p->armorPoints[i] = Reader_ReadInt32(reader); } #else - p->armorPoints = SV_ReadLong(); - p->armorType = SV_ReadLong(); + p->armorPoints = Reader_ReadInt32(reader); + p->armorType = Reader_ReadInt32(reader); #endif #if __JDOOM64__ || __JHEXEN__ P_InventoryEmpty(plrnum); for(int i = 0; i < getPlayerHeader()->numInvItemTypes; ++i) { - inventoryitemtype_t type = inventoryitemtype_t(SV_ReadLong()); - int count = SV_ReadLong(); + inventoryitemtype_t type = inventoryitemtype_t(Reader_ReadInt32(reader)); + int count = Reader_ReadInt32(reader); for(int j = 0; j < count; ++j) P_InventoryGive(plrnum, type, true); } - P_InventorySetReadyItem(plrnum, inventoryitemtype_t(SV_ReadLong())); + P_InventorySetReadyItem(plrnum, inventoryitemtype_t(Reader_ReadInt32(reader))); # if __JHEXEN__ Hu_InventorySelect(plrnum, P_InventoryReadyItem(plrnum)); if(ver < 5) { - SV_ReadLong(); // Current inventory item count? + Reader_ReadInt32(reader); // Current inventory item count? } if(ver < 6) - /*p->inventorySlotNum =*/ SV_ReadLong(); + /*p->inventorySlotNum =*/ Reader_ReadInt32(reader); # endif #endif for(int i = 0; i < getPlayerHeader()->numPowers; ++i) { - p->powers[i] = SV_ReadLong(); + p->powers[i] = Reader_ReadInt32(reader); } if(p->powers[PT_ALLMAP]) ST_RevealAutomap(plrnum, true); #if __JHEXEN__ - p->keys = SV_ReadLong(); + p->keys = Reader_ReadInt32(reader); #else for(int i = 0; i < getPlayerHeader()->numKeys; ++i) { - p->keys[i] = SV_ReadLong(); + p->keys[i] = Reader_ReadInt32(reader); } #endif #if __JHEXEN__ - p->pieces = SV_ReadLong(); + p->pieces = Reader_ReadInt32(reader); #else - p->backpack = SV_ReadLong(); + p->backpack = Reader_ReadInt32(reader); #endif for(int i = 0; i < getPlayerHeader()->numFrags; ++i) { - p->frags[i] = SV_ReadLong(); + p->frags[i] = Reader_ReadInt32(reader); } - p->readyWeapon = weapontype_t(SV_ReadLong()); + p->readyWeapon = weapontype_t(Reader_ReadInt32(reader)); #if __JHEXEN__ if(ver < 5) p->pendingWeapon = WT_NOCHANGE; else #endif - p->pendingWeapon = weapontype_t(SV_ReadLong()); + p->pendingWeapon = weapontype_t(Reader_ReadInt32(reader)); for(int i = 0; i < getPlayerHeader()->numWeapons; ++i) { - p->weapons[i].owned = (SV_ReadLong()? true : false); + p->weapons[i].owned = (Reader_ReadInt32(reader)? true : false); } for(int i = 0; i < getPlayerHeader()->numAmmoTypes; ++i) { - p->ammo[i].owned = SV_ReadLong(); + p->ammo[i].owned = Reader_ReadInt32(reader); #if !__JHEXEN__ - p->ammo[i].max = SV_ReadLong(); + p->ammo[i].max = Reader_ReadInt32(reader); #endif } - p->attackDown = SV_ReadLong(); - p->useDown = SV_ReadLong(); - p->cheats = SV_ReadLong(); - p->refire = SV_ReadLong(); - p->killCount = SV_ReadLong(); - p->itemCount = SV_ReadLong(); - p->secretCount = SV_ReadLong(); + p->attackDown = Reader_ReadInt32(reader); + p->useDown = Reader_ReadInt32(reader); + p->cheats = Reader_ReadInt32(reader); + p->refire = Reader_ReadInt32(reader); + p->killCount = Reader_ReadInt32(reader); + p->itemCount = Reader_ReadInt32(reader); + p->secretCount = Reader_ReadInt32(reader); #if __JHEXEN__ if(ver <= 1) { - /*p->messageTics =*/ SV_ReadLong(); - /*p->ultimateMessage =*/ SV_ReadLong(); - /*p->yellowMessage =*/ SV_ReadLong(); + /*p->messageTics =*/ Reader_ReadInt32(reader); + /*p->ultimateMessage =*/ Reader_ReadInt32(reader); + /*p->yellowMessage =*/ Reader_ReadInt32(reader); } #endif - p->damageCount = SV_ReadLong(); - p->bonusCount = SV_ReadLong(); + p->damageCount = Reader_ReadInt32(reader); + p->bonusCount = Reader_ReadInt32(reader); #if __JHEXEN__ - p->poisonCount = SV_ReadLong(); + p->poisonCount = Reader_ReadInt32(reader); #endif - dp->extraLight = SV_ReadLong(); - dp->fixedColorMap = SV_ReadLong(); - p->colorMap = SV_ReadLong(); + dp->extraLight = Reader_ReadInt32(reader); + dp->fixedColorMap = Reader_ReadInt32(reader); + p->colorMap = Reader_ReadInt32(reader); for(int i = 0; i < numPSprites; ++i) { pspdef_t *psp = &p->pSprites[i]; - psp->state = (state_t *) SV_ReadLong(); - psp->tics = SV_ReadLong(); - psp->pos[VX] = FIX2FLT(SV_ReadLong()); - psp->pos[VY] = FIX2FLT(SV_ReadLong()); + psp->state = (state_t *) Reader_ReadInt32(reader); + psp->tics = Reader_ReadInt32(reader); + psp->pos[VX] = FIX2FLT(Reader_ReadInt32(reader)); + psp->pos[VY] = FIX2FLT(Reader_ReadInt32(reader)); } #if !__JHEXEN__ - p->didSecret = SV_ReadLong(); + p->didSecret = Reader_ReadInt32(reader); # if __JDOOM__ || __JDOOM64__ if(ver == 2) // nolonger used in >= ver 3 - /*p->messageTics =*/ SV_ReadLong(); + /*p->messageTics =*/ Reader_ReadInt32(reader); if(ver >= 2) - p->flyHeight = SV_ReadLong(); + p->flyHeight = Reader_ReadInt32(reader); # elif __JHERETIC__ if(ver < 3) // nolonger used in >= ver 3 - /*p->messageTics =*/ SV_ReadLong(); + /*p->messageTics =*/ Reader_ReadInt32(reader); - p->flyHeight = SV_ReadLong(); + p->flyHeight = Reader_ReadInt32(reader); P_InventoryEmpty(plrnum); for(int i = 0; i < getPlayerHeader()->numInvItemTypes; ++i) { - inventoryitemtype_t type = inventoryitemtype_t(SV_ReadLong()); - int count = SV_ReadLong(); + inventoryitemtype_t type = inventoryitemtype_t(Reader_ReadInt32(reader)); + int count = Reader_ReadInt32(reader); for(int j = 0; j < count; ++j) P_InventoryGive(plrnum, type, true); } - P_InventorySetReadyItem(plrnum, (inventoryitemtype_t) SV_ReadLong()); + P_InventorySetReadyItem(plrnum, (inventoryitemtype_t) Reader_ReadInt32(reader)); Hu_InventorySelect(plrnum, P_InventoryReadyItem(plrnum)); if(ver < 5) { - SV_ReadLong(); // Current inventory item count? + Reader_ReadInt32(reader); // Current inventory item count? } if(ver < 6) - /*p->inventorySlotNum =*/ SV_ReadLong(); + /*p->inventorySlotNum =*/ Reader_ReadInt32(reader); - p->chickenPeck = SV_ReadLong(); + p->chickenPeck = Reader_ReadInt32(reader); # endif #endif #if __JHERETIC__ || __JHEXEN__ - p->morphTics = SV_ReadLong(); + p->morphTics = Reader_ReadInt32(reader); #endif if(ver >= 2) - p->airCounter = SV_ReadLong(); + p->airCounter = Reader_ReadInt32(reader); #if __JHEXEN__ - p->jumpTics = SV_ReadLong(); - p->worldTimer = SV_ReadLong(); + p->jumpTics = Reader_ReadInt32(reader); + p->worldTimer = Reader_ReadInt32(reader); #elif __JHERETIC__ - p->flameCount = SV_ReadLong(); + p->flameCount = Reader_ReadInt32(reader); if(ver >= 2) - p->class_ = playerclass_t(SV_ReadByte()); + p->class_ = playerclass_t(Reader_ReadByte(reader)); #endif #if !__JHEXEN__ @@ -1524,8 +1522,9 @@ static void SV_ReadPlayer(player_t *p) # define MOBJ_SAVEVERSION 10 #endif -static void SV_WriteMobj(mobj_t const *original) +static void SV_WriteMobj(thinker_t *th, Writer *writer) { + mobj_t const *original = (mobj_t*) th; mobj_t temp, *mo = &temp; std::memcpy(mo, original, sizeof(*mo)); @@ -1565,66 +1564,66 @@ static void SV_WriteMobj(mobj_t const *original) // JHEXEN // 7: Removed superfluous info ptr // 8: Added 'onMobj' - SV_WriteByte(MOBJ_SAVEVERSION); + Writer_WriteByte(writer, MOBJ_SAVEVERSION); #if !__JHEXEN__ // A version 2 features: archive number and target. - SV_WriteShort(SV_ThingArchiveId((mobj_t*) original)); - SV_WriteShort(SV_ThingArchiveId(mo->target)); + Writer_WriteInt16(writer, SV_ThingArchiveId((mobj_t*) original)); + Writer_WriteInt16(writer, SV_ThingArchiveId(mo->target)); # if __JDOOM__ || __JDOOM64__ // Ver 5 features: Save tracer (fixes Archvile, Revenant bug) - SV_WriteShort(SV_ThingArchiveId(mo->tracer)); + Writer_WriteInt16(writer, SV_ThingArchiveId(mo->tracer)); # endif #endif - SV_WriteShort(SV_ThingArchiveId(mo->onMobj)); + Writer_WriteInt16(writer, SV_ThingArchiveId(mo->onMobj)); // Info for drawing: position. - SV_WriteLong(FLT2FIX(mo->origin[VX])); - SV_WriteLong(FLT2FIX(mo->origin[VY])); - SV_WriteLong(FLT2FIX(mo->origin[VZ])); + Writer_WriteInt32(writer, FLT2FIX(mo->origin[VX])); + Writer_WriteInt32(writer, FLT2FIX(mo->origin[VY])); + Writer_WriteInt32(writer, FLT2FIX(mo->origin[VZ])); //More drawing info: to determine current sprite. - SV_WriteLong(mo->angle); // Orientation. - SV_WriteLong(mo->sprite); // Used to find patch_t and flip value. - SV_WriteLong(mo->frame); + Writer_WriteInt32(writer, mo->angle); // Orientation. + Writer_WriteInt32(writer, mo->sprite); // Used to find patch_t and flip value. + Writer_WriteInt32(writer, mo->frame); #if !__JHEXEN__ // The closest interval over all contacted Sectors. - SV_WriteLong(FLT2FIX(mo->floorZ)); - SV_WriteLong(FLT2FIX(mo->ceilingZ)); + Writer_WriteInt32(writer, FLT2FIX(mo->floorZ)); + Writer_WriteInt32(writer, FLT2FIX(mo->ceilingZ)); #endif // For movement checking. - SV_WriteLong(FLT2FIX(mo->radius)); - SV_WriteLong(FLT2FIX(mo->height)); + Writer_WriteInt32(writer, FLT2FIX(mo->radius)); + Writer_WriteInt32(writer, FLT2FIX(mo->height)); // Momentums, used to update position. - SV_WriteLong(FLT2FIX(mo->mom[MX])); - SV_WriteLong(FLT2FIX(mo->mom[MY])); - SV_WriteLong(FLT2FIX(mo->mom[MZ])); + Writer_WriteInt32(writer, FLT2FIX(mo->mom[MX])); + Writer_WriteInt32(writer, FLT2FIX(mo->mom[MY])); + Writer_WriteInt32(writer, FLT2FIX(mo->mom[MZ])); // If == VALIDCOUNT, already checked. - SV_WriteLong(mo->valid); + Writer_WriteInt32(writer, mo->valid); - SV_WriteLong(mo->type); - SV_WriteLong(mo->tics); // State tic counter. - SV_WriteLong(PTR2INT(mo->state)); + Writer_WriteInt32(writer, mo->type); + Writer_WriteInt32(writer, mo->tics); // State tic counter. + Writer_WriteInt32(writer, PTR2INT(mo->state)); #if __JHEXEN__ - SV_WriteLong(mo->damage); + Writer_WriteInt32(writer, mo->damage); #endif - SV_WriteLong(mo->flags); + Writer_WriteInt32(writer, mo->flags); #if __JHEXEN__ - SV_WriteLong(mo->flags2); - SV_WriteLong(mo->flags3); + Writer_WriteInt32(writer, mo->flags2); + Writer_WriteInt32(writer, mo->flags3); if(mo->type == MT_KORAX) - SV_WriteLong(0); // Searching index. + Writer_WriteInt32(writer, 0); // Searching index. else - SV_WriteLong(mo->special1); + Writer_WriteInt32(writer, mo->special1); switch(mo->type) { @@ -1633,76 +1632,76 @@ static void SV_WriteMobj(mobj_t const *original) case MT_HOLY_TAIL: case MT_LIGHTNING_CEILING: if(mo->flags & MF_CORPSE) - SV_WriteLong(0); + Writer_WriteInt32(writer, 0); else - SV_WriteLong(SV_ThingArchiveId(INT2PTR(mobj_t, mo->special2))); + Writer_WriteInt32(writer, SV_ThingArchiveId(INT2PTR(mobj_t, mo->special2))); break; default: - SV_WriteLong(mo->special2); + Writer_WriteInt32(writer, mo->special2); break; } #endif - SV_WriteLong(mo->health); + Writer_WriteInt32(writer, mo->health); // Movement direction, movement generation (zig-zagging). - SV_WriteLong(mo->moveDir); // 0-7 - SV_WriteLong(mo->moveCount); // When 0, select a new dir. + Writer_WriteInt32(writer, mo->moveDir); // 0-7 + Writer_WriteInt32(writer, mo->moveCount); // When 0, select a new dir. #if __JHEXEN__ if(mo->flags & MF_CORPSE) - SV_WriteLong(0); + Writer_WriteInt32(writer, 0); else - SV_WriteLong((int) SV_ThingArchiveId(mo->target)); + Writer_WriteInt32(writer, (int) SV_ThingArchiveId(mo->target)); #endif // Reaction time: if non 0, don't attack yet. // Used by player to freeze a bit after teleporting. - SV_WriteLong(mo->reactionTime); + Writer_WriteInt32(writer, mo->reactionTime); // If >0, the target will be chased no matter what (even if shot). - SV_WriteLong(mo->threshold); + Writer_WriteInt32(writer, mo->threshold); // Additional info record for player avatars only (only valid if type // == MT_PLAYER). - SV_WriteLong(PTR2INT(mo->player)); + Writer_WriteInt32(writer, PTR2INT(mo->player)); // Player number last looked for. - SV_WriteLong(mo->lastLook); + Writer_WriteInt32(writer, mo->lastLook); #if !__JHEXEN__ // For nightmare/multiplayer respawn. - SV_WriteLong(FLT2FIX(mo->spawnSpot.origin[VX])); - SV_WriteLong(FLT2FIX(mo->spawnSpot.origin[VY])); - SV_WriteLong(FLT2FIX(mo->spawnSpot.origin[VZ])); - SV_WriteLong(mo->spawnSpot.angle); - SV_WriteLong(mo->spawnSpot.flags); - - SV_WriteLong(mo->intFlags); // $dropoff_fix: internal flags. - SV_WriteLong(FLT2FIX(mo->dropOffZ)); // $dropoff_fix - SV_WriteLong(mo->gear); // Used in torque simulation. - - SV_WriteLong(mo->damage); - SV_WriteLong(mo->flags2); - SV_WriteLong(mo->flags3); + Writer_WriteInt32(writer, FLT2FIX(mo->spawnSpot.origin[VX])); + Writer_WriteInt32(writer, FLT2FIX(mo->spawnSpot.origin[VY])); + Writer_WriteInt32(writer, FLT2FIX(mo->spawnSpot.origin[VZ])); + Writer_WriteInt32(writer, mo->spawnSpot.angle); + Writer_WriteInt32(writer, mo->spawnSpot.flags); + + Writer_WriteInt32(writer, mo->intFlags); // $dropoff_fix: internal flags. + Writer_WriteInt32(writer, FLT2FIX(mo->dropOffZ)); // $dropoff_fix + Writer_WriteInt32(writer, mo->gear); // Used in torque simulation. + + Writer_WriteInt32(writer, mo->damage); + Writer_WriteInt32(writer, mo->flags2); + Writer_WriteInt32(writer, mo->flags3); # ifdef __JHERETIC__ - SV_WriteLong(mo->special1); - SV_WriteLong(mo->special2); - SV_WriteLong(mo->special3); + Writer_WriteInt32(writer, mo->special1); + Writer_WriteInt32(writer, mo->special2); + Writer_WriteInt32(writer, mo->special3); # endif - SV_WriteByte(mo->translucency); - SV_WriteByte((byte)(mo->visTarget +1)); + Writer_WriteByte(writer, mo->translucency); + Writer_WriteByte(writer, (byte)(mo->visTarget +1)); #endif - SV_WriteLong(FLT2FIX(mo->floorClip)); + Writer_WriteInt32(writer, FLT2FIX(mo->floorClip)); #if __JHEXEN__ - SV_WriteLong(SV_ThingArchiveId((mobj_t*) original)); - SV_WriteLong(mo->tid); - SV_WriteLong(mo->special); - SV_Write(mo->args, sizeof(mo->args)); - SV_WriteByte(mo->translucency); - SV_WriteByte((byte)(mo->visTarget +1)); + Writer_WriteInt32(writer, SV_ThingArchiveId((mobj_t*) original)); + Writer_WriteInt32(writer, mo->tid); + Writer_WriteInt32(writer, mo->special); + Writer_Write(writer, mo->args, sizeof(mo->args)); + Writer_WriteByte(writer, mo->translucency); + Writer_WriteByte(writer, (byte)(mo->visTarget +1)); switch(mo->type) { @@ -1717,21 +1716,21 @@ static void SV_WriteMobj(mobj_t const *original) case MT_HOLY_TAIL: case MT_LIGHTNING_CEILING: if(mo->flags & MF_CORPSE) - SV_WriteLong(0); + Writer_WriteInt32(writer, 0); else - SV_WriteLong(SV_ThingArchiveId(mo->tracer)); + Writer_WriteInt32(writer, SV_ThingArchiveId(mo->tracer)); break; default: DENG_ASSERT(mo->tracer == NULL); /// @todo Tracer won't be saved correctly? - SV_WriteLong(PTR2INT(mo->tracer)); + Writer_WriteInt32(writer, PTR2INT(mo->tracer)); break; } - SV_WriteLong(PTR2INT(mo->lastEnemy)); + Writer_WriteInt32(writer, PTR2INT(mo->lastEnemy)); #elif __JHERETIC__ // Ver 7 features: generator - SV_WriteShort(SV_ThingArchiveId(mo->generator)); + Writer_WriteInt16(writer, SV_ThingArchiveId(mo->generator)); #endif } @@ -1862,82 +1861,83 @@ static void RestoreMobj(mobj_t *mo, int ver) * Always returns @c false as a thinker will have already been allocated in * the mobj creation process. */ -static int SV_ReadMobj(thinker_t* th, int /*mapVersion*/) +static int SV_ReadMobj(thinker_t *th, Reader *reader, int /*mapVersion*/) { - int ver; - mobj_t* mo = (mobj_t*) th; - - ver = SV_ReadByte(); + mobj_t *mo = (mobj_t *) th; + int ver = Reader_ReadByte(reader); #if !__JHEXEN__ if(ver >= 2) // Version 2 has mobj archive numbers. - insertThingInArchive(mo, SV_ReadShort()); + { + insertThingInArchive(mo, Reader_ReadInt16(reader)); + } #endif #if !__JHEXEN__ - mo->target = NULL; + mo->target = 0; if(ver >= 2) { - mo->target = INT2PTR(mobj_t, SV_ReadShort()); + mo->target = INT2PTR(mobj_t, Reader_ReadInt16(reader)); } #endif #if __JDOOM__ || __JDOOM64__ // Tracer for enemy attacks (updated after all mobjs are loaded). - mo->tracer = NULL; + mo->tracer = 0; if(ver >= 5) { - mo->tracer = INT2PTR(mobj_t, SV_ReadShort()); + mo->tracer = INT2PTR(mobj_t, Reader_ReadInt16(reader)); } #endif // mobj this one is on top of (updated after all mobjs are loaded). - mo->onMobj = NULL; + mo->onMobj = 0; #if __JHEXEN__ if(ver >= 8) #else if(ver >= 5) #endif { - mo->onMobj = INT2PTR(mobj_t, SV_ReadShort()); + mo->onMobj = INT2PTR(mobj_t, Reader_ReadInt16(reader)); } // Info for drawing: position. - mo->origin[VX] = FIX2FLT(SV_ReadLong()); - mo->origin[VY] = FIX2FLT(SV_ReadLong()); - mo->origin[VZ] = FIX2FLT(SV_ReadLong()); + mo->origin[VX] = FIX2FLT(Reader_ReadInt32(reader)); + mo->origin[VY] = FIX2FLT(Reader_ReadInt32(reader)); + mo->origin[VZ] = FIX2FLT(Reader_ReadInt32(reader)); //More drawing info: to determine current sprite. - mo->angle = SV_ReadLong(); // orientation - mo->sprite = SV_ReadLong(); // used to find patch_t and flip value - mo->frame = SV_ReadLong(); // might be ORed with FF_FULLBRIGHT + mo->angle = Reader_ReadInt32(reader); // orientation + mo->sprite = Reader_ReadInt32(reader); // used to find patch_t and flip value + + mo->frame = Reader_ReadInt32(reader); // might be ORed with FF_FULLBRIGHT if(mo->frame & FF_FULLBRIGHT) mo->frame &= FF_FRAMEMASK; // not used anymore. #if __JHEXEN__ if(ver < 6) - SV_ReadLong(); // Used to be floorflat. + Reader_ReadInt32(reader); // Used to be floorflat. #else // The closest interval over all contacted Sectors. - mo->floorZ = FIX2FLT(SV_ReadLong()); - mo->ceilingZ = FIX2FLT(SV_ReadLong()); + mo->floorZ = FIX2FLT(Reader_ReadInt32(reader)); + mo->ceilingZ = FIX2FLT(Reader_ReadInt32(reader)); #endif // For movement checking. - mo->radius = FIX2FLT(SV_ReadLong()); - mo->height = FIX2FLT(SV_ReadLong()); + mo->radius = FIX2FLT(Reader_ReadInt32(reader)); + mo->height = FIX2FLT(Reader_ReadInt32(reader)); // Momentums, used to update position. - mo->mom[MX] = FIX2FLT(SV_ReadLong()); - mo->mom[MY] = FIX2FLT(SV_ReadLong()); - mo->mom[MZ] = FIX2FLT(SV_ReadLong()); + mo->mom[MX] = FIX2FLT(Reader_ReadInt32(reader)); + mo->mom[MY] = FIX2FLT(Reader_ReadInt32(reader)); + mo->mom[MZ] = FIX2FLT(Reader_ReadInt32(reader)); // If == VALIDCOUNT, already checked. - mo->valid = SV_ReadLong(); - mo->type = SV_ReadLong(); + mo->valid = Reader_ReadInt32(reader); + mo->type = Reader_ReadInt32(reader); #if __JHEXEN__ if(ver < 7) - /*mo->info = (mobjinfo_t *)*/ SV_ReadLong(); + /*mo->info = (mobjinfo_t *)*/ Reader_ReadInt32(reader); #endif mo->info = &MOBJINFO[mo->type]; @@ -1949,24 +1949,24 @@ static int SV_ReadMobj(thinker_t* th, int /*mapVersion*/) if(mo->info->flags2 & MF2_DONTDRAW) mo->ddFlags |= DDMF_DONTDRAW; - mo->tics = SV_ReadLong(); // state tic counter - mo->state = (state_t *) SV_ReadLong(); + mo->tics = Reader_ReadInt32(reader); // state tic counter + mo->state = (state_t *) Reader_ReadInt32(reader); #if __JHEXEN__ - mo->damage = SV_ReadLong(); + mo->damage = Reader_ReadInt32(reader); #endif - mo->flags = SV_ReadLong(); + mo->flags = Reader_ReadInt32(reader); #if __JHEXEN__ - mo->flags2 = SV_ReadLong(); + mo->flags2 = Reader_ReadInt32(reader); if(ver >= 5) - mo->flags3 = SV_ReadLong(); - mo->special1 = SV_ReadLong(); - mo->special2 = SV_ReadLong(); + mo->flags3 = Reader_ReadInt32(reader); + mo->special1 = Reader_ReadInt32(reader); + mo->special2 = Reader_ReadInt32(reader); #endif - mo->health = SV_ReadLong(); + mo->health = Reader_ReadInt32(reader); #if __JHERETIC__ if(ver < 8) { @@ -1994,52 +1994,52 @@ static int SV_ReadMobj(thinker_t* th, int /*mapVersion*/) #endif // Movement direction, movement generation (zig-zagging). - mo->moveDir = SV_ReadLong(); // 0-7 - mo->moveCount = SV_ReadLong(); // when 0, select a new dir + mo->moveDir = Reader_ReadInt32(reader); // 0-7 + mo->moveCount = Reader_ReadInt32(reader); // when 0, select a new dir #if __JHEXEN__ - mo->target = (mobj_t *) SV_ReadLong(); + mo->target = (mobj_t *) Reader_ReadInt32(reader); #endif // Reaction time: if non 0, don't attack yet. // Used by player to freeze a bit after teleporting. - mo->reactionTime = SV_ReadLong(); + mo->reactionTime = Reader_ReadInt32(reader); // If >0, the target will be chased // no matter what (even if shot) - mo->threshold = SV_ReadLong(); + mo->threshold = Reader_ReadInt32(reader); // Additional info record for player avatars only. // Only valid if type == MT_PLAYER - mo->player = (player_t *) SV_ReadLong(); + mo->player = (player_t *) Reader_ReadInt32(reader); // Player number last looked for. - mo->lastLook = SV_ReadLong(); + mo->lastLook = Reader_ReadInt32(reader); #if __JHEXEN__ - mo->floorClip = FIX2FLT(SV_ReadLong()); - insertThingInArchive(mo, SV_ReadLong()); - mo->tid = SV_ReadLong(); + mo->floorClip = FIX2FLT(Reader_ReadInt32(reader)); + insertThingInArchive(mo, Reader_ReadInt32(reader)); + mo->tid = Reader_ReadInt32(reader); #else // For nightmare respawn. if(ver >= 6) { - mo->spawnSpot.origin[VX] = FIX2FLT(SV_ReadLong()); - mo->spawnSpot.origin[VY] = FIX2FLT(SV_ReadLong()); - mo->spawnSpot.origin[VZ] = FIX2FLT(SV_ReadLong()); - mo->spawnSpot.angle = SV_ReadLong(); + mo->spawnSpot.origin[VX] = FIX2FLT(Reader_ReadInt32(reader)); + mo->spawnSpot.origin[VY] = FIX2FLT(Reader_ReadInt32(reader)); + mo->spawnSpot.origin[VZ] = FIX2FLT(Reader_ReadInt32(reader)); + mo->spawnSpot.angle = Reader_ReadInt32(reader); if(ver < 10) - /* mo->spawnSpot.type = */ SV_ReadLong(); - mo->spawnSpot.flags = SV_ReadLong(); + /* mo->spawnSpot.type = */ Reader_ReadInt32(reader); + mo->spawnSpot.flags = Reader_ReadInt32(reader); } else { - mo->spawnSpot.origin[VX] = (float) SV_ReadShort(); - mo->spawnSpot.origin[VY] = (float) SV_ReadShort(); + mo->spawnSpot.origin[VX] = (float) Reader_ReadInt16(reader); + mo->spawnSpot.origin[VY] = (float) Reader_ReadInt16(reader); mo->spawnSpot.origin[VZ] = 0; // Initialize with "something". - mo->spawnSpot.angle = (angle_t) (ANG45 * (SV_ReadShort() / 45)); - /*mo->spawnSpot.type = (int)*/ SV_ReadShort(); - mo->spawnSpot.flags = (int) SV_ReadShort(); + mo->spawnSpot.angle = (angle_t) (ANG45 * (Reader_ReadInt16(reader) / 45)); + /*mo->spawnSpot.type = (int)*/ Reader_ReadInt16(reader); + mo->spawnSpot.flags = (int) Reader_ReadInt16(reader); } # if __JDOOM__ || __JDOOM64__ @@ -2048,38 +2048,38 @@ static int SV_ReadMobj(thinker_t* th, int /*mapVersion*/) if(ver >= 5) # endif { - mo->intFlags = SV_ReadLong(); // killough $dropoff_fix: internal flags - mo->dropOffZ = FIX2FLT(SV_ReadLong()); // killough $dropoff_fix - mo->gear = SV_ReadLong(); // killough used in torque simulation + mo->intFlags = Reader_ReadInt32(reader); // killough $dropoff_fix: internal flags + mo->dropOffZ = FIX2FLT(Reader_ReadInt32(reader)); // killough $dropoff_fix + mo->gear = Reader_ReadInt32(reader); // killough used in torque simulation } # if __JDOOM__ || __JDOOM64__ if(ver >= 6) { - mo->damage = SV_ReadLong(); - mo->flags2 = SV_ReadLong(); + mo->damage = Reader_ReadInt32(reader); + mo->flags2 = Reader_ReadInt32(reader); }// Else flags2 will be applied from the defs. else mo->damage = DDMAXINT; // Use the value set in mo->info->damage # elif __JHERETIC__ - mo->damage = SV_ReadLong(); - mo->flags2 = SV_ReadLong(); + mo->damage = Reader_ReadInt32(reader); + mo->flags2 = Reader_ReadInt32(reader); # endif if(ver >= 7) - mo->flags3 = SV_ReadLong(); + mo->flags3 = Reader_ReadInt32(reader); // Else flags3 will be applied from the defs. #endif #if __JHEXEN__ - mo->special = SV_ReadLong(); - SV_Read(mo->args, 1 * 5); + mo->special = Reader_ReadInt32(reader); + Reader_Read(reader, mo->args, 1 * 5); #elif __JHERETIC__ - mo->special1 = SV_ReadLong(); - mo->special2 = SV_ReadLong(); + mo->special1 = Reader_ReadInt32(reader); + mo->special2 = Reader_ReadInt32(reader); if(ver >= 8) - mo->special3 = SV_ReadLong(); + mo->special3 = Reader_ReadInt32(reader); #endif #if __JHEXEN__ @@ -2087,29 +2087,29 @@ static int SV_ReadMobj(thinker_t* th, int /*mapVersion*/) #else if(ver >= 4) #endif - mo->translucency = SV_ReadByte(); + mo->translucency = Reader_ReadByte(reader); #if __JHEXEN__ if(ver >= 3) #else if(ver >= 5) #endif - mo->visTarget = (short) (SV_ReadByte()) -1; + mo->visTarget = (short) (Reader_ReadByte(reader)) -1; #if __JHEXEN__ if(ver >= 4) - mo->tracer = (mobj_t *) SV_ReadLong(); + mo->tracer = (mobj_t *) Reader_ReadInt32(reader); if(ver >= 4) - mo->lastEnemy = (mobj_t *) SV_ReadLong(); + mo->lastEnemy = (mobj_t *) Reader_ReadInt32(reader); #else if(ver >= 5) - mo->floorClip = FIX2FLT(SV_ReadLong()); + mo->floorClip = FIX2FLT(Reader_ReadInt32(reader)); #endif #if __JHERETIC__ if(ver >= 7) - mo->generator = INT2PTR(mobj_t, SV_ReadShort()); + mo->generator = INT2PTR(mobj_t, Reader_ReadInt16(reader)); else mo->generator = NULL; #endif @@ -2123,7 +2123,7 @@ static int SV_ReadMobj(thinker_t* th, int /*mapVersion*/) /** * Prepare and write the player header info. */ -static void writePlayerHeader() +static void writePlayerHeader(Writer *writer) { playerheader_t *ph = &playerHeader; @@ -2162,7 +2162,7 @@ static void writePlayerHeader() /** * Read player header info from the game state. */ -static void readPlayerHeader() +static void readPlayerHeader(Reader *reader) { #if __JHEXEN__ if(hdr->version >= 4) @@ -2171,28 +2171,28 @@ static void readPlayerHeader() #endif { SV_AssertSegment(ASEG_PLAYER_HEADER); - int ver = SV_ReadByte(); + int ver = Reader_ReadByte(reader); #if !__JHERETIC__ DENG_UNUSED(ver); #endif - playerHeader.numPowers = SV_ReadLong(); - playerHeader.numKeys = SV_ReadLong(); - playerHeader.numFrags = SV_ReadLong(); - playerHeader.numWeapons = SV_ReadLong(); - playerHeader.numAmmoTypes = SV_ReadLong(); - playerHeader.numPSprites = SV_ReadLong(); + playerHeader.numPowers = Reader_ReadInt32(reader); + playerHeader.numKeys = Reader_ReadInt32(reader); + playerHeader.numFrags = Reader_ReadInt32(reader); + playerHeader.numWeapons = Reader_ReadInt32(reader); + playerHeader.numAmmoTypes = Reader_ReadInt32(reader); + playerHeader.numPSprites = Reader_ReadInt32(reader); #if __JHERETIC__ if(ver >= 2) - playerHeader.numInvItemTypes = SV_ReadLong(); + playerHeader.numInvItemTypes = Reader_ReadInt32(reader); else playerHeader.numInvItemTypes = NUM_INVENTORYITEM_TYPES; #endif #if __JHEXEN__ || __JDOOM64__ - playerHeader.numInvItemTypes = SV_ReadLong(); + playerHeader.numInvItemTypes = Reader_ReadInt32(reader); #endif #if __JHEXEN__ - playerHeader.numArmorTypes = SV_ReadLong(); + playerHeader.numArmorTypes = Reader_ReadInt32(reader); #endif } else // The old format didn't save the counts. @@ -2229,14 +2229,14 @@ static void readPlayerHeader() playerHeaderOK = true; } -static void writePlayers() +static void writePlayers(Writer *writer) { SV_BeginSegment(ASEG_PLAYERS); { #if __JHEXEN__ for(int i = 0; i < MAXPLAYERS; ++i) { - SV_WriteByte(players[i].plr->inGame); + Writer_WriteByte(writer, players[i].plr->inGame); } #endif @@ -2245,14 +2245,14 @@ static void writePlayers() if(!players[i].plr->inGame) continue; - SV_WriteLong(Net_GetPlayerID(i)); - SV_WritePlayer(i); + Writer_WriteInt32(writer, Net_GetPlayerID(i)); + SV_WritePlayer(i, writer); } } SV_EndSegment(); } -static void readPlayers(dd_bool *infile, dd_bool *loaded) +static void readPlayers(dd_bool *infile, dd_bool *loaded, Reader *reader) { DENG_ASSERT(infile && loaded); @@ -2274,7 +2274,7 @@ static void readPlayers(dd_bool *infile, dd_bool *loaded) #if __JHEXEN__ for(int i = 0; i < MAXPLAYERS; ++i) { - infile[i] = SV_ReadByte(); + infile[i] = Reader_ReadByte(reader); } #endif @@ -2287,7 +2287,7 @@ static void readPlayers(dd_bool *infile, dd_bool *loaded) if(!infile[i]) continue; // The ID number will determine which player this actually is. - int pid = SV_ReadLong(); + int pid = Reader_ReadInt32(reader); player_t *player = 0; for(int k = 0; k < MAXPLAYERS; ++k) { @@ -2311,13 +2311,13 @@ static void readPlayers(dd_bool *infile, dd_bool *loaded) } // Read the data. - SV_ReadPlayer(player); + SV_ReadPlayer(player, reader); } } SV_AssertSegment(ASEG_END); } -static void SV_WriteSector(Sector *sec) +static void SV_WriteSector(Sector *sec, Writer *writer) { int i, type; float flooroffx = P_GetFloatp(sec, DMU_FLOOR_MATERIAL_OFFSET_X); @@ -2398,9 +2398,9 @@ static void SV_WriteSector(Sector *sec) } #if !__JHEXEN__ - if(xsec->xg) // Extended General? + if(xsec->xg) // Extended General? { - SV_WriteXGSector(sec); + SV_WriteXGSector(sec, writer); } // Count the number of sound targets @@ -2413,13 +2413,13 @@ static void SV_WriteSector(Sector *sec) * Reads all versions of archived sectors. * Including the old Ver1. */ -static void SV_ReadSector(Sector* sec) +static void SV_ReadSector(Sector *sec, Reader *reader, int mapVersion) { int i, ver = 1; int type = 0; - Material* floorMaterial = NULL, *ceilingMaterial = NULL; + Material *floorMaterial = 0, *ceilingMaterial = 0; byte rgb[3], lightlevel; - xsector_t* xsec = P_ToXSector(sec); + xsector_t *xsec = P_ToXSector(sec); int fh, ch; // A type byte? @@ -2432,7 +2432,7 @@ static void SV_ReadSector(Sector* sec) type = sc_normal; else #endif - type = SV_ReadByte(); + type = Reader_ReadByte(reader); // A version byte? #if __JHEXEN__ @@ -2440,10 +2440,10 @@ static void SV_ReadSector(Sector* sec) #else if(hdr->version > 4) #endif - ver = SV_ReadByte(); + ver = Reader_ReadByte(reader); - fh = SV_ReadShort(); - ch = SV_ReadShort(); + fh = Reader_ReadInt16(reader); + ch = Reader_ReadInt16(reader); P_SetIntp(sec, DMU_FLOOR_HEIGHT, fh); P_SetIntp(sec, DMU_CEILING_HEIGHT, ch); @@ -2461,10 +2461,10 @@ static void SV_ReadSector(Sector* sec) { // The flat numbers are absolute lump indices. Uri* uri = Uri_NewWithPath2("Flats:", RC_NULL); - Uri_SetPath(uri, Str_Text(W_LumpName(SV_ReadShort()))); + Uri_SetPath(uri, Str_Text(W_LumpName(Reader_ReadInt16(reader)))); floorMaterial = (Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); - Uri_SetPath(uri, Str_Text(W_LumpName(SV_ReadShort()))); + Uri_SetPath(uri, Str_Text(W_LumpName(Reader_ReadInt16(reader)))); ceilingMaterial = (Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); Uri_Delete(uri); } @@ -2472,8 +2472,8 @@ static void SV_ReadSector(Sector* sec) #endif { // The flat numbers are actually archive numbers. - floorMaterial = SV_GetArchiveMaterial(SV_ReadShort(), 0); - ceilingMaterial = SV_GetArchiveMaterial(SV_ReadShort(), 0); + floorMaterial = SV_GetArchiveMaterial(Reader_ReadInt16(reader), 0); + ceilingMaterial = SV_GetArchiveMaterial(Reader_ReadInt16(reader), 0); } P_SetPtrp(sec, DMU_FLOOR_MATERIAL, floorMaterial); @@ -2481,18 +2481,18 @@ static void SV_ReadSector(Sector* sec) if(ver >= 3) { - P_SetIntp(sec, DMU_FLOOR_FLAGS, SV_ReadShort()); - P_SetIntp(sec, DMU_CEILING_FLAGS, SV_ReadShort()); + P_SetIntp(sec, DMU_FLOOR_FLAGS, Reader_ReadInt16(reader)); + P_SetIntp(sec, DMU_CEILING_FLAGS, Reader_ReadInt16(reader)); } #if __JHEXEN__ - lightlevel = (byte) SV_ReadShort(); + lightlevel = (byte) Reader_ReadInt16(reader); #else // In Ver1 the light level is a short if(hdr->version == 1) - lightlevel = (byte) SV_ReadShort(); + lightlevel = (byte) Reader_ReadInt16(reader); else - lightlevel = SV_ReadByte(); + lightlevel = Reader_ReadByte(reader); #endif P_SetFloatp(sec, DMU_LIGHT_LEVEL, (float) lightlevel / 255.f); @@ -2500,7 +2500,7 @@ static void SV_ReadSector(Sector* sec) if(hdr->version > 1) #endif { - SV_Read(rgb, 3); + Reader_Read(reader, rgb, 3); for(i = 0; i < 3; ++i) P_SetFloatp(sec, DMU_COLOR_RED + i, rgb[i] / 255.f); } @@ -2508,20 +2508,20 @@ static void SV_ReadSector(Sector* sec) // Ver 2 includes surface colours if(ver >= 2) { - SV_Read(rgb, 3); + Reader_Read(reader, rgb, 3); for(i = 0; i < 3; ++i) P_SetFloatp(sec, DMU_FLOOR_COLOR_RED + i, rgb[i] / 255.f); - SV_Read(rgb, 3); + Reader_Read(reader, rgb, 3); for(i = 0; i < 3; ++i) P_SetFloatp(sec, DMU_CEILING_COLOR_RED + i, rgb[i] / 255.f); } - xsec->special = SV_ReadShort(); - /*xsec->tag =*/ SV_ReadShort(); + xsec->special = Reader_ReadInt16(reader); + /*xsec->tag =*/ Reader_ReadInt16(reader); #if __JHEXEN__ - xsec->seqType = seqtype_t(SV_ReadShort()); + xsec->seqType = seqtype_t(Reader_ReadInt16(reader)); #endif if(type == sc_ploff @@ -2530,19 +2530,19 @@ static void SV_ReadSector(Sector* sec) #endif ) { - P_SetFloatp(sec, DMU_FLOOR_MATERIAL_OFFSET_X, SV_ReadFloat()); - P_SetFloatp(sec, DMU_FLOOR_MATERIAL_OFFSET_Y, SV_ReadFloat()); - P_SetFloatp(sec, DMU_CEILING_MATERIAL_OFFSET_X, SV_ReadFloat()); - P_SetFloatp(sec, DMU_CEILING_MATERIAL_OFFSET_Y, SV_ReadFloat()); + P_SetFloatp(sec, DMU_FLOOR_MATERIAL_OFFSET_X, Reader_ReadFloat(reader)); + P_SetFloatp(sec, DMU_FLOOR_MATERIAL_OFFSET_Y, Reader_ReadFloat(reader)); + P_SetFloatp(sec, DMU_CEILING_MATERIAL_OFFSET_X, Reader_ReadFloat(reader)); + P_SetFloatp(sec, DMU_CEILING_MATERIAL_OFFSET_Y, Reader_ReadFloat(reader)); } #if !__JHEXEN__ if(type == sc_xg1) - SV_ReadXGSector(sec); + SV_ReadXGSector(sec, reader, mapVersion); #endif #if !__JHEXEN__ - if(hdr->version <= 1) + if(mapVersion <= 1) #endif { xsec->specialData = 0; @@ -2552,7 +2552,7 @@ static void SV_ReadSector(Sector* sec) xsec->soundTarget = 0; } -static void SV_WriteLine(Line *li) +static void SV_WriteLine(Line *li, Writer *writer) { xline_t *xli = P_ToXLine(li); @@ -2633,7 +2633,7 @@ static void SV_WriteLine(Line *li) // Extended General? if(xli->xg) { - SV_WriteXGLine(li); + SV_WriteXGLine(li, writer); } #endif } @@ -2642,7 +2642,7 @@ static void SV_WriteLine(Line *li) * Reads all versions of archived lines. * Including the old Ver1. */ -static void SV_ReadLine(Line *li) +static void SV_ReadLine(Line *li, Reader *reader, int mapVersion) { Material *topMaterial = 0, *bottomMaterial = 0, *middleMaterial = 0; xline_t *xli = P_ToXLine(li); @@ -2653,11 +2653,11 @@ static void SV_ReadLine(Line *li) #if __JHEXEN__ if(mapVersion < 4) #else - if(hdr->version < 2) + if(mapVersion < 2) #endif type = lc_normal; else - type = lineclass_t(SV_ReadByte()); + type = lineclass_t(Reader_ReadByte(reader)); #ifdef __JHEXEN__ DENG_UNUSED(type); @@ -2668,16 +2668,16 @@ static void SV_ReadLine(Line *li) #if __JHEXEN__ if(mapVersion < 3) #else - if(hdr->version < 5) + if(mapVersion < 5) #endif ver = 1; else - ver = (int) SV_ReadByte(); + ver = (int) Reader_ReadByte(reader); if(ver >= 4) - P_SetIntp(li, DMU_FLAGS, SV_ReadShort()); + P_SetIntp(li, DMU_FLAGS, Reader_ReadInt16(reader)); - int flags = SV_ReadShort(); + int flags = Reader_ReadInt16(reader); if(xli->flags & ML_TWOSIDED) flags |= ML_TWOSIDED; @@ -2726,19 +2726,19 @@ static void SV_ReadLine(Line *li) if(ver >= 3) { for(int i = 0; i < MAXPLAYERS; ++i) - xli->mapped[i] = SV_ReadByte(); + xli->mapped[i] = Reader_ReadByte(reader); } #if __JHEXEN__ - xli->special = SV_ReadByte(); - xli->arg1 = SV_ReadByte(); - xli->arg2 = SV_ReadByte(); - xli->arg3 = SV_ReadByte(); - xli->arg4 = SV_ReadByte(); - xli->arg5 = SV_ReadByte(); + xli->special = Reader_ReadByte(reader); + xli->arg1 = Reader_ReadByte(reader); + xli->arg2 = Reader_ReadByte(reader); + xli->arg3 = Reader_ReadByte(reader); + xli->arg4 = Reader_ReadByte(reader); + xli->arg5 = Reader_ReadByte(reader); #else - xli->special = SV_ReadShort(); - /*xli->tag =*/ SV_ReadShort(); + xli->special = Reader_ReadInt16(reader); + /*xli->tag =*/ Reader_ReadInt16(reader); #endif // For each side @@ -2752,24 +2752,24 @@ static void SV_ReadLine(Line *li) { float offset[2]; - offset[VX] = (float) SV_ReadShort(); - offset[VY] = (float) SV_ReadShort(); + offset[VX] = (float) Reader_ReadInt16(reader); + offset[VY] = (float) Reader_ReadInt16(reader); P_SetFloatpv(si, DMU_TOP_MATERIAL_OFFSET_XY, offset); - offset[VX] = (float) SV_ReadShort(); - offset[VY] = (float) SV_ReadShort(); + offset[VX] = (float) Reader_ReadInt16(reader); + offset[VY] = (float) Reader_ReadInt16(reader); P_SetFloatpv(si, DMU_MIDDLE_MATERIAL_OFFSET_XY, offset); - offset[VX] = (float) SV_ReadShort(); - offset[VY] = (float) SV_ReadShort(); + offset[VX] = (float) Reader_ReadInt16(reader); + offset[VY] = (float) Reader_ReadInt16(reader); P_SetFloatpv(si, DMU_BOTTOM_MATERIAL_OFFSET_XY, offset); } else { float offset[2]; - offset[VX] = (float) SV_ReadShort(); - offset[VY] = (float) SV_ReadShort(); + offset[VX] = (float) Reader_ReadInt16(reader); + offset[VY] = (float) Reader_ReadInt16(reader); P_SetFloatpv(si, DMU_TOP_MATERIAL_OFFSET_XY, offset); P_SetFloatpv(si, DMU_MIDDLE_MATERIAL_OFFSET_XY, offset); @@ -2778,18 +2778,18 @@ static void SV_ReadLine(Line *li) if(ver >= 3) { - P_SetIntp(si, DMU_TOP_FLAGS, SV_ReadShort()); - P_SetIntp(si, DMU_MIDDLE_FLAGS, SV_ReadShort()); - P_SetIntp(si, DMU_BOTTOM_FLAGS, SV_ReadShort()); + P_SetIntp(si, DMU_TOP_FLAGS, Reader_ReadInt16(reader)); + P_SetIntp(si, DMU_MIDDLE_FLAGS, Reader_ReadInt16(reader)); + P_SetIntp(si, DMU_BOTTOM_FLAGS, Reader_ReadInt16(reader)); } #if !__JHEXEN__ - if(hdr->version >= 4) + if(mapVersion >= 4) #endif { - topMaterial = SV_GetArchiveMaterial(SV_ReadShort(), 1); - bottomMaterial = SV_GetArchiveMaterial(SV_ReadShort(), 1); - middleMaterial = SV_GetArchiveMaterial(SV_ReadShort(), 1); + topMaterial = SV_GetArchiveMaterial(Reader_ReadInt16(reader), 1); + bottomMaterial = SV_GetArchiveMaterial(Reader_ReadInt16(reader), 1); + middleMaterial = SV_GetArchiveMaterial(Reader_ReadInt16(reader), 1); } P_SetPtrp(si, DMU_TOP_MATERIAL, topMaterial); @@ -2803,26 +2803,26 @@ static void SV_ReadLine(Line *li) int flags; for(int k = 0; k < 3; ++k) - rgba[k] = (float) SV_ReadByte() / 255.f; + rgba[k] = (float) Reader_ReadByte(reader) / 255.f; rgba[3] = 1; P_SetFloatpv(si, DMU_TOP_COLOR, rgba); for(int k = 0; k < 3; ++k) - rgba[k] = (float) SV_ReadByte() / 255.f; + rgba[k] = (float) Reader_ReadByte(reader) / 255.f; rgba[3] = 1; P_SetFloatpv(si, DMU_BOTTOM_COLOR, rgba); for(int k = 0; k < 4; ++k) - rgba[k] = (float) SV_ReadByte() / 255.f; + rgba[k] = (float) Reader_ReadByte(reader) / 255.f; P_SetFloatpv(si, DMU_MIDDLE_COLOR, rgba); - P_SetIntp(si, DMU_MIDDLE_BLENDMODE, SV_ReadLong()); + P_SetIntp(si, DMU_MIDDLE_BLENDMODE, Reader_ReadInt32(reader)); - flags = SV_ReadShort(); + flags = Reader_ReadInt16(reader); #if __JHEXEN__ if(mapVersion < 12) #else - if(hdr->version < 12) + if(mapVersion < 12) #endif { if(P_GetIntp(si, DMU_FLAGS) & SDF_SUPPRESS_BACK_SECTOR) @@ -2834,37 +2834,37 @@ static void SV_ReadLine(Line *li) #if !__JHEXEN__ if(type == lc_xg1) - SV_ReadXGLine(li); + SV_ReadXGLine(li, reader, mapVersion); #endif } #if __JHEXEN__ -static void SV_WritePolyObj(Polyobj *po) +static void SV_WritePolyObj(Polyobj *po, Writer *writer) { DENG_ASSERT(po != 0); - SV_WriteByte(1); // write a version byte. + Writer_WriteByte(writer, 1); // write a version byte. - SV_WriteLong(po->tag); - SV_WriteLong(po->angle); - SV_WriteLong(FLT2FIX(po->origin[VX])); - SV_WriteLong(FLT2FIX(po->origin[VY])); + Writer_WriteInt32(writer, po->tag); + Writer_WriteInt32(writer, po->angle); + Writer_WriteInt32(writer, FLT2FIX(po->origin[VX])); + Writer_WriteInt32(writer, FLT2FIX(po->origin[VY])); } -static int SV_ReadPolyObj() +static int SV_ReadPolyObj(Reader *reader, int mapVersion) { - int ver = (mapVersion >= 3)? SV_ReadByte() : 0; + int ver = (mapVersion >= 3)? Reader_ReadByte(reader) : 0; DENG_UNUSED(ver); - Polyobj *po = Polyobj_ByTag(SV_ReadLong()); + Polyobj *po = Polyobj_ByTag(Reader_ReadInt32(reader)); DENG_ASSERT(po != 0); - angle_t angle = angle_t(SV_ReadLong()); + angle_t angle = angle_t(Reader_ReadInt32(reader)); Polyobj_Rotate(po, angle); po->destAngle = angle; - float const origX = FIX2FLT(SV_ReadLong()); - float const origY = FIX2FLT(SV_ReadLong()); + float const origX = FIX2FLT(Reader_ReadInt32(reader)); + float const origY = FIX2FLT(Reader_ReadInt32(reader)); Polyobj_MoveXY(po, origX - po->origin[VX], origY - po->origin[VY]); /// @todo What about speed? It isn't saved at all? @@ -2879,49 +2879,49 @@ static void writeMapElements(Writer *writer) for(int i = 0; i < numsectors; ++i) { - SV_WriteSector((Sector *)P_ToPtr(DMU_SECTOR, i)); + SV_WriteSector((Sector *)P_ToPtr(DMU_SECTOR, i), writer); } for(int i = 0; i < numlines; ++i) { - SV_WriteLine((Line *)P_ToPtr(DMU_LINE, i)); + SV_WriteLine((Line *)P_ToPtr(DMU_LINE, i), writer); } #if __JHEXEN__ SV_BeginSegment(ASEG_POLYOBJS); - SV_WriteLong(numpolyobjs); + Writer_WriteInt32(writer, numpolyobjs); for(int i = 0; i < numpolyobjs; ++i) { - SV_WritePolyObj(Polyobj_ById(i)); + SV_WritePolyObj(Polyobj_ById(i), writer); } #endif } -static void readMapElements(Reader *reader) +static void readMapElements(Reader *reader, int mapVersion) { SV_AssertSegment(ASEG_MAP_ELEMENTS); // Load sectors. for(int i = 0; i < numsectors; ++i) { - SV_ReadSector((Sector *)P_ToPtr(DMU_SECTOR, i)); + SV_ReadSector((Sector *)P_ToPtr(DMU_SECTOR, i), reader, mapVersion); } // Load lines. for(int i = 0; i < numlines; ++i) { - SV_ReadLine((Line *)P_ToPtr(DMU_LINE, i)); + SV_ReadLine((Line *)P_ToPtr(DMU_LINE, i), reader, mapVersion); } #if __JHEXEN__ // Load polyobjects. SV_AssertSegment(ASEG_POLYOBJS); - long const writtenPolyobjCount = SV_ReadLong(); + long const writtenPolyobjCount = Reader_ReadInt32(reader); DENG_ASSERT(writtenPolyobjCount == numpolyobjs); for(int i = 0; i < writtenPolyobjCount; ++i) { - SV_ReadPolyObj(); + SV_ReadPolyObj(reader, mapVersion); } #endif } @@ -2944,37 +2944,37 @@ static void SV_WriteMovePoly(polyevent_t const *th) SV_WriteLong(FLT2FIX(th->speed[VY])); } -static int SV_ReadMovePoly(polyevent_t *th, int /*mapVersion*/) +static int SV_ReadMovePoly(polyevent_t *th, Reader *reader, int mapVersion) { DENG_ASSERT(th != 0); if(mapVersion >= 4) { // Note: the thinker class byte has already been read. - /*int ver =*/ SV_ReadByte(); // version byte. + /*int ver =*/ Reader_ReadByte(reader); // version byte. // Start of used data members. - th->polyobj = SV_ReadLong(); - th->intSpeed = SV_ReadLong(); - th->dist = SV_ReadLong(); - th->fangle = SV_ReadLong(); - th->speed[VX] = FIX2FLT(SV_ReadLong()); - th->speed[VY] = FIX2FLT(SV_ReadLong()); + th->polyobj = Reader_ReadInt32(reader); + th->intSpeed = Reader_ReadInt32(reader); + th->dist = Reader_ReadInt32(reader); + th->fangle = Reader_ReadInt32(reader); + th->speed[VX] = FIX2FLT(Reader_ReadInt32(reader)); + th->speed[VY] = FIX2FLT(Reader_ReadInt32(reader)); } else { // Its in the old pre V4 format which serialized polyevent_t // Padding at the start (an old thinker_t struct) - thinker_t junk; - SV_Read(&junk, (size_t) 16); + byte junk[16]; // sizeof thinker_t + Reader_Read(reader, junk, 16); // Start of used data members. - th->polyobj = SV_ReadLong(); - th->intSpeed = SV_ReadLong(); - th->dist = SV_ReadLong(); - th->fangle = SV_ReadLong(); - th->speed[VX] = FIX2FLT(SV_ReadLong()); - th->speed[VY] = FIX2FLT(SV_ReadLong()); + th->polyobj = Reader_ReadInt32(reader); + th->intSpeed = Reader_ReadInt32(reader); + th->dist = Reader_ReadInt32(reader); + th->fangle = Reader_ReadInt32(reader); + th->speed[VX] = FIX2FLT(Reader_ReadInt32(reader)); + th->speed[VY] = FIX2FLT(Reader_ReadInt32(reader)); } th->thinker.function = T_MovePoly; @@ -3227,19 +3227,9 @@ static void relinkThinkers() /** * Deserializes and then spawns thinkers for both client and server. */ -static void readThinkers(Reader *reader) +static void readThinkers(Reader *reader, int mapVersion) { -#if __JHEXEN__ - int const arcMapVersion = mapVersion; -#else - int const arcMapVersion = hdr->version; -#endif - -#if __JHEXEN__ bool const formatHasStasisInfo = (mapVersion >= 6); -#else - bool const formatHasStasisInfo = (hdr->version >= 6); -#endif removeLoadSpawnedThinkers(); @@ -3252,7 +3242,7 @@ static void readThinkers(Reader *reader) #if __JHEXEN__ initTargetPlayers(); - initThingArchiveForLoad(SV_ReadLong() /* num elements */); + initThingArchiveForLoad(Reader_ReadInt32(reader) /* num elements */); #endif // Read in saved thinkers. @@ -3260,15 +3250,16 @@ static void readThinkers(Reader *reader) int i = 0; bool reachedSpecialsBlock = (mapVersion >= 4); #else - bool reachedSpecialsBlock = (hdr->version >= 5); + bool reachedSpecialsBlock = (mapVersion >= 5); #endif + byte tClass = 0; for(;;) { #if __JHEXEN__ if(reachedSpecialsBlock) #endif - tClass = SV_ReadByte(); + tClass = Reader_ReadByte(reader); #if __JHEXEN__ if(mapVersion < 4) @@ -3296,7 +3287,7 @@ static void readThinkers(Reader *reader) } } #else - if(hdr->version < 5) + if(mapVersion < 5) { if(reachedSpecialsBlock) { @@ -3335,9 +3326,9 @@ static void readThinkers(Reader *reader) th = reinterpret_cast(Z_Calloc(thInfo->size, PU_MAP, 0)); } - bool putThinkerInStasis = (formatHasStasisInfo? CPP_BOOL(SV_ReadByte()) : false); + bool putThinkerInStasis = (formatHasStasisInfo? CPP_BOOL(Reader_ReadByte(reader)) : false); - if(thInfo->readFunc(th, reader, arcMapVersion)) + if(thInfo->readFunc(th, reader, mapVersion)) { Thinker_Add(th); } @@ -3363,49 +3354,49 @@ static void writeBrain(Writer *writer) // Not for us? if(!IS_SERVER) return; - SV_WriteByte(1); // Write a version byte. + Writer_WriteByte(writer, 1); // Write a version byte. - SV_WriteShort(brain.numTargets); - SV_WriteShort(brain.targetOn); - SV_WriteByte(brain.easy!=0? 1:0); + Writer_WriteInt16(writer, brain.numTargets); + Writer_WriteInt16(writer, brain.targetOn); + Writer_WriteByte(writer, brain.easy!=0? 1:0); // Write the mobj references using the mobj archive. for(int i = 0; i < brain.numTargets; ++i) { - SV_WriteShort(SV_ThingArchiveId(brain.targets[i])); + Writer_WriteInt16(writer, SV_ThingArchiveId(brain.targets[i])); } #endif } -static void readBrain(Reader *reader) +static void readBrain(Reader *reader, int mapVersion) { #if __JDOOM__ // Not for us? if(!IS_SERVER) return; // No brain data before version 3. - if(hdr->version < 3) return; + if(mapVersion < 3) return; P_BrainClearTargets(); - int ver = (hdr->version >= 8? SV_ReadByte() : 0); + int ver = (mapVersion >= 8? Reader_ReadByte(reader) : 0); int numTargets; if(ver >= 1) { - numTargets = SV_ReadShort(); - brain.targetOn = SV_ReadShort(); - brain.easy = (dd_bool)SV_ReadByte(); + numTargets = Reader_ReadInt16(reader); + brain.targetOn = Reader_ReadInt16(reader); + brain.easy = (dd_bool)Reader_ReadByte(reader); } else { - numTargets = SV_ReadByte(); - brain.targetOn = SV_ReadByte(); + numTargets = Reader_ReadByte(reader); + brain.targetOn = Reader_ReadByte(reader); brain.easy = false; } for(int i = 0; i < numTargets; ++i) { - P_BrainAddTarget(SV_GetArchiveThing((int) SV_ReadShort(), 0)); + P_BrainAddTarget(SV_GetArchiveThing((int) Reader_ReadInt16(reader), 0)); } #endif } @@ -3433,30 +3424,30 @@ static void writeSoundTargets(Writer *writer) #endif } -static void readSoundTargets(Reader *reader) +static void readSoundTargets(Reader *reader, int mapVersion) { #if !__JHEXEN__ // Not for us? if(!IS_SERVER) return; // Sound Target data was introduced in ver 5 - if(hdr->version < 5) return; + if(mapVersion < 5) return; // Read the number of targets - int numsoundtargets = SV_ReadLong(); + int numsoundtargets = Reader_ReadInt32(reader); // Read in the sound targets. for(int i = 0; i < numsoundtargets; ++i) { - xsector_t *xsec = P_ToXSector((Sector *)P_ToPtr(DMU_SECTOR, SV_ReadLong())); + xsector_t *xsec = P_ToXSector((Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(reader))); DENG_ASSERT(xsec != 0); if(!xsec) { - DENG_UNUSED(SV_ReadShort()); + DENG_UNUSED(Reader_ReadInt16(reader)); continue; } - xsec->soundTarget = INT2PTR(mobj_t, SV_ReadShort()); + xsec->soundTarget = INT2PTR(mobj_t, Reader_ReadInt16(reader)); xsec->soundTarget = SV_GetArchiveThing(PTR2INT(xsec->soundTarget), &xsec->soundTarget); } @@ -3475,14 +3466,14 @@ static void writeMisc(Writer *writer) #endif } -static void readMisc(Reader *reader) +static void readMisc(Reader *reader, int /*mapVersion*/) { #if __JHEXEN__ SV_AssertSegment(ASEG_MISC); for(int i = 0; i < MAXPLAYERS; ++i) { - localQuakeHappening[i] = SV_ReadLong(); + localQuakeHappening[i] = Reader_ReadInt32(reader); } #endif } @@ -3525,27 +3516,33 @@ static void readMap(Reader *reader) SV_AssertMapSegment(&mapSegmentId); { #if __JHEXEN__ - mapVersion = (mapSegmentId == ASEG_MAP_HEADER2? SV_ReadByte() : 2); + mapVersion = (mapSegmentId == ASEG_MAP_HEADER2? Reader_ReadByte(reader) : 2); +#else + int const mapVersion = hdr->version; +#endif +#if __JHEXEN__ // Read the map timer. - mapTime = SV_ReadLong(); + mapTime = Reader_ReadInt32(reader); #endif // Read the material archive for the map. #if !__JHEXEN__ - if(hdr->version >= 4) + if(mapVersion >= 4) #endif + { + MaterialArchive_Read(materialArchive, reader, materialArchiveVersion()); + } - MaterialArchive_Read(materialArchive, reader, materialArchiveVersion()); - readMapElements(reader); - readThinkers(reader); + readMapElements(reader, mapVersion); + readThinkers(reader, mapVersion); #if __JHEXEN__ - P_ReadMapACScriptData(reader); + P_ReadMapACScriptData(reader, mapVersion); SN_ReadSequences(reader, mapVersion); #endif - readMisc(reader); - readBrain(reader); - readSoundTargets(reader); + readMisc(reader, mapVersion); + readBrain(reader, mapVersion); + readSoundTargets(reader, mapVersion); } SV_AssertSegment(ASEG_END); @@ -3687,10 +3684,10 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) #endif #if !__JHEXEN__ - initThingArchiveForLoad(hdr->version >= 5? SV_ReadLong() : 1024 /* num elements */); + initThingArchiveForLoad(hdr->version >= 5? Reader_ReadInt32(reader) : 1024 /* num elements */); #endif - readPlayerHeader(); + readPlayerHeader(reader); // Read the player structures // We don't have the right to say which players are in the game. The @@ -3699,7 +3696,7 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) // players who were saved but are not currently in the game will be // discarded. dd_bool loaded[MAXPLAYERS], infile[MAXPLAYERS]; - readPlayers(infile, loaded); + readPlayers(infile, loaded, reader); #if __JHEXEN__ Z_Free(saveBuffer); @@ -3938,8 +3935,8 @@ void SV_SaveGameClient(uint gameId) SV_WriteLong(FLT2FIX(mo->ceilingZ)); SV_WriteLong(mo->angle); /* $unifiedangles */ SV_WriteFloat(pl->plr->lookDir); /* $unifiedangles */ - writePlayerHeader(); - SV_WritePlayer(CONSOLEPLAYER); + writePlayerHeader(writer); + SV_WritePlayer(CONSOLEPLAYER, writer); // Create and populate the MaterialArchive. materialArchive = MaterialArchive_New(false); @@ -4010,16 +4007,16 @@ void SV_LoadGameClient(uint gameId) mapTime = hdr->mapTime; P_MobjUnlink(mo); - mo->origin[VX] = FIX2FLT(SV_ReadLong()); - mo->origin[VY] = FIX2FLT(SV_ReadLong()); - mo->origin[VZ] = FIX2FLT(SV_ReadLong()); + mo->origin[VX] = FIX2FLT(Reader_ReadInt32(reader)); + mo->origin[VY] = FIX2FLT(Reader_ReadInt32(reader)); + mo->origin[VZ] = FIX2FLT(Reader_ReadInt32(reader)); P_MobjLink(mo); - mo->floorZ = FIX2FLT(SV_ReadLong()); - mo->ceilingZ = FIX2FLT(SV_ReadLong()); - mo->angle = SV_ReadLong(); /* $unifiedangles */ - cpl->plr->lookDir = SV_ReadFloat(); /* $unifiedangles */ - readPlayerHeader(); - SV_ReadPlayer(cpl); + mo->floorZ = FIX2FLT(Reader_ReadInt32(reader)); + mo->ceilingZ = FIX2FLT(Reader_ReadInt32(reader)); + mo->angle = Reader_ReadInt32(reader); /* $unifiedangles */ + cpl->plr->lookDir = Reader_ReadFloat(reader); /* $unifiedangles */ + readPlayerHeader(reader); + SV_ReadPlayer(cpl, reader); /** * Create and populate the MaterialArchive. @@ -4113,8 +4110,8 @@ static int saveStateWorker(Str const *path, SaveInfo *saveInfo) materialArchive = MaterialArchive_New(false); #endif - writePlayerHeader(); - writePlayers(); + writePlayerHeader(writer); + writePlayers(writer); #if __JHEXEN__ // Close the game session file (maps are saved into a seperate file). diff --git a/doomsday/plugins/common/src/p_xgsave.cpp b/doomsday/plugins/common/src/p_xgsave.cpp index 2b18d8cffe..765f5b0245 100644 --- a/doomsday/plugins/common/src/p_xgsave.cpp +++ b/doomsday/plugins/common/src/p_xgsave.cpp @@ -26,10 +26,9 @@ #include "p_saveg.h" #include "p_xg.h" -void SV_WriteXGLine(Line *li) +void SV_WriteXGLine(Line *li, Writer *writer) { - xgline_t *xg = P_ToXLine(li)->xg; - linetype_t *info = &xg->info; + xline_t *xline = P_ToXLine(li); // Version byte. SV_WriteByte(1); @@ -40,86 +39,88 @@ void SV_WriteXGLine(Line *li) * DED file. During loading, XL_SetLineType is called with the id in the savegame. */ - SV_WriteLong(info->id); - SV_WriteLong(info->actCount); - - SV_WriteByte(xg->active); - SV_WriteByte(xg->disabled); - SV_WriteLong(xg->timer); - SV_WriteLong(xg->tickerTimer); - SV_WriteShort(SV_ThingArchiveId((mobj_t *)xg->activator)); - SV_WriteLong(xg->idata); - SV_WriteFloat(xg->fdata); - SV_WriteLong(xg->chIdx); - SV_WriteFloat(xg->chTimer); + DENG_ASSERT(xline->xg != 0); + xgline_t *xg = xline->xg; + linetype_t *info = &xg->info; + + Writer_WriteInt32(writer, info->id); + Writer_WriteInt32(writer, info->actCount); + + Writer_WriteByte(writer, xg->active); + Writer_WriteByte(writer, xg->disabled); + Writer_WriteInt32(writer, xg->timer); + Writer_WriteInt32(writer, xg->tickerTimer); + Writer_WriteInt16(writer, SV_ThingArchiveId((mobj_t *)xg->activator)); + Writer_WriteInt32(writer, xg->idata); + Writer_WriteFloat(writer, xg->fdata); + Writer_WriteInt32(writer, xg->chIdx); + Writer_WriteFloat(writer, xg->chTimer); } -void SV_ReadXGLine(Line *li) +void SV_ReadXGLine(Line *li, Reader *reader, int /*mapVersion*/) { xline_t *xline = P_ToXLine(li); // Read version. - SV_ReadByte(); + Reader_ReadByte(reader); // This'll set all the correct string pointers and other data. - XL_SetLineType(li, SV_ReadLong()); + XL_SetLineType(li, Reader_ReadInt32(reader)); - DENG_ASSERT(xline != 0); DENG_ASSERT(xline->xg != 0); - xgline_t *xg = xline->xg; - xg->info.actCount = SV_ReadLong(); + xg->info.actCount = Reader_ReadInt32(reader); - xg->active = SV_ReadByte(); - xg->disabled = SV_ReadByte(); - xg->timer = SV_ReadLong(); - xg->tickerTimer = SV_ReadLong(); + xg->active = Reader_ReadByte(reader); + xg->disabled = Reader_ReadByte(reader); + xg->timer = Reader_ReadInt32(reader); + xg->tickerTimer = Reader_ReadInt32(reader); // Will be updated later. - xg->activator = INT2PTR(void, SV_ReadShort()); + xg->activator = INT2PTR(void, Reader_ReadInt16(reader)); - xg->idata = SV_ReadLong(); - xg->fdata = SV_ReadFloat(); - xg->chIdx = SV_ReadLong(); - xg->chTimer = SV_ReadFloat(); + xg->idata = Reader_ReadInt32(reader); + xg->fdata = Reader_ReadFloat(reader); + xg->chIdx = Reader_ReadInt32(reader); + xg->chTimer = Reader_ReadFloat(reader); } /** * @param fn This function must belong to XG sector @a xg. */ -void SV_WriteXGFunction(xgsector_t *xg, function_t *fn) +void SV_WriteXGFunction(xgsector_t *xg, function_t *fn, Writer *writer) { // Version byte. - SV_WriteByte(1); - - SV_WriteLong(fn->flags); - SV_WriteShort(fn->pos); - SV_WriteShort(fn->repeat); - SV_WriteShort(fn->timer); - SV_WriteShort(fn->maxTimer); - SV_WriteFloat(fn->value); - SV_WriteFloat(fn->oldValue); + Writer_WriteByte(writer, 1); + + Writer_WriteInt32(writer, fn->flags); + Writer_WriteInt16(writer, fn->pos); + Writer_WriteInt16(writer, fn->repeat); + Writer_WriteInt16(writer, fn->timer); + Writer_WriteInt16(writer, fn->maxTimer); + Writer_WriteFloat(writer, fn->value); + Writer_WriteFloat(writer, fn->oldValue); } /** * @param fn This function must belong to XG sector @a xg. */ -void SV_ReadXGFunction(xgsector_t *xg, function_t *fn) +void SV_ReadXGFunction(xgsector_t *xg, function_t *fn, Reader *reader, int mapVersion) { // Version byte. - SV_ReadByte(); - - fn->flags = SV_ReadLong(); - fn->pos = SV_ReadShort(); - fn->repeat = SV_ReadShort(); - fn->timer = SV_ReadShort(); - fn->maxTimer = SV_ReadShort(); - fn->value = SV_ReadFloat(); - fn->oldValue = SV_ReadFloat(); + Reader_ReadByte(reader); + + fn->flags = Reader_ReadInt32(reader); + fn->pos = Reader_ReadInt16(reader); + fn->repeat = Reader_ReadInt16(reader); + fn->timer = Reader_ReadInt16(reader); + fn->maxTimer = Reader_ReadInt16(reader); + fn->value = Reader_ReadFloat(reader); + fn->oldValue = Reader_ReadFloat(reader); } -void SV_WriteXGSector(Sector *sec) +void SV_WriteXGSector(Sector *sec, Writer *writer) { xsector_t *xsec = P_ToXSector(sec); @@ -127,48 +128,48 @@ void SV_WriteXGSector(Sector *sec) sectortype_t *info = &xg->info; // Version byte. - SV_WriteByte(1); + Writer_WriteByte(writer, 1); - SV_WriteLong(info->id); - SV_Write(info->count, sizeof(info->count)); - SV_Write(xg->chainTimer, sizeof(xg->chainTimer)); - SV_WriteLong(xg->timer); - SV_WriteByte(xg->disabled); + Writer_WriteInt32(writer, info->id); + Writer_Write(writer, info->count, sizeof(info->count)); + Writer_Write(writer, xg->chainTimer, sizeof(xg->chainTimer)); + Writer_WriteInt32(writer, xg->timer); + Writer_WriteByte(writer, xg->disabled); for(int i = 0; i < 3; ++i) { - SV_WriteXGFunction(xg, &xg->rgb[i]); + SV_WriteXGFunction(xg, &xg->rgb[i], writer); } for(int i = 0; i < 2; ++i) { - SV_WriteXGFunction(xg, &xg->plane[i]); + SV_WriteXGFunction(xg, &xg->plane[i], writer); } - SV_WriteXGFunction(xg, &xg->light); + SV_WriteXGFunction(xg, &xg->light, writer); } -void SV_ReadXGSector(Sector *sec) +void SV_ReadXGSector(Sector *sec, Reader *reader, int mapVersion) { xsector_t *xsec = P_ToXSector(sec); // Version byte. - SV_ReadByte(); + Reader_ReadByte(reader); // This'll init all the data. - XS_SetSectorType(sec, SV_ReadLong()); + XS_SetSectorType(sec, Reader_ReadInt32(reader)); xgsector_t *xg = xsec->xg; - SV_Read(xg->info.count, sizeof(xg->info.count)); - SV_Read(xg->chainTimer, sizeof(xg->chainTimer)); - xg->timer = SV_ReadLong(); - xg->disabled = SV_ReadByte(); + Reader_Read(reader, xg->info.count, sizeof(xg->info.count)); + Reader_Read(reader, xg->chainTimer, sizeof(xg->chainTimer)); + xg->timer = Reader_ReadInt32(reader); + xg->disabled = Reader_ReadByte(reader); for(int i = 0; i < 3; ++i) { - SV_ReadXGFunction(xg, &xg->rgb[i]); + SV_ReadXGFunction(xg, &xg->rgb[i], reader, mapVersion); } for(int i = 0; i < 2; ++i) { - SV_ReadXGFunction(xg, &xg->plane[i]); + SV_ReadXGFunction(xg, &xg->plane[i], reader, mapVersion); } - SV_ReadXGFunction(xg, &xg->light); + SV_ReadXGFunction(xg, &xg->light, reader, mapVersion); } void xgplanemover_t::write(Writer *writer) const @@ -208,7 +209,7 @@ int xgplanemover_t::read(Reader *reader, int mapVersion) ceiling = Reader_ReadByte(reader); flags = Reader_ReadInt32(reader); - int lineIndex = SV_ReadLong(); + int lineIndex = Reader_ReadInt32(reader); if(lineIndex > 0) origin = (Line *)P_ToPtr(DMU_LINE, lineIndex - 1); diff --git a/doomsday/plugins/doom/include/p_mobj.h b/doomsday/plugins/doom/include/p_mobj.h index 2997036513..3559d2be44 100644 --- a/doomsday/plugins/doom/include/p_mobj.h +++ b/doomsday/plugins/doom/include/p_mobj.h @@ -34,6 +34,7 @@ # error "Using jDoom headers without __JDOOM__" #endif +#include "doomsday.h" #include "dd_types.h" #include "d_think.h" #include "p_terraintype.h" @@ -218,6 +219,11 @@ typedef struct mobj_s { int turnTime; // $visangle-facetarget int corpseTics; // $vanish: how long has this been dead? + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } mobj_t; #ifdef __cplusplus diff --git a/doomsday/plugins/doom64/include/p_mobj.h b/doomsday/plugins/doom64/include/p_mobj.h index 89c80ddd9e..a2682d96d6 100644 --- a/doomsday/plugins/doom64/include/p_mobj.h +++ b/doomsday/plugins/doom64/include/p_mobj.h @@ -36,6 +36,7 @@ #endif // Basics. +#include "doomsday.h" #include "tables.h" #include "p_terraintype.h" @@ -240,6 +241,11 @@ typedef struct mobj_s { int turnTime; // $visangle-facetarget int corpseTics; // $vanish: how long has this been dead? int spawnFadeTics; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } mobj_t; #ifdef __cplusplus diff --git a/doomsday/plugins/heretic/include/p_mobj.h b/doomsday/plugins/heretic/include/p_mobj.h index 928245c38b..a089b4d072 100644 --- a/doomsday/plugins/heretic/include/p_mobj.h +++ b/doomsday/plugins/heretic/include/p_mobj.h @@ -34,6 +34,7 @@ # error "Using jHeretic headers without __JHERETIC__" #endif +#include "doomsday.h" #include "p_terraintype.h" #include "h_think.h" #include "info.h" @@ -217,6 +218,11 @@ typedef struct mobj_s { int turnTime; // $visangle-facetarget int corpseTics; // $vanish: how long has this been dead? + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } mobj_t; #ifdef __cplusplus diff --git a/doomsday/plugins/hexen/include/acscript.h b/doomsday/plugins/hexen/include/acscript.h index 0af3b06cb3..c7d48d6e8d 100644 --- a/doomsday/plugins/hexen/include/acscript.h +++ b/doomsday/plugins/hexen/include/acscript.h @@ -178,10 +178,10 @@ class ACScriptInterpreter void scriptFinished(ACScript *script); void writeWorldScriptData(Writer *writer); - void readWorldScriptData(Reader *reader, int saveVersion); + void readWorldScriptData(Reader *reader, int mapVersion); void writeMapScriptData(Writer *writer); - void readMapScriptData(Reader *reader); + void readMapScriptData(Reader *reader, int mapVersion); public: /// @todo make private: BytecodeScriptInfo &scriptInfoByIndex(int index); @@ -245,10 +245,10 @@ void P_ACScriptPolyobjFinished(int tag); void P_ACScriptRunDeferredTasks(uint map/*Uri const *map*/); void P_WriteGlobalACScriptData(Writer *writer); -void P_ReadGlobalACScriptData(Reader *reader, int saveVersion); +void P_ReadGlobalACScriptData(Reader *reader, int mapVersion); void P_WriteMapACScriptData(Writer *writer); -void P_ReadMapACScriptData(Reader *reader); +void P_ReadMapACScriptData(Reader *reader, int mapVersion); #ifdef __cplusplus } // extern "C" diff --git a/doomsday/plugins/hexen/include/p_mobj.h b/doomsday/plugins/hexen/include/p_mobj.h index 55ffdb8286..a50a37192b 100644 --- a/doomsday/plugins/hexen/include/p_mobj.h +++ b/doomsday/plugins/hexen/include/p_mobj.h @@ -33,6 +33,7 @@ # error "Using jHexen headers without __JHEXEN__" #endif +#include "doomsday.h" #include "p_terraintype.h" #define NOMOM_THRESHOLD (0.0001) // (integer) 0 @@ -206,6 +207,11 @@ typedef struct mobj_s { // Used by lightning zap struct mobj_s* lastEnemy; + +#ifdef __cplusplus + void write(Writer *writer) const; + int read(Reader *reader, int mapVersion); +#endif } mobj_t; #ifdef __cplusplus diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index 44722963d8..51a3dd3b73 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -495,11 +495,11 @@ void ACScriptInterpreter::writeWorldScriptData(Writer *writer) } } -void ACScriptInterpreter::readWorldScriptData(Reader *reader, int saveVersion) +void ACScriptInterpreter::readWorldScriptData(Reader *reader, int mapVersion) { int ver = 1; - if(saveVersion >= 7) + if(mapVersion >= 7) { SV_AssertSegment(ASEG_GLOBALSCRIPTDATA); ver = Reader_ReadByte(reader); @@ -553,7 +553,7 @@ void ACScriptInterpreter::readWorldScriptData(Reader *reader, int saveVersion) } } - if(saveVersion < 7) + if(mapVersion < 7) { SV_Seek(12); // Junk. } @@ -592,7 +592,7 @@ void ACScriptInterpreter::writeMapScriptData(Writer *writer) } } -void ACScriptInterpreter::readMapScriptData(Reader *reader) +void ACScriptInterpreter::readMapScriptData(Reader *reader, int /*mapVersion*/) { SV_AssertSegment(ASEG_SCRIPTS); @@ -1717,9 +1717,9 @@ void P_WriteGlobalACScriptData(Writer *writer) interp.writeWorldScriptData(writer); } -void P_ReadGlobalACScriptData(Reader *reader, int saveVersion) +void P_ReadGlobalACScriptData(Reader *reader, int mapVersion) { - interp.readWorldScriptData(reader, saveVersion); + interp.readWorldScriptData(reader, mapVersion); } void P_WriteMapACScriptData(Writer *writer) @@ -1727,9 +1727,9 @@ void P_WriteMapACScriptData(Writer *writer) interp.writeMapScriptData(writer); } -void P_ReadMapACScriptData(Reader *reader) +void P_ReadMapACScriptData(Reader *reader, int mapVersion) { - interp.readMapScriptData(reader); + interp.readMapScriptData(reader, mapVersion); } ACScriptInterpreter &ACScript::interpreter() const @@ -1830,7 +1830,7 @@ int ACScript::read(Reader *reader, int mapVersion) activator = (mobj_t *) Reader_ReadInt32(reader); activator = SV_GetArchiveThing(PTR2INT(activator), &activator); - int temp = SV_ReadLong(); + int temp = Reader_ReadInt32(reader); if(temp >= 0) { line = (Line *)P_ToPtr(DMU_LINE, temp); From ce17792c7a8232d03a66abc7e8e2b12b50a9fad3 Mon Sep 17 00:00:00 2001 From: danij Date: Fri, 31 Jan 2014 21:03:15 +0000 Subject: [PATCH 031/106] Refactor|libcommon: Completed save state (de)serialization Reader/Writer update --- doomsday/plugins/common/include/p_saveio.h | 20 +- doomsday/plugins/common/src/p_saveg.cpp | 308 ++++++++++----------- doomsday/plugins/common/src/p_saveio.c | 120 ++++---- doomsday/plugins/common/src/p_xgsave.cpp | 2 +- 4 files changed, 226 insertions(+), 224 deletions(-) diff --git a/doomsday/plugins/common/include/p_saveio.h b/doomsday/plugins/common/include/p_saveio.h index 216e49732f..0114cc4d91 100644 --- a/doomsday/plugins/common/include/p_saveio.h +++ b/doomsday/plugins/common/include/p_saveio.h @@ -58,23 +58,23 @@ void SV_InitIO(void); void SV_ShutdownIO(void); void SV_ConfigureSavePaths(void); -const char* SV_SavePath(void); +char const *SV_SavePath(void); #if !__JHEXEN__ -const char* SV_ClientSavePath(void); +char const *SV_ClientSavePath(void); #endif /* * File management */ -LZFILE* SV_OpenFile(Str const *filePath, char const *mode); +LZFILE *SV_OpenFile(Str const *filePath, char const *mode); void SV_CloseFile(void); -LZFILE* SV_File(void); +LZFILE *SV_File(void); dd_bool SV_ExistingFile(Str const *filePath); int SV_RemoveFile(Str const *filePath); void SV_CopyFile(Str const *srcPath, Str const *destPath); #if __JHEXEN__ -saveptr_t* SV_HxSavePtr(void); +saveptr_t *SV_HxSavePtr(void); void SV_HxSetSaveEndPtr(void *endPtr); dd_bool SV_HxBytesLeft(void); #endif // __JHEXEN__ @@ -107,10 +107,11 @@ void SV_ReadConsistencyBytes(void); */ void SV_Seek(uint offset); +#if 0 /* * Writing and reading values */ -void SV_Write(const void* data, int len); +void SV_Write(void const *data, int len); void SV_WriteByte(byte val); #if __JHEXEN__ void SV_WriteShort(unsigned short val); @@ -124,14 +125,15 @@ void SV_WriteLong(long val); #endif void SV_WriteFloat(float val); -void SV_Read(void* data, int len); +void SV_Read(void *data, int len); byte SV_ReadByte(void); short SV_ReadShort(void); long SV_ReadLong(void); float SV_ReadFloat(void); +#endif -Writer* SV_NewWriter(void); -Reader* SV_NewReader(void); +Writer *SV_NewWriter(void); +Reader *SV_NewReader(void); #ifdef __cplusplus } // extern "C" diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index c1768dab32..a4817380e6 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -119,7 +119,7 @@ static void SV_WriteMobj(thinker_t *th, Writer *writer); static int SV_ReadMobj(thinker_t *th, Reader *reader, int mapVersion); #if __JHEXEN__ -static void SV_WriteMovePoly(polyevent_t const *movepoly); +static void SV_WriteMovePoly(polyevent_t const *movepoly, Writer *writer); static int SV_ReadMovePoly(polyevent_t *movepoly, Reader *reader, int mapVersion); #endif @@ -1129,39 +1129,39 @@ static void SV_WritePlayer(int playernum, Writer *writer) // Version number. Increase when you make changes to the player data // segment format. - SV_WriteByte(6); + Writer_WriteByte(writer, 6); #if __JHEXEN__ // Class. - SV_WriteByte(cfg.playerClass[playernum]); + Writer_WriteByte(writer, cfg.playerClass[playernum]); #endif - SV_WriteLong(p->playerState); + Writer_WriteInt32(writer, p->playerState); #if __JHEXEN__ - SV_WriteLong(p->class_); // 2nd class...? + Writer_WriteInt32(writer, p->class_); // 2nd class...? #endif - SV_WriteLong(FLT2FIX(p->viewZ)); - SV_WriteLong(FLT2FIX(p->viewHeight)); - SV_WriteLong(FLT2FIX(p->viewHeightDelta)); + Writer_WriteInt32(writer, FLT2FIX(p->viewZ)); + Writer_WriteInt32(writer, FLT2FIX(p->viewHeight)); + Writer_WriteInt32(writer, FLT2FIX(p->viewHeightDelta)); #if !__JHEXEN__ - SV_WriteFloat(dp->lookDir); + Writer_WriteFloat(writer, dp->lookDir); #endif - SV_WriteLong(FLT2FIX(p->bob)); + Writer_WriteInt32(writer, FLT2FIX(p->bob)); #if __JHEXEN__ - SV_WriteLong(p->flyHeight); - SV_WriteFloat(dp->lookDir); - SV_WriteLong(p->centering); + Writer_WriteInt32(writer, p->flyHeight); + Writer_WriteFloat(writer, dp->lookDir); + Writer_WriteInt32(writer, p->centering); #endif - SV_WriteLong(p->health); + Writer_WriteInt32(writer, p->health); #if __JHEXEN__ for(i = 0; i < getPlayerHeader()->numArmorTypes; ++i) { - SV_WriteLong(p->armorPoints[i]); + Writer_WriteInt32(writer, p->armorPoints[i]); } #else - SV_WriteLong(p->armorPoints); - SV_WriteLong(p->armorType); + Writer_WriteInt32(writer, p->armorPoints); + Writer_WriteInt32(writer, p->armorType); #endif #if __JDOOM64__ || __JHEXEN__ @@ -1169,89 +1169,89 @@ static void SV_WritePlayer(int playernum, Writer *writer) { inventoryitemtype_t type = inventoryitemtype_t(IIT_FIRST + i); - SV_WriteLong(type); - SV_WriteLong(P_InventoryCount(playernum, type)); + Writer_WriteInt32(writer, type); + Writer_WriteInt32(writer, P_InventoryCount(playernum, type)); } - SV_WriteLong(P_InventoryReadyItem(playernum)); + Writer_WriteInt32(writer, P_InventoryReadyItem(playernum)); #endif for(i = 0; i < getPlayerHeader()->numPowers; ++i) { - SV_WriteLong(p->powers[i]); + Writer_WriteInt32(writer, p->powers[i]); } #if __JHEXEN__ - SV_WriteLong(p->keys); + Writer_WriteInt32(writer, p->keys); #else for(i = 0; i < getPlayerHeader()->numKeys; ++i) { - SV_WriteLong(p->keys[i]); + Writer_WriteInt32(writer, p->keys[i]); } #endif #if __JHEXEN__ - SV_WriteLong(p->pieces); + Writer_WriteInt32(writer, p->pieces); #else - SV_WriteLong(p->backpack); + Writer_WriteInt32(writer, p->backpack); #endif for(i = 0; i < getPlayerHeader()->numFrags; ++i) { - SV_WriteLong(p->frags[i]); + Writer_WriteInt32(writer, p->frags[i]); } - SV_WriteLong(p->readyWeapon); - SV_WriteLong(p->pendingWeapon); + Writer_WriteInt32(writer, p->readyWeapon); + Writer_WriteInt32(writer, p->pendingWeapon); for(i = 0; i < getPlayerHeader()->numWeapons; ++i) { - SV_WriteLong(p->weapons[i].owned); + Writer_WriteInt32(writer, p->weapons[i].owned); } for(i = 0; i < getPlayerHeader()->numAmmoTypes; ++i) { - SV_WriteLong(p->ammo[i].owned); + Writer_WriteInt32(writer, p->ammo[i].owned); #if !__JHEXEN__ - SV_WriteLong(p->ammo[i].max); + Writer_WriteInt32(writer, p->ammo[i].max); #endif } - SV_WriteLong(p->attackDown); - SV_WriteLong(p->useDown); + Writer_WriteInt32(writer, p->attackDown); + Writer_WriteInt32(writer, p->useDown); - SV_WriteLong(p->cheats); + Writer_WriteInt32(writer, p->cheats); - SV_WriteLong(p->refire); + Writer_WriteInt32(writer, p->refire); - SV_WriteLong(p->killCount); - SV_WriteLong(p->itemCount); - SV_WriteLong(p->secretCount); + Writer_WriteInt32(writer, p->killCount); + Writer_WriteInt32(writer, p->itemCount); + Writer_WriteInt32(writer, p->secretCount); - SV_WriteLong(p->damageCount); - SV_WriteLong(p->bonusCount); + Writer_WriteInt32(writer, p->damageCount); + Writer_WriteInt32(writer, p->bonusCount); #if __JHEXEN__ - SV_WriteLong(p->poisonCount); + Writer_WriteInt32(writer, p->poisonCount); #endif - SV_WriteLong(dp->extraLight); - SV_WriteLong(dp->fixedColorMap); - SV_WriteLong(p->colorMap); + Writer_WriteInt32(writer, dp->extraLight); + Writer_WriteInt32(writer, dp->fixedColorMap); + Writer_WriteInt32(writer, p->colorMap); for(i = 0; i < numPSprites; ++i) { - pspdef_t *psp = &p->pSprites[i]; + pspdef_t *psp = &p->pSprites[i]; - SV_WriteLong(PTR2INT(psp->state)); - SV_WriteLong(psp->tics); - SV_WriteLong(FLT2FIX(psp->pos[VX])); - SV_WriteLong(FLT2FIX(psp->pos[VY])); + Writer_WriteInt32(writer, PTR2INT(psp->state)); + Writer_WriteInt32(writer, psp->tics); + Writer_WriteInt32(writer, FLT2FIX(psp->pos[VX])); + Writer_WriteInt32(writer, FLT2FIX(psp->pos[VY])); } #if !__JHEXEN__ - SV_WriteLong(p->didSecret); + Writer_WriteInt32(writer, p->didSecret); // Added in ver 2 with __JDOOM__ - SV_WriteLong(p->flyHeight); + Writer_WriteInt32(writer, p->flyHeight); #endif #if __JHERETIC__ @@ -1259,27 +1259,27 @@ static void SV_WritePlayer(int playernum, Writer *writer) { inventoryitemtype_t type = inventoryitemtype_t(IIT_FIRST + i); - SV_WriteLong(type); - SV_WriteLong(P_InventoryCount(playernum, type)); + Writer_WriteInt32(writer, type); + Writer_WriteInt32(writer, P_InventoryCount(playernum, type)); } - SV_WriteLong(P_InventoryReadyItem(playernum)); - SV_WriteLong(p->chickenPeck); + Writer_WriteInt32(writer, P_InventoryReadyItem(playernum)); + Writer_WriteInt32(writer, p->chickenPeck); #endif #if __JHERETIC__ || __JHEXEN__ - SV_WriteLong(p->morphTics); + Writer_WriteInt32(writer, p->morphTics); #endif - SV_WriteLong(p->airCounter); + Writer_WriteInt32(writer, p->airCounter); #if __JHEXEN__ - SV_WriteLong(p->jumpTics); - SV_WriteLong(p->worldTimer); + Writer_WriteInt32(writer, p->jumpTics); + Writer_WriteInt32(writer, p->worldTimer); #elif __JHERETIC__ - SV_WriteLong(p->flameCount); + Writer_WriteInt32(writer, p->flameCount); // Added in ver 2 - SV_WriteByte(p->class_); + Writer_WriteByte(writer, p->class_); #endif } @@ -2128,32 +2128,32 @@ static void writePlayerHeader(Writer *writer) playerheader_t *ph = &playerHeader; SV_BeginSegment(ASEG_PLAYER_HEADER); - SV_WriteByte(2); // version byte - - ph->numPowers = NUM_POWER_TYPES; - ph->numKeys = NUM_KEY_TYPES; - ph->numFrags = MAXPLAYERS; - ph->numWeapons = NUM_WEAPON_TYPES; - ph->numAmmoTypes = NUM_AMMO_TYPES; - ph->numPSprites = NUMPSPRITES; + Writer_WriteByte(writer, 2); // version byte + + ph->numPowers = NUM_POWER_TYPES; + ph->numKeys = NUM_KEY_TYPES; + ph->numFrags = MAXPLAYERS; + ph->numWeapons = NUM_WEAPON_TYPES; + ph->numAmmoTypes = NUM_AMMO_TYPES; + ph->numPSprites = NUMPSPRITES; #if __JHERETIC__ || __JHEXEN__ || __JDOOM64__ ph->numInvItemTypes = NUM_INVENTORYITEM_TYPES; #endif #if __JHEXEN__ - ph->numArmorTypes = NUMARMOR; + ph->numArmorTypes = NUMARMOR; #endif - SV_WriteLong(ph->numPowers); - SV_WriteLong(ph->numKeys); - SV_WriteLong(ph->numFrags); - SV_WriteLong(ph->numWeapons); - SV_WriteLong(ph->numAmmoTypes); - SV_WriteLong(ph->numPSprites); + Writer_WriteInt32(writer, ph->numPowers); + Writer_WriteInt32(writer, ph->numKeys); + Writer_WriteInt32(writer, ph->numFrags); + Writer_WriteInt32(writer, ph->numWeapons); + Writer_WriteInt32(writer, ph->numAmmoTypes); + Writer_WriteInt32(writer, ph->numPSprites); #if __JDOOM64__ || __JHERETIC__ || __JHEXEN__ - SV_WriteLong(ph->numInvItemTypes); + Writer_WriteInt32(writer, ph->numInvItemTypes); #endif #if __JHEXEN__ - SV_WriteLong(ph->numArmorTypes); + Writer_WriteInt32(writer, ph->numArmorTypes); #endif playerHeaderOK = true; @@ -2346,43 +2346,43 @@ static void SV_WriteSector(Sector *sec, Writer *writer) type = sc_normal; // Type byte. - SV_WriteByte(type); + Writer_WriteByte(writer, type); // Version. // 2: Surface colors. // 3: Surface flags. - SV_WriteByte(3); // write a version byte. + Writer_WriteByte(writer, 3); // write a version byte. - SV_WriteShort(floorheight); - SV_WriteShort(ceilingheight); - SV_WriteShort(MaterialArchive_FindUniqueSerialId(materialArchive, floorMaterial)); - SV_WriteShort(MaterialArchive_FindUniqueSerialId(materialArchive, ceilingMaterial)); - SV_WriteShort(floorFlags); - SV_WriteShort(ceilingFlags); + Writer_WriteInt16(writer, floorheight); + Writer_WriteInt16(writer, ceilingheight); + Writer_WriteInt16(writer, MaterialArchive_FindUniqueSerialId(materialArchive, floorMaterial)); + Writer_WriteInt16(writer, MaterialArchive_FindUniqueSerialId(materialArchive, ceilingMaterial)); + Writer_WriteInt16(writer, floorFlags); + Writer_WriteInt16(writer, ceilingFlags); #if __JHEXEN__ - SV_WriteShort((short) lightlevel); + Writer_WriteInt16(writer, (short) lightlevel); #else - SV_WriteByte(lightlevel); + Writer_WriteByte(writer, lightlevel); #endif float rgb[3]; P_GetFloatpv(sec, DMU_COLOR, rgb); for(i = 0; i < 3; ++i) - SV_WriteByte((byte)(255.f * rgb[i])); + Writer_WriteByte(writer, (byte)(255.f * rgb[i])); P_GetFloatpv(sec, DMU_FLOOR_COLOR, rgb); for(i = 0; i < 3; ++i) - SV_WriteByte((byte)(255.f * rgb[i])); + Writer_WriteByte(writer, (byte)(255.f * rgb[i])); P_GetFloatpv(sec, DMU_CEILING_COLOR, rgb); for(i = 0; i < 3; ++i) - SV_WriteByte((byte)(255.f * rgb[i])); + Writer_WriteByte(writer, (byte)(255.f * rgb[i])); - SV_WriteShort(xsec->special); - SV_WriteShort(xsec->tag); + Writer_WriteInt16(writer, xsec->special); + Writer_WriteInt16(writer, xsec->tag); #if __JHEXEN__ - SV_WriteShort(xsec->seqType); + Writer_WriteInt16(writer, xsec->seqType); #endif if(type == sc_ploff @@ -2391,10 +2391,10 @@ static void SV_WriteSector(Sector *sec, Writer *writer) #endif ) { - SV_WriteFloat(flooroffx); - SV_WriteFloat(flooroffy); - SV_WriteFloat(ceiloffx); - SV_WriteFloat(ceiloffy); + Writer_WriteFloat(writer, flooroffx); + Writer_WriteFloat(writer, flooroffy); + Writer_WriteFloat(writer, ceiloffx); + Writer_WriteFloat(writer, ceiloffy); } #if !__JHEXEN__ @@ -2563,7 +2563,7 @@ static void SV_WriteLine(Line *li, Writer *writer) else #endif type = lc_normal; - SV_WriteByte(type); + Writer_WriteByte(writer, type); // Version. // 2: Per surface texture offsets. @@ -2571,24 +2571,24 @@ static void SV_WriteLine(Line *li, Writer *writer) // 3: "Mapped by player" values. // 3: Surface flags. // 4: Engine-side line flags. - SV_WriteByte(4); // Write a version byte + Writer_WriteByte(writer, 4); // Write a version byte - SV_WriteShort(P_GetIntp(li, DMU_FLAGS)); - SV_WriteShort(xli->flags); + Writer_WriteInt16(writer, P_GetIntp(li, DMU_FLAGS)); + Writer_WriteInt16(writer, xli->flags); for(int i = 0; i < MAXPLAYERS; ++i) - SV_WriteByte(xli->mapped[i]); + Writer_WriteByte(writer, xli->mapped[i]); #if __JHEXEN__ - SV_WriteByte(xli->special); - SV_WriteByte(xli->arg1); - SV_WriteByte(xli->arg2); - SV_WriteByte(xli->arg3); - SV_WriteByte(xli->arg4); - SV_WriteByte(xli->arg5); + Writer_WriteByte(writer, xli->special); + Writer_WriteByte(writer, xli->arg1); + Writer_WriteByte(writer, xli->arg2); + Writer_WriteByte(writer, xli->arg3); + Writer_WriteByte(writer, xli->arg4); + Writer_WriteByte(writer, xli->arg5); #else - SV_WriteShort(xli->special); - SV_WriteShort(xli->tag); + Writer_WriteInt16(writer, xli->special); + Writer_WriteInt16(writer, xli->tag); #endif // For each side @@ -2598,35 +2598,35 @@ static void SV_WriteLine(Line *li, Writer *writer) Side *si = (Side *)P_GetPtrp(li, (i? DMU_BACK:DMU_FRONT)); if(!si) continue; - SV_WriteShort(P_GetIntp(si, DMU_TOP_MATERIAL_OFFSET_X)); - SV_WriteShort(P_GetIntp(si, DMU_TOP_MATERIAL_OFFSET_Y)); - SV_WriteShort(P_GetIntp(si, DMU_MIDDLE_MATERIAL_OFFSET_X)); - SV_WriteShort(P_GetIntp(si, DMU_MIDDLE_MATERIAL_OFFSET_Y)); - SV_WriteShort(P_GetIntp(si, DMU_BOTTOM_MATERIAL_OFFSET_X)); - SV_WriteShort(P_GetIntp(si, DMU_BOTTOM_MATERIAL_OFFSET_Y)); + Writer_WriteInt16(writer, P_GetIntp(si, DMU_TOP_MATERIAL_OFFSET_X)); + Writer_WriteInt16(writer, P_GetIntp(si, DMU_TOP_MATERIAL_OFFSET_Y)); + Writer_WriteInt16(writer, P_GetIntp(si, DMU_MIDDLE_MATERIAL_OFFSET_X)); + Writer_WriteInt16(writer, P_GetIntp(si, DMU_MIDDLE_MATERIAL_OFFSET_Y)); + Writer_WriteInt16(writer, P_GetIntp(si, DMU_BOTTOM_MATERIAL_OFFSET_X)); + Writer_WriteInt16(writer, P_GetIntp(si, DMU_BOTTOM_MATERIAL_OFFSET_Y)); - SV_WriteShort(P_GetIntp(si, DMU_TOP_FLAGS)); - SV_WriteShort(P_GetIntp(si, DMU_MIDDLE_FLAGS)); - SV_WriteShort(P_GetIntp(si, DMU_BOTTOM_FLAGS)); + Writer_WriteInt16(writer, P_GetIntp(si, DMU_TOP_FLAGS)); + Writer_WriteInt16(writer, P_GetIntp(si, DMU_MIDDLE_FLAGS)); + Writer_WriteInt16(writer, P_GetIntp(si, DMU_BOTTOM_FLAGS)); - SV_WriteShort(MaterialArchive_FindUniqueSerialId(materialArchive, (Material *)P_GetPtrp(si, DMU_TOP_MATERIAL))); - SV_WriteShort(MaterialArchive_FindUniqueSerialId(materialArchive, (Material *)P_GetPtrp(si, DMU_BOTTOM_MATERIAL))); - SV_WriteShort(MaterialArchive_FindUniqueSerialId(materialArchive, (Material *)P_GetPtrp(si, DMU_MIDDLE_MATERIAL))); + Writer_WriteInt16(writer, MaterialArchive_FindUniqueSerialId(materialArchive, (Material *)P_GetPtrp(si, DMU_TOP_MATERIAL))); + Writer_WriteInt16(writer, MaterialArchive_FindUniqueSerialId(materialArchive, (Material *)P_GetPtrp(si, DMU_BOTTOM_MATERIAL))); + Writer_WriteInt16(writer, MaterialArchive_FindUniqueSerialId(materialArchive, (Material *)P_GetPtrp(si, DMU_MIDDLE_MATERIAL))); P_GetFloatpv(si, DMU_TOP_COLOR, rgba); for(int k = 0; k < 3; ++k) - SV_WriteByte((byte)(255 * rgba[k])); + Writer_WriteByte(writer, (byte)(255 * rgba[k])); P_GetFloatpv(si, DMU_BOTTOM_COLOR, rgba); for(int k = 0; k < 3; ++k) - SV_WriteByte((byte)(255 * rgba[k])); + Writer_WriteByte(writer, (byte)(255 * rgba[k])); P_GetFloatpv(si, DMU_MIDDLE_COLOR, rgba); for(int k = 0; k < 4; ++k) - SV_WriteByte((byte)(255 * rgba[k])); + Writer_WriteByte(writer, (byte)(255 * rgba[k])); - SV_WriteLong(P_GetIntp(si, DMU_MIDDLE_BLENDMODE)); - SV_WriteShort(P_GetIntp(si, DMU_FLAGS)); + Writer_WriteInt32(writer, P_GetIntp(si, DMU_MIDDLE_BLENDMODE)); + Writer_WriteInt16(writer, P_GetIntp(si, DMU_FLAGS)); } #if !__JHEXEN__ @@ -2927,21 +2927,21 @@ static void readMapElements(Reader *reader, int mapVersion) } #if __JHEXEN__ -static void SV_WriteMovePoly(polyevent_t const *th) +static void SV_WriteMovePoly(polyevent_t const *th, Writer *writer) { DENG_ASSERT(th != 0); - SV_WriteByte(1); // Write a version byte. + Writer_WriteByte(writer, 1); // Write a version byte. // Note we don't bother to save a byte to tell if the function // is present as we ALWAYS add one when loading. - SV_WriteLong(th->polyobj); - SV_WriteLong(th->intSpeed); - SV_WriteLong(th->dist); - SV_WriteLong(th->fangle); - SV_WriteLong(FLT2FIX(th->speed[VX])); - SV_WriteLong(FLT2FIX(th->speed[VY])); + Writer_WriteInt32(writer, th->polyobj); + Writer_WriteInt32(writer, th->intSpeed); + Writer_WriteInt32(writer, th->dist); + Writer_WriteInt32(writer, th->fangle); + Writer_WriteInt32(writer, FLT2FIX(th->speed[VX])); + Writer_WriteInt32(writer, FLT2FIX(th->speed[VY])); } static int SV_ReadMovePoly(polyevent_t *th, Reader *reader, int mapVersion) @@ -3009,8 +3009,8 @@ static int writeThinker(thinker_t *th, void *context) return false; // Write the header block for this thinker. - SV_WriteByte(thInfo->thinkclass); // Thinker type byte. - SV_WriteByte(th->inStasis? 1 : 0); // In stasis? + Writer_WriteByte(writer, thInfo->thinkclass); // Thinker type byte. + Writer_WriteByte(writer, th->inStasis? 1 : 0); // In stasis? // Write the thinker data. thInfo->writeFunc(th, writer); @@ -3031,13 +3031,13 @@ static void writeThinkers(Writer *writer) SV_BeginSegment(ASEG_THINKERS); { #if __JHEXEN__ - SV_WriteLong(thingArchiveSize); // number of mobjs. + Writer_WriteInt32(writer, thingArchiveSize); // number of mobjs. #endif // Serialize qualifying thinkers. Thinker_Iterate(0/*all thinkers*/, writeThinker, writer); } - SV_WriteByte(TC_END); + Writer_WriteByte(writer, TC_END); } static int restoreMobjLinks(thinker_t *th, void *parameters) @@ -3408,7 +3408,7 @@ static void writeSoundTargets(Writer *writer) if(!IS_SERVER) return; // Write the total number. - SV_WriteLong(numSoundTargets); + Writer_WriteInt32(writer, numSoundTargets); // Write the mobj references using the mobj archive. for(int i = 0; i < numsectors; ++i) @@ -3417,8 +3417,8 @@ static void writeSoundTargets(Writer *writer) if(xsec->soundTarget) { - SV_WriteLong(i); - SV_WriteShort(SV_ThingArchiveId(xsec->soundTarget)); + Writer_WriteInt32(writer, i); + Writer_WriteInt16(writer, SV_ThingArchiveId(xsec->soundTarget)); } } #endif @@ -3461,7 +3461,7 @@ static void writeMisc(Writer *writer) for(int i = 0; i < MAXPLAYERS; ++i) { - SV_WriteLong(localQuakeHappening[i]); + Writer_WriteInt32(writer, localQuakeHappening[i]); } #endif } @@ -3488,10 +3488,10 @@ static void writeMap(Writer *writer) SV_BeginSegment(ASEG_MAP_HEADER2); { #if __JHEXEN__ - SV_WriteByte(MY_SAVE_VERSION); // Map version also. + Writer_WriteByte(writer, MY_SAVE_VERSION); // Map version also. // Write the map timer - SV_WriteLong(mapTime); + Writer_WriteInt32(writer, mapTime); #endif MaterialArchive_Write(materialArchive, writer); @@ -3928,13 +3928,13 @@ void SV_SaveGameClient(uint gameId) // Some important information. // Our position and look angles. - SV_WriteLong(FLT2FIX(mo->origin[VX])); - SV_WriteLong(FLT2FIX(mo->origin[VY])); - SV_WriteLong(FLT2FIX(mo->origin[VZ])); - SV_WriteLong(FLT2FIX(mo->floorZ)); - SV_WriteLong(FLT2FIX(mo->ceilingZ)); - SV_WriteLong(mo->angle); /* $unifiedangles */ - SV_WriteFloat(pl->plr->lookDir); /* $unifiedangles */ + Writer_WriteInt32(writer, FLT2FIX(mo->origin[VX])); + Writer_WriteInt32(writer, FLT2FIX(mo->origin[VY])); + Writer_WriteInt32(writer, FLT2FIX(mo->origin[VZ])); + Writer_WriteInt32(writer, FLT2FIX(mo->floorZ)); + Writer_WriteInt32(writer, FLT2FIX(mo->ceilingZ)); + Writer_WriteInt32(writer, mo->angle); /* $unifiedangles */ + Writer_WriteFloat(writer, pl->plr->lookDir); /* $unifiedangles */ writePlayerHeader(writer); SV_WritePlayer(CONSOLEPLAYER, writer); @@ -4100,7 +4100,7 @@ static int saveStateWorker(Str const *path, SaveInfo *saveInfo) initThingArchiveForSave(); #if !__JHEXEN__ - SV_WriteLong(thingArchiveSize); + Writer_WriteInt32(writer, thingArchiveSize); #endif // Create and populate the MaterialArchive. diff --git a/doomsday/plugins/common/src/p_saveio.c b/doomsday/plugins/common/src/p_saveio.c index 136d1aa39e..dbc0b94809 100644 --- a/doomsday/plugins/common/src/p_saveio.c +++ b/doomsday/plugins/common/src/p_saveio.c @@ -224,66 +224,6 @@ dd_bool SV_HxBytesLeft(void) } #endif -void SV_AssertSegment(int segmentId) -{ - errorIfNotInited("SV_AssertSegment"); -#if __JHEXEN__ - if(segmentId == ASEG_END && SV_HxBytesLeft() < 4) - { - App_Log(DE2_LOG_WARNING, "Savegame lacks ASEG_END marker (unexpected end-of-file)\n"); - return; - } - if(SV_ReadLong() != segmentId) - { - Con_Error("Corrupt save game: Segment [%d] failed alignment check", segmentId); - } -#endif -} - -void SV_AssertMapSegment(savestatesegment_t *retSegmentId) -{ -#if __JHEXEN__ - int segmentId = SV_ReadLong(); - if(segmentId != ASEG_MAP_HEADER2 && segmentId != ASEG_MAP_HEADER) - Con_Error("Corrupt save game: Segment [%d] failed alignment check", segmentId); - - if(retSegmentId) *retSegmentId = segmentId; -#else - SV_AssertSegment(ASEG_MAP_HEADER2); - if(retSegmentId) *retSegmentId = ASEG_MAP_HEADER2; -#endif -} - -void SV_BeginSegment(int segType) -{ - errorIfNotInited("SV_BeginSegment"); -#if __JHEXEN__ - SV_WriteLong(segType); -#endif -} - -void SV_EndSegment() -{ - SV_BeginSegment(ASEG_END); -} - -void SV_WriteConsistencyBytes() -{ -#if !__JHEXEN__ - SV_WriteByte(CONSISTENCY); -#endif -} - -void SV_ReadConsistencyBytes() -{ -#if !__JHEXEN__ - if(SV_ReadByte() != CONSISTENCY) - { - Con_Error("Corrupt save game: Consistency test failed."); - } -#endif -} - void SV_Seek(uint offset) { errorIfNotInited("SV_SetPos"); @@ -397,6 +337,66 @@ float SV_ReadFloat(void) #endif } +void SV_AssertSegment(int segmentId) +{ + errorIfNotInited("SV_AssertSegment"); +#if __JHEXEN__ + if(segmentId == ASEG_END && SV_HxBytesLeft() < 4) + { + App_Log(DE2_LOG_WARNING, "Savegame lacks ASEG_END marker (unexpected end-of-file)\n"); + return; + } + if(SV_ReadLong() != segmentId) + { + Con_Error("Corrupt save game: Segment [%d] failed alignment check", segmentId); + } +#endif +} + +void SV_AssertMapSegment(savestatesegment_t *retSegmentId) +{ +#if __JHEXEN__ + int segmentId = SV_ReadLong(); + if(segmentId != ASEG_MAP_HEADER2 && segmentId != ASEG_MAP_HEADER) + Con_Error("Corrupt save game: Segment [%d] failed alignment check", segmentId); + + if(retSegmentId) *retSegmentId = segmentId; +#else + SV_AssertSegment(ASEG_MAP_HEADER2); + if(retSegmentId) *retSegmentId = ASEG_MAP_HEADER2; +#endif +} + +void SV_BeginSegment(int segType) +{ + errorIfNotInited("SV_BeginSegment"); +#if __JHEXEN__ + SV_WriteLong(segType); +#endif +} + +void SV_EndSegment() +{ + SV_BeginSegment(ASEG_END); +} + +void SV_WriteConsistencyBytes() +{ +#if !__JHEXEN__ + SV_WriteByte(CONSISTENCY); +#endif +} + +void SV_ReadConsistencyBytes() +{ +#if !__JHEXEN__ + if(SV_ReadByte() != CONSISTENCY) + { + Con_Error("Corrupt save game: Consistency test failed."); + } +#endif +} + static void swi8(Writer* w, char i) { if(!w) return; diff --git a/doomsday/plugins/common/src/p_xgsave.cpp b/doomsday/plugins/common/src/p_xgsave.cpp index 765f5b0245..4136fe6eb6 100644 --- a/doomsday/plugins/common/src/p_xgsave.cpp +++ b/doomsday/plugins/common/src/p_xgsave.cpp @@ -31,7 +31,7 @@ void SV_WriteXGLine(Line *li, Writer *writer) xline_t *xline = P_ToXLine(li); // Version byte. - SV_WriteByte(1); + Writer_WriteByte(writer, 1); /* * Remember, savegames are applied on top of an initialized map. No strings are saved, From 2a934f1f0aec48b2e4225cf771fb820774c9e3e6 Mon Sep 17 00:00:00 2001 From: danij Date: Fri, 31 Jan 2014 21:50:29 +0000 Subject: [PATCH 032/106] Fixed|libcommon: Compiler warnings (unused parameters) --- doomsday/plugins/common/src/p_ceiling.cpp | 2 +- doomsday/plugins/common/src/p_door.cpp | 2 +- doomsday/plugins/common/src/p_floor.cpp | 10 +++++----- doomsday/plugins/common/src/p_plat.cpp | 4 ++-- doomsday/plugins/common/src/p_scroll.cpp | 4 +++- doomsday/plugins/common/src/p_switch.cpp | 8 ++++++-- doomsday/plugins/common/src/p_xgsave.cpp | 4 ++-- doomsday/plugins/doom/src/p_lights.cpp | 2 +- doomsday/plugins/doom64/src/p_lights.cpp | 4 ++-- doomsday/plugins/hexen/src/acscript.cpp | 6 ++++++ doomsday/plugins/hexen/src/p_lights.cpp | 2 +- doomsday/plugins/hexen/src/p_pillar.cpp | 2 +- 12 files changed, 31 insertions(+), 19 deletions(-) diff --git a/doomsday/plugins/common/src/p_ceiling.cpp b/doomsday/plugins/common/src/p_ceiling.cpp index 7b24af233f..4ebba0e483 100644 --- a/doomsday/plugins/common/src/p_ceiling.cpp +++ b/doomsday/plugins/common/src/p_ceiling.cpp @@ -506,7 +506,7 @@ static int EV_DoCeiling2(int tag, float basespeed, ceilingtype_e type) } #if __JHEXEN__ -int EV_DoCeiling(Line *line, byte *args, ceilingtype_e type) +int EV_DoCeiling(Line * /*line*/, byte *args, ceilingtype_e type) #else int EV_DoCeiling(Line *line, ceilingtype_e type) #endif diff --git a/doomsday/plugins/common/src/p_door.cpp b/doomsday/plugins/common/src/p_door.cpp index 8bb4375f75..b3da08ba74 100644 --- a/doomsday/plugins/common/src/p_door.cpp +++ b/doomsday/plugins/common/src/p_door.cpp @@ -467,7 +467,7 @@ static int EV_DoDoor2(int tag, float speed, int topwait, doortype_e type) } #if __JHEXEN__ -int EV_DoDoor(Line *line, byte *args, doortype_e type) +int EV_DoDoor(Line * /*line*/, byte *args, doortype_e type) { return EV_DoDoor2((int) args[0], (float) args[1] * (1.0 / 8), (int) args[2], type); diff --git a/doomsday/plugins/common/src/p_floor.cpp b/doomsday/plugins/common/src/p_floor.cpp index f371cf7821..bae76a8fdd 100644 --- a/doomsday/plugins/common/src/p_floor.cpp +++ b/doomsday/plugins/common/src/p_floor.cpp @@ -663,9 +663,9 @@ static Sector *findSectorSurroundingAtFloorHeight(Sector *sec, coord_t height) #endif #if __JHEXEN__ -int EV_DoFloor(Line* line, byte* args, floortype_e floortype) +int EV_DoFloor(Line * /*line*/, byte* args, floortype_e floortype) #else -int EV_DoFloor(Line* line, floortype_e floortype) +int EV_DoFloor(Line *line, floortype_e floortype) #endif { #if !__JHEXEN__ @@ -1323,10 +1323,10 @@ static void processStairSector(Sector *sec, int type, coord_t height, #endif /** - * @param direction Positive = up. Negative = down. + * @param direction Positive = up. Negative = down. */ #if __JHEXEN__ -int EV_BuildStairs(Line *line, byte *args, int direction, stairs_e stairsType) +int EV_BuildStairs(Line * /*line*/, byte *args, int direction, stairs_e stairsType) { // Set global stairs variables stairData.textureChange = 0; @@ -1505,7 +1505,7 @@ static int stopFloorCrush(thinker_t *th, void *context) return false; // Continue iteration. } -int EV_FloorCrushStop(Line *line, byte *args) +int EV_FloorCrushStop(Line * /*line*/, byte * /*args*/) { dd_bool found = false; diff --git a/doomsday/plugins/common/src/p_plat.cpp b/doomsday/plugins/common/src/p_plat.cpp index 72d778772e..fbfd1bcb2f 100644 --- a/doomsday/plugins/common/src/p_plat.cpp +++ b/doomsday/plugins/common/src/p_plat.cpp @@ -292,9 +292,9 @@ int plat_t::read(Reader *reader, int mapVersion) } #if __JHEXEN__ -static int doPlat(Line* line, int tag, byte* args, plattype_e type, int amount) +static int doPlat(Line * /*line*/, int tag, byte *args, plattype_e type, int /*amount*/) #else -static int doPlat(Line* line, int tag, plattype_e type, int amount) +static int doPlat(Line *line, int tag, plattype_e type, int amount) #endif { #if !__JHEXEN__ diff --git a/doomsday/plugins/common/src/p_scroll.cpp b/doomsday/plugins/common/src/p_scroll.cpp index 1f9deef0a5..831dce7561 100644 --- a/doomsday/plugins/common/src/p_scroll.cpp +++ b/doomsday/plugins/common/src/p_scroll.cpp @@ -357,7 +357,9 @@ scroll_t *P_SpawnSectorMaterialOriginScroller(Sector *sector, uint planeId, shor elementBits = 1 << planeId; return spawnMaterialOriginScroller(sector, elementBits, offset); -#endif // __JHERETIC__ || __JHEXEN__ +#else // !(__JHERETIC__ || __JHEXEN__) + DENG_UNUSED(special); +#endif return 0; diff --git a/doomsday/plugins/common/src/p_switch.cpp b/doomsday/plugins/common/src/p_switch.cpp index 3787a4942a..97d8a5c03a 100644 --- a/doomsday/plugins/common/src/p_switch.cpp +++ b/doomsday/plugins/common/src/p_switch.cpp @@ -390,10 +390,14 @@ static int chooseDefaultSound(switchlist_t const *info) /// @todo Get these defaults from switchinfo. #if __JHEXEN__ return info->soundID; -#elif __JHERETIC__ - return SFX_SWITCH; #else +# if __JHERETIC__ + return SFX_SWITCH; +# else return SFX_SWTCHN; +# endif + + DENG_UNUSED(info); #endif } diff --git a/doomsday/plugins/common/src/p_xgsave.cpp b/doomsday/plugins/common/src/p_xgsave.cpp index 4136fe6eb6..b2ce76d7e6 100644 --- a/doomsday/plugins/common/src/p_xgsave.cpp +++ b/doomsday/plugins/common/src/p_xgsave.cpp @@ -89,7 +89,7 @@ void SV_ReadXGLine(Line *li, Reader *reader, int /*mapVersion*/) /** * @param fn This function must belong to XG sector @a xg. */ -void SV_WriteXGFunction(xgsector_t *xg, function_t *fn, Writer *writer) +void SV_WriteXGFunction(xgsector_t * /*xg*/, function_t *fn, Writer *writer) { // Version byte. Writer_WriteByte(writer, 1); @@ -106,7 +106,7 @@ void SV_WriteXGFunction(xgsector_t *xg, function_t *fn, Writer *writer) /** * @param fn This function must belong to XG sector @a xg. */ -void SV_ReadXGFunction(xgsector_t *xg, function_t *fn, Reader *reader, int mapVersion) +void SV_ReadXGFunction(xgsector_t * /*xg*/, function_t *fn, Reader *reader, int /*mapVersion*/) { // Version byte. Reader_ReadByte(reader); diff --git a/doomsday/plugins/doom/src/p_lights.cpp b/doomsday/plugins/doom/src/p_lights.cpp index 840b63106b..f9948f087d 100644 --- a/doomsday/plugins/doom/src/p_lights.cpp +++ b/doomsday/plugins/doom/src/p_lights.cpp @@ -65,7 +65,7 @@ void fireflicker_t::write(Writer *writer) const * T_FireFlicker was added to save games in ver5, therefore we don't have * an old format to support. */ -int fireflicker_t::read(Reader *reader, int mapVersion) +int fireflicker_t::read(Reader *reader, int /*mapVersion*/) { /*int ver =*/ Reader_ReadByte(reader); // version byte. diff --git a/doomsday/plugins/doom64/src/p_lights.cpp b/doomsday/plugins/doom64/src/p_lights.cpp index 3af10dec80..3c30ec4587 100644 --- a/doomsday/plugins/doom64/src/p_lights.cpp +++ b/doomsday/plugins/doom64/src/p_lights.cpp @@ -62,7 +62,7 @@ void fireflicker_t::write(Writer *writer) const * T_FireFlicker was added to save games in ver5, therefore we don't have * an old format to support. */ -int fireflicker_t::read(Reader *reader, int mapVersion) +int fireflicker_t::read(Reader *reader, int /*mapVersion*/) { /*int ver =*/ Reader_ReadByte(reader); // version byte. @@ -255,7 +255,7 @@ void lightblink_t::write(Writer *writer) const * T_LightBlink was added to save games in ver5, therefore we don't have an * old format to support */ -int lightblink_t::read(Reader *reader, int mapVersion) +int lightblink_t::read(Reader *reader, int /*mapVersion*/) { /*int ver =*/ Reader_ReadByte(reader); // version byte. diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index 51a3dd3b73..83a5421f97 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -660,11 +660,13 @@ typedef CommandResult (*CommandFunc) (CommandArgs const &args); ACS_COMMAND(NOP) { + DENG_UNUSED(args); return Continue; } ACS_COMMAND(Terminate) { + DENG_UNUSED(args); return Terminate; } @@ -1360,6 +1362,7 @@ ACS_COMMAND(CaseGoto) ACS_COMMAND(BeginPrint) { + DENG_UNUSED(args); *PrintBuffer = 0; return Continue; } @@ -1387,6 +1390,7 @@ ACS_COMMAND(EndPrint) ACS_COMMAND(EndPrintBold) { + DENG_UNUSED(args); for(int i = 0; i < MAXPLAYERS; ++i) { if(players[i].plr->inGame) @@ -1909,6 +1913,8 @@ int ACScript::read(Reader *reader, int mapVersion) D_CMD(ScriptInfo) { + DENG_UNUSED(src); + int whichOne = argc == 2? atoi(argv[1]) : -1; for(int i = 0; i < interp.scriptCount(); ++i) diff --git a/doomsday/plugins/hexen/src/p_lights.cpp b/doomsday/plugins/hexen/src/p_lights.cpp index a75365e796..dbe011e505 100644 --- a/doomsday/plugins/hexen/src/p_lights.cpp +++ b/doomsday/plugins/hexen/src/p_lights.cpp @@ -174,7 +174,7 @@ int light_t::read(Reader *reader, int mapVersion) return true; // Add this thinker. } -dd_bool EV_SpawnLight(Line *line, byte *arg, lighttype_t type) +dd_bool EV_SpawnLight(Line * /*line*/, byte *arg, lighttype_t type) { int arg1, arg2, arg3, arg4; diff --git a/doomsday/plugins/hexen/src/p_pillar.cpp b/doomsday/plugins/hexen/src/p_pillar.cpp index 89d1b11a8c..b9c32d62d3 100644 --- a/doomsday/plugins/hexen/src/p_pillar.cpp +++ b/doomsday/plugins/hexen/src/p_pillar.cpp @@ -105,7 +105,7 @@ int pillar_t::read(Reader *reader, int mapVersion) return true; // Add this thinker. } -int EV_BuildPillar(Line *line, byte *args, dd_bool crush) +int EV_BuildPillar(Line * /*line*/, byte *args, dd_bool crush) { iterlist_t *list = P_GetSectorIterListForTag((int) args[0], false); if(!list) return 0; From ebeffc05cc5837186829385795677c4cc6f39894 Mon Sep 17 00:00:00 2001 From: danij Date: Fri, 31 Jan 2014 23:42:55 +0000 Subject: [PATCH 033/106] Console|Hexen: Improved output of "scriptinfo" --- doomsday/plugins/hexen/include/acscript.h | 25 +++- doomsday/plugins/hexen/src/acscript.cpp | 133 ++++++++++++++-------- doomsday/plugins/hexen/src/hconsole.c | 6 +- 3 files changed, 112 insertions(+), 52 deletions(-) diff --git a/doomsday/plugins/hexen/include/acscript.h b/doomsday/plugins/hexen/include/acscript.h index c7d48d6e8d..df2a37da93 100644 --- a/doomsday/plugins/hexen/include/acscript.h +++ b/doomsday/plugins/hexen/include/acscript.h @@ -100,6 +100,18 @@ class ACScriptInterpreter int mapVars[MAX_ACS_MAP_VARS]; int worldVars[MAX_ACS_WORLD_VARS]; + /// Logical script states: + enum ScriptState { + Inactive, + Running, + Suspended, + WaitingForTag, + WaitingForPolyobj, + WaitingForScript, + Terminating + }; + +public: ACScriptInterpreter(); /** @@ -177,6 +189,17 @@ class ACScriptInterpreter */ void scriptFinished(ACScript *script); + /** + * Composes the human-friendly, textual name of the identified @a scriptNumber. + */ + AutoStr *scriptName(int scriptNumber); + + /** + * Composes a human-friendly, styled, textual description of the current status + * of the identified @a scriptNumber. + */ + AutoStr *scriptDescription(int scriptNumber); + void writeWorldScriptData(Writer *writer); void readWorldScriptData(Reader *reader, int mapVersion); @@ -188,12 +211,12 @@ class ACScriptInterpreter BytecodeScriptInfo &scriptInfoFor(ACScript *script); +private: /** * Returns the logical index of a @a scriptNumber; otherwise @c -1. */ int scriptInfoIndex(int scriptNumber); -private: ACScript *newACScript(BytecodeScriptInfo &info, byte const args[4], int delayCount = 0); /** diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index 83a5421f97..13c2287b55 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -31,31 +31,6 @@ #include #include -enum ACScriptState -{ - Inactive, - Running, - Suspended, - WaitingForTag, - WaitingForPolyobj, - WaitingForScript, - Terminating -}; - -static char const *scriptStateAsText(ACScriptState state) -{ - char const *names[] = { - "Inactive", - "Running", - "Suspended", - "Waiting for tag", - "Waiting for polyobj", - "Waiting for script", - "Terminating" - }; - return names[state]; -} - /** * Bytecode header. Read directly from the map lump. */ @@ -84,7 +59,7 @@ struct BytecodeScriptInfo // Current state: /// @todo Move to a separate array, in ACScriptInterpreter - ACScriptState state; + ACScriptInterpreter::ScriptState state; int waitValue; }; @@ -600,7 +575,7 @@ void ACScriptInterpreter::readMapScriptData(Reader *reader, int /*mapVersion*/) { BytecodeScriptInfo &info = _scriptInfo[i]; - info.state = ACScriptState( Reader_ReadInt16(reader) ); + info.state = ScriptState( Reader_ReadInt16(reader) ); info.waitValue = Reader_ReadInt16(reader); } @@ -672,7 +647,7 @@ ACS_COMMAND(Terminate) ACS_COMMAND(Suspend) { - args.scriptInfo->state = Suspended; + args.scriptInfo->state = ACScriptInterpreter::Suspended; return Stop; } @@ -1117,28 +1092,28 @@ ACS_COMMAND(ThingCountDirect) ACS_COMMAND(TagWait) { args.scriptInfo->waitValue = S_POP(); - args.scriptInfo->state = WaitingForTag; + args.scriptInfo->state = ACScriptInterpreter::WaitingForTag; return Stop; } ACS_COMMAND(TagWaitDirect) { args.scriptInfo->waitValue = LONG(*S_PCODEPTR++); - args.scriptInfo->state = WaitingForTag; + args.scriptInfo->state = ACScriptInterpreter::WaitingForTag; return Stop; } ACS_COMMAND(PolyWait) { args.scriptInfo->waitValue = S_POP(); - args.scriptInfo->state = WaitingForPolyobj; + args.scriptInfo->state = ACScriptInterpreter::WaitingForPolyobj; return Stop; } ACS_COMMAND(PolyWaitDirect) { args.scriptInfo->waitValue = LONG(*S_PCODEPTR++); - args.scriptInfo->state = WaitingForPolyobj; + args.scriptInfo->state = ACScriptInterpreter::WaitingForPolyobj; return Stop; } @@ -1326,14 +1301,14 @@ ACS_COMMAND(LineSide) ACS_COMMAND(ScriptWait) { args.scriptInfo->waitValue = S_POP(); - args.scriptInfo->state = WaitingForScript; + args.scriptInfo->state = ACScriptInterpreter::WaitingForScript; return Stop; } ACS_COMMAND(ScriptWaitDirect) { args.scriptInfo->waitValue = LONG(*S_PCODEPTR++); - args.scriptInfo->state = WaitingForScript; + args.scriptInfo->state = ACScriptInterpreter::WaitingForScript; return Stop; } @@ -1745,13 +1720,13 @@ void ACScript::runTick() { ACScriptInterpreter &interp = interpreter(); BytecodeScriptInfo &info = interp.scriptInfoFor(this); - if(info.state == Terminating) + if(info.state == ACScriptInterpreter::Terminating) { interp.scriptFinished(this); return; } - if(info.state != Running) + if(info.state != ACScriptInterpreter::Running) { return; } @@ -1796,11 +1771,7 @@ void ACScript::drop() stackPtr--; } -void ACScript_Thinker(ACScript *script) -{ - DENG_ASSERT(script != 0); - script->runTick(); -} + void ACScript::write(Writer *writer) const { @@ -1911,21 +1882,85 @@ int ACScript::read(Reader *reader, int mapVersion) return true; // Add this thinker. } -D_CMD(ScriptInfo) +AutoStr *ACScriptInterpreter::scriptName(int scriptNumber) +{ + BytecodeScriptInfo *info = scriptInfoPtr(scriptNumber); + if(!info) + { + return AutoStr_FromTextStd("(invalid-scriptnumber)"); + } + bool const open = (info->flags & BytecodeScriptInfo::Open) != 0; + return Str_Appendf(AutoStr_NewStd(), "#%i%s", scriptNumber, open? " (Open)" : ""); +} + +AutoStr *ACScriptInterpreter::scriptDescription(int scriptNumber) +{ + BytecodeScriptInfo *info = scriptInfoPtr(scriptNumber); + if(!info) + { + return AutoStr_FromTextStd("(invalid-scriptnumber)"); + } + + char const *stateLabels[] = { + "Inactive", + "Running", + "Suspended", + "Waiting for tag", + "Waiting for polyobj", + "Waiting for script", + "Terminating" + }; + + return Str_Appendf(AutoStr_NewStd(), "ACScript " DE2_ESC(b) "%s\n" + DE2_ESC(l) "State: " DE2_ESC(.) DE2_ESC(i) "%s" DE2_ESC(.) + DE2_ESC(l) " Wait-for: " DE2_ESC(.) DE2_ESC(i) "%i", + Str_Text(scriptName(scriptNumber)), + stateLabels[info->state], info->waitValue); +} + +void ACScript_Thinker(ACScript *script) +{ + DENG_ASSERT(script != 0); + script->runTick(); +} + +D_CMD(InspectACScript) { DENG_UNUSED(src); - int whichOne = argc == 2? atoi(argv[1]) : -1; + if(!interp.scriptCount()) + { + App_Log(DE2_SCR_MSG, "No ACScripts are currently loaded."); + return true; + } - for(int i = 0; i < interp.scriptCount(); ++i) + int whichOne = atoi(argv[1]); + if(!interp.hasScriptEntrypoint(whichOne)) { - BytecodeScriptInfo &info = interp.scriptInfoByIndex(i); + App_Log(DE2_SCR_WARNING, "Unknown ACScript #%i", whichOne); + return false; + } - if(whichOne != -1 && whichOne != info.scriptNumber) - continue; + App_Log(DE2_SCR_MSG, "%s", Str_Text(interp.scriptDescription(whichOne))); + return true; +} - App_Log(DE2_SCR_MSG, "%d %s (a: %d, w: %d)", info.scriptNumber, - scriptStateAsText(info.state), info.argCount, info.waitValue); +D_CMD(ListACScripts) +{ + DENG_UNUSED(src); + + if(!interp.scriptCount()) + { + App_Log(DE2_SCR_MSG, "No ACScripts are currently loaded."); + return true; + } + + App_Log(DE2_SCR_MSG, "Available ACScripts:"); + for(int i = 0; i < interp.scriptCount(); ++i) + { + BytecodeScriptInfo &info = interp.scriptInfoByIndex(i); + App_Log(DE2_SCR_MSG, "%s - args: %i", + Str_Text(interp.scriptName(info.scriptNumber)), info.argCount); } return true; diff --git a/doomsday/plugins/hexen/src/hconsole.c b/doomsday/plugins/hexen/src/hconsole.c index 6db4b02178..eab601708c 100644 --- a/doomsday/plugins/hexen/src/hconsole.c +++ b/doomsday/plugins/hexen/src/hconsole.c @@ -56,7 +56,8 @@ D_CMD(SpawnMobj); D_CMD(PrintPlayerCoords); -D_CMD(ScriptInfo); +D_CMD(InspectACScript); +D_CMD(ListACScripts); D_CMD(Test); D_CMD(MovePlane); D_CMD(ScreenShot); @@ -173,7 +174,8 @@ ccmdtemplate_t gameCCmds[] = { // Hexen specific {"pig", NULL, CCmdCheatMorph}, {"runscript", "i*", CCmdCheatRunScript}, - {"scriptinfo", NULL, CCmdScriptInfo}, + {"scriptinfo", "i", CCmdInspectACScript}, + {"scriptinfo", "", CCmdListACScripts}, {"class", "i*", CCmdCheatShadowcaster}, {NULL} }; From e722576503053640f072197006f69d6dd9cb9de6 Mon Sep 17 00:00:00 2001 From: danij Date: Sat, 1 Feb 2014 00:29:06 +0000 Subject: [PATCH 034/106] ACS|Hexen: Cleanup --- doomsday/plugins/common/src/g_game.c | 4 +- doomsday/plugins/common/src/p_ceiling.cpp | 2 +- doomsday/plugins/common/src/p_door.cpp | 4 +- doomsday/plugins/common/src/p_floor.cpp | 4 +- doomsday/plugins/common/src/p_map.cpp | 4 +- doomsday/plugins/common/src/p_mapsetup.cpp | 13 ++- doomsday/plugins/common/src/p_plat.cpp | 2 +- doomsday/plugins/common/src/p_saveg.cpp | 8 +- doomsday/plugins/common/src/polyobjs.cpp | 2 +- doomsday/plugins/hexen/include/acscript.h | 28 ++---- doomsday/plugins/hexen/src/acscript.cpp | 111 +++++++-------------- doomsday/plugins/hexen/src/m_cheat.c | 2 +- doomsday/plugins/hexen/src/p_enemy.c | 12 +-- doomsday/plugins/hexen/src/p_inter.c | 43 ++++---- doomsday/plugins/hexen/src/p_pillar.cpp | 2 +- doomsday/plugins/hexen/src/p_spec.c | 8 +- doomsday/plugins/hexen/src/p_waggle.cpp | 2 +- 17 files changed, 112 insertions(+), 139 deletions(-) diff --git a/doomsday/plugins/common/src/g_game.c b/doomsday/plugins/common/src/g_game.c index 8e375af4eb..2b34c95f9c 100644 --- a/doomsday/plugins/common/src/g_game.c +++ b/doomsday/plugins/common/src/g_game.c @@ -2183,7 +2183,7 @@ static void G_InitNewGame(void) SV_ClearSlot(AUTO_SLOT); #if __JHEXEN__ - P_InitACScript(); + Game_InitACScriptsForNewGame(); #endif } @@ -2726,7 +2726,7 @@ void G_DoLeaveMap(void) randomClassParm = oldRandomClassParm; // Launch waiting scripts. - P_ACScriptRunDeferredTasks(gameMap/*p.mapUri*/); + Game_ACScriptInterpreter_RunDeferredTasks(gameMap/*p.mapUri*/); #endif Uri_Delete(p.mapUri); diff --git a/doomsday/plugins/common/src/p_ceiling.cpp b/doomsday/plugins/common/src/p_ceiling.cpp index 4ebba0e483..13acc459ba 100644 --- a/doomsday/plugins/common/src/p_ceiling.cpp +++ b/doomsday/plugins/common/src/p_ceiling.cpp @@ -57,7 +57,7 @@ static void stopCeiling(ceiling_t *ceiling) { P_ToXSector(ceiling->sector)->specialData = 0; #if __JHEXEN__ - P_ACScriptTagFinished(P_ToXSector(ceiling->sector)->tag); + Game_ACScriptInterpreter().tagFinished(P_ToXSector(ceiling->sector)->tag); #endif Thinker_Remove(&ceiling->thinker); } diff --git a/doomsday/plugins/common/src/p_door.cpp b/doomsday/plugins/common/src/p_door.cpp index b3da08ba74..be7644e4fd 100644 --- a/doomsday/plugins/common/src/p_door.cpp +++ b/doomsday/plugins/common/src/p_door.cpp @@ -185,7 +185,7 @@ void T_Door(void *doorThinkerPtr) case DT_CLOSE: xsec->specialData = 0; #if __JHEXEN__ - P_ACScriptTagFinished(P_ToXSector(door->sector)->tag); + Game_ACScriptInterpreter().tagFinished(P_ToXSector(door->sector)->tag); #endif Thinker_Remove(&door->thinker); // Unlink and free. #if __JHERETIC__ @@ -266,7 +266,7 @@ void T_Door(void *doorThinkerPtr) case DT_OPEN: xsec->specialData = 0; #if __JHEXEN__ - P_ACScriptTagFinished(P_ToXSector(door->sector)->tag); + Game_ACScriptInterpreter().tagFinished(P_ToXSector(door->sector)->tag); #endif Thinker_Remove(&door->thinker); // Unlink and free. #if __JHERETIC__ diff --git a/doomsday/plugins/common/src/p_floor.cpp b/doomsday/plugins/common/src/p_floor.cpp index bae76a8fdd..d1c8dcba55 100644 --- a/doomsday/plugins/common/src/p_floor.cpp +++ b/doomsday/plugins/common/src/p_floor.cpp @@ -389,7 +389,7 @@ void T_MoveFloor(void *floorThinkerPtr) } #endif #if __JHEXEN__ - P_ACScriptTagFinished(P_ToXSector(floor->sector)->tag); + Game_ACScriptInterpreter().tagFinished(P_ToXSector(floor->sector)->tag); #endif Thinker_Remove(&floor->thinker); } @@ -1497,7 +1497,7 @@ static int stopFloorCrush(thinker_t *th, void *context) // Completely remove the crushing floor SN_StopSequence((mobj_t *)P_GetPtrp(floor->sector, DMU_EMITTER)); P_ToXSector(floor->sector)->specialData = NULL; - P_ACScriptTagFinished(P_ToXSector(floor->sector)->tag); + Game_ACScriptInterpreter().tagFinished(P_ToXSector(floor->sector)->tag); Thinker_Remove(&floor->thinker); (*found) = true; } diff --git a/doomsday/plugins/common/src/p_map.cpp b/doomsday/plugins/common/src/p_map.cpp index 0388f34668..561f0e7c6e 100644 --- a/doomsday/plugins/common/src/p_map.cpp +++ b/doomsday/plugins/common/src/p_map.cpp @@ -3195,7 +3195,7 @@ static int PTR_PuzzleItemTraverse(Intercept const *icpt, void *context) return true; // Item type doesn't match. } - P_StartACScript(xline->arg2, 0, &xline->arg3, parm.useMobj, icpt->line, 0); + Game_ACScriptInterpreter_StartScript(xline->arg2, 0, &xline->arg3, parm.useMobj, icpt->line, 0); xline->special = 0; parm.activated = true; @@ -3214,7 +3214,7 @@ static int PTR_PuzzleItemTraverse(Intercept const *icpt, void *context) return false; // Item type doesn't match... } - P_StartACScript(icpt->mobj->args[1], 0, &icpt->mobj->args[2], parm.useMobj, NULL, 0); + Game_ACScriptInterpreter_StartScript(icpt->mobj->args[1], 0, &icpt->mobj->args[2], parm.useMobj, NULL, 0); icpt->mobj->special = 0; parm.activated = true; diff --git a/doomsday/plugins/common/src/p_mapsetup.cpp b/doomsday/plugins/common/src/p_mapsetup.cpp index 241c496120..4d832a5077 100644 --- a/doomsday/plugins/common/src/p_mapsetup.cpp +++ b/doomsday/plugins/common/src/p_mapsetup.cpp @@ -866,7 +866,18 @@ void P_FinalizeMapChange(Uri const *uri) #if __JHEXEN__ /// @todo Should be interpreted by the map converter. - P_LoadACScripts(W_GetLumpNumForName(Str_Text(Uri_Path(uri))) + 11 /*ML_BEHAVIOR*/); // ACS object code + lumpnum_t acsLumpNum = W_CheckLumpNumForName(Str_Text(Uri_Path(uri))) + 11 /*ML_BEHAVIOR*/; + if(acsLumpNum >= 0 && !IS_CLIENT) + { + ACScriptInterpreter &interp = Game_ACScriptInterpreter(); + + interp.loadBytecode(acsLumpNum); + + memset(interp.mapVars, 0, sizeof(interp.mapVars)); + + // Start all scripts flagged to begin immediately. + interp.startOpenScripts(); + } #endif HU_UpdatePsprites(); diff --git a/doomsday/plugins/common/src/p_plat.cpp b/doomsday/plugins/common/src/p_plat.cpp index fbfd1bcb2f..600488f3f6 100644 --- a/doomsday/plugins/common/src/p_plat.cpp +++ b/doomsday/plugins/common/src/p_plat.cpp @@ -60,7 +60,7 @@ static void stopPlat(plat_t *plat) { P_ToXSector(plat->sector)->specialData = 0; #if __JHEXEN__ - P_ACScriptTagFinished(P_ToXSector(plat->sector)->tag); + Game_ACScriptInterpreter().tagFinished(P_ToXSector(plat->sector)->tag); #endif Thinker_Remove(&plat->thinker); } diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index a4817380e6..c03c80e50d 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -3498,7 +3498,7 @@ static void writeMap(Writer *writer) writeMapElements(writer); writeThinkers(writer); #if __JHEXEN__ - P_WriteMapACScriptData(writer); + Game_ACScriptInterpreter().writeMapScriptData(writer); SN_WriteSequences(writer); #endif writeMisc(writer); @@ -3537,7 +3537,7 @@ static void readMap(Reader *reader) readMapElements(reader, mapVersion); readThinkers(reader, mapVersion); #if __JHEXEN__ - P_ReadMapACScriptData(reader, mapVersion); + Game_ACScriptInterpreter().readMapScriptData(reader, mapVersion); SN_ReadSequences(reader, mapVersion); #endif readMisc(reader, mapVersion); @@ -3667,7 +3667,7 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) #endif #if __JHEXEN__ - P_ReadGlobalACScriptData(reader, hdr->version); + Game_ACScriptInterpreter().readWorldScriptData(reader, hdr->version); #endif /* @@ -4093,7 +4093,7 @@ static int saveStateWorker(Str const *path, SaveInfo *saveInfo) SaveInfo_Write(saveInfo, writer); #if __JHEXEN__ - P_WriteGlobalACScriptData(writer); + Game_ACScriptInterpreter().writeWorldScriptData(writer); #endif // Set the mobj archive numbers. diff --git a/doomsday/plugins/common/src/polyobjs.cpp b/doomsday/plugins/common/src/polyobjs.cpp index ed44f780da..e0f3e40172 100644 --- a/doomsday/plugins/common/src/polyobjs.cpp +++ b/doomsday/plugins/common/src/polyobjs.cpp @@ -57,7 +57,7 @@ static int findMirrorPolyobj(int tag) static void notifyPolyobjFinished(int tag) { #if __JHEXEN__ - P_ACScriptPolyobjFinished(tag); + Game_ACScriptInterpreter().polyobjFinished(tag); #else DENG_UNUSED(tag); #endif diff --git a/doomsday/plugins/hexen/include/acscript.h b/doomsday/plugins/hexen/include/acscript.h index df2a37da93..fd544bb0e4 100644 --- a/doomsday/plugins/hexen/include/acscript.h +++ b/doomsday/plugins/hexen/include/acscript.h @@ -242,8 +242,14 @@ class ACScriptInterpreter int _deferredTasksSize; DeferredTask *_deferredTasks; }; + +/// @return The game's global ACScript interpreter. +ACScriptInterpreter &Game_ACScriptInterpreter(); + #endif +// C wrapper API, for legacy modules ------------------------------------------- + #ifdef __cplusplus extern "C" { #endif @@ -251,27 +257,15 @@ extern "C" { /** * To be called when a new game session begins to initialize ACS scripting. */ -void P_InitACScript(void); - -void P_LoadACScripts(lumpnum_t lump); - -dd_bool P_StartACScript(int number, uint map, byte const args[4], mobj_t *activator, Line *line, int side); - -dd_bool P_TerminateACScript(int number, uint map); - -dd_bool P_SuspendACScript(int number, uint map); - -void P_ACScriptTagFinished(int tag); +void Game_InitACScriptsForNewGame(void); -void P_ACScriptPolyobjFinished(int tag); +dd_bool Game_ACScriptInterpreter_StartScript(int number, uint map, byte const args[4], mobj_t *activator, Line *line, int side); -void P_ACScriptRunDeferredTasks(uint map/*Uri const *map*/); +dd_bool Game_ACScriptInterpreter_TerminateScript(int number, uint map); -void P_WriteGlobalACScriptData(Writer *writer); -void P_ReadGlobalACScriptData(Reader *reader, int mapVersion); +dd_bool Game_ACScriptInterpreter_SuspendScript(int number, uint map); -void P_WriteMapACScriptData(Writer *writer); -void P_ReadMapACScriptData(Reader *reader, int mapVersion); +void Game_ACScriptInterpreter_RunDeferredTasks(uint map/*Uri const *map*/); #ifdef __cplusplus } // extern "C" diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index 13c2287b55..f6fbaa8dc4 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -602,9 +602,6 @@ static byte SpecArgs[5]; #define PRINT_BUFFER_SIZE 256 static char PrintBuffer[PRINT_BUFFER_SIZE]; -/// The One ACS interpreter instance. -static ACScriptInterpreter interp; - /// POD structure passed to bytecode commands. struct CommandArgs { @@ -1642,78 +1639,9 @@ static CommandFunc pcodeCmds[] = cmdThingSound, cmdEndPrintBold }; -void P_InitACScript() -{ - memset(interp.worldVars, 0, sizeof(interp.worldVars)); - interp.clearDeferredTasks(); -} - -void P_LoadACScripts(lumpnum_t lump) -{ - if(IS_CLIENT) return; - - interp.loadBytecode(lump); - - memset(interp.mapVars, 0, sizeof(interp.mapVars)); - - // Start all scripts flagged to begin immediately. - interp.startOpenScripts(); -} - -void P_ACScriptRunDeferredTasks(uint map/*Uri const *mapUri*/) -{ - interp.runDeferredTasks(map); -} - -dd_bool P_StartACScript(int scriptNumber, uint map, byte const args[], mobj_t *activator, - Line *line, int side) -{ - return interp.startScript(scriptNumber, map, args, activator, line, side); -} - -dd_bool P_TerminateACScript(int scriptNumber, uint map) -{ - return interp.terminateScript(scriptNumber, map); -} - -dd_bool P_SuspendACScript(int scriptNumber, uint map) -{ - return interp.suspendScript(scriptNumber, map); -} - -void P_ACScriptTagFinished(int tag) -{ - interp.tagFinished(tag); -} - -void P_ACScriptPolyobjFinished(int tag) -{ - interp.polyobjFinished(tag); -} - -void P_WriteGlobalACScriptData(Writer *writer) -{ - interp.writeWorldScriptData(writer); -} - -void P_ReadGlobalACScriptData(Reader *reader, int mapVersion) -{ - interp.readWorldScriptData(reader, mapVersion); -} - -void P_WriteMapACScriptData(Writer *writer) -{ - interp.writeMapScriptData(writer); -} - -void P_ReadMapACScriptData(Reader *reader, int mapVersion) -{ - interp.readMapScriptData(reader, mapVersion); -} - ACScriptInterpreter &ACScript::interpreter() const { - return interp; + return Game_ACScriptInterpreter(); } void ACScript::runTick() @@ -1771,8 +1699,6 @@ void ACScript::drop() stackPtr--; } - - void ACScript::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -1918,6 +1844,41 @@ AutoStr *ACScriptInterpreter::scriptDescription(int scriptNumber) stateLabels[info->state], info->waitValue); } +/// The One ACS interpreter instance. +static ACScriptInterpreter interp; + +ACScriptInterpreter &Game_ACScriptInterpreter() +{ + return interp; +} + +void Game_InitACScriptsForNewGame() +{ + memset(interp.worldVars, 0, sizeof(interp.worldVars)); + interp.clearDeferredTasks(); +} + +void Game_ACScriptInterpreter_RunDeferredTasks(uint map/*Uri const *mapUri*/) +{ + interp.runDeferredTasks(map); +} + +dd_bool Game_ACScriptInterpreter_StartScript(int scriptNumber, uint map, byte const args[], + mobj_t *activator, Line *line, int side) +{ + return interp.startScript(scriptNumber, map, args, activator, line, side); +} + +dd_bool Game_ACScriptInterpreter_TerminateScript(int scriptNumber, uint map) +{ + return interp.terminateScript(scriptNumber, map); +} + +dd_bool Game_ACScriptInterpreter_SuspendScript(int scriptNumber, uint map) +{ + return interp.suspendScript(scriptNumber, map); +} + void ACScript_Thinker(ACScript *script) { DENG_ASSERT(script != 0); diff --git a/doomsday/plugins/hexen/src/m_cheat.c b/doomsday/plugins/hexen/src/m_cheat.c index 1be80ae6e2..46527f9693 100644 --- a/doomsday/plugins/hexen/src/m_cheat.c +++ b/doomsday/plugins/hexen/src/m_cheat.c @@ -825,7 +825,7 @@ D_CMD(CheatRunScript) if(scriptNum < 1 || scriptNum > 99) return false; scriptArgs[0] = scriptArgs[1] = scriptArgs[2] = 0; - if(P_StartACScript(scriptNum, 0, scriptArgs, plr->plr->mo, NULL, 0)) + if(Game_ACScriptInterpreter_StartScript(scriptNum, 0, scriptArgs, plr->plr->mo, NULL, 0)) { AutoStr *cmd = Str_Appendf(AutoStr_NewStd(), "Running script %i", scriptNum); P_SetMessage(plr, LMF_NO_HIDE, Str_Text(cmd)); diff --git a/doomsday/plugins/hexen/src/p_enemy.c b/doomsday/plugins/hexen/src/p_enemy.c index 9fdcae8de7..55e5b6684b 100644 --- a/doomsday/plugins/hexen/src/p_enemy.c +++ b/doomsday/plugins/hexen/src/p_enemy.c @@ -4231,9 +4231,9 @@ void C_DECL A_FreezeDeathChunks(mobj_t* mo) * 255 For use in death script (spawn spots). */ -void C_DECL A_KoraxChase(mobj_t* actor) +void C_DECL A_KoraxChase(mobj_t *actor) { - mobj_t* spot; + mobj_t *spot; byte args[3] = { 0, 0, 0 }; if(!actor->special2 && actor->health <= actor->info->spawnHealth / 2) @@ -4245,7 +4245,7 @@ void C_DECL A_KoraxChase(mobj_t* actor) P_Teleport(actor, spot->origin[VX], spot->origin[VY], spot->angle, true); } - P_StartACScript(249, 0, args, actor, NULL, 0); + Game_ACScriptInterpreter_StartScript(249, 0, args, actor, NULL, 0); actor->special2 = 1; // Don't run again. return; @@ -4264,7 +4264,7 @@ void C_DECL A_KoraxChase(mobj_t* actor) } // Teleport away. - if(actor->health < actor->info->spawnHealth >> 1) + if(actor->health < actor->info->spawnHealth / 2) { if(P_Random() < 10) { @@ -4322,7 +4322,7 @@ void C_DECL A_KoraxBonePop(mobj_t* actor) if(mo) KSpiritInit(mo, actor); - P_StartACScript(255, 0, args, actor, NULL, 0); // Death script. + Game_ACScriptInterpreter_StartScript(255, 0, args, actor, NULL, 0); // Death script. } void KSpiritInit(mobj_t* spirit, mobj_t* korax) @@ -4510,7 +4510,7 @@ void C_DECL A_KoraxCommand(mobj_t* mo) } assert(scriptNumber >= 0); - P_StartACScript(scriptNumber, 0, args, mo, NULL, 0); + Game_ACScriptInterpreter_StartScript(scriptNumber, 0, args, mo, NULL, 0); } void C_DECL A_KSpiritWeave(mobj_t* mo) diff --git a/doomsday/plugins/hexen/src/p_inter.c b/doomsday/plugins/hexen/src/p_inter.c index f269144a8c..f03bdd8d2e 100644 --- a/doomsday/plugins/hexen/src/p_inter.c +++ b/doomsday/plugins/hexen/src/p_inter.c @@ -1425,11 +1425,11 @@ mobj_t* ActiveMinotaur(player_t* master) return NULL; } -void P_KillMobj(mobj_t* source, mobj_t* target) +void P_KillMobj(mobj_t *source, mobj_t *target) { - int dummy; - mobj_t* master; - statenum_t state; + int dummy; + mobj_t *master; + statenum_t state; if(!target) return; // Nothing to kill. @@ -1440,25 +1440,27 @@ void P_KillMobj(mobj_t* source, mobj_t* target) target->height /= 2*2; if((target->flags & MF_COUNTKILL || target->type == MT_ZBELL) && target->special) - { // Initiate monster death actions. + { + // Initiate monster death actions. if(target->type == MT_SORCBOSS) { dummy = 0; - P_StartACScript(target->special, 0, (byte *) &dummy, target, NULL, 0); + Game_ACScriptInterpreter_StartScript(target->special, 0, (byte *) &dummy, target, NULL, 0); } else { - P_ExecuteLineSpecial(target->special, target->args, NULL, 0, - target); + P_ExecuteLineSpecial(target->special, target->args, NULL, 0, target); } } if(source && source->player) - { // Check for frag changes. + { + // Check for frag changes. if(target->player && deathmatch) { if(target == source) - { // Self-frag. + { + // Self-frag. target->player->frags[target->player - players]--; NetSv_FragsForAll(target->player); } @@ -1471,9 +1473,11 @@ void P_KillMobj(mobj_t* source, mobj_t* target) } if(target->player) - { // Player death. + { + // Player death. if(!source) - { // Self-frag + { + // Self-frag target->player->frags[target->player - players]--; NetSv_FragsForAll(target->player); } @@ -1490,8 +1494,9 @@ void P_KillMobj(mobj_t* source, mobj_t* target) target->player->plr->flags |= DDPF_DEAD; P_DropWeapon(target->player); if(target->flags2 & MF2_FIREDAMAGE) - { // Player flame death. - //// \todo Should be pulled from the player class definition. + { + // Player flame death. + /// @todo Should be pulled from the player class definition. switch(target->player->class_) { case PCLASS_FIGHTER: @@ -1519,7 +1524,7 @@ void P_KillMobj(mobj_t* source, mobj_t* target) // Player ice death. target->flags &= ~MF_TRANSLATION; // no translation target->flags |= MF_ICECORPSE; - //// \todo Should be pulled from the player class definition. + /// @todo Should be pulled from the player class definition. switch(target->player->class_) { case PCLASS_FIGHTER: @@ -1557,7 +1562,7 @@ void P_KillMobj(mobj_t* source, mobj_t* target) * find MF_ targets->flags that indicated *only* enemies (not trees, * pots, etc), so built a list. * - * \todo This should be a Thing definition flag. + * @todo This should be a Thing definition flag. */ if(IS_NETGAME && !deathmatch && source && source->player && source->player->plr && (target->type == MT_CENTAUR || @@ -1694,11 +1699,13 @@ void P_KillMobj(mobj_t* source, mobj_t* target) if((state = P_GetState(target->type, SN_XDEATH)) != S_NULL && target->health < -(target->info->spawnHealth / 2)) - { // Extreme death. + { + // Extreme death. P_MobjChangeState(target, state); } else - { // Normal death. + { + // Normal death. if((state = P_GetState(target->type, SN_XDEATH)) != S_NULL && target->type == MT_FIREDEMON && target->origin[VZ] <= target->floorZ + 2) diff --git a/doomsday/plugins/hexen/src/p_pillar.cpp b/doomsday/plugins/hexen/src/p_pillar.cpp index b9c32d62d3..7aa2419d76 100644 --- a/doomsday/plugins/hexen/src/p_pillar.cpp +++ b/doomsday/plugins/hexen/src/p_pillar.cpp @@ -38,7 +38,7 @@ void T_BuildPillar(pillar_t *pillar) { P_ToXSector(pillar->sector)->specialData = 0; SN_StopSequenceInSec(pillar->sector); - P_ACScriptTagFinished(P_ToXSector(pillar->sector)->tag); + Game_ACScriptInterpreter().tagFinished(P_ToXSector(pillar->sector)->tag); Thinker_Remove(&pillar->thinker); } } diff --git a/doomsday/plugins/hexen/src/p_spec.c b/doomsday/plugins/hexen/src/p_spec.c index d5a885f445..ea3bd67fe8 100644 --- a/doomsday/plugins/hexen/src/p_spec.c +++ b/doomsday/plugins/hexen/src/p_spec.c @@ -241,7 +241,7 @@ dd_bool P_StartLockedACS(Line *line, byte *args, mobj_t *mo, int side) } newArgs[4] = 0; - return P_StartACScript(newArgs[0], newArgs[1], &newArgs[2], mo, line, side); + return Game_ACScriptInterpreter_StartScript(newArgs[0], newArgs[1], &newArgs[2], mo, line, side); } dd_bool P_ExecuteLineSpecial(int special, byte args[5], Line *line, int side, mobj_t *mo) @@ -518,15 +518,15 @@ dd_bool P_ExecuteLineSpecial(int special, byte args[5], Line *line, int side, mo break; case 80: // ACS_Execute - success = P_StartACScript(args[0], args[1], &args[2], mo, line, side); + success = Game_ACScriptInterpreter_StartScript(args[0], args[1], &args[2], mo, line, side); break; case 81: // ACS_Suspend - success = P_SuspendACScript(args[0], args[1]); + success = Game_ACScriptInterpreter_SuspendScript(args[0], args[1]); break; case 82: // ACS_Terminate - success = P_TerminateACScript(args[0], args[1]); + success = Game_ACScriptInterpreter_TerminateScript(args[0], args[1]); break; case 83: // ACS_LockedExecute diff --git a/doomsday/plugins/hexen/src/p_waggle.cpp b/doomsday/plugins/hexen/src/p_waggle.cpp index 406fc2ffd3..77e80234b2 100644 --- a/doomsday/plugins/hexen/src/p_waggle.cpp +++ b/doomsday/plugins/hexen/src/p_waggle.cpp @@ -59,7 +59,7 @@ void T_FloorWaggle(waggle_t *waggle) P_SetDoublep(waggle->sector, DMU_FLOOR_HEIGHT, waggle->originalHeight); P_ChangeSector(waggle->sector, 1 /*crush damage*/); P_ToXSector(waggle->sector)->specialData = NULL; - P_ACScriptTagFinished(P_ToXSector(waggle->sector)->tag); + Game_ACScriptInterpreter().tagFinished(P_ToXSector(waggle->sector)->tag); Thinker_Remove(&waggle->thinker); return; } From 662edcc45e93701656ad3ca6aa2a087f55dab692 Mon Sep 17 00:00:00 2001 From: danij Date: Sat, 1 Feb 2014 03:05:56 +0000 Subject: [PATCH 035/106] ACS|Hexen: Deferred script tasks now reference maps with URI --- doomsday/plugins/common/src/g_game.c | 26 +-- doomsday/plugins/common/src/p_map.cpp | 6 +- doomsday/plugins/common/src/p_mapsetup.cpp | 2 +- doomsday/plugins/hexen/include/acscript.h | 24 +-- doomsday/plugins/hexen/src/acscript.cpp | 185 +++++++++++---------- doomsday/plugins/hexen/src/m_cheat.c | 3 +- doomsday/plugins/hexen/src/p_enemy.c | 6 +- doomsday/plugins/hexen/src/p_inter.c | 3 +- doomsday/plugins/hexen/src/p_spec.c | 40 +++-- 9 files changed, 164 insertions(+), 131 deletions(-) diff --git a/doomsday/plugins/common/src/g_game.c b/doomsday/plugins/common/src/g_game.c index 2b34c95f9c..87016a6c8b 100644 --- a/doomsday/plugins/common/src/g_game.c +++ b/doomsday/plugins/common/src/g_game.c @@ -125,9 +125,9 @@ void G_DoReborn(int playernum); dd_bool G_StartDebriefing(); typedef struct { - Uri* mapUri; - uint episode; - uint map; + Uri *mapUri; + //uint episode; + //uint map; dd_bool revisit; } loadmap_params_t; int G_DoLoadMap(loadmap_params_t* params); @@ -2684,8 +2684,8 @@ void G_DoLeaveMap(void) #endif p.mapUri = G_ComposeMapUri(gameEpisode, nextMap); - p.episode = gameEpisode; - p.map = nextMap; + //p.episode = gameEpisode; + //p.map = nextMap; p.revisit = revisit; hasBrief = G_BriefingEnabled(p.mapUri, &fin); @@ -2694,7 +2694,7 @@ void G_DoLeaveMap(void) G_QueMapMusic(p.mapUri); } - gameMap = p.map; + gameMap = nextMap; // If we're the server, let clients know the map will change. NetSv_UpdateGameConfigDescription(); @@ -2726,7 +2726,7 @@ void G_DoLeaveMap(void) randomClassParm = oldRandomClassParm; // Launch waiting scripts. - Game_ACScriptInterpreter_RunDeferredTasks(gameMap/*p.mapUri*/); + Game_ACScriptInterpreter_RunDeferredTasks(p.mapUri); #endif Uri_Delete(p.mapUri); @@ -2767,8 +2767,8 @@ void G_DoRestartMap(void) DD_Executef(true, "texreset raw"); p.mapUri = G_ComposeMapUri(gameEpisode, gameMap); - p.episode = gameEpisode; - p.map = gameMap; + //p.episode = gameEpisode; + //p.map = gameMap; p.revisit = false; // Don't reload save state. // This is a restart, so we won't brief again. @@ -3038,10 +3038,10 @@ void G_NewGame(skillmode_t skill, uint episode, uint map, uint mapEntryPoint) dd_bool hasBrief; ddfinale_t fin; - p.mapUri = G_ComposeMapUri(gameEpisode, gameMap); - p.episode = gameEpisode; - p.map = gameMap; - p.revisit = false; + p.mapUri = G_ComposeMapUri(gameEpisode, gameMap); + //p.episode = gameEpisode; + //p.map = gameMap; + p.revisit = false; hasBrief = G_BriefingEnabled(p.mapUri, &fin); if(!hasBrief) diff --git a/doomsday/plugins/common/src/p_map.cpp b/doomsday/plugins/common/src/p_map.cpp index 561f0e7c6e..c55146f502 100644 --- a/doomsday/plugins/common/src/p_map.cpp +++ b/doomsday/plugins/common/src/p_map.cpp @@ -3195,7 +3195,8 @@ static int PTR_PuzzleItemTraverse(Intercept const *icpt, void *context) return true; // Item type doesn't match. } - Game_ACScriptInterpreter_StartScript(xline->arg2, 0, &xline->arg3, parm.useMobj, icpt->line, 0); + Game_ACScriptInterpreter_StartScript(xline->arg2, 0/*current-map*/, &xline->arg3, + parm.useMobj, icpt->line, 0); xline->special = 0; parm.activated = true; @@ -3214,7 +3215,8 @@ static int PTR_PuzzleItemTraverse(Intercept const *icpt, void *context) return false; // Item type doesn't match... } - Game_ACScriptInterpreter_StartScript(icpt->mobj->args[1], 0, &icpt->mobj->args[2], parm.useMobj, NULL, 0); + Game_ACScriptInterpreter_StartScript(icpt->mobj->args[1], 0/*current-map*/, + &icpt->mobj->args[2], parm.useMobj, NULL, 0); icpt->mobj->special = 0; parm.activated = true; diff --git a/doomsday/plugins/common/src/p_mapsetup.cpp b/doomsday/plugins/common/src/p_mapsetup.cpp index 4d832a5077..018649034b 100644 --- a/doomsday/plugins/common/src/p_mapsetup.cpp +++ b/doomsday/plugins/common/src/p_mapsetup.cpp @@ -865,7 +865,7 @@ void P_FinalizeMapChange(Uri const *uri) PO_InitForMap(); #if __JHEXEN__ - /// @todo Should be interpreted by the map converter. + /// @todo Should be translated by the map converter. lumpnum_t acsLumpNum = W_CheckLumpNumForName(Str_Text(Uri_Path(uri))) + 11 /*ML_BEHAVIOR*/; if(acsLumpNum >= 0 && !IS_CLIENT) { diff --git a/doomsday/plugins/hexen/include/acscript.h b/doomsday/plugins/hexen/include/acscript.h index fd544bb0e4..9cedd195ca 100644 --- a/doomsday/plugins/hexen/include/acscript.h +++ b/doomsday/plugins/hexen/include/acscript.h @@ -137,12 +137,12 @@ class ACScriptInterpreter * * @return @c true iff a script was newly started (or deferred). */ - bool startScript(int scriptNumber, uint map, byte const args[4], + bool startScript(int scriptNumber, Uri const *mapUri, byte const args[4], mobj_t *activator = 0, Line *line = 0, int side = 0); - bool suspendScript(int scriptNumber, uint map); + bool suspendScript(int scriptNumber, Uri const *mapUri); - bool terminateScript(int scriptNumber, uint map); + bool terminateScript(int scriptNumber, Uri const *mapUri); void tagFinished(int tag); void polyobjFinished(int tag); @@ -177,7 +177,7 @@ class ACScriptInterpreter * To be called when the current map changes to activate any deferred scripts * which should now begin/resume. */ - void runDeferredTasks(uint map/*Uri const *mapUri*/); + void runDeferredTasks(Uri const *mapUri); /** * To be called when the specified @a script is to be formally terminated. @@ -224,12 +224,15 @@ class ACScriptInterpreter */ struct DeferredTask { - uint map; ///< Target map. + Uri *mapUri; ///< Target map. int scriptNumber; ///< On the target map. byte args[4]; + + void write(Writer *write) const; + void read(Reader *reader, int segmentVersion); }; - bool newDeferredTask(uint map, int scriptNumber, byte const args[4]); + bool newDeferredTask(Uri const *mapUri, int scriptNumber, byte const args[4]); byte const *_pcode; ///< Start of the loaded bytecode. @@ -259,13 +262,14 @@ extern "C" { */ void Game_InitACScriptsForNewGame(void); -dd_bool Game_ACScriptInterpreter_StartScript(int number, uint map, byte const args[4], mobj_t *activator, Line *line, int side); +dd_bool Game_ACScriptInterpreter_StartScript(int scriptNumber, Uri const *mapUri, + byte const args[4], mobj_t *activator, Line *line, int side); -dd_bool Game_ACScriptInterpreter_TerminateScript(int number, uint map); +dd_bool Game_ACScriptInterpreter_TerminateScript(int scriptNumber, Uri const *mapUri); -dd_bool Game_ACScriptInterpreter_SuspendScript(int number, uint map); +dd_bool Game_ACScriptInterpreter_SuspendScript(int scriptNumber, Uri const *mapUri); -void Game_ACScriptInterpreter_RunDeferredTasks(uint map/*Uri const *map*/); +void Game_ACScriptInterpreter_RunDeferredTasks(Uri const *mapUri); #ifdef __cplusplus } // extern "C" diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index f6fbaa8dc4..d7d9907301 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -23,6 +23,7 @@ #include "acscript.h" #include "dmu_lib.h" +#include "g_common.h" #include "p_player.h" #include "p_map.h" #include "p_saveg.h" @@ -63,6 +64,33 @@ struct BytecodeScriptInfo int waitValue; }; +void ACScriptInterpreter::DeferredTask::write(Writer *writer) const +{ + Uri_Write(mapUri, writer); + Writer_WriteInt32(writer, scriptNumber); + for(int i = 0; i < 4; ++i) + { + Writer_WriteByte(writer, args[i]); + } +} + +void ACScriptInterpreter::DeferredTask::read(Reader *reader, int segmentVersion) +{ + if(segmentVersion >= 4) + { + mapUri = Uri_FromReader(reader); + } + else + { + mapUri = G_ComposeMapUri(gameEpisode, Reader_ReadInt32(reader)); + } + scriptNumber = Reader_ReadInt32(reader); + for(int i = 0; i < 4; ++i) + { + args[i] = Reader_ReadByte(reader); + } +} + int ACScriptInterpreter::scriptInfoIndex(int scriptNumber) { for(int i = 0; i < _scriptCount; ++i) @@ -102,31 +130,23 @@ ACScript *ACScriptInterpreter::newACScript(BytecodeScriptInfo &info, byte const return script; } -bool ACScriptInterpreter::newDeferredTask(uint map, int scriptNumber, byte const args[]) +bool ACScriptInterpreter::newDeferredTask(Uri const *mapUri, int scriptNumber, byte const args[]) { - if(_deferredTasksSize) + // Don't allow duplicates. + for(int i = 0; i < _deferredTasksSize; ++i) { - // Don't allow duplicates. - for(int i = 0; i < _deferredTasksSize; ++i) + DeferredTask &task = _deferredTasks[i]; + if(task.scriptNumber == scriptNumber && + Uri_Equality(task.mapUri, mapUri)) { - DeferredTask &task = _deferredTasks[i]; - if(task.scriptNumber == scriptNumber && task.map == map) - { - return false; - } + return false; } - - _deferredTasks = (DeferredTask *) Z_Realloc(_deferredTasks, ++_deferredTasksSize * sizeof(DeferredTask), PU_GAMESTATIC); - } - else - { - _deferredTasks = (DeferredTask *) Z_Malloc(sizeof(DeferredTask), PU_GAMESTATIC, 0); - _deferredTasksSize = 1; } + _deferredTasks = (DeferredTask *) Z_Realloc(_deferredTasks, sizeof(*_deferredTasks) * ++_deferredTasksSize, PU_GAMESTATIC); DeferredTask *task = &_deferredTasks[_deferredTasksSize - 1]; - task->map = map; + task->mapUri = Uri_Dup(mapUri); task->scriptNumber = scriptNumber; task->args[0] = args[0]; task->args[1] = args[1]; @@ -234,16 +254,23 @@ void ACScriptInterpreter::startOpenScripts() } } -bool ACScriptInterpreter::startScript(int scriptNumber, uint map, byte const args[], - mobj_t *activator, Line *line, int side) +bool ACScriptInterpreter::startScript(int scriptNumber, Uri const *mapUri, + byte const args[], mobj_t *activator, Line *line, int side) { DENG_ASSERT(!IS_CLIENT); - if(map && map - 1 != gameMap) + if(mapUri) { - // Script is not for the current map. - // Add it to the store to be started when that map is next entered. - return newDeferredTask(map - 1, scriptNumber, args); + Uri *currentMapUri = G_ComposeMapUri(gameEpisode, gameMap); + if(!Uri_Equality(mapUri, currentMapUri)) + { + Uri_Delete(currentMapUri); + + // Script is not for the current map. + // Add it to the store to be started when that map is next entered. + return newDeferredTask(mapUri, scriptNumber, args); + } + Uri_Delete(currentMapUri); } if(BytecodeScriptInfo *info = scriptInfoPtr(scriptNumber)) @@ -271,7 +298,7 @@ bool ACScriptInterpreter::startScript(int scriptNumber, uint map, byte const arg return false; // Perhaps its already executing? } -bool ACScriptInterpreter::suspendScript(int scriptNumber, uint /*map*/) +bool ACScriptInterpreter::suspendScript(int scriptNumber, Uri const * /*mapUri*/) { if(BytecodeScriptInfo *info = scriptInfoPtr(scriptNumber)) { @@ -286,7 +313,7 @@ bool ACScriptInterpreter::suspendScript(int scriptNumber, uint /*map*/) return false; } -bool ACScriptInterpreter::terminateScript(int scriptNumber, uint /*map*/) +bool ACScriptInterpreter::terminateScript(int scriptNumber, Uri const * /*mapUri*/) { if(BytecodeScriptInfo *info = scriptInfoPtr(scriptNumber)) { @@ -359,11 +386,15 @@ byte const *ACScriptInterpreter::bytecode() const void ACScriptInterpreter::clearDeferredTasks() { + for(int i = 0; i < _deferredTasksSize; ++i) + { + Uri_Delete(_deferredTasks[i].mapUri); + } Z_Free(_deferredTasks); _deferredTasks = 0; _deferredTasksSize = 0; } -void ACScriptInterpreter::runDeferredTasks(uint map/*Uri const *mapUri*/) +void ACScriptInterpreter::runDeferredTasks(Uri const *mapUri) { //DENG_ASSERT(mapUri != 0); @@ -382,7 +413,7 @@ void ACScriptInterpreter::runDeferredTasks(uint map/*Uri const *mapUri*/) DeferredTask *task = &_deferredTasks[i]; int scriptNumber = task->scriptNumber; - if(task->map != map) + if(!Uri_Equality(task->mapUri, mapUri)) { i++; continue; @@ -405,6 +436,8 @@ void ACScriptInterpreter::runDeferredTasks(uint map/*Uri const *mapUri*/) App_Log(DE2_SCR_WARNING, "ACS: Unknown script #%i", scriptNumber); } + Uri_Delete(_deferredTasks[i].mapUri); + _deferredTasksSize -= 1; if(i == _deferredTasksSize) break; @@ -412,17 +445,18 @@ void ACScriptInterpreter::runDeferredTasks(uint map/*Uri const *mapUri*/) memmove(&_deferredTasks[i], &_deferredTasks[i + 1], sizeof(DeferredTask) * (_deferredTasksSize - i)); } - if(_deferredTasksSize == origSize) - return; - - if(_deferredTasksSize) + if(_deferredTasksSize < origSize) { - _deferredTasks = (DeferredTask *) Z_Realloc(_deferredTasks, sizeof(DeferredTask) * _deferredTasksSize, PU_GAMESTATIC); - return; + if(_deferredTasksSize) + { + _deferredTasks = (DeferredTask *) Z_Realloc(_deferredTasks, sizeof(DeferredTask) * _deferredTasksSize, PU_GAMESTATIC); + } + else + { + Z_Free(_deferredTasks); + _deferredTasks = 0; + } } - - Z_Free(_deferredTasks); - _deferredTasks = 0; } void ACScriptInterpreter::scriptFinished(ACScript *script) @@ -449,7 +483,7 @@ void ACScriptInterpreter::writeWorldScriptData(Writer *writer) { SV_BeginSegment(ASEG_GLOBALSCRIPTDATA); - Writer_WriteByte(writer, 3); // version byte + Writer_WriteByte(writer, 4); // version byte for(int i = 0; i < MAX_ACS_WORLD_VARS; ++i) { @@ -460,13 +494,7 @@ void ACScriptInterpreter::writeWorldScriptData(Writer *writer) Writer_WriteInt32(writer, _deferredTasksSize); for(int i = 0; i < _deferredTasksSize; ++i) { - DeferredTask const *task = &_deferredTasks[i]; - Writer_WriteInt32(writer, task->map); - Writer_WriteInt32(writer, task->scriptNumber); - for(int k = 0; k < 4; ++k) - { - Writer_WriteByte(writer, task->args[k]); - } + _deferredTasks[i].write(writer); } } @@ -486,45 +514,37 @@ void ACScriptInterpreter::readWorldScriptData(Reader *reader, int mapVersion) } // Deserialize the deferred task queue. + clearDeferredTasks(); if(ver >= 3) { _deferredTasksSize = Reader_ReadInt32(reader); if(_deferredTasksSize) { - if(_deferredTasks) - _deferredTasks = (DeferredTask *) Z_Realloc(_deferredTasks, sizeof(DeferredTask) * _deferredTasksSize, PU_GAMESTATIC); - else - _deferredTasks = (DeferredTask *) Z_Malloc(sizeof(DeferredTask) * _deferredTasksSize, PU_GAMESTATIC, 0); - + _deferredTasks = (DeferredTask *) Z_Realloc(_deferredTasks, sizeof(*_deferredTasks) * _deferredTasksSize, PU_GAMESTATIC); for(int i = 0; i < _deferredTasksSize; ++i) { - DeferredTask *task = &_deferredTasks[i]; - - task->map = Reader_ReadInt32(reader); - task->scriptNumber = Reader_ReadInt32(reader); - for(int k = 0; k < 4; ++k) - { - task->args[k] = Reader_ReadByte(reader); - } + _deferredTasks[i].read(reader, ver); } } } else { // Old format. - DeferredTask tempTasks[20]; - - _deferredTasksSize = 0; for(int i = 0; i < 20; ++i) { - int map = Reader_ReadInt32(reader); - DeferredTask *task = &tempTasks[map < 0? 19 : _deferredTasksSize++]; - - task->map = map < 0? 0 : map-1; - task->scriptNumber = Reader_ReadInt32(reader); + int map = Reader_ReadInt32(reader); + int scriptNumber = Reader_ReadInt32(reader); + byte args[4]; for(int k = 0; k < 4; ++k) { - task->args[k] = Reader_ReadByte(reader); + args[k] = Reader_ReadByte(reader); + } + + if(map > 0) + { + Uri *mapUri = G_ComposeMapUri(gameEpisode, map - 1); + newDeferredTask(mapUri, scriptNumber, args); + Uri_Delete(mapUri); } } @@ -532,21 +552,6 @@ void ACScriptInterpreter::readWorldScriptData(Reader *reader, int mapVersion) { SV_Seek(12); // Junk. } - - if(_deferredTasksSize) - { - if(_deferredTasks) - _deferredTasks = (DeferredTask *) Z_Realloc(_deferredTasks, sizeof(DeferredTask) * _deferredTasksSize, PU_GAMESTATIC); - else - _deferredTasks = (DeferredTask *) Z_Malloc(sizeof(DeferredTask) * _deferredTasksSize, PU_GAMESTATIC, 0); - - memcpy(_deferredTasks, tempTasks, sizeof(DeferredTask) * _deferredTasksSize); - } - } - - if(!_deferredTasksSize && _deferredTasks) - { - Z_Free(_deferredTasks); _deferredTasks = 0; } } @@ -1858,25 +1863,25 @@ void Game_InitACScriptsForNewGame() interp.clearDeferredTasks(); } -void Game_ACScriptInterpreter_RunDeferredTasks(uint map/*Uri const *mapUri*/) +void Game_ACScriptInterpreter_RunDeferredTasks(Uri const *mapUri) { - interp.runDeferredTasks(map); + interp.runDeferredTasks(mapUri); } -dd_bool Game_ACScriptInterpreter_StartScript(int scriptNumber, uint map, byte const args[], - mobj_t *activator, Line *line, int side) +dd_bool Game_ACScriptInterpreter_StartScript(int scriptNumber, Uri const *mapUri, + byte const args[], mobj_t *activator, Line *line, int side) { - return interp.startScript(scriptNumber, map, args, activator, line, side); + return interp.startScript(scriptNumber, mapUri, args, activator, line, side); } -dd_bool Game_ACScriptInterpreter_TerminateScript(int scriptNumber, uint map) +dd_bool Game_ACScriptInterpreter_TerminateScript(int scriptNumber, Uri const *mapUri) { - return interp.terminateScript(scriptNumber, map); + return interp.terminateScript(scriptNumber, mapUri); } -dd_bool Game_ACScriptInterpreter_SuspendScript(int scriptNumber, uint map) +dd_bool Game_ACScriptInterpreter_SuspendScript(int scriptNumber, Uri const *mapUri) { - return interp.suspendScript(scriptNumber, map); + return interp.suspendScript(scriptNumber, mapUri); } void ACScript_Thinker(ACScript *script) diff --git a/doomsday/plugins/hexen/src/m_cheat.c b/doomsday/plugins/hexen/src/m_cheat.c index 46527f9693..ff6abd106d 100644 --- a/doomsday/plugins/hexen/src/m_cheat.c +++ b/doomsday/plugins/hexen/src/m_cheat.c @@ -825,7 +825,8 @@ D_CMD(CheatRunScript) if(scriptNum < 1 || scriptNum > 99) return false; scriptArgs[0] = scriptArgs[1] = scriptArgs[2] = 0; - if(Game_ACScriptInterpreter_StartScript(scriptNum, 0, scriptArgs, plr->plr->mo, NULL, 0)) + if(Game_ACScriptInterpreter_StartScript(scriptNum, 0/*current-map*/, + scriptArgs, plr->plr->mo, NULL, 0)) { AutoStr *cmd = Str_Appendf(AutoStr_NewStd(), "Running script %i", scriptNum); P_SetMessage(plr, LMF_NO_HIDE, Str_Text(cmd)); diff --git a/doomsday/plugins/hexen/src/p_enemy.c b/doomsday/plugins/hexen/src/p_enemy.c index 55e5b6684b..48fd2178e8 100644 --- a/doomsday/plugins/hexen/src/p_enemy.c +++ b/doomsday/plugins/hexen/src/p_enemy.c @@ -4245,7 +4245,7 @@ void C_DECL A_KoraxChase(mobj_t *actor) P_Teleport(actor, spot->origin[VX], spot->origin[VY], spot->angle, true); } - Game_ACScriptInterpreter_StartScript(249, 0, args, actor, NULL, 0); + Game_ACScriptInterpreter_StartScript(249, 0/*current-map*/, args, actor, NULL, 0); actor->special2 = 1; // Don't run again. return; @@ -4322,7 +4322,7 @@ void C_DECL A_KoraxBonePop(mobj_t* actor) if(mo) KSpiritInit(mo, actor); - Game_ACScriptInterpreter_StartScript(255, 0, args, actor, NULL, 0); // Death script. + Game_ACScriptInterpreter_StartScript(255, 0/*current-map*/, args, actor, NULL, 0); // Death script. } void KSpiritInit(mobj_t* spirit, mobj_t* korax) @@ -4510,7 +4510,7 @@ void C_DECL A_KoraxCommand(mobj_t* mo) } assert(scriptNumber >= 0); - Game_ACScriptInterpreter_StartScript(scriptNumber, 0, args, mo, NULL, 0); + Game_ACScriptInterpreter_StartScript(scriptNumber, 0/*current-map*/, args, mo, NULL, 0); } void C_DECL A_KSpiritWeave(mobj_t* mo) diff --git a/doomsday/plugins/hexen/src/p_inter.c b/doomsday/plugins/hexen/src/p_inter.c index f03bdd8d2e..eeb1219259 100644 --- a/doomsday/plugins/hexen/src/p_inter.c +++ b/doomsday/plugins/hexen/src/p_inter.c @@ -1445,7 +1445,8 @@ void P_KillMobj(mobj_t *source, mobj_t *target) if(target->type == MT_SORCBOSS) { dummy = 0; - Game_ACScriptInterpreter_StartScript(target->special, 0, (byte *) &dummy, target, NULL, 0); + Game_ACScriptInterpreter_StartScript(target->special, 0/*current-map*/, + (byte *) &dummy, target, NULL, 0); } else { diff --git a/doomsday/plugins/hexen/src/p_spec.c b/doomsday/plugins/hexen/src/p_spec.c index ea3bd67fe8..ee067c9b61 100644 --- a/doomsday/plugins/hexen/src/p_spec.c +++ b/doomsday/plugins/hexen/src/p_spec.c @@ -214,6 +214,9 @@ dd_bool P_StartLockedACS(Line *line, byte *args, mobj_t *mo, int side) { byte newArgs[5]; int i, lock; + dd_bool success; + int mapNumber; + Uri *mapUri; DENG_ASSERT(args != 0); @@ -241,7 +244,18 @@ dd_bool P_StartLockedACS(Line *line, byte *args, mobj_t *mo, int side) } newArgs[4] = 0; - return Game_ACScriptInterpreter_StartScript(newArgs[0], newArgs[1], &newArgs[2], mo, line, side); + mapNumber = newArgs[1]; // logical + mapUri = mapNumber? G_ComposeMapUri(gameEpisode, mapNumber - 1) : 0; + success = Game_ACScriptInterpreter_StartScript(newArgs[0], mapUri, &newArgs[2], mo, line, side); + Uri_Delete(mapUri); + + return success; +} + +static Uri *mapUriFromLogicalNumber(int number) +{ + if(!number) return 0; // current map. + return G_ComposeMapUri(gameEpisode, number - 1); } dd_bool P_ExecuteLineSpecial(int special, byte args[5], Line *line, int side, mobj_t *mo) @@ -517,17 +531,23 @@ dd_bool P_ExecuteLineSpecial(int special, byte args[5], Line *line, int side, mo } break; - case 80: // ACS_Execute - success = Game_ACScriptInterpreter_StartScript(args[0], args[1], &args[2], mo, line, side); - break; + case 80: /* ACS_Execute */ { + Uri *mapUri = mapUriFromLogicalNumber(args[1]); + success = Game_ACScriptInterpreter_StartScript(args[0], mapUri, &args[2], mo, line, side); + Uri_Delete(mapUri); + break; } - case 81: // ACS_Suspend - success = Game_ACScriptInterpreter_SuspendScript(args[0], args[1]); - break; + case 81: /* ACS_Suspend */ { + Uri *mapUri = mapUriFromLogicalNumber(args[1]); + success = Game_ACScriptInterpreter_SuspendScript(args[0], mapUri); + Uri_Delete(mapUri); + break; } - case 82: // ACS_Terminate - success = Game_ACScriptInterpreter_TerminateScript(args[0], args[1]); - break; + case 82: /* ACS_Terminate */ { + Uri *mapUri = mapUriFromLogicalNumber(args[1]); + success = Game_ACScriptInterpreter_TerminateScript(args[0], mapUri); + Uri_Delete(mapUri); + break; } case 83: // ACS_LockedExecute success = P_StartLockedACS(line, args, mo, side); From 3265a0b16d373776ba8965249810a81f0937da93 Mon Sep 17 00:00:00 2001 From: danij Date: Sat, 1 Feb 2014 03:14:26 +0000 Subject: [PATCH 036/106] libcommon: Cleanup --- doomsday/plugins/common/src/g_game.c | 12 ++---------- doomsday/plugins/hexen/src/p_spec.c | 16 +++++++--------- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/doomsday/plugins/common/src/g_game.c b/doomsday/plugins/common/src/g_game.c index 87016a6c8b..b3fe9320fe 100644 --- a/doomsday/plugins/common/src/g_game.c +++ b/doomsday/plugins/common/src/g_game.c @@ -126,8 +126,6 @@ dd_bool G_StartDebriefing(); typedef struct { Uri *mapUri; - //uint episode; - //uint map; dd_bool revisit; } loadmap_params_t; int G_DoLoadMap(loadmap_params_t* params); @@ -2684,8 +2682,6 @@ void G_DoLeaveMap(void) #endif p.mapUri = G_ComposeMapUri(gameEpisode, nextMap); - //p.episode = gameEpisode; - //p.map = nextMap; p.revisit = revisit; hasBrief = G_BriefingEnabled(p.mapUri, &fin); @@ -2766,10 +2762,8 @@ void G_DoRestartMap(void) // Delete raw images to conserve texture memory. DD_Executef(true, "texreset raw"); - p.mapUri = G_ComposeMapUri(gameEpisode, gameMap); - //p.episode = gameEpisode; - //p.map = gameMap; - p.revisit = false; // Don't reload save state. + p.mapUri = G_ComposeMapUri(gameEpisode, gameMap); + p.revisit = false; // Don't reload save state. // This is a restart, so we won't brief again. G_QueMapMusic(p.mapUri); @@ -3039,8 +3033,6 @@ void G_NewGame(skillmode_t skill, uint episode, uint map, uint mapEntryPoint) ddfinale_t fin; p.mapUri = G_ComposeMapUri(gameEpisode, gameMap); - //p.episode = gameEpisode; - //p.map = gameMap; p.revisit = false; hasBrief = G_BriefingEnabled(p.mapUri, &fin); diff --git a/doomsday/plugins/hexen/src/p_spec.c b/doomsday/plugins/hexen/src/p_spec.c index ee067c9b61..5b8de23bef 100644 --- a/doomsday/plugins/hexen/src/p_spec.c +++ b/doomsday/plugins/hexen/src/p_spec.c @@ -210,12 +210,17 @@ dd_bool EV_LineSearchForPuzzleItem(Line* line, byte* args, mobj_t* mo) return P_InventoryUse(mo->player - players, type, false); } +static Uri *mapUriFromLogicalNumber(int number) +{ + if(!number) return 0; // current map. + return G_ComposeMapUri(gameEpisode, number - 1); +} + dd_bool P_StartLockedACS(Line *line, byte *args, mobj_t *mo, int side) { byte newArgs[5]; int i, lock; dd_bool success; - int mapNumber; Uri *mapUri; DENG_ASSERT(args != 0); @@ -244,20 +249,13 @@ dd_bool P_StartLockedACS(Line *line, byte *args, mobj_t *mo, int side) } newArgs[4] = 0; - mapNumber = newArgs[1]; // logical - mapUri = mapNumber? G_ComposeMapUri(gameEpisode, mapNumber - 1) : 0; + mapUri = mapUriFromLogicalNumber(newArgs[1]); success = Game_ACScriptInterpreter_StartScript(newArgs[0], mapUri, &newArgs[2], mo, line, side); Uri_Delete(mapUri); return success; } -static Uri *mapUriFromLogicalNumber(int number) -{ - if(!number) return 0; // current map. - return G_ComposeMapUri(gameEpisode, number - 1); -} - dd_bool P_ExecuteLineSpecial(int special, byte args[5], Line *line, int side, mobj_t *mo) { dd_bool success = false; From 2a4968acc490dbb7f4c1db085015f16b86007054 Mon Sep 17 00:00:00 2001 From: danij Date: Sat, 1 Feb 2014 04:05:17 +0000 Subject: [PATCH 037/106] libcommon|Cleanup: Added G_CurrentMapUri() --- doomsday/plugins/common/include/g_common.h | 36 ++++++++++++-------- doomsday/plugins/common/src/d_netsv.c | 2 +- doomsday/plugins/common/src/fi_lib.c | 4 +-- doomsday/plugins/common/src/g_game.c | 39 ++++++++++++---------- doomsday/plugins/common/src/g_update.c | 2 +- doomsday/plugins/common/src/hu_stuff.cpp | 2 +- doomsday/plugins/common/src/p_mapsetup.cpp | 4 +-- doomsday/plugins/common/src/p_xgline.c | 2 +- doomsday/plugins/doom/src/m_cheat.c | 2 +- doomsday/plugins/doom/src/p_enemy.c | 4 +-- doomsday/plugins/doom/src/p_spec.c | 10 +++--- doomsday/plugins/doom64/src/m_cheat.c | 2 +- doomsday/plugins/heretic/src/m_cheat.c | 2 +- doomsday/plugins/hexen/src/acscript.cpp | 2 +- doomsday/plugins/hexen/src/m_cheat.c | 2 +- doomsday/plugins/hexen/src/p_spec.c | 2 +- 16 files changed, 66 insertions(+), 51 deletions(-) diff --git a/doomsday/plugins/common/include/g_common.h b/doomsday/plugins/common/include/g_common.h index 398f118475..e8f4649548 100644 --- a/doomsday/plugins/common/include/g_common.h +++ b/doomsday/plugins/common/include/g_common.h @@ -85,38 +85,48 @@ void G_BeginMap(void); * (if __JHEXEN__ the intermission will only be displayed when exiting a * hub and in DeathMatch games) * - * @param newMap Logical map number we are entering (i.e., not a warp/translated number). - * @param mapEntryPoint Logical map entry point on the new map. - * @param secretExit @c true if the exit taken was marked as 'secret'. + * @param newMap Logical map number we are entering (i.e., not a warp/translated number). + * @param mapEntryPoint Logical map entry point on the new map. + * @param secretExit @c true if the exit taken was marked as 'secret'. */ void G_LeaveMap(uint newMap, uint mapEntryPoint, dd_bool secretExit); /** * Compose a Uri for the identified @a episode and @a map combination. * - * @param episode Logical episode number. - * @param map Logical map number. + * @param episode Logical episode number. + * @param map Logical map number. * * @return Resultant Uri. Must be destroyed with Uri_Delete() when no longer needed. */ -Uri* G_ComposeMapUri(uint episode, uint map); +Uri *G_ComposeMapUri(uint episode, uint map); + +/** + * Compose the Uri for the @em current map. + * + * @note Some APIs are designed such that a NULL uri pointer means the "current map", + * so, calling this may be unnecessary. + * + * @return Resultant Uri. Must be destroyed with Uri_Delete() when no longer needed. + */ +Uri *G_CurrentMapUri(void); /** * Determine if the specified @a episode and @a map value pair are valid and if not, * adjust their are values within the ranges defined by the current game type and mode. * - * @param episode Logical episode number to be validated. - * @param map Logical map number to be validated. + * @param episode Logical episode number to be validated. + * @param map Logical map number to be validated. * * @return @c true= The original @a episode and @a map value pair were already valid. */ -dd_bool G_ValidateMap(uint* episode, uint* map); +dd_bool G_ValidateMap(uint *episode, uint *map); /** * Return the next map according to the default map progression. * - * @param episode Current episode. - * @param map Current map. + * @param episode Current episode. + * @param map Current map. * @param secretExit * * @return The next map. @@ -124,9 +134,9 @@ dd_bool G_ValidateMap(uint* episode, uint* map); uint G_GetNextMap(uint episode, uint map, dd_bool secretExit); /// @return Logical map number. -uint G_GetMapNumber(uint episode, uint map); +uint G_LogicalMapNumber(uint episode, uint map); -AutoStr* G_GenerateSaveGameName(void); +AutoStr *G_GenerateSaveGameName(void); D_CMD( CCmdMakeLocal ); D_CMD( CCmdSetCamera ); diff --git a/doomsday/plugins/common/src/d_netsv.c b/doomsday/plugins/common/src/d_netsv.c index 174d388e70..9721f18668 100644 --- a/doomsday/plugins/common/src/d_netsv.c +++ b/doomsday/plugins/common/src/d_netsv.c @@ -736,7 +736,7 @@ void NetSv_SendGameState(int flags, int to) return; DD_GameInfo(&gameInfo); - mapUri = G_ComposeMapUri(gameEpisode, gameMap); + mapUri = G_CurrentMapUri(); // Print a short message that describes the game state. str = Uri_Resolved(mapUri); diff --git a/doomsday/plugins/common/src/fi_lib.c b/doomsday/plugins/common/src/fi_lib.c index 494a59f0da..e40c1897ef 100644 --- a/doomsday/plugins/common/src/fi_lib.c +++ b/doomsday/plugins/common/src/fi_lib.c @@ -103,7 +103,7 @@ static void initStateConditions(fi_state_t *s) #if __JHEXEN__ // Leaving the current cluster? { - Uri *curMapUri = G_ComposeMapUri(gameEpisode, gameMap); + Uri *curMapUri = G_CurrentMapUri(); Uri *nextMapUri = G_ComposeMapUri(gameEpisode, nextMap); mapinfo_t *curMapInfo = P_MapInfo(curMapUri); @@ -453,7 +453,7 @@ int Hook_FinaleScriptStop(int hookType, int finaleId, void* parameters) else if(mode == FIMODE_BEFORE) // A briefing has ended. { // Its time to start the map; que music and begin! - Uri *mapUri = G_ComposeMapUri(gameEpisode, gameMap); + Uri *mapUri = G_CurrentMapUri(); S_MapMusic(mapUri); HU_WakeWidgets(-1 /* all players */); diff --git a/doomsday/plugins/common/src/g_game.c b/doomsday/plugins/common/src/g_game.c index b3fe9320fe..fb8c2031cc 100644 --- a/doomsday/plugins/common/src/g_game.c +++ b/doomsday/plugins/common/src/g_game.c @@ -1147,7 +1147,7 @@ void G_StartHelp(void) */ static void printMapBanner(void) { - Uri *mapUri = G_ComposeMapUri(gameEpisode, gameMap); + Uri *mapUri = G_CurrentMapUri(); char const *title = P_CurrentMapTitle(); App_Log(DE2_LOG_MAP, DE2_ESC(R)); @@ -1262,7 +1262,7 @@ static void initFogForMap(ddmapinfo_t *mapInfo) #if __JHEXEN__ { - Uri *mapUri = G_ComposeMapUri(gameEpisode, gameMap); + Uri *mapUri = G_CurrentMapUri(); mapinfo_t const *mapInfo = P_MapInfo(mapUri); if(mapInfo) { @@ -1769,7 +1769,7 @@ void G_PlayerLeaveMap(int player) #if __JHEXEN__ { - Uri *mapUri = G_ComposeMapUri(gameEpisode, gameMap); + Uri *mapUri = G_CurrentMapUri(); Uri *nextMapUri = G_ComposeMapUri(gameEpisode, nextMap); newCluster = (P_MapInfo(mapUri)->cluster != P_MapInfo(nextMapUri)->cluster); @@ -2414,7 +2414,7 @@ void G_DoMapCompleted(void) #if __JDOOM__ || __JHERETIC__ || __JDOOM64__ { ddmapinfo_t minfo; - Uri* mapUri = G_ComposeMapUri(gameEpisode, gameMap); + Uri* mapUri = G_CurrentMapUri(); AutoStr* mapPath = Uri_Compose(mapUri); if(Def_Get(DD_DEF_MAP_INFO, Str_Text(mapPath), &minfo) && (minfo.flags & MIF_NO_INTERMISSION)) { @@ -2478,7 +2478,7 @@ void G_DoMapCompleted(void) #if __JDOOM__ || __JDOOM64__ void G_PrepareWIData(void) { - Uri* mapUri = G_ComposeMapUri(gameEpisode, gameMap); + Uri* mapUri = G_CurrentMapUri(); AutoStr* mapPath = Uri_Compose(mapUri); wbstartstruct_t* info = &wmInfo; ddmapinfo_t minfo; @@ -2516,7 +2516,7 @@ void G_PrepareWIData(void) */ dd_bool G_StartDebriefing() { - Uri *mapUri = G_ComposeMapUri(gameEpisode, gameMap); + Uri *mapUri = G_CurrentMapUri(); ddfinale_t fin; if(G_DebriefingEnabled(mapUri, &fin) && @@ -2613,7 +2613,7 @@ void G_DoLeaveMap(void) // Same cluster? { - Uri *mapUri = G_ComposeMapUri(gameEpisode, gameMap); + Uri *mapUri = G_CurrentMapUri(); Uri *nextMapUri = G_ComposeMapUri(gameEpisode, nextMap); if(P_MapInfo(mapUri)->cluster == P_MapInfo(nextMapUri)->cluster) { @@ -2762,7 +2762,7 @@ void G_DoRestartMap(void) // Delete raw images to conserve texture memory. DD_Executef(true, "texreset raw"); - p.mapUri = G_ComposeMapUri(gameEpisode, gameMap); + p.mapUri = G_CurrentMapUri(); p.revisit = false; // Don't reload save state. // This is a restart, so we won't brief again. @@ -2886,7 +2886,7 @@ AutoStr *G_GenerateSaveGameName(void) minutes = time / 60; time -= minutes * 60; seconds = time; - mapUri = G_ComposeMapUri(gameEpisode, gameMap); + mapUri = G_CurrentMapUri(); mapPath = Uri_Compose(mapUri); mapTitle = P_CurrentMapTitle(); @@ -3032,7 +3032,7 @@ void G_NewGame(skillmode_t skill, uint episode, uint map, uint mapEntryPoint) dd_bool hasBrief; ddfinale_t fin; - p.mapUri = G_ComposeMapUri(gameEpisode, gameMap); + p.mapUri = G_CurrentMapUri(); p.revisit = false; hasBrief = G_BriefingEnabled(p.mapUri, &fin); @@ -3094,11 +3094,11 @@ void G_QuitGame(void) Hu_MsgStart(MSG_YESNO, endString, G_QuitGameResponse, 0, NULL); } -const char* P_GetGameModeName(void) +char const *P_GetGameModeName(void) { - static const char* dm = "deathmatch"; - static const char* coop = "cooperative"; - static const char* sp = "singleplayer"; + static char const *dm = "deathmatch"; + static char const *coop = "cooperative"; + static char const *sp = "singleplayer"; if(IS_NETGAME) { if(deathmatch) return dm; @@ -3107,7 +3107,7 @@ const char* P_GetGameModeName(void) return sp; } -uint G_GetMapNumber(uint episode, uint map) +uint G_LogicalMapNumber(uint episode, uint map) { #if __JHEXEN__ return P_TranslateMap(map); @@ -3125,7 +3125,7 @@ uint G_GetMapNumber(uint episode, uint map) #endif } -Uri* G_ComposeMapUri(uint episode, uint map) +Uri *G_ComposeMapUri(uint episode, uint map) { lumpname_t mapId; #if __JDOOM64__ @@ -3143,6 +3143,11 @@ Uri* G_ComposeMapUri(uint episode, uint map) return Uri_NewWithPath2(mapId, RC_NULL); } +Uri *G_CurrentMapUri(void) +{ + return G_ComposeMapUri(gameEpisode, gameMap); +} + dd_bool G_ValidateMap(uint *episode, uint *map) { dd_bool ok = true; @@ -3233,7 +3238,7 @@ uint G_GetNextMap(uint episode, uint map, dd_bool secretExit) { #if __JHEXEN__ Uri *mapUri = G_ComposeMapUri(episode, map); - int nextMap = G_GetMapNumber(episode, P_MapInfo(mapUri)->nextMap); + int nextMap = G_LogicalMapNumber(episode, P_MapInfo(mapUri)->nextMap); Uri_Delete(mapUri); return nextMap; diff --git a/doomsday/plugins/common/src/g_update.c b/doomsday/plugins/common/src/g_update.c index d7e7e3db82..83bc4738b8 100644 --- a/doomsday/plugins/common/src/g_update.c +++ b/doomsday/plugins/common/src/g_update.c @@ -133,7 +133,7 @@ void G_UpdateState(int step) #if __JDOOM__ || __JHERETIC__ || __JDOOM64__ { - Uri *mapUri = G_ComposeMapUri(gameEpisode, gameMap); + Uri *mapUri = G_CurrentMapUri(); S_MapMusic(mapUri); Uri_Delete(mapUri); } diff --git a/doomsday/plugins/common/src/hu_stuff.cpp b/doomsday/plugins/common/src/hu_stuff.cpp index 1cd7236c82..43ccda05eb 100644 --- a/doomsday/plugins/common/src/hu_stuff.cpp +++ b/doomsday/plugins/common/src/hu_stuff.cpp @@ -1530,7 +1530,7 @@ void Hu_DrawMapTitle(float alpha, dd_bool mapIdInsteadOfAuthor) if(mapIdInsteadOfAuthor) { - Uri *mapUri = G_ComposeMapUri(gameEpisode, gameMap); + Uri *mapUri = G_CurrentMapUri(); FR_SetFont(FID(GF_FONTA)); #if defined(__JHERETIC__) || defined(__JHEXEN__) FR_SetColorAndAlpha(.85f, .85f, .85f, alpha); diff --git a/doomsday/plugins/common/src/p_mapsetup.cpp b/doomsday/plugins/common/src/p_mapsetup.cpp index 018649034b..f922835d98 100644 --- a/doomsday/plugins/common/src/p_mapsetup.cpp +++ b/doomsday/plugins/common/src/p_mapsetup.cpp @@ -1127,7 +1127,7 @@ char const *P_MapAuthor(Uri const *mapUri, dd_bool supressGameAuthor) char const *P_CurrentMapTitle() { - Uri *mapUri = G_ComposeMapUri(gameEpisode, gameMap); + Uri *mapUri = G_CurrentMapUri(); char const *title = P_MapTitle(mapUri); Uri_Delete(mapUri); return title; @@ -1135,7 +1135,7 @@ char const *P_CurrentMapTitle() char const *P_CurrentMapAuthor(dd_bool supressGameAuthor) { - Uri *mapUri = G_ComposeMapUri(gameEpisode, gameMap); + Uri *mapUri = G_CurrentMapUri(); char const *author = P_MapAuthor(mapUri, supressGameAuthor); Uri_Delete(mapUri); return author; diff --git a/doomsday/plugins/common/src/p_xgline.c b/doomsday/plugins/common/src/p_xgline.c index 196aea24e8..906b77c16e 100644 --- a/doomsday/plugins/common/src/p_xgline.c +++ b/doomsday/plugins/common/src/p_xgline.c @@ -1796,7 +1796,7 @@ int C_DECL XLTrav_LeaveMap(Line* line, dd_bool dummy, void* context, if(mapSpecified) { XG_Dev("XLTrav_LeaveMap: Next map set to %u", map+1); - map = G_GetMapNumber(gameEpisode, map); + map = G_LogicalMapNumber(gameEpisode, map); } else { diff --git a/doomsday/plugins/doom/src/m_cheat.c b/doomsday/plugins/doom/src/m_cheat.c index 5fea64d5c7..0ff7802b41 100644 --- a/doomsday/plugins/doom/src/m_cheat.c +++ b/doomsday/plugins/doom/src/m_cheat.c @@ -675,7 +675,7 @@ D_CMD(CheatWhere) if(G_GameState() != GS_MAP || !plr->plr->mo) return true; - mapUri = G_ComposeMapUri(gameEpisode, gameMap); + mapUri = G_CurrentMapUri(); mapPath = Uri_ToString(mapUri); sprintf(textBuffer, "MAP [%s] X:%g Y:%g Z:%g", Str_Text(mapPath), plr->plr->mo->origin[VX], plr->plr->mo->origin[VY], diff --git a/doomsday/plugins/doom/src/p_enemy.c b/doomsday/plugins/doom/src/p_enemy.c index 5f3a70ad6a..33835cca11 100644 --- a/doomsday/plugins/doom/src/p_enemy.c +++ b/doomsday/plugins/doom/src/p_enemy.c @@ -1696,7 +1696,7 @@ void C_DECL A_BossDeath(mobj_t *mo) } } - G_LeaveMap(G_GetMapNumber(gameEpisode, gameMap), 0, false); + G_LeaveMap(G_LogicalMapNumber(gameEpisode, gameMap), 0, false); } void C_DECL A_Hoof(mobj_t *mo) @@ -1833,7 +1833,7 @@ void C_DECL A_BrainExplode(mobj_t *mo) void C_DECL A_BrainDie(mobj_t* mo) { - G_LeaveMap(G_GetMapNumber(gameEpisode, gameMap), 0, false); + G_LeaveMap(G_LogicalMapNumber(gameEpisode, gameMap), 0, false); } void C_DECL A_BrainSpit(mobj_t* mo) diff --git a/doomsday/plugins/doom/src/p_spec.c b/doomsday/plugins/doom/src/p_spec.c index 9ef871ab25..a4da75948c 100644 --- a/doomsday/plugins/doom/src/p_spec.c +++ b/doomsday/plugins/doom/src/p_spec.c @@ -468,7 +468,7 @@ static void crossSpecialLine(Line* line, int side, mobj_t* thing) case 52: // EXIT! - G_LeaveMap(G_GetMapNumber(gameEpisode, gameMap), 0, false); + G_LeaveMap(G_LogicalMapNumber(gameEpisode, gameMap), 0, false); break; case 53: @@ -551,7 +551,7 @@ static void crossSpecialLine(Line* line, int side, mobj_t* thing) case 124: // Secret EXIT. - G_LeaveMap(G_GetMapNumber(gameEpisode, gameMap), 0, true); + G_LeaveMap(G_LogicalMapNumber(gameEpisode, gameMap), 0, true); break; case 125: @@ -839,7 +839,7 @@ void P_PlayerInSpecialSector(player_t *player) P_DamageMobj(player->plr->mo, NULL, NULL, 20, false); if(player->health <= 10) - G_LeaveMap(G_GetMapNumber(gameEpisode, gameMap), 0, false); + G_LeaveMap(G_LogicalMapNumber(gameEpisode, gameMap), 0, false); break; } } @@ -1011,7 +1011,7 @@ dd_bool P_UseSpecialLine2(mobj_t* mo, Line* line, int side) P_ToggleSwitch(P_GetPtrp(line, DMU_FRONT), SFX_NONE, false, 0); xline->special = 0; - G_LeaveMap(G_GetMapNumber(gameEpisode, gameMap), 0, false); + G_LeaveMap(G_LogicalMapNumber(gameEpisode, gameMap), 0, false); break; case 14: @@ -1127,7 +1127,7 @@ dd_bool P_UseSpecialLine2(mobj_t* mo, Line* line, int side) P_ToggleSwitch(P_GetPtrp(line, DMU_FRONT), SFX_NONE, false, 0); xline->special = 0; - G_LeaveMap(G_GetMapNumber(gameEpisode, gameMap), 0, true); + G_LeaveMap(G_LogicalMapNumber(gameEpisode, gameMap), 0, true); break; case 55: diff --git a/doomsday/plugins/doom64/src/m_cheat.c b/doomsday/plugins/doom64/src/m_cheat.c index 81cfe4cab8..a78842d6ec 100644 --- a/doomsday/plugins/doom64/src/m_cheat.c +++ b/doomsday/plugins/doom64/src/m_cheat.c @@ -191,7 +191,7 @@ void printDebugInfo(player_t *plr) if(G_GameState() != GS_MAP || !plr->plr->mo) return; - mapUri = G_ComposeMapUri(gameEpisode, gameMap); + mapUri = G_CurrentMapUri(); mapPath = Uri_ToString(mapUri); sprintf(textBuffer, "MAP [%s] X:%g Y:%g Z:%g", Str_Text(mapPath), plr->plr->mo->origin[VX], plr->plr->mo->origin[VY], diff --git a/doomsday/plugins/heretic/src/m_cheat.c b/doomsday/plugins/heretic/src/m_cheat.c index aa7fa27fc6..300062c284 100644 --- a/doomsday/plugins/heretic/src/m_cheat.c +++ b/doomsday/plugins/heretic/src/m_cheat.c @@ -676,7 +676,7 @@ D_CMD(CheatWhere) if(G_GameState() != GS_MAP || !plr->plr->mo) return true; - mapUri = G_ComposeMapUri(gameEpisode, gameMap); + mapUri = G_CurrentMapUri(); mapPath = Uri_ToString(mapUri); sprintf(textBuffer, "MAP [%s] X:%g Y:%g Z:%g", Str_Text(mapPath), plr->plr->mo->origin[VX], plr->plr->mo->origin[VY], diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index d7d9907301..bb8f004a6e 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -261,7 +261,7 @@ bool ACScriptInterpreter::startScript(int scriptNumber, Uri const *mapUri, if(mapUri) { - Uri *currentMapUri = G_ComposeMapUri(gameEpisode, gameMap); + Uri *currentMapUri = G_CurrentMapUri(); if(!Uri_Equality(mapUri, currentMapUri)) { Uri_Delete(currentMapUri); diff --git a/doomsday/plugins/hexen/src/m_cheat.c b/doomsday/plugins/hexen/src/m_cheat.c index ff6abd106d..e223197e37 100644 --- a/doomsday/plugins/hexen/src/m_cheat.c +++ b/doomsday/plugins/hexen/src/m_cheat.c @@ -676,7 +676,7 @@ D_CMD(CheatWhere) if(G_GameState() != GS_MAP || !plr->plr->mo) return true; - mapUri = G_ComposeMapUri(gameEpisode, gameMap); + mapUri = G_CurrentMapUri(); mapPath = Uri_ToString(mapUri); sprintf(textBuffer, "Map [%s] x:%g y:%g z:%g", Str_Text(mapPath), plr->plr->mo->origin[VX], plr->plr->mo->origin[VY], diff --git a/doomsday/plugins/hexen/src/p_spec.c b/doomsday/plugins/hexen/src/p_spec.c index 5b8de23bef..c03f7a5aa9 100644 --- a/doomsday/plugins/hexen/src/p_spec.c +++ b/doomsday/plugins/hexen/src/p_spec.c @@ -1072,7 +1072,7 @@ void P_ForceLightning(void) void P_InitLightning(void) { int i, secCount; - Uri *mapUri = G_ComposeMapUri(gameEpisode, gameMap); + Uri *mapUri = G_CurrentMapUri(); mapinfo_t const *mapInfo = P_MapInfo(mapUri); Uri_Delete(mapUri); From 298e45043d7f6730ae6353c828588de8045266a6 Mon Sep 17 00:00:00 2001 From: danij Date: Sat, 1 Feb 2014 05:03:16 +0000 Subject: [PATCH 038/106] libcommon: Continued cleaning up logical episode and/or map number usage The goal being a straight map from URI to logical [episode &] map number(s), allowing for dynamic reindexing of maps at runtime. Todo: Presently, the "raw" logical numbers are still used by/for: - G_NewGame(), G_DeferredNewGame() (need update API) - Map specific playsim behavior (need generalize, expose via MapInfo) - Save info header (switch to URI) - Networked game state comms (need update protocol) --- doomsday/plugins/common/include/g_common.h | 6 +++ doomsday/plugins/common/src/g_game.c | 12 ++++- doomsday/plugins/common/src/p_tick.c | 2 +- doomsday/plugins/common/src/p_xgline.c | 4 +- doomsday/plugins/doom/src/m_cheat.c | 2 +- doomsday/plugins/doom/src/p_enemy.c | 4 +- doomsday/plugins/doom/src/p_spec.c | 10 ++-- doomsday/plugins/doom/src/st_stuff.c | 56 -------------------- doomsday/plugins/doom64/src/m_cheat.c | 2 +- doomsday/plugins/doom64/src/p_enemy.c | 4 +- doomsday/plugins/doom64/src/p_spec.c | 8 +-- doomsday/plugins/doom64/src/st_stuff.c | 59 ---------------------- doomsday/plugins/heretic/src/m_cheat.c | 2 +- doomsday/plugins/heretic/src/p_spec.c | 8 +-- doomsday/plugins/heretic/src/st_stuff.c | 43 ---------------- doomsday/plugins/hexen/src/st_stuff.c | 45 ----------------- 16 files changed, 40 insertions(+), 227 deletions(-) diff --git a/doomsday/plugins/common/include/g_common.h b/doomsday/plugins/common/include/g_common.h index e8f4649548..dad330e507 100644 --- a/doomsday/plugins/common/include/g_common.h +++ b/doomsday/plugins/common/include/g_common.h @@ -133,9 +133,15 @@ dd_bool G_ValidateMap(uint *episode, uint *map); */ uint G_GetNextMap(uint episode, uint map, dd_bool secretExit); +/// @return Logical map number. +uint G_NextLogicalMapNumber(dd_bool secretExit); + /// @return Logical map number. uint G_LogicalMapNumber(uint episode, uint map); +/// @return Logical map number. +uint G_CurrentLogicalMapNumber(void); + AutoStr *G_GenerateSaveGameName(void); D_CMD( CCmdMakeLocal ); diff --git a/doomsday/plugins/common/src/g_game.c b/doomsday/plugins/common/src/g_game.c index fb8c2031cc..c08fcc8afb 100644 --- a/doomsday/plugins/common/src/g_game.c +++ b/doomsday/plugins/common/src/g_game.c @@ -2444,7 +2444,7 @@ void G_DoMapCompleted(void) # endif // Determine the next map. - nextMap = G_GetNextMap(gameEpisode, gameMap, secretExit); + nextMap = G_NextLogicalMapNumber(secretExit); #endif // Time for an intermission. @@ -3125,6 +3125,11 @@ uint G_LogicalMapNumber(uint episode, uint map) #endif } +uint G_CurrentLogicalMapNumber(void) +{ + return G_LogicalMapNumber(gameEpisode, gameMap); +} + Uri *G_ComposeMapUri(uint episode, uint map) { lumpname_t mapId; @@ -3346,6 +3351,11 @@ uint G_GetNextMap(uint episode, uint map, dd_bool secretExit) #endif } +uint G_NextLogicalMapNumber(dd_bool secretExit) +{ + return G_GetNextMap(gameEpisode, gameMap, secretExit); +} + /** * Print a list of maps and the WAD files where they are from. */ diff --git a/doomsday/plugins/common/src/p_tick.c b/doomsday/plugins/common/src/p_tick.c index 79595d14c2..c24ebddeb1 100644 --- a/doomsday/plugins/common/src/p_tick.c +++ b/doomsday/plugins/common/src/p_tick.c @@ -104,7 +104,7 @@ void P_DoTick(void) { if(!--timerGame) { - G_LeaveMap(G_GetNextMap(gameEpisode, gameMap, false), 0, false); + G_LeaveMap(G_NextLogicalMapNumber(false), 0, false); } } diff --git a/doomsday/plugins/common/src/p_xgline.c b/doomsday/plugins/common/src/p_xgline.c index 906b77c16e..1d53cb9fa0 100644 --- a/doomsday/plugins/common/src/p_xgline.c +++ b/doomsday/plugins/common/src/p_xgline.c @@ -1763,7 +1763,7 @@ int C_DECL XLTrav_LeaveMap(Line* line, dd_bool dummy, void* context, // Is this a secret exit? if(info->iparm[0] > 0) { - G_LeaveMap(G_GetNextMap(gameEpisode, gameMap, true), 0, true); + G_LeaveMap(G_NextLogicalMapNumber(true), 0, true); return false; } @@ -1800,7 +1800,7 @@ int C_DECL XLTrav_LeaveMap(Line* line, dd_bool dummy, void* context, } else { - map = G_GetNextMap(gameEpisode, gameMap, false); + map = G_NextLogicalMapNumber(false); } G_LeaveMap(map, 0, false); diff --git a/doomsday/plugins/doom/src/m_cheat.c b/doomsday/plugins/doom/src/m_cheat.c index 0ff7802b41..89a5fae33a 100644 --- a/doomsday/plugins/doom/src/m_cheat.c +++ b/doomsday/plugins/doom/src/m_cheat.c @@ -719,6 +719,6 @@ D_CMD(CheatLeaveMap) return true; } - G_LeaveMap(G_GetNextMap(gameEpisode, gameMap, false), 0, false); + G_LeaveMap(G_NextLogicalMapNumber(false), 0, false); return true; } diff --git a/doomsday/plugins/doom/src/p_enemy.c b/doomsday/plugins/doom/src/p_enemy.c index 33835cca11..baaaed3377 100644 --- a/doomsday/plugins/doom/src/p_enemy.c +++ b/doomsday/plugins/doom/src/p_enemy.c @@ -1696,7 +1696,7 @@ void C_DECL A_BossDeath(mobj_t *mo) } } - G_LeaveMap(G_LogicalMapNumber(gameEpisode, gameMap), 0, false); + G_LeaveMap(G_CurrentLogicalMapNumber(), 0, false); } void C_DECL A_Hoof(mobj_t *mo) @@ -1833,7 +1833,7 @@ void C_DECL A_BrainExplode(mobj_t *mo) void C_DECL A_BrainDie(mobj_t* mo) { - G_LeaveMap(G_LogicalMapNumber(gameEpisode, gameMap), 0, false); + G_LeaveMap(G_CurrentLogicalMapNumber(), 0, false); } void C_DECL A_BrainSpit(mobj_t* mo) diff --git a/doomsday/plugins/doom/src/p_spec.c b/doomsday/plugins/doom/src/p_spec.c index a4da75948c..28e4b5acdd 100644 --- a/doomsday/plugins/doom/src/p_spec.c +++ b/doomsday/plugins/doom/src/p_spec.c @@ -468,7 +468,7 @@ static void crossSpecialLine(Line* line, int side, mobj_t* thing) case 52: // EXIT! - G_LeaveMap(G_LogicalMapNumber(gameEpisode, gameMap), 0, false); + G_LeaveMap(G_CurrentLogicalMapNumber(), 0, false); break; case 53: @@ -551,7 +551,7 @@ static void crossSpecialLine(Line* line, int side, mobj_t* thing) case 124: // Secret EXIT. - G_LeaveMap(G_LogicalMapNumber(gameEpisode, gameMap), 0, true); + G_LeaveMap(G_CurrentLogicalMapNumber(), 0, true); break; case 125: @@ -839,7 +839,7 @@ void P_PlayerInSpecialSector(player_t *player) P_DamageMobj(player->plr->mo, NULL, NULL, 20, false); if(player->health <= 10) - G_LeaveMap(G_LogicalMapNumber(gameEpisode, gameMap), 0, false); + G_LeaveMap(G_CurrentLogicalMapNumber(), 0, false); break; } } @@ -1011,7 +1011,7 @@ dd_bool P_UseSpecialLine2(mobj_t* mo, Line* line, int side) P_ToggleSwitch(P_GetPtrp(line, DMU_FRONT), SFX_NONE, false, 0); xline->special = 0; - G_LeaveMap(G_LogicalMapNumber(gameEpisode, gameMap), 0, false); + G_LeaveMap(G_CurrentLogicalMapNumber(), 0, false); break; case 14: @@ -1127,7 +1127,7 @@ dd_bool P_UseSpecialLine2(mobj_t* mo, Line* line, int side) P_ToggleSwitch(P_GetPtrp(line, DMU_FRONT), SFX_NONE, false, 0); xline->special = 0; - G_LeaveMap(G_LogicalMapNumber(gameEpisode, gameMap), 0, true); + G_LeaveMap(G_CurrentLogicalMapNumber(), 0, true); break; case 55: diff --git a/doomsday/plugins/doom/src/st_stuff.c b/doomsday/plugins/doom/src/st_stuff.c index 074cc2fa85..2a5ddec5df 100644 --- a/doomsday/plugins/doom/src/st_stuff.c +++ b/doomsday/plugins/doom/src/st_stuff.c @@ -2463,61 +2463,6 @@ void Secrets_UpdateGeometry(uiwidget_t* obj) .5f + textSize.height * cfg.hudCheatCounterScale); } -#if 0 -void MapName_Drawer(uiwidget_t* obj, const Point2Raw* offset) -{ - const float scale = .75f; - const float textAlpha = uiRendState->pageAlpha; - const patchid_t patch = P_FindMapTitlePatch(gameEpisode, gameMap); - const char* text = Hu_ChoosePatchReplacement2(PRM_ALLOW_TEXT, patch, P_CurrentMapTitle()); - assert(obj->type == GUI_MAPNAME); - - if(!text && 0 == patch) return; - - DGL_MatrixMode(DGL_MODELVIEW); - DGL_PushMatrix(); - if(offset) DGL_Translatef(offset->x, offset->y, 0); - DGL_Scalef(scale, scale, 1); - - DGL_Enable(DGL_TEXTURE_2D); - DGL_Color4f(1, 1, 1, textAlpha); - FR_SetFont(obj->font); - FR_SetColorAndAlpha(cfg.hudColor[0], cfg.hudColor[1], cfg.hudColor[2], textAlpha); - - WI_DrawPatchXY3(patch, text, 0, 0, ALIGN_TOPLEFT, 0, DTF_NO_EFFECTS); - - DGL_Disable(DGL_TEXTURE_2D); - DGL_MatrixMode(DGL_MODELVIEW); - DGL_PopMatrix(); -} - -void MapName_UpdateGeometry(uiwidget_t* obj) -{ - const patchid_t patch = P_FindMapTitlePatch(gameEpisode, gameMap); - const char* text = Hu_ChoosePatchReplacement2(PRM_ALLOW_TEXT, patch, P_CurrentMapTitle()); - const float scale = .75f; - patchinfo_t info; - assert(obj && obj->type == GUI_MAPNAME); - - Rect_SetWidthHeight(obj->geometry, 0, 0); - - if(!text && 0 == patch) return; - - if(text) - { - Size2Raw textSize; - FR_SetFont(obj->font); - FR_TextSize(&textSize, text); - Rect_SetWidthHeight(obj->geometry, textSize.width * scale, textSize.height * scale); - return; - } - - R_GetPatchInfo(patch, &info); - Rect_SetWidthHeight(obj->geometry, info.geometry.size.width * scale, - info.geometry.size.height * scale); -} -#endif - static void drawUIWidgetsForPlayer(player_t* plr) { #define DISPLAY_BORDER (2) /// Units in fixed 320x200 screen space. @@ -2983,7 +2928,6 @@ typedef struct { { GUI_AMMO, ALIGN_TOPLEFT, UWG_STATUSBAR, GF_INDEX, MaxAmmo_UpdateGeometry, MaxAmmo_Drawer, MaxAmmo_Ticker, &hud->sbarMaxammos[AT_SHELL] }, { GUI_AMMO, ALIGN_TOPLEFT, UWG_STATUSBAR, GF_INDEX, MaxAmmo_UpdateGeometry, MaxAmmo_Drawer, MaxAmmo_Ticker, &hud->sbarMaxammos[AT_CELL] }, { GUI_AMMO, ALIGN_TOPLEFT, UWG_STATUSBAR, GF_INDEX, MaxAmmo_UpdateGeometry, MaxAmmo_Drawer, MaxAmmo_Ticker, &hud->sbarMaxammos[AT_MISSILE] }, - //{ GUI_MAPNAME, ALIGN_BOTTOMLEFT, UWG_MAPNAME, GF_FONTB, MapName_UpdateGeometry, MapName_Drawer }, { GUI_BOX, ALIGN_BOTTOMLEFT, UWG_BOTTOMLEFT2, 0, HealthIcon_UpdateGeometry, HealthIcon_Drawer }, { GUI_HEALTH, ALIGN_BOTTOMLEFT, UWG_BOTTOMLEFT2, GF_FONTB, Health_UpdateGeometry, Health_Drawer, Health_Ticker, &hud->health }, { GUI_READYAMMOICON, ALIGN_BOTTOMLEFT, UWG_BOTTOMLEFT2, 0, ReadyAmmoIcon_UpdateGeometry, ReadyAmmoIcon_Drawer, ReadyAmmoIcon_Ticker, &hud->readyammoicon }, diff --git a/doomsday/plugins/doom64/src/m_cheat.c b/doomsday/plugins/doom64/src/m_cheat.c index a78842d6ec..5b2f0bf95a 100644 --- a/doomsday/plugins/doom64/src/m_cheat.c +++ b/doomsday/plugins/doom64/src/m_cheat.c @@ -626,6 +626,6 @@ D_CMD(CheatLeaveMap) return true; } - G_LeaveMap(G_GetNextMap(gameEpisode, gameMap, false), 0, false); + G_LeaveMap(G_NextLogicalMapNumber(false), 0, false); return true; } diff --git a/doomsday/plugins/doom64/src/p_enemy.c b/doomsday/plugins/doom64/src/p_enemy.c index 316584b705..5bb730077a 100644 --- a/doomsday/plugins/doom64/src/p_enemy.c +++ b/doomsday/plugins/doom64/src/p_enemy.c @@ -1944,7 +1944,7 @@ void C_DECL A_CyberDeath(mobj_t* actor) } else if(gameMap == 34) { - G_LeaveMap(G_GetNextMap(gameEpisode, gameMap, false), 0, false); + G_LeaveMap(G_NextLogicalMapNumber(false), 0, false); } } @@ -2067,7 +2067,7 @@ void C_DECL A_BossDeath(mobj_t* mo) return; } - G_LeaveMap(G_GetNextMap(gameEpisode, gameMap, false), 0, false); + G_LeaveMap(G_NextLogicalMapNumber(false), 0, false); } void C_DECL A_Hoof(mobj_t *mo) diff --git a/doomsday/plugins/doom64/src/p_spec.c b/doomsday/plugins/doom64/src/p_spec.c index 7f4c6c8b18..ae58149244 100644 --- a/doomsday/plugins/doom64/src/p_spec.c +++ b/doomsday/plugins/doom64/src/p_spec.c @@ -530,7 +530,7 @@ static void P_CrossSpecialLine(Line* line, int side, mobj_t* thing) case 52: // EXIT! - G_LeaveMap(G_GetNextMap(gameEpisode, gameMap, false), 0, false); + G_LeaveMap(G_NextLogicalMapNumber(false), 0, false); break; case 53: @@ -613,7 +613,7 @@ static void P_CrossSpecialLine(Line* line, int side, mobj_t* thing) case 124: // Secret EXIT - G_LeaveMap(G_GetNextMap(gameEpisode, gameMap, true), 0, true); + G_LeaveMap(G_NextLogicalMapNumber(true), 0, true); break; case 125: @@ -1150,7 +1150,7 @@ dd_bool P_UseSpecialLine2(mobj_t* mo, Line* line, int side) P_ToggleSwitch(P_GetPtrp(line, DMU_FRONT), SFX_SWTCHX, false, 0); xline->special = 0; - G_LeaveMap(G_GetNextMap(gameEpisode, gameMap, false), 0, false); + G_LeaveMap(G_NextLogicalMapNumber(false), 0, false); break; case 14: @@ -1266,7 +1266,7 @@ dd_bool P_UseSpecialLine2(mobj_t* mo, Line* line, int side) P_ToggleSwitch(P_GetPtrp(line, DMU_FRONT), SFX_NONE, false, 0); xline->special = 0; - G_LeaveMap(G_GetNextMap(gameEpisode, gameMap, true), 0, true); + G_LeaveMap(G_NextLogicalMapNumber(true), 0, true); break; case 55: diff --git a/doomsday/plugins/doom64/src/st_stuff.c b/doomsday/plugins/doom64/src/st_stuff.c index 7096bb6ad6..d6a6899859 100644 --- a/doomsday/plugins/doom64/src/st_stuff.c +++ b/doomsday/plugins/doom64/src/st_stuff.c @@ -523,65 +523,6 @@ Draw_EndZoom(); DGL_PopMatrix(); } -#if 0 -void MapName_Drawer(uiwidget_t* obj, int x, int y) -{ - assert(obj && obj->type == GUI_MAPNAME); - { - const float scale = .75f; - const float textAlpha = uiRendState->pageAlpha; - const patchid_t patch = P_FindMapTitlePatch(gameEpisode, gameMap); - const char* text = Hu_ChoosePatchReplacement2(PRM_ALLOW_TEXT, patch, P_CurrentMapTitle()); - - if(!text && 0 == patch) return; - - DGL_MatrixMode(DGL_MODELVIEW); - DGL_PushMatrix(); - DGL_Translatef(x, y, 0); - DGL_Scalef(scale, scale, 1); - - DGL_Enable(DGL_TEXTURE_2D); - DGL_Color4f(1, 1, 1, textAlpha); - FR_SetFont(obj->font); - FR_SetColorAndAlpha(cfg.hudColor[0], cfg.hudColor[1], cfg.hudColor[2], textAlpha); - - WI_DrawPatchXY3(patch, text, 0, 0, ALIGN_BOTTOMLEFT, 0, DTF_NO_EFFECTS); - - DGL_Disable(DGL_TEXTURE_2D); - DGL_MatrixMode(DGL_MODELVIEW); - DGL_PopMatrix(); - } -} - -void MapName_UpdateGeometry(uiwidget_t* obj) -{ - const patchid_t patch = P_FindMapTitlePatch(gameEpisode, gameMap); - const char* text = Hu_ChoosePatchReplacement2(PRM_ALLOW_TEXT, patch, P_CurrentMapTitle()); - const float scale = .75f; - patchinfo_t info; - assert(obj && obj->type == GUI_MAPNAME); - - Rect_SetWidthHeight(obj->geometry, 0, 0); - - if(!text && 0 == patch) return; - - if(text) - { - Size2Raw textSize; - FR_SetFont(obj->font); - FR_TextSize(&textSize, text); - textSize.width *= scale; - textSize.height *= scale; - Rect_SetWidthHeight(obj->geometry, textSize.width, textSize.height); - return; - } - - R_GetPatchInfo(patch, &info); - Rect_SetWidthHeight(obj->geometry, info.geometry.size.width * scale, - info.geometry.size.height * scale); -} -#endif - typedef struct { guiwidgettype_t type; int group; diff --git a/doomsday/plugins/heretic/src/m_cheat.c b/doomsday/plugins/heretic/src/m_cheat.c index 300062c284..7e1f339477 100644 --- a/doomsday/plugins/heretic/src/m_cheat.c +++ b/doomsday/plugins/heretic/src/m_cheat.c @@ -719,7 +719,7 @@ D_CMD(CheatLeaveMap) return true; } - G_LeaveMap(G_GetNextMap(gameEpisode, gameMap, false), 0, false); + G_LeaveMap(G_NextLogicalMapNumber(false), 0, false); return true; } diff --git a/doomsday/plugins/heretic/src/p_spec.c b/doomsday/plugins/heretic/src/p_spec.c index 50fc753166..4f1743f5ac 100644 --- a/doomsday/plugins/heretic/src/p_spec.c +++ b/doomsday/plugins/heretic/src/p_spec.c @@ -583,7 +583,7 @@ static void P_CrossSpecialLine(Line* line, int side, mobj_t* thing) case 52: // EXIT! - G_LeaveMap(G_GetNextMap(gameEpisode, gameMap, false), 0, false); + G_LeaveMap(G_NextLogicalMapNumber(false), 0, false); break; case 53: @@ -630,7 +630,7 @@ static void P_CrossSpecialLine(Line* line, int side, mobj_t* thing) case 105: // Secret EXIT - G_LeaveMap(G_GetNextMap(gameEpisode, gameMap, true), 0, true); + G_LeaveMap(G_NextLogicalMapNumber(true), 0, true); break; case 106: @@ -1199,7 +1199,7 @@ dd_bool P_UseSpecialLine2(mobj_t* mo, Line* line, int side) if(cyclingMaps && mapCycleNoExit) break; - G_LeaveMap(G_GetNextMap(gameEpisode, gameMap, false), 0, false); + G_LeaveMap(G_NextLogicalMapNumber(false), 0, false); P_ToggleSwitch(P_GetPtrp(line, DMU_FRONT), SFX_NONE, false, 0); xline->special = 0; break; @@ -1296,7 +1296,7 @@ dd_bool P_UseSpecialLine2(mobj_t* mo, Line* line, int side) if(cyclingMaps && mapCycleNoExit) break; - G_LeaveMap(G_GetNextMap(gameEpisode, gameMap, true), 0, true); + G_LeaveMap(G_NextLogicalMapNumber(true), 0, true); P_ToggleSwitch(P_GetPtrp(line, DMU_FRONT), SFX_NONE, false, 0); xline->special = 0; break; diff --git a/doomsday/plugins/heretic/src/st_stuff.c b/doomsday/plugins/heretic/src/st_stuff.c index 9d317d7db0..776a274679 100644 --- a/doomsday/plugins/heretic/src/st_stuff.c +++ b/doomsday/plugins/heretic/src/st_stuff.c @@ -2289,48 +2289,6 @@ void Secrets_UpdateGeometry(uiwidget_t* obj) .5f + textSize.height * cfg.hudCheatCounterScale); } -#if 0 -void MapName_Drawer(uiwidget_t* obj, const Point2Raw* offset) -{ - const float scale = .75f; - const float textAlpha = uiRendState->pageAlpha; - const char* text = P_CurrentMapTitle(); - assert(obj->type == GUI_MAPNAME); - - if(!text) return; - - DGL_MatrixMode(DGL_MODELVIEW); - DGL_PushMatrix(); - if(offset) DGL_Translatef(offset->x, offset->y, 0); - DGL_Scalef(scale, scale, 1); - - DGL_Enable(DGL_TEXTURE_2D); - FR_SetFont(obj->font); - FR_SetColorAndAlpha(defFontRGB3[0], defFontRGB3[1], defFontRGB3[2], textAlpha); - FR_DrawTextXY(text, 0, 0); - DGL_Disable(DGL_TEXTURE_2D); - - DGL_MatrixMode(DGL_MODELVIEW); - DGL_PopMatrix(); -} - -void MapName_UpdateGeometry(uiwidget_t* obj) -{ - const char* text = P_CurrentMapTitle(); - const float scale = .75f; - Size2Raw textSize; - assert(obj->type == GUI_MAPNAME); - - Rect_SetWidthHeight(obj->geometry, 0, 0); - - if(!text) return; - - FR_SetFont(obj->font); - FR_TextSize(&textSize, text); - Rect_SetWidthHeight(obj->geometry, textSize.width * scale, textSize.height * scale); -} -#endif - static void drawUIWidgetsForPlayer(player_t* plr) { /// Units in fixed 320x200 screen space. @@ -2794,7 +2752,6 @@ typedef struct { { GUI_READYAMMOICON, ALIGN_TOPLEFT, UWG_STATUSBAR, 0, SBarReadyAmmoIcon_UpdateGeometry, SBarReadyAmmoIcon_Drawer, ReadyAmmoIcon_Ticker, &hud->sbarReadyammoicon }, { GUI_READYITEM, ALIGN_TOPLEFT, UWG_STATUSBAR, GF_SMALLIN, SBarReadyItem_UpdateGeometry, SBarReadyItem_Drawer, ReadyItem_Ticker, &hud->sbarReadyitem }, { GUI_CHAIN, ALIGN_TOPLEFT, UWG_STATUSBAR, 0, SBarChain_UpdateGeometry, SBarChain_Drawer, SBarChain_Ticker, &hud->sbarChain }, - //{ GUI_MAPNAME, ALIGN_TOPLEFT, UWG_MAPNAME, GF_FONTA, MapName_UpdateGeometry, MapName_Drawer }, { GUI_READYAMMOICON, ALIGN_TOPLEFT, UWG_TOPLEFT, 0, ReadyAmmoIcon_UpdateGeometry, ReadyAmmoIcon_Drawer, ReadyAmmoIcon_Ticker, &hud->readyammoicon }, { GUI_READYAMMO, ALIGN_TOPLEFT, UWG_TOPLEFT, GF_STATUS, ReadyAmmo_UpdateGeometry, ReadyAmmo_Drawer, ReadyAmmo_Ticker, &hud->readyammo }, { GUI_FLIGHT, ALIGN_TOPLEFT, UWG_TOPLEFT, 0, Flight_UpdateGeometry, Flight_Drawer, Flight_Ticker, &hud->flight }, diff --git a/doomsday/plugins/hexen/src/st_stuff.c b/doomsday/plugins/hexen/src/st_stuff.c index e5c39307e7..5244118496 100644 --- a/doomsday/plugins/hexen/src/st_stuff.c +++ b/doomsday/plugins/hexen/src/st_stuff.c @@ -2661,50 +2661,6 @@ void WorldTimer_UpdateGeometry(uiwidget_t* obj) #undef ORIGINX } -#if 0 -void MapName_Drawer(uiwidget_t* obj, const Point2Raw* offset) -{ - const float scale = .75f; - const float textAlpha = uiRendState->pageAlpha; - const char* text = P_CurrentMapTitle(); - assert(obj->type == GUI_MAPNAME); - - if(!text) return; - - DGL_MatrixMode(DGL_MODELVIEW); - DGL_PushMatrix(); - if(offset) DGL_Translatef(offset->x, offset->y, 0); - DGL_Scalef(scale, scale, 1); - DGL_Enable(DGL_TEXTURE_2D); - - FR_SetFont(obj->font); - FR_SetTracking(0); - FR_SetColorAndAlpha(defFontRGB3[0], defFontRGB3[1], defFontRGB3[2], textAlpha); - FR_DrawTextXY(text, 0, 0); - - DGL_Disable(DGL_TEXTURE_2D); - DGL_MatrixMode(DGL_MODELVIEW); - DGL_PopMatrix(); -} - -void MapName_UpdateGeometry(uiwidget_t* obj) -{ - const char* text = P_CurrentMapTitle(); - const float scale = .75f; - Size2Raw textSize; - assert(obj->type == GUI_MAPNAME); - - Rect_SetWidthHeight(obj->geometry, 0, 0); - - if(!text) return; - - FR_SetFont(obj->font); - FR_SetTracking(0); - FR_TextSize(&textSize, text); - Rect_SetWidthHeight(obj->geometry, textSize.width * scale, textSize.height * scale); -} -#endif - void ST_loadGraphics(void) { char namebuf[9]; @@ -3065,7 +3021,6 @@ typedef struct { { GUI_GREENMANAICON, ALIGN_TOPLEFT, UWG_STATUSBAR, 0, SBarGreenManaIcon_UpdateGeometry, SBarGreenManaIcon_Drawer, GreenManaIcon_Ticker, &hud->sbarGreenmanaicon }, { GUI_GREENMANA, ALIGN_TOPLEFT, UWG_STATUSBAR, GF_SMALLIN, SBarGreenMana_UpdateGeometry, SBarGreenMana_Drawer, GreenMana_Ticker, &hud->sbarGreenmana }, { GUI_GREENMANAVIAL, ALIGN_TOPLEFT, UWG_STATUSBAR, 0, SBarGreenManaVial_UpdateGeometry, SBarGreenManaVial_Drawer, GreenManaVial_Ticker, &hud->sbarGreenmanavial }, - //{ GUI_MAPNAME, ALIGN_TOPLEFT, UWG_MAPNAME, GF_FONTA, MapName_UpdateGeometry, MapName_Drawer }, { GUI_BLUEMANAICON, ALIGN_TOPLEFT, UWG_TOPLEFT, 0, BlueManaIcon_UpdateGeometry, BlueManaIcon_Drawer, BlueManaIcon_Ticker, &hud->bluemanaicon }, { GUI_BLUEMANA, ALIGN_TOPLEFT, UWG_TOPLEFT, GF_STATUS, BlueMana_UpdateGeometry, BlueMana_Drawer, BlueMana_Ticker, &hud->bluemana }, { GUI_GREENMANAICON, ALIGN_TOPLEFT, UWG_TOPLEFT2, 0, GreenManaIcon_UpdateGeometry, GreenManaIcon_Drawer, GreenManaIcon_Ticker, &hud->greenmanaicon }, From 591423879d7af09955e017992f1238ebab713a06 Mon Sep 17 00:00:00 2001 From: danij Date: Sat, 1 Feb 2014 06:04:29 +0000 Subject: [PATCH 039/106] ACS|Hexen: Simplified ACScript => BytecodeScriptInfo lookup ACScript instances only ever exist while the bytecode which defines said script is in memory. Once loaded/populated, the script info db is never reallocated (only modified). Therefore, linking the info to a given ACScript thinker can be done directly, using a pointer. --- doomsday/plugins/hexen/include/acscript.h | 10 +- doomsday/plugins/hexen/src/acscript.cpp | 507 +++++++++++----------- 2 files changed, 246 insertions(+), 271 deletions(-) diff --git a/doomsday/plugins/hexen/include/acscript.h b/doomsday/plugins/hexen/include/acscript.h index 9cedd195ca..2553675469 100644 --- a/doomsday/plugins/hexen/include/acscript.h +++ b/doomsday/plugins/hexen/include/acscript.h @@ -34,6 +34,7 @@ #define MAX_ACS_WORLD_VARS 64 #define ACS_STACK_DEPTH 32 +struct BytecodeScriptInfo; #ifdef __cplusplus class ACScriptInterpreter; #endif @@ -46,8 +47,7 @@ typedef struct acscript_s { mobj_t *activator; Line *line; int side; - int number; - int infoIndex; + BytecodeScriptInfo *_info; int delayCount; int stack[ACS_STACK_DEPTH]; int stackPtr; @@ -57,6 +57,8 @@ typedef struct acscript_s { #ifdef __cplusplus ACScriptInterpreter &interpreter() const; + BytecodeScriptInfo &info() const; + void runTick(); /** @@ -89,8 +91,6 @@ void ACScript_Thinker(ACScript *script); #endif #ifdef __cplusplus -struct BytecodeScriptInfo; - /** * Action-Code Script (ACS) bytecode interpreter. */ @@ -209,8 +209,6 @@ class ACScriptInterpreter public: /// @todo make private: BytecodeScriptInfo &scriptInfoByIndex(int index); - BytecodeScriptInfo &scriptInfoFor(ACScript *script); - private: /** * Returns the logical index of a @a scriptNumber; otherwise @c -1. diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index bb8f004a6e..c6bbedd2b5 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -112,8 +112,7 @@ ACScript *ACScriptInterpreter::newACScript(BytecodeScriptInfo &info, byte const ACScript *script = (ACScript *) Z_Calloc(sizeof(*script), PU_MAP, 0); script->thinker.function = (thinkfunc_t) ACScript_Thinker; - script->number = info.scriptNumber; - script->infoIndex = scriptInfoIndex(info.scriptNumber); + script->_info = &info; script->pcodePtr = info.pcodePtr; script->delayCount = delayCount; @@ -464,13 +463,13 @@ void ACScriptInterpreter::scriptFinished(ACScript *script) if(!script) return; // This script has now finished. - scriptInfoFor(script).state = Inactive; + script->info().state = Inactive; // Notify any scripts which are waiting for this script to finish. for(int i = 0; i < _scriptCount; ++i) { BytecodeScriptInfo &info = _scriptInfo[i]; - if(info.state == WaitingForScript && info.waitValue == script->number) + if(info.state == WaitingForScript && info.waitValue == script->info().scriptNumber) { info.state = Running; } @@ -596,24 +595,11 @@ BytecodeScriptInfo &ACScriptInterpreter::scriptInfoByIndex(int index) return _scriptInfo[index]; } -BytecodeScriptInfo &ACScriptInterpreter::scriptInfoFor(ACScript *script) -{ - DENG_ASSERT(script != 0); - return scriptInfoByIndex(script->infoIndex); -} - static byte SpecArgs[5]; #define PRINT_BUFFER_SIZE 256 static char PrintBuffer[PRINT_BUFFER_SIZE]; -/// POD structure passed to bytecode commands. -struct CommandArgs -{ - ACScript *script; - BytecodeScriptInfo *scriptInfo; -}; - /// Bytecode command return value. enum CommandResult { @@ -622,512 +608,500 @@ enum CommandResult Terminate }; -typedef CommandResult (*CommandFunc) (CommandArgs const &args); +typedef CommandResult (*CommandFunc) (ACScript &acs); /// Helper macro for declaring an ACS command function. -#define ACS_COMMAND(Name) CommandResult cmd##Name(CommandArgs const &args) - -/// ACS command helper macros: -#define S_INTERPRETER() args.script->interpreter() -#define S_PCODEPTR args.script->pcodePtr -#define S_PUSH(value) args.script->push(value) -#define S_POP() args.script->pop() -#define S_TOP() args.script->top() -#define S_DROP() args.script->drop() +#define ACS_COMMAND(Name) CommandResult cmd##Name(ACScript &acs) ACS_COMMAND(NOP) { - DENG_UNUSED(args); + DENG_UNUSED(acs); return Continue; } ACS_COMMAND(Terminate) { - DENG_UNUSED(args); + DENG_UNUSED(acs); return Terminate; } ACS_COMMAND(Suspend) { - args.scriptInfo->state = ACScriptInterpreter::Suspended; + acs.info().state = ACScriptInterpreter::Suspended; return Stop; } ACS_COMMAND(PushNumber) { - S_PUSH(LONG(*S_PCODEPTR++)); + acs.push(LONG(*acs.pcodePtr++)); return Continue; } ACS_COMMAND(LSpec1) { - int special = LONG(*S_PCODEPTR++); - SpecArgs[0] = S_POP(); - P_ExecuteLineSpecial(special, SpecArgs, args.script->line, args.script->side, - args.script->activator); + int special = LONG(*acs.pcodePtr++); + SpecArgs[0] = acs.pop(); + P_ExecuteLineSpecial(special, SpecArgs, acs.line, acs.side, acs.activator); return Continue; } ACS_COMMAND(LSpec2) { - int special = LONG(*S_PCODEPTR++); - SpecArgs[1] = S_POP(); - SpecArgs[0] = S_POP(); - P_ExecuteLineSpecial(special, SpecArgs, args.script->line, args.script->side, - args.script->activator); + int special = LONG(*acs.pcodePtr++); + SpecArgs[1] = acs.pop(); + SpecArgs[0] = acs.pop(); + P_ExecuteLineSpecial(special, SpecArgs, acs.line, acs.side, acs.activator); return Continue; } ACS_COMMAND(LSpec3) { - int special = LONG(*S_PCODEPTR++); - SpecArgs[2] = S_POP(); - SpecArgs[1] = S_POP(); - SpecArgs[0] = S_POP(); - P_ExecuteLineSpecial(special, SpecArgs, args.script->line, args.script->side, - args.script->activator); + int special = LONG(*acs.pcodePtr++); + SpecArgs[2] = acs.pop(); + SpecArgs[1] = acs.pop(); + SpecArgs[0] = acs.pop(); + P_ExecuteLineSpecial(special, SpecArgs, acs.line, acs.side, acs.activator); return Continue; } ACS_COMMAND(LSpec4) { - int special = LONG(*S_PCODEPTR++); - SpecArgs[3] = S_POP(); - SpecArgs[2] = S_POP(); - SpecArgs[1] = S_POP(); - SpecArgs[0] = S_POP(); - P_ExecuteLineSpecial(special, SpecArgs, args.script->line, args.script->side, - args.script->activator); + int special = LONG(*acs.pcodePtr++); + SpecArgs[3] = acs.pop(); + SpecArgs[2] = acs.pop(); + SpecArgs[1] = acs.pop(); + SpecArgs[0] = acs.pop(); + P_ExecuteLineSpecial(special, SpecArgs, acs.line, acs.side, acs.activator); return Continue; } ACS_COMMAND(LSpec5) { - int special = LONG(*S_PCODEPTR++); - SpecArgs[4] = S_POP(); - SpecArgs[3] = S_POP(); - SpecArgs[2] = S_POP(); - SpecArgs[1] = S_POP(); - SpecArgs[0] = S_POP(); - P_ExecuteLineSpecial(special, SpecArgs, args.script->line, args.script->side, - args.script->activator); + int special = LONG(*acs.pcodePtr++); + SpecArgs[4] = acs.pop(); + SpecArgs[3] = acs.pop(); + SpecArgs[2] = acs.pop(); + SpecArgs[1] = acs.pop(); + SpecArgs[0] = acs.pop(); + P_ExecuteLineSpecial(special, SpecArgs, acs.line, acs.side, + acs.activator); return Continue; } ACS_COMMAND(LSpec1Direct) { - int special = LONG(*S_PCODEPTR++); - SpecArgs[0] = LONG(*S_PCODEPTR++); - P_ExecuteLineSpecial(special, SpecArgs, args.script->line, args.script->side, - args.script->activator); + int special = LONG(*acs.pcodePtr++); + SpecArgs[0] = LONG(*acs.pcodePtr++); + P_ExecuteLineSpecial(special, SpecArgs, acs.line, acs.side, + acs.activator); return Continue; } ACS_COMMAND(LSpec2Direct) { - int special = LONG(*S_PCODEPTR++); - SpecArgs[0] = LONG(*S_PCODEPTR++); - SpecArgs[1] = LONG(*S_PCODEPTR++); - P_ExecuteLineSpecial(special, SpecArgs, args.script->line, args.script->side, - args.script->activator); + int special = LONG(*acs.pcodePtr++); + SpecArgs[0] = LONG(*acs.pcodePtr++); + SpecArgs[1] = LONG(*acs.pcodePtr++); + P_ExecuteLineSpecial(special, SpecArgs, acs.line, acs.side, + acs.activator); return Continue; } ACS_COMMAND(LSpec3Direct) { - int special = LONG(*S_PCODEPTR++); - SpecArgs[0] = LONG(*S_PCODEPTR++); - SpecArgs[1] = LONG(*S_PCODEPTR++); - SpecArgs[2] = LONG(*S_PCODEPTR++); - P_ExecuteLineSpecial(special, SpecArgs, args.script->line, args.script->side, - args.script->activator); + int special = LONG(*acs.pcodePtr++); + SpecArgs[0] = LONG(*acs.pcodePtr++); + SpecArgs[1] = LONG(*acs.pcodePtr++); + SpecArgs[2] = LONG(*acs.pcodePtr++); + P_ExecuteLineSpecial(special, SpecArgs, acs.line, acs.side, + acs.activator); return Continue; } ACS_COMMAND(LSpec4Direct) { - int special = LONG(*S_PCODEPTR++); - SpecArgs[0] = LONG(*S_PCODEPTR++); - SpecArgs[1] = LONG(*S_PCODEPTR++); - SpecArgs[2] = LONG(*S_PCODEPTR++); - SpecArgs[3] = LONG(*S_PCODEPTR++); - P_ExecuteLineSpecial(special, SpecArgs, args.script->line, args.script->side, - args.script->activator); + int special = LONG(*acs.pcodePtr++); + SpecArgs[0] = LONG(*acs.pcodePtr++); + SpecArgs[1] = LONG(*acs.pcodePtr++); + SpecArgs[2] = LONG(*acs.pcodePtr++); + SpecArgs[3] = LONG(*acs.pcodePtr++); + P_ExecuteLineSpecial(special, SpecArgs, acs.line, acs.side, + acs.activator); return Continue; } ACS_COMMAND(LSpec5Direct) { - int special = LONG(*S_PCODEPTR++); - SpecArgs[0] = LONG(*S_PCODEPTR++); - SpecArgs[1] = LONG(*S_PCODEPTR++); - SpecArgs[2] = LONG(*S_PCODEPTR++); - SpecArgs[3] = LONG(*S_PCODEPTR++); - SpecArgs[4] = LONG(*S_PCODEPTR++); - P_ExecuteLineSpecial(special, SpecArgs, args.script->line, args.script->side, - args.script->activator); + int special = LONG(*acs.pcodePtr++); + SpecArgs[0] = LONG(*acs.pcodePtr++); + SpecArgs[1] = LONG(*acs.pcodePtr++); + SpecArgs[2] = LONG(*acs.pcodePtr++); + SpecArgs[3] = LONG(*acs.pcodePtr++); + SpecArgs[4] = LONG(*acs.pcodePtr++); + P_ExecuteLineSpecial(special, SpecArgs, acs.line, acs.side, + acs.activator); return Continue; } ACS_COMMAND(Add) { - S_PUSH(S_POP() + S_POP()); + acs.push(acs.pop() + acs.pop()); return Continue; } ACS_COMMAND(Subtract) { - int operand2 = S_POP(); - S_PUSH(S_POP() - operand2); + int operand2 = acs.pop(); + acs.push(acs.pop() - operand2); return Continue; } ACS_COMMAND(Multiply) { - S_PUSH(S_POP() * S_POP()); + acs.push(acs.pop() * acs.pop()); return Continue; } ACS_COMMAND(Divide) { - int operand2 = S_POP(); - S_PUSH(S_POP() / operand2); + int operand2 = acs.pop(); + acs.push(acs.pop() / operand2); return Continue; } ACS_COMMAND(Modulus) { - int operand2 = S_POP(); - S_PUSH(S_POP() % operand2); + int operand2 = acs.pop(); + acs.push(acs.pop() % operand2); return Continue; } ACS_COMMAND(EQ) { - S_PUSH(S_POP() == S_POP()); + acs.push(acs.pop() == acs.pop()); return Continue; } ACS_COMMAND(NE) { - S_PUSH(S_POP() != S_POP()); + acs.push(acs.pop() != acs.pop()); return Continue; } ACS_COMMAND(LT) { - int operand2 = S_POP(); - S_PUSH(S_POP() < operand2); + int operand2 = acs.pop(); + acs.push(acs.pop() < operand2); return Continue; } ACS_COMMAND(GT) { - int operand2 = S_POP(); - S_PUSH(S_POP() > operand2); + int operand2 = acs.pop(); + acs.push(acs.pop() > operand2); return Continue; } ACS_COMMAND(LE) { - int operand2 = S_POP(); - S_PUSH(S_POP() <= operand2); + int operand2 = acs.pop(); + acs.push(acs.pop() <= operand2); return Continue; } ACS_COMMAND(GE) { - int operand2 = S_POP(); - S_PUSH(S_POP() >= operand2); + int operand2 = acs.pop(); + acs.push(acs.pop() >= operand2); return Continue; } ACS_COMMAND(AssignScriptVar) { - args.script->vars[LONG(*S_PCODEPTR++)] = S_POP(); + acs.vars[LONG(*acs.pcodePtr++)] = acs.pop(); return Continue; } ACS_COMMAND(AssignMapVar) { - S_INTERPRETER().mapVars[LONG(*S_PCODEPTR++)] = S_POP(); + acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] = acs.pop(); return Continue; } ACS_COMMAND(AssignWorldVar) { - S_INTERPRETER().worldVars[LONG(*S_PCODEPTR++)] = S_POP(); + acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] = acs.pop(); return Continue; } ACS_COMMAND(PushScriptVar) { - S_PUSH(args.script->vars[LONG(*S_PCODEPTR++)]); + acs.push(acs.vars[LONG(*acs.pcodePtr++)]); return Continue; } ACS_COMMAND(PushMapVar) { - S_PUSH(S_INTERPRETER().mapVars[LONG(*S_PCODEPTR++)]); + acs.push(acs.interpreter().mapVars[LONG(*acs.pcodePtr++)]); return Continue; } ACS_COMMAND(PushWorldVar) { - S_PUSH(S_INTERPRETER().worldVars[LONG(*S_PCODEPTR++)]); + acs.push(acs.interpreter().worldVars[LONG(*acs.pcodePtr++)]); return Continue; } ACS_COMMAND(AddScriptVar) { - args.script->vars[LONG(*S_PCODEPTR++)] += S_POP(); + acs.vars[LONG(*acs.pcodePtr++)] += acs.pop(); return Continue; } ACS_COMMAND(AddMapVar) { - S_INTERPRETER().mapVars[LONG(*S_PCODEPTR++)] += S_POP(); + acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] += acs.pop(); return Continue; } ACS_COMMAND(AddWorldVar) { - S_INTERPRETER().worldVars[LONG(*S_PCODEPTR++)] += S_POP(); + acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] += acs.pop(); return Continue; } ACS_COMMAND(SubScriptVar) { - args.script->vars[LONG(*S_PCODEPTR++)] -= S_POP(); + acs.vars[LONG(*acs.pcodePtr++)] -= acs.pop(); return Continue; } ACS_COMMAND(SubMapVar) { - S_INTERPRETER().mapVars[LONG(*S_PCODEPTR++)] -= S_POP(); + acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] -= acs.pop(); return Continue; } ACS_COMMAND(SubWorldVar) { - S_INTERPRETER().worldVars[LONG(*S_PCODEPTR++)] -= S_POP(); + acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] -= acs.pop(); return Continue; } ACS_COMMAND(MulScriptVar) { - args.script->vars[LONG(*S_PCODEPTR++)] *= S_POP(); + acs.vars[LONG(*acs.pcodePtr++)] *= acs.pop(); return Continue; } ACS_COMMAND(MulMapVar) { - S_INTERPRETER().mapVars[LONG(*S_PCODEPTR++)] *= S_POP(); + acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] *= acs.pop(); return Continue; } ACS_COMMAND(MulWorldVar) { - S_INTERPRETER().worldVars[LONG(*S_PCODEPTR++)] *= S_POP(); + acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] *= acs.pop(); return Continue; } ACS_COMMAND(DivScriptVar) { - args.script->vars[LONG(*S_PCODEPTR++)] /= S_POP(); + acs.vars[LONG(*acs.pcodePtr++)] /= acs.pop(); return Continue; } ACS_COMMAND(DivMapVar) { - S_INTERPRETER().mapVars[LONG(*S_PCODEPTR++)] /= S_POP(); + acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] /= acs.pop(); return Continue; } ACS_COMMAND(DivWorldVar) { - S_INTERPRETER().worldVars[LONG(*S_PCODEPTR++)] /= S_POP(); + acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] /= acs.pop(); return Continue; } ACS_COMMAND(ModScriptVar) { - args.script->vars[LONG(*S_PCODEPTR++)] %= S_POP(); + acs.vars[LONG(*acs.pcodePtr++)] %= acs.pop(); return Continue; } ACS_COMMAND(ModMapVar) { - S_INTERPRETER().mapVars[LONG(*S_PCODEPTR++)] %= S_POP(); + acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] %= acs.pop(); return Continue; } ACS_COMMAND(ModWorldVar) { - S_INTERPRETER().worldVars[LONG(*S_PCODEPTR++)] %= S_POP(); + acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] %= acs.pop(); return Continue; } ACS_COMMAND(IncScriptVar) { - args.script->vars[LONG(*S_PCODEPTR++)]++; + acs.vars[LONG(*acs.pcodePtr++)]++; return Continue; } ACS_COMMAND(IncMapVar) { - S_INTERPRETER().mapVars[LONG(*S_PCODEPTR++)]++; + acs.interpreter().mapVars[LONG(*acs.pcodePtr++)]++; return Continue; } ACS_COMMAND(IncWorldVar) { - S_INTERPRETER().worldVars[LONG(*S_PCODEPTR++)]++; + acs.interpreter().worldVars[LONG(*acs.pcodePtr++)]++; return Continue; } ACS_COMMAND(DecScriptVar) { - args.script->vars[LONG(*S_PCODEPTR++)]--; + acs.vars[LONG(*acs.pcodePtr++)]--; return Continue; } ACS_COMMAND(DecMapVar) { - S_INTERPRETER().mapVars[LONG(*S_PCODEPTR++)]--; + acs.interpreter().mapVars[LONG(*acs.pcodePtr++)]--; return Continue; } ACS_COMMAND(DecWorldVar) { - S_INTERPRETER().worldVars[LONG(*S_PCODEPTR++)]--; + acs.interpreter().worldVars[LONG(*acs.pcodePtr++)]--; return Continue; } ACS_COMMAND(Goto) { - S_PCODEPTR = (int *) (S_INTERPRETER().bytecode() + LONG(*S_PCODEPTR)); + acs.pcodePtr = (int *) (acs.interpreter().bytecode() + LONG(*acs.pcodePtr)); return Continue; } ACS_COMMAND(IfGoto) { - if(S_POP()) + if(acs.pop()) { - S_PCODEPTR = (int *) (S_INTERPRETER().bytecode() + LONG(*S_PCODEPTR)); + acs.pcodePtr = (int *) (acs.interpreter().bytecode() + LONG(*acs.pcodePtr)); } else { - S_PCODEPTR++; + acs.pcodePtr++; } return Continue; } ACS_COMMAND(Drop) { - S_DROP(); + acs.drop(); return Continue; } ACS_COMMAND(Delay) { - args.script->delayCount = S_POP(); + acs.delayCount = acs.pop(); return Stop; } ACS_COMMAND(DelayDirect) { - args.script->delayCount = LONG(*S_PCODEPTR++); + acs.delayCount = LONG(*acs.pcodePtr++); return Stop; } ACS_COMMAND(Random) { - int high = S_POP(); - int low = S_POP(); - S_PUSH(low + (P_Random() % (high - low + 1))); + int high = acs.pop(); + int low = acs.pop(); + acs.push(low + (P_Random() % (high - low + 1))); return Continue; } ACS_COMMAND(RandomDirect) { - int low = LONG(*S_PCODEPTR++); - int high = LONG(*S_PCODEPTR++); - S_PUSH(low + (P_Random() % (high - low + 1))); + int low = LONG(*acs.pcodePtr++); + int high = LONG(*acs.pcodePtr++); + acs.push(low + (P_Random() % (high - low + 1))); return Continue; } ACS_COMMAND(ThingCount) { - int tid = S_POP(); - int type = S_POP(); + int tid = acs.pop(); + int type = acs.pop(); // Anything to count? if(type + tid) { - S_PUSH(P_MobjCount(type, tid)); + acs.push(P_MobjCount(type, tid)); } return Continue; } ACS_COMMAND(ThingCountDirect) { - int type = LONG(*S_PCODEPTR++); - int tid = LONG(*S_PCODEPTR++); + int type = LONG(*acs.pcodePtr++); + int tid = LONG(*acs.pcodePtr++); // Anything to count? if(type + tid) { - S_PUSH(P_MobjCount(type, tid)); + acs.push(P_MobjCount(type, tid)); } return Continue; } ACS_COMMAND(TagWait) { - args.scriptInfo->waitValue = S_POP(); - args.scriptInfo->state = ACScriptInterpreter::WaitingForTag; + acs.info().waitValue = acs.pop(); + acs.info().state = ACScriptInterpreter::WaitingForTag; return Stop; } ACS_COMMAND(TagWaitDirect) { - args.scriptInfo->waitValue = LONG(*S_PCODEPTR++); - args.scriptInfo->state = ACScriptInterpreter::WaitingForTag; + acs.info().waitValue = LONG(*acs.pcodePtr++); + acs.info().state = ACScriptInterpreter::WaitingForTag; return Stop; } ACS_COMMAND(PolyWait) { - args.scriptInfo->waitValue = S_POP(); - args.scriptInfo->state = ACScriptInterpreter::WaitingForPolyobj; + acs.info().waitValue = acs.pop(); + acs.info().state = ACScriptInterpreter::WaitingForPolyobj; return Stop; } ACS_COMMAND(PolyWaitDirect) { - args.scriptInfo->waitValue = LONG(*S_PCODEPTR++); - args.scriptInfo->state = ACScriptInterpreter::WaitingForPolyobj; + acs.info().waitValue = LONG(*acs.pcodePtr++); + acs.info().state = ACScriptInterpreter::WaitingForPolyobj; return Stop; } ACS_COMMAND(ChangeFloor) { - AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), S_INTERPRETER().string(S_POP()))); + AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), acs.interpreter().string(acs.pop()))); Uri *uri = Uri_NewWithPath3("Flats", Str_Text(path)); Material *mat = (Material *) P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); Uri_Delete(uri); - int tag = S_POP(); + int tag = acs.pop(); if(iterlist_t *list = P_GetSectorIterListForTag(tag, false)) { @@ -1146,9 +1120,9 @@ ACS_COMMAND(ChangeFloor) ACS_COMMAND(ChangeFloorDirect) { - int tag = LONG(*S_PCODEPTR++); + int tag = LONG(*acs.pcodePtr++); - AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), S_INTERPRETER().string(LONG(*S_PCODEPTR++)))); + AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), acs.interpreter().string(LONG(*acs.pcodePtr++)))); Uri *uri = Uri_NewWithPath3("Flats", Str_Text(path)); Material *mat = (Material *) P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); @@ -1171,13 +1145,13 @@ ACS_COMMAND(ChangeFloorDirect) ACS_COMMAND(ChangeCeiling) { - AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), S_INTERPRETER().string(S_POP()))); + AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), acs.interpreter().string(acs.pop()))); Uri *uri = Uri_NewWithPath3("Flats", Str_Text(path)); Material *mat = (Material *) P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); Uri_Delete(uri); - int tag = S_POP(); + int tag = acs.pop(); if(iterlist_t *list = P_GetSectorIterListForTag(tag, false)) { @@ -1196,9 +1170,9 @@ ACS_COMMAND(ChangeCeiling) ACS_COMMAND(ChangeCeilingDirect) { - int tag = LONG(*S_PCODEPTR++); + int tag = LONG(*acs.pcodePtr++); - AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), S_INTERPRETER().string(LONG(*S_PCODEPTR++)))); + AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), acs.interpreter().string(LONG(*acs.pcodePtr++)))); Uri *uri = Uri_NewWithPath3("Flats", Str_Text(path)); Material *mat = (Material *) P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); @@ -1221,134 +1195,134 @@ ACS_COMMAND(ChangeCeilingDirect) ACS_COMMAND(Restart) { - S_PCODEPTR = args.scriptInfo->pcodePtr; + acs.pcodePtr = acs.info().pcodePtr; return Continue; } ACS_COMMAND(AndLogical) { - S_PUSH(S_POP() && S_POP()); + acs.push(acs.pop() && acs.pop()); return Continue; } ACS_COMMAND(OrLogical) { - S_PUSH(S_POP() || S_POP()); + acs.push(acs.pop() || acs.pop()); return Continue; } ACS_COMMAND(AndBitwise) { - S_PUSH(S_POP() & S_POP()); + acs.push(acs.pop() & acs.pop()); return Continue; } ACS_COMMAND(OrBitwise) { - S_PUSH(S_POP() | S_POP()); + acs.push(acs.pop() | acs.pop()); return Continue; } ACS_COMMAND(EorBitwise) { - S_PUSH(S_POP() ^ S_POP()); + acs.push(acs.pop() ^ acs.pop()); return Continue; } ACS_COMMAND(NegateLogical) { - S_PUSH(!S_POP()); + acs.push(!acs.pop()); return Continue; } ACS_COMMAND(LShift) { - int operand2 = S_POP(); - S_PUSH(S_POP() << operand2); + int operand2 = acs.pop(); + acs.push(acs.pop() << operand2); return Continue; } ACS_COMMAND(RShift) { - int operand2 = S_POP(); - S_PUSH(S_POP() >> operand2); + int operand2 = acs.pop(); + acs.push(acs.pop() >> operand2); return Continue; } ACS_COMMAND(UnaryMinus) { - S_PUSH(-S_POP()); + acs.push(-acs.pop()); return Continue; } ACS_COMMAND(IfNotGoto) { - if(S_POP()) + if(acs.pop()) { - S_PCODEPTR++; + acs.pcodePtr++; } else { - S_PCODEPTR = (int *) (S_INTERPRETER().bytecode() + LONG(*S_PCODEPTR)); + acs.pcodePtr = (int *) (acs.interpreter().bytecode() + LONG(*acs.pcodePtr)); } return Continue; } ACS_COMMAND(LineSide) { - S_PUSH(args.script->side); + acs.push(acs.side); return Continue; } ACS_COMMAND(ScriptWait) { - args.scriptInfo->waitValue = S_POP(); - args.scriptInfo->state = ACScriptInterpreter::WaitingForScript; + acs.info().waitValue = acs.pop(); + acs.info().state = ACScriptInterpreter::WaitingForScript; return Stop; } ACS_COMMAND(ScriptWaitDirect) { - args.scriptInfo->waitValue = LONG(*S_PCODEPTR++); - args.scriptInfo->state = ACScriptInterpreter::WaitingForScript; + acs.info().waitValue = LONG(*acs.pcodePtr++); + acs.info().state = ACScriptInterpreter::WaitingForScript; return Stop; } ACS_COMMAND(ClearLineSpecial) { - if(args.script->line) + if(acs.line) { - P_ToXLine(args.script->line)->special = 0; + P_ToXLine(acs.line)->special = 0; } return Continue; } ACS_COMMAND(CaseGoto) { - if(S_TOP() == LONG(*S_PCODEPTR++)) + if(acs.top() == LONG(*acs.pcodePtr++)) { - S_PCODEPTR = (int *) (S_INTERPRETER().bytecode() + LONG(*S_PCODEPTR)); - S_DROP(); + acs.pcodePtr = (int *) (acs.interpreter().bytecode() + LONG(*acs.pcodePtr)); + acs.drop(); } else { - S_PCODEPTR++; + acs.pcodePtr++; } return Continue; } ACS_COMMAND(BeginPrint) { - DENG_UNUSED(args); + DENG_UNUSED(acs); *PrintBuffer = 0; return Continue; } ACS_COMMAND(EndPrint) { - if(args.script->activator && args.script->activator->player) + if(acs.activator && acs.activator->player) { - P_SetMessage(args.script->activator->player, 0, PrintBuffer); + P_SetMessage(acs.activator->player, 0, PrintBuffer); } else { @@ -1367,7 +1341,7 @@ ACS_COMMAND(EndPrint) ACS_COMMAND(EndPrintBold) { - DENG_UNUSED(args); + DENG_UNUSED(acs); for(int i = 0; i < MAXPLAYERS; ++i) { if(players[i].plr->inGame) @@ -1380,14 +1354,14 @@ ACS_COMMAND(EndPrintBold) ACS_COMMAND(PrintString) { - strcat(PrintBuffer, Str_Text(S_INTERPRETER().string(S_POP()))); + strcat(PrintBuffer, Str_Text(acs.interpreter().string(acs.pop()))); return Continue; } ACS_COMMAND(PrintNumber) { char tempStr[16]; - sprintf(tempStr, "%d", S_POP()); + sprintf(tempStr, "%d", acs.pop()); strcat(PrintBuffer, tempStr); return Continue; } @@ -1395,7 +1369,7 @@ ACS_COMMAND(PrintNumber) ACS_COMMAND(PrintCharacter) { char *bufferEnd = PrintBuffer + strlen(PrintBuffer); - *bufferEnd++ = S_POP(); + *bufferEnd++ = acs.pop(); *bufferEnd = 0; return Continue; } @@ -1407,7 +1381,7 @@ ACS_COMMAND(PlayerCount) { count += players[i].plr->inGame; } - S_PUSH(count); + acs.push(count); return Continue; } @@ -1427,42 +1401,42 @@ ACS_COMMAND(GameType) { gametype = 1; // cooperative } - S_PUSH(gametype); + acs.push(gametype); return Continue; } ACS_COMMAND(GameSkill) { - S_PUSH((int)gameSkill); + acs.push((int)gameSkill); return Continue; } ACS_COMMAND(Timer) { - S_PUSH(mapTime); + acs.push(mapTime); return Continue; } ACS_COMMAND(SectorSound) { mobj_t *mobj = 0; - if(args.script->line) + if(acs.line) { - Sector *front = (Sector *) P_GetPtrp(args.script->line, DMU_FRONT_SECTOR); + Sector *front = (Sector *) P_GetPtrp(acs.line, DMU_FRONT_SECTOR); mobj = (mobj_t *) P_GetPtrp(front, DMU_EMITTER); } - int volume = S_POP(); + int volume = acs.pop(); - S_StartSoundAtVolume(S_GetSoundID(Str_Text(S_INTERPRETER().string(S_POP()))), mobj, volume / 127.0f); + S_StartSoundAtVolume(S_GetSoundID(Str_Text(acs.interpreter().string(acs.pop()))), mobj, volume / 127.0f); return Continue; } ACS_COMMAND(ThingSound) { - int volume = S_POP(); - int sound = S_GetSoundID(Str_Text(S_INTERPRETER().string(S_POP()))); - int tid = S_POP(); + int volume = acs.pop(); + int sound = S_GetSoundID(Str_Text(acs.interpreter().string(acs.pop()))); + int tid = acs.pop(); int searcher = -1; mobj_t *mobj; @@ -1479,7 +1453,7 @@ ACS_COMMAND(AmbientSound) mobj_t *mobj = 0; // For 3D positioning. mobj_t *plrmo = players[DISPLAYPLAYER].plr->mo; - int volume = S_POP(); + int volume = acs.pop(); // If we are playing 3D sounds, create a temporary source mobj for the sound. if(cfg.snd3D && plrmo) @@ -1496,7 +1470,7 @@ ACS_COMMAND(AmbientSound) } } - int sound = S_GetSoundID(Str_Text(S_INTERPRETER().string(S_POP()))); + int sound = S_GetSoundID(Str_Text(acs.interpreter().string(acs.pop()))); S_StartSoundAtVolume(sound, mobj, volume / 127.0f); return Continue; @@ -1505,12 +1479,12 @@ ACS_COMMAND(AmbientSound) ACS_COMMAND(SoundSequence) { mobj_t *mobj = 0; - if(args.script->line) + if(acs.line) { - Sector *front = (Sector *) P_GetPtrp(args.script->line, DMU_FRONT_SECTOR); + Sector *front = (Sector *) P_GetPtrp(acs.line, DMU_FRONT_SECTOR); mobj = (mobj_t *) P_GetPtrp(front, DMU_EMITTER); } - SN_StartSequenceName(mobj, Str_Text(S_INTERPRETER().string(S_POP()))); + SN_StartSequenceName(mobj, Str_Text(acs.interpreter().string(acs.pop()))); return Continue; } @@ -1521,15 +1495,15 @@ ACS_COMMAND(SetLineTexture) #define TEXTURE_MIDDLE 1 #define TEXTURE_BOTTOM 2 - AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), S_INTERPRETER().string(S_POP()))); + AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), acs.interpreter().string(acs.pop()))); Uri *uri = Uri_NewWithPath3("Textures", Str_Text(path)); Material *mat = (Material *) P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); Uri_Delete(uri); - int position = S_POP(); - int side = S_POP(); - int lineTag = S_POP(); + int position = acs.pop(); + int side = acs.pop(); + int lineTag = acs.pop(); if(iterlist_t *list = P_GetLineIterListForTag(lineTag, false)) { @@ -1565,8 +1539,8 @@ ACS_COMMAND(SetLineTexture) ACS_COMMAND(SetLineBlocking) { - int lineFlags = S_POP()? DDLF_BLOCKING : 0; - int lineTag = S_POP(); + int lineFlags = acs.pop()? DDLF_BLOCKING : 0; + int lineTag = acs.pop(); if(iterlist_t *list = P_GetLineIterListForTag(lineTag, false)) { @@ -1585,13 +1559,13 @@ ACS_COMMAND(SetLineBlocking) ACS_COMMAND(SetLineSpecial) { - int arg5 = S_POP(); - int arg4 = S_POP(); - int arg3 = S_POP(); - int arg2 = S_POP(); - int arg1 = S_POP(); - int special = S_POP(); - int lineTag = S_POP(); + int arg5 = acs.pop(); + int arg4 = acs.pop(); + int arg3 = acs.pop(); + int arg2 = acs.pop(); + int arg1 = acs.pop(); + int special = acs.pop(); + int lineTag = acs.pop(); if(iterlist_t *list = P_GetLineIterListForTag(lineTag, false)) { @@ -1649,17 +1623,22 @@ ACScriptInterpreter &ACScript::interpreter() const return Game_ACScriptInterpreter(); } +BytecodeScriptInfo &ACScript::info() const +{ + DENG_ASSERT(_info != 0); + return *_info; +} + void ACScript::runTick() { ACScriptInterpreter &interp = interpreter(); - BytecodeScriptInfo &info = interp.scriptInfoFor(this); - if(info.state == ACScriptInterpreter::Terminating) + if(info().state == ACScriptInterpreter::Terminating) { interp.scriptFinished(this); return; } - if(info.state != ACScriptInterpreter::Running) + if(info().state != ACScriptInterpreter::Running) { return; } @@ -1670,12 +1649,8 @@ void ACScript::runTick() return; } - CommandArgs args; - args.script = this; - args.scriptInfo = &info; - int action; - while((action = pcodeCmds[LONG(*pcodePtr++)](args)) == Continue) + while((action = pcodeCmds[LONG(*pcodePtr++)](*this)) == Continue) {} if(action == Terminate) @@ -1706,13 +1681,12 @@ void ACScript::drop() void ACScript::write(Writer *writer) const { - Writer_WriteByte(writer, 1); // Write a version byte. + Writer_WriteByte(writer, 2); // Write a version byte. Writer_WriteInt32(writer, SV_ThingArchiveId(activator)); Writer_WriteInt32(writer, P_ToIndex(line)); Writer_WriteInt32(writer, side); - Writer_WriteInt32(writer, number); - Writer_WriteInt32(writer, infoIndex); + Writer_WriteInt32(writer, info().scriptNumber); Writer_WriteInt32(writer, delayCount); for(uint i = 0; i < ACS_STACK_DEPTH; ++i) { @@ -1731,40 +1705,43 @@ int ACScript::read(Reader *reader, int mapVersion) if(mapVersion >= 4) { // Note: the thinker class byte has already been read. - /*int ver =*/ Reader_ReadByte(reader); // version byte. + int ver = Reader_ReadByte(reader); // version byte. - activator = (mobj_t *) Reader_ReadInt32(reader); - activator = SV_GetArchiveThing(PTR2INT(activator), &activator); + activator = (mobj_t *) Reader_ReadInt32(reader); + activator = SV_GetArchiveThing(PTR2INT(activator), &activator); int temp = Reader_ReadInt32(reader); if(temp >= 0) { - line = (Line *)P_ToPtr(DMU_LINE, temp); + line = (Line *)P_ToPtr(DMU_LINE, temp); DENG_ASSERT(line != 0); } else { - line = 0; + line = 0; } - side = Reader_ReadInt32(reader); - number = Reader_ReadInt32(reader); - infoIndex = Reader_ReadInt32(reader); - delayCount = Reader_ReadInt32(reader); + side = Reader_ReadInt32(reader); + _info = interpreter().scriptInfoPtr(Reader_ReadInt32(reader)); + if(ver < 2) + { + /*infoIndex =*/ Reader_ReadInt32(reader); + } + delayCount = Reader_ReadInt32(reader); for(uint i = 0; i < ACS_STACK_DEPTH; ++i) { stack[i] = Reader_ReadInt32(reader); } - stackPtr = Reader_ReadInt32(reader); + stackPtr = Reader_ReadInt32(reader); for(uint i = 0; i < MAX_ACS_SCRIPT_VARS; ++i) { vars[i] = Reader_ReadInt32(reader); } - pcodePtr = (int *) (interpreter().bytecode() + Reader_ReadInt32(reader)); + pcodePtr = (int *) (interpreter().bytecode() + Reader_ReadInt32(reader)); } else { @@ -1774,38 +1751,38 @@ int ACScript::read(Reader *reader, int mapVersion) Reader_Read(reader, junk, 16); // Start of used data members. - activator = (mobj_t *) Reader_ReadInt32(reader); - activator = SV_GetArchiveThing(PTR2INT(activator), &activator); + activator = (mobj_t *) Reader_ReadInt32(reader); + activator = SV_GetArchiveThing(PTR2INT(activator), &activator); int temp = Reader_ReadInt32(reader); if(temp >= 0) { - line = (Line *)P_ToPtr(DMU_LINE, temp); + line = (Line *)P_ToPtr(DMU_LINE, temp); DENG_ASSERT(line != 0); } else { - line = 0; + line = 0; } - side = Reader_ReadInt32(reader); - number = Reader_ReadInt32(reader); - infoIndex = Reader_ReadInt32(reader); - delayCount = Reader_ReadInt32(reader); + side = Reader_ReadInt32(reader); + _info = interpreter().scriptInfoPtr(Reader_ReadInt32(reader)); + /*infoIndex =*/ Reader_ReadInt32(reader); + delayCount = Reader_ReadInt32(reader); for(uint i = 0; i < ACS_STACK_DEPTH; ++i) { stack[i] = Reader_ReadInt32(reader); } - stackPtr = Reader_ReadInt32(reader); + stackPtr = Reader_ReadInt32(reader); for(uint i = 0; i < MAX_ACS_SCRIPT_VARS; ++i) { vars[i] = Reader_ReadInt32(reader); } - pcodePtr = (int *) (interpreter().bytecode() + Reader_ReadInt32(reader)); + pcodePtr = (int *) (interpreter().bytecode() + Reader_ReadInt32(reader)); } thinker.function = (thinkfunc_t) ACScript_Thinker; From 44f8a2d7dec81479a46268011590d4366852c183 Mon Sep 17 00:00:00 2001 From: danij Date: Sat, 1 Feb 2014 06:47:55 +0000 Subject: [PATCH 040/106] Debug|ACS|Hexen: Error if a script tries to address outside its local value stack --- doomsday/plugins/hexen/include/acscript.h | 20 +- doomsday/plugins/hexen/src/acscript.cpp | 342 +++++++++++----------- 2 files changed, 185 insertions(+), 177 deletions(-) diff --git a/doomsday/plugins/hexen/include/acscript.h b/doomsday/plugins/hexen/include/acscript.h index 2553675469..bc3c845f91 100644 --- a/doomsday/plugins/hexen/include/acscript.h +++ b/doomsday/plugins/hexen/include/acscript.h @@ -49,8 +49,17 @@ typedef struct acscript_s { int side; BytecodeScriptInfo *_info; int delayCount; - int stack[ACS_STACK_DEPTH]; - int stackPtr; + struct Stack { // Local value stack. + int values[ACS_STACK_DEPTH]; + int height; + +#ifdef __cplusplus + void push(int value); + int pop(); + int top() const; + void drop(); +#endif + } locals; int vars[MAX_ACS_SCRIPT_VARS]; int const *pcodePtr; @@ -70,13 +79,6 @@ typedef struct acscript_s { * Deserialize the thinker from the currently open save file. */ int read(Reader *reader, int mapVersion); - -public: /// @todo make private: - void push(int value); - int pop(); - int top() const; - void drop(); - #endif // __cplusplus } ACScript; diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index c6bbedd2b5..b9f6151abd 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -595,6 +595,42 @@ BytecodeScriptInfo &ACScriptInterpreter::scriptInfoByIndex(int index) return _scriptInfo[index]; } +AutoStr *ACScriptInterpreter::scriptName(int scriptNumber) +{ + BytecodeScriptInfo *info = scriptInfoPtr(scriptNumber); + if(!info) + { + return AutoStr_FromTextStd("(invalid-scriptnumber)"); + } + bool const open = (info->flags & BytecodeScriptInfo::Open) != 0; + return Str_Appendf(AutoStr_NewStd(), "#%i%s", scriptNumber, open? " (Open)" : ""); +} + +AutoStr *ACScriptInterpreter::scriptDescription(int scriptNumber) +{ + BytecodeScriptInfo *info = scriptInfoPtr(scriptNumber); + if(!info) + { + return AutoStr_FromTextStd("(invalid-scriptnumber)"); + } + + char const *stateLabels[] = { + "Inactive", + "Running", + "Suspended", + "Waiting for tag", + "Waiting for polyobj", + "Waiting for script", + "Terminating" + }; + + return Str_Appendf(AutoStr_NewStd(), "ACScript " DE2_ESC(b) "%s\n" + DE2_ESC(l) "State: " DE2_ESC(.) DE2_ESC(i) "%s" DE2_ESC(.) + DE2_ESC(l) " Wait-for: " DE2_ESC(.) DE2_ESC(i) "%i", + Str_Text(scriptName(scriptNumber)), + stateLabels[info->state], info->waitValue); +} + static byte SpecArgs[5]; #define PRINT_BUFFER_SIZE 256 @@ -633,14 +669,14 @@ ACS_COMMAND(Suspend) ACS_COMMAND(PushNumber) { - acs.push(LONG(*acs.pcodePtr++)); + acs.locals.push(LONG(*acs.pcodePtr++)); return Continue; } ACS_COMMAND(LSpec1) { int special = LONG(*acs.pcodePtr++); - SpecArgs[0] = acs.pop(); + SpecArgs[0] = acs.locals.pop(); P_ExecuteLineSpecial(special, SpecArgs, acs.line, acs.side, acs.activator); return Continue; @@ -649,8 +685,8 @@ ACS_COMMAND(LSpec1) ACS_COMMAND(LSpec2) { int special = LONG(*acs.pcodePtr++); - SpecArgs[1] = acs.pop(); - SpecArgs[0] = acs.pop(); + SpecArgs[1] = acs.locals.pop(); + SpecArgs[0] = acs.locals.pop(); P_ExecuteLineSpecial(special, SpecArgs, acs.line, acs.side, acs.activator); return Continue; @@ -659,9 +695,9 @@ ACS_COMMAND(LSpec2) ACS_COMMAND(LSpec3) { int special = LONG(*acs.pcodePtr++); - SpecArgs[2] = acs.pop(); - SpecArgs[1] = acs.pop(); - SpecArgs[0] = acs.pop(); + SpecArgs[2] = acs.locals.pop(); + SpecArgs[1] = acs.locals.pop(); + SpecArgs[0] = acs.locals.pop(); P_ExecuteLineSpecial(special, SpecArgs, acs.line, acs.side, acs.activator); return Continue; @@ -670,10 +706,10 @@ ACS_COMMAND(LSpec3) ACS_COMMAND(LSpec4) { int special = LONG(*acs.pcodePtr++); - SpecArgs[3] = acs.pop(); - SpecArgs[2] = acs.pop(); - SpecArgs[1] = acs.pop(); - SpecArgs[0] = acs.pop(); + SpecArgs[3] = acs.locals.pop(); + SpecArgs[2] = acs.locals.pop(); + SpecArgs[1] = acs.locals.pop(); + SpecArgs[0] = acs.locals.pop(); P_ExecuteLineSpecial(special, SpecArgs, acs.line, acs.side, acs.activator); return Continue; @@ -682,11 +718,11 @@ ACS_COMMAND(LSpec4) ACS_COMMAND(LSpec5) { int special = LONG(*acs.pcodePtr++); - SpecArgs[4] = acs.pop(); - SpecArgs[3] = acs.pop(); - SpecArgs[2] = acs.pop(); - SpecArgs[1] = acs.pop(); - SpecArgs[0] = acs.pop(); + SpecArgs[4] = acs.locals.pop(); + SpecArgs[3] = acs.locals.pop(); + SpecArgs[2] = acs.locals.pop(); + SpecArgs[1] = acs.locals.pop(); + SpecArgs[0] = acs.locals.pop(); P_ExecuteLineSpecial(special, SpecArgs, acs.line, acs.side, acs.activator); @@ -755,200 +791,200 @@ ACS_COMMAND(LSpec5Direct) ACS_COMMAND(Add) { - acs.push(acs.pop() + acs.pop()); + acs.locals.push(acs.locals.pop() + acs.locals.pop()); return Continue; } ACS_COMMAND(Subtract) { - int operand2 = acs.pop(); - acs.push(acs.pop() - operand2); + int operand2 = acs.locals.pop(); + acs.locals.push(acs.locals.pop() - operand2); return Continue; } ACS_COMMAND(Multiply) { - acs.push(acs.pop() * acs.pop()); + acs.locals.push(acs.locals.pop() * acs.locals.pop()); return Continue; } ACS_COMMAND(Divide) { - int operand2 = acs.pop(); - acs.push(acs.pop() / operand2); + int operand2 = acs.locals.pop(); + acs.locals.push(acs.locals.pop() / operand2); return Continue; } ACS_COMMAND(Modulus) { - int operand2 = acs.pop(); - acs.push(acs.pop() % operand2); + int operand2 = acs.locals.pop(); + acs.locals.push(acs.locals.pop() % operand2); return Continue; } ACS_COMMAND(EQ) { - acs.push(acs.pop() == acs.pop()); + acs.locals.push(acs.locals.pop() == acs.locals.pop()); return Continue; } ACS_COMMAND(NE) { - acs.push(acs.pop() != acs.pop()); + acs.locals.push(acs.locals.pop() != acs.locals.pop()); return Continue; } ACS_COMMAND(LT) { - int operand2 = acs.pop(); - acs.push(acs.pop() < operand2); + int operand2 = acs.locals.pop(); + acs.locals.push(acs.locals.pop() < operand2); return Continue; } ACS_COMMAND(GT) { - int operand2 = acs.pop(); - acs.push(acs.pop() > operand2); + int operand2 = acs.locals.pop(); + acs.locals.push(acs.locals.pop() > operand2); return Continue; } ACS_COMMAND(LE) { - int operand2 = acs.pop(); - acs.push(acs.pop() <= operand2); + int operand2 = acs.locals.pop(); + acs.locals.push(acs.locals.pop() <= operand2); return Continue; } ACS_COMMAND(GE) { - int operand2 = acs.pop(); - acs.push(acs.pop() >= operand2); + int operand2 = acs.locals.pop(); + acs.locals.push(acs.locals.pop() >= operand2); return Continue; } ACS_COMMAND(AssignScriptVar) { - acs.vars[LONG(*acs.pcodePtr++)] = acs.pop(); + acs.vars[LONG(*acs.pcodePtr++)] = acs.locals.pop(); return Continue; } ACS_COMMAND(AssignMapVar) { - acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] = acs.pop(); + acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] = acs.locals.pop(); return Continue; } ACS_COMMAND(AssignWorldVar) { - acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] = acs.pop(); + acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] = acs.locals.pop(); return Continue; } ACS_COMMAND(PushScriptVar) { - acs.push(acs.vars[LONG(*acs.pcodePtr++)]); + acs.locals.push(acs.vars[LONG(*acs.pcodePtr++)]); return Continue; } ACS_COMMAND(PushMapVar) { - acs.push(acs.interpreter().mapVars[LONG(*acs.pcodePtr++)]); + acs.locals.push(acs.interpreter().mapVars[LONG(*acs.pcodePtr++)]); return Continue; } ACS_COMMAND(PushWorldVar) { - acs.push(acs.interpreter().worldVars[LONG(*acs.pcodePtr++)]); + acs.locals.push(acs.interpreter().worldVars[LONG(*acs.pcodePtr++)]); return Continue; } ACS_COMMAND(AddScriptVar) { - acs.vars[LONG(*acs.pcodePtr++)] += acs.pop(); + acs.vars[LONG(*acs.pcodePtr++)] += acs.locals.pop(); return Continue; } ACS_COMMAND(AddMapVar) { - acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] += acs.pop(); + acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] += acs.locals.pop(); return Continue; } ACS_COMMAND(AddWorldVar) { - acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] += acs.pop(); + acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] += acs.locals.pop(); return Continue; } ACS_COMMAND(SubScriptVar) { - acs.vars[LONG(*acs.pcodePtr++)] -= acs.pop(); + acs.vars[LONG(*acs.pcodePtr++)] -= acs.locals.pop(); return Continue; } ACS_COMMAND(SubMapVar) { - acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] -= acs.pop(); + acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] -= acs.locals.pop(); return Continue; } ACS_COMMAND(SubWorldVar) { - acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] -= acs.pop(); + acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] -= acs.locals.pop(); return Continue; } ACS_COMMAND(MulScriptVar) { - acs.vars[LONG(*acs.pcodePtr++)] *= acs.pop(); + acs.vars[LONG(*acs.pcodePtr++)] *= acs.locals.pop(); return Continue; } ACS_COMMAND(MulMapVar) { - acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] *= acs.pop(); + acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] *= acs.locals.pop(); return Continue; } ACS_COMMAND(MulWorldVar) { - acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] *= acs.pop(); + acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] *= acs.locals.pop(); return Continue; } ACS_COMMAND(DivScriptVar) { - acs.vars[LONG(*acs.pcodePtr++)] /= acs.pop(); + acs.vars[LONG(*acs.pcodePtr++)] /= acs.locals.pop(); return Continue; } ACS_COMMAND(DivMapVar) { - acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] /= acs.pop(); + acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] /= acs.locals.pop(); return Continue; } ACS_COMMAND(DivWorldVar) { - acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] /= acs.pop(); + acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] /= acs.locals.pop(); return Continue; } ACS_COMMAND(ModScriptVar) { - acs.vars[LONG(*acs.pcodePtr++)] %= acs.pop(); + acs.vars[LONG(*acs.pcodePtr++)] %= acs.locals.pop(); return Continue; } ACS_COMMAND(ModMapVar) { - acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] %= acs.pop(); + acs.interpreter().mapVars[LONG(*acs.pcodePtr++)] %= acs.locals.pop(); return Continue; } ACS_COMMAND(ModWorldVar) { - acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] %= acs.pop(); + acs.interpreter().worldVars[LONG(*acs.pcodePtr++)] %= acs.locals.pop(); return Continue; } @@ -996,7 +1032,7 @@ ACS_COMMAND(Goto) ACS_COMMAND(IfGoto) { - if(acs.pop()) + if(acs.locals.pop()) { acs.pcodePtr = (int *) (acs.interpreter().bytecode() + LONG(*acs.pcodePtr)); } @@ -1009,13 +1045,13 @@ ACS_COMMAND(IfGoto) ACS_COMMAND(Drop) { - acs.drop(); + acs.locals.drop(); return Continue; } ACS_COMMAND(Delay) { - acs.delayCount = acs.pop(); + acs.delayCount = acs.locals.pop(); return Stop; } @@ -1027,9 +1063,9 @@ ACS_COMMAND(DelayDirect) ACS_COMMAND(Random) { - int high = acs.pop(); - int low = acs.pop(); - acs.push(low + (P_Random() % (high - low + 1))); + int high = acs.locals.pop(); + int low = acs.locals.pop(); + acs.locals.push(low + (P_Random() % (high - low + 1))); return Continue; } @@ -1037,18 +1073,18 @@ ACS_COMMAND(RandomDirect) { int low = LONG(*acs.pcodePtr++); int high = LONG(*acs.pcodePtr++); - acs.push(low + (P_Random() % (high - low + 1))); + acs.locals.push(low + (P_Random() % (high - low + 1))); return Continue; } ACS_COMMAND(ThingCount) { - int tid = acs.pop(); - int type = acs.pop(); + int tid = acs.locals.pop(); + int type = acs.locals.pop(); // Anything to count? if(type + tid) { - acs.push(P_MobjCount(type, tid)); + acs.locals.push(P_MobjCount(type, tid)); } return Continue; } @@ -1060,14 +1096,14 @@ ACS_COMMAND(ThingCountDirect) // Anything to count? if(type + tid) { - acs.push(P_MobjCount(type, tid)); + acs.locals.push(P_MobjCount(type, tid)); } return Continue; } ACS_COMMAND(TagWait) { - acs.info().waitValue = acs.pop(); + acs.info().waitValue = acs.locals.pop(); acs.info().state = ACScriptInterpreter::WaitingForTag; return Stop; } @@ -1081,7 +1117,7 @@ ACS_COMMAND(TagWaitDirect) ACS_COMMAND(PolyWait) { - acs.info().waitValue = acs.pop(); + acs.info().waitValue = acs.locals.pop(); acs.info().state = ACScriptInterpreter::WaitingForPolyobj; return Stop; } @@ -1095,13 +1131,13 @@ ACS_COMMAND(PolyWaitDirect) ACS_COMMAND(ChangeFloor) { - AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), acs.interpreter().string(acs.pop()))); + AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), acs.interpreter().string(acs.locals.pop()))); Uri *uri = Uri_NewWithPath3("Flats", Str_Text(path)); Material *mat = (Material *) P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); Uri_Delete(uri); - int tag = acs.pop(); + int tag = acs.locals.pop(); if(iterlist_t *list = P_GetSectorIterListForTag(tag, false)) { @@ -1145,13 +1181,13 @@ ACS_COMMAND(ChangeFloorDirect) ACS_COMMAND(ChangeCeiling) { - AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), acs.interpreter().string(acs.pop()))); + AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), acs.interpreter().string(acs.locals.pop()))); Uri *uri = Uri_NewWithPath3("Flats", Str_Text(path)); Material *mat = (Material *) P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); Uri_Delete(uri); - int tag = acs.pop(); + int tag = acs.locals.pop(); if(iterlist_t *list = P_GetSectorIterListForTag(tag, false)) { @@ -1201,63 +1237,63 @@ ACS_COMMAND(Restart) ACS_COMMAND(AndLogical) { - acs.push(acs.pop() && acs.pop()); + acs.locals.push(acs.locals.pop() && acs.locals.pop()); return Continue; } ACS_COMMAND(OrLogical) { - acs.push(acs.pop() || acs.pop()); + acs.locals.push(acs.locals.pop() || acs.locals.pop()); return Continue; } ACS_COMMAND(AndBitwise) { - acs.push(acs.pop() & acs.pop()); + acs.locals.push(acs.locals.pop() & acs.locals.pop()); return Continue; } ACS_COMMAND(OrBitwise) { - acs.push(acs.pop() | acs.pop()); + acs.locals.push(acs.locals.pop() | acs.locals.pop()); return Continue; } ACS_COMMAND(EorBitwise) { - acs.push(acs.pop() ^ acs.pop()); + acs.locals.push(acs.locals.pop() ^ acs.locals.pop()); return Continue; } ACS_COMMAND(NegateLogical) { - acs.push(!acs.pop()); + acs.locals.push(!acs.locals.pop()); return Continue; } ACS_COMMAND(LShift) { - int operand2 = acs.pop(); - acs.push(acs.pop() << operand2); + int operand2 = acs.locals.pop(); + acs.locals.push(acs.locals.pop() << operand2); return Continue; } ACS_COMMAND(RShift) { - int operand2 = acs.pop(); - acs.push(acs.pop() >> operand2); + int operand2 = acs.locals.pop(); + acs.locals.push(acs.locals.pop() >> operand2); return Continue; } ACS_COMMAND(UnaryMinus) { - acs.push(-acs.pop()); + acs.locals.push(-acs.locals.pop()); return Continue; } ACS_COMMAND(IfNotGoto) { - if(acs.pop()) + if(acs.locals.pop()) { acs.pcodePtr++; } @@ -1270,13 +1306,13 @@ ACS_COMMAND(IfNotGoto) ACS_COMMAND(LineSide) { - acs.push(acs.side); + acs.locals.push(acs.side); return Continue; } ACS_COMMAND(ScriptWait) { - acs.info().waitValue = acs.pop(); + acs.info().waitValue = acs.locals.pop(); acs.info().state = ACScriptInterpreter::WaitingForScript; return Stop; } @@ -1299,10 +1335,10 @@ ACS_COMMAND(ClearLineSpecial) ACS_COMMAND(CaseGoto) { - if(acs.top() == LONG(*acs.pcodePtr++)) + if(acs.locals.top() == LONG(*acs.pcodePtr++)) { acs.pcodePtr = (int *) (acs.interpreter().bytecode() + LONG(*acs.pcodePtr)); - acs.drop(); + acs.locals.drop(); } else { @@ -1354,14 +1390,14 @@ ACS_COMMAND(EndPrintBold) ACS_COMMAND(PrintString) { - strcat(PrintBuffer, Str_Text(acs.interpreter().string(acs.pop()))); + strcat(PrintBuffer, Str_Text(acs.interpreter().string(acs.locals.pop()))); return Continue; } ACS_COMMAND(PrintNumber) { char tempStr[16]; - sprintf(tempStr, "%d", acs.pop()); + sprintf(tempStr, "%d", acs.locals.pop()); strcat(PrintBuffer, tempStr); return Continue; } @@ -1369,7 +1405,7 @@ ACS_COMMAND(PrintNumber) ACS_COMMAND(PrintCharacter) { char *bufferEnd = PrintBuffer + strlen(PrintBuffer); - *bufferEnd++ = acs.pop(); + *bufferEnd++ = acs.locals.pop(); *bufferEnd = 0; return Continue; } @@ -1381,7 +1417,7 @@ ACS_COMMAND(PlayerCount) { count += players[i].plr->inGame; } - acs.push(count); + acs.locals.push(count); return Continue; } @@ -1401,20 +1437,20 @@ ACS_COMMAND(GameType) { gametype = 1; // cooperative } - acs.push(gametype); + acs.locals.push(gametype); return Continue; } ACS_COMMAND(GameSkill) { - acs.push((int)gameSkill); + acs.locals.push((int)gameSkill); return Continue; } ACS_COMMAND(Timer) { - acs.push(mapTime); + acs.locals.push(mapTime); return Continue; } @@ -1426,17 +1462,17 @@ ACS_COMMAND(SectorSound) Sector *front = (Sector *) P_GetPtrp(acs.line, DMU_FRONT_SECTOR); mobj = (mobj_t *) P_GetPtrp(front, DMU_EMITTER); } - int volume = acs.pop(); + int volume = acs.locals.pop(); - S_StartSoundAtVolume(S_GetSoundID(Str_Text(acs.interpreter().string(acs.pop()))), mobj, volume / 127.0f); + S_StartSoundAtVolume(S_GetSoundID(Str_Text(acs.interpreter().string(acs.locals.pop()))), mobj, volume / 127.0f); return Continue; } ACS_COMMAND(ThingSound) { - int volume = acs.pop(); - int sound = S_GetSoundID(Str_Text(acs.interpreter().string(acs.pop()))); - int tid = acs.pop(); + int volume = acs.locals.pop(); + int sound = S_GetSoundID(Str_Text(acs.interpreter().string(acs.locals.pop()))); + int tid = acs.locals.pop(); int searcher = -1; mobj_t *mobj; @@ -1453,7 +1489,7 @@ ACS_COMMAND(AmbientSound) mobj_t *mobj = 0; // For 3D positioning. mobj_t *plrmo = players[DISPLAYPLAYER].plr->mo; - int volume = acs.pop(); + int volume = acs.locals.pop(); // If we are playing 3D sounds, create a temporary source mobj for the sound. if(cfg.snd3D && plrmo) @@ -1470,7 +1506,7 @@ ACS_COMMAND(AmbientSound) } } - int sound = S_GetSoundID(Str_Text(acs.interpreter().string(acs.pop()))); + int sound = S_GetSoundID(Str_Text(acs.interpreter().string(acs.locals.pop()))); S_StartSoundAtVolume(sound, mobj, volume / 127.0f); return Continue; @@ -1484,7 +1520,7 @@ ACS_COMMAND(SoundSequence) Sector *front = (Sector *) P_GetPtrp(acs.line, DMU_FRONT_SECTOR); mobj = (mobj_t *) P_GetPtrp(front, DMU_EMITTER); } - SN_StartSequenceName(mobj, Str_Text(acs.interpreter().string(acs.pop()))); + SN_StartSequenceName(mobj, Str_Text(acs.interpreter().string(acs.locals.pop()))); return Continue; } @@ -1495,15 +1531,15 @@ ACS_COMMAND(SetLineTexture) #define TEXTURE_MIDDLE 1 #define TEXTURE_BOTTOM 2 - AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), acs.interpreter().string(acs.pop()))); + AutoStr *path = Str_PercentEncode(Str_Copy(AutoStr_New(), acs.interpreter().string(acs.locals.pop()))); Uri *uri = Uri_NewWithPath3("Textures", Str_Text(path)); Material *mat = (Material *) P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); Uri_Delete(uri); - int position = acs.pop(); - int side = acs.pop(); - int lineTag = acs.pop(); + int position = acs.locals.pop(); + int side = acs.locals.pop(); + int lineTag = acs.locals.pop(); if(iterlist_t *list = P_GetLineIterListForTag(lineTag, false)) { @@ -1539,8 +1575,8 @@ ACS_COMMAND(SetLineTexture) ACS_COMMAND(SetLineBlocking) { - int lineFlags = acs.pop()? DDLF_BLOCKING : 0; - int lineTag = acs.pop(); + int lineFlags = acs.locals.pop()? DDLF_BLOCKING : 0; + int lineTag = acs.locals.pop(); if(iterlist_t *list = P_GetLineIterListForTag(lineTag, false)) { @@ -1559,13 +1595,13 @@ ACS_COMMAND(SetLineBlocking) ACS_COMMAND(SetLineSpecial) { - int arg5 = acs.pop(); - int arg4 = acs.pop(); - int arg3 = acs.pop(); - int arg2 = acs.pop(); - int arg1 = acs.pop(); - int special = acs.pop(); - int lineTag = acs.pop(); + int arg5 = acs.locals.pop(); + int arg4 = acs.locals.pop(); + int arg3 = acs.locals.pop(); + int arg2 = acs.locals.pop(); + int arg1 = acs.locals.pop(); + int special = acs.locals.pop(); + int lineTag = acs.locals.pop(); if(iterlist_t *list = P_GetLineIterListForTag(lineTag, false)) { @@ -1659,24 +1695,32 @@ void ACScript::runTick() } } -void ACScript::push(int value) +void ACScript::Stack::push(int value) { - stack[stackPtr++] = value; + if(height == ACS_STACK_DEPTH) + App_Log(DE2_SCR_ERROR, "ACScript::Stack::push: Overflow"); + values[height++] = value; } -int ACScript::pop() +int ACScript::Stack::pop() { - return stack[--stackPtr]; + if(height == 0) + App_Log(DE2_SCR_ERROR, "ACScript::Stack::pop: Underflow"); + return values[--height]; } -int ACScript::top() const +int ACScript::Stack::top() const { - return stack[stackPtr - 1]; + if(height == 0) + App_Log(DE2_SCR_ERROR, "ACScript::Stack::top: Underflow"); + return values[height - 1]; } -void ACScript::drop() +void ACScript::Stack::drop() { - stackPtr--; + if(height == 0) + App_Log(DE2_SCR_ERROR, "ACScript::Stack::drop: Underflow"); + height--; } void ACScript::write(Writer *writer) const @@ -1690,9 +1734,9 @@ void ACScript::write(Writer *writer) const Writer_WriteInt32(writer, delayCount); for(uint i = 0; i < ACS_STACK_DEPTH; ++i) { - Writer_WriteInt32(writer, stack[i]); + Writer_WriteInt32(writer, locals.values[i]); } - Writer_WriteInt32(writer, stackPtr); + Writer_WriteInt32(writer, locals.height); for(uint i = 0; i < MAX_ACS_SCRIPT_VARS; ++i) { Writer_WriteInt32(writer, vars[i]); @@ -1731,10 +1775,9 @@ int ACScript::read(Reader *reader, int mapVersion) for(uint i = 0; i < ACS_STACK_DEPTH; ++i) { - stack[i] = Reader_ReadInt32(reader); + locals.values[i] = Reader_ReadInt32(reader); } - - stackPtr = Reader_ReadInt32(reader); + locals.height = Reader_ReadInt32(reader); for(uint i = 0; i < MAX_ACS_SCRIPT_VARS; ++i) { @@ -1772,10 +1815,9 @@ int ACScript::read(Reader *reader, int mapVersion) for(uint i = 0; i < ACS_STACK_DEPTH; ++i) { - stack[i] = Reader_ReadInt32(reader); + locals.values[i] = Reader_ReadInt32(reader); } - - stackPtr = Reader_ReadInt32(reader); + locals.height = Reader_ReadInt32(reader); for(uint i = 0; i < MAX_ACS_SCRIPT_VARS; ++i) { @@ -1790,42 +1832,6 @@ int ACScript::read(Reader *reader, int mapVersion) return true; // Add this thinker. } -AutoStr *ACScriptInterpreter::scriptName(int scriptNumber) -{ - BytecodeScriptInfo *info = scriptInfoPtr(scriptNumber); - if(!info) - { - return AutoStr_FromTextStd("(invalid-scriptnumber)"); - } - bool const open = (info->flags & BytecodeScriptInfo::Open) != 0; - return Str_Appendf(AutoStr_NewStd(), "#%i%s", scriptNumber, open? " (Open)" : ""); -} - -AutoStr *ACScriptInterpreter::scriptDescription(int scriptNumber) -{ - BytecodeScriptInfo *info = scriptInfoPtr(scriptNumber); - if(!info) - { - return AutoStr_FromTextStd("(invalid-scriptnumber)"); - } - - char const *stateLabels[] = { - "Inactive", - "Running", - "Suspended", - "Waiting for tag", - "Waiting for polyobj", - "Waiting for script", - "Terminating" - }; - - return Str_Appendf(AutoStr_NewStd(), "ACScript " DE2_ESC(b) "%s\n" - DE2_ESC(l) "State: " DE2_ESC(.) DE2_ESC(i) "%s" DE2_ESC(.) - DE2_ESC(l) " Wait-for: " DE2_ESC(.) DE2_ESC(i) "%i", - Str_Text(scriptName(scriptNumber)), - stateLabels[info->state], info->waitValue); -} - /// The One ACS interpreter instance. static ACScriptInterpreter interp; From 1b850e5c2d55d8ac44deefa5161e1cd1e0e656a8 Mon Sep 17 00:00:00 2001 From: danij Date: Sat, 1 Feb 2014 07:09:40 +0000 Subject: [PATCH 041/106] Typos --- doomsday/plugins/hexen/include/acscript.h | 2 +- doomsday/plugins/hexen/src/acscript.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doomsday/plugins/hexen/include/acscript.h b/doomsday/plugins/hexen/include/acscript.h index bc3c845f91..326a8fac94 100644 --- a/doomsday/plugins/hexen/include/acscript.h +++ b/doomsday/plugins/hexen/include/acscript.h @@ -47,7 +47,7 @@ typedef struct acscript_s { mobj_t *activator; Line *line; int side; - BytecodeScriptInfo *_info; + struct BytecodeScriptInfo *_info; int delayCount; struct Stack { // Local value stack. int values[ACS_STACK_DEPTH]; diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index b9f6151abd..cd9636b4ae 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -614,7 +614,7 @@ AutoStr *ACScriptInterpreter::scriptDescription(int scriptNumber) return AutoStr_FromTextStd("(invalid-scriptnumber)"); } - char const *stateLabels[] = { + static char const *stateLabels[] = { "Inactive", "Running", "Suspended", From 8932ee5f7c72e4029c8ebd631ea3feeaffecfa4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sat, 1 Feb 2014 10:06:05 +0200 Subject: [PATCH 042/106] Fixed|libcommon|64-bit: Casts from integer to pointer Use the INT2PTR() macro to make casts with the correct integer sizes. --- doomsday/plugins/common/src/p_saveg.cpp | 12 ++++++------ doomsday/plugins/hexen/src/acscript.cpp | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index c03c80e50d..3ad73481d3 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -1434,7 +1434,7 @@ static void SV_ReadPlayer(player_t *p, Reader *reader) { pspdef_t *psp = &p->pSprites[i]; - psp->state = (state_t *) Reader_ReadInt32(reader); + psp->state = INT2PTR(state_t, Reader_ReadInt32(reader)); psp->tics = Reader_ReadInt32(reader); psp->pos[VX] = FIX2FLT(Reader_ReadInt32(reader)); psp->pos[VY] = FIX2FLT(Reader_ReadInt32(reader)); @@ -1950,7 +1950,7 @@ static int SV_ReadMobj(thinker_t *th, Reader *reader, int /*mapVersion*/) mo->ddFlags |= DDMF_DONTDRAW; mo->tics = Reader_ReadInt32(reader); // state tic counter - mo->state = (state_t *) Reader_ReadInt32(reader); + mo->state = INT2PTR(state_t, Reader_ReadInt32(reader)); #if __JHEXEN__ mo->damage = Reader_ReadInt32(reader); @@ -1998,7 +1998,7 @@ static int SV_ReadMobj(thinker_t *th, Reader *reader, int /*mapVersion*/) mo->moveCount = Reader_ReadInt32(reader); // when 0, select a new dir #if __JHEXEN__ - mo->target = (mobj_t *) Reader_ReadInt32(reader); + mo->target = INT2PTR(mobj_t, Reader_ReadInt32(reader)); #endif // Reaction time: if non 0, don't attack yet. @@ -2011,7 +2011,7 @@ static int SV_ReadMobj(thinker_t *th, Reader *reader, int /*mapVersion*/) // Additional info record for player avatars only. // Only valid if type == MT_PLAYER - mo->player = (player_t *) Reader_ReadInt32(reader); + mo->player = INT2PTR(player_t, Reader_ReadInt32(reader)); // Player number last looked for. mo->lastLook = Reader_ReadInt32(reader); @@ -2098,10 +2098,10 @@ static int SV_ReadMobj(thinker_t *th, Reader *reader, int /*mapVersion*/) #if __JHEXEN__ if(ver >= 4) - mo->tracer = (mobj_t *) Reader_ReadInt32(reader); + mo->tracer = INT2PTR(mobj_t, Reader_ReadInt32(reader)); if(ver >= 4) - mo->lastEnemy = (mobj_t *) Reader_ReadInt32(reader); + mo->lastEnemy = INT2PTR(mobj_t, Reader_ReadInt32(reader)); #else if(ver >= 5) mo->floorClip = FIX2FLT(Reader_ReadInt32(reader)); diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index cd9636b4ae..8faa124acf 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -1751,7 +1751,7 @@ int ACScript::read(Reader *reader, int mapVersion) // Note: the thinker class byte has already been read. int ver = Reader_ReadByte(reader); // version byte. - activator = (mobj_t *) Reader_ReadInt32(reader); + activator = INT2PTR(mobj_t, Reader_ReadInt32(reader)); activator = SV_GetArchiveThing(PTR2INT(activator), &activator); int temp = Reader_ReadInt32(reader); @@ -1794,7 +1794,7 @@ int ACScript::read(Reader *reader, int mapVersion) Reader_Read(reader, junk, 16); // Start of used data members. - activator = (mobj_t *) Reader_ReadInt32(reader); + activator = INT2PTR(mobj_t, Reader_ReadInt32(reader)); activator = SV_GetArchiveThing(PTR2INT(activator), &activator); int temp = Reader_ReadInt32(reader); From 7879a29e40b2772070c8a8351fb1932ea55de4e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sat, 1 Feb 2014 10:06:05 +0200 Subject: [PATCH 043/106] Fixed|libcommon|64-bit: Casts from integer to pointer Use the INT2PTR() macro to make casts with the correct integer sizes. --- doomsday/plugins/common/src/p_saveg.cpp | 12 ++++++------ doomsday/plugins/hexen/src/acscript.cpp | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index c03c80e50d..3ad73481d3 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -1434,7 +1434,7 @@ static void SV_ReadPlayer(player_t *p, Reader *reader) { pspdef_t *psp = &p->pSprites[i]; - psp->state = (state_t *) Reader_ReadInt32(reader); + psp->state = INT2PTR(state_t, Reader_ReadInt32(reader)); psp->tics = Reader_ReadInt32(reader); psp->pos[VX] = FIX2FLT(Reader_ReadInt32(reader)); psp->pos[VY] = FIX2FLT(Reader_ReadInt32(reader)); @@ -1950,7 +1950,7 @@ static int SV_ReadMobj(thinker_t *th, Reader *reader, int /*mapVersion*/) mo->ddFlags |= DDMF_DONTDRAW; mo->tics = Reader_ReadInt32(reader); // state tic counter - mo->state = (state_t *) Reader_ReadInt32(reader); + mo->state = INT2PTR(state_t, Reader_ReadInt32(reader)); #if __JHEXEN__ mo->damage = Reader_ReadInt32(reader); @@ -1998,7 +1998,7 @@ static int SV_ReadMobj(thinker_t *th, Reader *reader, int /*mapVersion*/) mo->moveCount = Reader_ReadInt32(reader); // when 0, select a new dir #if __JHEXEN__ - mo->target = (mobj_t *) Reader_ReadInt32(reader); + mo->target = INT2PTR(mobj_t, Reader_ReadInt32(reader)); #endif // Reaction time: if non 0, don't attack yet. @@ -2011,7 +2011,7 @@ static int SV_ReadMobj(thinker_t *th, Reader *reader, int /*mapVersion*/) // Additional info record for player avatars only. // Only valid if type == MT_PLAYER - mo->player = (player_t *) Reader_ReadInt32(reader); + mo->player = INT2PTR(player_t, Reader_ReadInt32(reader)); // Player number last looked for. mo->lastLook = Reader_ReadInt32(reader); @@ -2098,10 +2098,10 @@ static int SV_ReadMobj(thinker_t *th, Reader *reader, int /*mapVersion*/) #if __JHEXEN__ if(ver >= 4) - mo->tracer = (mobj_t *) Reader_ReadInt32(reader); + mo->tracer = INT2PTR(mobj_t, Reader_ReadInt32(reader)); if(ver >= 4) - mo->lastEnemy = (mobj_t *) Reader_ReadInt32(reader); + mo->lastEnemy = INT2PTR(mobj_t, Reader_ReadInt32(reader)); #else if(ver >= 5) mo->floorClip = FIX2FLT(Reader_ReadInt32(reader)); diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index cd9636b4ae..8faa124acf 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -1751,7 +1751,7 @@ int ACScript::read(Reader *reader, int mapVersion) // Note: the thinker class byte has already been read. int ver = Reader_ReadByte(reader); // version byte. - activator = (mobj_t *) Reader_ReadInt32(reader); + activator = INT2PTR(mobj_t, Reader_ReadInt32(reader)); activator = SV_GetArchiveThing(PTR2INT(activator), &activator); int temp = Reader_ReadInt32(reader); @@ -1794,7 +1794,7 @@ int ACScript::read(Reader *reader, int mapVersion) Reader_Read(reader, junk, 16); // Start of used data members. - activator = (mobj_t *) Reader_ReadInt32(reader); + activator = INT2PTR(mobj_t, Reader_ReadInt32(reader)); activator = SV_GetArchiveThing(PTR2INT(activator), &activator); int temp = Reader_ReadInt32(reader); From de7cb077063a9826d6f651eabcdd3ead657d035a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sat, 1 Feb 2014 10:42:38 +0200 Subject: [PATCH 044/106] libdeng2|Time: Better time formatting for log entries If more than an hour has elapsed, separate hours from seconds. --- doomsday/libdeng2/include/de/math.h | 5 +++++ doomsday/libdeng2/src/data/time.cpp | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/doomsday/libdeng2/include/de/math.h b/doomsday/libdeng2/include/de/math.h index 2ea9b98d93..3a32e8566e 100644 --- a/doomsday/libdeng2/include/de/math.h +++ b/doomsday/libdeng2/include/de/math.h @@ -111,6 +111,11 @@ inline dint64 ceil(ddouble const &value) { return dint64(std::ceil(value)); } +template +inline Type fract(Type const &value) { + return value - std::floor(value); +} + /// Compare two single-precision floating-point values for equality, /// with the precision of FLOAT_EPSILON. inline bool fequal(dfloat a, dfloat b) { diff --git a/doomsday/libdeng2/src/data/time.cpp b/doomsday/libdeng2/src/data/time.cpp index b145def1b6..0e7fffa212 100644 --- a/doomsday/libdeng2/src/data/time.cpp +++ b/doomsday/libdeng2/src/data/time.cpp @@ -308,8 +308,19 @@ String Time::asText(Format format) const } else if(format == BuildNumberAndSecondsSinceStart) { - return QString("#%1 %2").arg(asBuildNumber(), -4) - .arg(highPerfTimer.elapsed(), 7, 'f', 3, '0'); + TimeDelta const elapsed = highPerfTimer.elapsed(); + int hours = elapsed.asHours(); + double sec = elapsed - hours * 3600.0; + if(hours > 0) + { + return QString("#%1 %2h%3") + .arg(asBuildNumber(), -4) + .arg(hours) + .arg(sec, 7, 'f', 3, '0'); + } + return QString("#%1 %2") + .arg(asBuildNumber(), -4) + .arg(sec, 7, 'f', 3, '0'); } else { From da2c7823959f135282af61b32124567579bd2108 Mon Sep 17 00:00:00 2001 From: danij Date: Sat, 1 Feb 2014 10:10:19 +0000 Subject: [PATCH 045/106] Fixed|libcommon: Compiler warnings (unused parameters) --- doomsday/plugins/common/src/p_saveg.cpp | 14 ++++++++++++++ doomsday/plugins/common/src/p_xgsave.cpp | 2 +- doomsday/plugins/hexen/src/acscript.cpp | 3 +++ doomsday/plugins/hexen/src/p_pillar.cpp | 2 +- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index 3ad73481d3..aff6e0a26c 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -3365,6 +3365,8 @@ static void writeBrain(Writer *writer) { Writer_WriteInt16(writer, SV_ThingArchiveId(brain.targets[i])); } +#else + DENG_UNUSED(writer); #endif } @@ -3398,6 +3400,9 @@ static void readBrain(Reader *reader, int mapVersion) { P_BrainAddTarget(SV_GetArchiveThing((int) Reader_ReadInt16(reader), 0)); } +#else + DENG_UNUSED(reader); + DENG_UNUSED(mapVersion); #endif } @@ -3421,6 +3426,8 @@ static void writeSoundTargets(Writer *writer) Writer_WriteInt16(writer, SV_ThingArchiveId(xsec->soundTarget)); } } +#else + DENG_UNUSED(writer); #endif } @@ -3451,6 +3458,9 @@ static void readSoundTargets(Reader *reader, int mapVersion) xsec->soundTarget = SV_GetArchiveThing(PTR2INT(xsec->soundTarget), &xsec->soundTarget); } +#else + DENG_UNUSED(reader); + DENG_UNUSED(mapVersion); #endif } @@ -3463,6 +3473,8 @@ static void writeMisc(Writer *writer) { Writer_WriteInt32(writer, localQuakeHappening[i]); } +#else + DENG_UNUSED(writer); #endif } @@ -3475,6 +3487,8 @@ static void readMisc(Reader *reader, int /*mapVersion*/) { localQuakeHappening[i] = Reader_ReadInt32(reader); } +#else + DENG_UNUSED(reader); #endif } diff --git a/doomsday/plugins/common/src/p_xgsave.cpp b/doomsday/plugins/common/src/p_xgsave.cpp index b2ce76d7e6..f4b67d9f2c 100644 --- a/doomsday/plugins/common/src/p_xgsave.cpp +++ b/doomsday/plugins/common/src/p_xgsave.cpp @@ -201,7 +201,7 @@ void xgplanemover_t::write(Writer *writer) const Writer_WriteInt32(writer, timer); } -int xgplanemover_t::read(Reader *reader, int mapVersion) +int xgplanemover_t::read(Reader *reader, int /*mapVersion*/) { byte ver = Reader_ReadByte(reader); // Version. diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index 8faa124acf..0a29d3d8d3 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -1876,6 +1876,7 @@ void ACScript_Thinker(ACScript *script) D_CMD(InspectACScript) { DENG_UNUSED(src); + DENG_UNUSED(argc); if(!interp.scriptCount()) { @@ -1897,6 +1898,8 @@ D_CMD(InspectACScript) D_CMD(ListACScripts) { DENG_UNUSED(src); + DENG_UNUSED(argc); + DENG_UNUSED(argv); if(!interp.scriptCount()) { diff --git a/doomsday/plugins/hexen/src/p_pillar.cpp b/doomsday/plugins/hexen/src/p_pillar.cpp index 7aa2419d76..36fbf3662c 100644 --- a/doomsday/plugins/hexen/src/p_pillar.cpp +++ b/doomsday/plugins/hexen/src/p_pillar.cpp @@ -177,7 +177,7 @@ int EV_BuildPillar(Line * /*line*/, byte *args, dd_bool crush) return rtn; } -int EV_OpenPillar(Line *line, byte *args) +int EV_OpenPillar(Line * /*line*/, byte *args) { iterlist_t *list = P_GetSectorIterListForTag((int) args[0], false); if(!list) return 0; From 88f7eeb37d436032368067faf604ca062776ba1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sat, 1 Feb 2014 15:36:25 +0200 Subject: [PATCH 046/106] UI|Client|CVarLineEditWidget: Added a line editor for cvars --- doomsday/client/client.pro | 2 + .../include/ui/widgets/cvarlineeditwidget.h | 51 +++++++++++++ .../src/ui/widgets/cvarlineeditwidget.cpp | 76 +++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 doomsday/client/include/ui/widgets/cvarlineeditwidget.h create mode 100644 doomsday/client/src/ui/widgets/cvarlineeditwidget.cpp diff --git a/doomsday/client/client.pro b/doomsday/client/client.pro index f504c2280c..cacac01f5c 100644 --- a/doomsday/client/client.pro +++ b/doomsday/client/client.pro @@ -389,6 +389,7 @@ DENG_HEADERS += \ include/ui/widgets/consolecommandwidget.h \ include/ui/widgets/consolewidget.h \ include/ui/widgets/cvarchoicewidget.h \ + include/ui/widgets/cvarlineeditwidget.h \ include/ui/widgets/cvarsliderwidget.h \ include/ui/widgets/cvartogglewidget.h \ include/ui/widgets/gameselectionwidget.h \ @@ -725,6 +726,7 @@ SOURCES += \ src/ui/widgets/consolecommandwidget.cpp \ src/ui/widgets/consolewidget.cpp \ src/ui/widgets/cvarchoicewidget.cpp \ + src/ui/widgets/cvarlineeditwidget.cpp \ src/ui/widgets/cvarsliderwidget.cpp \ src/ui/widgets/cvartogglewidget.cpp \ src/ui/widgets/gameselectionwidget.cpp \ diff --git a/doomsday/client/include/ui/widgets/cvarlineeditwidget.h b/doomsday/client/include/ui/widgets/cvarlineeditwidget.h new file mode 100644 index 0000000000..4ba2e3c03b --- /dev/null +++ b/doomsday/client/include/ui/widgets/cvarlineeditwidget.h @@ -0,0 +1,51 @@ +/** @file cvarlineeditwidget.h Console variable edit widget. + * + * @authors Copyright (c) 2014 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, see: + * http://www.gnu.org/licenses + */ + +#ifndef DENG_CLIENT_CVARLINEEDITWIDGET_H +#define DENG_CLIENT_CVARLINEEDITWIDGET_H + +#include +#include "icvarwidget.h" + +/** + * Console variable text editor. + */ +class CVarLineEditWidget : public de::LineEditWidget, public ICVarWidget +{ + Q_OBJECT + +public: + CVarLineEditWidget(char const *cvarPath); + + char const *cvarPath() const; + +public slots: + void updateFromCVar(); + void endEditing(); + +protected slots: + void setCVarValueFromWidget(); + +protected: + void contentChanged(); + +private: + DENG2_PRIVATE(d) +}; + +#endif // DENG_CLIENT_CVARLINEEDITWIDGET_H diff --git a/doomsday/client/src/ui/widgets/cvarlineeditwidget.cpp b/doomsday/client/src/ui/widgets/cvarlineeditwidget.cpp new file mode 100644 index 0000000000..dbdfd1b1bc --- /dev/null +++ b/doomsday/client/src/ui/widgets/cvarlineeditwidget.cpp @@ -0,0 +1,76 @@ +/** @file cvarlineeditwidget.cpp + * + * @authors Copyright (c) 2014 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, see: + * http://www.gnu.org/licenses + */ + +#include "ui/widgets/cvarlineeditwidget.h" +#include "con_main.h" + +using namespace de; +using namespace ui; + +DENG2_PIMPL_NOREF(CVarLineEditWidget) +{ + char const *cvar; + + cvar_t *var() const + { + cvar_t *cv = Con_FindVariable(cvar); + DENG2_ASSERT(cv != 0); + return cv; + } +}; + +CVarLineEditWidget::CVarLineEditWidget(char const *cvarPath) + : d(new Instance) +{ + setSignalOnEnter(true); + connect(this, SIGNAL(enterPressed(QString)), this, SLOT(endEditing())); + + d->cvar = cvarPath; + updateFromCVar(); +} + +void CVarLineEditWidget::contentChanged() +{ + LineEditWidget::contentChanged(); + + if(String(CVar_String(d->var())) != text()) + { + setCVarValueFromWidget(); + } +} + +char const *CVarLineEditWidget::cvarPath() const +{ + return d->cvar; +} + +void CVarLineEditWidget::updateFromCVar() +{ + setText(CVar_String(d->var())); +} + +void CVarLineEditWidget::endEditing() +{ + root().setFocus(0); +} + +void CVarLineEditWidget::setCVarValueFromWidget() +{ + CVar_SetString(d->var(), text().toUtf8()); +} + From c1723996e5e7c3e44a96d2153772cd821db5ab08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sat, 1 Feb 2014 15:36:56 +0200 Subject: [PATCH 047/106] libdeng2|ScalarRule: Added method to finish current animation --- doomsday/libdeng2/include/de/widgets/scalarrule.h | 2 ++ doomsday/libdeng2/src/widgets/scalarrule.cpp | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/doomsday/libdeng2/include/de/widgets/scalarrule.h b/doomsday/libdeng2/include/de/widgets/scalarrule.h index de0cc2683c..8959a4a2ff 100644 --- a/doomsday/libdeng2/include/de/widgets/scalarrule.h +++ b/doomsday/libdeng2/include/de/widgets/scalarrule.h @@ -64,6 +64,8 @@ class DENG2_PUBLIC ScalarRule : public Rule, DENG2_OBSERVES(Clock, TimeChange) */ void shift(float delta); + void finish(); + String description() const; protected: diff --git a/doomsday/libdeng2/src/widgets/scalarrule.cpp b/doomsday/libdeng2/src/widgets/scalarrule.cpp index c2e22c8afb..3d37ac2c54 100644 --- a/doomsday/libdeng2/src/widgets/scalarrule.cpp +++ b/doomsday/libdeng2/src/widgets/scalarrule.cpp @@ -69,6 +69,11 @@ void ScalarRule::shift(float delta) invalidate(); } +void ScalarRule::finish() +{ + _animation.finish(); +} + String ScalarRule::description() const { String desc = "Scalar(" + _animation.asText(); From 723a51243c248c219e6ca1217516654143efbe86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sat, 1 Feb 2014 15:37:42 +0200 Subject: [PATCH 048/106] Fixed|LineEditWidget|libappfw: Don't animate height immediately after creation --- .../libappfw/src/widgets/lineeditwidget.cpp | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/doomsday/libappfw/src/widgets/lineeditwidget.cpp b/doomsday/libappfw/src/widgets/lineeditwidget.cpp index cba9516323..8d65f53af0 100644 --- a/doomsday/libappfw/src/widgets/lineeditwidget.cpp +++ b/doomsday/libappfw/src/widgets/lineeditwidget.cpp @@ -44,10 +44,10 @@ DENG_GUI_PIMPL(LineEditWidget) FontLineWrapping &wraps; LabelWidget *hint; bool signalOnEnter; + bool firstUpdateAfterCreation; // Style. Font const *font; - int margin; Time blinkTime; Animation hovering; @@ -59,16 +59,16 @@ DENG_GUI_PIMPL(LineEditWidget) GLUniform uCursorColor; Instance(Public *i) - : Base(i), - wraps(static_cast(i->lineWraps())), - hint(0), - signalOnEnter(false), - font(0), - margin(0), - hovering(0, Animation::Linear), - uMvpMatrix ("uMvpMatrix", GLUniform::Mat4), - uColor ("uColor", GLUniform::Vec4), - uCursorColor("uColor", GLUniform::Vec4) + : Base(i) + , wraps(static_cast(i->lineWraps())) + , hint(0) + , signalOnEnter(false) + , firstUpdateAfterCreation(true) + , font(0) + , hovering(0, Animation::Linear) + , uMvpMatrix ("uMvpMatrix", GLUniform::Mat4) + , uColor ("uColor", GLUniform::Vec4) + , uCursorColor("uColor", GLUniform::Vec4) { height = new ScalarRule(0); @@ -89,7 +89,6 @@ DENG_GUI_PIMPL(LineEditWidget) void updateStyle() { font = &self.font(); - margin = style().rules().rule("gap").valuei(); updateBackground(); @@ -104,7 +103,7 @@ DENG_GUI_PIMPL(LineEditWidget) int calculateHeight() { int const hgt = de::max(font->height().valuei(), wraps.totalHeightInPixels()); - return hgt + 2 * margin; + return hgt + self.margins().height().valuei(); } void updateProjection() @@ -214,7 +213,8 @@ DENG_GUI_PIMPL(LineEditWidget) inline Rectanglei contentRect() const { - return self.rule().recti().shrunk(margin); + Vector4i const margins = self.margins().toVector(); + return self.rule().recti().adjusted(margins.xy(), -margins.zw()); } }; @@ -345,6 +345,13 @@ void LineEditWidget::update() // Rewrap content if necessary. updateLineWraps(WrapUnlessWrappedAlready); + + if(d->firstUpdateAfterCreation) + { + // Don't animate height immediately after creation. + d->firstUpdateAfterCreation = false; + d->height->finish(); + } } void LineEditWidget::drawContent() @@ -450,7 +457,7 @@ shell::AbstractLineEditor::KeyModifiers LineEditWidget::modifiersFromKeyEvent(Ke int LineEditWidget::maximumWidth() const { - return rule().recti().width() - 2 * d->margin; + return rule().recti().width() - margins().width().valuei(); } void LineEditWidget::numberOfLinesChanged(int /*lineCount*/) From 40cd9fe70f5f48664efcc192ba15bf673ba8a100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sat, 1 Feb 2014 15:38:15 +0200 Subject: [PATCH 049/106] UI|Client: Working on network settings and the multiplayer dialog --- .../client/data/defaultstyle.pack/rules.dei | 1 + .../ui/dialogs/networksettingsdialog.h | 1 + .../src/ui/dialogs/multiplayerdialog.cpp | 23 ++++++------ .../src/ui/dialogs/networksettingsdialog.cpp | 36 +++++++++++++++---- .../client/src/ui/widgets/taskbarwidget.cpp | 2 +- 5 files changed, 45 insertions(+), 18 deletions(-) diff --git a/doomsday/client/data/defaultstyle.pack/rules.dei b/doomsday/client/data/defaultstyle.pack/rules.dei index 163e852914..9f533dfafa 100644 --- a/doomsday/client/data/defaultstyle.pack/rules.dei +++ b/doomsday/client/data/defaultstyle.pack/rules.dei @@ -21,6 +21,7 @@ group document { } group editor { + rule width { constant $= UNIT * 55 } rule completion.height { constant $= UNIT * 100 } } diff --git a/doomsday/client/include/ui/dialogs/networksettingsdialog.h b/doomsday/client/include/ui/dialogs/networksettingsdialog.h index 64a47577dd..6b8a0f4b24 100644 --- a/doomsday/client/include/ui/dialogs/networksettingsdialog.h +++ b/doomsday/client/include/ui/dialogs/networksettingsdialog.h @@ -33,6 +33,7 @@ class NetworkSettingsDialog : public de::DialogWidget public slots: void resetToDefaults(); + void showDeveloperPopup(); private: DENG2_PRIVATE(d) diff --git a/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp b/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp index f7095e9d6a..3436e4a995 100644 --- a/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp +++ b/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp @@ -23,6 +23,7 @@ #include "con_main.h" #include "CommandAction" #include "ui/widgets/taskbarwidget.h" +#include "ui/dialogs/networksettingsdialog.h" #include #include @@ -37,11 +38,14 @@ DENG_GUI_PIMPL(MultiplayerDialog) , DENG2_OBSERVES(ServerLink, DiscoveryUpdate) , public ChildWidgetOrganizer::IWidgetFactory { - static String hostId(serverinfo_t const &sv) - { + static ServerLink &link() { return ClientApp::serverLink(); } + static String hostId(serverinfo_t const &sv) { return String("%1:%2").arg(sv.address).arg(sv.port); } + /** + * Data item with information about a found server. + */ class ServerListItem : public ui::Item { public: @@ -254,11 +258,6 @@ DENG_GUI_PIMPL(MultiplayerDialog) } } } - - static ServerLink &link() - { - return ClientApp::serverLink(); - } }; MultiplayerDialog::MultiplayerDialog(String const &name) @@ -277,12 +276,16 @@ MultiplayerDialog::MultiplayerDialog(String const &name) area().setContentSize(layout.width(), layout.height()); buttons() - << new DialogButtonItem(DialogWidget::Default | DialogWidget::Accept, tr("Close")) - << new DialogButtonItem(DialogWidget::Action, style().images().image("gear"), + << new DialogButtonItem(Default | Accept, tr("Close")) + << new DialogButtonItem(Action | Id1, + style().images().image("gear"), new SignalAction(this, SLOT(showSettings()))); } void MultiplayerDialog::showSettings() { - + NetworkSettingsDialog *dlg = new NetworkSettingsDialog; + dlg->setAnchorAndOpeningDirection(buttonWidget(Id1)->rule(), ui::Up); + dlg->setDeleteAfterDismissed(true); + dlg->exec(root()); } diff --git a/doomsday/client/src/ui/dialogs/networksettingsdialog.cpp b/doomsday/client/src/ui/dialogs/networksettingsdialog.cpp index cffb443ed8..25959c2912 100644 --- a/doomsday/client/src/ui/dialogs/networksettingsdialog.cpp +++ b/doomsday/client/src/ui/dialogs/networksettingsdialog.cpp @@ -20,24 +20,35 @@ #include "ui/widgets/cvarsliderwidget.h" #include "ui/widgets/cvartogglewidget.h" #include "ui/widgets/cvarchoicewidget.h" +#include "ui/widgets/cvarlineeditwidget.h" #include "de_audio.h" #include "con_main.h" #include +#include using namespace de; using namespace ui; DENG_GUI_PIMPL(NetworkSettingsDialog) { + CVarLineEditWidget *masterUrl; + GridPopupWidget *devPopup; CVarToggleWidget *devInfo; Instance(Public *i) : Base(i) { ScrollAreaWidget &area = self.area(); - area.add(devInfo = new CVarToggleWidget("net-dev")); + area.add(masterUrl = new CVarLineEditWidget("net-master-address")); + masterUrl->rule().setInput(Rule::Width, style().rules().rule("editor.width")); + + // Developer options. + self.add(devPopup = new GridPopupWidget); + devPopup->layout().setGridSize(1, 0); + *devPopup << (devInfo = new CVarToggleWidget("net-dev")); + devPopup->commit(); } void fetch() @@ -53,18 +64,24 @@ NetworkSettingsDialog::NetworkSettingsDialog(String const &name) d->devInfo->setText(tr("Developer Info")); + LabelWidget *masterUrlLabel = LabelWidget::newWithText(tr("Master URL:"), &area()); + // Layout. GridLayout layout(area().contentRule().left(), area().contentRule().top()); - layout.setGridSize(1, 0); - //layout.setColumnAlignment(0, ui::AlignRight); - layout << *d->devInfo; + layout.setGridSize(2, 0); + layout.setColumnAlignment(0, ui::AlignRight); + layout << *masterUrlLabel << *d->masterUrl; area().setContentSize(layout.width(), layout.height()); buttons() - << new DialogButtonItem(DialogWidget::Default | DialogWidget::Accept, tr("Close")) - << new DialogButtonItem(DialogWidget::Action, tr("Reset to Defaults"), - new SignalAction(this, SLOT(resetToDefaults()))); + << new DialogButtonItem(Default | Accept, tr("Close")) + << new DialogButtonItem(Action, tr("Reset to Defaults"), + new SignalAction(this, SLOT(resetToDefaults()))) + << new DialogButtonItem(Action | Id1, style().images().image("gauge"), + new SignalAction(this, SLOT(showDeveloperPopup()))); + + d->devPopup->setAnchorAndOpeningDirection(buttonWidget(Id1)->rule(), ui::Up); d->fetch(); } @@ -75,3 +92,8 @@ void NetworkSettingsDialog::resetToDefaults() d->fetch(); } + +void NetworkSettingsDialog::showDeveloperPopup() +{ + d->devPopup->open(); +} diff --git a/doomsday/client/src/ui/widgets/taskbarwidget.cpp b/doomsday/client/src/ui/widgets/taskbarwidget.cpp index 04ab4d2618..c9f35c845d 100644 --- a/doomsday/client/src/ui/widgets/taskbarwidget.cpp +++ b/doomsday/client/src/ui/widgets/taskbarwidget.cpp @@ -403,7 +403,7 @@ TaskBarWidget::TaskBarWidget() : GuiWidget("taskbar"), d(new Instance(this)) << new ui::SubwidgetItem(style().images().image("updater"), tr("Updater"), ui::Left, makeUpdaterSettings); d->mainMenu->items() - << new ui::SubwidgetItem(tr("Multiplayer Games..."), ui::Left, makePopup) + << new ui::SubwidgetItem(tr("Multiplayer Games"), ui::Left, makePopup) << new ui::Item(ui::Item::Separator) << new ui::ActionItem(tr("Check for Updates..."), new CommandAction("updateandnotify")) << new ui::ActionItem(tr("About Doomsday"), new SignalAction(this, SLOT(showAbout()))) From ea78196edc41ecb3c280158bf8387fd1856a12f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sat, 1 Feb 2014 16:06:02 +0200 Subject: [PATCH 050/106] UI|Client: Added more network settings to the dialog --- doomsday/client/include/clientapp.h | 1 + doomsday/client/src/clientapp.cpp | 12 ++++++++++ .../src/ui/dialogs/networksettingsdialog.cpp | 22 ++++++++++++++----- .../libappfw/src/dialogcontentstylist.cpp | 6 +++++ 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/doomsday/client/include/clientapp.h b/doomsday/client/include/clientapp.h index 700a926650..4e2c1cb742 100644 --- a/doomsday/client/include/clientapp.h +++ b/doomsday/client/include/clientapp.h @@ -65,6 +65,7 @@ class ClientApp : public de::BaseGuiApp static ClientApp &app(); static Updater &updater(); static SettingsRegister &logSettings(); + static SettingsRegister &networkSettings(); static SettingsRegister &audioSettings(); ///< @todo Belongs in AudioSystem. static ServerLink &serverLink(); static InputSystem &inputSystem(); diff --git a/doomsday/client/src/clientapp.cpp b/doomsday/client/src/clientapp.cpp index 698bbbeadf..d854ea1325 100644 --- a/doomsday/client/src/clientapp.cpp +++ b/doomsday/client/src/clientapp.cpp @@ -157,6 +157,7 @@ DENG2_PIMPL(ClientApp) Binder binder; QScopedPointer updater; SettingsRegister audioSettings; + SettingsRegister networkSettings; SettingsRegister logSettings; QMenuBar *menuBar; InputSystem *inputSys; @@ -270,6 +271,12 @@ DENG2_PIMPL(ClientApp) /// @todo These belong in their respective subsystems. + networkSettings + .define(SReg::StringCVar, "net-master-address", "www.dengine.net") + .define(SReg::StringCVar, "net-master-path", "/master.php") + .define(SReg::IntCVar, "net-master-port", 80) + .define(SReg::IntCVar, "net-dev", 0); + audioSettings .define(SReg::IntCVar, "sound-volume", 255) .define(SReg::IntCVar, "music-volume", 255) @@ -478,6 +485,11 @@ SettingsRegister &ClientApp::logSettings() return app().d->logSettings; } +SettingsRegister &ClientApp::networkSettings() +{ + return app().d->networkSettings; +} + SettingsRegister &ClientApp::audioSettings() { return app().d->audioSettings; diff --git a/doomsday/client/src/ui/dialogs/networksettingsdialog.cpp b/doomsday/client/src/ui/dialogs/networksettingsdialog.cpp index 25959c2912..95312ee5a7 100644 --- a/doomsday/client/src/ui/dialogs/networksettingsdialog.cpp +++ b/doomsday/client/src/ui/dialogs/networksettingsdialog.cpp @@ -22,6 +22,7 @@ #include "ui/widgets/cvarchoicewidget.h" #include "ui/widgets/cvarlineeditwidget.h" +#include "clientapp.h" #include "de_audio.h" #include "con_main.h" @@ -34,6 +35,7 @@ using namespace ui; DENG_GUI_PIMPL(NetworkSettingsDialog) { CVarLineEditWidget *masterUrl; + CVarLineEditWidget *masterPath; GridPopupWidget *devPopup; CVarToggleWidget *devInfo; @@ -41,8 +43,8 @@ DENG_GUI_PIMPL(NetworkSettingsDialog) { ScrollAreaWidget &area = self.area(); - area.add(masterUrl = new CVarLineEditWidget("net-master-address")); - masterUrl->rule().setInput(Rule::Width, style().rules().rule("editor.width")); + area.add(masterUrl = new CVarLineEditWidget("net-master-address")); + area.add(masterPath = new CVarLineEditWidget("net-master-path")); // Developer options. self.add(devPopup = new GridPopupWidget); @@ -53,7 +55,13 @@ DENG_GUI_PIMPL(NetworkSettingsDialog) void fetch() { - devInfo->updateFromCVar(); + foreach(Widget *w, self.area().childWidgets() + devPopup->content().childWidgets()) + { + if(ICVarWidget *cv = w->maybeAs()) + { + cv->updateFromCVar(); + } + } } }; @@ -64,13 +72,15 @@ NetworkSettingsDialog::NetworkSettingsDialog(String const &name) d->devInfo->setText(tr("Developer Info")); - LabelWidget *masterUrlLabel = LabelWidget::newWithText(tr("Master URL:"), &area()); + LabelWidget *masterUrlLabel = LabelWidget::newWithText(tr("Master URL:"), &area()); + LabelWidget *masterPathLabel = LabelWidget::newWithText(tr("Path:"), &area()); // Layout. GridLayout layout(area().contentRule().left(), area().contentRule().top()); layout.setGridSize(2, 0); layout.setColumnAlignment(0, ui::AlignRight); - layout << *masterUrlLabel << *d->masterUrl; + layout << *masterUrlLabel << *d->masterUrl + << *masterPathLabel << *d->masterPath; area().setContentSize(layout.width(), layout.height()); @@ -88,7 +98,7 @@ NetworkSettingsDialog::NetworkSettingsDialog(String const &name) void NetworkSettingsDialog::resetToDefaults() { - Con_SetInteger("net-dev", 0); + ClientApp::networkSettings().resetToDefaults(); d->fetch(); } diff --git a/doomsday/libappfw/src/dialogcontentstylist.cpp b/doomsday/libappfw/src/dialogcontentstylist.cpp index ba06cf04c6..771eb7be13 100644 --- a/doomsday/libappfw/src/dialogcontentstylist.cpp +++ b/doomsday/libappfw/src/dialogcontentstylist.cpp @@ -20,6 +20,7 @@ #include "de/DialogWidget" #include "de/ToggleWidget" #include "de/LabelWidget" +#include "de/LineEditWidget" namespace de { @@ -75,6 +76,11 @@ void DialogContentStylist::applyStyle(GuiWidget &w) { tog->set(GuiWidget::Background()); } + + if(LineEditWidget *ed = w.maybeAs()) + { + ed->rule().setInput(Rule::Width, _container->style().rules().rule("editor.width")); + } } } // namespace de From 6cc8d9e4c94804f58c1bf04f79f553aa31d9af25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sat, 1 Feb 2014 16:56:29 +0200 Subject: [PATCH 051/106] UI|Ring Zero: Center game selection menu in available space --- doomsday/client/src/ui/clientwindow.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/doomsday/client/src/ui/clientwindow.cpp b/doomsday/client/src/ui/clientwindow.cpp index 97b4a2bde6..89653c939a 100644 --- a/doomsday/client/src/ui/clientwindow.cpp +++ b/doomsday/client/src/ui/clientwindow.cpp @@ -193,7 +193,7 @@ DENG2_OBSERVES(App, StartupComplete) gameSelMenu = new GameSelectionWidget; gameSelMenu->rule() .setInput(Rule::AnchorX, root.viewLeft() + root.viewWidth() / 2) - .setInput(Rule::AnchorY, root.viewTop() + root.viewHeight() / 2) + //.setInput(Rule::AnchorY, root.viewTop() + root.viewHeight() / 2) .setInput(Rule::Width, OperatorRule::minimum(root.viewWidth(), style.rules().rule("gameselection.max.width"))) .setAnchorPoint(Vector2f(.5f, .5f)); @@ -224,9 +224,14 @@ DENG2_OBSERVES(App, StartupComplete) container().add(taskBar); // The game selection's height depends on the taskbar. - gameSelMenu->rule().setInput(Rule::Height, - OperatorRule::minimum(root.viewHeight(), - (taskBar->rule().top() - root.viewHeight() / 2) * 2, style.rules().rule("gameselection.max.height"))); + gameSelMenu->rule() + .setInput(Rule::AnchorY, taskBar->rule().top() / 2) + .setInput(Rule::Height, + OperatorRule::minimum(style.rules().rule("gameselection.max.height"), + taskBar->rule().top())); + /*OperatorRule::minimum(root.viewHeight(), + (taskBar->rule().top() - root.viewHeight() / 2) * 2, + style.rules().rule("gameselection.max.height")));*/ // Color adjustment dialog. colorAdjust = new ColorAdjustmentDialog; From de244c61dd702e6debc9060949f1376a7269349a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sat, 1 Feb 2014 16:57:03 +0200 Subject: [PATCH 052/106] libappfw|SliderWidget: Use defined precision in edit popup --- doomsday/libappfw/include/de/widgets/sliderwidget.h | 1 + doomsday/libappfw/src/widgets/sliderwidget.cpp | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/doomsday/libappfw/include/de/widgets/sliderwidget.h b/doomsday/libappfw/include/de/widgets/sliderwidget.h index 7b75ffdea5..d9f5666026 100644 --- a/doomsday/libappfw/include/de/widgets/sliderwidget.h +++ b/doomsday/libappfw/include/de/widgets/sliderwidget.h @@ -56,6 +56,7 @@ class LIBAPPFW_PUBLIC SliderWidget : public GuiWidget Ranged range() const; ddouble value() const; + int precision() const; ddouble displayFactor() const; // Events. diff --git a/doomsday/libappfw/src/widgets/sliderwidget.cpp b/doomsday/libappfw/src/widgets/sliderwidget.cpp index faf2324664..f195a46a77 100644 --- a/doomsday/libappfw/src/widgets/sliderwidget.cpp +++ b/doomsday/libappfw/src/widgets/sliderwidget.cpp @@ -44,7 +44,8 @@ class ValuePopup : public PopupWidget connect(_edit, SIGNAL(enterPressed(QString)), this, SLOT(close())); _edit->rule().setInput(Rule::Width, slider.style().rules().rule("slider.editor")); - _edit->setText(QString::number(slider.value() * slider.displayFactor(), 'g', 4)); + _edit->setText(QString::number(slider.value() * slider.displayFactor(), 'f', + slider.precision())); } LineEditWidget &editor() const @@ -462,7 +463,9 @@ SliderWidget::SliderWidget(String const &name) // Default size. rule().setInput(Rule::Width, style().rules().rule("slider.width")) - .setInput(Rule::Height, font().height() + margins().height()); + .setInput(Rule::Height, OperatorRule::maximum( + style().fonts().font("default").height(), + font().height()) + margins().height()); } void SliderWidget::setRange(Rangei const &intRange, int step) @@ -529,6 +532,11 @@ ddouble SliderWidget::value() const return d->value; } +int SliderWidget::precision() const +{ + return d->precision; +} + ddouble SliderWidget::displayFactor() const { return d->displayFactor; From 73f3e1cdc3d8087ea59153e2dcd2bc0d2b1bff7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sat, 1 Feb 2014 16:57:28 +0200 Subject: [PATCH 053/106] UI|Client: Added more network settings to dialog --- doomsday/client/src/clientapp.cpp | 2 +- .../client/src/ui/dialogs/networksettingsdialog.cpp | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/doomsday/client/src/clientapp.cpp b/doomsday/client/src/clientapp.cpp index d854ea1325..195ea61b75 100644 --- a/doomsday/client/src/clientapp.cpp +++ b/doomsday/client/src/clientapp.cpp @@ -274,7 +274,7 @@ DENG2_PIMPL(ClientApp) networkSettings .define(SReg::StringCVar, "net-master-address", "www.dengine.net") .define(SReg::StringCVar, "net-master-path", "/master.php") - .define(SReg::IntCVar, "net-master-port", 80) + .define(SReg::IntCVar, "net-master-port", 0) .define(SReg::IntCVar, "net-dev", 0); audioSettings diff --git a/doomsday/client/src/ui/dialogs/networksettingsdialog.cpp b/doomsday/client/src/ui/dialogs/networksettingsdialog.cpp index 95312ee5a7..79b0ba93a1 100644 --- a/doomsday/client/src/ui/dialogs/networksettingsdialog.cpp +++ b/doomsday/client/src/ui/dialogs/networksettingsdialog.cpp @@ -36,6 +36,7 @@ DENG_GUI_PIMPL(NetworkSettingsDialog) { CVarLineEditWidget *masterUrl; CVarLineEditWidget *masterPath; + CVarSliderWidget *masterPort; GridPopupWidget *devPopup; CVarToggleWidget *devInfo; @@ -45,6 +46,9 @@ DENG_GUI_PIMPL(NetworkSettingsDialog) area.add(masterUrl = new CVarLineEditWidget("net-master-address")); area.add(masterPath = new CVarLineEditWidget("net-master-path")); + area.add(masterPort = new CVarSliderWidget("net-master-port")); + + masterPort->setMinLabel(tr("80")); // Developer options. self.add(devPopup = new GridPopupWidget); @@ -73,14 +77,16 @@ NetworkSettingsDialog::NetworkSettingsDialog(String const &name) d->devInfo->setText(tr("Developer Info")); LabelWidget *masterUrlLabel = LabelWidget::newWithText(tr("Master URL:"), &area()); - LabelWidget *masterPathLabel = LabelWidget::newWithText(tr("Path:"), &area()); + LabelWidget *masterPathLabel = LabelWidget::newWithText(tr("Master Path:"), &area()); + LabelWidget *masterPortLabel = LabelWidget::newWithText(tr("Master Port:"), &area()); // Layout. GridLayout layout(area().contentRule().left(), area().contentRule().top()); layout.setGridSize(2, 0); layout.setColumnAlignment(0, ui::AlignRight); - layout << *masterUrlLabel << *d->masterUrl - << *masterPathLabel << *d->masterPath; + layout << *masterUrlLabel << *d->masterUrl + << *masterPathLabel << *d->masterPath + << *masterPortLabel << *d->masterPort; area().setContentSize(layout.width(), layout.height()); From 32599f0b490ef0272c20c4707639eadd99aa08fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sun, 2 Feb 2014 19:20:01 +0200 Subject: [PATCH 054/106] libdeng2|Debug|IndirectRule: More concise description --- doomsday/libdeng2/src/widgets/indirectrule.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doomsday/libdeng2/src/widgets/indirectrule.cpp b/doomsday/libdeng2/src/widgets/indirectrule.cpp index 501596dc0f..0f7c98def5 100644 --- a/doomsday/libdeng2/src/widgets/indirectrule.cpp +++ b/doomsday/libdeng2/src/widgets/indirectrule.cpp @@ -59,11 +59,11 @@ String IndirectRule::description() const { if(_source) { - return String("Indirect => ") + source().description(); + return source().description(); } else { - return String("Indirect => (null)"); + return String("(null)"); } } From 43549b145e97a2b5eb5418957827007ef478592c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sun, 2 Feb 2014 19:21:28 +0200 Subject: [PATCH 055/106] Fixed|libappfw: De- and re-initializing procedural images --- .../libappfw/include/de/framework/atlasproceduralimage.h | 5 +++++ doomsday/libappfw/include/de/framework/proceduralimage.h | 1 + doomsday/libappfw/src/proceduralimage.cpp | 5 +++++ doomsday/libappfw/src/widgets/labelwidget.cpp | 5 +++++ 4 files changed, 16 insertions(+) diff --git a/doomsday/libappfw/include/de/framework/atlasproceduralimage.h b/doomsday/libappfw/include/de/framework/atlasproceduralimage.h index 2045937e49..fc27545677 100644 --- a/doomsday/libappfw/include/de/framework/atlasproceduralimage.h +++ b/doomsday/libappfw/include/de/framework/atlasproceduralimage.h @@ -88,6 +88,11 @@ class LIBAPPFW_PUBLIC AtlasProceduralImage : public ProceduralImage } } + void glInit() + { + alloc(); + } + void glDeinit() { release(); diff --git a/doomsday/libappfw/include/de/framework/proceduralimage.h b/doomsday/libappfw/include/de/framework/proceduralimage.h index 15a60fb9cd..744222cda5 100644 --- a/doomsday/libappfw/include/de/framework/proceduralimage.h +++ b/doomsday/libappfw/include/de/framework/proceduralimage.h @@ -50,6 +50,7 @@ class LIBAPPFW_PUBLIC ProceduralImage void setColor(Color const &color); virtual void update(); + virtual void glInit(); virtual void glDeinit(); virtual void glMakeGeometry(DefaultVertexBuf::Builder &verts, Rectanglef const &rect) = 0; diff --git a/doomsday/libappfw/src/proceduralimage.cpp b/doomsday/libappfw/src/proceduralimage.cpp index 7d0d193ecf..7b9a7dcea5 100644 --- a/doomsday/libappfw/src/proceduralimage.cpp +++ b/doomsday/libappfw/src/proceduralimage.cpp @@ -51,6 +51,11 @@ void ProceduralImage::update() // optional for derived classes } +void ProceduralImage::glInit() +{ + // optional for derived classes +} + void ProceduralImage::glDeinit() { // optional for derived classes diff --git a/doomsday/libappfw/src/widgets/labelwidget.cpp b/doomsday/libappfw/src/widgets/labelwidget.cpp index e2862e1574..6a8f3c2346 100644 --- a/doomsday/libappfw/src/widgets/labelwidget.cpp +++ b/doomsday/libappfw/src/widgets/labelwidget.cpp @@ -181,6 +181,11 @@ public Font::RichFormat::IStyle << uMvpMatrix << uColor << uAtlas(); glText.init(atlas(), self.font(), this); + + if(!image.isNull()) + { + image->glInit(); + } } void glDeinit() From 8b30915acf43ae63e169c95684d20498d9644d38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sun, 2 Feb 2014 19:22:45 +0200 Subject: [PATCH 056/106] Fixed|libappfw|MenuWidget: Take padding into account in layout Also added a helper template method for getting widgets representing items. --- doomsday/libappfw/include/de/widgets/menuwidget.h | 5 +++++ doomsday/libappfw/src/widgets/menuwidget.cpp | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/doomsday/libappfw/include/de/widgets/menuwidget.h b/doomsday/libappfw/include/de/widgets/menuwidget.h index 1dec98eee4..65d4cc5366 100644 --- a/doomsday/libappfw/include/de/widgets/menuwidget.h +++ b/doomsday/libappfw/include/de/widgets/menuwidget.h @@ -94,6 +94,11 @@ class LIBAPPFW_PUBLIC MenuWidget : public ScrollAreaWidget ChildWidgetOrganizer &organizer(); ChildWidgetOrganizer const &organizer() const; + template + WidgetType &itemWidget(ui::Item const &item) const { + return organizer().itemWidget(item)->as(); + } + /** * Returns the number of visible items in the menu. Hidden items are not * included in this count. diff --git a/doomsday/libappfw/src/widgets/menuwidget.cpp b/doomsday/libappfw/src/widgets/menuwidget.cpp index d572d20632..80c8694125 100644 --- a/doomsday/libappfw/src/widgets/menuwidget.cpp +++ b/doomsday/libappfw/src/widgets/menuwidget.cpp @@ -385,13 +385,15 @@ void MenuWidget::setGridSize(int columns, ui::SizePolicy columnPolicy, if(d->colPolicy == ui::Filled) { DENG2_ASSERT(columns > 0); - d->layout.setOverrideWidth((rule().width() - margins().width()) / float(columns)); + d->layout.setOverrideWidth((rule().width() - margins().width() - + (columns - 1) * d->layout.columnPadding()) / float(columns)); } if(d->rowPolicy == ui::Filled) { DENG2_ASSERT(rows > 0); - d->layout.setOverrideHeight((rule().height() - margins().height()) / float(rows)); + d->layout.setOverrideHeight((rule().height() - margins().height() - + (rows - 1) * d->layout.rowPadding()) / float(rows)); } d->needLayout = true; From 47c69e20abeaa90568cf3517ac3e882287fa988c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sun, 2 Feb 2014 19:24:10 +0200 Subject: [PATCH 057/106] libappfw|FoldPanelWidget: Fold title must be manually created Previously the title button would be created but never deleted, if it was unused. --- .../client/src/ui/editors/rendererappearanceeditor.cpp | 1 + doomsday/libappfw/include/de/widgets/foldpanelwidget.h | 10 ++++++++++ doomsday/libappfw/src/widgets/foldpanelwidget.cpp | 10 +++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/doomsday/client/src/ui/editors/rendererappearanceeditor.cpp b/doomsday/client/src/ui/editors/rendererappearanceeditor.cpp index 0edc96aef5..d14d8571db 100644 --- a/doomsday/client/src/ui/editors/rendererappearanceeditor.cpp +++ b/doomsday/client/src/ui/editors/rendererappearanceeditor.cpp @@ -99,6 +99,7 @@ DENG2_OBSERVES(App, GameChange) { _group = new GuiWidget; setContent(_group); + makeTitle(titleText); title().setText(titleText); title().setTextColor("accent"); diff --git a/doomsday/libappfw/include/de/widgets/foldpanelwidget.h b/doomsday/libappfw/include/de/widgets/foldpanelwidget.h index 66fe219dec..98fdaf2f1c 100644 --- a/doomsday/libappfw/include/de/widgets/foldpanelwidget.h +++ b/doomsday/libappfw/include/de/widgets/foldpanelwidget.h @@ -44,6 +44,16 @@ class LIBAPPFW_PUBLIC FoldPanelWidget : public PanelWidget public: FoldPanelWidget(String const &name = ""); + /** + * Creates a title button widget for toggling the fold open and closed. + * The method does not add the title as a child to anything. + * + * @param text Text. + * + * @return Button widget instance. Caller gets ownership. + */ + ButtonWidget *makeTitle(String const &text = ""); + ButtonWidget &title(); void setContent(GuiWidget *content); diff --git a/doomsday/libappfw/src/widgets/foldpanelwidget.cpp b/doomsday/libappfw/src/widgets/foldpanelwidget.cpp index e57e9a38b8..e18adb257d 100644 --- a/doomsday/libappfw/src/widgets/foldpanelwidget.cpp +++ b/doomsday/libappfw/src/widgets/foldpanelwidget.cpp @@ -61,7 +61,7 @@ DENG2_PIMPL_NOREF(FoldPanelWidget) } };*/ - ButtonWidget *title; + ButtonWidget *title; // not owned GuiWidget *container; ///< Held here while not part of the widget tree. DialogContentStylist stylist; @@ -69,8 +69,13 @@ DENG2_PIMPL_NOREF(FoldPanelWidget) }; FoldPanelWidget::FoldPanelWidget(String const &name) : PanelWidget(name), d(new Instance) +{} + +ButtonWidget *FoldPanelWidget::makeTitle(String const &text) { d->title = new ButtonWidget; + + d->title->setText(text); d->title->setSizePolicy(Expand, Expand); d->title->set(Background()); // no frame or background d->title->setHoverTextColor("text"); @@ -81,10 +86,13 @@ FoldPanelWidget::FoldPanelWidget(String const &name) : PanelWidget(name), d(new // Icon is disabled for now, doesn't look quite right. //d->title->setImage(new Instance::FoldImage(*this)); //d->title->setTextAlignment(ui::AlignRight); // Text is on the right from the image. + + return d->title; } ButtonWidget &FoldPanelWidget::title() { + DENG2_ASSERT(d->title != 0); return *d->title; } From 294bced7ba78a66d322f98c1c02ae0208a428380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sun, 2 Feb 2014 19:24:48 +0200 Subject: [PATCH 058/106] Fixed|libappfw|Margins: Updating margins The sum of the left and right margins wasn't always updated properly. --- doomsday/libappfw/src/margins.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/doomsday/libappfw/src/margins.cpp b/doomsday/libappfw/src/margins.cpp index 5311893660..18457e4902 100644 --- a/doomsday/libappfw/src/margins.cpp +++ b/doomsday/libappfw/src/margins.cpp @@ -89,7 +89,10 @@ DENG2_PIMPL(Margins) void updateOutput(int side) { - if(!outputs[side]) return; + if(side < 4 && outputs[side] && inputs[side]) + { + outputs[side]->setSource(*inputs[side]); + } // Update the sums. if(side == LeftRight || side == SideLeft || side == SideRight) @@ -106,11 +109,6 @@ DENG2_PIMPL(Margins) outputs[TopBottom]->setSource(*inputs[SideTop] + *inputs[SideBottom]); } } - - if(side < 4 && inputs[side]) - { - outputs[side]->setSource(*inputs[side]); - } } Rule const &getOutput(int side) From e5d394c080f833d5e76d08479043df9cebe231fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sun, 2 Feb 2014 19:26:00 +0200 Subject: [PATCH 059/106] libappfw|GridLayout: Added method for querying the layout's paddings --- .../libappfw/include/de/framework/gridlayout.h | 2 ++ doomsday/libappfw/src/gridlayout.cpp | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/doomsday/libappfw/include/de/framework/gridlayout.h b/doomsday/libappfw/include/de/framework/gridlayout.h index 038378f975..8e508d0190 100644 --- a/doomsday/libappfw/include/de/framework/gridlayout.h +++ b/doomsday/libappfw/include/de/framework/gridlayout.h @@ -129,6 +129,8 @@ class LIBAPPFW_PUBLIC GridLayout Rule const &rowHeight(int row) const; Rule const &overrideWidth() const; Rule const &overrideHeight() const; + Rule const &columnPadding() const; + Rule const &rowPadding() const; private: DENG2_PRIVATE(d) diff --git a/doomsday/libappfw/src/gridlayout.cpp b/doomsday/libappfw/src/gridlayout.cpp index c21fa97c24..d662a8cdd2 100644 --- a/doomsday/libappfw/src/gridlayout.cpp +++ b/doomsday/libappfw/src/gridlayout.cpp @@ -42,6 +42,7 @@ DENG2_PIMPL(GridLayout) CellAlignments cellAlignment; Rule const *colPad; Rule const *rowPad; + Rule const *zeroRule; struct Metric { Rule const *fixedLength; ///< May be @c NULL. @@ -93,6 +94,7 @@ DENG2_PIMPL(GridLayout) fixedCellHeight(0), colPad(0), rowPad(0), + zeroRule(new ConstantRule(0)), totalWidth(new ConstantRule(0)), totalHeight(new ConstantRule(0)), current(0), @@ -109,6 +111,7 @@ DENG2_PIMPL(GridLayout) releaseRef(fixedCellHeight); releaseRef(colPad); releaseRef(rowPad); + releaseRef(zeroRule); releaseRef(totalWidth); releaseRef(totalHeight); @@ -716,6 +719,18 @@ Rule const &GridLayout::overrideHeight() const return *d->fixedCellHeight; } +Rule const &GridLayout::columnPadding() const +{ + if(d->colPad) return *d->colPad; + return *d->zeroRule; +} + +Rule const &GridLayout::rowPadding() const +{ + if(d->rowPad) return *d->rowPad; + return *d->zeroRule; +} + void GridLayout::setCellAlignment(Vector2i const &cell, ui::Alignment cellAlign) { d->cellAlignment[cell] = cellAlign; From dac63a3db0c2acc1c32079e71172a40865ce546b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sun, 2 Feb 2014 19:28:59 +0200 Subject: [PATCH 060/106] UI|Ring Zero: Revised game selection menu The game selection menu is now divided into foldable subgroups. Incomplete games are put in a separate group. Changed the layout of the menu so that items have a fixed height regardless of view size. The number of columns still changes depending on view width, though. --- .../include/ui/widgets/gameselectionwidget.h | 4 +- doomsday/client/src/ui/clientwindow.cpp | 9 +- .../src/ui/widgets/gameselectionwidget.cpp | 259 ++++++++++++------ 3 files changed, 183 insertions(+), 89 deletions(-) diff --git a/doomsday/client/include/ui/widgets/gameselectionwidget.h b/doomsday/client/include/ui/widgets/gameselectionwidget.h index e77a1d16e0..3bee2fe10a 100644 --- a/doomsday/client/include/ui/widgets/gameselectionwidget.h +++ b/doomsday/client/include/ui/widgets/gameselectionwidget.h @@ -19,12 +19,12 @@ #ifndef DENG_CLIENT_GAMESELECTIONWIDGET_H #define DENG_CLIENT_GAMESELECTIONWIDGET_H -#include +#include /** * Menu for selecting */ -class GameSelectionWidget : public de::MenuWidget +class GameSelectionWidget : public de::ScrollAreaWidget { public: GameSelectionWidget(de::String const &name = "gameselection"); diff --git a/doomsday/client/src/ui/clientwindow.cpp b/doomsday/client/src/ui/clientwindow.cpp index 89653c939a..a9f42c2735 100644 --- a/doomsday/client/src/ui/clientwindow.cpp +++ b/doomsday/client/src/ui/clientwindow.cpp @@ -226,12 +226,9 @@ DENG2_OBSERVES(App, StartupComplete) // The game selection's height depends on the taskbar. gameSelMenu->rule() .setInput(Rule::AnchorY, taskBar->rule().top() / 2) - .setInput(Rule::Height, - OperatorRule::minimum(style.rules().rule("gameselection.max.height"), - taskBar->rule().top())); - /*OperatorRule::minimum(root.viewHeight(), - (taskBar->rule().top() - root.viewHeight() / 2) * 2, - style.rules().rule("gameselection.max.height")));*/ + .setInput(Rule::Height, OperatorRule::minimum( + taskBar->rule().top(), + gameSelMenu->contentRule().height() + gameSelMenu->margins().height())); // Color adjustment dialog. colorAdjust = new ColorAdjustmentDialog; diff --git a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp index dc37b6a68b..dfc3c7f12e 100644 --- a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp +++ b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp @@ -23,6 +23,9 @@ #include "dd_main.h" #include +#include +#include +#include #include #include #include @@ -37,78 +40,19 @@ DENG_GUI_PIMPL(GameSelectionWidget) , DENG2_OBSERVES(App, StartupComplete) , public ChildWidgetOrganizer::IWidgetFactory { - /// ActionItem with a Game member. + /// ActionItem with a Game member, for loading a particular game. struct GameItem : public ui::ActionItem { GameItem(Game const &gameRef, de::String const &label, de::Action *action) - : ui::ActionItem(label, action), game(gameRef) {} + : ui::ActionItem(label, action), game(gameRef) { + setData(&gameRef); + } Game const &game; }; - FIFO pendingGames; - - Instance(Public *i) : Base(i) - { - App_Games().audienceForAddition += this; - App::app().audienceForStartupComplete += this; - - self.organizer().setWidgetFactory(*this); - } - - ~Instance() - { - App_Games().audienceForAddition -= this; - App::app().audienceForStartupComplete -= this; - } - - void gameAdded(Game &game) - { - // Called from a non-UI thread. - pendingGames.put(&game); - } - - void addPendingGames() - { - while(Game *game = pendingGames.take()) - { - self.items().append(makeItemForGame(*game)); - } - } - - ui::Item *makeItemForGame(Game &game) - { - String const idKey = game.identityKey(); - - CommandAction *loadAction = new CommandAction(String("load ") + idKey); - String label = String(_E(b) "%1" _E(.) /*_E(s)_E(C) " %2\n" _E(.)_E(.)*/ "\n" - _E(l)_E(D) "%2") - .arg(game.title()) - //.arg(game.author()) - .arg(idKey); - - GameItem *item = new GameItem(game, label, loadAction); - - /// @todo The name of the plugin should be accessible via the plugin loader. - String plugName; - if(idKey.contains("heretic")) - { - plugName = "libheretic"; - } - else if(idKey.contains("hexen")) - { - plugName = "libhexen"; - } - else - { - plugName = "libdoom"; - } - if(style().images().has(game.logoImageId())) - { - item->setImage(style().images().image(game.logoImageId())); - } - - return item; - } - + /** + * Widget for representing an item in the game selection menu. Has two buttons: + * one for starting the game and one for configuring it. + */ struct GameWidget : public GuiWidget , DENG2_OBSERVES(ButtonWidget, Press) @@ -121,6 +65,8 @@ DENG_GUI_PIMPL(GameSelectionWidget) GameWidget() : game(0) { + rule().setInput(Rule::Height, style().fonts().font("default").height() * 4); + add(load = new ButtonWidget); add(info = new ButtonWidget); @@ -177,6 +123,136 @@ DENG_GUI_PIMPL(GameSelectionWidget) } }; + struct Subset : public FoldPanelWidget + { + MenuWidget *menu; + + Subset(String const &headingText, GameSelectionWidget::Instance *owner) + { + owner->self.add(makeTitle(headingText)); + title().setFont("title"); + title().setTextColor("inverted.text"); + title().setAlignment(ui::AlignLeft); + title().margins().setLeft(""); + + setContent(menu = new MenuWidget); + menu->margins().set(""); + menu->layout().setColumnPadding(owner->style().rules().rule("unit")); + menu->enableScrolling(false); + menu->organizer().setWidgetFactory(*owner); + + menu->rule().setInput(Rule::Width, + owner->self.rule().width() - + owner->self.margins().width()); + + setColumns(3); + } + + void setColumns(int cols) + { + if(menu->layout().maxGridSize().x != cols) + { + menu->setGridSize(cols, ui::Filled, 0, ui::Expand); + } + } + + ui::Data &items() + { + return menu->items(); + } + + GameWidget &gameWidget(ui::Item const &item) + { + return menu->itemWidget(item); + } + }; + + FIFO pendingGames; + SequentialLayout superLayout; + + Subset *available; + Subset *incomplete; + + Instance(Public *i) + : Base(i) + , superLayout(i->contentRule().left(), i->contentRule().top(), ui::Down) + { + // Menu of available games. + self.add(available = new Subset(tr("Available Games"), this)); + + // Menu of incomplete games. + self.add(incomplete = new Subset(tr("Incomplete Games"), this)); + + superLayout.setOverrideWidth(self.rule().width() - self.margins().width()); + + available->title().margins().setTop(""); + + superLayout << available->title() + << *available + << incomplete->title() + << *incomplete; + + self.setContentSize(superLayout.width(), superLayout.height()); + + App_Games().audienceForAddition += this; + App::app().audienceForStartupComplete += this; + } + + ~Instance() + { + App_Games().audienceForAddition -= this; + App::app().audienceForStartupComplete -= this; + } + + void gameAdded(Game &game) + { + // Called from a non-UI thread. + pendingGames.put(&game); + } + + void addPendingGames() + { + while(Game *game = pendingGames.take()) + { + incomplete->items().append(makeItemForGame(*game)); + } + } + + ui::Item *makeItemForGame(Game &game) + { + String const idKey = game.identityKey(); + + CommandAction *loadAction = new CommandAction(String("load ") + idKey); + String label = String(_E(b) "%1" _E(.) /*_E(s)_E(C) " %2\n" _E(.)_E(.)*/ "\n" + _E(l)_E(D) "%2") + .arg(game.title()) + //.arg(game.author()) + .arg(idKey); + + GameItem *item = new GameItem(game, label, loadAction); + + /// @todo The name of the plugin should be accessible via the plugin loader. + String plugName; + if(idKey.contains("heretic")) + { + plugName = "libheretic"; + } + else if(idKey.contains("hexen")) + { + plugName = "libhexen"; + } + else + { + plugName = "libdoom"; + } + if(style().images().has(game.logoImageId())) + { + item->setImage(style().images().image(game.logoImageId())); + } + + return item; + } + GuiWidget *makeItemWidget(ui::Item const &, GuiWidget const *) { return new GameWidget; @@ -201,23 +277,46 @@ DENG_GUI_PIMPL(GameSelectionWidget) void updateGameAvailability() { - for(uint i = 0; i < self.items().size(); ++i) + // Available games. + for(uint i = 0; i < available->items().size(); ++i) { - GameItem const &item = self.items().at(i).as(); + GameItem const &item = available->items().at(i).as(); + if(item.game.allStartupFilesFound()) + { + available->gameWidget(item).load->enable(); + } + else + { + incomplete->items().append(available->items().take(i--)); + incomplete->gameWidget(item).load->disable(); + } + } - GameWidget &w = self.organizer().itemWidget(item)->as(); - w.load->enable(item.game.allStartupFilesFound()); + // Incomplete games. + for(uint i = 0; i < incomplete->items().size(); ++i) + { + GameItem const &item = incomplete->items().at(i).as(); + if(item.game.allStartupFilesFound()) + { + available->items().append(incomplete->items().take(i--)); + available->gameWidget(item).load->enable(); + } + else + { + incomplete->gameWidget(item).load->disable(); + } } - self.items().sort(); + available->items().sort(); + incomplete->items().sort(); } }; GameSelectionWidget::GameSelectionWidget(String const &name) - : MenuWidget(name), d(new Instance(this)) + : ScrollAreaWidget(name), d(new Instance(this)) { - layout().setColumnPadding(style().rules().rule("unit")); - setGridSize(3, ui::Filled, 6, ui::Filled); + d->available->open(); + d->incomplete->open(); // We want the full menu to be visible even when it doesn't fit the // designated area. @@ -226,7 +325,7 @@ GameSelectionWidget::GameSelectionWidget(String const &name) void GameSelectionWidget::viewResized() { - MenuWidget::viewResized(); + ScrollAreaWidget::viewResized(); // If the view is too small, we'll want to reduce the number of items in the menu. int const maxWidth = style().rules().rule("gameselection.max.width").valuei(); @@ -235,15 +334,13 @@ void GameSelectionWidget::viewResized() Vector2i suitable(clamp(1, 3 * rule().width().valuei() / maxWidth, 3), clamp(1, 8 * rule().height().valuei() / maxHeight, 6)); - if(layout().maxGridSize() != suitable) - { - setGridSize(suitable.x, ui::Filled, suitable.y, ui::Filled); - } + d->available->setColumns(suitable.x); + d->incomplete->setColumns(suitable.x); } void GameSelectionWidget::update() { d->addPendingGames(); - MenuWidget::update(); + ScrollAreaWidget::update(); } From e1e2107bc8c2faeffb5aa8bc33430c0d9be66b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sun, 2 Feb 2014 21:31:25 +0200 Subject: [PATCH 061/106] Refactor|UI|Ring Zero: Incorporate MP games in the game selection menu Added another subgroup into the Ring Zero game selection menu for multiplayer games. MPSelectionWidget is a menu that populates itself with the found MP servers. Todo: The "Multiplayer Games" dialog should simply be a Games dialog that shows the selection of games. --- doomsday/client/client.pro | 4 + .../include/ui/widgets/gamesessionwidget.h | 45 +++ .../include/ui/widgets/mpselectionwidget.h | 38 +++ .../src/ui/dialogs/multiplayerdialog.cpp | 231 +-------------- .../src/ui/widgets/gameselectionwidget.cpp | 148 ++++------ .../src/ui/widgets/gamesessionwidget.cpp | 115 ++++++++ .../src/ui/widgets/mpselectionwidget.cpp | 265 ++++++++++++++++++ 7 files changed, 528 insertions(+), 318 deletions(-) create mode 100644 doomsday/client/include/ui/widgets/gamesessionwidget.h create mode 100644 doomsday/client/include/ui/widgets/mpselectionwidget.h create mode 100644 doomsday/client/src/ui/widgets/gamesessionwidget.cpp create mode 100644 doomsday/client/src/ui/widgets/mpselectionwidget.cpp diff --git a/doomsday/client/client.pro b/doomsday/client/client.pro index cacac01f5c..5251beb03d 100644 --- a/doomsday/client/client.pro +++ b/doomsday/client/client.pro @@ -393,10 +393,12 @@ DENG_HEADERS += \ include/ui/widgets/cvarsliderwidget.h \ include/ui/widgets/cvartogglewidget.h \ include/ui/widgets/gameselectionwidget.h \ + include/ui/widgets/gamesessionwidget.h \ include/ui/widgets/gameuiwidget.h \ include/ui/widgets/gamewidget.h \ include/ui/widgets/icvarwidget.h \ include/ui/widgets/keygrabberwidget.h \ + include/ui/widgets/mpselectionwidget.h \ include/ui/widgets/multiplayermenuwidget.h \ include/ui/widgets/profilepickerwidget.h \ include/ui/widgets/taskbarwidget.h \ @@ -730,9 +732,11 @@ SOURCES += \ src/ui/widgets/cvarsliderwidget.cpp \ src/ui/widgets/cvartogglewidget.cpp \ src/ui/widgets/gameselectionwidget.cpp \ + src/ui/widgets/gamesessionwidget.cpp \ src/ui/widgets/gamewidget.cpp \ src/ui/widgets/gameuiwidget.cpp \ src/ui/widgets/keygrabberwidget.cpp \ + src/ui/widgets/mpselectionwidget.cpp \ src/ui/widgets/multiplayermenuwidget.cpp \ src/ui/widgets/profilepickerwidget.cpp \ src/ui/widgets/taskbarwidget.cpp \ diff --git a/doomsday/client/include/ui/widgets/gamesessionwidget.h b/doomsday/client/include/ui/widgets/gamesessionwidget.h new file mode 100644 index 0000000000..21a0cc201f --- /dev/null +++ b/doomsday/client/include/ui/widgets/gamesessionwidget.h @@ -0,0 +1,45 @@ +/** @file gamesessionwidget.h + * + * @authors Copyright (c) 2014 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, see: + * http://www.gnu.org/licenses + */ + +#ifndef DENG_CLIENT_GAMESESSIONWIDGET_H +#define DENG_CLIENT_GAMESESSIONWIDGET_H + +#include +#include + +/** + * Widget for representing an item (game session) in the game selection menu. + * + * It has two buttons: one for starting the game and one for configuring it. + */ +class GameSessionWidget : public de::GuiWidget +{ +public: + GameSessionWidget(); + + de::ButtonWidget &loadButton(); + de::ButtonWidget &infoButton(); + de::DocumentWidget &document(); + + virtual void updateInfoContent(); + +private: + DENG2_PRIVATE(d) +}; + +#endif // DENG_CLIENT_GAMESESSIONWIDGET_H diff --git a/doomsday/client/include/ui/widgets/mpselectionwidget.h b/doomsday/client/include/ui/widgets/mpselectionwidget.h new file mode 100644 index 0000000000..f38bef1ca2 --- /dev/null +++ b/doomsday/client/include/ui/widgets/mpselectionwidget.h @@ -0,0 +1,38 @@ +/** @file mpselectionwidget.h + * + * @authors Copyright (c) 2014 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, see: + * http://www.gnu.org/licenses + */ + +#ifndef DENG_CLIENT_MPSELECTIONWIDGET_H +#define DENG_CLIENT_MPSELECTIONWIDGET_H + +#include + +/** + * Menu that populates itself with available multiplayer games. + * + * @ingroup ui + */ +class MPSelectionWidget : public de::MenuWidget +{ +public: + MPSelectionWidget(); + +private: + DENG2_PRIVATE(d) +}; + +#endif // DENG_CLIENT_MPSELECTIONWIDGET_H diff --git a/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp b/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp index 3436e4a995..440a249da3 100644 --- a/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp +++ b/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp @@ -17,246 +17,19 @@ */ #include "ui/dialogs/multiplayerdialog.h" -#include "network/serverlink.h" -#include "clientapp.h" -#include "dd_main.h" -#include "con_main.h" #include "CommandAction" -#include "ui/widgets/taskbarwidget.h" #include "ui/dialogs/networksettingsdialog.h" -#include #include -#include -#include -#include -#include using namespace de; DENG_GUI_PIMPL(MultiplayerDialog) -, DENG2_OBSERVES(ServerLink, DiscoveryUpdate) -, public ChildWidgetOrganizer::IWidgetFactory { - static ServerLink &link() { return ClientApp::serverLink(); } - static String hostId(serverinfo_t const &sv) { - return String("%1:%2").arg(sv.address).arg(sv.port); - } - - /** - * Data item with information about a found server. - */ - class ServerListItem : public ui::Item - { - public: - ServerListItem(serverinfo_t const &serverInfo) - { - setData(hostId(serverInfo)); - std::memcpy(&_info, &serverInfo, sizeof(serverInfo)); - } - - serverinfo_t const &info() const - { - return _info; - } - - void setInfo(serverinfo_t const &serverInfo) - { - std::memcpy(&_info, &serverInfo, sizeof(serverInfo)); - notifyChange(); - } - - private: - serverinfo_t _info; - }; - - /** - * Widget representing a ServerListItem in the dialog's menu. - */ - struct ServerWidget : public GuiWidget - { - LabelWidget *title; - ButtonWidget *extra; - ButtonWidget *join; - QScopedPointer layout; - DocumentPopupWidget *info; - - struct JoinAction : public Action - { - public: - JoinAction(serverinfo_t const &sv, ButtonWidget *owner) - : _owner(owner) - { - _gameId = sv.gameIdentityKey; - _cmd = String("connect %1 %2").arg(sv.address).arg(sv.port); - } - - void trigger() - { - Action::trigger(); - - BusyMode_FreezeGameForBusyMode(); - - // Closing the taskbar will cause this action to be deleted. Let's take - // ownership of the action so we can delete after we're done. - _owner->takeAction(); - - ClientWindow::main().taskBar().close(); - - App_ChangeGame(App_Games().byIdentityKey(_gameId), false /*no reload*/); - Con_Execute(CMDS_DDAY, _cmd.toLatin1(), false, false); - - delete this; - } - - Action *duplicate() const - { - DENG2_ASSERT(!"JoinAction: cannot duplicate"); - return 0; - } - - private: - ButtonWidget *_owner; - String _gameId; - String _cmd; - }; - - ServerWidget() - { - setBehavior(ContentClipping); - - add(title = new LabelWidget); - add(extra = new ButtonWidget); - add(join = new ButtonWidget); - - extra->setText(tr("...")); - join->setText(tr("Join")); - - title->setSizePolicy(ui::Expand, ui::Expand); - title->setAppearanceAnimation(LabelWidget::AppearGrowVertically, 0.5); - title->setAlignment(ui::AlignTop); - title->setTextAlignment(ui::AlignRight); - title->setTextLineAlignment(ui::AlignLeft); - title->setImageAlignment(ui::AlignCenter); - title->setMaximumTextWidth(style().rules().rule("dialog.multiplayer.width").valuei()); - - extra->setSizePolicy(ui::Expand, ui::Expand); - join->setSizePolicy(ui::Expand, ui::Expand); - - join->disable(); - - layout.reset(new SequentialLayout(rule().left(), rule().top(), ui::Right)); - *layout << *title << *extra << *join; - rule().setSize(layout->width(), title->rule().height()); - - // Extra info popup. - info = new DocumentPopupWidget; - info->document().setMaximumLineWidth(style().rules().rule("dialog.multiplayer.width").valuei()); - info->setAnchorAndOpeningDirection(extra->rule(), ui::Up); - add(info); - - extra->setAction(new SignalAction(info, SLOT(open()))); - } - - void updateFromItem(ServerListItem const &item) - { - try - { - Game const &svGame = App_Games().byIdentityKey(item.info().gameIdentityKey); - - if(style().images().has(svGame.logoImageId())) - { - title->setImage(style().images().image(svGame.logoImageId())); - } - - serverinfo_t const &sv = item.info(); - - join->enable(sv.canJoin); - if(sv.canJoin) - { - join->setAction(new JoinAction(sv, join)); - } - - title->setText(String(_E(1) "%1 " _E(.)_E(2) "(%5/%6)" _E(.) "\n%2" - _E(D)_E(l) "\n%7 %4") - .arg(sv.name) - .arg(svGame.title()) - .arg(sv.gameConfig) - .arg(sv.numPlayers) - .arg(sv.maxPlayers) - .arg(sv.map)); - - // Extra information. - info->document().setText(ServerInfo_AsStyledText(&sv)); - } - catch(Error const &) - { - /// @todo - } - } - }; - - MenuWidget *list; + //MenuWidget *list; Instance(Public *i) : Base(i) { - self.area().add(list = new MenuWidget); - - // Configure the server list widet. - list->setGridSize(1, ui::Expand, 0, ui::Expand); - list->organizer().setWidgetFactory(*this); - - link().audienceForDiscoveryUpdate += this; - } - - ~Instance() - { - link().audienceForDiscoveryUpdate -= this; - } - - GuiWidget *makeItemWidget(ui::Item const &item, GuiWidget const *) - { - ServerWidget *w = new ServerWidget; - // Automatically close the info popup if the dialog is closed. - QObject::connect(thisPublic, SIGNAL(closed()), w->info, SLOT(close())); - return w; - } - - void updateItemWidget(GuiWidget &widget, ui::Item const &item) - { - widget.as().updateFromItem(item.as()); - } - - void linkDiscoveryUpdate(ServerLink const &link) - { - // Remove obsolete entries. - for(ui::Data::Pos idx = 0; idx < list->items().size(); ++idx) - { - String const id = list->items().at(idx).data().toString(); - if(!link.isFound(Address::parse(id))) - { - list->items().remove(idx--); - } - } - - // Add new entries and update existing ones. - foreach(de::Address const &host, link.foundServers()) - { - serverinfo_t info; - if(!link.foundServerInfo(host, &info)) continue; - - ui::Data::Pos found = list->items().findData(hostId(info)); - if(found == ui::Data::InvalidPos) - { - // Needs to be added. - list->items().append(new ServerListItem(info)); - } - else - { - // Update the info. - list->items().at(found).as().setInfo(info); - } - } } }; @@ -271,7 +44,7 @@ MultiplayerDialog::MultiplayerDialog(String const &name) layout.setGridSize(1, 0); //layout.setColumnAlignment(0, ui::AlignRight); - layout << *lab << *d->list; + layout << *lab;// << *d->list; area().setContentSize(layout.width(), layout.height()); diff --git a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp index dfc3c7f12e..05820e8ba7 100644 --- a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp +++ b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp @@ -17,6 +17,8 @@ */ #include "ui/widgets/gameselectionwidget.h" +#include "ui/widgets/gamesessionwidget.h" +#include "ui/widgets/mpselectionwidget.h" #include "CommandAction" #include "clientapp.h" #include "games.h" @@ -49,98 +51,55 @@ DENG_GUI_PIMPL(GameSelectionWidget) Game const &game; }; - /** - * Widget for representing an item in the game selection menu. Has two buttons: - * one for starting the game and one for configuring it. - */ - struct GameWidget - : public GuiWidget - , DENG2_OBSERVES(ButtonWidget, Press) - , DENG2_OBSERVES(App, GameUnload) + struct GameWidget : public GameSessionWidget { - ButtonWidget *load; - ButtonWidget *info; - DocumentPopupWidget *popup; Game const *game; - GameWidget() : game(0) - { - rule().setInput(Rule::Height, style().fonts().font("default").height() * 4); - - add(load = new ButtonWidget); - add(info = new ButtonWidget); - - load->disable(); - load->setBehavior(Widget::ContentClipping); - load->setAlignment(ui::AlignLeft); - load->setTextAlignment(ui::AlignRight); - load->setTextLineAlignment(ui::AlignLeft); - - info->setWidthPolicy(ui::Expand); - info->setAlignment(ui::AlignBottom); - info->setText(_E(s)_E(B) + tr("...")); - - add(popup = new DocumentPopupWidget); - popup->setAnchorAndOpeningDirection(info->rule(), ui::Up); - popup->document().setMaximumLineWidth(popup->style().rules().rule("document.popup.width").valuei()); - info->audienceForPress += this; - - // Button for extra information. - load->rule() - .setInput(Rule::Left, rule().left()) - .setInput(Rule::Top, rule().top()) - .setInput(Rule::Bottom, rule().bottom()) - .setInput(Rule::Right, info->rule().left()); - info->rule() - .setInput(Rule::Top, rule().top()) - .setInput(Rule::Right, rule().right()) - .setInput(Rule::Bottom, rule().bottom()); - - App::app().audienceForGameUnload += this; - } - - ~GameWidget() - { - App::app().audienceForGameUnload -= this; - } - - void aboutToUnloadGame(game::Game const &) - { - popup->close(0); - } - - void buttonPressed(ButtonWidget &bt) - { - /* - // Show information about the game. - popup->setAnchorAndOpeningDirection( - bt.rule(), - bt.rule().top().valuei() + bt.rule().height().valuei() / 2 < - bt.root().viewRule().height().valuei() / 2? - ui::Down : ui::Up);*/ - popup->document().setText(game->description()); - popup->open(); + GameWidget() : game(0) {} + void updateInfoContent() { + DENG2_ASSERT(game != 0); + document().setText(game->description()); } }; + /** + * Foldable group of games. + */ struct Subset : public FoldPanelWidget { + enum Type { + NormalGames, + MultiplayerGames + }; + + Type type; MenuWidget *menu; - Subset(String const &headingText, GameSelectionWidget::Instance *owner) - { + Subset(Type selType, String const &headingText, GameSelectionWidget::Instance *owner) + : type(selType) + { owner->self.add(makeTitle(headingText)); title().setFont("title"); title().setTextColor("inverted.text"); title().setAlignment(ui::AlignLeft); title().margins().setLeft(""); - setContent(menu = new MenuWidget); + switch(type) + { + case NormalGames: + menu = new MenuWidget; + menu->organizer().setWidgetFactory(*owner); + break; + + case MultiplayerGames: + menu = new MPSelectionWidget; + break; + } + + setContent(menu); + menu->enableScrolling(false); menu->margins().set(""); menu->layout().setColumnPadding(owner->style().rules().rule("unit")); - menu->enableScrolling(false); - menu->organizer().setWidgetFactory(*owner); - menu->rule().setInput(Rule::Width, owner->self.rule().width() - owner->self.margins().width()); @@ -172,16 +131,23 @@ DENG_GUI_PIMPL(GameSelectionWidget) Subset *available; Subset *incomplete; + Subset *multi; Instance(Public *i) : Base(i) , superLayout(i->contentRule().left(), i->contentRule().top(), ui::Down) { // Menu of available games. - self.add(available = new Subset(tr("Available Games"), this)); + self.add(available = new Subset(Subset::NormalGames, + tr("Available Games"), this)); // Menu of incomplete games. - self.add(incomplete = new Subset(tr("Incomplete Games"), this)); + self.add(incomplete = new Subset(Subset::NormalGames, + tr("Games with Missing Resources"), this)); + + // Menu of multiplayer games. + self.add(multi = new Subset(Subset::MultiplayerGames, + tr("Multiplayer Games"), this)); superLayout.setOverrideWidth(self.rule().width() - self.margins().width()); @@ -189,6 +155,8 @@ DENG_GUI_PIMPL(GameSelectionWidget) superLayout << available->title() << *available + << multi->title() + << *multi << incomplete->title() << *incomplete; @@ -265,9 +233,9 @@ DENG_GUI_PIMPL(GameSelectionWidget) w.game = &it.game; - w.load->setImage(it.image()); - w.load->setText(it.label()); - w.load->setAction(it.action()->duplicate()); + w.loadButton().setImage(it.image()); + w.loadButton().setText(it.label()); + w.loadButton().setAction(it.action()->duplicate()); } void appStartupCompleted() @@ -283,12 +251,12 @@ DENG_GUI_PIMPL(GameSelectionWidget) GameItem const &item = available->items().at(i).as(); if(item.game.allStartupFilesFound()) { - available->gameWidget(item).load->enable(); + available->gameWidget(item).loadButton().enable(); } else { incomplete->items().append(available->items().take(i--)); - incomplete->gameWidget(item).load->disable(); + incomplete->gameWidget(item).loadButton().disable(); } } @@ -299,11 +267,11 @@ DENG_GUI_PIMPL(GameSelectionWidget) if(item.game.allStartupFilesFound()) { available->items().append(incomplete->items().take(i--)); - available->gameWidget(item).load->enable(); + available->gameWidget(item).loadButton().enable(); } else { - incomplete->gameWidget(item).load->disable(); + incomplete->gameWidget(item).loadButton().disable(); } } @@ -316,6 +284,7 @@ GameSelectionWidget::GameSelectionWidget(String const &name) : ScrollAreaWidget(name), d(new Instance(this)) { d->available->open(); + d->multi->open(); d->incomplete->open(); // We want the full menu to be visible even when it doesn't fit the @@ -328,14 +297,15 @@ void GameSelectionWidget::viewResized() ScrollAreaWidget::viewResized(); // If the view is too small, we'll want to reduce the number of items in the menu. - int const maxWidth = style().rules().rule("gameselection.max.width").valuei(); - int const maxHeight = style().rules().rule("gameselection.max.height").valuei(); + int const maxWidth = style().rules().rule("gameselection.max.width").valuei(); + //int const maxHeight = style().rules().rule("gameselection.max.height").valuei(); - Vector2i suitable(clamp(1, 3 * rule().width().valuei() / maxWidth, 3), - clamp(1, 8 * rule().height().valuei() / maxHeight, 6)); + int suitable = clamp(1, 3 * rule().width().valuei() / maxWidth, 3); + //clamp(1, 8 * rule().height().valuei() / maxHeight, 6)); - d->available->setColumns(suitable.x); - d->incomplete->setColumns(suitable.x); + d->available->setColumns(suitable); + d->incomplete->setColumns(suitable); + d->multi->setColumns(suitable); } void GameSelectionWidget::update() diff --git a/doomsday/client/src/ui/widgets/gamesessionwidget.cpp b/doomsday/client/src/ui/widgets/gamesessionwidget.cpp new file mode 100644 index 0000000000..8ea413fa0e --- /dev/null +++ b/doomsday/client/src/ui/widgets/gamesessionwidget.cpp @@ -0,0 +1,115 @@ +/** @file gamesessionwidget.cpp + * + * @authors Copyright (c) 2014 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, see: + * http://www.gnu.org/licenses + */ + +#include "ui/widgets/gamesessionwidget.h" + +#include +#include + +using namespace de; + +DENG2_PIMPL(GameSessionWidget) +, DENG2_OBSERVES(de::ButtonWidget, Press) +, DENG2_OBSERVES(App, GameUnload) +{ + ButtonWidget *load; + ButtonWidget *info; + DocumentPopupWidget *popup; + + Instance(Public *i) : Base(i) + { + self.add(load = new ButtonWidget); + self.add(info = new ButtonWidget); + + load->disable(); + load->setBehavior(Widget::ContentClipping); + load->setAlignment(ui::AlignLeft); + load->setTextAlignment(ui::AlignRight); + load->setTextLineAlignment(ui::AlignLeft); + + info->setWidthPolicy(ui::Expand); + info->setAlignment(ui::AlignBottom); + info->setText(_E(s)_E(B) + tr("...")); + + self.add(popup = new DocumentPopupWidget); + popup->setAnchorAndOpeningDirection(info->rule(), ui::Up); + popup->document().setMaximumLineWidth(popup->style().rules().rule("document.popup.width").valuei()); + info->audienceForPress += this; + + App::app().audienceForGameUnload += this; + } + + ~Instance() + { + App::app().audienceForGameUnload -= this; + } + + void aboutToUnloadGame(game::Game const &) + { + popup->close(0); + } + + void buttonPressed(ButtonWidget &bt) + { + /* + // Show information about the game. + popup->setAnchorAndOpeningDirection( + bt.rule(), + bt.rule().top().valuei() + bt.rule().height().valuei() / 2 < + bt.root().viewRule().height().valuei() / 2? + ui::Down : ui::Up);*/ + self.updateInfoContent(); + popup->open(); + } +}; + +GameSessionWidget::GameSessionWidget() : d(new Instance(this)) +{ + rule().setInput(Rule::Height, style().fonts().font("default").height() * 4); + + // Button for extra information. + d->load->rule() + .setInput(Rule::Left, rule().left()) + .setInput(Rule::Top, rule().top()) + .setInput(Rule::Bottom, rule().bottom()) + .setInput(Rule::Right, d->info->rule().left()); + d->info->rule() + .setInput(Rule::Top, rule().top()) + .setInput(Rule::Right, rule().right()) + .setInput(Rule::Bottom, rule().bottom()); +} + +ButtonWidget &GameSessionWidget::loadButton() +{ + return *d->load; +} + +ButtonWidget &GameSessionWidget::infoButton() +{ + return *d->info; +} + +DocumentWidget &GameSessionWidget::document() +{ + return d->popup->document(); +} + +void GameSessionWidget::updateInfoContent() +{ + // overridden by derived classes +} diff --git a/doomsday/client/src/ui/widgets/mpselectionwidget.cpp b/doomsday/client/src/ui/widgets/mpselectionwidget.cpp new file mode 100644 index 0000000000..bb72968e45 --- /dev/null +++ b/doomsday/client/src/ui/widgets/mpselectionwidget.cpp @@ -0,0 +1,265 @@ +/** @file mpselectionwidget.cpp + * + * @authors Copyright (c) 2014 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, see: + * http://www.gnu.org/licenses + */ + +#include "ui/widgets/mpselectionwidget.h" +#include "ui/widgets/taskbarwidget.h" +#include "ui/widgets/gamesessionwidget.h" +#include "network/serverlink.h" +#include "clientapp.h" +#include "dd_main.h" +#include "con_main.h" + +#include +#include +#include +#include +#include +#include + +using namespace de; + +DENG_GUI_PIMPL(MPSelectionWidget) +, DENG2_OBSERVES(ServerLink, DiscoveryUpdate) +, public ChildWidgetOrganizer::IWidgetFactory +{ + static ServerLink &link() { return ClientApp::serverLink(); } + static String hostId(serverinfo_t const &sv) { + return String("%1:%2").arg(sv.address).arg(sv.port); + } + + /** + * Data item with information about a found server. + */ + class ServerListItem : public ui::Item + { + public: + ServerListItem(serverinfo_t const &serverInfo) + { + setData(hostId(serverInfo)); + std::memcpy(&_info, &serverInfo, sizeof(serverInfo)); + } + + serverinfo_t const &info() const + { + return _info; + } + + void setInfo(serverinfo_t const &serverInfo) + { + std::memcpy(&_info, &serverInfo, sizeof(serverInfo)); + notifyChange(); + } + + private: + serverinfo_t _info; + }; + + /** + * Widget representing a ServerListItem in the dialog's menu. + */ + struct ServerWidget : public GameSessionWidget + { + //LabelWidget *title; + //ButtonWidget *extra; + //ButtonWidget *join; + //QScopedPointer layout; + //DocumentPopupWidget *info; + + struct JoinAction : public Action + { + public: + JoinAction(serverinfo_t const &sv, ButtonWidget &owner) + : _owner(&owner) + { + _gameId = sv.gameIdentityKey; + _cmd = String("connect %1 %2").arg(sv.address).arg(sv.port); + } + + void trigger() + { + Action::trigger(); + + BusyMode_FreezeGameForBusyMode(); + + // Closing the taskbar will cause this action to be deleted. Let's take + // ownership of the action so we can delete after we're done. + _owner->takeAction(); + + ClientWindow::main().taskBar().close(); + + App_ChangeGame(App_Games().byIdentityKey(_gameId), false /*no reload*/); + Con_Execute(CMDS_DDAY, _cmd.toLatin1(), false, false); + + delete this; + } + + Action *duplicate() const + { + DENG2_ASSERT(!"JoinAction: cannot duplicate"); + return 0; + } + + private: + ButtonWidget *_owner; + String _gameId; + String _cmd; + }; + + ServerWidget() + { + //setBehavior(ContentClipping); + + //add(title = new LabelWidget); + //add(extra = new ButtonWidget); + //add(join = new ButtonWidget); + + //extra->setText(tr("...")); + //join->setText(tr("Join")); + + //title->setSizePolicy(ui::Expand, ui::Expand); + //title->setAppearanceAnimation(LabelWidget::AppearGrowVertically, 0.5); + /*title->setAlignment(ui::AlignTop); + title->setTextAlignment(ui::AlignRight); + title->setTextLineAlignment(ui::AlignLeft); + title->setImageAlignment(ui::AlignCenter); + title->setMaximumTextWidth(style().rules().rule("dialog.multiplayer.width").valuei());*/ + + //extra->setSizePolicy(ui::Expand, ui::Expand); + //join->setSizePolicy(ui::Expand, ui::Expand); + + //join->disable(); + loadButton().disable(); + + loadButton().setHeightPolicy(ui::Expand); + + /* + layout.reset(new SequentialLayout(rule().left(), rule().top(), ui::Right)); + *layout << *title << *extra << *join; + rule().setSize(layout->width(), title->rule().height()); + + // Extra info popup. + info = new DocumentPopupWidget; + info->document().setMaximumLineWidth(style().rules().rule("dialog.multiplayer.width").valuei()); + info->setAnchorAndOpeningDirection(extra->rule(), ui::Up); + add(info); + + extra->setAction(new SignalAction(info, SLOT(open())));*/ + } + + void updateFromItem(ServerListItem const &item) + { + try + { + Game const &svGame = App_Games().byIdentityKey(item.info().gameIdentityKey); + + if(style().images().has(svGame.logoImageId())) + { + loadButton().setImage(style().images().image(svGame.logoImageId())); + } + + serverinfo_t const &sv = item.info(); + + loadButton().enable(sv.canJoin); + if(sv.canJoin) + { + loadButton().setAction(new JoinAction(sv, loadButton())); + } + + loadButton().setText(String(_E(1) "%1 " _E(.)_E(2) "(%5/%6)" _E(.) "\n%2" + _E(D)_E(l) "\n%7 %4") + .arg(sv.name) + .arg(svGame.title()) + .arg(sv.gameConfig) + .arg(sv.numPlayers) + .arg(sv.maxPlayers) + .arg(sv.map)); + + // Extra information. + document().setText(ServerInfo_AsStyledText(&sv)); + } + catch(Error const &) + { + /// @todo + } + } + }; + + Instance(Public *i) : Base(i) + { + self.organizer().setWidgetFactory(*this); + link().audienceForDiscoveryUpdate += this; + } + + ~Instance() + { + link().audienceForDiscoveryUpdate -= this; + } + + GuiWidget *makeItemWidget(ui::Item const &item, GuiWidget const *) + { + ServerWidget *w = new ServerWidget; + + w->rule().setInput(Rule::Height, w->loadButton().rule().height()); + + // Automatically close the info popup if the dialog is closed. + //QObject::connect(thisPublic, SIGNAL(closed()), w->info, SLOT(close())); + + return w; + } + + void updateItemWidget(GuiWidget &widget, ui::Item const &item) + { + widget.as().updateFromItem(item.as()); + } + + void linkDiscoveryUpdate(ServerLink const &link) + { + // Remove obsolete entries. + for(ui::Data::Pos idx = 0; idx < self.items().size(); ++idx) + { + String const id = self.items().at(idx).data().toString(); + if(!link.isFound(Address::parse(id))) + { + self.items().remove(idx--); + } + } + + // Add new entries and update existing ones. + foreach(de::Address const &host, link.foundServers()) + { + serverinfo_t info; + if(!link.foundServerInfo(host, &info)) continue; + + ui::Data::Pos found = self.items().findData(hostId(info)); + if(found == ui::Data::InvalidPos) + { + // Needs to be added. + self.items().append(new ServerListItem(info)); + } + else + { + // Update the info. + self.items().at(found).as().setInfo(info); + } + } + } +}; + +MPSelectionWidget::MPSelectionWidget() + : MenuWidget("mp-selection"), d(new Instance(this)) +{} From 87fa8467ada9d2b8d11760ddcb2140e2f2fb9ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Mon, 3 Feb 2014 12:17:00 +0200 Subject: [PATCH 062/106] UI|Client: Replaced "Multiplayer Games" with a "Games" dialog The Games dialog shows both the available game sessions and the multiplayer games. It uses the same game selection widget that is used in the Ring Zero UI. --- doomsday/client/client.pro | 4 +- .../client/data/defaultstyle.pack/rules.dei | 2 +- .../{multiplayerdialog.h => gamesdialog.h} | 19 +++--- .../include/ui/widgets/gameselectionwidget.h | 3 +- .../include/ui/widgets/mpselectionwidget.h | 2 + .../client/include/ui/widgets/taskbarwidget.h | 1 + ...{multiplayerdialog.cpp => gamesdialog.cpp} | 41 +++++++++---- .../src/ui/widgets/gameselectionwidget.cpp | 58 ++++++++++++++----- .../src/ui/widgets/mpselectionwidget.cpp | 35 ++++++++++- .../client/src/ui/widgets/taskbarwidget.cpp | 11 +++- 10 files changed, 135 insertions(+), 41 deletions(-) rename doomsday/client/include/ui/dialogs/{multiplayerdialog.h => gamesdialog.h} (66%) rename doomsday/client/src/ui/dialogs/{multiplayerdialog.cpp => gamesdialog.cpp} (57%) diff --git a/doomsday/client/client.pro b/doomsday/client/client.pro index 5251beb03d..ad26b1249b 100644 --- a/doomsday/client/client.pro +++ b/doomsday/client/client.pro @@ -376,9 +376,9 @@ DENG_HEADERS += \ include/ui/dialogs/alertdialog.h \ include/ui/dialogs/audiosettingsdialog.h \ include/ui/dialogs/coloradjustmentdialog.h \ + include/ui/dialogs/gamesdialog.h \ include/ui/dialogs/inputsettingsdialog.h \ include/ui/dialogs/logsettingsdialog.h \ - include/ui/dialogs/multiplayerdialog.h \ include/ui/dialogs/networksettingsdialog.h \ include/ui/dialogs/renderersettingsdialog.h \ include/ui/dialogs/videosettingsdialog.h \ @@ -703,9 +703,9 @@ SOURCES += \ src/ui/dialogs/alertdialog.cpp \ src/ui/dialogs/audiosettingsdialog.cpp \ src/ui/dialogs/coloradjustmentdialog.cpp \ + src/ui/dialogs/gamesdialog.cpp \ src/ui/dialogs/inputsettingsdialog.cpp \ src/ui/dialogs/logsettingsdialog.cpp \ - src/ui/dialogs/multiplayerdialog.cpp \ src/ui/dialogs/networksettingsdialog.cpp \ src/ui/dialogs/videosettingsdialog.cpp \ src/ui/dialogs/vrsettingsdialog.cpp \ diff --git a/doomsday/client/data/defaultstyle.pack/rules.dei b/doomsday/client/data/defaultstyle.pack/rules.dei index 9f533dfafa..c54b63b450 100644 --- a/doomsday/client/data/defaultstyle.pack/rules.dei +++ b/doomsday/client/data/defaultstyle.pack/rules.dei @@ -63,7 +63,7 @@ group console { group gameselection { rule max.width { constant $= UNIT * 215 } - rule max.height { constant $= UNIT * 150 } + rule max.height { constant $= UNIT * 215 } } group coloradjustment { diff --git a/doomsday/client/include/ui/dialogs/multiplayerdialog.h b/doomsday/client/include/ui/dialogs/gamesdialog.h similarity index 66% rename from doomsday/client/include/ui/dialogs/multiplayerdialog.h rename to doomsday/client/include/ui/dialogs/gamesdialog.h index 81d6aa9fcd..05891cae5f 100644 --- a/doomsday/client/include/ui/dialogs/multiplayerdialog.h +++ b/doomsday/client/include/ui/dialogs/gamesdialog.h @@ -1,4 +1,4 @@ -/** @file multiplayerdialog.h Dialog for listing found servers and joining games. +/** @file gamesdialog.h Dialog for viewing and loading available games. * * @authors Copyright (c) 2014 Jaakko Keränen * @@ -16,28 +16,29 @@ * http://www.gnu.org/licenses */ -#ifndef DENG_CLIENT_MULTIPLAYERDIALOG_H -#define DENG_CLIENT_MULTIPLAYERDIALOG_H +#ifndef DENG_CLIENT_GAMESDIALOG_H +#define DENG_CLIENT_GAMESDIALOG_H #include /** - * Dialog for listing found multiplayer servers and joining games. - * - * Servers can be found via the Master Server, LAN Beacon, and manual IP address. + * Dialog for viewing and loading available games. */ -class MultiplayerDialog : public de::DialogWidget +class GamesDialog : public de::DialogWidget { Q_OBJECT public: - MultiplayerDialog(de::String const &name = "multiplayer"); + GamesDialog(de::String const &name = "games"); public slots: void showSettings(); +protected: + void preparePanelForOpening(); + private: DENG2_PRIVATE(d) }; -#endif // DENG_CLIENT_MULTIPLAYERDIALOG_H +#endif // DENG_CLIENT_GAMESDIALOG_H diff --git a/doomsday/client/include/ui/widgets/gameselectionwidget.h b/doomsday/client/include/ui/widgets/gameselectionwidget.h index 3bee2fe10a..8aacd2b603 100644 --- a/doomsday/client/include/ui/widgets/gameselectionwidget.h +++ b/doomsday/client/include/ui/widgets/gameselectionwidget.h @@ -29,8 +29,9 @@ class GameSelectionWidget : public de::ScrollAreaWidget public: GameSelectionWidget(de::String const &name = "gameselection"); + void setTitleColor(de::DotPath const &colorId); + // Events. - void viewResized(); void update(); private: diff --git a/doomsday/client/include/ui/widgets/mpselectionwidget.h b/doomsday/client/include/ui/widgets/mpselectionwidget.h index f38bef1ca2..f7667f500f 100644 --- a/doomsday/client/include/ui/widgets/mpselectionwidget.h +++ b/doomsday/client/include/ui/widgets/mpselectionwidget.h @@ -31,6 +31,8 @@ class MPSelectionWidget : public de::MenuWidget public: MPSelectionWidget(); + void setColumns(int numberOfColumns); + private: DENG2_PRIVATE(d) }; diff --git a/doomsday/client/include/ui/widgets/taskbarwidget.h b/doomsday/client/include/ui/widgets/taskbarwidget.h index d5d264e8f7..481d2f6718 100644 --- a/doomsday/client/include/ui/widgets/taskbarwidget.h +++ b/doomsday/client/include/ui/widgets/taskbarwidget.h @@ -63,6 +63,7 @@ public slots: void unloadGame(); void showAbout(); void showUpdaterSettings(); + void showGames(); protected slots: void updateCommandLineLayout(); diff --git a/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp b/doomsday/client/src/ui/dialogs/gamesdialog.cpp similarity index 57% rename from doomsday/client/src/ui/dialogs/multiplayerdialog.cpp rename to doomsday/client/src/ui/dialogs/gamesdialog.cpp index 440a249da3..e5f12cebe4 100644 --- a/doomsday/client/src/ui/dialogs/multiplayerdialog.cpp +++ b/doomsday/client/src/ui/dialogs/gamesdialog.cpp @@ -1,4 +1,4 @@ -/** @file multiplayerdialog.cpp Dialog for listing found servers and joining games. +/** @file gamesdialog.cpp Dialog for viewing and loading available games. * * @authors Copyright (c) 2014 Jaakko Keränen * @@ -16,35 +16,44 @@ * http://www.gnu.org/licenses */ -#include "ui/dialogs/multiplayerdialog.h" -#include "CommandAction" +#include "ui/dialogs/gamesdialog.h" +#include "ui/widgets/gameselectionwidget.h" #include "ui/dialogs/networksettingsdialog.h" +#include "CommandAction" + #include using namespace de; -DENG_GUI_PIMPL(MultiplayerDialog) +DENG_GUI_PIMPL(GamesDialog) { - //MenuWidget *list; + GameSelectionWidget *gameSel; //MenuWidget *list; Instance(Public *i) : Base(i) { + self.area().add(gameSel = new GameSelectionWidget("games")); + + gameSel->enableScrolling(false); + gameSel->setTitleColor("text"); + gameSel->rule().setInput(Rule::Height, gameSel->contentRule().height()); } }; -MultiplayerDialog::MultiplayerDialog(String const &name) - : DialogWidget(name, WithHeading), d(new Instance(this)) +GamesDialog::GamesDialog(String const &name) + : DialogWidget(name/*, WithHeading*/), d(new Instance(this)) { - heading().setText(tr("Multiplayer Games")); + //heading().setText(tr("Games")); + + //LabelWidget *lab = LabelWidget::newWithText(tr("Games from Master Server and local network:"), &area()); - LabelWidget *lab = LabelWidget::newWithText(tr("Games from Master Server and local network:"), &area()); + //d->gameSel->rule().setInput(Rule::Height, d->gameSel->contentRule().height()/*style().rules().rule("gameselection.max.height")*/); GridLayout layout(area().contentRule().left(), area().contentRule().top()); layout.setGridSize(1, 0); //layout.setColumnAlignment(0, ui::AlignRight); - layout << *lab;// << *d->list; + layout << *d->gameSel; area().setContentSize(layout.width(), layout.height()); @@ -55,10 +64,20 @@ MultiplayerDialog::MultiplayerDialog(String const &name) new SignalAction(this, SLOT(showSettings()))); } -void MultiplayerDialog::showSettings() +void GamesDialog::showSettings() { NetworkSettingsDialog *dlg = new NetworkSettingsDialog; dlg->setAnchorAndOpeningDirection(buttonWidget(Id1)->rule(), ui::Up); dlg->setDeleteAfterDismissed(true); dlg->exec(root()); } + +void GamesDialog::preparePanelForOpening() +{ + DialogWidget::preparePanelForOpening(); + + d->gameSel->rule() + .setInput(Rule::Width, OperatorRule::minimum( + style().rules().rule("gameselection.max.width"), + root().viewWidth() - margins().width())); +} diff --git a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp index 05820e8ba7..f3965ce43c 100644 --- a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp +++ b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp @@ -178,11 +178,28 @@ DENG_GUI_PIMPL(GameSelectionWidget) pendingGames.put(&game); } + void addExistingGames() + { + for(int i = 0; i < App_Games().count(); ++i) + { + gameAdded(App_Games().byIndex(i)); + } + } + void addPendingGames() { while(Game *game = pendingGames.take()) { - incomplete->items().append(makeItemForGame(*game)); + if(game->allStartupFilesFound()) + { + ui::Item *item = makeItemForGame(*game); + available->items().append(item); + available->gameWidget(*item).loadButton().enable(); + } + else + { + incomplete->items().append(makeItemForGame(*game)); + } } } @@ -278,6 +295,18 @@ DENG_GUI_PIMPL(GameSelectionWidget) available->items().sort(); incomplete->items().sort(); } + + void updateLayoutForWidth(int width) + { + // If the view is too small, we'll want to reduce the number of items in the menu. + int const maxWidth = style().rules().rule("gameselection.max.width").valuei(); + + int suitable = clamp(1, 3 * width / maxWidth, 3); + + available->setColumns(suitable); + incomplete->setColumns(suitable); + multi->setColumns(suitable); + } }; GameSelectionWidget::GameSelectionWidget(String const &name) @@ -290,22 +319,16 @@ GameSelectionWidget::GameSelectionWidget(String const &name) // We want the full menu to be visible even when it doesn't fit the // designated area. unsetBehavior(ChildVisibilityClipping); + + // Maybe there are games loaded already. + d->addExistingGames(); } -void GameSelectionWidget::viewResized() +void GameSelectionWidget::setTitleColor(DotPath const &colorId) { - ScrollAreaWidget::viewResized(); - - // If the view is too small, we'll want to reduce the number of items in the menu. - int const maxWidth = style().rules().rule("gameselection.max.width").valuei(); - //int const maxHeight = style().rules().rule("gameselection.max.height").valuei(); - - int suitable = clamp(1, 3 * rule().width().valuei() / maxWidth, 3); - //clamp(1, 8 * rule().height().valuei() / maxHeight, 6)); - - d->available->setColumns(suitable); - d->incomplete->setColumns(suitable); - d->multi->setColumns(suitable); + d->available->title().setTextColor(colorId); + d->multi->title().setTextColor(colorId); + d->incomplete->title().setTextColor(colorId); } void GameSelectionWidget::update() @@ -313,4 +336,11 @@ void GameSelectionWidget::update() d->addPendingGames(); ScrollAreaWidget::update(); + + // Adapt grid layout for the widget width. + Rectanglei rect; + if(hasChangedPlace(rect)) + { + d->updateLayoutForWidth(rect.width()); + } } diff --git a/doomsday/client/src/ui/widgets/mpselectionwidget.cpp b/doomsday/client/src/ui/widgets/mpselectionwidget.cpp index bb72968e45..c72b4217cc 100644 --- a/doomsday/client/src/ui/widgets/mpselectionwidget.cpp +++ b/doomsday/client/src/ui/widgets/mpselectionwidget.cpp @@ -258,8 +258,41 @@ DENG_GUI_PIMPL(MPSelectionWidget) } } } + + /* + void updateLayoutForWidth(int width) + { + // If the view is too small, we'll want to reduce the number of items in the menu. + int const maxWidth = style().rules().rule("mpselection.max.width").valuei(); + + qDebug() << maxWidth << width; + + int suitable = clamp(1, 3 * width / maxWidth, 3); + }*/ }; MPSelectionWidget::MPSelectionWidget() : MenuWidget("mp-selection"), d(new Instance(this)) -{} +{ + setGridSize(3, ui::Filled, 0, ui::Expand); +} + +void MPSelectionWidget::setColumns(int numberOfColumns) +{ + if(layout().maxGridSize().x != numberOfColumns) + { + setGridSize(numberOfColumns, ui::Filled, 0, ui::Expand); + } +} +/* +void MPSelectionWidget::update() +{ + MenuWidget::update(); + + Rectanglei rect; + if(hasChangedPlace(rect)) + { + d->updateLayoutForWidth(rect.width()); + } +} +*/ diff --git a/doomsday/client/src/ui/widgets/taskbarwidget.cpp b/doomsday/client/src/ui/widgets/taskbarwidget.cpp index c9f35c845d..4e2995d6cf 100644 --- a/doomsday/client/src/ui/widgets/taskbarwidget.cpp +++ b/doomsday/client/src/ui/widgets/taskbarwidget.cpp @@ -26,7 +26,7 @@ #include "ui/dialogs/networksettingsdialog.h" #include "ui/dialogs/renderersettingsdialog.h" #include "ui/dialogs/vrsettingsdialog.h" -#include "ui/dialogs/multiplayerdialog.h" +#include "ui/dialogs/gamesdialog.h" #include "updater/updatersettingsdialog.h" #include "ui/clientwindow.h" #include "ui/clientrootwidget.h" @@ -403,7 +403,7 @@ TaskBarWidget::TaskBarWidget() : GuiWidget("taskbar"), d(new Instance(this)) << new ui::SubwidgetItem(style().images().image("updater"), tr("Updater"), ui::Left, makeUpdaterSettings); d->mainMenu->items() - << new ui::SubwidgetItem(tr("Multiplayer Games"), ui::Left, makePopup) + << new ui::ActionItem(tr("Games..."), new SignalAction(this, SLOT(showGames()))) << new ui::Item(ui::Item::Separator) << new ui::ActionItem(tr("Check for Updates..."), new CommandAction("updateandnotify")) << new ui::ActionItem(tr("About Doomsday"), new SignalAction(this, SLOT(showAbout()))) @@ -695,6 +695,13 @@ void TaskBarWidget::showUpdaterSettings() dlg->open(); } +void TaskBarWidget::showGames() +{ + GamesDialog *games = new GamesDialog; + games->setDeleteAfterDismissed(true); + games->exec(root()); +} + void TaskBarWidget::updateCommandLineLayout() { SequentialLayout layout(rule().right(), rule().top(), ui::Left); From 22a181662711eee482ad665d02e08f93a707ce5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Mon, 3 Feb 2014 12:52:12 +0200 Subject: [PATCH 063/106] UI|Task Bar: "Games" is only accessible when not in Ring Zero --- doomsday/client/src/ui/widgets/taskbarwidget.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/doomsday/client/src/ui/widgets/taskbarwidget.cpp b/doomsday/client/src/ui/widgets/taskbarwidget.cpp index 4e2995d6cf..76eb7d2ac7 100644 --- a/doomsday/client/src/ui/widgets/taskbarwidget.cpp +++ b/doomsday/client/src/ui/widgets/taskbarwidget.cpp @@ -59,6 +59,8 @@ static TimeDelta OPEN_CLOSE_SPAN = 0.2; enum MenuItemPositions { // DE menu: + POS_GAMES = 0, + POS_GAMES_SEPARATOR = 1, POS_UNLOAD = 5, // Config menu: @@ -257,7 +259,9 @@ DENG_GUI_PIMPL(TaskBarWidget) { updateStatus(); - itemWidget(mainMenu, POS_UNLOAD).show(!newGame.isNull()); + itemWidget(mainMenu, POS_GAMES) .show(!newGame.isNull()); + itemWidget(mainMenu, POS_GAMES_SEPARATOR).show(!newGame.isNull()); + itemWidget(mainMenu, POS_UNLOAD) .show(!newGame.isNull()); itemWidget(configMenu, POS_RENDERER_SETTINGS).show(!newGame.isNull()); itemWidget(configMenu, POS_VR_SETTINGS) .show(!newGame.isNull()); @@ -411,8 +415,9 @@ TaskBarWidget::TaskBarWidget() : GuiWidget("taskbar"), d(new Instance(this)) << unloadMenu // hidden with null-game << new ui::ActionItem(tr("Quit Doomsday"), new CommandAction("quit")); + d->itemWidget(d->mainMenu, POS_GAMES).hide(); + d->itemWidget(d->mainMenu, POS_GAMES_SEPARATOR).hide(); d->itemWidget(d->mainMenu, POS_UNLOAD).hide(); - //d->itemWidget(d->mainMenu, POS_GAME_SEPARATOR).hide(); d->itemWidget(d->configMenu, POS_RENDERER_SETTINGS).hide(); d->itemWidget(d->configMenu, POS_VR_SETTINGS).hide(); From c6ee12969bb04a7a2f53a5fba697d8bf7a09c938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Mon, 3 Feb 2014 12:52:48 +0200 Subject: [PATCH 064/106] UI|Client: Close Games dialog when a game session has been selected A signal is emitted from GameSelectionWidget after a selection has been made. --- doomsday/client/include/ui/commandaction.h | 4 +- .../include/ui/widgets/gameselectionwidget.h | 5 ++ .../include/ui/widgets/mpselectionwidget.h | 5 ++ doomsday/client/src/ui/commandaction.cpp | 2 +- .../client/src/ui/dialogs/gamesdialog.cpp | 2 + .../src/ui/widgets/gameselectionwidget.cpp | 37 ++++++++++++-- .../src/ui/widgets/mpselectionwidget.cpp | 50 +++---------------- 7 files changed, 58 insertions(+), 47 deletions(-) diff --git a/doomsday/client/include/ui/commandaction.h b/doomsday/client/include/ui/commandaction.h index e9fa0d858c..54fc02b029 100644 --- a/doomsday/client/include/ui/commandaction.h +++ b/doomsday/client/include/ui/commandaction.h @@ -33,8 +33,10 @@ class CommandAction : public de::Action public: CommandAction(de::String const &cmd, int commandSource = CMDS_DDAY); + de::String command() const { return _command; } + void trigger(); - CommandAction *duplicate() const; + Action *duplicate() const; private: de::String _command; diff --git a/doomsday/client/include/ui/widgets/gameselectionwidget.h b/doomsday/client/include/ui/widgets/gameselectionwidget.h index 8aacd2b603..5846acd2f1 100644 --- a/doomsday/client/include/ui/widgets/gameselectionwidget.h +++ b/doomsday/client/include/ui/widgets/gameselectionwidget.h @@ -26,6 +26,8 @@ */ class GameSelectionWidget : public de::ScrollAreaWidget { + Q_OBJECT + public: GameSelectionWidget(de::String const &name = "gameselection"); @@ -34,6 +36,9 @@ class GameSelectionWidget : public de::ScrollAreaWidget // Events. void update(); +signals: + void gameSessionSelected(); + private: DENG2_PRIVATE(d) }; diff --git a/doomsday/client/include/ui/widgets/mpselectionwidget.h b/doomsday/client/include/ui/widgets/mpselectionwidget.h index f7667f500f..b35c6198ab 100644 --- a/doomsday/client/include/ui/widgets/mpselectionwidget.h +++ b/doomsday/client/include/ui/widgets/mpselectionwidget.h @@ -28,11 +28,16 @@ */ class MPSelectionWidget : public de::MenuWidget { + Q_OBJECT + public: MPSelectionWidget(); void setColumns(int numberOfColumns); +signals: + void gameSelected(); + private: DENG2_PRIVATE(d) }; diff --git a/doomsday/client/src/ui/commandaction.cpp b/doomsday/client/src/ui/commandaction.cpp index d5d1ec0fac..021c5eb964 100644 --- a/doomsday/client/src/ui/commandaction.cpp +++ b/doomsday/client/src/ui/commandaction.cpp @@ -33,7 +33,7 @@ void CommandAction::trigger() Con_Execute(_source, _command.toUtf8(), false /*silent*/, false /*net*/); } -CommandAction *CommandAction::duplicate() const +Action *CommandAction::duplicate() const { return new CommandAction(_command, _source); } diff --git a/doomsday/client/src/ui/dialogs/gamesdialog.cpp b/doomsday/client/src/ui/dialogs/gamesdialog.cpp index e5f12cebe4..f0f3b2f125 100644 --- a/doomsday/client/src/ui/dialogs/gamesdialog.cpp +++ b/doomsday/client/src/ui/dialogs/gamesdialog.cpp @@ -43,6 +43,8 @@ DENG_GUI_PIMPL(GamesDialog) GamesDialog::GamesDialog(String const &name) : DialogWidget(name/*, WithHeading*/), d(new Instance(this)) { + connect(d->gameSel, SIGNAL(gameSessionSelected()), this, SLOT(accept())); + //heading().setText(tr("Games")); //LabelWidget *lab = LabelWidget::newWithText(tr("Games from Master Server and local network:"), &area()); diff --git a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp index f3965ce43c..27b3edb29d 100644 --- a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp +++ b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp @@ -93,6 +93,7 @@ DENG_GUI_PIMPL(GameSelectionWidget) case MultiplayerGames: menu = new MPSelectionWidget; + QObject::connect(menu, SIGNAL(gameSelected()), owner->thisPublic, SIGNAL(gameSessionSelected())); break; } @@ -188,6 +189,8 @@ DENG_GUI_PIMPL(GameSelectionWidget) void addPendingGames() { + if(pendingGames.isEmpty()) return; + while(Game *game = pendingGames.take()) { if(game->allStartupFilesFound()) @@ -201,13 +204,36 @@ DENG_GUI_PIMPL(GameSelectionWidget) incomplete->items().append(makeItemForGame(*game)); } } + + sortGames(); } + struct LoadGameAction : public CommandAction + { + GameSelectionWidget &owner; + + LoadGameAction(String const &cmd, GameSelectionWidget &gameSel) + : CommandAction(cmd) + , owner(gameSel) + {} + + void trigger() + { + emit owner.gameSessionSelected(); + CommandAction::trigger(); + } + + Action *duplicate() const + { + return new LoadGameAction(command(), owner); + } + }; + ui::Item *makeItemForGame(Game &game) { String const idKey = game.identityKey(); - CommandAction *loadAction = new CommandAction(String("load ") + idKey); + LoadGameAction *loadAction = new LoadGameAction(String("load ") + idKey, self); String label = String(_E(b) "%1" _E(.) /*_E(s)_E(C) " %2\n" _E(.)_E(.)*/ "\n" _E(l)_E(D) "%2") .arg(game.title()) @@ -260,6 +286,12 @@ DENG_GUI_PIMPL(GameSelectionWidget) updateGameAvailability(); } + void sortGames() + { + available->items().sort(); + incomplete->items().sort(); + } + void updateGameAvailability() { // Available games. @@ -292,8 +324,7 @@ DENG_GUI_PIMPL(GameSelectionWidget) } } - available->items().sort(); - incomplete->items().sort(); + sortGames(); } void updateLayoutForWidth(int width) diff --git a/doomsday/client/src/ui/widgets/mpselectionwidget.cpp b/doomsday/client/src/ui/widgets/mpselectionwidget.cpp index c72b4217cc..24e6370ffa 100644 --- a/doomsday/client/src/ui/widgets/mpselectionwidget.cpp +++ b/doomsday/client/src/ui/widgets/mpselectionwidget.cpp @@ -35,6 +35,7 @@ using namespace de; DENG_GUI_PIMPL(MPSelectionWidget) , DENG2_OBSERVES(ServerLink, DiscoveryUpdate) +, DENG2_OBSERVES(ButtonWidget, Press) , public ChildWidgetOrganizer::IWidgetFactory { static ServerLink &link() { return ClientApp::serverLink(); } @@ -74,12 +75,6 @@ DENG_GUI_PIMPL(MPSelectionWidget) */ struct ServerWidget : public GameSessionWidget { - //LabelWidget *title; - //ButtonWidget *extra; - //ButtonWidget *join; - //QScopedPointer layout; - //DocumentPopupWidget *info; - struct JoinAction : public Action { public: @@ -122,43 +117,8 @@ DENG_GUI_PIMPL(MPSelectionWidget) ServerWidget() { - //setBehavior(ContentClipping); - - //add(title = new LabelWidget); - //add(extra = new ButtonWidget); - //add(join = new ButtonWidget); - - //extra->setText(tr("...")); - //join->setText(tr("Join")); - - //title->setSizePolicy(ui::Expand, ui::Expand); - //title->setAppearanceAnimation(LabelWidget::AppearGrowVertically, 0.5); - /*title->setAlignment(ui::AlignTop); - title->setTextAlignment(ui::AlignRight); - title->setTextLineAlignment(ui::AlignLeft); - title->setImageAlignment(ui::AlignCenter); - title->setMaximumTextWidth(style().rules().rule("dialog.multiplayer.width").valuei());*/ - - //extra->setSizePolicy(ui::Expand, ui::Expand); - //join->setSizePolicy(ui::Expand, ui::Expand); - - //join->disable(); loadButton().disable(); - loadButton().setHeightPolicy(ui::Expand); - - /* - layout.reset(new SequentialLayout(rule().left(), rule().top(), ui::Right)); - *layout << *title << *extra << *join; - rule().setSize(layout->width(), title->rule().height()); - - // Extra info popup. - info = new DocumentPopupWidget; - info->document().setMaximumLineWidth(style().rules().rule("dialog.multiplayer.width").valuei()); - info->setAnchorAndOpeningDirection(extra->rule(), ui::Up); - add(info); - - extra->setAction(new SignalAction(info, SLOT(open())));*/ } void updateFromItem(ServerListItem const &item) @@ -213,7 +173,7 @@ DENG_GUI_PIMPL(MPSelectionWidget) GuiWidget *makeItemWidget(ui::Item const &item, GuiWidget const *) { ServerWidget *w = new ServerWidget; - + w->loadButton().audienceForPress += this; w->rule().setInput(Rule::Height, w->loadButton().rule().height()); // Automatically close the info popup if the dialog is closed. @@ -227,6 +187,12 @@ DENG_GUI_PIMPL(MPSelectionWidget) widget.as().updateFromItem(item.as()); } + void buttonPressed(ButtonWidget &) + { + // A load button has been pressed. + emit self.gameSelected(); + } + void linkDiscoveryUpdate(ServerLink const &link) { // Remove obsolete entries. From 06b4c96b6dd47e708c7c5cae02df2669387679c4 Mon Sep 17 00:00:00 2001 From: danij Date: Mon, 3 Feb 2014 18:51:27 +0000 Subject: [PATCH 065/106] Refactor|libcommon: Switched all remaining sources dealing with save state IO to C++ --- doomsday/client/src/dd_main.cpp | 12 +- doomsday/client/src/world/map.cpp | 2 +- doomsday/plugins/common/common.pri | 6 +- doomsday/plugins/common/include/p_saveio.h | 43 +- doomsday/plugins/common/include/p_xg.h | 7 +- doomsday/plugins/common/include/saveinfo.h | 10 +- .../common/src/{p_saveio.c => p_saveio.cpp} | 153 +++--- doomsday/plugins/common/src/p_xgfile.c | 519 ------------------ doomsday/plugins/common/src/p_xgfile.cpp | 307 +++++++++++ .../common/src/{saveinfo.c => saveinfo.cpp} | 61 +- 10 files changed, 438 insertions(+), 682 deletions(-) rename doomsday/plugins/common/src/{p_saveio.c => p_saveio.cpp} (72%) delete mode 100644 doomsday/plugins/common/src/p_xgfile.c create mode 100644 doomsday/plugins/common/src/p_xgfile.cpp rename doomsday/plugins/common/src/{saveinfo.c => saveinfo.cpp} (92%) diff --git a/doomsday/client/src/dd_main.cpp b/doomsday/client/src/dd_main.cpp index f0803206a0..17be63a9e1 100644 --- a/doomsday/client/src/dd_main.cpp +++ b/doomsday/client/src/dd_main.cpp @@ -104,7 +104,10 @@ class ZipFileType : public de::NativeFileType { public: ZipFileType() : NativeFileType("FT_ZIP", RC_PACKAGE) - {} + { + addKnownExtension(".pk3"); + addKnownExtension(".zip"); + } de::File1 *interpret(de::FileHandle &hndl, String path, FileInfo const &info) const { @@ -122,7 +125,9 @@ class WadFileType : public de::NativeFileType { public: WadFileType() : NativeFileType("FT_WAD", RC_PACKAGE) - {} + { + addKnownExtension(".wad"); + } de::File1 *interpret(de::FileHandle &hndl, String path, FileInfo const &info) const { @@ -186,13 +191,10 @@ static void registerResourceFileTypes() ResourceClass& packageClass = App_ResourceClass("RC_PACKAGE"); ftype = new ZipFileType(); - ftype->addKnownExtension(".pk3"); - ftype->addKnownExtension(".zip"); packageClass.addFileType(*ftype); fileTypeMap.insert(ftype->name().toLower(), ftype); ftype = new WadFileType(); - ftype->addKnownExtension(".wad"); packageClass.addFileType(*ftype); fileTypeMap.insert(ftype->name().toLower(), ftype); diff --git a/doomsday/client/src/world/map.cpp b/doomsday/client/src/world/map.cpp index 09ce60d893..e45398d04d 100644 --- a/doomsday/client/src/world/map.cpp +++ b/doomsday/client/src/world/map.cpp @@ -247,7 +247,7 @@ DENG2_OBSERVES(bsp::Partitioner, UnclosedSectorFound) */ ListNode *newLink() { - if(linkStoreCursor < LINKSTORE_SIZE) + if(linkStoreCursor < (unsigned)LINKSTORE_SIZE) { return &linkStore[linkStoreCursor++]; } diff --git a/doomsday/plugins/common/common.pri b/doomsday/plugins/common/common.pri index e5b219362c..ff6a49b2cd 100644 --- a/doomsday/plugins/common/common.pri +++ b/doomsday/plugins/common/common.pri @@ -107,7 +107,7 @@ SOURCES += \ $$common_src/p_plat.cpp \ $$common_src/p_player.c \ $$common_src/p_saveg.cpp \ - $$common_src/p_saveio.c \ + $$common_src/p_saveio.cpp \ $$common_src/p_scroll.cpp \ $$common_src/p_sound.cpp \ $$common_src/p_start.cpp \ @@ -116,11 +116,11 @@ SOURCES += \ $$common_src/p_tick.c \ $$common_src/p_user.c \ $$common_src/p_view.c \ - $$common_src/p_xgfile.c \ + $$common_src/p_xgfile.cpp \ $$common_src/p_xgline.c \ $$common_src/p_xgsave.cpp \ $$common_src/p_xgsec.c \ $$common_src/polyobjs.cpp \ $$common_src/r_common.c \ - $$common_src/saveinfo.c \ + $$common_src/saveinfo.cpp \ $$common_src/x_hair.c diff --git a/doomsday/plugins/common/include/p_saveio.h b/doomsday/plugins/common/include/p_saveio.h index 0114cc4d91..19cddf04e8 100644 --- a/doomsday/plugins/common/include/p_saveio.h +++ b/doomsday/plugins/common/include/p_saveio.h @@ -1,9 +1,7 @@ -/** - * @file p_saveio.h - * Game save file IO. +/** @file p_saveio.h Game save file IO. * - * @authors Copyright © 2003-2013 Jaakko Keränen - * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -28,10 +26,6 @@ #include "lzss.h" #include "p_savedef.h" -#ifdef __cplusplus -extern "C" { -#endif - typedef enum savestatesegment_e { ASEG_MAP_HEADER = 102, // Hexen only ASEG_MAP_ELEMENTS, @@ -54,6 +48,10 @@ enum { SV_INVALIDFILENAME }; +#ifdef __cplusplus +extern "C" { +#endif + void SV_InitIO(void); void SV_ShutdownIO(void); @@ -107,31 +105,6 @@ void SV_ReadConsistencyBytes(void); */ void SV_Seek(uint offset); -#if 0 -/* - * Writing and reading values - */ -void SV_Write(void const *data, int len); -void SV_WriteByte(byte val); -#if __JHEXEN__ -void SV_WriteShort(unsigned short val); -#else -void SV_WriteShort(short val); -#endif -#if __JHEXEN__ -void SV_WriteLong(unsigned int val); -#else -void SV_WriteLong(long val); -#endif -void SV_WriteFloat(float val); - -void SV_Read(void *data, int len); -byte SV_ReadByte(void); -short SV_ReadShort(void); -long SV_ReadLong(void); -float SV_ReadFloat(void); -#endif - Writer *SV_NewWriter(void); Reader *SV_NewReader(void); @@ -139,4 +112,4 @@ Reader *SV_NewReader(void); } // extern "C" #endif -#endif /* LIBCOMMON_SAVESTATE_INPUT_OUTPUT_H */ +#endif // LIBCOMMON_SAVESTATE_INPUT_OUTPUT_H diff --git a/doomsday/plugins/common/include/p_xg.h b/doomsday/plugins/common/include/p_xg.h index b0143c2698..1915f41d7b 100644 --- a/doomsday/plugins/common/include/p_xg.h +++ b/doomsday/plugins/common/include/p_xg.h @@ -1,4 +1,4 @@ -/** @file p_xg.h Extended Generalised Line / Sector Types. +/** @file p_xg.h Extended generalised line / sector types. * * @authors Copyright © 2003-2013 Jaakko Keränen * @authors Copyright © 2006-2013 Daniel Swanson @@ -46,6 +46,9 @@ void XG_Ticker(void); // Updates XG state during engine reset. void XG_Update(void); +/** + * See if any line or sector types are saved in a DDXGDATA lump. + */ void XG_ReadTypes(void); linetype_t *XG_GetLumpLine(int id); @@ -55,4 +58,4 @@ sectortype_t *XG_GetLumpSector(int id); } // extern "C" #endif -#endif /* LIBCOMMON_PLAYSIM_XG_H */ +#endif // LIBCOMMON_PLAYSIM_XG_H diff --git a/doomsday/plugins/common/include/saveinfo.h b/doomsday/plugins/common/include/saveinfo.h index 55ef988c33..8858d072ec 100644 --- a/doomsday/plugins/common/include/saveinfo.h +++ b/doomsday/plugins/common/include/saveinfo.h @@ -1,4 +1,4 @@ -/** @file common/saveinfo.h Save state info. +/** @file saveinfo.h Save state info. * * @authors Copyright © 2003-2013 Jaakko Keränen * @authors Copyright © 2005-2013 Daniel Swanson @@ -24,10 +24,6 @@ #include "doomsday.h" #include "common.h" -#ifdef __cplusplus -extern "C" { -#endif - typedef struct saveheader_s { int magic; int version; @@ -58,6 +54,10 @@ typedef struct saveinfo_s { saveheader_t header; } SaveInfo; +#ifdef __cplusplus +extern "C" { +#endif + SaveInfo *SaveInfo_New(void); SaveInfo *SaveInfo_NewCopy(SaveInfo const *other); diff --git a/doomsday/plugins/common/src/p_saveio.c b/doomsday/plugins/common/src/p_saveio.cpp similarity index 72% rename from doomsday/plugins/common/src/p_saveio.c rename to doomsday/plugins/common/src/p_saveio.cpp index dbc0b94809..266893a449 100644 --- a/doomsday/plugins/common/src/p_saveio.c +++ b/doomsday/plugins/common/src/p_saveio.cpp @@ -1,42 +1,38 @@ -/**\file p_saveio.c - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_saveio.cpp Game save file IO. * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -#include -#include -#include - #include "common.h" +#include "p_saveio.h" + #include "dmu_lib.h" #include "p_mapsetup.h" #include "p_saveg.h" -#include "p_saveio.h" #include "p_savedef.h" #include "saveinfo.h" #include "api_materialarchive.h" +#include +#include + static dd_bool inited; -static LZFILE* savefile; +static LZFILE *savefile; static ddstring_t savePath; // e.g., "savegame/" #if !__JHEXEN__ static ddstring_t clientSavePath; // e.g., "savegame/client/" @@ -47,7 +43,7 @@ static saveptr_t saveptr; static void *saveEndPtr; #endif -static void errorIfNotInited(const char* callerName) +static void errorIfNotInited(char const *callerName) { if(inited) return; Con_Error("%s: Savegame I/O is not presently initialized.", callerName); @@ -56,9 +52,9 @@ static void errorIfNotInited(const char* callerName) } /// @return Possibly relative saved game directory. Does not need to be free'd. -static AutoStr* composeSaveDir(void) +static AutoStr *composeSaveDir() { - AutoStr* dir = AutoStr_NewStd(); + AutoStr *dir = AutoStr_NewStd(); if(CommandLine_CheckWith("-savedir", 1)) { @@ -70,18 +66,18 @@ static AutoStr* composeSaveDir(void) } // Use the default path. - { GameInfo gameInfo; + GameInfo gameInfo; if(DD_GameInfo(&gameInfo)) { Str_Appendf(dir, SAVEGAME_DEFAULT_DIR "/%s/", Str_Text(gameInfo.identityKey)); return dir; - }} + } Con_Error("composeSaveDir: Error, failed retrieving GameInfo."); exit(1); // Unreachable. } -void SV_InitIO(void) +void SV_InitIO() { Str_Init(&savePath); #if !__JHEXEN__ @@ -91,7 +87,7 @@ void SV_InitIO(void) savefile = 0; } -void SV_ShutdownIO(void) +void SV_ShutdownIO() { if(!inited) return; @@ -105,24 +101,24 @@ void SV_ShutdownIO(void) inited = false; } -const char* SV_SavePath(void) +char const *SV_SavePath() { return Str_Text(&savePath); } #if !__JHEXEN__ -const char* SV_ClientSavePath(void) +char const *SV_ClientSavePath() { return Str_Text(&clientSavePath); } #endif // Compose and create the saved game directories. -void SV_ConfigureSavePaths(void) +void SV_ConfigureSavePaths() { - assert(inited); - { - AutoStr* saveDir = composeSaveDir(); + DENG_ASSERT(inited); + + AutoStr *saveDir = composeSaveDir(); dd_bool savePathExists; Str_Set(&savePath, Str_Text(saveDir)); @@ -136,14 +132,16 @@ void SV_ConfigureSavePaths(void) if(!F_MakePath(Str_Text(&clientSavePath))) savePathExists = false; #endif + if(!savePathExists) + { App_Log(DE2_RES_ERROR, "SV_ConfigureSavePaths: Failed to locate \"%s\". Perhaps it could " "not be created (insufficent permissions?). Saving will not be possible.", Str_Text(&savePath)); } } -LZFILE *SV_File(void) +LZFILE *SV_File() { return savefile; } @@ -155,7 +153,7 @@ LZFILE *SV_OpenFile(Str const *filePath, char const *mode) return savefile; } -void SV_CloseFile(void) +void SV_CloseFile() { if(savefile) { @@ -166,8 +164,7 @@ void SV_CloseFile(void) dd_bool SV_ExistingFile(Str const *filePath) { - FILE *fp; - if((fp = fopen(Str_Text(filePath), "rb"))) + if(FILE *fp = fopen(Str_Text(filePath), "rb")) { fclose(fp); return true; @@ -183,32 +180,29 @@ int SV_RemoveFile(Str const *filePath) void SV_CopyFile(Str const *srcPath, Str const *destPath) { - size_t length; - char *buffer; - LZFILE *outf; - if(!srcPath || !destPath) return; if(!SV_ExistingFile(srcPath)) return; - length = M_ReadFile(Str_Text(srcPath), &buffer); - if(length == 0) + char *buffer; + size_t length = M_ReadFile(Str_Text(srcPath), &buffer); + if(!length) { App_Log(DE2_RES_ERROR, "SV_CopyFile: Failed opening \"%s\" for reading", Str_Text(srcPath)); return; } - outf = lzOpen((char*)Str_Text(destPath), "wp"); - if(outf) + if(LZFILE *outf = lzOpen((char*)Str_Text(destPath), "wp")) { lzWrite(buffer, length, outf); lzClose(outf); } + Z_Free(buffer); } #ifdef __JHEXEN__ -saveptr_t *SV_HxSavePtr(void) +saveptr_t *SV_HxSavePtr() { return &saveptr; } @@ -218,7 +212,7 @@ void SV_HxSetSaveEndPtr(void *endPtr) saveEndPtr = endPtr; } -dd_bool SV_HxBytesLeft(void) +dd_bool SV_HxBytesLeft() { return (byte *) saveEndPtr - saveptr.b; } @@ -234,10 +228,10 @@ void SV_Seek(uint offset) #endif } -void SV_Write(const void* data, int len) +void SV_Write(void const *data, int len) { errorIfNotInited("SV_Write"); - lzWrite((void*)data, len, savefile); + lzWrite((void *)data, len, savefile); } void SV_WriteByte(byte val) @@ -268,10 +262,11 @@ void SV_WriteLong(long val) void SV_WriteFloat(float val) { + DENG_ASSERT(sizeof(val) == 4); + int32_t temp = 0; - assert(sizeof(val) == 4); errorIfNotInited("SV_WriteFloat"); - memcpy(&temp, &val, 4); + std::memcpy(&temp, &val, 4); lzPutL(temp, savefile); } @@ -279,47 +274,47 @@ void SV_Read(void *data, int len) { errorIfNotInited("SV_Read"); #if __JHEXEN__ - memcpy(data, saveptr.b, len); + std::memcpy(data, saveptr.b, len); saveptr.b += len; #else lzRead(data, len, savefile); #endif } -byte SV_ReadByte(void) +byte SV_ReadByte() { errorIfNotInited("SV_ReadByte"); #if __JHEXEN__ - assert((saveptr.b + 1) <= (byte *) saveEndPtr); + DENG_ASSERT((saveptr.b + 1) <= (byte *) saveEndPtr); return (*saveptr.b++); #else return lzGetC(savefile); #endif } -short SV_ReadShort(void) +short SV_ReadShort() { errorIfNotInited("SV_ReadShort"); #if __JHEXEN__ - assert((saveptr.w + 1) <= (short *) saveEndPtr); + DENG_ASSERT((saveptr.w + 1) <= (short *) saveEndPtr); return (SHORT(*saveptr.w++)); #else return lzGetW(savefile); #endif } -long SV_ReadLong(void) +long SV_ReadLong() { errorIfNotInited("SV_ReadLong"); #if __JHEXEN__ - assert((saveptr.l + 1) <= (int *) saveEndPtr); + DENG_ASSERT((saveptr.l + 1) <= (int *) saveEndPtr); return (LONG(*saveptr.l++)); #else return lzGetL(savefile); #endif } -float SV_ReadFloat(void) +float SV_ReadFloat() { #if !__JHEXEN__ float returnValue = 0; @@ -331,8 +326,8 @@ float SV_ReadFloat(void) #else val = lzGetL(savefile); returnValue = 0; - assert(sizeof(float) == 4); - memcpy(&returnValue, &val, 4); + DENG_ASSERT(sizeof(float) == 4); + std::memcpy(&returnValue, &val, 4); return returnValue; #endif } @@ -360,7 +355,7 @@ void SV_AssertMapSegment(savestatesegment_t *retSegmentId) if(segmentId != ASEG_MAP_HEADER2 && segmentId != ASEG_MAP_HEADER) Con_Error("Corrupt save game: Segment [%d] failed alignment check", segmentId); - if(retSegmentId) *retSegmentId = segmentId; + if(retSegmentId) *retSegmentId = savestatesegment_t(segmentId); #else SV_AssertSegment(ASEG_MAP_HEADER2); if(retSegmentId) *retSegmentId = ASEG_MAP_HEADER2; @@ -397,72 +392,72 @@ void SV_ReadConsistencyBytes() #endif } -static void swi8(Writer* w, char i) +static void swi8(Writer *w, char i) { if(!w) return; SV_WriteByte(i); } -static void swi16(Writer* w, short i) +static void swi16(Writer *w, short i) { if(!w) return; SV_WriteShort(i); } -static void swi32(Writer* w, int i) +static void swi32(Writer *w, int i) { if(!w) return; SV_WriteLong(i); } -static void swf(Writer* w, float i) +static void swf(Writer *w, float i) { if(!w) return; SV_WriteFloat(i); } -static void swd(Writer* w, const char* data, int len) +static void swd(Writer *w, char const *data, int len) { if(!w) return; SV_Write(data, len); } -Writer* SV_NewWriter(void) +Writer *SV_NewWriter() { return Writer_NewWithCallbacks(swi8, swi16, swi32, swf, swd); } -static char sri8(Reader* r) +static char sri8(Reader *r) { if(!r) return 0; return SV_ReadByte(); } -static short sri16(Reader* r) +static short sri16(Reader *r) { if(!r) return 0; return SV_ReadShort(); } -static int sri32(Reader* r) +static int sri32(Reader *r) { if(!r) return 0; return SV_ReadLong(); } -static float srf(Reader* r) +static float srf(Reader *r) { if(!r) return 0; return SV_ReadFloat(); } -static void srd(Reader* r, char* data, int len) +static void srd(Reader *r, char *data, int len) { if(!r) return; SV_Read(data, len); } -Reader* SV_NewReader(void) +Reader *SV_NewReader() { return Reader_NewWithCallbacks(sri8, sri16, sri32, srf, srd); } diff --git a/doomsday/plugins/common/src/p_xgfile.c b/doomsday/plugins/common/src/p_xgfile.c deleted file mode 100644 index a76abf28ac..0000000000 --- a/doomsday/plugins/common/src/p_xgfile.c +++ /dev/null @@ -1,519 +0,0 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html - * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2005-2013 Daniel Swanson - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * p_xgfile.c: Extended Generalized Line Types. - * - * Writes XG data to file. Parses DD_XGDATA lumps. - */ - -#if __JDOOM__ || __JHERETIC__ || __JDOOM64__ - -// HEADER FILES ------------------------------------------------------------ - -#include -#include -#include - -#if __JDOOM__ -# include "jdoom.h" -#elif __JDOOM64__ -# include "jdoom64.h" -#elif __JHERETIC__ -# include "jheretic.h" -#elif __JSTRIFE__ -# include "jstrife.h" -#endif - -#include "p_xg.h" - -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -typedef enum xgsegenum_e { - XGSEG_END, - XGSEG_LINE, - XGSEG_SECTOR -} xgsegenum_t; - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -dd_bool xgDataLumps = false; - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -static FILE* file; -static const byte* readptr; - -static linetype_t*linetypes = 0; -static int num_linetypes = 0; - -static sectortype_t* sectypes; -static int num_sectypes; - -// CODE -------------------------------------------------------------------- - -static void WriteByte(byte b) -{ - fputc(b, file); -} - -static void WriteShort(short s) -{ - s = SHORT(s); - fwrite(&s, 2, 1, file); -} - -static void WriteLong(long l) -{ - l = LONG(l); - fwrite(&l, 4, 1, file); -} - -static void WriteFloat(float f) -{ - f = FLOAT(f); - fwrite(&f, 4, 1, file); -} - -/*void Write(void *data, int len) -{ - fwrite(data, len, 1, file); -} -*/ - -static void WriteString(char *str) -{ - int len; - - if(!str) - { - WriteShort(0); - return; - } - len = strlen(str); - WriteShort(len); - //Write(str, len); - fwrite(str, len, 1, file); -} - -static byte ReadByte(void) -{ - return *readptr++; -} - -static short ReadShort(void) -{ - short s = *(const short *) readptr; - - readptr += 2; - // Swap the bytes. - //s = (s<<8) + (s>>8); - return SHORT(s); -} - -static long ReadLong(void) -{ - long l = *(const long *) readptr; - - readptr += 4; - // Swap the bytes. - //l = (l<<24) + (l>>24) + ((l & 0xff0000) >> 8) + ((l & 0xff00) << 8); - return LONG(l); -} - -static float ReadFloat(void) -{ - long f = ReadLong(); - float returnValue = 0; - - memcpy(&returnValue, &f, 4); - return returnValue; -} - -/** - * I could just return a pointer to the string, but that risks losing - * it somewhere. Now we can be absolutely sure it can't be lost. - */ -static void ReadString(char** str) -{ - int len = ReadShort(); - - if(!len) // Null string? - { - *str = 0; - return; - } - - if(len < 0) - Con_Error("ReadString: Bogus len!\n"); - - // Allocate memory for the string. - *str = Z_Malloc(len + 1, PU_GAMESTATIC, 0); - memcpy(*str, readptr, len); - readptr += len; - (*str)[len] = 0; -} - -#if 0 // No longer supported. -void XG_WriteTypes(FILE* f) -{ - int i, k; - int linecount = 0, sectorcount = 0; - char buff[6]; - linetype_t line; - sectortype_t sec; - - file = f; - - // The first four four bytes are a header. - // They will be updated with the real counts afterwards. - WriteShort(0); // Number of lines & sectors (two shorts). - WriteShort(0); - - // This is a very simple way to get the definitions. - for(i = 1; i < 65536; ++i) - { - sprintf(buff, "%i", i); - if(!Def_Get(DD_DEF_LINE_TYPE, buff, &line)) - continue; - - linecount++; - - // Write marker. - WriteByte(XGSEG_LINE); - - WriteShort(line.id); - WriteLong(line.flags); - WriteLong(line.flags2); - WriteLong(line.flags3); - WriteShort(line.lineClass); - WriteByte(line.actType); - WriteShort(line.actCount); - WriteFloat(line.actTime); - WriteLong(line.actTag); - for(k = 0; k < DDLT_MAX_APARAMS; ++k) - WriteLong(line.aparm[k]); - WriteFloat(line.tickerStart); - WriteFloat(line.tickerEnd); - WriteLong(line.tickerInterval); - WriteShort(line.actSound); - WriteShort(line.deactSound); - WriteShort(line.evChain); - WriteShort(line.actChain); - WriteShort(line.deactChain); - WriteByte(line.wallSection); - WriteShort(line.actMaterial); - WriteShort(line.deactMaterial); - WriteString(line.actMsg); - WriteString(line.deactMsg); - WriteFloat(line.materialMoveAngle); - WriteFloat(line.materialMoveSpeed); - for(k = 0; k < DDLT_MAX_PARAMS; ++k) - WriteLong(line.iparm[k]); - for(k = 0; k < DDLT_MAX_PARAMS; ++k) - WriteFloat(line.fparm[k]); - for(k = 0; k < DDLT_MAX_SPARAMS; k++) - WriteString(line.sparm[k]); - } - - // Then the sectors. - for(i = 1; i < 65536; ++i) - { - sprintf(buff, "%i", i); - if(!Def_Get(DD_DEF_SECTOR_TYPE, buff, &sec)) - continue; - - sectorcount++; - - // Write marker. - WriteByte(XGSEG_SECTOR); - - WriteShort(sec.id); - WriteLong(sec.flags); - WriteLong(sec.actTag); - for(k = 0; k < DDLT_MAX_CHAINS; ++k) - WriteLong(sec.chain[k]); - for(k = 0; k < DDLT_MAX_CHAINS; ++k) - WriteLong(sec.chainFlags[k]); - for(k = 0; k < DDLT_MAX_CHAINS; ++k) - WriteFloat(sec.start[k]); - for(k = 0; k < DDLT_MAX_CHAINS; ++k) - WriteFloat(sec.end[k]); - for(k = 0; k < DDLT_MAX_CHAINS; ++k) - { - WriteFloat(sec.interval[k][0]); - WriteFloat(sec.interval[k][1]); - } - for(k = 0; k < DDLT_MAX_CHAINS; ++k) - WriteLong(sec.count[k]); - WriteShort(sec.ambientSound); - WriteFloat(sec.soundInterval[0]); - WriteFloat(sec.soundInterval[1]); - WriteFloat(sec.materialMoveAngle[0]); - WriteFloat(sec.materialMoveAngle[1]); - WriteFloat(sec.materialMoveSpeed[0]); - WriteFloat(sec.materialMoveSpeed[1]); - WriteFloat(sec.windAngle); - WriteFloat(sec.windSpeed); - WriteFloat(sec.verticalWind); - WriteFloat(sec.gravity); - WriteFloat(sec.friction); - WriteString(sec.lightFunc); - WriteShort(sec.lightInterval[0]); - WriteShort(sec.lightInterval[1]); - WriteString(sec.colFunc[0]); - WriteString(sec.colFunc[1]); - WriteString(sec.colFunc[2]); - for(k = 0; k < 3; ++k) - { - WriteShort(sec.colInterval[k][0]); - WriteShort(sec.colInterval[k][1]); - } - WriteString(sec.floorFunc); - WriteFloat(sec.floorMul); - WriteFloat(sec.floorOff); - WriteShort(sec.floorInterval[0]); - WriteShort(sec.floorInterval[1]); - WriteString(sec.ceilFunc); - WriteFloat(sec.ceilMul); - WriteFloat(sec.ceilOff); - WriteShort(sec.ceilInterval[0]); - WriteShort(sec.ceilInterval[1]); - } - - // Write the end marker. - WriteByte(XGSEG_END); - - // Update header. - rewind(file); - WriteShort(linecount); - WriteShort(sectorcount); -} -#endif - -static Uri* readTextureUrn(void) -{ - return Uri_NewWithPath2(Str_Text(Str_Appendf(AutoStr_NewStd(), "urn:Textures:%i", ReadShort())), RC_NULL); -} - -void XG_ReadXGLump(lumpnum_t lumpNum) -{ - int lc = 0, sc = 0, i; - sectortype_t* sec; - linetype_t* li; - dd_bool done = false; - size_t len; - uint8_t* buf; - - if(0 > lumpNum) - return; // No such lump. - - xgDataLumps = true; - - App_Log(DE2_RES_MSG, "Reading XG types from DDXGDATA"); - - len = W_LumpLength(lumpNum); - buf = (uint8_t*) M_Malloc(len); - W_ReadLump(lumpNum, buf); - - readptr = (byte*)buf; - - num_linetypes = ReadShort(); - num_sectypes = ReadShort(); - - // Allocate the arrays. - linetypes = Z_Calloc(sizeof(*linetypes) * num_linetypes, PU_GAMESTATIC, 0); - sectypes = Z_Calloc(sizeof(*sectypes) * num_sectypes, PU_GAMESTATIC, 0); - - while(!done) - { - // Get next segment. - switch(ReadByte()) - { - case XGSEG_END: - done = true; - break; - - case XGSEG_LINE: - li = linetypes + lc++; - // Read the def. - li->id = ReadShort(); - li->flags = ReadLong(); - li->flags2 = ReadLong(); - li->flags3 = ReadLong(); - li->lineClass = ReadShort(); - li->actType = ReadByte(); - li->actCount = ReadShort(); - li->actTime = ReadFloat(); - li->actTag = ReadLong(); - for(i = 0; i < DDLT_MAX_APARAMS; ++i) - li->aparm[i] = ReadLong(); - li->tickerStart = ReadFloat(); - li->tickerEnd = ReadFloat(); - li->tickerInterval = ReadLong(); - li->actSound = ReadShort(); - li->deactSound = ReadShort(); - li->evChain = ReadShort(); - li->actChain = ReadShort(); - li->deactChain = ReadShort(); - li->wallSection = ReadByte(); - - { - Uri* textureUrn = readTextureUrn(); - li->actMaterial = P_ToIndex(DD_MaterialForTextureUri(textureUrn)); - Uri_Delete(textureUrn); - } - - { - Uri* textureUrn = readTextureUrn(); - li->deactMaterial = P_ToIndex(DD_MaterialForTextureUri(textureUrn)); - Uri_Delete(textureUrn); - } - - ReadString(&li->actMsg); - ReadString(&li->deactMsg); - li->materialMoveAngle = ReadFloat(); - li->materialMoveSpeed = ReadFloat(); - for(i = 0; i < DDLT_MAX_PARAMS; ++i) - li->iparm[i] = ReadLong(); - for(i = 0; i < DDLT_MAX_PARAMS; ++i) - li->fparm[i] = ReadFloat(); - for(i = 0; i < DDLT_MAX_SPARAMS; ++i) - ReadString(&li->sparm[i]); - break; - - case XGSEG_SECTOR: - sec = sectypes + sc++; - // Read the def. - sec->id = ReadShort(); - sec->flags = ReadLong(); - sec->actTag = ReadLong(); - for(i = 0; i < DDLT_MAX_CHAINS; ++i) - sec->chain[i] = ReadLong(); - for(i = 0; i < DDLT_MAX_CHAINS; ++i) - sec->chainFlags[i] = ReadLong(); - for(i = 0; i < DDLT_MAX_CHAINS; ++i) - sec->start[i] = ReadFloat(); - for(i = 0; i < DDLT_MAX_CHAINS; ++i) - sec->end[i] = ReadFloat(); - for(i = 0; i < DDLT_MAX_CHAINS; ++i) - { - sec->interval[i][0] = ReadFloat(); - sec->interval[i][1] = ReadFloat(); - } - for(i = 0; i < DDLT_MAX_CHAINS; ++i) - sec->count[i] = ReadLong(); - sec->ambientSound = ReadShort(); - sec->soundInterval[0] = ReadFloat(); - sec->soundInterval[1] = ReadFloat(); - sec->materialMoveAngle[0] = ReadFloat(); - sec->materialMoveAngle[1] = ReadFloat(); - sec->materialMoveSpeed[0] = ReadFloat(); - sec->materialMoveSpeed[1] = ReadFloat(); - sec->windAngle = ReadFloat(); - sec->windSpeed = ReadFloat(); - sec->verticalWind = ReadFloat(); - sec->gravity = ReadFloat(); - sec->friction = ReadFloat(); - ReadString(&sec->lightFunc); - sec->lightInterval[0] = ReadShort(); - sec->lightInterval[1] = ReadShort(); - ReadString(&sec->colFunc[0]); - ReadString(&sec->colFunc[1]); - ReadString(&sec->colFunc[2]); - for(i = 0; i < 3; ++i) - { - sec->colInterval[i][0] = ReadShort(); - sec->colInterval[i][1] = ReadShort(); - } - ReadString(&sec->floorFunc); - sec->floorMul = ReadFloat(); - sec->floorOff = ReadFloat(); - sec->floorInterval[0] = ReadShort(); - sec->floorInterval[1] = ReadShort(); - ReadString(&sec->ceilFunc); - sec->ceilMul = ReadFloat(); - sec->ceilOff = ReadFloat(); - sec->ceilInterval[0] = ReadShort(); - sec->ceilInterval[1] = ReadShort(); - break; - - default: - Con_Error("XG_ReadXGLump: Bad segment!\n"); - } - } - - M_Free(buf); -} - -/** - * See if any line or sector types are saved in a DDXGDATA lump. - */ -void XG_ReadTypes(void) -{ - num_linetypes = 0; - num_sectypes = 0; - if(linetypes) - Z_Free(linetypes); - if(sectypes) - Z_Free(sectypes); - linetypes = 0; - sectypes = 0; - - XG_ReadXGLump(W_CheckLumpNumForName("DDXGDATA")); -} - -linetype_t* XG_GetLumpLine(int id) -{ - int i; - - for(i = 0; i < num_linetypes; ++i) - if(linetypes[i].id == id) - return linetypes + i; - - return NULL; // Not found. -} - -sectortype_t *XG_GetLumpSector(int id) -{ - int i; - - for(i = 0; i < num_sectypes; ++i) - if(sectypes[i].id == id) - return sectypes + i; - - return NULL; // Not found. -} - -#endif diff --git a/doomsday/plugins/common/src/p_xgfile.cpp b/doomsday/plugins/common/src/p_xgfile.cpp new file mode 100644 index 0000000000..d79cacd18b --- /dev/null +++ b/doomsday/plugins/common/src/p_xgfile.cpp @@ -0,0 +1,307 @@ +/** @file p_xgfile.cpp Extended Generalized Line Types. + * + * DD_XGDATA lump reader. + * + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#if __JDOOM__ || __JHERETIC__ || __JDOOM64__ + +#include "common.h" +#include "p_xg.h" + +#include +#include +#include + +enum xgsegenum_t +{ + XGSEG_END, + XGSEG_LINE, + XGSEG_SECTOR +}; + +dd_bool xgDataLumps; + +static FILE *file; +static byte const *readptr; + +static linetype_t *linetypes; +static int num_linetypes; + +static sectortype_t *sectypes; +static int num_sectypes; + +static byte ReadByte() +{ + return *readptr++; +} + +static short ReadShort() +{ + short s = *(const short *) readptr; + readptr += 2; + // Swap the bytes. + //s = (s<<8) + (s>>8); + return SHORT(s); +} + +static long ReadLong() +{ + long l = *(const long *) readptr; + readptr += 4; + // Swap the bytes. + //l = (l<<24) + (l>>24) + ((l & 0xff0000) >> 8) + ((l & 0xff00) << 8); + return LONG(l); +} + +static float ReadFloat() +{ + long f = ReadLong(); + float returnValue = 0; + std::memcpy(&returnValue, &f, 4); + return returnValue; +} + +/** + * I could just return a pointer to the string, but that risks losing + * it somewhere. Now we can be absolutely sure it can't be lost. + */ +static void ReadString(char **str) +{ + int len = ReadShort(); + if(!len) // Null string? + { + *str = 0; + return; + } + + if(len < 0) + Con_Error("ReadString: Bogus len!\n"); + + // Allocate memory for the string. + *str = (char *) Z_Malloc(len + 1, PU_GAMESTATIC, 0); + std::memcpy(*str, readptr, len); + readptr += len; + (*str)[len] = 0; +} + +static Uri *readTextureUrn() +{ + return Uri_NewWithPath2(Str_Text(Str_Appendf(AutoStr_NewStd(), "urn:Textures:%i", ReadShort())), RC_NULL); +} + +void XG_ReadXGLump(lumpnum_t lumpNum) +{ + if(0 > lumpNum) + return; // No such lump. + + xgDataLumps = true; + + App_Log(DE2_RES_MSG, "Reading XG types from DDXGDATA"); + + size_t len = W_LumpLength(lumpNum); + uint8_t *buf = (uint8_t *) M_Malloc(len); + W_ReadLump(lumpNum, buf); + + readptr = (byte *)buf; + + // Allocate the arrays. + + num_linetypes = ReadShort(); + linetypes = (linetype_t *)Z_Calloc(sizeof(*linetypes) * num_linetypes, PU_GAMESTATIC, 0); + + num_sectypes = ReadShort(); + sectypes = (sectortype_t *)Z_Calloc(sizeof(*sectypes) * num_sectypes, PU_GAMESTATIC, 0); + + int lc = 0, sc = 0; + + dd_bool done = false; + while(!done) + { + // Get next segment. + switch(ReadByte()) + { + case XGSEG_END: + done = true; + break; + + case XGSEG_LINE: { + linetype_t *li = linetypes + lc++; + + // Read the def. + li->id = ReadShort(); + li->flags = ReadLong(); + li->flags2 = ReadLong(); + li->flags3 = ReadLong(); + li->lineClass = ReadShort(); + li->actType = ReadByte(); + li->actCount = ReadShort(); + li->actTime = ReadFloat(); + li->actTag = ReadLong(); + for(int i = 0; i < DDLT_MAX_APARAMS; ++i) + { + li->aparm[i] = ReadLong(); + } + li->tickerStart = ReadFloat(); + li->tickerEnd = ReadFloat(); + li->tickerInterval = ReadLong(); + li->actSound = ReadShort(); + li->deactSound = ReadShort(); + li->evChain = ReadShort(); + li->actChain = ReadShort(); + li->deactChain = ReadShort(); + li->wallSection = ReadByte(); + + { + Uri *textureUrn = readTextureUrn(); + li->actMaterial = P_ToIndex(DD_MaterialForTextureUri(textureUrn)); + Uri_Delete(textureUrn); + } + + { + Uri *textureUrn = readTextureUrn(); + li->deactMaterial = P_ToIndex(DD_MaterialForTextureUri(textureUrn)); + Uri_Delete(textureUrn); + } + + ReadString(&li->actMsg); + ReadString(&li->deactMsg); + li->materialMoveAngle = ReadFloat(); + li->materialMoveSpeed = ReadFloat(); + for(int i = 0; i < DDLT_MAX_PARAMS; ++i) + { + li->iparm[i] = ReadLong(); + } + for(int i = 0; i < DDLT_MAX_PARAMS; ++i) + { + li->fparm[i] = ReadFloat(); + } + for(int i = 0; i < DDLT_MAX_SPARAMS; ++i) + { + ReadString(&li->sparm[i]); + } + break; } + + case XGSEG_SECTOR: { + sectortype_t *sec = sectypes + sc++; + + // Read the def. + sec->id = ReadShort(); + sec->flags = ReadLong(); + sec->actTag = ReadLong(); + for(int i = 0; i < DDLT_MAX_CHAINS; ++i) + { + sec->chain[i] = ReadLong(); + } + for(int i = 0; i < DDLT_MAX_CHAINS; ++i) + { + sec->chainFlags[i] = ReadLong(); + } + for(int i = 0; i < DDLT_MAX_CHAINS; ++i) + { + sec->start[i] = ReadFloat(); + } + for(int i = 0; i < DDLT_MAX_CHAINS; ++i) + { + sec->end[i] = ReadFloat(); + } + for(int i = 0; i < DDLT_MAX_CHAINS; ++i) + { + sec->interval[i][0] = ReadFloat(); + sec->interval[i][1] = ReadFloat(); + } + for(int i = 0; i < DDLT_MAX_CHAINS; ++i) + { + sec->count[i] = ReadLong(); + } + sec->ambientSound = ReadShort(); + sec->soundInterval[0] = ReadFloat(); + sec->soundInterval[1] = ReadFloat(); + sec->materialMoveAngle[0] = ReadFloat(); + sec->materialMoveAngle[1] = ReadFloat(); + sec->materialMoveSpeed[0] = ReadFloat(); + sec->materialMoveSpeed[1] = ReadFloat(); + sec->windAngle = ReadFloat(); + sec->windSpeed = ReadFloat(); + sec->verticalWind = ReadFloat(); + sec->gravity = ReadFloat(); + sec->friction = ReadFloat(); + ReadString(&sec->lightFunc); + sec->lightInterval[0] = ReadShort(); + sec->lightInterval[1] = ReadShort(); + ReadString(&sec->colFunc[0]); + ReadString(&sec->colFunc[1]); + ReadString(&sec->colFunc[2]); + for(int i = 0; i < 3; ++i) + { + sec->colInterval[i][0] = ReadShort(); + sec->colInterval[i][1] = ReadShort(); + } + ReadString(&sec->floorFunc); + sec->floorMul = ReadFloat(); + sec->floorOff = ReadFloat(); + sec->floorInterval[0] = ReadShort(); + sec->floorInterval[1] = ReadShort(); + ReadString(&sec->ceilFunc); + sec->ceilMul = ReadFloat(); + sec->ceilOff = ReadFloat(); + sec->ceilInterval[0] = ReadShort(); + sec->ceilInterval[1] = ReadShort(); + break; } + + default: + Con_Error("XG_ReadXGLump: Bad segment!"); + } + } + + M_Free(buf); +} + +void XG_ReadTypes() +{ + num_linetypes = 0; + Z_Free(linetypes); linetypes = 0; + + num_sectypes = 0; + Z_Free(sectypes); sectypes = 0; + + XG_ReadXGLump(W_CheckLumpNumForName("DDXGDATA")); +} + +linetype_t* XG_GetLumpLine(int id) +{ + for(int i = 0; i < num_linetypes; ++i) + { + if(linetypes[i].id == id) + return linetypes + i; + } + return 0; // Not found. +} + +sectortype_t *XG_GetLumpSector(int id) +{ + for(int i = 0; i < num_sectypes; ++i) + { + if(sectypes[i].id == id) + return sectypes + i; + } + return 0; // Not found. +} + +#endif diff --git a/doomsday/plugins/common/src/saveinfo.c b/doomsday/plugins/common/src/saveinfo.cpp similarity index 92% rename from doomsday/plugins/common/src/saveinfo.c rename to doomsday/plugins/common/src/saveinfo.cpp index 4c5d71ab60..9af76adb4e 100644 --- a/doomsday/plugins/common/src/saveinfo.c +++ b/doomsday/plugins/common/src/saveinfo.cpp @@ -1,4 +1,4 @@ -/** @file common/saveinfo.c Save state info. +/** @file saveinfo.cpp Save state info. * * @authors Copyright © 2003-2013 Jaakko Keränen * @authors Copyright © 2005-2013 Daniel Swanson @@ -18,19 +18,17 @@ * 02110-1301 USA */ -#include -#include - #include "common.h" - -#include +#include "saveinfo.h" #include "p_tick.h" #include "p_saveg.h" #include "p_saveio.h" -#include "saveinfo.h" +#include +#include +#include -SaveInfo *SaveInfo_New(void) +SaveInfo *SaveInfo_New() { SaveInfo *info = (SaveInfo *)M_Malloc(sizeof *info); @@ -96,10 +94,9 @@ void SaveInfo_SetName(SaveInfo *info, Str const *newName) void SaveInfo_Configure(SaveInfo *info) { - saveheader_t *hdr; DENG_ASSERT(info != 0); - hdr = &info->header; + saveheader_t *hdr = &info->header; hdr->magic = IS_NETWORK_CLIENT? MY_CLIENT_SAVE_MAGIC : MY_SAVE_MAGIC; hdr->version = MY_SAVE_VERSION; @@ -127,11 +124,10 @@ void SaveInfo_Configure(SaveInfo *info) hdr->respawnMonsters = respawnMonsters; hdr->mapTime = mapTime; - { int i; - for(i = 0; i < MAXPLAYERS; i++) + for(int i = 0; i < MAXPLAYERS; i++) { hdr->players[i] = players[i].plr->inGame; - }} + } #endif } @@ -149,10 +145,9 @@ dd_bool SaveInfo_IsLoadable(SaveInfo *info) void SaveInfo_Write(SaveInfo *info, Writer *writer) { - saveheader_t *hdr; DENG_ASSERT(info != 0); - hdr = &info->header; + saveheader_t *hdr = &info->header; Writer_WriteInt32(writer, hdr->magic); Writer_WriteInt32(writer, hdr->version); Writer_WriteInt32(writer, hdr->gameMode); @@ -172,11 +167,10 @@ void SaveInfo_Write(SaveInfo *info, Writer *writer) Writer_WriteByte(writer, hdr->respawnMonsters); Writer_WriteInt32(writer, hdr->mapTime); - { int i; - for(i = 0; i < MAXPLAYERS; ++i) + for(int i = 0; i < MAXPLAYERS; ++i) { Writer_WriteByte(writer, hdr->players[i]); - }} + } #endif Writer_WriteInt32(writer, info->gameId); } @@ -184,6 +178,8 @@ void SaveInfo_Write(SaveInfo *info, Writer *writer) #if __JDOOM__ || __JHERETIC__ static void translateLegacyGameMode(gamemode_t *mode, int saveVersion) { + DENG_ASSERT(mode != 0); + static gamemode_t const oldGameModes[] = { # if __JDOOM__ doom_shareware, @@ -197,8 +193,6 @@ static void translateLegacyGameMode(gamemode_t *mode, int saveVersion) # endif }; - DENG_ASSERT(mode != 0); - // Is translation unnecessary? #if __JDOOM__ if(saveVersion >= 9) return; @@ -226,12 +220,12 @@ static void translateLegacyGameMode(gamemode_t *mode, int saveVersion) void SaveInfo_Read(SaveInfo *info, Reader *reader) { - saveheader_t *hdr; DENG_ASSERT(info != 0); - hdr = &info->header; - hdr->magic = Reader_ReadInt32(reader); - hdr->version = Reader_ReadInt32(reader); + saveheader_t *hdr = &info->header; + + hdr->magic = Reader_ReadInt32(reader); + hdr->version = Reader_ReadInt32(reader); hdr->gameMode = (gamemode_t)Reader_ReadInt32(reader); if(hdr->version >= 10) @@ -241,10 +235,12 @@ void SaveInfo_Read(SaveInfo *info, Reader *reader) else { // Older formats use a fixed-length name (24 characters). -#define OLD_NAME_LENGTH 24 +#define OLD_NAME_LENGTH 24 + char buf[OLD_NAME_LENGTH]; Reader_Read(reader, buf, OLD_NAME_LENGTH); Str_Set(&info->name, buf); + #undef OLD_NAME_LENGTH } @@ -273,7 +269,7 @@ void SaveInfo_Read(SaveInfo *info, Reader *reader) else #endif { - hdr->skill = Reader_ReadByte(reader) & 0x7f; + hdr->skill = skillmode_t( Reader_ReadByte(reader) & 0x7f ); // Interpret skill levels outside the normal range as "spawn no things". if(hdr->skill < SM_BABY || hdr->skill >= NUM_SKILL_MODES) @@ -300,11 +296,10 @@ void SaveInfo_Read(SaveInfo *info, Reader *reader) hdr->mapTime = Reader_ReadInt32(reader); - { int i; - for(i = 0; i < MAXPLAYERS; ++i) + for(int i = 0; i < MAXPLAYERS; ++i) { hdr->players[i] = Reader_ReadByte(reader); - }} + } #endif info->gameId = Reader_ReadInt32(reader); @@ -322,12 +317,12 @@ void SaveInfo_Read_Hx_v9(SaveInfo *info, Reader *reader) # define HXS_VERSION_TEXT_LENGTH 16 # define HXS_NAME_LENGTH 24 - char verText[HXS_VERSION_TEXT_LENGTH], nameBuffer[HXS_NAME_LENGTH]; - saveheader_t *hdr; - DENG_ASSERT(info != 0); - hdr = &info->header; + char verText[HXS_VERSION_TEXT_LENGTH]; + char nameBuffer[HXS_NAME_LENGTH]; + + saveheader_t *hdr = &info->header; Reader_Read(reader, nameBuffer, HXS_NAME_LENGTH); Str_Set(&info->name, nameBuffer); From 84b2733fba88c16715bc8f576a28fb097f36ee64 Mon Sep 17 00:00:00 2001 From: danij Date: Mon, 3 Feb 2014 20:02:07 +0000 Subject: [PATCH 066/106] Refactor|libdoom: Switched DOOM v1.9 save state interpreter/reader to C++ --- doomsday/plugins/doom/doom.pro | 2 +- .../doom/src/{p_oldsvg.c => p_oldsvg.cpp} | 534 ++++++++---------- 2 files changed, 252 insertions(+), 284 deletions(-) rename doomsday/plugins/doom/src/{p_oldsvg.c => p_oldsvg.cpp} (62%) diff --git a/doomsday/plugins/doom/doom.pro b/doomsday/plugins/doom/doom.pro index 0fad8a1a4a..64ab353d97 100644 --- a/doomsday/plugins/doom/doom.pro +++ b/doomsday/plugins/doom/doom.pro @@ -82,7 +82,7 @@ SOURCES += \ src/p_lights.cpp \ src/p_maputl.c \ src/p_mobj.c \ - src/p_oldsvg.c \ + src/p_oldsvg.cpp \ src/p_pspr.c \ src/p_setup.c \ src/p_spec.c \ diff --git a/doomsday/plugins/doom/src/p_oldsvg.c b/doomsday/plugins/doom/src/p_oldsvg.cpp similarity index 62% rename from doomsday/plugins/doom/src/p_oldsvg.c rename to doomsday/plugins/doom/src/p_oldsvg.cpp index 8e297a4b7b..9203d4b73b 100644 --- a/doomsday/plugins/doom/src/p_oldsvg.c +++ b/doomsday/plugins/doom/src/p_oldsvg.cpp @@ -1,10 +1,8 @@ -/** - * @file p_oldsvg.c - * Doom ver 1.9 save game reader. +/** @file p_oldsvg.cpp Doom ver 1.9 save game reader. * - * @authors Copyright © 2003-2013 Jaakko Keränen - * @authors Copyright © 2005-2013 Daniel Swanson - * @authors Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 1993-1996 id Software, Inc. * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -22,6 +20,7 @@ */ #include "jdoom.h" +#include "p_oldsvg.h" #include "dmu_lib.h" #include "p_saveg.h" @@ -48,80 +47,81 @@ #define SIZEOF_V19_THINKER_T 12 #define V19_THINKER_T_FUNC_OFFSET 8 -static byte* savePtr; -static byte* saveBuffer; -static Reader* svReader; +static byte *savePtr; +static byte *saveBuffer; +static Reader *svReader; -static dd_bool SV_OpenFile_Dm_v19(const char* filePath); -static void SV_CloseFile_Dm_v19(void); -static Reader* SV_NewReader_Dm_v19(void); +static dd_bool SV_OpenFile_Dm_v19(char const *filePath); +static void SV_CloseFile_Dm_v19(); +static Reader *SV_NewReader_Dm_v19(); -static void SaveInfo_Read_Dm_v19(SaveInfo* info, Reader* reader); +static void SaveInfo_Read_Dm_v19(SaveInfo *info, Reader *reader); -static char sri8(Reader* r) +static char sri8(Reader *r) { if(!r) return 0; savePtr++; - return *(char*) (savePtr - 1); + return *(char *) (savePtr - 1); } -static short sri16(Reader* r) +static short sri16(Reader *r) { if(!r) return 0; savePtr += 2; return *(int16_t *) (savePtr - 2); } -static int sri32(Reader* r) +static int sri32(Reader *r) { if(!r) return 0; savePtr += 4; return *(int32_t *) (savePtr - 4); } -static void srd(Reader* r, char* data, int len) +static void srd(Reader *r, char *data, int len) { if(!r) return; if(data) { - memcpy(data, savePtr, len); + std::memcpy(data, savePtr, len); } savePtr += len; } -static void SV_v19_ReadPlayer(player_t* pl) +static void SV_v19_ReadPlayer(player_t *pl) { - int i; - Reader_ReadInt32(svReader); - pl->playerState = Reader_ReadInt32(svReader); + + pl->playerState = playerstate_t(Reader_ReadInt32(svReader)); + Reader_Read(svReader, NULL, 8); - pl->viewZ = FIX2FLT(Reader_ReadInt32(svReader)); - pl->viewHeight = FIX2FLT(Reader_ReadInt32(svReader)); + + pl->viewZ = FIX2FLT(Reader_ReadInt32(svReader)); + pl->viewHeight = FIX2FLT(Reader_ReadInt32(svReader)); pl->viewHeightDelta = FIX2FLT(Reader_ReadInt32(svReader)); - pl->bob = FLT2FIX(Reader_ReadInt32(svReader)); - pl->flyHeight = 0; - pl->health = Reader_ReadInt32(svReader); - pl->armorPoints = Reader_ReadInt32(svReader); - pl->armorType = Reader_ReadInt32(svReader); + pl->bob = FLT2FIX(Reader_ReadInt32(svReader)); + pl->flyHeight = 0; + pl->health = Reader_ReadInt32(svReader); + pl->armorPoints = Reader_ReadInt32(svReader); + pl->armorType = Reader_ReadInt32(svReader); memset(pl->powers, 0, sizeof(pl->powers)); pl->powers[PT_INVULNERABILITY] = (Reader_ReadInt32(svReader)? true : false); - pl->powers[PT_STRENGTH] = (Reader_ReadInt32(svReader)? true : false); - pl->powers[PT_INVISIBILITY] = (Reader_ReadInt32(svReader)? true : false); - pl->powers[PT_IRONFEET] = (Reader_ReadInt32(svReader)? true : false); - pl->powers[PT_ALLMAP] = (Reader_ReadInt32(svReader)? true : false); + pl->powers[PT_STRENGTH] = (Reader_ReadInt32(svReader)? true : false); + pl->powers[PT_INVISIBILITY] = (Reader_ReadInt32(svReader)? true : false); + pl->powers[PT_IRONFEET] = (Reader_ReadInt32(svReader)? true : false); + pl->powers[PT_ALLMAP] = (Reader_ReadInt32(svReader)? true : false); if(pl->powers[PT_ALLMAP]) ST_RevealAutomap(pl - players, true); - pl->powers[PT_INFRARED] = (Reader_ReadInt32(svReader)? true : false); + pl->powers[PT_INFRARED] = (Reader_ReadInt32(svReader)? true : false); memset(pl->keys, 0, sizeof(pl->keys)); - pl->keys[KT_BLUECARD] = (Reader_ReadInt32(svReader)? true : false); - pl->keys[KT_YELLOWCARD] = (Reader_ReadInt32(svReader)? true : false); - pl->keys[KT_REDCARD] = (Reader_ReadInt32(svReader)? true : false); - pl->keys[KT_BLUESKULL] = (Reader_ReadInt32(svReader)? true : false); + pl->keys[KT_BLUECARD] = (Reader_ReadInt32(svReader)? true : false); + pl->keys[KT_YELLOWCARD] = (Reader_ReadInt32(svReader)? true : false); + pl->keys[KT_REDCARD] = (Reader_ReadInt32(svReader)? true : false); + pl->keys[KT_BLUESKULL] = (Reader_ReadInt32(svReader)? true : false); pl->keys[KT_YELLOWSKULL] = (Reader_ReadInt32(svReader)? true : false); - pl->keys[KT_REDSKULL] = (Reader_ReadInt32(svReader)? true : false); + pl->keys[KT_REDSKULL] = (Reader_ReadInt32(svReader)? true : false); pl->backpack = Reader_ReadInt32(svReader); @@ -131,77 +131,75 @@ static void SV_v19_ReadPlayer(player_t* pl) pl->frags[2] = Reader_ReadInt32(svReader); pl->frags[3] = Reader_ReadInt32(svReader); - pl->readyWeapon = Reader_ReadInt32(svReader); - pl->pendingWeapon = Reader_ReadInt32(svReader); + pl->readyWeapon = weapontype_t(Reader_ReadInt32(svReader)); + pl->pendingWeapon = weapontype_t(Reader_ReadInt32(svReader)); memset(pl->weapons, 0, sizeof(pl->weapons)); - pl->weapons[WT_FIRST].owned = (Reader_ReadInt32(svReader)? true : false); - pl->weapons[WT_SECOND].owned = (Reader_ReadInt32(svReader)? true : false); - pl->weapons[WT_THIRD].owned = (Reader_ReadInt32(svReader)? true : false); - pl->weapons[WT_FOURTH].owned = (Reader_ReadInt32(svReader)? true : false); - pl->weapons[WT_FIFTH].owned = (Reader_ReadInt32(svReader)? true : false); - pl->weapons[WT_SIXTH].owned = (Reader_ReadInt32(svReader)? true : false); + pl->weapons[WT_FIRST].owned = (Reader_ReadInt32(svReader)? true : false); + pl->weapons[WT_SECOND].owned = (Reader_ReadInt32(svReader)? true : false); + pl->weapons[WT_THIRD].owned = (Reader_ReadInt32(svReader)? true : false); + pl->weapons[WT_FOURTH].owned = (Reader_ReadInt32(svReader)? true : false); + pl->weapons[WT_FIFTH].owned = (Reader_ReadInt32(svReader)? true : false); + pl->weapons[WT_SIXTH].owned = (Reader_ReadInt32(svReader)? true : false); pl->weapons[WT_SEVENTH].owned = (Reader_ReadInt32(svReader)? true : false); - pl->weapons[WT_EIGHTH].owned = (Reader_ReadInt32(svReader)? true : false); - pl->weapons[WT_NINETH].owned = (Reader_ReadInt32(svReader)? true : false); + pl->weapons[WT_EIGHTH].owned = (Reader_ReadInt32(svReader)? true : false); + pl->weapons[WT_NINETH].owned = (Reader_ReadInt32(svReader)? true : false); memset(pl->ammo, 0, sizeof(pl->ammo)); - pl->ammo[AT_CLIP].owned = Reader_ReadInt32(svReader); - pl->ammo[AT_SHELL].owned = Reader_ReadInt32(svReader); - pl->ammo[AT_CELL].owned = Reader_ReadInt32(svReader); + pl->ammo[AT_CLIP].owned = Reader_ReadInt32(svReader); + pl->ammo[AT_SHELL].owned = Reader_ReadInt32(svReader); + pl->ammo[AT_CELL].owned = Reader_ReadInt32(svReader); pl->ammo[AT_MISSILE].owned = Reader_ReadInt32(svReader); - pl->ammo[AT_CLIP].max = Reader_ReadInt32(svReader); - pl->ammo[AT_SHELL].max = Reader_ReadInt32(svReader); - pl->ammo[AT_CELL].max = Reader_ReadInt32(svReader); + + pl->ammo[AT_CLIP].max = Reader_ReadInt32(svReader); + pl->ammo[AT_SHELL].max = Reader_ReadInt32(svReader); + pl->ammo[AT_CELL].max = Reader_ReadInt32(svReader); pl->ammo[AT_MISSILE].max = Reader_ReadInt32(svReader); - pl->attackDown = Reader_ReadInt32(svReader); - pl->useDown = Reader_ReadInt32(svReader); + pl->attackDown = Reader_ReadInt32(svReader); + pl->useDown = Reader_ReadInt32(svReader); - pl->cheats = Reader_ReadInt32(svReader); - pl->refire = Reader_ReadInt32(svReader); + pl->cheats = Reader_ReadInt32(svReader); + pl->refire = Reader_ReadInt32(svReader); - pl->killCount = Reader_ReadInt32(svReader); - pl->itemCount = Reader_ReadInt32(svReader); + pl->killCount = Reader_ReadInt32(svReader); + pl->itemCount = Reader_ReadInt32(svReader); pl->secretCount = Reader_ReadInt32(svReader); Reader_ReadInt32(svReader); pl->damageCount = Reader_ReadInt32(svReader); - pl->bonusCount = Reader_ReadInt32(svReader); + pl->bonusCount = Reader_ReadInt32(svReader); Reader_ReadInt32(svReader); - pl->plr->extraLight = Reader_ReadInt32(svReader); + pl->plr->extraLight = Reader_ReadInt32(svReader); pl->plr->fixedColorMap = Reader_ReadInt32(svReader); + pl->colorMap = Reader_ReadInt32(svReader); - for(i = 0; i < 2; ++i) + + for(int i = 0; i < 2; ++i) { - pspdef_t* psp = &pl->pSprites[i]; + pspdef_t *psp = &pl->pSprites[i]; - psp->state = INT2PTR(state_t, Reader_ReadInt32(svReader)); + psp->state = INT2PTR(state_t, Reader_ReadInt32(svReader)); psp->pos[VX] = Reader_ReadInt32(svReader); psp->pos[VY] = Reader_ReadInt32(svReader); - psp->tics = Reader_ReadInt32(svReader); + psp->tics = Reader_ReadInt32(svReader); } - pl->didSecret = Reader_ReadInt32(svReader); + + pl->didSecret = Reader_ReadInt32(svReader); } -static void SV_v19_ReadMobj(void) +static void SV_v19_ReadMobj() { - float pos[3], mom[3], radius, height, floorz, ceilingz; - angle_t angle; - spritenum_t sprite; - int frame, valid, type, ddflags = 0; - mobj_t* mo; - mobjinfo_t* info; - // List: thinker links. Reader_ReadInt32(svReader); Reader_ReadInt32(svReader); Reader_ReadInt32(svReader); // Info for drawing: position. + coord_t pos[3]; pos[VX] = FIX2FLT(Reader_ReadInt32(svReader)); pos[VY] = FIX2FLT(Reader_ReadInt32(svReader)); pos[VZ] = FIX2FLT(Reader_ReadInt32(svReader)); @@ -211,9 +209,10 @@ static void SV_v19_ReadMobj(void) Reader_ReadInt32(svReader); //More drawing info: to determine current sprite. - angle = Reader_ReadInt32(svReader); // orientation - sprite = Reader_ReadInt32(svReader); // used to find patch_t and flip value - frame = Reader_ReadInt32(svReader); // might be ORed with FF_FULLBRIGHT + angle_t angle = Reader_ReadInt32(svReader); // orientation + spritenum_t sprite = Reader_ReadInt32(svReader); // used to find patch_t and flip value + + int frame = Reader_ReadInt32(svReader); // might be ORed with FF_FULLBRIGHT if(frame & FF_FULLBRIGHT) frame &= FF_FRAMEMASK; // not used anymore. @@ -224,30 +223,32 @@ static void SV_v19_ReadMobj(void) Reader_ReadInt32(svReader); // The closest interval over all contacted Sectors. - floorz = FIX2FLT(Reader_ReadInt32(svReader)); - ceilingz = FIX2FLT(Reader_ReadInt32(svReader)); + coord_t floorz = FIX2FLT(Reader_ReadInt32(svReader)); + coord_t ceilingz = FIX2FLT(Reader_ReadInt32(svReader)); // For movement checking. - radius = FIX2FLT(Reader_ReadInt32(svReader)); - height = FIX2FLT(Reader_ReadInt32(svReader)); + coord_t radius = FIX2FLT(Reader_ReadInt32(svReader)); + coord_t height = FIX2FLT(Reader_ReadInt32(svReader)); // Momentums, used to update position. + coord_t mom[3]; mom[MX] = FIX2FLT(Reader_ReadInt32(svReader)); mom[MY] = FIX2FLT(Reader_ReadInt32(svReader)); mom[MZ] = FIX2FLT(Reader_ReadInt32(svReader)); - valid = Reader_ReadInt32(svReader); - type = Reader_ReadInt32(svReader); - info = &MOBJINFO[type]; + int valid = Reader_ReadInt32(svReader); + int type = Reader_ReadInt32(svReader); + mobjinfo_t *info = &MOBJINFO[type]; + int ddflags = 0; if(info->flags & MF_SOLID) ddflags |= DDMF_SOLID; if(info->flags2 & MF2_DONTDRAW) ddflags |= DDMF_DONTDRAW; - /** + /* * We now have all the information we need to create the mobj. */ - mo = Mobj_CreateXYZ(P_MobjThinker, pos[VX], pos[VY], pos[VZ], angle, - radius, height, ddflags); + mobj_t *mo = Mobj_CreateXYZ(P_MobjThinker, pos[VX], pos[VY], pos[VZ], angle, + radius, height, ddflags); mo->sprite = sprite; mo->frame = frame; @@ -260,20 +261,17 @@ static void SV_v19_ReadMobj(void) mo->type = type; mo->moveDir = DI_NODIR; - /** - * Continue reading the mobj data. - */ - Reader_ReadInt32(svReader); // &mobjinfo[mo->type] + Reader_ReadInt32(svReader); // &mobjinfo[mo->type] - mo->tics = Reader_ReadInt32(svReader); // state tic counter + mo->tics = Reader_ReadInt32(svReader); // state tic counter mo->state = INT2PTR(state_t, Reader_ReadInt32(svReader)); mo->damage = DDMAXINT; // Use damage set in mo->info->damage mo->flags = Reader_ReadInt32(svReader); mo->health = Reader_ReadInt32(svReader); // Movement direction, movement generation (zig-zagging). - mo->moveDir = Reader_ReadInt32(svReader); // 0-7 - mo->moveCount = Reader_ReadInt32(svReader); // when 0, select a new dir + mo->moveDir = Reader_ReadInt32(svReader); // 0-7 + mo->moveCount = Reader_ReadInt32(svReader); // when 0, select a new dir // Thing being chased/attacked (or NULL), // also the originator for missiles. @@ -301,12 +299,10 @@ static void SV_v19_ReadMobj(void) mo->spawnSpot.angle = (angle_t) (ANG45 * ((int)Reader_ReadInt16(svReader) / 45)); /* mo->spawnSpot.type = (int) */ Reader_ReadInt16(svReader); - { int spawnFlags = ((int) Reader_ReadInt16(svReader)) & ~MASK_UNKNOWN_MSF_FLAGS; // Spawn on the floor by default unless the mobjtype flags override. spawnFlags |= MSF_Z_FLOOR; mo->spawnSpot.flags = spawnFlags; - } // Thing being chased/attacked for tracers. Reader_ReadInt32(svReader); @@ -331,11 +327,9 @@ static void SV_v19_ReadMobj(void) mo->ceilingZ = P_GetDoublep(Mobj_Sector(mo), DMU_CEILING_HEIGHT); } -static void P_v19_UnArchivePlayers(void) +static void P_v19_UnArchivePlayers() { - int i, j; - - for(i = 0; i < 4; ++i) + for(int i = 0; i < 4; ++i) { if(!players[i].plr->inGame) continue; @@ -347,12 +341,12 @@ static void P_v19_UnArchivePlayers(void) players[i].plr->mo = NULL; players[i].attacker = NULL; - for(j = 0; j < NUMPSPRITES; ++j) + for(int k = 0; k < NUMPSPRITES; ++k) { - if(players[i].pSprites[j].state) + if(players[i].pSprites[k].state) { - players[i].pSprites[j].state = - &STATES[PTR2INT(players[i].pSprites[j].state)]; + players[i].pSprites[k].state = + &STATES[PTR2INT(players[i].pSprites[k].state)]; } } } @@ -360,35 +354,26 @@ static void P_v19_UnArchivePlayers(void) static Uri *readTextureUrn(Reader *reader, char const *schemeName) { - DENG_ASSERT(reader && schemeName); + DENG_ASSERT(reader != 0 && schemeName != 0); return Uri_NewWithPath2(Str_Text(Str_Appendf(AutoStr_NewStd(), "urn:%s:%i", schemeName, Reader_ReadInt16(svReader))), RC_NULL); } -static void P_v19_UnArchiveWorld(void) +static void P_v19_UnArchiveWorld() { - int i, j; - float matOffset[2]; - Sector *sec; - xsector_t *xsec; - Line *line; - xline_t *xline; - // Do sectors. - for(i = 0; i < numsectors; ++i) + for(int i = 0; i < numsectors; ++i) { - Uri *floorTextureUrn, *ceilingTextureUrn; - - sec = P_ToPtr(DMU_SECTOR, i); - xsec = P_ToXSector(sec); + Sector *sec = (Sector *)P_ToPtr(DMU_SECTOR, i); + xsector_t *xsec = P_ToXSector(sec); P_SetDoublep(sec, DMU_FLOOR_HEIGHT, (coord_t) Reader_ReadInt16(svReader)); P_SetDoublep(sec, DMU_CEILING_HEIGHT, (coord_t) Reader_ReadInt16(svReader)); - floorTextureUrn = readTextureUrn(svReader, "Flats"); + Uri *floorTextureUrn = readTextureUrn(svReader, "Flats"); P_SetPtrp (sec, DMU_FLOOR_MATERIAL, DD_MaterialForTextureUri(floorTextureUrn)); Uri_Delete(floorTextureUrn); - ceilingTextureUrn = readTextureUrn(svReader, "Flats"); + Uri *ceilingTextureUrn = readTextureUrn(svReader, "Flats"); P_SetPtrp (sec, DMU_CEILING_MATERIAL, DD_MaterialForTextureUri(ceilingTextureUrn)); Uri_Delete(ceilingTextureUrn); @@ -400,74 +385,69 @@ static void P_v19_UnArchiveWorld(void) } // Do lines. - for(i = 0; i < numlines; ++i) + for(int i = 0; i < numlines; ++i) { - line = P_ToPtr(DMU_LINE, i); - xline = P_ToXLine(line); + Line *line = (Line *)P_ToPtr(DMU_LINE, i); + xline_t *xline = P_ToXLine(line); xline->flags = Reader_ReadInt16(svReader); xline->special = Reader_ReadInt16(svReader); /*xline->tag =*/Reader_ReadInt16(svReader); - for(j = 0; j < 2; ++j) + for(int k = 0; k < 2; ++k) { - Uri *topTextureUrn, *bottomTextureUrn, *middleTextureUrn; - - Side* sdef = P_GetPtrp(line, (j? DMU_BACK:DMU_FRONT)); + Side *sdef = (Side *)P_GetPtrp(line, (k? DMU_BACK:DMU_FRONT)); if(!sdef) continue; + float matOffset[2]; matOffset[VX] = (float) (Reader_ReadInt16(svReader)); matOffset[VY] = (float) (Reader_ReadInt16(svReader)); P_SetFloatpv(sdef, DMU_TOP_MATERIAL_OFFSET_XY, matOffset); P_SetFloatpv(sdef, DMU_MIDDLE_MATERIAL_OFFSET_XY, matOffset); P_SetFloatpv(sdef, DMU_BOTTOM_MATERIAL_OFFSET_XY, matOffset); - topTextureUrn = readTextureUrn(svReader, "Textures"); + Uri *topTextureUrn = readTextureUrn(svReader, "Textures"); P_SetPtrp(sdef, DMU_TOP_MATERIAL, DD_MaterialForTextureUri(topTextureUrn)); Uri_Delete(topTextureUrn); - bottomTextureUrn = readTextureUrn(svReader, "Textures"); + Uri *bottomTextureUrn = readTextureUrn(svReader, "Textures"); P_SetPtrp(sdef, DMU_BOTTOM_MATERIAL, DD_MaterialForTextureUri(bottomTextureUrn)); Uri_Delete(bottomTextureUrn); - middleTextureUrn = readTextureUrn(svReader, "Textures"); + Uri *middleTextureUrn = readTextureUrn(svReader, "Textures"); P_SetPtrp(sdef, DMU_MIDDLE_MATERIAL, DD_MaterialForTextureUri(middleTextureUrn)); Uri_Delete(middleTextureUrn); } } } -static int removeThinker(thinker_t* th, void* context) +static int removeThinker(thinker_t *th, void *context) { if(th->function == (thinkfunc_t) P_MobjThinker) + { P_MobjRemove((mobj_t *) th, true); + } else + { Z_Free(th); + } return false; // Continue iteration. } -static void P_v19_UnArchiveThinkers(void) +static void P_v19_UnArchiveThinkers() { - enum thinkerclass_e { - TC_END, - TC_MOBJ - }; - byte tClass; - // Remove all the current thinkers. Thinker_Iterate(NULL, removeThinker, NULL); Thinker_Init(); // Read in saved thinkers. - for(;;) + byte tClass; + while((tClass = Reader_ReadByte(svReader)) != 0 /*TC_END*/) { - tClass = Reader_ReadByte(svReader); switch(tClass) { - case TC_END: return; // End of list. - - case TC_MOBJ: + case 1: //TC_MOBJ PADSAVEP(); SV_v19_ReadMobj(); break; @@ -478,7 +458,7 @@ static void P_v19_UnArchiveThinkers(void) } } -static int SV_v19_ReadCeiling(ceiling_t* ceiling) +static int SV_v19_ReadCeiling(ceiling_t *ceiling) { /* Original DOOM format: typedef struct { @@ -500,24 +480,26 @@ typedef struct { Reader_Read(svReader, &temp, SIZEOF_V19_THINKER_T); // Start of used data members. - ceiling->type = Reader_ReadInt32(svReader); + ceiling->type = ceilingtype_e(Reader_ReadInt32(svReader)); // A 32bit pointer to sector, serialized. - ceiling->sector = P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); + ceiling->sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); if(!ceiling->sector) Con_Error("tc_ceiling: bad sector number\n"); ceiling->bottomHeight = FIX2FLT(Reader_ReadInt32(svReader)); ceiling->topHeight = FIX2FLT(Reader_ReadInt32(svReader)); - ceiling->speed = FIX2FLT(Reader_ReadInt32(svReader)); - ceiling->crush = Reader_ReadInt32(svReader); - ceiling->state = (Reader_ReadInt32(svReader) == -1? CS_DOWN : CS_UP); - ceiling->tag = Reader_ReadInt32(svReader); - ceiling->oldState = (Reader_ReadInt32(svReader) == -1? CS_DOWN : CS_UP); + ceiling->speed = FIX2FLT(Reader_ReadInt32(svReader)); + ceiling->crush = Reader_ReadInt32(svReader); + ceiling->state = (Reader_ReadInt32(svReader) == -1? CS_DOWN : CS_UP); + ceiling->tag = Reader_ReadInt32(svReader); + ceiling->oldState = (Reader_ReadInt32(svReader) == -1? CS_DOWN : CS_UP); ceiling->thinker.function = T_MoveCeiling; if(!(temp + V19_THINKER_T_FUNC_OFFSET)) + { Thinker_SetStasis(&ceiling->thinker, true); + } P_ToXSector(ceiling->sector)->specialData = ceiling; return true; // Add this thinker. @@ -541,17 +523,17 @@ typedef struct { Reader_Read(svReader, NULL, SIZEOF_V19_THINKER_T); // Start of used data members. - door->type = Reader_ReadInt32(svReader); + door->type = doortype_e(Reader_ReadInt32(svReader)); // A 32bit pointer to sector, serialized. - door->sector = P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); + door->sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); if(!door->sector) Con_Error("tc_door: bad sector number\n"); - door->topHeight = FIX2FLT(Reader_ReadInt32(svReader)); - door->speed = FIX2FLT(Reader_ReadInt32(svReader)); - door->state = Reader_ReadInt32(svReader); - door->topWait = Reader_ReadInt32(svReader); + door->topHeight = FIX2FLT(Reader_ReadInt32(svReader)); + door->speed = FIX2FLT(Reader_ReadInt32(svReader)); + door->state = doorstate_e(Reader_ReadInt32(svReader)); + door->topWait = Reader_ReadInt32(svReader); door->topCountDown = Reader_ReadInt32(svReader); door->thinker.function = T_Door; @@ -575,29 +557,28 @@ typedef struct { fixed_t speed; } v19_floormove_t; */ - Uri *newTextureUrn; // Padding at the start (an old thinker_t struct) Reader_Read(svReader, NULL, SIZEOF_V19_THINKER_T); // Start of used data members. - floor->type = Reader_ReadInt32(svReader); - floor->crush = Reader_ReadInt32(svReader); + floor->type = floortype_e(Reader_ReadInt32(svReader)); + floor->crush = Reader_ReadInt32(svReader); // A 32bit pointer to sector, serialized. - floor->sector = P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); + floor->sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); if(!floor->sector) Con_Error("tc_floor: bad sector number\n"); - floor->state = (int) Reader_ReadInt32(svReader); - floor->newSpecial = Reader_ReadInt32(svReader); + floor->state = floorstate_e(Reader_ReadInt32(svReader)); + floor->newSpecial = Reader_ReadInt32(svReader); - newTextureUrn = readTextureUrn(svReader, "Flats"); - floor->material = DD_MaterialForTextureUri(newTextureUrn); + Uri *newTextureUrn = readTextureUrn(svReader, "Flats"); + floor->material = DD_MaterialForTextureUri(newTextureUrn); Uri_Delete(newTextureUrn); floor->floorDestHeight = FIX2FLT(Reader_ReadInt32(svReader)); - floor->speed = FIX2FLT(Reader_ReadInt32(svReader)); + floor->speed = FIX2FLT(Reader_ReadInt32(svReader)); floor->thinker.function = T_MoveFloor; @@ -623,31 +604,33 @@ typedef struct { plattype_e type; // was 32bit int } v19_plat_t; */ - byte temp[SIZEOF_V19_THINKER_T]; + byte temp[SIZEOF_V19_THINKER_T]; // Padding at the start (an old thinker_t struct) Reader_Read(svReader, temp, SIZEOF_V19_THINKER_T); // Start of used data members. // A 32bit pointer to sector, serialized. - plat->sector = P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); + plat->sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); if(!plat->sector) Con_Error("tc_plat: bad sector number\n"); - plat->speed = FIX2FLT(Reader_ReadInt32(svReader)); - plat->low = FIX2FLT(Reader_ReadInt32(svReader)); - plat->high = FIX2FLT(Reader_ReadInt32(svReader)); - plat->wait = Reader_ReadInt32(svReader); - plat->count = Reader_ReadInt32(svReader); - plat->state = Reader_ReadInt32(svReader); - plat->oldState = Reader_ReadInt32(svReader); - plat->crush = Reader_ReadInt32(svReader); - plat->tag = Reader_ReadInt32(svReader); - plat->type = Reader_ReadInt32(svReader); + plat->speed = FIX2FLT(Reader_ReadInt32(svReader)); + plat->low = FIX2FLT(Reader_ReadInt32(svReader)); + plat->high = FIX2FLT(Reader_ReadInt32(svReader)); + plat->wait = Reader_ReadInt32(svReader); + plat->count = Reader_ReadInt32(svReader); + plat->state = platstate_e(Reader_ReadInt32(svReader)); + plat->oldState = platstate_e(Reader_ReadInt32(svReader)); + plat->crush = Reader_ReadInt32(svReader); + plat->tag = Reader_ReadInt32(svReader); + plat->type = plattype_e(Reader_ReadInt32(svReader)); plat->thinker.function = T_PlatRaise; if(!(temp + V19_THINKER_T_FUNC_OFFSET)) + { Thinker_SetStasis(&plat->thinker, true); + } P_ToXSector(plat->sector)->specialData = plat; return true; // Add this thinker. @@ -671,15 +654,15 @@ typedef struct { // Start of used data members. // A 32bit pointer to sector, serialized. - flash->sector = P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); + flash->sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); if(!flash->sector) Con_Error("tc_flash: bad sector number\n"); - flash->count = Reader_ReadInt32(svReader); + flash->count = Reader_ReadInt32(svReader); flash->maxLight = (float) Reader_ReadInt32(svReader) / 255.0f; flash->minLight = (float) Reader_ReadInt32(svReader) / 255.0f; - flash->maxTime = Reader_ReadInt32(svReader); - flash->minTime = Reader_ReadInt32(svReader); + flash->maxTime = Reader_ReadInt32(svReader); + flash->minTime = Reader_ReadInt32(svReader); flash->thinker.function = (thinkfunc_t) T_LightFlash; return true; // Add this thinker. @@ -703,14 +686,14 @@ typedef struct { // Start of used data members. // A 32bit pointer to sector, serialized. - strobe->sector = P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); + strobe->sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); if(!strobe->sector) Con_Error("tc_strobe: bad sector number\n"); - strobe->count = Reader_ReadInt32(svReader); - strobe->minLight = (float) Reader_ReadInt32(svReader) / 255.0f; - strobe->maxLight = (float) Reader_ReadInt32(svReader) / 255.0f; - strobe->darkTime = Reader_ReadInt32(svReader); + strobe->count = Reader_ReadInt32(svReader); + strobe->minLight = (float) Reader_ReadInt32(svReader) / 255.0f; + strobe->maxLight = (float) Reader_ReadInt32(svReader) / 255.0f; + strobe->darkTime = Reader_ReadInt32(svReader); strobe->brightTime = Reader_ReadInt32(svReader); strobe->thinker.function = (thinkfunc_t) T_StrobeFlash; @@ -733,18 +716,29 @@ typedef struct { // Start of used data members. // A 32bit pointer to sector, serialized. - glow->sector = P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); + glow->sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); if(!glow->sector) Con_Error("tc_glow: bad sector number\n"); - glow->minLight = (float) Reader_ReadInt32(svReader) / 255.0f; - glow->maxLight = (float) Reader_ReadInt32(svReader) / 255.0f; + glow->minLight = (float) Reader_ReadInt32(svReader) / 255.0f; + glow->maxLight = (float) Reader_ReadInt32(svReader) / 255.0f; glow->direction = Reader_ReadInt32(svReader); glow->thinker.function = (thinkfunc_t) T_Glow; return true; // Add this thinker. } +enum { + tc_ceiling, + tc_door, + tc_floor, + tc_plat, + tc_flash, + tc_strobe, + tc_glow, + tc_endspecials +}; + /* * Things to handle: * @@ -756,111 +750,84 @@ typedef struct { * T_Glow, (glow_t: Sector *), * T_PlatRaise, (plat_t: Sector *), - active list */ -static void P_v19_UnArchiveSpecials(void) +static void P_v19_UnArchiveSpecials() { - enum { - tc_ceiling, - tc_door, - tc_floor, - tc_plat, - tc_flash, - tc_strobe, - tc_glow, - tc_endspecials - }; - byte tClass; - ceiling_t* ceiling; - door_t* door; - floor_t* floor; - plat_t* plat; - lightflash_t* flash; - strobe_t* strobe; - glow_t* glow; - - // Read in saved thinkers. - for(;;) + while((tClass = Reader_ReadByte(svReader)) != tc_endspecials) { - tClass = Reader_ReadByte(svReader); switch(tClass) { - case tc_endspecials: - return; // End of list. - - case tc_ceiling: + case tc_ceiling: { PADSAVEP(); - ceiling = Z_Calloc(sizeof(*ceiling), PU_MAP, NULL); + ceiling_t *ceiling = (ceiling_t *)Z_Calloc(sizeof(*ceiling), PU_MAP, NULL); SV_v19_ReadCeiling(ceiling); Thinker_Add(&ceiling->thinker); - break; + break; } - case tc_door: + case tc_door: { PADSAVEP(); - door = Z_Calloc(sizeof(*door), PU_MAP, NULL); + door_t *door = (door_t *)Z_Calloc(sizeof(*door), PU_MAP, NULL); SV_v19_ReadDoor(door); Thinker_Add(&door->thinker); - break; + break; } - case tc_floor: + case tc_floor: { PADSAVEP(); - floor = Z_Calloc(sizeof(*floor), PU_MAP, NULL); + floor_t *floor = (floor_t *)Z_Calloc(sizeof(*floor), PU_MAP, NULL); SV_v19_ReadFloor(floor); Thinker_Add(&floor->thinker); - break; + break; } - case tc_plat: + case tc_plat: { PADSAVEP(); - plat = Z_Calloc(sizeof(*plat), PU_MAP, NULL); + plat_t *plat = (plat_t *)Z_Calloc(sizeof(*plat), PU_MAP, NULL); SV_v19_ReadPlat(plat); Thinker_Add(&plat->thinker); - break; + break; } - case tc_flash: + case tc_flash: { PADSAVEP(); - flash = Z_Calloc(sizeof(*flash), PU_MAP, NULL); + lightflash_t *flash = (lightflash_t *)Z_Calloc(sizeof(*flash), PU_MAP, NULL); SV_v19_ReadFlash(flash); Thinker_Add(&flash->thinker); - break; + break; } - case tc_strobe: + case tc_strobe: { PADSAVEP(); - strobe = Z_Calloc(sizeof(*strobe), PU_MAP, NULL); + strobe_t *strobe = (strobe_t *)Z_Calloc(sizeof(*strobe), PU_MAP, NULL); SV_v19_ReadStrobe(strobe); Thinker_Add(&strobe->thinker); - break; + break; } - case tc_glow: + case tc_glow: { PADSAVEP(); - glow = Z_Calloc(sizeof(*glow), PU_MAP, NULL); + glow_t *glow = (glow_t *)Z_Calloc(sizeof(*glow), PU_MAP, NULL); SV_v19_ReadGlow(glow); Thinker_Add(&glow->thinker); - break; + break; } default: - Con_Error("P_UnarchiveSpecials:Unknown tclass %i in savegame", - tClass); + Con_Error("P_UnarchiveSpecials: Unknown tclass %i in savegame", tClass); } } } int SV_LoadState_Dm_v19(Str const *path, SaveInfo *info) { - saveheader_t const *hdr; - DENG_ASSERT(path != 0 && info != 0); if(!SV_OpenFile_Dm_v19(Str_Text(path))) return 1; @@ -870,19 +837,20 @@ int SV_LoadState_Dm_v19(Str const *path, SaveInfo *info) // Read the header again. /// @todo Seek past the header straight to the game state. { - SaveInfo* tmp = SaveInfo_New(); - SaveInfo_Read_Dm_v19(tmp, svReader); - SaveInfo_Delete(tmp); + SaveInfo *tmp = SaveInfo_New(); + SaveInfo_Read_Dm_v19(tmp, svReader); + SaveInfo_Delete(tmp); } - hdr = SaveInfo_Header(info); - gameSkill = hdr->skill; - gameEpisode = hdr->episode; - gameMap = hdr->map; + saveheader_t const *hdr = SaveInfo_Header(info); + + gameSkill = hdr->skill; + gameEpisode = hdr->episode; + gameMap = hdr->map; gameMapEntryPoint = 0; // We don't want to see a briefing if we're loading a save game. - briefDisabled = true; + briefDisabled = true; // Load a base map. G_NewGame(gameSkill, gameEpisode, gameMap, gameMapEntryPoint); @@ -898,92 +866,92 @@ int SV_LoadState_Dm_v19(Str const *path, SaveInfo *info) if(Reader_ReadByte(svReader) != 0x1d) { - Reader_Delete(svReader); - svReader = NULL; + Reader_Delete(svReader); svReader = 0; SV_CloseFile_Dm_v19(); Con_Error("SV_LoadState_Dm_v19: Bad savegame (consistency test failed!)"); exit(1); // Unreachable. } - Reader_Delete(svReader); - svReader = NULL; + Reader_Delete(svReader); svReader = 0; SV_CloseFile_Dm_v19(); return 0; // Success! } -static void SaveInfo_Read_Dm_v19(SaveInfo* info, Reader* reader) +static void SaveInfo_Read_Dm_v19(SaveInfo *info, Reader *reader) { - saveheader_t* hdr = &info->header; - char nameBuffer[V19_SAVESTRINGSIZE]; - char vcheck[VERSIONSIZE]; - int i; - assert(info); + DENG_ASSERT(info != 0); + + saveheader_t *hdr = &info->header; + char nameBuffer[V19_SAVESTRINGSIZE]; Reader_Read(reader, nameBuffer, V19_SAVESTRINGSIZE); nameBuffer[V19_SAVESTRINGSIZE - 1] = 0; Str_Set(&info->name, nameBuffer); + char vcheck[VERSIONSIZE]; Reader_Read(reader, vcheck, VERSIONSIZE); - //assert(!strncmp(vcheck, "version ", 8)); // Ensure save state format has been recognised by now. - hdr->version = atoi(&vcheck[8]); + //DENG_ASSERT(!strncmp(vcheck, "version ", 8)); // Ensure save state format has been recognised by now. + + hdr->version = atoi(&vcheck[8]); - hdr->skill = (skillmode_t) Reader_ReadByte(reader); + hdr->skill = (skillmode_t) Reader_ReadByte(reader); // Interpret skill levels outside the normal range as "spawn no things". if(hdr->skill < SM_BABY || hdr->skill >= NUM_SKILL_MODES) hdr->skill = SM_NOTHINGS; - hdr->episode = Reader_ReadByte(reader)-1; - hdr->map = Reader_ReadByte(reader)-1; - for(i = 0; i < 4; ++i) + hdr->episode = Reader_ReadByte(reader)-1; + hdr->map = Reader_ReadByte(reader)-1; + + for(int i = 0; i < 4; ++i) { hdr->players[i] = Reader_ReadByte(reader); } + memset(&hdr->players[4], 0, sizeof(*hdr->players) * (MAXPLAYERS-4)); // Get the map time. - { int a = Reader_ReadByte(reader); + int a = Reader_ReadByte(reader); int b = Reader_ReadByte(reader); int c = Reader_ReadByte(reader); - hdr->mapTime = (a << 16) + (b << 8) + c; - } + hdr->mapTime = (a << 16) + (b << 8) + c; - hdr->magic = 0; // Initialize with *something*. + hdr->magic = 0; // Initialize with *something*. /// @note Older formats do not contain all needed values: - hdr->gameMode = gameMode; // Assume the current mode. - hdr->deathmatch = 0; - hdr->noMonsters = 0; + hdr->gameMode = gameMode; // Assume the current mode. + hdr->deathmatch = 0; + hdr->noMonsters = 0; hdr->respawnMonsters = 0; info->gameId = 0; // None. } -static dd_bool SV_OpenFile_Dm_v19(const char* filePath) +static dd_bool SV_OpenFile_Dm_v19(char const *filePath) { dd_bool fileOpened; #if _DEBUG if(saveBuffer) Con_Error("SV_OpenFile_Dm_v19: A save state file has already been opened!"); #endif - fileOpened = 0 != M_ReadFile(filePath, (char**)&saveBuffer); + fileOpened = 0 != M_ReadFile(filePath, (char **)&saveBuffer); if(!fileOpened) return false; savePtr = saveBuffer; return true; } -static void SV_CloseFile_Dm_v19(void) +static void SV_CloseFile_Dm_v19() { if(!saveBuffer) return; Z_Free(saveBuffer); - saveBuffer = savePtr = NULL; + saveBuffer = savePtr = 0; } -static Reader *SV_NewReader_Dm_v19(void) +static Reader *SV_NewReader_Dm_v19() { - if(!saveBuffer) return NULL; + if(!saveBuffer) return 0; return Reader_NewWithCallbacks(sri8, sri16, sri32, NULL, srd); } @@ -1009,11 +977,11 @@ dd_bool SV_RecogniseState_Dm_v19(Str const *path, SaveInfo *info) result = (SaveInfo_Header(info)->version <= V19_SAVE_VERSION); } - Reader_Delete(svReader); - svReader = NULL; + Reader_Delete(svReader); svReader = 0; SV_CloseFile_Dm_v19(); return result; } + return false; } From 7296820955a0210d41069a2e56ad37fa688fd80d Mon Sep 17 00:00:00 2001 From: danij Date: Mon, 3 Feb 2014 20:28:38 +0000 Subject: [PATCH 067/106] Refactor|libheretic: Switched Heretic v1.3 save state interpreter/reader to C++ --- doomsday/plugins/heretic/heretic.pro | 2 +- doomsday/plugins/heretic/include/p_oldsvg.h | 2 +- .../heretic/src/{p_oldsvg.c => p_oldsvg.cpp} | 507 ++++++++---------- 3 files changed, 236 insertions(+), 275 deletions(-) rename doomsday/plugins/heretic/src/{p_oldsvg.c => p_oldsvg.cpp} (68%) diff --git a/doomsday/plugins/heretic/heretic.pro b/doomsday/plugins/heretic/heretic.pro index b2266bb9ce..56c6f0265e 100644 --- a/doomsday/plugins/heretic/heretic.pro +++ b/doomsday/plugins/heretic/heretic.pro @@ -84,7 +84,7 @@ SOURCES += \ src/p_lights.cpp \ src/p_maputl.c \ src/p_mobj.c \ - src/p_oldsvg.c \ + src/p_oldsvg.cpp \ src/p_pspr.c \ src/p_setup.c \ src/p_spec.c \ diff --git a/doomsday/plugins/heretic/include/p_oldsvg.h b/doomsday/plugins/heretic/include/p_oldsvg.h index 54155048cb..5d38e49fb4 100644 --- a/doomsday/plugins/heretic/include/p_oldsvg.h +++ b/doomsday/plugins/heretic/include/p_oldsvg.h @@ -1,4 +1,4 @@ -/** @file heretic/p_oldsvg.h Heretic ver 1.3 saved game state reader. +/** @file p_oldsvg.h Heretic ver 1.3 save game reader. * * @authors Copyright © 2003-2013 Jaakko Keränen * @authors Copyright © 2006-2013 Daniel Swanson diff --git a/doomsday/plugins/heretic/src/p_oldsvg.c b/doomsday/plugins/heretic/src/p_oldsvg.cpp similarity index 68% rename from doomsday/plugins/heretic/src/p_oldsvg.c rename to doomsday/plugins/heretic/src/p_oldsvg.cpp index 05199c3ad9..2206e94b60 100644 --- a/doomsday/plugins/heretic/src/p_oldsvg.c +++ b/doomsday/plugins/heretic/src/p_oldsvg.cpp @@ -1,10 +1,8 @@ -/** - * @file p_oldsvg.c - * Heretic ver 1.3 save game reader. +/** @file p_oldsvg.cpp Heretic ver 1.3 save game reader. * - * @authors Copyright © 2003-2013 Jaakko Keränen - * @authors Copyright © 2006-2013 Daniel Swanson - * @authors Copyright © 1999 Activision + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2006-2013 Daniel Swanson + * @authors Copyright © 1999 Activision * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -21,10 +19,8 @@ * 02110-1301 USA */ -#include -#include - #include "jheretic.h" +#include "p_oldsvg.h" #include "dmu_lib.h" #include "p_saveg.h" @@ -38,6 +34,8 @@ #include "am_map.h" #include "p_inventory.h" #include "hu_inventory.h" +#include +#include // Do NOT change this: #define V13_SAVE_VERSION 130 ///< Version number associated with a recognised heretic.exe game save state. @@ -50,56 +48,59 @@ #define SIZEOF_V13_THINKER_T 12 #define V13_THINKER_T_FUNC_OFFSET 8 -static byte* savePtr; -static byte* saveBuffer; -static Reader* svReader; +static byte *savePtr; +static byte *saveBuffer; +static Reader *svReader; -static dd_bool SV_OpenFile_Hr_v13(const char* filePath); -static void SV_CloseFile_Hr_v13(void); -static Reader* SV_NewReader_Hr_v13(void); +static dd_bool SV_OpenFile_Hr_v13(char const *filePath); +static void SV_CloseFile_Hr_v13(); +static Reader *SV_NewReader_Hr_v13(); -static void SaveInfo_Read_Hr_v13(SaveInfo* info, Reader* reader); +static void SaveInfo_Read_Hr_v13(SaveInfo *info, Reader *reader); -static char sri8(Reader* r) +static char sri8(Reader *r) { if(!r) return 0; savePtr++; - return *(char*) (savePtr - 1); + return *(char *) (savePtr - 1); } -static short sri16(Reader* r) +static short sri16(Reader *r) { if(!r) return 0; savePtr += 2; - return *(int16_t*) (savePtr - 2); + return *(int16_t *) (savePtr - 2); } -static int sri32(Reader* r) +static int sri32(Reader *r) { if(!r) return 0; savePtr += 4; - return *(int32_t*) (savePtr - 4); + return *(int32_t *) (savePtr - 4); } -static void srd(Reader* r, char* data, int len) +static void srd(Reader *r, char *data, int len) { if(!r) return; if(data) { - memcpy(data, savePtr, len); + std::memcpy(data, savePtr, len); } savePtr += len; } -static void SV_v13_ReadPlayer(player_t* pl) +static void SV_v13_ReadPlayer(player_t *pl) { - int i, plrnum = pl - players; - ddplayer_t* ddpl = pl->plr; - byte temp[12]; + int plrnum = pl - players; + ddplayer_t *ddpl = pl->plr; Reader_ReadInt32(svReader); // mo - pl->playerState = Reader_ReadInt32(svReader); - Reader_Read(svReader, temp, 10); // ticcmd_t + + pl->playerState = playerstate_t(Reader_ReadInt32(svReader)); + + byte junk[12]; + Reader_Read(svReader, junk, 10); // ticcmd_t + pl->viewZ = FIX2FLT(Reader_ReadInt32(svReader)); pl->viewHeight = FIX2FLT(Reader_ReadInt32(svReader)); pl->viewHeightDelta = FIX2FLT(Reader_ReadInt32(svReader)); @@ -112,16 +113,18 @@ static void SV_v13_ReadPlayer(player_t* pl) pl->armorType = Reader_ReadInt32(svReader); P_InventoryEmpty(plrnum); - for(i = 0; i < 14; ++i) + for(int i = 0; i < 14; ++i) { - inventoryitemtype_t type = Reader_ReadInt32(svReader); - int j, count = Reader_ReadInt32(svReader); + inventoryitemtype_t type = inventoryitemtype_t(Reader_ReadInt32(svReader)); + int count = Reader_ReadInt32(svReader); - for(j = 0; j < count; ++j) + for(int k = 0; k < count; ++k) + { P_InventoryGive(plrnum, type, true); + } } - P_InventorySetReadyItem(plrnum, (inventoryitemtype_t) Reader_ReadInt32(svReader)); + P_InventorySetReadyItem(plrnum, inventoryitemtype_t(Reader_ReadInt32(svReader))); Hu_InventorySelect(plrnum, P_InventoryReadyItem(plrnum)); Reader_ReadInt32(svReader); // current inventory item count? /*pl->inventorySlotNum =*/ Reader_ReadInt32(svReader); @@ -153,8 +156,8 @@ static void SV_v13_ReadPlayer(player_t* pl) pl->frags[2] = Reader_ReadInt32(svReader); pl->frags[3] = Reader_ReadInt32(svReader); - pl->readyWeapon = Reader_ReadInt32(svReader); - pl->pendingWeapon = Reader_ReadInt32(svReader); + pl->readyWeapon = weapontype_t(Reader_ReadInt32(svReader)); + pl->pendingWeapon = weapontype_t(Reader_ReadInt32(svReader)); // Owned weapons. memset(pl->weapons, 0, sizeof(pl->weapons)); @@ -181,52 +184,48 @@ static void SV_v13_ReadPlayer(player_t* pl) pl->ammo[AT_FIREORB].max = Reader_ReadInt32(svReader); pl->ammo[AT_MSPHERE].max = Reader_ReadInt32(svReader); - pl->attackDown = Reader_ReadInt32(svReader); - pl->useDown = Reader_ReadInt32(svReader); - pl->cheats = Reader_ReadInt32(svReader); - pl->refire = Reader_ReadInt32(svReader); - pl->killCount = Reader_ReadInt32(svReader); - pl->itemCount = Reader_ReadInt32(svReader); + pl->attackDown = Reader_ReadInt32(svReader); + pl->useDown = Reader_ReadInt32(svReader); + pl->cheats = Reader_ReadInt32(svReader); + pl->refire = Reader_ReadInt32(svReader); + pl->killCount = Reader_ReadInt32(svReader); + pl->itemCount = Reader_ReadInt32(svReader); pl->secretCount = Reader_ReadInt32(svReader); Reader_ReadInt32(svReader); // message, char* pl->damageCount = Reader_ReadInt32(svReader); - pl->bonusCount = Reader_ReadInt32(svReader); - pl->flameCount = Reader_ReadInt32(svReader); + pl->bonusCount = Reader_ReadInt32(svReader); + pl->flameCount = Reader_ReadInt32(svReader); Reader_ReadInt32(svReader); // attacker - ddpl->extraLight = Reader_ReadInt32(svReader); + ddpl->extraLight = Reader_ReadInt32(svReader); ddpl->fixedColorMap = Reader_ReadInt32(svReader); - pl->colorMap = Reader_ReadInt32(svReader); - for(i = 0; i < 2; ++i) + pl->colorMap = Reader_ReadInt32(svReader); + + for(int i = 0; i < 2; ++i) { - pspdef_t* psp = &pl->pSprites[i]; + pspdef_t *psp = &pl->pSprites[i]; - psp->state = INT2PTR(state_t, Reader_ReadInt32(svReader)); + psp->state = INT2PTR(state_t, Reader_ReadInt32(svReader)); psp->pos[VX] = Reader_ReadInt32(svReader); psp->pos[VY] = Reader_ReadInt32(svReader); - psp->tics = Reader_ReadInt32(svReader); + psp->tics = Reader_ReadInt32(svReader); } - pl->didSecret = Reader_ReadInt32(svReader); - pl->morphTics = Reader_ReadInt32(svReader); + pl->didSecret = Reader_ReadInt32(svReader); + pl->morphTics = Reader_ReadInt32(svReader); pl->chickenPeck = Reader_ReadInt32(svReader); + Reader_ReadInt32(svReader); // rain1 Reader_ReadInt32(svReader); // rain2 } -static void SV_v13_ReadMobj(void) +static void SV_v13_ReadMobj() { - coord_t pos[3], mom[3], floorz, ceilingz, radius, height; - int frame, valid, type, ddflags = 0; - spritenum_t sprite; - mobjinfo_t* info; - angle_t angle; - mobj_t* mo; - // The thinker was 3 ints long. Reader_ReadInt32(svReader); Reader_ReadInt32(svReader); Reader_ReadInt32(svReader); + coord_t pos[3]; pos[VX] = FIX2FLT(Reader_ReadInt32(svReader)); pos[VY] = FIX2FLT(Reader_ReadInt32(svReader)); pos[VZ] = FIX2FLT(Reader_ReadInt32(svReader)); @@ -235,9 +234,9 @@ static void SV_v13_ReadMobj(void) Reader_ReadInt32(svReader); Reader_ReadInt32(svReader); - angle = (angle_t) (ANG45 * (Reader_ReadInt32(svReader) / 45)); - sprite = Reader_ReadInt32(svReader); - frame = Reader_ReadInt32(svReader); + angle_t angle = (angle_t) (ANG45 * (Reader_ReadInt32(svReader) / 45)); + spritenum_t sprite = Reader_ReadInt32(svReader); + int frame = Reader_ReadInt32(svReader); frame &= ~FF_FRAMEMASK; // not used anymore. // Block links. @@ -247,28 +246,30 @@ static void SV_v13_ReadMobj(void) // Subsector. Reader_ReadInt32(svReader); - floorz = FIX2FLT(Reader_ReadInt32(svReader)); - ceilingz = FIX2FLT(Reader_ReadInt32(svReader)); - radius = FIX2FLT(Reader_ReadInt32(svReader)); - height = FIX2FLT(Reader_ReadInt32(svReader)); + coord_t floorz = FIX2FLT(Reader_ReadInt32(svReader)); + coord_t ceilingz = FIX2FLT(Reader_ReadInt32(svReader)); + coord_t radius = FIX2FLT(Reader_ReadInt32(svReader)); + coord_t height = FIX2FLT(Reader_ReadInt32(svReader)); + + coord_t mom[3]; mom[MX] = FIX2FLT(Reader_ReadInt32(svReader)); mom[MY] = FIX2FLT(Reader_ReadInt32(svReader)); mom[MZ] = FIX2FLT(Reader_ReadInt32(svReader)); - valid = Reader_ReadInt32(svReader); - type = Reader_ReadInt32(svReader); - info = &MOBJINFO[type]; + int valid = Reader_ReadInt32(svReader); + int type = Reader_ReadInt32(svReader); - if(info->flags & MF_SOLID) - ddflags |= DDMF_SOLID; - if(info->flags2 & MF2_DONTDRAW) - ddflags |= DDMF_DONTDRAW; + mobjinfo_t *info = &MOBJINFO[type]; - /** + int ddflags = 0; + if(info->flags & MF_SOLID) ddflags |= DDMF_SOLID; + if(info->flags2 & MF2_DONTDRAW) ddflags |= DDMF_DONTDRAW; + + /* * We now have all the information we need to create the mobj. */ - mo = Mobj_CreateXYZ(P_MobjThinker, pos[VX], pos[VY], pos[VZ], angle, - radius, height, ddflags); + mobj_t *mo = Mobj_CreateXYZ(P_MobjThinker, pos[VX], pos[VY], pos[VZ], angle, + radius, height, ddflags); mo->sprite = sprite; mo->frame = frame; @@ -281,10 +282,9 @@ static void SV_v13_ReadMobj(void) mo->type = type; mo->moveDir = DI_NODIR; - /** + /* * Continue reading the mobj data. */ - Reader_ReadInt32(svReader); // info mo->tics = Reader_ReadInt32(svReader); @@ -328,12 +328,10 @@ static void SV_v13_ReadMobj(void) mo->spawnSpot.angle = (angle_t) (ANG45 * (Reader_ReadInt32(svReader) / 45)); /*mo->spawnSpot.type = (int)*/ Reader_ReadInt32(svReader); - { int spawnFlags = ((int) Reader_ReadInt32(svReader)) & ~MASK_UNKNOWN_MSF_FLAGS; // Spawn on the floor by default unless the mobjtype flags override. spawnFlags |= MSF_Z_FLOOR; mo->spawnSpot.flags = spawnFlags; - } mo->info = info; SV_TranslateLegacyMobjFlags(mo, 0); @@ -351,24 +349,22 @@ static void SV_v13_ReadMobj(void) mo->ceilingZ = P_GetDoublep(Mobj_Sector(mo), DMU_CEILING_HEIGHT); } -static void P_v13_UnArchivePlayers(void) +static void P_v13_UnArchivePlayers() { - int i, j; - - for(i = 0; i < 4; ++i) + for(int i = 0; i < 4; ++i) { if(!players[i].plr->inGame) continue; SV_v13_ReadPlayer(players + i); players[i].plr->mo = NULL; // Will be set when unarc thinker. players[i].attacker = NULL; - for(j = 0; j < NUMPSPRITES; ++j) + for(int k = 0; k < NUMPSPRITES; ++k) { player_t *plr = &players[i]; - if(plr->pSprites[j].state) + if(plr->pSprites[k].state) { - plr->pSprites[j].state = &STATES[PTR2INT(plr->pSprites[j].state)]; + plr->pSprites[k].state = &STATES[PTR2INT(plr->pSprites[k].state)]; } } } @@ -380,31 +376,22 @@ static Uri *readTextureUrn(Reader *reader, char const *schemeName) return Uri_NewWithPath2(Str_Text(Str_Appendf(AutoStr_NewStd(), "urn:%s:%i", schemeName, Reader_ReadInt16(svReader))), RC_NULL); } -static void P_v13_UnArchiveWorld(void) +static void P_v13_UnArchiveWorld() { - int i, j; - fixed_t offx, offy; - Sector* sec; - xsector_t* xsec; - Line* line; - xline_t* xline; - // Do sectors. - for(i = 0; i < numsectors; ++i) + for(int i = 0; i < numsectors; ++i) { - Uri *floorTextureUrn, *ceilingTextureUrn; - - sec = P_ToPtr(DMU_SECTOR, i); - xsec = P_ToXSector(sec); + Sector *sec = (Sector *)P_ToPtr(DMU_SECTOR, i); + xsector_t *xsec = P_ToXSector(sec); P_SetDoublep(sec, DMU_FLOOR_HEIGHT, (coord_t)Reader_ReadInt16(svReader)); P_SetDoublep(sec, DMU_CEILING_HEIGHT, (coord_t)Reader_ReadInt16(svReader)); - floorTextureUrn = readTextureUrn(svReader, "Flats"); + Uri *floorTextureUrn = readTextureUrn(svReader, "Flats"); P_SetPtrp(sec, DMU_FLOOR_MATERIAL, DD_MaterialForTextureUri(floorTextureUrn)); Uri_Delete(floorTextureUrn); - ceilingTextureUrn = readTextureUrn(svReader, "Flats"); + Uri *ceilingTextureUrn = readTextureUrn(svReader, "Flats"); P_SetPtrp(sec, DMU_CEILING_MATERIAL, DD_MaterialForTextureUri(ceilingTextureUrn)); Uri_Delete(ceilingTextureUrn); @@ -417,24 +404,22 @@ static void P_v13_UnArchiveWorld(void) } // Do lines. - for(i = 0; i < numlines; ++i) + for(int i = 0; i < numlines; ++i) { - line = P_ToPtr(DMU_LINE, i); - xline = P_ToXLine(line); + Line *line = (Line *)P_ToPtr(DMU_LINE, i); + xline_t *xline = P_ToXLine(line); xline->flags = Reader_ReadInt16(svReader); xline->special = Reader_ReadInt16(svReader); /*xline->tag =*/Reader_ReadInt16(svReader); - for(j = 0; j < 2; ++j) + for(int k = 0; k < 2; ++k) { - Uri *topTextureUrn, *bottomTextureUrn, *middleTextureUrn; - - Side* sdef = P_GetPtrp(line, j == 0? DMU_FRONT : DMU_BACK); + Side *sdef = (Side *)P_GetPtrp(line, k == 0? DMU_FRONT : DMU_BACK); if(!sdef) continue; - offx = Reader_ReadInt16(svReader) << FRACBITS; - offy = Reader_ReadInt16(svReader) << FRACBITS; + fixed_t offx = Reader_ReadInt16(svReader) << FRACBITS; + fixed_t offy = Reader_ReadInt16(svReader) << FRACBITS; P_SetFixedp(sdef, DMU_TOP_MATERIAL_OFFSET_X, offx); P_SetFixedp(sdef, DMU_TOP_MATERIAL_OFFSET_Y, offy); P_SetFixedp(sdef, DMU_MIDDLE_MATERIAL_OFFSET_X, offx); @@ -442,54 +427,48 @@ static void P_v13_UnArchiveWorld(void) P_SetFixedp(sdef, DMU_BOTTOM_MATERIAL_OFFSET_X, offx); P_SetFixedp(sdef, DMU_BOTTOM_MATERIAL_OFFSET_Y, offy); - topTextureUrn = readTextureUrn(svReader, "Textures"); + Uri *topTextureUrn = readTextureUrn(svReader, "Textures"); P_SetPtrp(sdef, DMU_TOP_MATERIAL, DD_MaterialForTextureUri(topTextureUrn)); Uri_Delete(topTextureUrn); - bottomTextureUrn = readTextureUrn(svReader, "Textures"); + Uri *bottomTextureUrn = readTextureUrn(svReader, "Textures"); P_SetPtrp(sdef, DMU_BOTTOM_MATERIAL, DD_MaterialForTextureUri(bottomTextureUrn)); Uri_Delete(bottomTextureUrn); - middleTextureUrn = readTextureUrn(svReader, "Textures"); + Uri *middleTextureUrn = readTextureUrn(svReader, "Textures"); P_SetPtrp(sdef, DMU_MIDDLE_MATERIAL, DD_MaterialForTextureUri(middleTextureUrn)); Uri_Delete(middleTextureUrn); } } } -static int removeThinker(thinker_t* th, void* context) +static int removeThinker(thinker_t *th, void *context) { if(th->function == (thinkfunc_t) P_MobjThinker) + { P_MobjRemove((mobj_t *) th, true); + } else + { Z_Free(th); + } return false; // Continue iteration. } -static void P_v13_UnArchiveThinkers(void) -{ -typedef enum +static void P_v13_UnArchiveThinkers() { - TC_END, - TC_MOBJ -} thinkerclass_t; - - byte tclass; - // Remove all the current thinkers. Thinker_Iterate(NULL, removeThinker, NULL); Thinker_Init(); // read in saved thinkers - for(;;) + byte tclass; + while((tclass = Reader_ReadByte(svReader)) != 0/*TC_END*/) { - tclass = Reader_ReadByte(svReader); switch(tclass) { - case TC_END: return; // End of list. - - case TC_MOBJ: + case 1: // TC_MOBJ SV_v13_ReadMobj(); break; @@ -520,10 +499,10 @@ typedef struct { Reader_Read(svReader, &temp, SIZEOF_V13_THINKER_T); // Start of used data members. - ceiling->type = Reader_ReadInt32(svReader); + ceiling->type = ceilingtype_e(Reader_ReadInt32(svReader)); // A 32bit pointer to sector, serialized. - ceiling->sector = P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); + ceiling->sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); if(!ceiling->sector) Con_Error("tc_ceiling: bad sector number\n"); @@ -562,17 +541,17 @@ typedef struct { Reader_Read(svReader, NULL, SIZEOF_V13_THINKER_T); // Start of used data members. - door->type = Reader_ReadInt32(svReader); + door->type = doortype_e(Reader_ReadInt32(svReader)); // A 32bit pointer to sector, serialized. - door->sector = P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); + door->sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); if(!door->sector) Con_Error("tc_door: bad sector number\n"); - door->topHeight = FIX2FLT(Reader_ReadInt32(svReader)); - door->speed = FIX2FLT(Reader_ReadInt32(svReader)); - door->state = Reader_ReadInt32(svReader); - door->topWait = Reader_ReadInt32(svReader); + door->topHeight = FIX2FLT(Reader_ReadInt32(svReader)); + door->speed = FIX2FLT(Reader_ReadInt32(svReader)); + door->state = doorstate_e(Reader_ReadInt32(svReader)); + door->topWait = Reader_ReadInt32(svReader); door->topCountDown = Reader_ReadInt32(svReader); door->thinker.function = T_Door; @@ -596,29 +575,28 @@ typedef struct { fixed_t speed; } v13_floormove_t; */ - Uri *newTextureUrn; // Padding at the start (an old thinker_t struct) Reader_Read(svReader, NULL, SIZEOF_V13_THINKER_T); // Start of used data members. - floor->type = Reader_ReadInt32(svReader); - floor->crush = Reader_ReadInt32(svReader); + floor->type = floortype_e(Reader_ReadInt32(svReader)); + floor->crush = Reader_ReadInt32(svReader); // A 32bit pointer to sector, serialized. - floor->sector = P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); + floor->sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); if(!floor->sector) - Con_Error("tc_floor: bad sector number\n"); + Con_Error("tc_floor: bad sector number"); - floor->state = (int) Reader_ReadInt32(svReader); - floor->newSpecial = Reader_ReadInt32(svReader); + floor->state = floorstate_e(Reader_ReadInt32(svReader)); + floor->newSpecial = Reader_ReadInt32(svReader); - newTextureUrn = readTextureUrn(svReader, "Flats"); - floor->material = DD_MaterialForTextureUri(newTextureUrn); + Uri *newTextureUrn = readTextureUrn(svReader, "Flats"); + floor->material = DD_MaterialForTextureUri(newTextureUrn); Uri_Delete(newTextureUrn); floor->floorDestHeight = FIX2FLT(Reader_ReadInt32(svReader)); - floor->speed = FIX2FLT(Reader_ReadInt32(svReader)); + floor->speed = FIX2FLT(Reader_ReadInt32(svReader)); floor->thinker.function = T_MoveFloor; @@ -630,18 +608,18 @@ static int SV_ReadPlat(plat_t *plat) { /* Original Heretic format: typedef struct { - thinker_t thinker; // was 12 bytes + thinker_t thinker; // was 12 bytes Sector *sector; fixed_t speed; fixed_t low; fixed_t high; int wait; int count; - platstate_e status; // was 32bit int - platstate_e oldStatus; // was 32bit int + platstate_e status; // was 32bit int + platstate_e oldStatus; // was 32bit int dd_bool crush; int tag; - plattype_e type; // was 32bit int + plattype_e type; // was 32bit int } v13_plat_t; */ byte temp[SIZEOF_V13_THINKER_T]; @@ -650,20 +628,20 @@ typedef struct { // Start of used data members. // A 32bit pointer to sector, serialized. - plat->sector = P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); + plat->sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); if(!plat->sector) - Con_Error("tc_plat: bad sector number\n"); - - plat->speed = FIX2FLT(Reader_ReadInt32(svReader)); - plat->low = FIX2FLT(Reader_ReadInt32(svReader)); - plat->high = FIX2FLT(Reader_ReadInt32(svReader)); - plat->wait = Reader_ReadInt32(svReader); - plat->count = Reader_ReadInt32(svReader); - plat->state = Reader_ReadInt32(svReader); - plat->oldState = Reader_ReadInt32(svReader); - plat->crush = Reader_ReadInt32(svReader); - plat->tag = Reader_ReadInt32(svReader); - plat->type = Reader_ReadInt32(svReader); + Con_Error("tc_plat: bad sector number"); + + plat->speed = FIX2FLT(Reader_ReadInt32(svReader)); + plat->low = FIX2FLT(Reader_ReadInt32(svReader)); + plat->high = FIX2FLT(Reader_ReadInt32(svReader)); + plat->wait = Reader_ReadInt32(svReader); + plat->count = Reader_ReadInt32(svReader); + plat->state = platstate_e(Reader_ReadInt32(svReader)); + plat->oldState = platstate_e(Reader_ReadInt32(svReader)); + plat->crush = Reader_ReadInt32(svReader); + plat->tag = Reader_ReadInt32(svReader); + plat->type = plattype_e(Reader_ReadInt32(svReader)); plat->thinker.function = T_PlatRaise; if(!(temp + V13_THINKER_T_FUNC_OFFSET)) @@ -677,7 +655,7 @@ static int SV_ReadFlash(lightflash_t *flash) { /* Original Heretic format: typedef struct { - thinker_t thinker; // was 12 bytes + thinker_t thinker; // was 12 bytes Sector *sector; int count; int maxLight; @@ -691,15 +669,15 @@ typedef struct { // Start of used data members. // A 32bit pointer to sector, serialized. - flash->sector = P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); + flash->sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); if(!flash->sector) - Con_Error("tc_flash: bad sector number\n"); + Con_Error("tc_flash: bad sector number"); - flash->count = Reader_ReadInt32(svReader); + flash->count = Reader_ReadInt32(svReader); flash->maxLight = (float) Reader_ReadInt32(svReader) / 255.0f; flash->minLight = (float) Reader_ReadInt32(svReader) / 255.0f; - flash->maxTime = Reader_ReadInt32(svReader); - flash->minTime = Reader_ReadInt32(svReader); + flash->maxTime = Reader_ReadInt32(svReader); + flash->minTime = Reader_ReadInt32(svReader); flash->thinker.function = (thinkfunc_t) T_LightFlash; return true; // Add this thinker. @@ -709,7 +687,7 @@ static int SV_ReadStrobe(strobe_t *strobe) { /* Original Heretic format: typedef struct { - thinker_t thinker; // was 12 bytes + thinker_t thinker; // was 12 bytes Sector *sector; int count; int minLight; @@ -723,14 +701,14 @@ typedef struct { // Start of used data members. // A 32bit pointer to sector, serialized. - strobe->sector = P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); + strobe->sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); if(!strobe->sector) - Con_Error("tc_strobe: bad sector number\n"); + Con_Error("tc_strobe: bad sector number"); - strobe->count = Reader_ReadInt32(svReader); - strobe->minLight = (float) Reader_ReadInt32(svReader) / 255.0f; - strobe->maxLight = (float) Reader_ReadInt32(svReader) / 255.0f; - strobe->darkTime = Reader_ReadInt32(svReader); + strobe->count = Reader_ReadInt32(svReader); + strobe->minLight = (float) Reader_ReadInt32(svReader) / 255.0f; + strobe->maxLight = (float) Reader_ReadInt32(svReader) / 255.0f; + strobe->darkTime = Reader_ReadInt32(svReader); strobe->brightTime = Reader_ReadInt32(svReader); strobe->thinker.function = (thinkfunc_t) T_StrobeFlash; @@ -741,7 +719,7 @@ static int SV_ReadGlow(glow_t *glow) { /* Original Heretic format: typedef struct { - thinker_t thinker; // was 12 bytes + thinker_t thinker; // was 12 bytes Sector *sector; int minLight; int maxLight; @@ -753,18 +731,29 @@ typedef struct { // Start of used data members. // A 32bit pointer to sector, serialized. - glow->sector = P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); + glow->sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); if(!glow->sector) - Con_Error("tc_glow: bad sector number\n"); + Con_Error("tc_glow: bad sector number"); - glow->minLight = (float) Reader_ReadInt32(svReader) / 255.0f; - glow->maxLight = (float) Reader_ReadInt32(svReader) / 255.0f; + glow->minLight = (float) Reader_ReadInt32(svReader) / 255.0f; + glow->maxLight = (float) Reader_ReadInt32(svReader) / 255.0f; glow->direction = Reader_ReadInt32(svReader); glow->thinker.function = (thinkfunc_t) T_Glow; return true; // Add this thinker. } +enum { + tc_ceiling, + tc_door, + tc_floor, + tc_plat, + tc_flash, + tc_strobe, + tc_glow, + tc_endspecials +}; + /** * Things to handle: * @@ -776,103 +765,78 @@ typedef struct { * T_Glow, (glow_t: Sector *), * T_PlatRaise, (plat_t: Sector *), - active list */ -static void P_v13_UnArchiveSpecials(void) +static void P_v13_UnArchiveSpecials() { - enum { - tc_ceiling, - tc_door, - tc_floor, - tc_plat, - tc_flash, - tc_strobe, - tc_glow, - tc_endspecials - }; - - byte tclass; - ceiling_t* ceiling; - door_t* door; - floor_t* floor; - plat_t* plat; - lightflash_t* flash; - strobe_t* strobe; - glow_t* glow; - // Read in saved thinkers. - for(;;) + byte tclass; + while((tclass = Reader_ReadByte(svReader)) != tc_endspecials) { - tclass = Reader_ReadByte(svReader); switch(tclass) { - case tc_endspecials: return; // End of list. - - case tc_ceiling: - ceiling = Z_Calloc(sizeof(*ceiling), PU_MAP, NULL); + case tc_ceiling: { + ceiling_t *ceiling = (ceiling_t *)Z_Calloc(sizeof(*ceiling), PU_MAP, NULL); SV_ReadCeiling(ceiling); Thinker_Add(&ceiling->thinker); - break; + break; } - case tc_door: - door = Z_Calloc(sizeof(*door), PU_MAP, NULL); + case tc_door: { + door_t *door = (door_t *)Z_Calloc(sizeof(*door), PU_MAP, NULL); SV_ReadDoor(door); Thinker_Add(&door->thinker); - break; + break; } - case tc_floor: - floor = Z_Calloc(sizeof(*floor), PU_MAP, NULL); + case tc_floor: { + floor_t *floor = (floor_t *)Z_Calloc(sizeof(*floor), PU_MAP, NULL); SV_ReadFloor(floor); Thinker_Add(&floor->thinker); - break; + break; } - case tc_plat: - plat = Z_Calloc(sizeof(*plat), PU_MAP, NULL); + case tc_plat: { + plat_t *plat = (plat_t *)Z_Calloc(sizeof(*plat), PU_MAP, NULL); SV_ReadPlat(plat); Thinker_Add(&plat->thinker); - break; + break; } - case tc_flash: - flash = Z_Calloc(sizeof(*flash), PU_MAP, NULL); + case tc_flash: { + lightflash_t *flash = (lightflash_t *)Z_Calloc(sizeof(*flash), PU_MAP, NULL); SV_ReadFlash(flash); Thinker_Add(&flash->thinker); - break; + break; } - case tc_strobe: - strobe = Z_Calloc(sizeof(*strobe), PU_MAP, NULL); + case tc_strobe: { + strobe_t *strobe = (strobe_t *)Z_Calloc(sizeof(*strobe), PU_MAP, NULL); SV_ReadStrobe(strobe); Thinker_Add(&strobe->thinker); - break; + break; } - case tc_glow: - glow = Z_Calloc(sizeof(*glow), PU_MAP, NULL); + case tc_glow: { + glow_t *glow = (glow_t *)Z_Calloc(sizeof(*glow), PU_MAP, NULL); SV_ReadGlow(glow); Thinker_Add(&glow->thinker); - break; + break; } default: - Con_Error("P_UnarchiveSpecials:Unknown tclass %i " "in savegame", - tclass); + Con_Error("P_UnarchiveSpecials:Unknown tclass %i " "in savegame", tclass); } } } int SV_LoadState_Hr_v13(Str const *path, SaveInfo *info) { - saveheader_t const *hdr; - DENG_ASSERT(path != 0 && info != 0); if(!SV_OpenFile_Hr_v13(Str_Text(path))) return 1; @@ -882,19 +846,20 @@ int SV_LoadState_Hr_v13(Str const *path, SaveInfo *info) // Read the header again. /// @todo Seek past the header straight to the game state. { - SaveInfo *tmp = SaveInfo_New(); - SaveInfo_Read_Hr_v13(tmp, svReader); - SaveInfo_Delete(tmp); + SaveInfo *tmp = SaveInfo_New(); + SaveInfo_Read_Hr_v13(tmp, svReader); + SaveInfo_Delete(tmp); } - hdr = SaveInfo_Header(info); - gameSkill = hdr->skill; - gameEpisode = hdr->episode; - gameMap = hdr->map; + saveheader_t const *hdr = SaveInfo_Header(info); + + gameSkill = hdr->skill; + gameEpisode = hdr->episode; + gameMap = hdr->map; gameMapEntryPoint = 0; // We don't want to see a briefing if we're loading a save game. - briefDisabled = true; + briefDisabled = true; // Load a base map. G_NewGame(gameSkill, gameEpisode, gameMap, gameMapEntryPoint); @@ -910,92 +875,89 @@ int SV_LoadState_Hr_v13(Str const *path, SaveInfo *info) if(Reader_ReadByte(svReader) != SAVE_GAME_TERMINATOR) { - Reader_Delete(svReader); - svReader = NULL; + Reader_Delete(svReader); svReader = 0; SV_CloseFile_Hr_v13(); Con_Error("Bad savegame"); // Missing savegame termination marker. exit(1); // Unreachable. } - Reader_Delete(svReader); - svReader = NULL; + Reader_Delete(svReader); svReader = 0; SV_CloseFile_Hr_v13(); return 0; // Success! } -static void SaveInfo_Read_Hr_v13(SaveInfo* info, Reader* reader) +static void SaveInfo_Read_Hr_v13(SaveInfo *info, Reader *reader) { - saveheader_t* hdr = &info->header; - char nameBuffer[V13_SAVESTRINGSIZE]; - char vcheck[VERSIONSIZE]; - int i; - assert(info); + DENG_ASSERT(info != 0); + + saveheader_t *hdr = &info->header; + char nameBuffer[V13_SAVESTRINGSIZE]; Reader_Read(reader, nameBuffer, V13_SAVESTRINGSIZE); nameBuffer[V13_SAVESTRINGSIZE - 1] = 0; Str_Set(&info->name, nameBuffer); + char vcheck[VERSIONSIZE]; Reader_Read(reader, vcheck, VERSIONSIZE); - //assert(!strncmp(vcheck, "version ", 8)); // Ensure save state format has been recognised by now. - hdr->version = atoi(&vcheck[8]); + //DENG_ASSERT(!strncmp(vcheck, "version ", 8)); // Ensure save state format has been recognised by now. + hdr->version = atoi(&vcheck[8]); - hdr->skill = (skillmode_t) Reader_ReadByte(reader); + hdr->skill = (skillmode_t) Reader_ReadByte(reader); // Interpret skill levels outside the normal range as "spawn no things". if(hdr->skill < SM_BABY || hdr->skill >= NUM_SKILL_MODES) hdr->skill = SM_NOTHINGS; - hdr->episode = Reader_ReadByte(reader)-1; - hdr->map = Reader_ReadByte(reader)-1; - for(i = 0; i < 4; ++i) + hdr->episode = Reader_ReadByte(reader)-1; + hdr->map = Reader_ReadByte(reader)-1; + for(int i = 0; i < 4; ++i) { hdr->players[i] = Reader_ReadByte(reader); } memset(&hdr->players[4], 0, sizeof(*hdr->players) * (MAXPLAYERS-4)); // Get the map time. - { int a = Reader_ReadByte(reader); + int a = Reader_ReadByte(reader); int b = Reader_ReadByte(reader); int c = Reader_ReadByte(reader); - hdr->mapTime = (a << 16) + (b << 8) + c; - } + hdr->mapTime = (a << 16) + (b << 8) + c; - hdr->magic = 0; // Initialize with *something*. + hdr->magic = 0; // Initialize with *something*. /// @note Older formats do not contain all needed values: - hdr->gameMode = gameMode; // Assume the current mode. - hdr->deathmatch = 0; - hdr->noMonsters = 0; + hdr->gameMode = gameMode; // Assume the current mode. + hdr->deathmatch = 0; + hdr->noMonsters = 0; hdr->respawnMonsters = 0; info->gameId = 0; // None. } -static dd_bool SV_OpenFile_Hr_v13(const char* filePath) +static dd_bool SV_OpenFile_Hr_v13(char const *filePath) { dd_bool fileOpened; #if _DEBUG if(saveBuffer) Con_Error("SV_OpenFile_Hr_v13: A save state file has already been opened!"); #endif - fileOpened = 0 != M_ReadFile(filePath, (char**)&saveBuffer); + fileOpened = 0 != M_ReadFile(filePath, (char **)&saveBuffer); if(!fileOpened) return false; savePtr = saveBuffer; return true; } -static void SV_CloseFile_Hr_v13(void) +static void SV_CloseFile_Hr_v13() { if(!saveBuffer) return; Z_Free(saveBuffer); - saveBuffer = savePtr = NULL; + saveBuffer = savePtr = 0; } -static Reader* SV_NewReader_Hr_v13(void) +static Reader *SV_NewReader_Hr_v13() { - if(!saveBuffer) return NULL; + if(!saveBuffer) return 0; return Reader_NewWithCallbacks(sri8, sri16, sri32, NULL, srd); } @@ -1021,8 +983,7 @@ dd_bool SV_RecogniseState_Hr_v13(Str const *path, SaveInfo *info) result = (SaveInfo_Header(info)->version == V13_SAVE_VERSION); } - Reader_Delete(svReader); - svReader = NULL; + Reader_Delete(svReader); svReader = 0; SV_CloseFile_Hr_v13(); return result; From fd92237e6e5d6877f5d74967006d09639313582f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Mon, 3 Feb 2014 22:53:07 +0200 Subject: [PATCH 068/106] Fixed|libdeng2|Time: Printing the correct time --- doomsday/libdeng2/src/data/time.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doomsday/libdeng2/src/data/time.cpp b/doomsday/libdeng2/src/data/time.cpp index 0e7fffa212..db07d09977 100644 --- a/doomsday/libdeng2/src/data/time.cpp +++ b/doomsday/libdeng2/src/data/time.cpp @@ -308,7 +308,9 @@ String Time::asText(Format format) const } else if(format == BuildNumberAndSecondsSinceStart) { - TimeDelta const elapsed = highPerfTimer.elapsed(); + DENG2_ASSERT(d->flags & Instance::HighPerformance); + + TimeDelta const elapsed = d->highPerfElapsed; int hours = elapsed.asHours(); double sec = elapsed - hours * 3600.0; if(hours > 0) From aae0f35557b9c8ed4b6f774fe45de66ef73a3692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Mon, 3 Feb 2014 22:55:22 +0200 Subject: [PATCH 069/106] Refactor|libdeng2|Action|Counted: Actions are reference counted Rather than requiring duplication of Action instances, they are now reference counted so they can be conveniently shared between items and widgets, and multiple widgets. Added more convenience utilities for Counted objects: RefArg and AutoRef. The former takes care of reference passing convention in method arguments while the latter auto-releases a reference after its scope runs out. --- doomsday/libdeng2/include/de/data/counted.h | 85 +++++++++++++++++-- doomsday/libdeng2/include/de/widgets/action.h | 18 ++-- doomsday/libdeng2/src/widgets/action.cpp | 5 +- 3 files changed, 89 insertions(+), 19 deletions(-) diff --git a/doomsday/libdeng2/include/de/data/counted.h b/doomsday/libdeng2/include/de/data/counted.h index 73295705f4..3551050394 100644 --- a/doomsday/libdeng2/include/de/data/counted.h +++ b/doomsday/libdeng2/include/de/data/counted.h @@ -160,17 +160,31 @@ inline CountedType const *holdRef(CountedType const &counted) { return counted.template ref(); } -template -inline void changeRef(CountedType1 const *&counted, CountedType2 const *newRef) { - CountedType1 const *old = counted; - counted = holdRef(newRef); +template +inline void changeRef(CountedType const *&counted, Counted const *newRef) { + CountedType const *old = counted; + counted = (newRef? newRef->ref() : 0); + releaseRef(old); +} + +template +inline void changeRef(CountedType const *&counted, Counted const &newRef) { + CountedType const *old = counted; + counted = newRef.ref(); + releaseRef(old); +} + +template +inline void changeRef(CountedType *&counted, Counted *newRef) { + CountedType *old = counted; + counted = (newRef? newRef->ref() : 0); releaseRef(old); } -template -inline void changeRef(CountedType1 const *&counted, CountedType2 const &newRef) { - CountedType1 const *old = counted; - counted = holdRef(newRef); +template +inline void changeRef(CountedType *&counted, Counted &newRef) { + CountedType *old = counted; + counted = newRef.ref(); releaseRef(old); } @@ -198,6 +212,61 @@ inline void releaseRef(CountedType const *&ref) { ref = 0; } +/** + * Utility for passing Counted objects as arguments. + * + * RefArg enforces the following conventions when used as an method argument type: + * - If a Counted non-const pointer is given as an argument, it is assumed the + * caller has already held a reference and is giving that reference's ownership + * away. For instance, when constructing new Counted objects. + * - If a Counted const reference is given as an argument, no changes occur in the + * object's refcount. + * + * The method that uses RefArgs must hold a reference to each object. + */ +template +class RefArg +{ +public: + RefArg() : _ref(0) {} + RefArg(RefArg const &other) : _ref(other._ref) {} + RefArg(CountedType *preHeld) : _ref(refless(preHeld)) {} + RefArg(CountedType const &ref) : _ref(const_cast(&ref)) {} + operator CountedType const * () const { return _ref; } + operator CountedType * () { return _ref; } + CountedType *get() { return _ref; } + CountedType const &operator * () const { return *_ref; } + CountedType & operator * () { return *_ref; } + CountedType const *operator -> () const { return _ref; } + CountedType * operator -> () { return _ref; } + CountedType *holdRef() { return de::holdRef(_ref); } +private: + CountedType *_ref; +}; + +/** + * Utility for managing a newly created Counted object. Automatically releases the + * reference added by the constructor. + */ +template +class AutoRef +{ +public: + AutoRef(CountedType *preHeld) : _ref(preHeld) {} + AutoRef(CountedType &ref) : _ref(holdRef(ref)) {} + ~AutoRef() { releaseRef(_ref); } + void reset(RefArg ref) { changeRef(_ref, ref); } + CountedType *get() const { return _ref; } + CountedType &operator * () const { return *_ref; } + CountedType *operator -> () const { return _ref; } + operator CountedType const * () const { return _ref; } + operator CountedType * () { return _ref; } + operator CountedType const & () const { return *_ref; } + operator CountedType & () { *_ref; } +private: + CountedType *_ref; +}; + } // namespace de #endif /* LIBDENG2_COUNTED_H */ diff --git a/doomsday/libdeng2/include/de/widgets/action.h b/doomsday/libdeng2/include/de/widgets/action.h index c9beb23cdb..5251cacde6 100644 --- a/doomsday/libdeng2/include/de/widgets/action.h +++ b/doomsday/libdeng2/include/de/widgets/action.h @@ -20,15 +20,20 @@ #define LIBDENG2_ACTION_H #include +#include namespace de { /** * Abstract base class for user interface actions. * + * Actions are reference-counted so that they can be shared by widgets and data model + * items. Also, the same actions could be used by different sets of widgets representing + * a single data item. + * * @ingroup widgets */ -class DENG2_PUBLIC Action +class DENG2_PUBLIC Action : public Counted { public: /** @@ -36,9 +41,6 @@ class DENG2_PUBLIC Action */ DENG2_DEFINE_AUDIENCE(Triggered, void actionTriggered(Action &)) -public: - virtual ~Action(); - /** * Perform the action this instance represents. Derived classes must call * this or manually notify the Triggered audience in their own @@ -46,12 +48,8 @@ class DENG2_PUBLIC Action */ virtual void trigger(); - /** - * Returns a duplicate copy of the action. - * - * @return Duplicated action. Caller gets ownership. - */ - virtual Action *duplicate() const = 0; +protected: + virtual ~Action(); // ref counted, hence not publicly deletable }; } // namespace de diff --git a/doomsday/libdeng2/src/widgets/action.cpp b/doomsday/libdeng2/src/widgets/action.cpp index 69b0c79346..c952d840d2 100644 --- a/doomsday/libdeng2/src/widgets/action.cpp +++ b/doomsday/libdeng2/src/widgets/action.cpp @@ -25,7 +25,10 @@ Action::~Action() void Action::trigger() { - DENG2_FOR_AUDIENCE(Triggered, i) i->actionTriggered(*this); + DENG2_FOR_AUDIENCE(Triggered, i) + { + i->actionTriggered(*this); + } } } // namespace de From eb973f9ba4bb94a3cb702973b1480cbfbf70449b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Mon, 3 Feb 2014 22:55:58 +0200 Subject: [PATCH 070/106] Refactor|libshell: Use reference-counted Action instances --- doomsday/libshell/include/de/shell/action.h | 7 ++--- .../libshell/include/de/shell/menuwidget.h | 4 +-- .../libshell/include/de/shell/textwidget.h | 2 +- doomsday/libshell/src/action.cpp | 5 ---- doomsday/libshell/src/menuwidget.cpp | 29 ++++++++++++++----- doomsday/libshell/src/textwidget.cpp | 20 ++++++++++--- 6 files changed, 43 insertions(+), 24 deletions(-) diff --git a/doomsday/libshell/include/de/shell/action.h b/doomsday/libshell/include/de/shell/action.h index 9d341cbbe6..72d6a24e22 100644 --- a/doomsday/libshell/include/de/shell/action.h +++ b/doomsday/libshell/include/de/shell/action.h @@ -42,8 +42,6 @@ class Action : public QObject, public de::Action Action(KeyEvent const &event, QObject *target = 0, char const *slot = 0); - ~Action(); - void setLabel(String const &label); String label() const; @@ -59,11 +57,12 @@ class Action : public QObject, public de::Action void trigger(); - Action *duplicate() const; - signals: void triggered(); +protected: + ~Action(); + private: KeyEvent _event; String _label; diff --git a/doomsday/libshell/include/de/shell/menuwidget.h b/doomsday/libshell/include/de/shell/menuwidget.h index 196e9d4a50..80777930f4 100644 --- a/doomsday/libshell/include/de/shell/menuwidget.h +++ b/doomsday/libshell/include/de/shell/menuwidget.h @@ -64,7 +64,7 @@ class LIBSHELL_PUBLIC MenuWidget : public TextWidget * @param action Action to add as a shortcut for triggering the item. * @param shortcutLabel Label to show, representing the action shortcut to the user. */ - void appendItem(Action *action, String const &shortcutLabel = ""); + void appendItem(RefArg action, String const &shortcutLabel = ""); /** * Inserts an item into the menu. @@ -73,7 +73,7 @@ class LIBSHELL_PUBLIC MenuWidget : public TextWidget * @param action Action to add as a shortcut for triggering the item. * @param shortcutLabel Label to show, representing the action shortcut to the user. */ - void insertItem(int pos, Action *action, String const &shortcutLabel = ""); + void insertItem(int pos, RefArg action, String const &shortcutLabel = ""); void appendSeparator(); diff --git a/doomsday/libshell/include/de/shell/textwidget.h b/doomsday/libshell/include/de/shell/textwidget.h index 536faeed8f..db7b5532ab 100644 --- a/doomsday/libshell/include/de/shell/textwidget.h +++ b/doomsday/libshell/include/de/shell/textwidget.h @@ -108,7 +108,7 @@ class LIBSHELL_PUBLIC TextWidget : public QObject, public Widget * * @param action Action instance. Ownership taken. */ - void addAction(Action *action); + void addAction(RefArg action); /** * Removes an action from the widget. diff --git a/doomsday/libshell/src/action.cpp b/doomsday/libshell/src/action.cpp index 90ba639062..bb3a4325ef 100644 --- a/doomsday/libshell/src/action.cpp +++ b/doomsday/libshell/src/action.cpp @@ -80,10 +80,5 @@ void Action::trigger() emit triggered(); } -Action *Action::duplicate() const -{ - return new Action(_label, _event, _target, _slot); -} - } // namespace shell } // namespace de diff --git a/doomsday/libshell/src/menuwidget.cpp b/doomsday/libshell/src/menuwidget.cpp index d2ff3e948f..338442b22f 100644 --- a/doomsday/libshell/src/menuwidget.cpp +++ b/doomsday/libshell/src/menuwidget.cpp @@ -42,8 +42,23 @@ DENG2_PIMPL(MenuWidget) String shortcutLabel; bool separatorAfter; - Item() : action(0), separatorAfter(false) - {} + Item() : action(0), separatorAfter(false) {} + + Item(Item const &other) + : action(holdRef(other.action)) + , shortcutLabel(other.shortcutLabel) + , separatorAfter(other.separatorAfter) {} + + ~Item() { + releaseRef(action); + } + + Item &operator = (Item const &other) { + changeRef(action, other.action); + shortcutLabel = other.shortcutLabel; + separatorAfter = other.separatorAfter; + return *this; + } }; QList items; @@ -74,7 +89,6 @@ DENG2_PIMPL(MenuWidget) foreach(Item i, items) { self.removeAction(*i.action); - delete i.action; } items.clear(); updateSize(); @@ -103,7 +117,6 @@ DENG2_PIMPL(MenuWidget) void removeItem(int pos) { self.removeAction(*items[pos].action); - delete items[pos].action; items.removeAt(pos); updateSize(); } @@ -135,10 +148,10 @@ int MenuWidget::itemCount() const return d->items.size(); } -void MenuWidget::appendItem(Action *action, String const &shortcutLabel) +void MenuWidget::appendItem(RefArg action, String const &shortcutLabel) { Instance::Item item; - item.action = action; + item.action = action.holdRef(); item.shortcutLabel = shortcutLabel; d->items.append(item); d->updateSize(); @@ -156,10 +169,10 @@ void MenuWidget::appendSeparator() redraw(); } -void MenuWidget::insertItem(int pos, Action *action, String const &shortcutLabel) +void MenuWidget::insertItem(int pos, RefArg action, String const &shortcutLabel) { Instance::Item item; - item.action = action; + item.action = action.holdRef(); item.shortcutLabel = shortcutLabel; d->items.insert(pos, item); d->updateSize(); diff --git a/doomsday/libshell/src/textwidget.cpp b/doomsday/libshell/src/textwidget.cpp index cb7556ecb6..f697d15cdf 100644 --- a/doomsday/libshell/src/textwidget.cpp +++ b/doomsday/libshell/src/textwidget.cpp @@ -36,7 +36,19 @@ DENG2_PIMPL_NOREF(TextWidget) ~Instance() { delete rule; - foreach(Action *act, actions) delete act; + foreach(Action *act, actions) releaseRef(act); + } + + void removeAction(Action &action) + { + for(int i = actions.size() - 1; i >= 0; --i) + { + if(actions.at(i) == &action) + { + releaseRef(actions[i]); + actions.removeAt(i); + } + } } /** @@ -123,14 +135,14 @@ Vector2i TextWidget::cursorPosition() const rule().top().valuei()); } -void TextWidget::addAction(Action *action) +void TextWidget::addAction(RefArg action) { - d->actions.append(action); + d->actions.append(action.holdRef()); } void TextWidget::removeAction(Action &action) { - d->actions.removeAll(&action); + d->removeAction(action); } bool TextWidget::handleEvent(Event const &event) From b61e600a21e78ce7334ca0639e9550f654e47904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Mon, 3 Feb 2014 22:56:31 +0200 Subject: [PATCH 071/106] Refactor|libappfw: Use reference-counted Action instances --- .../include/de/framework/actionitem.h | 42 ++++++++++++------- .../include/de/framework/signalaction.h | 1 - .../include/de/widgets/buttonwidget.h | 7 ++-- .../include/de/widgets/dialogwidget.h | 14 +++---- doomsday/libappfw/src/signalaction.cpp | 5 --- .../libappfw/src/widgets/buttonwidget.cpp | 31 ++++++++------ .../libappfw/src/widgets/choicewidget.cpp | 6 --- .../libappfw/src/widgets/dialogwidget.cpp | 8 ++-- doomsday/libappfw/src/widgets/menuwidget.cpp | 10 +---- 9 files changed, 62 insertions(+), 62 deletions(-) diff --git a/doomsday/libappfw/include/de/framework/actionitem.h b/doomsday/libappfw/include/de/framework/actionitem.h index 9d945ed15e..f27970b0f2 100644 --- a/doomsday/libappfw/include/de/framework/actionitem.h +++ b/doomsday/libappfw/include/de/framework/actionitem.h @@ -33,36 +33,50 @@ namespace ui { class LIBAPPFW_PUBLIC ActionItem : public Item { public: - ActionItem(de::String const &label = "", de::Action *action = 0) - : Item(ShownAsButton | ActivationClosesPopup, label), _action(action) {} + ActionItem(String const &label = "", + RefArg action = RefArg()) + : Item(ShownAsButton | ActivationClosesPopup, label) + , _action(action.holdRef()) {} - ActionItem(Semantics semantics, de::String const &label = "", de::Action *action = 0) - : Item(semantics, label), _action(action) {} + ActionItem(Semantics semantics, + String const &label = "", + RefArg action = RefArg()) + : Item(semantics, label) + , _action(action.holdRef()) {} - ActionItem(Semantics semantics, de::Image const &img, de::String const &label = "", de::Action *action = 0) - : Item(semantics, label), _action(action), _image(img) {} + ActionItem(Semantics semantics, + Image const &img, + String const &label = "", + RefArg action = RefArg()) + : Item(semantics, label) + , _action(action.holdRef()) + , _image(img) {} - ActionItem(de::Image const &img, de::String const &label = "", de::Action *action = 0) - : Item(ShownAsButton | ActivationClosesPopup, label), _action(action), _image(img) {} + ActionItem(Image const &img, + String const &label = "", + RefArg action = RefArg()) + : Item(ShownAsButton | ActivationClosesPopup, label) + , _action(action.holdRef()) + , _image(img) {} - de::Action *action() const { return _action.data(); } // ownership kept - de::Image const &image() const { return _image; } + Action const *action() const { return _action; } + Image const &image() const { return _image; } - void setAction(de::Action *action) + void setAction(RefArg action) { _action.reset(action); notifyChange(); } - void setImage(de::Image const &image) + void setImage(Image const &image) { _image = image; notifyChange(); } private: - QScopedPointer _action; - de::Image _image; + AutoRef _action; + Image _image; }; } // namespace ui diff --git a/doomsday/libappfw/include/de/framework/signalaction.h b/doomsday/libappfw/include/de/framework/signalaction.h index 591c0ad155..41790d94a6 100644 --- a/doomsday/libappfw/include/de/framework/signalaction.h +++ b/doomsday/libappfw/include/de/framework/signalaction.h @@ -33,7 +33,6 @@ class LIBAPPFW_PUBLIC SignalAction : public QObject, public Action SignalAction(QObject *target, char const *slot); void trigger(); - SignalAction *duplicate() const; signals: void triggered(); diff --git a/doomsday/libappfw/include/de/widgets/buttonwidget.h b/doomsday/libappfw/include/de/widgets/buttonwidget.h index 85be12adfd..9312a8fa89 100644 --- a/doomsday/libappfw/include/de/widgets/buttonwidget.h +++ b/doomsday/libappfw/include/de/widgets/buttonwidget.h @@ -73,12 +73,11 @@ class LIBAPPFW_PUBLIC ButtonWidget : public LabelWidget * Sets the action of the button. It gets triggered when the button is * pressed. * - * @param action Action instance. Widget takes ownership. + * @param action Action instance. Widget holds a reference. */ - void setAction(Action *action); + void setAction(RefArg action); - Action *action() const; - Action *takeAction(); + Action const *action() const; State state() const; diff --git a/doomsday/libappfw/include/de/widgets/dialogwidget.h b/doomsday/libappfw/include/de/widgets/dialogwidget.h index 5aebd1d85c..db06a9009d 100644 --- a/doomsday/libappfw/include/de/widgets/dialogwidget.h +++ b/doomsday/libappfw/include/de/widgets/dialogwidget.h @@ -109,18 +109,18 @@ class LIBAPPFW_PUBLIC DialogWidget : public PopupWidget * @param flags Role flags for the button. * @param label Label for the button. If empty, the default label will be used. */ - ButtonItem(RoleFlags flags, de::String const &label = ""); + ButtonItem(RoleFlags flags, String const &label = ""); /** * Button with custom action. * @param flags Role flags for the button. * @param label Label for the button. If empty, the default label will be used. */ - ButtonItem(RoleFlags flags, de::String const &label, de::Action *action); + ButtonItem(RoleFlags flags, String const &label, RefArg action); - ButtonItem(RoleFlags flags, de::Image const &image, de::Action *action); + ButtonItem(RoleFlags flags, Image const &image, RefArg action); - ButtonItem(RoleFlags flags, de::Image const &image, de::String const &label, de::Action *action); + ButtonItem(RoleFlags flags, Image const &image, String const &label, RefArg action); RoleFlags role() const { return _role; } @@ -129,7 +129,7 @@ class LIBAPPFW_PUBLIC DialogWidget : public PopupWidget }; public: - DialogWidget(de::String const &name = "", Flags const &flags = DefaultFlags); + DialogWidget(String const &name = "", Flags const &flags = DefaultFlags); Modality modality() const; @@ -155,7 +155,7 @@ class LIBAPPFW_PUBLIC DialogWidget : public PopupWidget ui::Data &buttons(); - ButtonWidget &buttonWidget(de::String const &label) const; + ButtonWidget &buttonWidget(String const &label) const; ButtonWidget *buttonWidget(int roleId) const; @@ -180,7 +180,7 @@ class LIBAPPFW_PUBLIC DialogWidget : public PopupWidget // Events. void update(); - bool handleEvent(de::Event const &event); + bool handleEvent(Event const &event); public slots: void accept(int result = 1); diff --git a/doomsday/libappfw/src/signalaction.cpp b/doomsday/libappfw/src/signalaction.cpp index 498ac827e9..c21d856dac 100644 --- a/doomsday/libappfw/src/signalaction.cpp +++ b/doomsday/libappfw/src/signalaction.cpp @@ -32,9 +32,4 @@ void SignalAction::trigger() emit triggered(); } -SignalAction *SignalAction::duplicate() const -{ - return new SignalAction(_target, _slot); -} - } // namespace de diff --git a/doomsday/libappfw/src/widgets/buttonwidget.cpp b/doomsday/libappfw/src/widgets/buttonwidget.cpp index 4f5a411751..eee7b0aff0 100644 --- a/doomsday/libappfw/src/widgets/buttonwidget.cpp +++ b/doomsday/libappfw/src/widgets/buttonwidget.cpp @@ -29,7 +29,7 @@ DENG2_OBSERVES(Action, Triggered) { State state; DotPath hoverTextColor; - QScopedPointer action; + Action *action; Animation scale; Animation frameOpacity; bool animating; @@ -37,6 +37,7 @@ DENG2_OBSERVES(Action, Triggered) Instance(Public *i) : Base(i) , state(Up) + , action(0) , scale(1.f) , frameOpacity(.08f, Animation::Linear) , animating(false) @@ -44,6 +45,12 @@ DENG2_OBSERVES(Action, Triggered) setDefaultBackground(); } + ~Instance() + { + if(action) action->audienceForTriggered -= this; + releaseRef(action); + } + void setState(State st) { if(state == st) return; @@ -151,14 +158,14 @@ void ButtonWidget::setHoverTextColor(DotPath const &hoverTextId) d->hoverTextColor = hoverTextId; } -void ButtonWidget::setAction(Action *action) +void ButtonWidget::setAction(RefArg action) { - if(!d->action.isNull()) + if(d->action) { d->action->audienceForTriggered -= d; } - d->action.reset(action); + changeRef(d->action, action); if(action) { @@ -166,14 +173,9 @@ void ButtonWidget::setAction(Action *action) } } -Action *ButtonWidget::action() const +Action const *ButtonWidget::action() const { - return d->action.data(); -} - -Action *ButtonWidget::takeAction() -{ - return d->action.take(); + return d->action; } ButtonWidget::State ButtonWidget::state() const @@ -206,12 +208,15 @@ bool ButtonWidget::handleEvent(Event const &event) d->updateHover(mouse.pos()); if(hitTest(mouse.pos())) { + // Hold an extra ref so the action isn't deleted by triggering. + AutoRef held = holdRef(d->action); + // Notify. DENG2_FOR_AUDIENCE(Press, i) i->buttonPressed(*this); - if(!d->action.isNull()) + if(held) { - d->action->trigger(); + held->trigger(); } } return true; diff --git a/doomsday/libappfw/src/widgets/choicewidget.cpp b/doomsday/libappfw/src/widgets/choicewidget.cpp index 29d56c94e9..5dd8625680 100644 --- a/doomsday/libappfw/src/widgets/choicewidget.cpp +++ b/doomsday/libappfw/src/widgets/choicewidget.cpp @@ -52,12 +52,6 @@ DENG2_OBSERVES(ChildWidgetOrganizer, WidgetUpdate) emit d->self.selectionChangedByUser(d->selected); } - - Action *duplicate() const - { - DENG2_ASSERT(false); // not needed - return 0; - } }; PopupMenuWidget *choices; diff --git a/doomsday/libappfw/src/widgets/dialogwidget.cpp b/doomsday/libappfw/src/widgets/dialogwidget.cpp index e93b8202a4..8685fc6892 100644 --- a/doomsday/libappfw/src/widgets/dialogwidget.cpp +++ b/doomsday/libappfw/src/widgets/dialogwidget.cpp @@ -520,7 +520,7 @@ bool DialogWidget::handleEvent(Event const &event) ButtonWidget const &but = d->buttonWidget(*defaultAction); if(but.action()) { - but.action()->trigger(); + const_cast(but.action())->trigger(); } } return true; @@ -626,15 +626,15 @@ DialogWidget::ButtonItem::ButtonItem(RoleFlags flags, String const &label) : ui::ActionItem(label, 0), _role(flags) {} -DialogWidget::ButtonItem::ButtonItem(RoleFlags flags, String const &label, de::Action *action) +DialogWidget::ButtonItem::ButtonItem(RoleFlags flags, String const &label, RefArg action) : ui::ActionItem(label, action), _role(flags) {} -DialogWidget::ButtonItem::ButtonItem(RoleFlags flags, Image const &image, de::Action *action) +DialogWidget::ButtonItem::ButtonItem(RoleFlags flags, Image const &image, RefArg action) : ui::ActionItem(image, "", action), _role(flags) {} -DialogWidget::ButtonItem::ButtonItem(RoleFlags flags, Image const &image, String const &label, de::Action *action) +DialogWidget::ButtonItem::ButtonItem(RoleFlags flags, Image const &image, String const &label, RefArg action) : ui::ActionItem(image, label, action), _role(flags) {} diff --git a/doomsday/libappfw/src/widgets/menuwidget.cpp b/doomsday/libappfw/src/widgets/menuwidget.cpp index 80c8694125..cb9d907c0f 100644 --- a/doomsday/libappfw/src/widgets/menuwidget.cpp +++ b/doomsday/libappfw/src/widgets/menuwidget.cpp @@ -94,12 +94,6 @@ DENG2_PIMPL(MenuWidget) _widget->open(); } - Action *duplicate() const - { - DENG2_ASSERT(false); // not needed - return 0; - } - protected: Instance *d; ui::Item const &_parentItem; @@ -284,7 +278,7 @@ DENG2_PIMPL(MenuWidget) b.setText(act->label()); if(act->action()) { - b.setAction(act->action()->duplicate()); + b.setAction(*act->action()); } } else if(item.semantics().testFlag(Item::ShownAsLabel)) @@ -297,7 +291,7 @@ DENG2_PIMPL(MenuWidget) t.setText(act->label()); if(act->action()) { - t.setAction(act->action()->duplicate()); + t.setAction(*act->action()); } } } From 7d7806ed2e3ca29bbff16bb2fcedbaa7f8eb5e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Mon, 3 Feb 2014 22:57:08 +0200 Subject: [PATCH 072/106] Refactor|UI|Client: Use reference-counted Action instances --- doomsday/client/include/ui/commandaction.h | 1 - doomsday/client/src/ui/commandaction.cpp | 5 ----- .../src/ui/editors/rendererappearanceeditor.cpp | 9 ++------- doomsday/client/src/ui/widgetactions.cpp | 4 ++-- .../client/src/ui/widgets/gameselectionwidget.cpp | 12 +++--------- .../client/src/ui/widgets/mpselectionwidget.cpp | 13 ------------- 6 files changed, 7 insertions(+), 37 deletions(-) diff --git a/doomsday/client/include/ui/commandaction.h b/doomsday/client/include/ui/commandaction.h index 54fc02b029..f802b56e28 100644 --- a/doomsday/client/include/ui/commandaction.h +++ b/doomsday/client/include/ui/commandaction.h @@ -36,7 +36,6 @@ class CommandAction : public de::Action de::String command() const { return _command; } void trigger(); - Action *duplicate() const; private: de::String _command; diff --git a/doomsday/client/src/ui/commandaction.cpp b/doomsday/client/src/ui/commandaction.cpp index 021c5eb964..6c60f6b583 100644 --- a/doomsday/client/src/ui/commandaction.cpp +++ b/doomsday/client/src/ui/commandaction.cpp @@ -32,8 +32,3 @@ void CommandAction::trigger() Con_Execute(_source, _command.toUtf8(), false /*silent*/, false /*net*/); } - -Action *CommandAction::duplicate() const -{ - return new CommandAction(_command, _source); -} diff --git a/doomsday/client/src/ui/editors/rendererappearanceeditor.cpp b/doomsday/client/src/ui/editors/rendererappearanceeditor.cpp index d14d8571db..6fe24e100c 100644 --- a/doomsday/client/src/ui/editors/rendererappearanceeditor.cpp +++ b/doomsday/client/src/ui/editors/rendererappearanceeditor.cpp @@ -79,15 +79,10 @@ DENG2_OBSERVES(App, GameChange) class Group : public FoldPanelWidget { /// Action for reseting the group's settings to defaults. - struct ResetAction : public Action - { + struct ResetAction : public Action { Group *group; - ResetAction(Group *groupToReset) : group(groupToReset) {} - Action *duplicate() const { return new ResetAction(group); } - - void trigger() - { + void trigger() { Action::trigger(); group->resetToDefaults(); } diff --git a/doomsday/client/src/ui/widgetactions.cpp b/doomsday/client/src/ui/widgetactions.cpp index 2aef7645a0..8ad4735da4 100644 --- a/doomsday/client/src/ui/widgetactions.cpp +++ b/doomsday/client/src/ui/widgetactions.cpp @@ -53,7 +53,7 @@ bool WidgetActions::tryEvent(Event const &event, String const &context) bcontext_t *bc = B_ContextByName(context.toLatin1()); if(bc) { - std::auto_ptr act(BindContext_ActionForEvent(bc, &ddev, false)); + AutoRef act(BindContext_ActionForEvent(bc, &ddev, false)); if(act.get()) { act->trigger(); @@ -66,7 +66,7 @@ bool WidgetActions::tryEvent(Event const &event, String const &context) bool WidgetActions::tryEvent(ddevent_t const *ev) { - std::auto_ptr act(B_ActionForEvent(ev)); + AutoRef act(B_ActionForEvent(ev)); if(act.get()) { act->trigger(); diff --git a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp index 27b3edb29d..55d610b2bb 100644 --- a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp +++ b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp @@ -44,7 +44,7 @@ DENG_GUI_PIMPL(GameSelectionWidget) { /// ActionItem with a Game member, for loading a particular game. struct GameItem : public ui::ActionItem { - GameItem(Game const &gameRef, de::String const &label, de::Action *action) + GameItem(Game const &gameRef, de::String const &label, RefArg action) : ui::ActionItem(label, action), game(gameRef) { setData(&gameRef); } @@ -222,25 +222,19 @@ DENG_GUI_PIMPL(GameSelectionWidget) emit owner.gameSessionSelected(); CommandAction::trigger(); } - - Action *duplicate() const - { - return new LoadGameAction(command(), owner); - } }; ui::Item *makeItemForGame(Game &game) { String const idKey = game.identityKey(); - LoadGameAction *loadAction = new LoadGameAction(String("load ") + idKey, self); String label = String(_E(b) "%1" _E(.) /*_E(s)_E(C) " %2\n" _E(.)_E(.)*/ "\n" _E(l)_E(D) "%2") .arg(game.title()) //.arg(game.author()) .arg(idKey); - GameItem *item = new GameItem(game, label, loadAction); + GameItem *item = new GameItem(game, label, new LoadGameAction(String("load ") + idKey, self)); /// @todo The name of the plugin should be accessible via the plugin loader. String plugName; @@ -278,7 +272,7 @@ DENG_GUI_PIMPL(GameSelectionWidget) w.loadButton().setImage(it.image()); w.loadButton().setText(it.label()); - w.loadButton().setAction(it.action()->duplicate()); + w.loadButton().setAction(*it.action()); } void appStartupCompleted() diff --git a/doomsday/client/src/ui/widgets/mpselectionwidget.cpp b/doomsday/client/src/ui/widgets/mpselectionwidget.cpp index 24e6370ffa..754dbdd9b5 100644 --- a/doomsday/client/src/ui/widgets/mpselectionwidget.cpp +++ b/doomsday/client/src/ui/widgets/mpselectionwidget.cpp @@ -90,23 +90,10 @@ DENG_GUI_PIMPL(MPSelectionWidget) Action::trigger(); BusyMode_FreezeGameForBusyMode(); - - // Closing the taskbar will cause this action to be deleted. Let's take - // ownership of the action so we can delete after we're done. - _owner->takeAction(); - ClientWindow::main().taskBar().close(); App_ChangeGame(App_Games().byIdentityKey(_gameId), false /*no reload*/); Con_Execute(CMDS_DDAY, _cmd.toLatin1(), false, false); - - delete this; - } - - Action *duplicate() const - { - DENG2_ASSERT(!"JoinAction: cannot duplicate"); - return 0; } private: From b9b93e80a122abd0d41ada049906b3f48dbd9a70 Mon Sep 17 00:00:00 2001 From: danij Date: Mon, 3 Feb 2014 21:00:29 +0000 Subject: [PATCH 073/106] SaveInfo|libcommon: Began transforming SaveInfo into a C++ class --- doomsday/plugins/common/include/saveinfo.h | 90 +++++++--- doomsday/plugins/common/src/p_saveg.cpp | 20 ++- doomsday/plugins/common/src/p_xgfile.cpp | 2 +- doomsday/plugins/common/src/saveinfo.cpp | 194 ++++++++++++++------- doomsday/plugins/doom/src/p_oldsvg.cpp | 6 +- doomsday/plugins/heretic/src/p_oldsvg.cpp | 6 +- 6 files changed, 215 insertions(+), 103 deletions(-) diff --git a/doomsday/plugins/common/include/saveinfo.h b/doomsday/plugins/common/include/saveinfo.h index 8858d072ec..65067c86d2 100644 --- a/doomsday/plugins/common/include/saveinfo.h +++ b/doomsday/plugins/common/include/saveinfo.h @@ -45,21 +45,77 @@ typedef struct saveheader_s { #endif } saveheader_t; +#ifdef __cplusplus /** - * SaveInfo instance. + * Saved game session info. */ -typedef struct saveinfo_s { - Str name; - uint gameId; - saveheader_t header; -} SaveInfo; +class SaveInfo +{ +public: /// @todo make private: + Str _name; + uint _gameId; + saveheader_t _header; + +public: + SaveInfo(); + SaveInfo(SaveInfo const &other); + ~SaveInfo(); + + SaveInfo &operator = (SaveInfo const &other); + + void configure(); + + /** + * Returns @a true if the game state is compatibile with the current game session + * and @em should be loadable. + */ + dd_bool isLoadable(); + + int version() const; + + uint gameId() const; + void setGameId(uint newGameId); + + Str const *name() const; + void setName(Str const *newName); + + /** + * Serializes the save info using @a writer. + * + * @param writer Writer instance. + */ + void write(Writer *writer) const; + + /** + * Deserializes the save info using @a reader. + * + * @param reader Reader instance. + */ + void read(Reader *reader); + +#if __JHEXEN__ + /** + * @brief libhexen specific version of @ref SaveInfo_Read() for deserializing + * legacy version 9 save state info. + */ + void read_Hx_v9(Reader *reader); +#endif + + saveheader_t const *header() const; +}; + +#endif // __cplusplus + +// C wrapper API, for legacy modules ------------------------------------------- #ifdef __cplusplus extern "C" { +#else +typedef void *SaveInfo; #endif SaveInfo *SaveInfo_New(void); -SaveInfo *SaveInfo_NewCopy(SaveInfo const *other); +SaveInfo *SaveInfo_Dup(SaveInfo const *other); void SaveInfo_Delete(SaveInfo *info); @@ -77,33 +133,13 @@ void SaveInfo_SetName(SaveInfo *info, Str const *newName); void SaveInfo_Configure(SaveInfo *info); -/** - * Returns @a true if the game state is compatibile with the current game session - * and @em should be loadable. - */ dd_bool SaveInfo_IsLoadable(SaveInfo *info); -/** - * Serializes the save info using @a writer. - * - * @param info SaveInfo instance. - * @param writer Writer instance. - */ void SaveInfo_Write(SaveInfo *info, Writer *writer); -/** - * Deserializes the save info using @a reader. - * - * @param info SaveInfo instance. - * @param reader Reader instance. - */ void SaveInfo_Read(SaveInfo *info, Reader *reader); #if __JHEXEN__ -/** - * @brief libhexen specific version of @ref SaveInfo_Read() for deserializing - * legacy version 9 save state info. - */ void SaveInfo_Read_Hx_v9(SaveInfo *info, Reader *reader); #endif diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index aff6e0a26c..db621f9cc8 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -689,19 +689,27 @@ static bool recogniseNativeState(Str const *path, SaveInfo *info) #endif // Magic must match. - if(info->header.magic != MY_SAVE_MAGIC && - info->header.magic != MY_CLIENT_SAVE_MAGIC) return false; + saveheader_t const *hdr = &info->_header; + if(hdr->magic != MY_SAVE_MAGIC && hdr->magic != MY_CLIENT_SAVE_MAGIC) + { + return false; + } /* * Check for unsupported versions. */ - // A future version? - if(info->header.version > MY_SAVE_VERSION) return false; + if(hdr->version > MY_SAVE_VERSION) // Future version? + { + return false; + } #if __JHEXEN__ // We are incompatible with v3 saves due to an invalid test used to determine // present sides (ver3 format's sides contain chunks of junk data). - if(info->header.version == 3) return false; + if(hdr->version == 3) + { + return false; + } #endif return true; @@ -848,7 +856,7 @@ void SV_CopySlot(int sourceSlot, int destSlot) SV_CopyFile(src, dst); // Copy saveinfo too. - replaceSaveInfo(destSlot, SaveInfo_NewCopy(findSaveInfoForSlot(sourceSlot))); + replaceSaveInfo(destSlot, SaveInfo_Dup(findSaveInfoForSlot(sourceSlot))); } #if __JHEXEN__ diff --git a/doomsday/plugins/common/src/p_xgfile.cpp b/doomsday/plugins/common/src/p_xgfile.cpp index d79cacd18b..3f37672a16 100644 --- a/doomsday/plugins/common/src/p_xgfile.cpp +++ b/doomsday/plugins/common/src/p_xgfile.cpp @@ -1,4 +1,4 @@ -/** @file p_xgfile.cpp Extended Generalized Line Types. +/** @file p_xgfile.cpp Extended generalized line types. * * DD_XGDATA lump reader. * diff --git a/doomsday/plugins/common/src/saveinfo.cpp b/doomsday/plugins/common/src/saveinfo.cpp index 9af76adb4e..ba11927604 100644 --- a/doomsday/plugins/common/src/saveinfo.cpp +++ b/doomsday/plugins/common/src/saveinfo.cpp @@ -28,75 +28,66 @@ #include #include -SaveInfo *SaveInfo_New() +SaveInfo::SaveInfo() + : _gameId(0) { - SaveInfo *info = (SaveInfo *)M_Malloc(sizeof *info); - - Str_Init(&info->name); - info->gameId = 0; - memset(&info->header, 0, sizeof(info->header)); - - return info; + Str_InitStd(&_name); + memset(&_header, 0, sizeof(_header)); } -SaveInfo *SaveInfo_NewCopy(SaveInfo const *other) +SaveInfo::SaveInfo(SaveInfo const &other) + : _gameId(other._gameId) { - return SaveInfo_Copy(SaveInfo_New(), other); + Str_Copy(Str_InitStd(&_name), &other._name); + std::memcpy(&_header, &other._header, sizeof(_header)); } -void SaveInfo_Delete(SaveInfo *info) +SaveInfo::~SaveInfo() { - DENG_ASSERT(info != 0); - Str_Free(&info->name); - M_Free(info); + Str_Free(&_name); } -SaveInfo *SaveInfo_Copy(SaveInfo *info, SaveInfo const *other) +SaveInfo &SaveInfo::operator = (SaveInfo const &other) { - DENG_ASSERT(info != 0 && other != 0); - - Str_Copy(&info->name, SaveInfo_Name(other)); - info->gameId = SaveInfo_GameId(other); - memcpy(&info->header, SaveInfo_Header(other), sizeof(info->header)); - - return info; + Str_Copy(&_name, &other._name); + _gameId = other._gameId; + std::memcpy(&_header, &other._header, sizeof(_header)); + return *this; } -uint SaveInfo_GameId(SaveInfo const *info) +int SaveInfo::version() const { - DENG_ASSERT(info != 0); - return info->gameId; + return _header.version; } -saveheader_t const *SaveInfo_Header(SaveInfo const *info) +uint SaveInfo::gameId() const { - DENG_ASSERT(info != 0); - return &info->header; + return _gameId; } -Str const *SaveInfo_Name(SaveInfo const *info) +void SaveInfo::setGameId(uint newGameId) { - DENG_ASSERT(info != 0); - return &info->name; + _gameId = newGameId; } -void SaveInfo_SetGameId(SaveInfo *info, uint newGameId) +Str const *SaveInfo::name() const { - DENG_ASSERT(info != 0); - info->gameId = newGameId; + return &_name; } -void SaveInfo_SetName(SaveInfo *info, Str const *newName) +void SaveInfo::setName(Str const *newName) { - DENG_ASSERT(info != 0); - Str_CopyOrClear(&info->name, newName); + Str_CopyOrClear(&_name, newName); } -void SaveInfo_Configure(SaveInfo *info) +saveheader_t const *SaveInfo::header() const { - DENG_ASSERT(info != 0); + return &_header; +} - saveheader_t *hdr = &info->header; +void SaveInfo::configure() +{ + saveheader_t *hdr = &_header; hdr->magic = IS_NETWORK_CLIENT? MY_CLIENT_SAVE_MAGIC : MY_SAVE_MAGIC; hdr->version = MY_SAVE_VERSION; @@ -131,27 +122,23 @@ void SaveInfo_Configure(SaveInfo *info) #endif } -dd_bool SaveInfo_IsLoadable(SaveInfo *info) +dd_bool SaveInfo::isLoadable() { - DENG_ASSERT(info != 0); - // Game Mode missmatch? - if(info->header.gameMode != gameMode) return false; + if(_header.gameMode != gameMode) return false; /// @todo Validate loaded add-ons and checksum the definition database. return true; // It's good! } -void SaveInfo_Write(SaveInfo *info, Writer *writer) +void SaveInfo::write(Writer *writer) const { - DENG_ASSERT(info != 0); - - saveheader_t *hdr = &info->header; + saveheader_t const *hdr = &_header; Writer_WriteInt32(writer, hdr->magic); Writer_WriteInt32(writer, hdr->version); Writer_WriteInt32(writer, hdr->gameMode); - Str_Write(&info->name, writer); + Str_Write(&_name, writer); Writer_WriteByte(writer, hdr->skill & 0x7f); Writer_WriteByte(writer, hdr->episode); @@ -172,7 +159,7 @@ void SaveInfo_Write(SaveInfo *info, Writer *writer) Writer_WriteByte(writer, hdr->players[i]); } #endif - Writer_WriteInt32(writer, info->gameId); + Writer_WriteInt32(writer, _gameId); } #if __JDOOM__ || __JHERETIC__ @@ -218,11 +205,9 @@ static void translateLegacyGameMode(gamemode_t *mode, int saveVersion) } #endif -void SaveInfo_Read(SaveInfo *info, Reader *reader) +void SaveInfo::read(Reader *reader) { - DENG_ASSERT(info != 0); - - saveheader_t *hdr = &info->header; + saveheader_t *hdr = &_header; hdr->magic = Reader_ReadInt32(reader); hdr->version = Reader_ReadInt32(reader); @@ -230,7 +215,7 @@ void SaveInfo_Read(SaveInfo *info, Reader *reader) if(hdr->version >= 10) { - Str_Read(&info->name, reader); + Str_Read(&_name, reader); } else { @@ -239,7 +224,7 @@ void SaveInfo_Read(SaveInfo *info, Reader *reader) char buf[OLD_NAME_LENGTH]; Reader_Read(reader, buf, OLD_NAME_LENGTH); - Str_Set(&info->name, buf); + Str_Set(&_name, buf); #undef OLD_NAME_LENGTH } @@ -302,7 +287,7 @@ void SaveInfo_Read(SaveInfo *info, Reader *reader) } #endif - info->gameId = Reader_ReadInt32(reader); + _gameId = Reader_ReadInt32(reader); #if __JDOOM__ || __JHERETIC__ // Translate gameMode identifiers from older save versions. @@ -311,21 +296,19 @@ void SaveInfo_Read(SaveInfo *info, Reader *reader) } #if __JHEXEN__ -void SaveInfo_Read_Hx_v9(SaveInfo *info, Reader *reader) +void SaveInfo::read_Hx_v9(Reader *reader) { # define HXS_VERSION_TEXT "HXS Ver " // Do not change me! # define HXS_VERSION_TEXT_LENGTH 16 # define HXS_NAME_LENGTH 24 - DENG_ASSERT(info != 0); - char verText[HXS_VERSION_TEXT_LENGTH]; char nameBuffer[HXS_NAME_LENGTH]; - saveheader_t *hdr = &info->header; + saveheader_t *hdr = &_header; Reader_Read(reader, nameBuffer, HXS_NAME_LENGTH); - Str_Set(&info->name, nameBuffer); + Str_Set(&_name, nameBuffer); Reader_Read(reader, &verText, HXS_VERSION_TEXT_LENGTH); hdr->version = atoi(&verText[8]); @@ -349,10 +332,95 @@ void SaveInfo_Read_Hx_v9(SaveInfo *info, Reader *reader) /// @note Older formats do not contain all needed values: hdr->gameMode = gameMode; // Assume the current mode. - info->gameId = 0; // None. + _gameId = 0; // None. # undef HXS_NAME_LENGTH # undef HXS_VERSION_TEXT_LENGTH # undef HXS_VERSION_TEXT } #endif + +SaveInfo *SaveInfo_New() +{ + return new SaveInfo; +} + +SaveInfo *SaveInfo_Dup(SaveInfo const *other) +{ + DENG_ASSERT(other != 0); + return new SaveInfo(*other); +} + +void SaveInfo_Delete(SaveInfo *info) +{ + if(info) delete info; +} + +SaveInfo *SaveInfo_Copy(SaveInfo *info, SaveInfo const *other) +{ + DENG_ASSERT(info != 0 && other != 0); + *info = *other; + return info; +} + +uint SaveInfo_GameId(SaveInfo const *info) +{ + DENG_ASSERT(info != 0); + return info->gameId(); +} + +void SaveInfo_SetGameId(SaveInfo *info, uint newGameId) +{ + DENG_ASSERT(info != 0); + info->setGameId(newGameId); +} + +saveheader_t const *SaveInfo_Header(SaveInfo const *info) +{ + DENG_ASSERT(info != 0); + return info->header(); +} + +Str const *SaveInfo_Name(SaveInfo const *info) +{ + DENG_ASSERT(info != 0); + return info->name(); +} + +void SaveInfo_SetName(SaveInfo *info, Str const *newName) +{ + DENG_ASSERT(info != 0); + info->setName(newName); +} + +void SaveInfo_Configure(SaveInfo *info) +{ + DENG_ASSERT(info != 0); + info->configure(); +} + +dd_bool SaveInfo_IsLoadable(SaveInfo *info) +{ + DENG_ASSERT(info != 0); + return info->isLoadable(); +} + +void SaveInfo_Write(SaveInfo *info, Writer *writer) +{ + DENG_ASSERT(info != 0); + info->write(writer); +} + +void SaveInfo_Read(SaveInfo *info, Reader *reader) +{ + DENG_ASSERT(info != 0); + info->read(reader); +} + +#if __JHEXEN__ +void SaveInfo_Read_Hx_v9(SaveInfo *info, Reader *reader) +{ + DENG_ASSERT(info != 0); + info->read_Hx_v9(reader); +} +#endif diff --git a/doomsday/plugins/doom/src/p_oldsvg.cpp b/doomsday/plugins/doom/src/p_oldsvg.cpp index 9203d4b73b..972dc760ba 100644 --- a/doomsday/plugins/doom/src/p_oldsvg.cpp +++ b/doomsday/plugins/doom/src/p_oldsvg.cpp @@ -883,12 +883,12 @@ static void SaveInfo_Read_Dm_v19(SaveInfo *info, Reader *reader) { DENG_ASSERT(info != 0); - saveheader_t *hdr = &info->header; + saveheader_t *hdr = &info->_header; char nameBuffer[V19_SAVESTRINGSIZE]; Reader_Read(reader, nameBuffer, V19_SAVESTRINGSIZE); nameBuffer[V19_SAVESTRINGSIZE - 1] = 0; - Str_Set(&info->name, nameBuffer); + Str_Set(&info->_name, nameBuffer); char vcheck[VERSIONSIZE]; Reader_Read(reader, vcheck, VERSIONSIZE); @@ -926,7 +926,7 @@ static void SaveInfo_Read_Dm_v19(SaveInfo *info, Reader *reader) hdr->noMonsters = 0; hdr->respawnMonsters = 0; - info->gameId = 0; // None. + info->_gameId = 0; // None. } static dd_bool SV_OpenFile_Dm_v19(char const *filePath) diff --git a/doomsday/plugins/heretic/src/p_oldsvg.cpp b/doomsday/plugins/heretic/src/p_oldsvg.cpp index 2206e94b60..7bedfd9ee9 100644 --- a/doomsday/plugins/heretic/src/p_oldsvg.cpp +++ b/doomsday/plugins/heretic/src/p_oldsvg.cpp @@ -892,12 +892,12 @@ static void SaveInfo_Read_Hr_v13(SaveInfo *info, Reader *reader) { DENG_ASSERT(info != 0); - saveheader_t *hdr = &info->header; + saveheader_t *hdr = &info->_header; char nameBuffer[V13_SAVESTRINGSIZE]; Reader_Read(reader, nameBuffer, V13_SAVESTRINGSIZE); nameBuffer[V13_SAVESTRINGSIZE - 1] = 0; - Str_Set(&info->name, nameBuffer); + Str_Set(&info->_name, nameBuffer); char vcheck[VERSIONSIZE]; Reader_Read(reader, vcheck, VERSIONSIZE); @@ -932,7 +932,7 @@ static void SaveInfo_Read_Hr_v13(SaveInfo *info, Reader *reader) hdr->noMonsters = 0; hdr->respawnMonsters = 0; - info->gameId = 0; // None. + info->_gameId = 0; // None. } static dd_bool SV_OpenFile_Hr_v13(char const *filePath) From d00a767d1592e9cad8d2bcf9b4a337e2d285738c Mon Sep 17 00:00:00 2001 From: danij Date: Mon, 3 Feb 2014 21:21:05 +0000 Subject: [PATCH 074/106] Refactor|libcommon: Updated save state IO to use SaveInfo's C++ API, directly --- doomsday/plugins/common/include/saveinfo.h | 53 ++++++++------ doomsday/plugins/common/src/g_game.c | 12 +-- doomsday/plugins/common/src/hu_menu.c | 2 +- doomsday/plugins/common/src/p_saveg.cpp | 85 +++++++++++----------- doomsday/plugins/common/src/saveinfo.cpp | 34 ++++----- doomsday/plugins/doom/src/p_oldsvg.cpp | 10 +-- doomsday/plugins/heretic/src/p_oldsvg.cpp | 10 +-- 7 files changed, 107 insertions(+), 99 deletions(-) diff --git a/doomsday/plugins/common/include/saveinfo.h b/doomsday/plugins/common/include/saveinfo.h index 65067c86d2..804f74486f 100644 --- a/doomsday/plugins/common/include/saveinfo.h +++ b/doomsday/plugins/common/include/saveinfo.h @@ -52,7 +52,7 @@ typedef struct saveheader_s { class SaveInfo { public: /// @todo make private: - Str _name; + Str _description; uint _gameId; saveheader_t _header; @@ -66,41 +66,50 @@ class SaveInfo void configure(); /** - * Returns @a true if the game state is compatibile with the current game session - * and @em should be loadable. + * Returns @a true if the game session is compatibile with the current game session + * and @em should therefore be loadable. */ - dd_bool isLoadable(); + bool isLoadable(); + /** + * Returns the logicl version of the serialized game session state. + */ int version() const; + /** + * Returns the textual description of the game session (provided by the user). + */ + Str const *description() const; + void setDescription(Str const *newDesc); + + /** + * @see SV_GenerateGameId() + */ uint gameId() const; void setGameId(uint newGameId); - Str const *name() const; - void setName(Str const *newName); - /** - * Serializes the save info using @a writer. - * - * @param writer Writer instance. + * Serializes the game session info using @a writer. */ void write(Writer *writer) const; /** - * Deserializes the save info using @a reader. - * - * @param reader Reader instance. + * Deserializes the game session info using @a reader. */ void read(Reader *reader); #if __JHEXEN__ /** * @brief libhexen specific version of @ref SaveInfo_Read() for deserializing - * legacy version 9 save state info. + * legacy version 9 game session info. */ void read_Hx_v9(Reader *reader); #endif + /** + * Provides readonly access to the game session header. + * @todo refactor away. + */ saveheader_t const *header() const; }; @@ -121,20 +130,16 @@ void SaveInfo_Delete(SaveInfo *info); SaveInfo *SaveInfo_Copy(SaveInfo *info, SaveInfo const *other); -uint SaveInfo_GameId(SaveInfo const *info); +void SaveInfo_Configure(SaveInfo *info); -saveheader_t const *SaveInfo_Header(SaveInfo const *info); +dd_bool SaveInfo_IsLoadable(SaveInfo *info); -Str const *SaveInfo_Name(SaveInfo const *info); +Str const *SaveInfo_Description(SaveInfo const *info); +void SaveInfo_SetDescription(SaveInfo *info, Str const *newName); +uint SaveInfo_GameId(SaveInfo const *info); void SaveInfo_SetGameId(SaveInfo *info, uint newGameId); -void SaveInfo_SetName(SaveInfo *info, Str const *newName); - -void SaveInfo_Configure(SaveInfo *info); - -dd_bool SaveInfo_IsLoadable(SaveInfo *info); - void SaveInfo_Write(SaveInfo *info, Writer *writer); void SaveInfo_Read(SaveInfo *info, Reader *reader); @@ -143,6 +148,8 @@ void SaveInfo_Read(SaveInfo *info, Reader *reader); void SaveInfo_Read_Hx_v9(SaveInfo *info, Reader *reader); #endif +saveheader_t const *SaveInfo_Header(SaveInfo const *info); + #ifdef __cplusplus } // extern "C" #endif diff --git a/doomsday/plugins/common/src/g_game.c b/doomsday/plugins/common/src/g_game.c index c08fcc8afb..ecbcc32bf7 100644 --- a/doomsday/plugins/common/src/g_game.c +++ b/doomsday/plugins/common/src/g_game.c @@ -2147,7 +2147,7 @@ void G_DoReborn(int plrNum) { // Compose the confirmation message. SaveInfo* info = SV_SaveInfoForSlot(chosenSlot); - AutoStr* msg = Str_Appendf(AutoStr_NewStd(), REBORNLOAD_CONFIRM, Str_Text(SaveInfo_Name(info))); + AutoStr* msg = Str_Appendf(AutoStr_NewStd(), REBORNLOAD_CONFIRM, Str_Text(SaveInfo_Description(info))); S_LocalSound(SFX_REBORNLOAD_CONFIRM, NULL); Hu_MsgStart(MSG_YESNO, Str_Text(msg), rebornLoadConfirmResponse, chosenSlot, 0); } @@ -2929,10 +2929,10 @@ void G_DoSaveGame(void) { // No name specified. SaveInfo* info = SV_SaveInfoForSlot(gaSaveGameSlot); - if(!gaSaveGameGenerateName && !Str_IsEmpty(SaveInfo_Name(info))) + if(!gaSaveGameGenerateName && !Str_IsEmpty(SaveInfo_Description(info))) { // Slot already in use; reuse the existing name. - name = Str_Text(SaveInfo_Name(info)); + name = Str_Text(SaveInfo_Description(info)); } else { @@ -3663,7 +3663,7 @@ D_CMD(LoadGame) info = SV_SaveInfoForSlot(slot); // Compose the confirmation message. - msg = Str_Appendf(AutoStr_NewStd(), QLPROMPT, Str_Text(SaveInfo_Name(info))); + msg = Str_Appendf(AutoStr_NewStd(), QLPROMPT, Str_Text(SaveInfo_Description(info))); S_LocalSound(SFX_QUICKLOAD_PROMPT, NULL); Hu_MsgStart(MSG_YESNO, Str_Text(msg), loadGameConfirmResponse, slot, 0); @@ -3762,7 +3762,7 @@ D_CMD(SaveGame) } // Compose the confirmation message. - msg = Str_Appendf(AutoStr_NewStd(), QSPROMPT, Str_Text(SaveInfo_Name(info))); + msg = Str_Appendf(AutoStr_NewStd(), QSPROMPT, Str_Text(SaveInfo_Description(info))); // Make a copy of the name. name = Str_Copy(Str_New(), &localName); @@ -3856,7 +3856,7 @@ D_CMD(DeleteGameSave) { // Compose the confirmation message. SaveInfo* info = SV_SaveInfoForSlot(slot); - AutoStr* msg = Str_Appendf(AutoStr_NewStd(), DELETESAVEGAME_CONFIRM, Str_Text(SaveInfo_Name(info))); + AutoStr* msg = Str_Appendf(AutoStr_NewStd(), DELETESAVEGAME_CONFIRM, Str_Text(SaveInfo_Description(info))); S_LocalSound(SFX_DELETESAVEGAME_CONFIRM, NULL); Hu_MsgStart(MSG_YESNO, Str_Text(msg), deleteSaveGameConfirmResponse, slot, 0); } diff --git a/doomsday/plugins/common/src/hu_menu.c b/doomsday/plugins/common/src/hu_menu.c index 79b3ad43ac..ce90e861bd 100644 --- a/doomsday/plugins/common/src/hu_menu.c +++ b/doomsday/plugins/common/src/hu_menu.c @@ -5662,7 +5662,7 @@ void Hu_MenuUpdateGameSaveWidgets(void) if(SV_IsSlotUsed(edit->data2)) { SaveInfo* info = SV_SaveInfoForSlot(edit->data2); - text = Str_Text(SaveInfo_Name(info)); + text = Str_Text(SaveInfo_Description(info)); MNObject_SetFlags(obj, FO_CLEAR, MNF_DISABLED); } MNEdit_SetText(obj, MNEDIT_STF_NO_ACTION, text); diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index db621f9cc8..96e6187088 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -439,24 +439,24 @@ static void clearSaveInfo() { for(int i = 0; i < NUMSAVESLOTS; ++i) { - SaveInfo_Delete(saveInfo[i]); + delete saveInfo[i]; } M_Free(saveInfo); saveInfo = 0; } if(autoSaveInfo) { - SaveInfo_Delete(autoSaveInfo); autoSaveInfo = 0; + delete autoSaveInfo; autoSaveInfo = 0; } #if __JHEXEN__ if(baseSaveInfo) { - SaveInfo_Delete(baseSaveInfo); baseSaveInfo = 0; + delete baseSaveInfo; baseSaveInfo = 0; } #endif if(nullSaveInfo) { - SaveInfo_Delete(nullSaveInfo); nullSaveInfo = 0; + delete nullSaveInfo; nullSaveInfo = 0; } } @@ -468,8 +468,8 @@ static void updateSaveInfo(Str const *path, SaveInfo *info) { // The save path cannot be accessed for some reason. Perhaps its a // network path? Clear the info for this slot. - SaveInfo_SetName(info, 0); - SaveInfo_SetGameId(info, 0); + info->setDescription(0); + info->setGameId(0); return; } @@ -477,15 +477,15 @@ static void updateSaveInfo(Str const *path, SaveInfo *info) if(!recogniseGameState(path, info)) { // Clear the info for this slot. - SaveInfo_SetName(info, 0); - SaveInfo_SetGameId(info, 0); + info->setDescription(0); + info->setGameId(0); return; } // Ensure we have a valid name. - if(Str_IsEmpty(SaveInfo_Name(info))) + if(Str_IsEmpty(info->description())) { - SaveInfo_SetName(info, AutoStr_FromText("UNNAMED")); + info->setDescription(AutoStr_FromText("UNNAMED")); } } @@ -502,13 +502,13 @@ static void buildSaveInfo() // Initialize. for(int i = 0; i < NUMSAVESLOTS; ++i) { - saveInfo[i] = SaveInfo_New(); + saveInfo[i] = new SaveInfo; } - autoSaveInfo = SaveInfo_New(); + autoSaveInfo = new SaveInfo; #if __JHEXEN__ - baseSaveInfo = SaveInfo_New(); + baseSaveInfo = new SaveInfo; #endif - nullSaveInfo = SaveInfo_New(); + nullSaveInfo = new SaveInfo; } /// Scan the save paths and populate the list. @@ -566,7 +566,7 @@ static void replaceSaveInfo(int slot, SaveInfo *newInfo) destAdr = &saveInfo[slot]; } - if(*destAdr) SaveInfo_Delete(*destAdr); + if(*destAdr) delete (*destAdr); *destAdr = newInfo; } @@ -650,12 +650,12 @@ static void SV_SaveInfo_Read(SaveInfo *info, Reader *reader) ( IS_NETWORK_CLIENT && magic != MY_CLIENT_SAVE_MAGIC)) { // Perhaps the old v9 format? - SaveInfo_Read_Hx_v9(info, reader); + info->read_Hx_v9(reader); } else #endif { - SaveInfo_Read(info, reader); + info->read(reader); } } @@ -794,7 +794,7 @@ int SV_SlotForSaveName(char const *name) do { SaveInfo *info = saveInfo[i]; - if(!Str_CompareIgnoreCase(SaveInfo_Name(info), name)) + if(!Str_CompareIgnoreCase(info->description(), name)) { // This is the one! saveSlot = i; @@ -809,8 +809,7 @@ dd_bool SV_IsSlotUsed(int slot) DENG_ASSERT(inited); if(SV_ExistingFile(composeGameSavePathForSlot(slot))) { - SaveInfo *info = SV_SaveInfoForSlot(slot); - return SaveInfo_IsLoadable(info); + return SV_SaveInfoForSlot(slot)->isLoadable(); } return false; } @@ -856,7 +855,9 @@ void SV_CopySlot(int sourceSlot, int destSlot) SV_CopyFile(src, dst); // Copy saveinfo too. - replaceSaveInfo(destSlot, SaveInfo_Dup(findSaveInfoForSlot(sourceSlot))); + SaveInfo *info = findSaveInfoForSlot(sourceSlot); + DENG_ASSERT(info != 0); + replaceSaveInfo(destSlot, new SaveInfo(*info)); } #if __JHEXEN__ @@ -3660,15 +3661,15 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) // Read the header again. /// @todo Seek past the header straight to the game state. { - SaveInfo *tmp = SaveInfo_New(); + SaveInfo *tmp = new SaveInfo; SV_SaveInfo_Read(tmp, reader); - SaveInfo_Delete(tmp); + delete tmp; } /* * Configure global game state: */ - hdr = SaveInfo_Header(saveInfo); + hdr = saveInfo->header(); gameEpisode = hdr->episode - 1; gameMap = hdr->map - 1; @@ -3810,7 +3811,7 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) #if !__JHEXEN__ // In netgames, the server tells the clients about this. - NetSv_LoadGame(SaveInfo_GameId(saveInfo)); + NetSv_LoadGame(saveInfo->gameId()); #endif Reader_Delete(reader); @@ -3849,7 +3850,7 @@ static int loadStateWorker(Str const *path, SaveInfo &saveInfo) */ // Material origin scrollers must be re-spawned for older save state versions. - saveheader_t const *hdr = SaveInfo_Header(&saveInfo); + saveheader_t const *hdr = saveInfo.header(); /// @todo Implement SaveInfo format type identifiers. if((hdr->magic != (IS_NETWORK_CLIENT? MY_CLIENT_SAVE_MAGIC : MY_SAVE_MAGIC)) || @@ -3941,12 +3942,12 @@ void SV_SaveGameClient(uint gameId) } // Prepare the header. - saveInfo = SaveInfo_New(); - SaveInfo_SetGameId(saveInfo, gameId); - SaveInfo_Configure(saveInfo); + saveInfo = new SaveInfo; + saveInfo->setGameId(gameId); + saveInfo->configure(); Writer *writer = SV_NewWriter(); - SaveInfo_Write(saveInfo, writer); + saveInfo->write(writer); // Some important information. // Our position and look angles. @@ -3970,7 +3971,7 @@ void SV_SaveGameClient(uint gameId) SV_CloseFile(); Writer_Delete(writer); - SaveInfo_Delete(saveInfo); + delete saveInfo; #else DENG_UNUSED(gameId); #endif @@ -3998,15 +3999,15 @@ void SV_LoadGameClient(uint gameId) return; } - saveInfo = SaveInfo_New(); + saveInfo = new SaveInfo; Reader *reader = SV_NewReader(); SV_SaveInfo_Read(saveInfo, reader); - hdr = SaveInfo_Header(saveInfo); + hdr = saveInfo->header(); if(hdr->magic != MY_CLIENT_SAVE_MAGIC) { Reader_Delete(reader); - SaveInfo_Delete(saveInfo); + delete saveInfo; SV_CloseFile(); App_Log(DE2_RES_ERROR, "Client save file format not recognized"); return; @@ -4055,7 +4056,7 @@ void SV_LoadGameClient(uint gameId) SV_CloseFile(); Reader_Delete(reader); - SaveInfo_Delete(saveInfo); + delete saveInfo; #else DENG_UNUSED(gameId); #endif @@ -4098,7 +4099,7 @@ static int saveStateWorker(Str const *path, SaveInfo *saveInfo) // In networked games the server tells the clients to save their games. #if !__JHEXEN__ - NetSv_SaveGame(SaveInfo_GameId(saveInfo)); + NetSv_SaveGame(saveInfo->gameId()); #endif if(!openGameSaveFile(path, true)) @@ -4112,7 +4113,7 @@ static int saveStateWorker(Str const *path, SaveInfo *saveInfo) * Write the game session header. */ Writer *writer = SV_NewWriter(); - SaveInfo_Write(saveInfo, writer); + saveInfo->write(writer); #if __JHEXEN__ Game_ACScriptInterpreter().writeWorldScriptData(writer); @@ -4169,10 +4170,10 @@ static int saveStateWorker(Str const *path, SaveInfo *saveInfo) static SaveInfo *createSaveInfo(char const *name) { ddstring_t nameStr; - SaveInfo *info = SaveInfo_New(); - SaveInfo_SetName(info, Str_InitStatic(&nameStr, name)); - SaveInfo_SetGameId(info, SV_GenerateGameId()); - SaveInfo_Configure(info); + SaveInfo *info = new SaveInfo; + info->setDescription(Str_InitStatic(&nameStr, name)); + info->setGameId(SV_GenerateGameId()); + info->configure(); return info; } @@ -4224,7 +4225,7 @@ dd_bool SV_SaveGame(int slot, char const *name) else { // We no longer need the info. - SaveInfo_Delete(info); + delete info; if(saveError == SV_INVALIDFILENAME) { diff --git a/doomsday/plugins/common/src/saveinfo.cpp b/doomsday/plugins/common/src/saveinfo.cpp index ba11927604..f0b2d32f2b 100644 --- a/doomsday/plugins/common/src/saveinfo.cpp +++ b/doomsday/plugins/common/src/saveinfo.cpp @@ -31,25 +31,25 @@ SaveInfo::SaveInfo() : _gameId(0) { - Str_InitStd(&_name); + Str_InitStd(&_description); memset(&_header, 0, sizeof(_header)); } SaveInfo::SaveInfo(SaveInfo const &other) : _gameId(other._gameId) { - Str_Copy(Str_InitStd(&_name), &other._name); + Str_Copy(Str_InitStd(&_description), &other._description); std::memcpy(&_header, &other._header, sizeof(_header)); } SaveInfo::~SaveInfo() { - Str_Free(&_name); + Str_Free(&_description); } SaveInfo &SaveInfo::operator = (SaveInfo const &other) { - Str_Copy(&_name, &other._name); + Str_Copy(&_description, &other._description); _gameId = other._gameId; std::memcpy(&_header, &other._header, sizeof(_header)); return *this; @@ -70,14 +70,14 @@ void SaveInfo::setGameId(uint newGameId) _gameId = newGameId; } -Str const *SaveInfo::name() const +Str const *SaveInfo::description() const { - return &_name; + return &_description; } -void SaveInfo::setName(Str const *newName) +void SaveInfo::setDescription(Str const *newName) { - Str_CopyOrClear(&_name, newName); + Str_CopyOrClear(&_description, newName); } saveheader_t const *SaveInfo::header() const @@ -122,7 +122,7 @@ void SaveInfo::configure() #endif } -dd_bool SaveInfo::isLoadable() +bool SaveInfo::isLoadable() { // Game Mode missmatch? if(_header.gameMode != gameMode) return false; @@ -138,7 +138,7 @@ void SaveInfo::write(Writer *writer) const Writer_WriteInt32(writer, hdr->magic); Writer_WriteInt32(writer, hdr->version); Writer_WriteInt32(writer, hdr->gameMode); - Str_Write(&_name, writer); + Str_Write(&_description, writer); Writer_WriteByte(writer, hdr->skill & 0x7f); Writer_WriteByte(writer, hdr->episode); @@ -215,7 +215,7 @@ void SaveInfo::read(Reader *reader) if(hdr->version >= 10) { - Str_Read(&_name, reader); + Str_Read(&_description, reader); } else { @@ -224,7 +224,7 @@ void SaveInfo::read(Reader *reader) char buf[OLD_NAME_LENGTH]; Reader_Read(reader, buf, OLD_NAME_LENGTH); - Str_Set(&_name, buf); + Str_Set(&_description, buf); #undef OLD_NAME_LENGTH } @@ -308,7 +308,7 @@ void SaveInfo::read_Hx_v9(Reader *reader) saveheader_t *hdr = &_header; Reader_Read(reader, nameBuffer, HXS_NAME_LENGTH); - Str_Set(&_name, nameBuffer); + Str_Set(&_description, nameBuffer); Reader_Read(reader, &verText, HXS_VERSION_TEXT_LENGTH); hdr->version = atoi(&verText[8]); @@ -381,16 +381,16 @@ saveheader_t const *SaveInfo_Header(SaveInfo const *info) return info->header(); } -Str const *SaveInfo_Name(SaveInfo const *info) +Str const *SaveInfo_Description(SaveInfo const *info) { DENG_ASSERT(info != 0); - return info->name(); + return info->description(); } -void SaveInfo_SetName(SaveInfo *info, Str const *newName) +void SaveInfo_SetDescription(SaveInfo *info, Str const *newName) { DENG_ASSERT(info != 0); - info->setName(newName); + info->setDescription(newName); } void SaveInfo_Configure(SaveInfo *info) diff --git a/doomsday/plugins/doom/src/p_oldsvg.cpp b/doomsday/plugins/doom/src/p_oldsvg.cpp index 972dc760ba..7b99144f07 100644 --- a/doomsday/plugins/doom/src/p_oldsvg.cpp +++ b/doomsday/plugins/doom/src/p_oldsvg.cpp @@ -837,12 +837,12 @@ int SV_LoadState_Dm_v19(Str const *path, SaveInfo *info) // Read the header again. /// @todo Seek past the header straight to the game state. { - SaveInfo *tmp = SaveInfo_New(); + SaveInfo *tmp = new SaveInfo; SaveInfo_Read_Dm_v19(tmp, svReader); - SaveInfo_Delete(tmp); + delete tmp; } - saveheader_t const *hdr = SaveInfo_Header(info); + saveheader_t const *hdr = info->header(); gameSkill = hdr->skill; gameEpisode = hdr->episode; @@ -888,7 +888,7 @@ static void SaveInfo_Read_Dm_v19(SaveInfo *info, Reader *reader) char nameBuffer[V19_SAVESTRINGSIZE]; Reader_Read(reader, nameBuffer, V19_SAVESTRINGSIZE); nameBuffer[V19_SAVESTRINGSIZE - 1] = 0; - Str_Set(&info->_name, nameBuffer); + Str_Set(&info->_description, nameBuffer); char vcheck[VERSIONSIZE]; Reader_Read(reader, vcheck, VERSIONSIZE); @@ -974,7 +974,7 @@ dd_bool SV_RecogniseState_Dm_v19(Str const *path, SaveInfo *info) if(strncmp(vcheck, "version ", 8))*/ { SaveInfo_Read_Dm_v19(info, svReader); - result = (SaveInfo_Header(info)->version <= V19_SAVE_VERSION); + result = (info->version() <= V19_SAVE_VERSION); } Reader_Delete(svReader); svReader = 0; diff --git a/doomsday/plugins/heretic/src/p_oldsvg.cpp b/doomsday/plugins/heretic/src/p_oldsvg.cpp index 7bedfd9ee9..8e4f89c6b4 100644 --- a/doomsday/plugins/heretic/src/p_oldsvg.cpp +++ b/doomsday/plugins/heretic/src/p_oldsvg.cpp @@ -846,12 +846,12 @@ int SV_LoadState_Hr_v13(Str const *path, SaveInfo *info) // Read the header again. /// @todo Seek past the header straight to the game state. { - SaveInfo *tmp = SaveInfo_New(); + SaveInfo *tmp = new SaveInfo; SaveInfo_Read_Hr_v13(tmp, svReader); - SaveInfo_Delete(tmp); + delete tmp; } - saveheader_t const *hdr = SaveInfo_Header(info); + saveheader_t const *hdr = info->header(); gameSkill = hdr->skill; gameEpisode = hdr->episode; @@ -897,7 +897,7 @@ static void SaveInfo_Read_Hr_v13(SaveInfo *info, Reader *reader) char nameBuffer[V13_SAVESTRINGSIZE]; Reader_Read(reader, nameBuffer, V13_SAVESTRINGSIZE); nameBuffer[V13_SAVESTRINGSIZE - 1] = 0; - Str_Set(&info->_name, nameBuffer); + Str_Set(&info->_description, nameBuffer); char vcheck[VERSIONSIZE]; Reader_Read(reader, vcheck, VERSIONSIZE); @@ -980,7 +980,7 @@ dd_bool SV_RecogniseState_Hr_v13(Str const *path, SaveInfo *info) if(strncmp(vcheck, "version ", 8))*/ { SaveInfo_Read_Hr_v13(info, svReader); - result = (SaveInfo_Header(info)->version == V13_SAVE_VERSION); + result = (info->version() == V13_SAVE_VERSION); } Reader_Delete(svReader); svReader = 0; From f477cd2762c06165acb3b1b767d2b1fa6760edfa Mon Sep 17 00:00:00 2001 From: danij Date: Mon, 3 Feb 2014 21:55:36 +0000 Subject: [PATCH 075/106] Refactor|SaveInfo|libcommon: Group values comprising the saved ruleset for the game session --- doomsday/plugins/common/include/saveinfo.h | 29 +++-- doomsday/plugins/common/src/p_saveg.cpp | 44 ++++--- doomsday/plugins/common/src/saveinfo.cpp | 126 ++++++++++++--------- doomsday/plugins/doom/src/p_oldsvg.cpp | 11 +- doomsday/plugins/heretic/src/p_oldsvg.cpp | 11 +- 5 files changed, 126 insertions(+), 95 deletions(-) diff --git a/doomsday/plugins/common/include/saveinfo.h b/doomsday/plugins/common/include/saveinfo.h index 804f74486f..d37e829581 100644 --- a/doomsday/plugins/common/include/saveinfo.h +++ b/doomsday/plugins/common/include/saveinfo.h @@ -1,4 +1,4 @@ -/** @file saveinfo.h Save state info. +/** @file saveinfo.h Saved game session info. * * @authors Copyright © 2003-2013 Jaakko Keränen * @authors Copyright © 2005-2013 Daniel Swanson @@ -24,22 +24,28 @@ #include "doomsday.h" #include "common.h" -typedef struct saveheader_s { - int magic; - int version; - gamemode_t gameMode; +typedef struct gamerules_s { skillmode_t skill; #if !__JHEXEN__ byte fast; #endif - byte episode; - byte map; byte deathmatch; byte noMonsters; #if __JHEXEN__ byte randomClasses; #else byte respawnMonsters; +#endif +} gamerules_t; + +typedef struct saveheader_s { + int magic; + int version; + gamemode_t gameMode; + gamerules_t gameRules; + byte episode; + byte map; +#if !__JHEXEN__ int mapTime; byte players[MAXPLAYERS]; #endif @@ -72,9 +78,10 @@ class SaveInfo bool isLoadable(); /** - * Returns the logicl version of the serialized game session state. + * Returns the logical version of the serialized game session state. */ int version() const; + int magic() const; /** * Returns the textual description of the game session (provided by the user). @@ -88,6 +95,10 @@ class SaveInfo uint gameId() const; void setGameId(uint newGameId); + uint episode() const; + uint map() const; + gamerules_t const &gameRules() const; + /** * Serializes the game session info using @a writer. */ @@ -130,8 +141,6 @@ void SaveInfo_Delete(SaveInfo *info); SaveInfo *SaveInfo_Copy(SaveInfo *info, SaveInfo const *other); -void SaveInfo_Configure(SaveInfo *info); - dd_bool SaveInfo_IsLoadable(SaveInfo *info); Str const *SaveInfo_Description(SaveInfo const *info); diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index 96e6187088..10fee7cd48 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -689,8 +689,7 @@ static bool recogniseNativeState(Str const *path, SaveInfo *info) #endif // Magic must match. - saveheader_t const *hdr = &info->_header; - if(hdr->magic != MY_SAVE_MAGIC && hdr->magic != MY_CLIENT_SAVE_MAGIC) + if(info->magic() != MY_SAVE_MAGIC && info->magic() != MY_CLIENT_SAVE_MAGIC) { return false; } @@ -698,7 +697,7 @@ static bool recogniseNativeState(Str const *path, SaveInfo *info) /* * Check for unsupported versions. */ - if(hdr->version > MY_SAVE_VERSION) // Future version? + if(info->version() > MY_SAVE_VERSION) // Future version? { return false; } @@ -706,7 +705,7 @@ static bool recogniseNativeState(Str const *path, SaveInfo *info) #if __JHEXEN__ // We are incompatible with v3 saves due to an invalid test used to determine // present sides (ver3 format's sides contain chunks of junk data). - if(hdr->version == 3) + if(info->version() == 3) { return false; } @@ -3671,22 +3670,21 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) */ hdr = saveInfo->header(); - gameEpisode = hdr->episode - 1; - gameMap = hdr->map - 1; + gameEpisode = saveInfo->episode(); + gameMap = saveInfo->map(); // Apply the game rules: -#if __JHEXEN__ - gameSkill = hdr->skill; -#else - gameSkill = hdr->skill; - fastParm = hdr->fast; + gamerules_t const &newRules = saveInfo->gameRules(); + gameSkill = newRules.skill; +#if !__JHEXEN__ + fastParm = newRules.fast; #endif - deathmatch = hdr->deathmatch; - noMonstersParm = hdr->noMonsters; + deathmatch = newRules.deathmatch; + noMonstersParm = newRules.noMonsters; #if __JHEXEN__ - randomClassParm = hdr->randomClasses; + randomClassParm = newRules.randomClasses; #else - respawnMonsters = hdr->respawnMonsters; + respawnMonsters = newRules.respawnMonsters; #endif #if __JHEXEN__ @@ -3850,11 +3848,9 @@ static int loadStateWorker(Str const *path, SaveInfo &saveInfo) */ // Material origin scrollers must be re-spawned for older save state versions. - saveheader_t const *hdr = saveInfo.header(); - /// @todo Implement SaveInfo format type identifiers. - if((hdr->magic != (IS_NETWORK_CLIENT? MY_CLIENT_SAVE_MAGIC : MY_SAVE_MAGIC)) || - hdr->version <= 10) + if((saveInfo.magic() != (IS_NETWORK_CLIENT? MY_CLIENT_SAVE_MAGIC : MY_SAVE_MAGIC)) || + saveInfo.version() <= 10) { P_SpawnAllMaterialOriginScrollers(); } @@ -4013,10 +4009,12 @@ void SV_LoadGameClient(uint gameId) return; } - gameSkill = skillmode_t( hdr->skill ); - deathmatch = hdr->deathmatch; - noMonstersParm = hdr->noMonsters; - respawnMonsters = hdr->respawnMonsters; + gamerules_t const &newRules = saveInfo->gameRules(); + gameSkill = skillmode_t( newRules.skill ); + deathmatch = newRules.deathmatch; + noMonstersParm = newRules.noMonsters; + respawnMonsters = newRules.respawnMonsters; + // Do we need to change the map? if(gameMap != (unsigned) (hdr->map - 1) || gameEpisode != (unsigned) (hdr->episode - 1)) { diff --git a/doomsday/plugins/common/src/saveinfo.cpp b/doomsday/plugins/common/src/saveinfo.cpp index f0b2d32f2b..b1d28c2134 100644 --- a/doomsday/plugins/common/src/saveinfo.cpp +++ b/doomsday/plugins/common/src/saveinfo.cpp @@ -1,4 +1,4 @@ -/** @file saveinfo.cpp Save state info. +/** @file saveinfo.cpp Saved game session info. * * @authors Copyright © 2003-2013 Jaakko Keränen * @authors Copyright © 2005-2013 Daniel Swanson @@ -60,6 +60,21 @@ int SaveInfo::version() const return _header.version; } +int SaveInfo::magic() const +{ + return _header.magic; +} + +Str const *SaveInfo::description() const +{ + return &_description; +} + +void SaveInfo::setDescription(Str const *newName) +{ + Str_CopyOrClear(&_description, newName); +} + uint SaveInfo::gameId() const { return _gameId; @@ -70,14 +85,19 @@ void SaveInfo::setGameId(uint newGameId) _gameId = newGameId; } -Str const *SaveInfo::description() const +uint SaveInfo::episode() const { - return &_description; + return _header.episode - 1; } -void SaveInfo::setDescription(Str const *newName) +uint SaveInfo::map() const { - Str_CopyOrClear(&_description, newName); + return _header.map - 1; +} + +gamerules_t const &SaveInfo::gameRules() const +{ + return _header.gameRules; } saveheader_t const *SaveInfo::header() const @@ -99,20 +119,24 @@ void SaveInfo::configure() #else hdr->episode = gameEpisode+1; #endif + #if __JHEXEN__ - hdr->skill = gameSkill; - hdr->randomClasses = randomClassParm; + hdr->gameRules.skill = gameSkill; + hdr->gameRules.randomClasses = randomClassParm; #else - hdr->skill = gameSkill; - hdr->fast = fastParm; + hdr->gameRules.skill = gameSkill; + hdr->gameRules.fast = fastParm; #endif - hdr->deathmatch = deathmatch; - hdr->noMonsters = noMonstersParm; + hdr->gameRules.deathmatch = deathmatch; + hdr->gameRules.noMonsters = noMonstersParm; #if __JHEXEN__ - hdr->randomClasses = randomClassParm; + hdr->gameRules.randomClasses = randomClassParm; #else - hdr->respawnMonsters = respawnMonsters; + hdr->gameRules.respawnMonsters = respawnMonsters; +#endif + +#if !__JHEXEN__ hdr->mapTime = mapTime; for(int i = 0; i < MAXPLAYERS; i++) @@ -140,18 +164,21 @@ void SaveInfo::write(Writer *writer) const Writer_WriteInt32(writer, hdr->gameMode); Str_Write(&_description, writer); - Writer_WriteByte(writer, hdr->skill & 0x7f); + Writer_WriteByte(writer, hdr->gameRules.skill & 0x7f); Writer_WriteByte(writer, hdr->episode); Writer_WriteByte(writer, hdr->map); - Writer_WriteByte(writer, hdr->deathmatch); + Writer_WriteByte(writer, hdr->gameRules.deathmatch); #if !__JHEXEN__ - Writer_WriteByte(writer, hdr->fast); + Writer_WriteByte(writer, hdr->gameRules.fast); #endif - Writer_WriteByte(writer, hdr->noMonsters); + Writer_WriteByte(writer, hdr->gameRules.noMonsters); #if __JHEXEN__ - Writer_WriteByte(writer, hdr->randomClasses); + Writer_WriteByte(writer, hdr->gameRules.randomClasses); #else - Writer_WriteByte(writer, hdr->respawnMonsters); + Writer_WriteByte(writer, hdr->gameRules.respawnMonsters); +#endif + +#if !__JHEXEN__ Writer_WriteInt32(writer, hdr->mapTime); for(int i = 0; i < MAXPLAYERS; ++i) @@ -240,41 +267,44 @@ void SaveInfo::read(Reader *reader) // by default this means "spawn no things" and if so then the "fast" game // rule is meaningless so it is forced off. byte skillModePlusFastBit = Reader_ReadByte(reader); - hdr->skill = (skillmode_t) (skillModePlusFastBit & 0x7f); - if(hdr->skill < SM_BABY || hdr->skill >= NUM_SKILL_MODES) + hdr->gameRules.skill = (skillmode_t) (skillModePlusFastBit & 0x7f); + if(hdr->gameRules.skill < SM_BABY || hdr->gameRules.skill >= NUM_SKILL_MODES) { - hdr->skill = SM_NOTHINGS; - hdr->fast = 0; + hdr->gameRules.skill = SM_NOTHINGS; + hdr->gameRules.fast = 0; } else { - hdr->fast = (skillModePlusFastBit & 0x80) != 0; + hdr->gameRules.fast = (skillModePlusFastBit & 0x80) != 0; } } else #endif { - hdr->skill = skillmode_t( Reader_ReadByte(reader) & 0x7f ); + hdr->gameRules.skill = skillmode_t( Reader_ReadByte(reader) & 0x7f ); // Interpret skill levels outside the normal range as "spawn no things". - if(hdr->skill < SM_BABY || hdr->skill >= NUM_SKILL_MODES) - hdr->skill = SM_NOTHINGS; + if(hdr->gameRules.skill < SM_BABY || hdr->gameRules.skill >= NUM_SKILL_MODES) + { + hdr->gameRules.skill = SM_NOTHINGS; + } } hdr->episode = Reader_ReadByte(reader); hdr->map = Reader_ReadByte(reader); - hdr->deathmatch = Reader_ReadByte(reader); + + hdr->gameRules.deathmatch = Reader_ReadByte(reader); #if !__JHEXEN__ if(hdr->version >= 13) - hdr->fast = Reader_ReadByte(reader); + hdr->gameRules.fast = Reader_ReadByte(reader); #endif - hdr->noMonsters = Reader_ReadByte(reader); + hdr->gameRules.noMonsters = Reader_ReadByte(reader); #if __JHEXEN__ - hdr->randomClasses = Reader_ReadByte(reader); + hdr->gameRules.randomClasses = Reader_ReadByte(reader); #endif #if !__JHEXEN__ - hdr->respawnMonsters = Reader_ReadByte(reader); + hdr->gameRules.respawnMonsters = Reader_ReadByte(reader); // Older formats serialize the unpacked saveheader_t struct; skip the junk values (alignment). if(hdr->version < 10) SV_Seek(2); @@ -311,26 +341,24 @@ void SaveInfo::read_Hx_v9(Reader *reader) Str_Set(&_description, nameBuffer); Reader_Read(reader, &verText, HXS_VERSION_TEXT_LENGTH); - hdr->version = atoi(&verText[8]); + hdr->version = atoi(&verText[8]); /*Skip junk*/ SV_Seek(4); - hdr->episode = 1; - hdr->map = Reader_ReadByte(reader); - hdr->skill = (skillmode_t) (Reader_ReadByte(reader) & 0x7f); + hdr->episode = 1; + hdr->map = Reader_ReadByte(reader); + hdr->magic = MY_SAVE_MAGIC; // Lets pretend... + hdr->gameMode = gameMode; // Assume the current mode. - // Interpret skill modes outside the normal range as "spawn no things". - if(hdr->skill < SM_BABY || hdr->skill >= NUM_SKILL_MODES) - hdr->skill = SM_NOTHINGS; + hdr->gameRules.skill = (skillmode_t) (Reader_ReadByte(reader) & 0x7f); - hdr->deathmatch = Reader_ReadByte(reader); - hdr->noMonsters = Reader_ReadByte(reader); - hdr->randomClasses = Reader_ReadByte(reader); - - hdr->magic = MY_SAVE_MAGIC; // Lets pretend... + // Interpret skill modes outside the normal range as "spawn no things". + if(hdr->gameRules.skill < SM_BABY || hdr->gameRules.skill >= NUM_SKILL_MODES) + hdr->gameRules.skill = SM_NOTHINGS; - /// @note Older formats do not contain all needed values: - hdr->gameMode = gameMode; // Assume the current mode. + hdr->gameRules.deathmatch = Reader_ReadByte(reader); + hdr->gameRules.noMonsters = Reader_ReadByte(reader); + hdr->gameRules.randomClasses = Reader_ReadByte(reader); _gameId = 0; // None. @@ -393,12 +421,6 @@ void SaveInfo_SetDescription(SaveInfo *info, Str const *newName) info->setDescription(newName); } -void SaveInfo_Configure(SaveInfo *info) -{ - DENG_ASSERT(info != 0); - info->configure(); -} - dd_bool SaveInfo_IsLoadable(SaveInfo *info) { DENG_ASSERT(info != 0); diff --git a/doomsday/plugins/doom/src/p_oldsvg.cpp b/doomsday/plugins/doom/src/p_oldsvg.cpp index 7b99144f07..e78f4ed45d 100644 --- a/doomsday/plugins/doom/src/p_oldsvg.cpp +++ b/doomsday/plugins/doom/src/p_oldsvg.cpp @@ -842,11 +842,11 @@ int SV_LoadState_Dm_v19(Str const *path, SaveInfo *info) delete tmp; } - saveheader_t const *hdr = info->header(); + saveheader_t const &hdr = info->_header; - gameSkill = hdr->skill; - gameEpisode = hdr->episode; - gameMap = hdr->map; + gameSkill = hdr.skill; + gameEpisode = hdr.episode; + gameMap = hdr.map; gameMapEntryPoint = 0; // We don't want to see a briefing if we're loading a save game. @@ -858,7 +858,8 @@ int SV_LoadState_Dm_v19(Str const *path, SaveInfo *info) G_SetGameAction(GA_NONE); // Recreate map state. - mapTime = hdr->mapTime; + mapTime = hdr.mapTime; + P_v19_UnArchivePlayers(); P_v19_UnArchiveWorld(); P_v19_UnArchiveThinkers(); diff --git a/doomsday/plugins/heretic/src/p_oldsvg.cpp b/doomsday/plugins/heretic/src/p_oldsvg.cpp index 8e4f89c6b4..22c06e8013 100644 --- a/doomsday/plugins/heretic/src/p_oldsvg.cpp +++ b/doomsday/plugins/heretic/src/p_oldsvg.cpp @@ -851,11 +851,11 @@ int SV_LoadState_Hr_v13(Str const *path, SaveInfo *info) delete tmp; } - saveheader_t const *hdr = info->header(); + saveheader_t const &hdr = info->_header; - gameSkill = hdr->skill; - gameEpisode = hdr->episode; - gameMap = hdr->map; + gameSkill = hdr.skill; + gameEpisode = hdr.episode; + gameMap = hdr.map; gameMapEntryPoint = 0; // We don't want to see a briefing if we're loading a save game. @@ -867,7 +867,8 @@ int SV_LoadState_Hr_v13(Str const *path, SaveInfo *info) G_SetGameAction(GA_NONE); // Recreate map state. - mapTime = hdr->mapTime; + mapTime = hdr.mapTime; + P_v13_UnArchivePlayers(); P_v13_UnArchiveWorld(); P_v13_UnArchiveThinkers(); From 570bd2e86678504e7b80d78a583136bbd3b59c37 Mon Sep 17 00:00:00 2001 From: danij Date: Mon, 3 Feb 2014 22:13:21 +0000 Subject: [PATCH 076/106] SaveInfo|libcommon: Encapsulate saveheader_t within SaveInfo --- doomsday/plugins/common/include/saveinfo.h | 11 ++------ doomsday/plugins/common/src/p_saveg.cpp | 32 +++++++++++----------- doomsday/plugins/common/src/saveinfo.cpp | 18 +++++------- doomsday/plugins/doom/src/p_oldsvg.cpp | 29 ++++++++++---------- doomsday/plugins/heretic/src/p_oldsvg.cpp | 29 ++++++++++---------- 5 files changed, 56 insertions(+), 63 deletions(-) diff --git a/doomsday/plugins/common/include/saveinfo.h b/doomsday/plugins/common/include/saveinfo.h index d37e829581..b6d0395b59 100644 --- a/doomsday/plugins/common/include/saveinfo.h +++ b/doomsday/plugins/common/include/saveinfo.h @@ -97,6 +97,9 @@ class SaveInfo uint episode() const; uint map() const; +#if !__JHEXEN__ + int mapTime() const; +#endif gamerules_t const &gameRules() const; /** @@ -116,12 +119,6 @@ class SaveInfo */ void read_Hx_v9(Reader *reader); #endif - - /** - * Provides readonly access to the game session header. - * @todo refactor away. - */ - saveheader_t const *header() const; }; #endif // __cplusplus @@ -157,8 +154,6 @@ void SaveInfo_Read(SaveInfo *info, Reader *reader); void SaveInfo_Read_Hx_v9(SaveInfo *info, Reader *reader); #endif -saveheader_t const *SaveInfo_Header(SaveInfo const *info); - #ifdef __cplusplus } // extern "C" #endif diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index 10fee7cd48..d116162fd5 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -3668,7 +3668,7 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) /* * Configure global game state: */ - hdr = saveInfo->header(); + hdr = &saveInfo->_header; gameEpisode = saveInfo->episode(); gameMap = saveInfo->map(); @@ -3688,7 +3688,7 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) #endif #if __JHEXEN__ - Game_ACScriptInterpreter().readWorldScriptData(reader, hdr->version); + Game_ACScriptInterpreter().readWorldScriptData(reader, saveInfo->version()); #endif /* @@ -3705,7 +3705,7 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) #endif #if !__JHEXEN__ - initThingArchiveForLoad(hdr->version >= 5? Reader_ReadInt32(reader) : 1024 /* num elements */); + initThingArchiveForLoad(saveInfo->version() >= 5? Reader_ReadInt32(reader) : 1024 /* num elements */); #endif readPlayerHeader(reader); @@ -3980,27 +3980,26 @@ void SV_LoadGameClient(uint gameId) player_t *cpl = players + CONSOLEPLAYER; mobj_t *mo = cpl->plr->mo; - AutoStr *gameSavePath; - SaveInfo *saveInfo; if(!IS_CLIENT || !mo) return; playerHeaderOK = false; // Uninitialized. - gameSavePath = composeGameSavePathForClientGameId(gameId); + AutoStr *gameSavePath = composeGameSavePathForClientGameId(gameId); if(!SV_OpenFile(gameSavePath, "rp")) { App_Log(DE2_RES_WARNING, "SV_LoadGameClient: Failed opening \"%s\" for reading", Str_Text(gameSavePath)); return; } - saveInfo = new SaveInfo; + SaveInfo *saveInfo = new SaveInfo; Reader *reader = SV_NewReader(); SV_SaveInfo_Read(saveInfo, reader); - hdr = saveInfo->header(); - if(hdr->magic != MY_CLIENT_SAVE_MAGIC) + hdr = &saveInfo->_header; + + if(saveInfo->magic() != MY_CLIENT_SAVE_MAGIC) { Reader_Delete(reader); delete saveInfo; @@ -4010,16 +4009,16 @@ void SV_LoadGameClient(uint gameId) } gamerules_t const &newRules = saveInfo->gameRules(); - gameSkill = skillmode_t( newRules.skill ); + gameSkill = newRules.skill; deathmatch = newRules.deathmatch; noMonstersParm = newRules.noMonsters; respawnMonsters = newRules.respawnMonsters; // Do we need to change the map? - if(gameMap != (unsigned) (hdr->map - 1) || gameEpisode != (unsigned) (hdr->episode - 1)) + if(gameMap != saveInfo->map() || gameEpisode != saveInfo->episode()) { - gameEpisode = hdr->episode - 1; - gameMap = hdr->map - 1; + gameEpisode = saveInfo->episode(); + gameMap = saveInfo->map(); gameMapEntryPoint = 0; G_NewGame(gameSkill, gameEpisode, gameMap, gameMapEntryPoint); /// @todo Necessary? @@ -4032,10 +4031,11 @@ void SV_LoadGameClient(uint gameId) mo->origin[VY] = FIX2FLT(Reader_ReadInt32(reader)); mo->origin[VZ] = FIX2FLT(Reader_ReadInt32(reader)); P_MobjLink(mo); - mo->floorZ = FIX2FLT(Reader_ReadInt32(reader)); - mo->ceilingZ = FIX2FLT(Reader_ReadInt32(reader)); - mo->angle = Reader_ReadInt32(reader); /* $unifiedangles */ + mo->floorZ = FIX2FLT(Reader_ReadInt32(reader)); + mo->ceilingZ = FIX2FLT(Reader_ReadInt32(reader)); + mo->angle = Reader_ReadInt32(reader); /* $unifiedangles */ cpl->plr->lookDir = Reader_ReadFloat(reader); /* $unifiedangles */ + readPlayerHeader(reader); SV_ReadPlayer(cpl, reader); diff --git a/doomsday/plugins/common/src/saveinfo.cpp b/doomsday/plugins/common/src/saveinfo.cpp index b1d28c2134..4eb2c7b600 100644 --- a/doomsday/plugins/common/src/saveinfo.cpp +++ b/doomsday/plugins/common/src/saveinfo.cpp @@ -95,14 +95,16 @@ uint SaveInfo::map() const return _header.map - 1; } -gamerules_t const &SaveInfo::gameRules() const +#if !__JHEXEN__ +int SaveInfo::mapTime() const { - return _header.gameRules; + return _header.mapTime; } +#endif -saveheader_t const *SaveInfo::header() const +gamerules_t const &SaveInfo::gameRules() const { - return &_header; + return _header.gameRules; } void SaveInfo::configure() @@ -137,7 +139,7 @@ void SaveInfo::configure() #endif #if !__JHEXEN__ - hdr->mapTime = mapTime; + hdr->mapTime = ::mapTime; for(int i = 0; i < MAXPLAYERS; i++) { @@ -403,12 +405,6 @@ void SaveInfo_SetGameId(SaveInfo *info, uint newGameId) info->setGameId(newGameId); } -saveheader_t const *SaveInfo_Header(SaveInfo const *info) -{ - DENG_ASSERT(info != 0); - return info->header(); -} - Str const *SaveInfo_Description(SaveInfo const *info) { DENG_ASSERT(info != 0); diff --git a/doomsday/plugins/doom/src/p_oldsvg.cpp b/doomsday/plugins/doom/src/p_oldsvg.cpp index e78f4ed45d..ed4ec328e3 100644 --- a/doomsday/plugins/doom/src/p_oldsvg.cpp +++ b/doomsday/plugins/doom/src/p_oldsvg.cpp @@ -842,13 +842,13 @@ int SV_LoadState_Dm_v19(Str const *path, SaveInfo *info) delete tmp; } - saveheader_t const &hdr = info->_header; - - gameSkill = hdr.skill; - gameEpisode = hdr.episode; - gameMap = hdr.map; + gameEpisode = info->episode(); + gameMap = info->map(); gameMapEntryPoint = 0; + gamerules_t const &newRules = info->gameRules(); + gameSkill = newRules.skill; + // We don't want to see a briefing if we're loading a save game. briefDisabled = true; @@ -858,7 +858,7 @@ int SV_LoadState_Dm_v19(Str const *path, SaveInfo *info) G_SetGameAction(GA_NONE); // Recreate map state. - mapTime = hdr.mapTime; + mapTime = info->mapTime(); P_v19_UnArchivePlayers(); P_v19_UnArchiveWorld(); @@ -897,14 +897,14 @@ static void SaveInfo_Read_Dm_v19(SaveInfo *info, Reader *reader) hdr->version = atoi(&vcheck[8]); - hdr->skill = (skillmode_t) Reader_ReadByte(reader); + hdr->gameRules.skill = (skillmode_t) Reader_ReadByte(reader); // Interpret skill levels outside the normal range as "spawn no things". - if(hdr->skill < SM_BABY || hdr->skill >= NUM_SKILL_MODES) - hdr->skill = SM_NOTHINGS; + if(hdr->gameRules.skill < SM_BABY || hdr->gameRules.skill >= NUM_SKILL_MODES) + hdr->gameRules.skill = SM_NOTHINGS; - hdr->episode = Reader_ReadByte(reader)-1; - hdr->map = Reader_ReadByte(reader)-1; + hdr->episode = Reader_ReadByte(reader); + hdr->map = Reader_ReadByte(reader); for(int i = 0; i < 4; ++i) { @@ -923,9 +923,10 @@ static void SaveInfo_Read_Dm_v19(SaveInfo *info, Reader *reader) /// @note Older formats do not contain all needed values: hdr->gameMode = gameMode; // Assume the current mode. - hdr->deathmatch = 0; - hdr->noMonsters = 0; - hdr->respawnMonsters = 0; + + hdr->gameRules.deathmatch = 0; + hdr->gameRules.noMonsters = 0; + hdr->gameRules.respawnMonsters = 0; info->_gameId = 0; // None. } diff --git a/doomsday/plugins/heretic/src/p_oldsvg.cpp b/doomsday/plugins/heretic/src/p_oldsvg.cpp index 22c06e8013..e0fc66a3c3 100644 --- a/doomsday/plugins/heretic/src/p_oldsvg.cpp +++ b/doomsday/plugins/heretic/src/p_oldsvg.cpp @@ -851,13 +851,13 @@ int SV_LoadState_Hr_v13(Str const *path, SaveInfo *info) delete tmp; } - saveheader_t const &hdr = info->_header; - - gameSkill = hdr.skill; - gameEpisode = hdr.episode; - gameMap = hdr.map; + gameEpisode = info->episode(); + gameMap = info->map(); gameMapEntryPoint = 0; + gamerules_t const &newRules = info->gameRules(); + gameSkill = newRules.skill; + // We don't want to see a briefing if we're loading a save game. briefDisabled = true; @@ -867,7 +867,7 @@ int SV_LoadState_Hr_v13(Str const *path, SaveInfo *info) G_SetGameAction(GA_NONE); // Recreate map state. - mapTime = hdr.mapTime; + mapTime = info->mapTime(); P_v13_UnArchivePlayers(); P_v13_UnArchiveWorld(); @@ -905,14 +905,14 @@ static void SaveInfo_Read_Hr_v13(SaveInfo *info, Reader *reader) //DENG_ASSERT(!strncmp(vcheck, "version ", 8)); // Ensure save state format has been recognised by now. hdr->version = atoi(&vcheck[8]); - hdr->skill = (skillmode_t) Reader_ReadByte(reader); + hdr->gameRules.skill = (skillmode_t) Reader_ReadByte(reader); // Interpret skill levels outside the normal range as "spawn no things". - if(hdr->skill < SM_BABY || hdr->skill >= NUM_SKILL_MODES) - hdr->skill = SM_NOTHINGS; + if(hdr->gameRules.skill < SM_BABY || hdr->gameRules.skill >= NUM_SKILL_MODES) + hdr->gameRules.skill = SM_NOTHINGS; - hdr->episode = Reader_ReadByte(reader)-1; - hdr->map = Reader_ReadByte(reader)-1; + hdr->episode = Reader_ReadByte(reader); + hdr->map = Reader_ReadByte(reader); for(int i = 0; i < 4; ++i) { hdr->players[i] = Reader_ReadByte(reader); @@ -929,9 +929,10 @@ static void SaveInfo_Read_Hr_v13(SaveInfo *info, Reader *reader) /// @note Older formats do not contain all needed values: hdr->gameMode = gameMode; // Assume the current mode. - hdr->deathmatch = 0; - hdr->noMonsters = 0; - hdr->respawnMonsters = 0; + + hdr->gameRules.deathmatch = 0; + hdr->gameRules.noMonsters = 0; + hdr->gameRules.respawnMonsters = 0; info->_gameId = 0; // None. } From 63f04fd0fb50175b5eb076be05ac011fe5d8205e Mon Sep 17 00:00:00 2001 From: danij Date: Mon, 3 Feb 2014 23:00:44 +0000 Subject: [PATCH 077/106] Refactor|SaveInfo|libcommon: Removed the old saveheader_t abstraction --- doomsday/plugins/common/include/saveinfo.h | 24 ++- doomsday/plugins/common/src/p_saveg.cpp | 32 ++-- doomsday/plugins/common/src/saveinfo.cpp | 192 ++++++++++++--------- doomsday/plugins/doom/src/p_oldsvg.cpp | 30 ++-- doomsday/plugins/heretic/src/p_oldsvg.cpp | 30 ++-- 5 files changed, 162 insertions(+), 146 deletions(-) diff --git a/doomsday/plugins/common/include/saveinfo.h b/doomsday/plugins/common/include/saveinfo.h index b6d0395b59..1605f8eb4f 100644 --- a/doomsday/plugins/common/include/saveinfo.h +++ b/doomsday/plugins/common/include/saveinfo.h @@ -38,19 +38,6 @@ typedef struct gamerules_s { #endif } gamerules_t; -typedef struct saveheader_s { - int magic; - int version; - gamemode_t gameMode; - gamerules_t gameRules; - byte episode; - byte map; -#if !__JHEXEN__ - int mapTime; - byte players[MAXPLAYERS]; -#endif -} saveheader_t; - #ifdef __cplusplus /** * Saved game session info. @@ -60,7 +47,16 @@ class SaveInfo public: /// @todo make private: Str _description; uint _gameId; - saveheader_t _header; + int _magic; + int _version; + gamemode_t _gameMode; + byte _episode; + byte _map; +#if !__JHEXEN__ + int _mapTime; + byte _players[MAXPLAYERS]; +#endif + gamerules_t _gameRules; public: SaveInfo(); diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index d116162fd5..779b863565 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -144,7 +144,7 @@ static SaveInfo *nullSaveInfo; #if __JHEXEN__ static int mapVersion; #endif -static saveheader_t const *hdr; +static SaveInfo const *curInfo; static playerheader_t playerHeader; static dd_bool playerHeaderOK; @@ -1102,7 +1102,7 @@ static inline int materialArchiveVersion() #if __JHEXEN__ if(mapVersion < 6) #else - if(hdr->version < 6) + if(curInfo->version() < 6) #endif { return 0; @@ -2173,9 +2173,9 @@ static void writePlayerHeader(Writer *writer) static void readPlayerHeader(Reader *reader) { #if __JHEXEN__ - if(hdr->version >= 4) + if(curInfo->version() >= 4) #else - if(hdr->version >= 5) + if(curInfo->version() >= 5) #endif { SV_AssertSegment(ASEG_PLAYER_HEADER); @@ -2273,7 +2273,7 @@ static void readPlayers(dd_bool *infile, dd_bool *loaded, Reader *reader) { loaded[i] = 0; #if !__JHEXEN__ - infile[i] = hdr->players[i]; + infile[i] = curInfo->_players[i]; #endif } @@ -2436,7 +2436,7 @@ static void SV_ReadSector(Sector *sec, Reader *reader, int mapVersion) type = sc_ploff; else #else - if(hdr->version <= 1) + if(curInfo->version() <= 1) type = sc_normal; else #endif @@ -2446,7 +2446,7 @@ static void SV_ReadSector(Sector *sec, Reader *reader, int mapVersion) #if __JHEXEN__ if(mapVersion > 2) #else - if(hdr->version > 4) + if(curInfo->version() > 4) #endif ver = Reader_ReadByte(reader); @@ -2465,7 +2465,7 @@ static void SV_ReadSector(Sector *sec, Reader *reader, int mapVersion) #endif #if !__JHEXEN__ - if(hdr->version == 1) + if(curInfo->version() == 1) { // The flat numbers are absolute lump indices. Uri* uri = Uri_NewWithPath2("Flats:", RC_NULL); @@ -2476,7 +2476,7 @@ static void SV_ReadSector(Sector *sec, Reader *reader, int mapVersion) ceilingMaterial = (Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); Uri_Delete(uri); } - else if(hdr->version >= 4) + else if(curInfo->version() >= 4) #endif { // The flat numbers are actually archive numbers. @@ -2497,7 +2497,7 @@ static void SV_ReadSector(Sector *sec, Reader *reader, int mapVersion) lightlevel = (byte) Reader_ReadInt16(reader); #else // In Ver1 the light level is a short - if(hdr->version == 1) + if(curInfo->version() == 1) lightlevel = (byte) Reader_ReadInt16(reader); else lightlevel = Reader_ReadByte(reader); @@ -2505,7 +2505,7 @@ static void SV_ReadSector(Sector *sec, Reader *reader, int mapVersion) P_SetFloatp(sec, DMU_LIGHT_LEVEL, (float) lightlevel / 255.f); #if !__JHEXEN__ - if(hdr->version > 1) + if(curInfo->version() > 1) #endif { Reader_Read(reader, rgb, 3); @@ -3540,7 +3540,7 @@ static void readMap(Reader *reader) #if __JHEXEN__ mapVersion = (mapSegmentId == ASEG_MAP_HEADER2? Reader_ReadByte(reader) : 2); #else - int const mapVersion = hdr->version; + int const mapVersion = curInfo->version(); #endif #if __JHEXEN__ @@ -3668,7 +3668,7 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) /* * Configure global game state: */ - hdr = &saveInfo->_header; + curInfo = saveInfo; gameEpisode = saveInfo->episode(); gameMap = saveInfo->map(); @@ -3701,7 +3701,7 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) #if !__JHEXEN__ // Set the time. - mapTime = hdr->mapTime; + mapTime = saveInfo->mapTime(); #endif #if !__JHEXEN__ @@ -3997,7 +3997,7 @@ void SV_LoadGameClient(uint gameId) Reader *reader = SV_NewReader(); SV_SaveInfo_Read(saveInfo, reader); - hdr = &saveInfo->_header; + curInfo = saveInfo; if(saveInfo->magic() != MY_CLIENT_SAVE_MAGIC) { @@ -4024,7 +4024,7 @@ void SV_LoadGameClient(uint gameId) /// @todo Necessary? G_SetGameAction(GA_NONE); } - mapTime = hdr->mapTime; + mapTime = saveInfo->mapTime(); P_MobjUnlink(mo); mo->origin[VX] = FIX2FLT(Reader_ReadInt32(reader)); diff --git a/doomsday/plugins/common/src/saveinfo.cpp b/doomsday/plugins/common/src/saveinfo.cpp index 4eb2c7b600..16b41a3f77 100644 --- a/doomsday/plugins/common/src/saveinfo.cpp +++ b/doomsday/plugins/common/src/saveinfo.cpp @@ -29,17 +29,39 @@ #include SaveInfo::SaveInfo() - : _gameId(0) + : _gameId (0) + , _magic (0) + , _version (0) + , _gameMode(NUM_GAME_MODES) + , _episode (0) + , _map (0) +#if !__JHEXEN__ + , _mapTime (0) +#endif { Str_InitStd(&_description); - memset(&_header, 0, sizeof(_header)); +#if !__JHEXEN__ + memset(&_players, 0, sizeof(_players)); +#endif + memset(&_gameRules, 0, sizeof(_gameRules)); } SaveInfo::SaveInfo(SaveInfo const &other) - : _gameId(other._gameId) + : _gameId (other._gameId) + , _magic (other._magic) + , _version (other._version) + , _gameMode(other._gameMode) + , _episode (other._episode) + , _map (other._map) +#if !__JHEXEN__ + , _mapTime (other._mapTime) +#endif { Str_Copy(Str_InitStd(&_description), &other._description); - std::memcpy(&_header, &other._header, sizeof(_header)); +#if !__JHEXEN__ + std::memcpy(&_players, &other._players, sizeof(_players)); +#endif + std::memcpy(&_gameRules, &other._gameRules, sizeof(_gameRules)); } SaveInfo::~SaveInfo() @@ -51,18 +73,27 @@ SaveInfo &SaveInfo::operator = (SaveInfo const &other) { Str_Copy(&_description, &other._description); _gameId = other._gameId; - std::memcpy(&_header, &other._header, sizeof(_header)); + _magic = other._magic; + _version = other._version; + _gameMode = other._gameMode; + _episode = other._episode; + _map = other._map; +#if !__JHEXEN__ + _mapTime = other._mapTime; + std::memcpy(&_players, &other._players, sizeof(_players)); +#endif + std::memcpy(&_gameRules, &other._gameRules, sizeof(_gameRules)); return *this; } int SaveInfo::version() const { - return _header.version; + return _version; } int SaveInfo::magic() const { - return _header.magic; + return _magic; } Str const *SaveInfo::description() const @@ -87,63 +118,61 @@ void SaveInfo::setGameId(uint newGameId) uint SaveInfo::episode() const { - return _header.episode - 1; + return _episode - 1; } uint SaveInfo::map() const { - return _header.map - 1; + return _map - 1; } #if !__JHEXEN__ int SaveInfo::mapTime() const { - return _header.mapTime; + return _mapTime; } #endif gamerules_t const &SaveInfo::gameRules() const { - return _header.gameRules; + return _gameRules; } void SaveInfo::configure() { - saveheader_t *hdr = &_header; + _magic = IS_NETWORK_CLIENT? MY_CLIENT_SAVE_MAGIC : MY_SAVE_MAGIC; + _version = MY_SAVE_VERSION; + _gameMode = gameMode; - hdr->magic = IS_NETWORK_CLIENT? MY_CLIENT_SAVE_MAGIC : MY_SAVE_MAGIC; - hdr->version = MY_SAVE_VERSION; - hdr->gameMode = gameMode; - - hdr->map = gameMap+1; + _map = gameMap+1; #if __JHEXEN__ - hdr->episode = 1; + _episode = 1; #else - hdr->episode = gameEpisode+1; + _episode = gameEpisode+1; #endif #if __JHEXEN__ - hdr->gameRules.skill = gameSkill; - hdr->gameRules.randomClasses = randomClassParm; + _gameRules.skill = gameSkill; + _gameRules.randomClasses = randomClassParm; #else - hdr->gameRules.skill = gameSkill; - hdr->gameRules.fast = fastParm; + _gameRules.skill = gameSkill; + _gameRules.fast = fastParm; #endif - hdr->gameRules.deathmatch = deathmatch; - hdr->gameRules.noMonsters = noMonstersParm; + _gameRules.deathmatch = deathmatch; + _gameRules.noMonsters = noMonstersParm; #if __JHEXEN__ - hdr->gameRules.randomClasses = randomClassParm; + _gameRules.randomClasses = randomClassParm; #else - hdr->gameRules.respawnMonsters = respawnMonsters; + _gameRules.respawnMonsters = respawnMonsters; #endif #if !__JHEXEN__ - hdr->mapTime = ::mapTime; + _mapTime = ::mapTime; for(int i = 0; i < MAXPLAYERS; i++) { - hdr->players[i] = players[i].plr->inGame; + _players[i] = players[i].plr->inGame; } #endif } @@ -151,7 +180,7 @@ void SaveInfo::configure() bool SaveInfo::isLoadable() { // Game Mode missmatch? - if(_header.gameMode != gameMode) return false; + if(_gameMode != gameMode) return false; /// @todo Validate loaded add-ons and checksum the definition database. @@ -160,32 +189,31 @@ bool SaveInfo::isLoadable() void SaveInfo::write(Writer *writer) const { - saveheader_t const *hdr = &_header; - Writer_WriteInt32(writer, hdr->magic); - Writer_WriteInt32(writer, hdr->version); - Writer_WriteInt32(writer, hdr->gameMode); + Writer_WriteInt32(writer, _magic); + Writer_WriteInt32(writer, _version); + Writer_WriteInt32(writer, _gameMode); Str_Write(&_description, writer); - Writer_WriteByte(writer, hdr->gameRules.skill & 0x7f); - Writer_WriteByte(writer, hdr->episode); - Writer_WriteByte(writer, hdr->map); - Writer_WriteByte(writer, hdr->gameRules.deathmatch); + Writer_WriteByte(writer, _gameRules.skill & 0x7f); + Writer_WriteByte(writer, _episode); + Writer_WriteByte(writer, _map); + Writer_WriteByte(writer, _gameRules.deathmatch); #if !__JHEXEN__ - Writer_WriteByte(writer, hdr->gameRules.fast); + Writer_WriteByte(writer, _gameRules.fast); #endif - Writer_WriteByte(writer, hdr->gameRules.noMonsters); + Writer_WriteByte(writer, _gameRules.noMonsters); #if __JHEXEN__ - Writer_WriteByte(writer, hdr->gameRules.randomClasses); + Writer_WriteByte(writer, _gameRules.randomClasses); #else - Writer_WriteByte(writer, hdr->gameRules.respawnMonsters); + Writer_WriteByte(writer, _gameRules.respawnMonsters); #endif #if !__JHEXEN__ - Writer_WriteInt32(writer, hdr->mapTime); + Writer_WriteInt32(writer, _mapTime); for(int i = 0; i < MAXPLAYERS; ++i) { - Writer_WriteByte(writer, hdr->players[i]); + Writer_WriteByte(writer, _players[i]); } #endif Writer_WriteInt32(writer, _gameId); @@ -236,13 +264,11 @@ static void translateLegacyGameMode(gamemode_t *mode, int saveVersion) void SaveInfo::read(Reader *reader) { - saveheader_t *hdr = &_header; - - hdr->magic = Reader_ReadInt32(reader); - hdr->version = Reader_ReadInt32(reader); - hdr->gameMode = (gamemode_t)Reader_ReadInt32(reader); + _magic = Reader_ReadInt32(reader); + _version = Reader_ReadInt32(reader); + _gameMode = (gamemode_t)Reader_ReadInt32(reader); - if(hdr->version >= 10) + if(_version >= 10) { Str_Read(&_description, reader); } @@ -259,7 +285,7 @@ void SaveInfo::read(Reader *reader) } #if !__JHEXEN__ - if(hdr->version < 13) + if(_version < 13) { // In DOOM the high bit of the skill mode byte is also used for the // "fast" game rule dd_bool. There is more confusion in that SM_NOTHINGS @@ -269,53 +295,53 @@ void SaveInfo::read(Reader *reader) // by default this means "spawn no things" and if so then the "fast" game // rule is meaningless so it is forced off. byte skillModePlusFastBit = Reader_ReadByte(reader); - hdr->gameRules.skill = (skillmode_t) (skillModePlusFastBit & 0x7f); - if(hdr->gameRules.skill < SM_BABY || hdr->gameRules.skill >= NUM_SKILL_MODES) + _gameRules.skill = (skillmode_t) (skillModePlusFastBit & 0x7f); + if(_gameRules.skill < SM_BABY || _gameRules.skill >= NUM_SKILL_MODES) { - hdr->gameRules.skill = SM_NOTHINGS; - hdr->gameRules.fast = 0; + _gameRules.skill = SM_NOTHINGS; + _gameRules.fast = 0; } else { - hdr->gameRules.fast = (skillModePlusFastBit & 0x80) != 0; + _gameRules.fast = (skillModePlusFastBit & 0x80) != 0; } } else #endif { - hdr->gameRules.skill = skillmode_t( Reader_ReadByte(reader) & 0x7f ); + _gameRules.skill = skillmode_t( Reader_ReadByte(reader) & 0x7f ); // Interpret skill levels outside the normal range as "spawn no things". - if(hdr->gameRules.skill < SM_BABY || hdr->gameRules.skill >= NUM_SKILL_MODES) + if(_gameRules.skill < SM_BABY || _gameRules.skill >= NUM_SKILL_MODES) { - hdr->gameRules.skill = SM_NOTHINGS; + _gameRules.skill = SM_NOTHINGS; } } - hdr->episode = Reader_ReadByte(reader); - hdr->map = Reader_ReadByte(reader); + _episode = Reader_ReadByte(reader); + _map = Reader_ReadByte(reader); - hdr->gameRules.deathmatch = Reader_ReadByte(reader); + _gameRules.deathmatch = Reader_ReadByte(reader); #if !__JHEXEN__ - if(hdr->version >= 13) - hdr->gameRules.fast = Reader_ReadByte(reader); + if(_version >= 13) + _gameRules.fast = Reader_ReadByte(reader); #endif - hdr->gameRules.noMonsters = Reader_ReadByte(reader); + _gameRules.noMonsters = Reader_ReadByte(reader); #if __JHEXEN__ - hdr->gameRules.randomClasses = Reader_ReadByte(reader); + _gameRules.randomClasses = Reader_ReadByte(reader); #endif #if !__JHEXEN__ - hdr->gameRules.respawnMonsters = Reader_ReadByte(reader); + _gameRules.respawnMonsters = Reader_ReadByte(reader); // Older formats serialize the unpacked saveheader_t struct; skip the junk values (alignment). - if(hdr->version < 10) SV_Seek(2); + if(_version < 10) SV_Seek(2); - hdr->mapTime = Reader_ReadInt32(reader); + _mapTime = Reader_ReadInt32(reader); for(int i = 0; i < MAXPLAYERS; ++i) { - hdr->players[i] = Reader_ReadByte(reader); + _players[i] = Reader_ReadByte(reader); } #endif @@ -323,7 +349,7 @@ void SaveInfo::read(Reader *reader) #if __JDOOM__ || __JHERETIC__ // Translate gameMode identifiers from older save versions. - translateLegacyGameMode(&hdr->gameMode, hdr->version); + translateLegacyGameMode(&_gameMode, _version); #endif } @@ -337,30 +363,28 @@ void SaveInfo::read_Hx_v9(Reader *reader) char verText[HXS_VERSION_TEXT_LENGTH]; char nameBuffer[HXS_NAME_LENGTH]; - saveheader_t *hdr = &_header; - Reader_Read(reader, nameBuffer, HXS_NAME_LENGTH); Str_Set(&_description, nameBuffer); Reader_Read(reader, &verText, HXS_VERSION_TEXT_LENGTH); - hdr->version = atoi(&verText[8]); + _version = atoi(&verText[8]); /*Skip junk*/ SV_Seek(4); - hdr->episode = 1; - hdr->map = Reader_ReadByte(reader); - hdr->magic = MY_SAVE_MAGIC; // Lets pretend... - hdr->gameMode = gameMode; // Assume the current mode. + _episode = 1; + _map = Reader_ReadByte(reader); + _magic = MY_SAVE_MAGIC; // Lets pretend... + _gameMode = gameMode; // Assume the current mode. - hdr->gameRules.skill = (skillmode_t) (Reader_ReadByte(reader) & 0x7f); + _gameRules.skill = (skillmode_t) (Reader_ReadByte(reader) & 0x7f); // Interpret skill modes outside the normal range as "spawn no things". - if(hdr->gameRules.skill < SM_BABY || hdr->gameRules.skill >= NUM_SKILL_MODES) - hdr->gameRules.skill = SM_NOTHINGS; + if(_gameRules.skill < SM_BABY || _gameRules.skill >= NUM_SKILL_MODES) + _gameRules.skill = SM_NOTHINGS; - hdr->gameRules.deathmatch = Reader_ReadByte(reader); - hdr->gameRules.noMonsters = Reader_ReadByte(reader); - hdr->gameRules.randomClasses = Reader_ReadByte(reader); + _gameRules.deathmatch = Reader_ReadByte(reader); + _gameRules.noMonsters = Reader_ReadByte(reader); + _gameRules.randomClasses = Reader_ReadByte(reader); _gameId = 0; // None. diff --git a/doomsday/plugins/doom/src/p_oldsvg.cpp b/doomsday/plugins/doom/src/p_oldsvg.cpp index ed4ec328e3..cae8b7a9e0 100644 --- a/doomsday/plugins/doom/src/p_oldsvg.cpp +++ b/doomsday/plugins/doom/src/p_oldsvg.cpp @@ -884,8 +884,6 @@ static void SaveInfo_Read_Dm_v19(SaveInfo *info, Reader *reader) { DENG_ASSERT(info != 0); - saveheader_t *hdr = &info->_header; - char nameBuffer[V19_SAVESTRINGSIZE]; Reader_Read(reader, nameBuffer, V19_SAVESTRINGSIZE); nameBuffer[V19_SAVESTRINGSIZE - 1] = 0; @@ -895,38 +893,38 @@ static void SaveInfo_Read_Dm_v19(SaveInfo *info, Reader *reader) Reader_Read(reader, vcheck, VERSIONSIZE); //DENG_ASSERT(!strncmp(vcheck, "version ", 8)); // Ensure save state format has been recognised by now. - hdr->version = atoi(&vcheck[8]); + info->_version = atoi(&vcheck[8]); - hdr->gameRules.skill = (skillmode_t) Reader_ReadByte(reader); + info->_gameRules.skill = (skillmode_t) Reader_ReadByte(reader); // Interpret skill levels outside the normal range as "spawn no things". - if(hdr->gameRules.skill < SM_BABY || hdr->gameRules.skill >= NUM_SKILL_MODES) - hdr->gameRules.skill = SM_NOTHINGS; + if(info->_gameRules.skill < SM_BABY || info->_gameRules.skill >= NUM_SKILL_MODES) + info->_gameRules.skill = SM_NOTHINGS; - hdr->episode = Reader_ReadByte(reader); - hdr->map = Reader_ReadByte(reader); + info->_episode = Reader_ReadByte(reader); + info->_map = Reader_ReadByte(reader); for(int i = 0; i < 4; ++i) { - hdr->players[i] = Reader_ReadByte(reader); + info->_players[i] = Reader_ReadByte(reader); } - memset(&hdr->players[4], 0, sizeof(*hdr->players) * (MAXPLAYERS-4)); + memset(&info->_players[4], 0, sizeof(*info->_players) * (MAXPLAYERS-4)); // Get the map time. int a = Reader_ReadByte(reader); int b = Reader_ReadByte(reader); int c = Reader_ReadByte(reader); - hdr->mapTime = (a << 16) + (b << 8) + c; + info->_mapTime = (a << 16) + (b << 8) + c; - hdr->magic = 0; // Initialize with *something*. + info->_magic = 0; // Initialize with *something*. /// @note Older formats do not contain all needed values: - hdr->gameMode = gameMode; // Assume the current mode. + info->_gameMode = gameMode; // Assume the current mode. - hdr->gameRules.deathmatch = 0; - hdr->gameRules.noMonsters = 0; - hdr->gameRules.respawnMonsters = 0; + info->_gameRules.deathmatch = 0; + info->_gameRules.noMonsters = 0; + info->_gameRules.respawnMonsters = 0; info->_gameId = 0; // None. } diff --git a/doomsday/plugins/heretic/src/p_oldsvg.cpp b/doomsday/plugins/heretic/src/p_oldsvg.cpp index e0fc66a3c3..2e6d2c89d7 100644 --- a/doomsday/plugins/heretic/src/p_oldsvg.cpp +++ b/doomsday/plugins/heretic/src/p_oldsvg.cpp @@ -893,8 +893,6 @@ static void SaveInfo_Read_Hr_v13(SaveInfo *info, Reader *reader) { DENG_ASSERT(info != 0); - saveheader_t *hdr = &info->_header; - char nameBuffer[V13_SAVESTRINGSIZE]; Reader_Read(reader, nameBuffer, V13_SAVESTRINGSIZE); nameBuffer[V13_SAVESTRINGSIZE - 1] = 0; @@ -903,36 +901,36 @@ static void SaveInfo_Read_Hr_v13(SaveInfo *info, Reader *reader) char vcheck[VERSIONSIZE]; Reader_Read(reader, vcheck, VERSIONSIZE); //DENG_ASSERT(!strncmp(vcheck, "version ", 8)); // Ensure save state format has been recognised by now. - hdr->version = atoi(&vcheck[8]); + info->_version = atoi(&vcheck[8]); - hdr->gameRules.skill = (skillmode_t) Reader_ReadByte(reader); + info->_gameRules.skill = (skillmode_t) Reader_ReadByte(reader); // Interpret skill levels outside the normal range as "spawn no things". - if(hdr->gameRules.skill < SM_BABY || hdr->gameRules.skill >= NUM_SKILL_MODES) - hdr->gameRules.skill = SM_NOTHINGS; + if(info->_gameRules.skill < SM_BABY || info->_gameRules.skill >= NUM_SKILL_MODES) + info->_gameRules.skill = SM_NOTHINGS; - hdr->episode = Reader_ReadByte(reader); - hdr->map = Reader_ReadByte(reader); + info->_episode = Reader_ReadByte(reader); + info->_map = Reader_ReadByte(reader); for(int i = 0; i < 4; ++i) { - hdr->players[i] = Reader_ReadByte(reader); + info->_players[i] = Reader_ReadByte(reader); } - memset(&hdr->players[4], 0, sizeof(*hdr->players) * (MAXPLAYERS-4)); + memset(&info->_players[4], 0, sizeof(*info->_players) * (MAXPLAYERS-4)); // Get the map time. int a = Reader_ReadByte(reader); int b = Reader_ReadByte(reader); int c = Reader_ReadByte(reader); - hdr->mapTime = (a << 16) + (b << 8) + c; + info->_mapTime = (a << 16) + (b << 8) + c; - hdr->magic = 0; // Initialize with *something*. + info->_magic = 0; // Initialize with *something*. /// @note Older formats do not contain all needed values: - hdr->gameMode = gameMode; // Assume the current mode. + info->_gameMode = gameMode; // Assume the current mode. - hdr->gameRules.deathmatch = 0; - hdr->gameRules.noMonsters = 0; - hdr->gameRules.respawnMonsters = 0; + info->_gameRules.deathmatch = 0; + info->_gameRules.noMonsters = 0; + info->_gameRules.respawnMonsters = 0; info->_gameId = 0; // None. } From 30d105c006811c386d37d04149dfa489b934b8c2 Mon Sep 17 00:00:00 2001 From: danij Date: Mon, 3 Feb 2014 23:22:20 +0000 Subject: [PATCH 078/106] libcommon: Cleanup --- doomsday/plugins/common/common.pri | 1 + doomsday/plugins/common/include/common.h | 1 + doomsday/plugins/common/include/gamerules.h | 43 +++++++++++++++++++++ doomsday/plugins/common/include/saveinfo.h | 14 ------- doomsday/plugins/common/src/g_game.c | 20 ++++++++++ doomsday/plugins/common/src/saveinfo.cpp | 17 +------- doomsday/plugins/doom/include/g_game.h | 7 ++++ doomsday/plugins/doom64/include/g_game.h | 9 ++++- doomsday/plugins/heretic/include/g_game.h | 9 ++++- doomsday/plugins/hexen/include/g_game.h | 7 ++++ 10 files changed, 97 insertions(+), 31 deletions(-) create mode 100644 doomsday/plugins/common/include/gamerules.h diff --git a/doomsday/plugins/common/common.pri b/doomsday/plugins/common/common.pri index ff6a49b2cd..e6b0a978df 100644 --- a/doomsday/plugins/common/common.pri +++ b/doomsday/plugins/common/common.pri @@ -17,6 +17,7 @@ HEADERS += \ $$common_inc/d_netsv.h \ $$common_inc/dmu_lib.h \ $$common_inc/fi_lib.h \ + $$common_inc/gamerules.h \ $$common_inc/g_common.h \ $$common_inc/g_controls.h \ $$common_inc/g_defs.h \ diff --git a/doomsday/plugins/common/include/common.h b/doomsday/plugins/common/include/common.h index 61261c8e73..a468733d6d 100644 --- a/doomsday/plugins/common/include/common.h +++ b/doomsday/plugins/common/include/common.h @@ -40,6 +40,7 @@ # include "jhexen.h" #endif +#include "gamerules.h" #include "pause.h" DENG_EXTERN_C dd_bool sc_FileScripts; diff --git a/doomsday/plugins/common/include/gamerules.h b/doomsday/plugins/common/include/gamerules.h new file mode 100644 index 0000000000..fadf143454 --- /dev/null +++ b/doomsday/plugins/common/include/gamerules.h @@ -0,0 +1,43 @@ +/** @file gamerules.h Game rule set. + * + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef LIBCOMMON_GAMERULES_H +#define LIBCOMMON_GAMERULES_H + +#include "common.h" + +/** + * @ingroup libcommon + */ +typedef struct gamerules_s { + skillmode_t skill; +#if !__JHEXEN__ + byte fast; +#endif + byte deathmatch; + byte noMonsters; +#if __JHEXEN__ + byte randomClasses; +#else + byte respawnMonsters; +#endif +} gamerules_t; + +#endif // LIBCOMMON_GAMERULES_H diff --git a/doomsday/plugins/common/include/saveinfo.h b/doomsday/plugins/common/include/saveinfo.h index 1605f8eb4f..380c4fbeee 100644 --- a/doomsday/plugins/common/include/saveinfo.h +++ b/doomsday/plugins/common/include/saveinfo.h @@ -24,20 +24,6 @@ #include "doomsday.h" #include "common.h" -typedef struct gamerules_s { - skillmode_t skill; -#if !__JHEXEN__ - byte fast; -#endif - byte deathmatch; - byte noMonsters; -#if __JHEXEN__ - byte randomClasses; -#else - byte respawnMonsters; -#endif -} gamerules_t; - #ifdef __cplusplus /** * Saved game session info. diff --git a/doomsday/plugins/common/src/g_game.c b/doomsday/plugins/common/src/g_game.c index ecbcc32bf7..290093c464 100644 --- a/doomsday/plugins/common/src/g_game.c +++ b/doomsday/plugins/common/src/g_game.c @@ -2185,6 +2185,26 @@ static void G_InitNewGame(void) #endif } +void G_GetGameRules(gamerules_t *rules) +{ + DENG_ASSERT(rules != 0); +#if __JHEXEN__ + rules->skill = gameSkill; + rules->randomClasses = randomClassParm; +#else + rules->skill = gameSkill; + rules->fast = fastParm; +#endif + rules->deathmatch = deathmatch; + rules->noMonsters = noMonstersParm; + +#if __JHEXEN__ + rules->randomClasses = randomClassParm; +#else + rules->respawnMonsters = respawnMonsters; +#endif +} + #if __JDOOM__ || __JDOOM64__ static void G_ApplyGameRuleFastMonsters(dd_bool fast) { diff --git a/doomsday/plugins/common/src/saveinfo.cpp b/doomsday/plugins/common/src/saveinfo.cpp index 16b41a3f77..e9ba0f6a72 100644 --- a/doomsday/plugins/common/src/saveinfo.cpp +++ b/doomsday/plugins/common/src/saveinfo.cpp @@ -151,21 +151,8 @@ void SaveInfo::configure() _episode = gameEpisode+1; #endif -#if __JHEXEN__ - _gameRules.skill = gameSkill; - _gameRules.randomClasses = randomClassParm; -#else - _gameRules.skill = gameSkill; - _gameRules.fast = fastParm; -#endif - _gameRules.deathmatch = deathmatch; - _gameRules.noMonsters = noMonstersParm; - -#if __JHEXEN__ - _gameRules.randomClasses = randomClassParm; -#else - _gameRules.respawnMonsters = respawnMonsters; -#endif + // Make a copy of the current game rules. + G_GetGameRules(&_gameRules); #if !__JHEXEN__ _mapTime = ::mapTime; diff --git a/doomsday/plugins/doom/include/g_game.h b/doomsday/plugins/doom/include/g_game.h index 2c86737b6d..1c09d3bcfd 100644 --- a/doomsday/plugins/doom/include/g_game.h +++ b/doomsday/plugins/doom/include/g_game.h @@ -37,6 +37,7 @@ #include "doomdef.h" #include "d_event.h" #include "d_player.h" +#include "gamerules.h" #ifdef __cplusplus extern "C" { @@ -73,6 +74,12 @@ void G_CommonPreInit(void); void G_CommonPostInit(void); void G_CommonShutdown(void); +/** + * Configure the given @a rules structure according to the @em current game rules. + * @todo Refactor away. + */ +void G_GetGameRules(gamerules_t *rules); + void R_InitRefresh(void); void G_PrintMapList(void); diff --git a/doomsday/plugins/doom64/include/g_game.h b/doomsday/plugins/doom64/include/g_game.h index 6483f91068..30fba62b99 100644 --- a/doomsday/plugins/doom64/include/g_game.h +++ b/doomsday/plugins/doom64/include/g_game.h @@ -36,6 +36,7 @@ #include "doomdef.h" #include "d_player.h" +#include "gamerules.h" #include "wi_stuff.h" #ifdef __cplusplus @@ -72,8 +73,14 @@ void G_Register(void); void G_CommonPreInit(void); void G_CommonPostInit(void); void G_CommonShutdown(void); -void R_InitRefresh(void); +/** + * Configure the given @a rules structure according to the @em current game rules. + * @todo Refactor away. + */ +void G_GetGameRules(gamerules_t *rules); + +void R_InitRefresh(void); void G_DeathMatchSpawnPlayer(int playernum); void G_PrintMapList(void); diff --git a/doomsday/plugins/heretic/include/g_game.h b/doomsday/plugins/heretic/include/g_game.h index a65266d27c..7a0d8faf94 100644 --- a/doomsday/plugins/heretic/include/g_game.h +++ b/doomsday/plugins/heretic/include/g_game.h @@ -35,6 +35,7 @@ #endif #include "doomdef.h" +#include "gamerules.h" #include "h_event.h" #include "h_player.h" @@ -71,8 +72,14 @@ void G_Register(void); void G_CommonPreInit(void); void G_CommonPostInit(void); void G_CommonShutdown(void); -void R_InitRefresh(void); +/** + * Configure the given @a rules structure according to the @em current game rules. + * @todo Refactor away. + */ +void G_GetGameRules(gamerules_t *rules); + +void R_InitRefresh(void); void G_DeathMatchSpawnPlayer(int playernum); void G_PrintMapList(void); diff --git a/doomsday/plugins/hexen/include/g_game.h b/doomsday/plugins/hexen/include/g_game.h index f677860933..ce1ed07c20 100644 --- a/doomsday/plugins/hexen/include/g_game.h +++ b/doomsday/plugins/hexen/include/g_game.h @@ -32,6 +32,7 @@ # error "Using jHexen headers without __JHEXEN__" #endif +#include "gamerules.h" #include "p_mobj.h" #include "x_player.h" @@ -65,6 +66,12 @@ extern int gsvMapMusic; void G_CommonShutdown(void); +/** + * Configure the given @a rules structure according to the @em current game rules. + * @todo Refactor away. + */ +void G_GetGameRules(gamerules_t *rules); + void R_InitRefresh(void); void R_GetTranslation(int plrClass, int plrColor, int* tclass, int* tmap); void Mobj_UpdateTranslationClassAndMap(mobj_t* mo); From b4e9bc5dc5a45a6e71b9d12c1dd53439c3075a53 Mon Sep 17 00:00:00 2001 From: danij Date: Tue, 4 Feb 2014 00:19:25 +0000 Subject: [PATCH 079/106] GameRuleset|libcommon: Added a (de)serialization mechanism The save version was bumped to v14 as previous save state formats interleaved the game rules with other game session configuration info. --- doomsday/plugins/common/common.pri | 4 +- doomsday/plugins/common/include/gamerules.h | 16 ++++- doomsday/plugins/common/include/p_savedef.h | 2 +- doomsday/plugins/common/include/saveinfo.h | 4 +- doomsday/plugins/common/src/g_game.c | 2 +- doomsday/plugins/common/src/gamerules.c | 62 +++++++++++++++++ doomsday/plugins/common/src/p_saveg.cpp | 4 +- doomsday/plugins/common/src/saveinfo.cpp | 76 +++++++++------------ doomsday/plugins/doom/include/g_game.h | 2 +- doomsday/plugins/doom/src/p_oldsvg.cpp | 2 +- doomsday/plugins/doom64/include/g_game.h | 2 +- doomsday/plugins/heretic/include/g_game.h | 2 +- doomsday/plugins/heretic/src/p_oldsvg.cpp | 2 +- doomsday/plugins/hexen/include/g_game.h | 2 +- 14 files changed, 123 insertions(+), 59 deletions(-) create mode 100644 doomsday/plugins/common/src/gamerules.c diff --git a/doomsday/plugins/common/common.pri b/doomsday/plugins/common/common.pri index e6b0a978df..8033d3ebf3 100644 --- a/doomsday/plugins/common/common.pri +++ b/doomsday/plugins/common/common.pri @@ -17,12 +17,12 @@ HEADERS += \ $$common_inc/d_netsv.h \ $$common_inc/dmu_lib.h \ $$common_inc/fi_lib.h \ - $$common_inc/gamerules.h \ $$common_inc/g_common.h \ $$common_inc/g_controls.h \ $$common_inc/g_defs.h \ $$common_inc/g_eventsequence.h \ $$common_inc/g_update.h \ + $$common_inc/gamerules.h \ $$common_inc/gl_drawpatch.h \ $$common_inc/hexlex.h \ $$common_inc/hu_automap.h \ @@ -82,6 +82,8 @@ SOURCES += \ $$common_src/g_eventsequence.cpp \ $$common_src/g_game.c \ $$common_src/g_update.c \ + $$common_src/g_update.c \ + $$common_src/gamerules.c \ $$common_src/gl_drawpatch.c \ $$common_src/hexlex.cpp \ $$common_src/hu_automap.c \ diff --git a/doomsday/plugins/common/include/gamerules.h b/doomsday/plugins/common/include/gamerules.h index fadf143454..deb553303d 100644 --- a/doomsday/plugins/common/include/gamerules.h +++ b/doomsday/plugins/common/include/gamerules.h @@ -26,7 +26,8 @@ /** * @ingroup libcommon */ -typedef struct gamerules_s { +typedef struct gameruleset_s +{ skillmode_t skill; #if !__JHEXEN__ byte fast; @@ -38,6 +39,17 @@ typedef struct gamerules_s { #else byte respawnMonsters; #endif -} gamerules_t; +} GameRuleset; + +#ifdef __cplusplus +extern "C" { +#endif + +void GameRuleset_Write(GameRuleset const *rules, Writer *writer); +void GameRuleset_Read(GameRuleset *rules, Reader *reader); + +#ifdef __cplusplus +} // extern "C" +#endif #endif // LIBCOMMON_GAMERULES_H diff --git a/doomsday/plugins/common/include/p_savedef.h b/doomsday/plugins/common/include/p_savedef.h index 43c9eba880..77d467006a 100644 --- a/doomsday/plugins/common/include/p_savedef.h +++ b/doomsday/plugins/common/include/p_savedef.h @@ -21,7 +21,7 @@ #ifndef LIBCOMMON_SAVEGAME_DEFS_H #define LIBCOMMON_SAVEGAME_DEFS_H -#define MY_SAVE_VERSION 13 +#define MY_SAVE_VERSION 14 #if __JDOOM__ # define MY_SAVE_MAGIC 0x1DEAD666 diff --git a/doomsday/plugins/common/include/saveinfo.h b/doomsday/plugins/common/include/saveinfo.h index 380c4fbeee..a1fd223976 100644 --- a/doomsday/plugins/common/include/saveinfo.h +++ b/doomsday/plugins/common/include/saveinfo.h @@ -42,7 +42,7 @@ class SaveInfo int _mapTime; byte _players[MAXPLAYERS]; #endif - gamerules_t _gameRules; + GameRuleset _gameRules; public: SaveInfo(); @@ -82,7 +82,7 @@ class SaveInfo #if !__JHEXEN__ int mapTime() const; #endif - gamerules_t const &gameRules() const; + GameRuleset const &gameRules() const; /** * Serializes the game session info using @a writer. diff --git a/doomsday/plugins/common/src/g_game.c b/doomsday/plugins/common/src/g_game.c index 290093c464..0ccc25124f 100644 --- a/doomsday/plugins/common/src/g_game.c +++ b/doomsday/plugins/common/src/g_game.c @@ -2185,7 +2185,7 @@ static void G_InitNewGame(void) #endif } -void G_GetGameRules(gamerules_t *rules) +void G_GetGameRules(GameRuleset *rules) { DENG_ASSERT(rules != 0); #if __JHEXEN__ diff --git a/doomsday/plugins/common/src/gamerules.c b/doomsday/plugins/common/src/gamerules.c new file mode 100644 index 0000000000..0e8e39a2fa --- /dev/null +++ b/doomsday/plugins/common/src/gamerules.c @@ -0,0 +1,62 @@ +/** @file gamerules.cpp Game rule set. + * + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include "common.h" +#include "gamerules.h" + +void GameRuleset_Write(GameRuleset const *rules, Writer *writer) +{ + DENG_ASSERT(rules != 0 && writer != 0); + Writer_WriteByte(writer, rules->skill); + Writer_WriteByte(writer, rules->deathmatch); +#if !__JHEXEN__ + Writer_WriteByte(writer, rules->fast); +#endif + Writer_WriteByte(writer, rules->noMonsters); +#if __JHEXEN__ + Writer_WriteByte(writer, rules->randomClasses); +#else + Writer_WriteByte(writer, rules->respawnMonsters); +#endif +} + +void GameRuleset_Read(GameRuleset *rules, Reader *reader) +{ + DENG_ASSERT(rules != 0 && reader != 0); + + rules->skill = (skillmode_t) Reader_ReadByte(reader); + // Interpret skill levels outside the normal range as "spawn no things". + if(rules->skill < SM_BABY || rules->skill >= NUM_SKILL_MODES) + { + rules->skill = SM_NOTHINGS; + } + + rules->deathmatch = Reader_ReadByte(reader); +#if !__JHEXEN__ + rules->fast = Reader_ReadByte(reader); +#endif + rules->noMonsters = Reader_ReadByte(reader); +#if __JHEXEN__ + rules->randomClasses = Reader_ReadByte(reader); +#endif +#if !__JHEXEN__ + rules->respawnMonsters = Reader_ReadByte(reader); +#endif +} diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index 779b863565..6b74d8ee43 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -3674,7 +3674,7 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) gameMap = saveInfo->map(); // Apply the game rules: - gamerules_t const &newRules = saveInfo->gameRules(); + GameRuleset const &newRules = saveInfo->gameRules(); gameSkill = newRules.skill; #if !__JHEXEN__ fastParm = newRules.fast; @@ -4008,7 +4008,7 @@ void SV_LoadGameClient(uint gameId) return; } - gamerules_t const &newRules = saveInfo->gameRules(); + GameRuleset const &newRules = saveInfo->gameRules(); gameSkill = newRules.skill; deathmatch = newRules.deathmatch; noMonstersParm = newRules.noMonsters; diff --git a/doomsday/plugins/common/src/saveinfo.cpp b/doomsday/plugins/common/src/saveinfo.cpp index e9ba0f6a72..3bc1c37f7c 100644 --- a/doomsday/plugins/common/src/saveinfo.cpp +++ b/doomsday/plugins/common/src/saveinfo.cpp @@ -133,30 +133,28 @@ int SaveInfo::mapTime() const } #endif -gamerules_t const &SaveInfo::gameRules() const +GameRuleset const &SaveInfo::gameRules() const { return _gameRules; } void SaveInfo::configure() { - _magic = IS_NETWORK_CLIENT? MY_CLIENT_SAVE_MAGIC : MY_SAVE_MAGIC; - _version = MY_SAVE_VERSION; - _gameMode = gameMode; - - _map = gameMap+1; + _magic = IS_NETWORK_CLIENT? MY_CLIENT_SAVE_MAGIC : MY_SAVE_MAGIC; + _version = MY_SAVE_VERSION; + _gameMode = gameMode; #if __JHEXEN__ - _episode = 1; + _episode = 1; #else - _episode = gameEpisode+1; + _episode = gameEpisode + 1; + _mapTime = ::mapTime; #endif + _map = gameMap + 1; // Make a copy of the current game rules. G_GetGameRules(&_gameRules); #if !__JHEXEN__ - _mapTime = ::mapTime; - for(int i = 0; i < MAXPLAYERS; i++) { _players[i] = players[i].plr->inGame; @@ -181,19 +179,8 @@ void SaveInfo::write(Writer *writer) const Writer_WriteInt32(writer, _gameMode); Str_Write(&_description, writer); - Writer_WriteByte(writer, _gameRules.skill & 0x7f); Writer_WriteByte(writer, _episode); Writer_WriteByte(writer, _map); - Writer_WriteByte(writer, _gameRules.deathmatch); -#if !__JHEXEN__ - Writer_WriteByte(writer, _gameRules.fast); -#endif - Writer_WriteByte(writer, _gameRules.noMonsters); -#if __JHEXEN__ - Writer_WriteByte(writer, _gameRules.randomClasses); -#else - Writer_WriteByte(writer, _gameRules.respawnMonsters); -#endif #if !__JHEXEN__ Writer_WriteInt32(writer, _mapTime); @@ -204,6 +191,8 @@ void SaveInfo::write(Writer *writer) const } #endif Writer_WriteInt32(writer, _gameId); + + GameRuleset_Write(&_gameRules, writer); } #if __JDOOM__ || __JHERETIC__ @@ -271,9 +260,16 @@ void SaveInfo::read(Reader *reader) #undef OLD_NAME_LENGTH } -#if !__JHEXEN__ - if(_version < 13) + if(_version >= 14) { + _episode = Reader_ReadByte(reader); + _map = Reader_ReadByte(reader); + + GameRuleset_Read(&_gameRules, reader); + } + else + { +#if !__JHEXEN__ // In DOOM the high bit of the skill mode byte is also used for the // "fast" game rule dd_bool. There is more confusion in that SM_NOTHINGS // will result in 0xff and thus always set the fast bit. @@ -292,39 +288,31 @@ void SaveInfo::read(Reader *reader) { _gameRules.fast = (skillModePlusFastBit & 0x80) != 0; } - } - else #endif - { - _gameRules.skill = skillmode_t( Reader_ReadByte(reader) & 0x7f ); - - // Interpret skill levels outside the normal range as "spawn no things". - if(_gameRules.skill < SM_BABY || _gameRules.skill >= NUM_SKILL_MODES) - { - _gameRules.skill = SM_NOTHINGS; - } - } - _episode = Reader_ReadByte(reader); - _map = Reader_ReadByte(reader); + _episode = Reader_ReadByte(reader); + _map = Reader_ReadByte(reader); - _gameRules.deathmatch = Reader_ReadByte(reader); + _gameRules.deathmatch = Reader_ReadByte(reader); #if !__JHEXEN__ - if(_version >= 13) - _gameRules.fast = Reader_ReadByte(reader); + if(_version >= 13) + _gameRules.fast = Reader_ReadByte(reader); #endif - _gameRules.noMonsters = Reader_ReadByte(reader); + _gameRules.noMonsters = Reader_ReadByte(reader); #if __JHEXEN__ - _gameRules.randomClasses = Reader_ReadByte(reader); + _gameRules.randomClasses = Reader_ReadByte(reader); #endif - #if !__JHEXEN__ - _gameRules.respawnMonsters = Reader_ReadByte(reader); + _gameRules.respawnMonsters = Reader_ReadByte(reader); +#endif + } + +#if !__JHEXEN__ // Older formats serialize the unpacked saveheader_t struct; skip the junk values (alignment). if(_version < 10) SV_Seek(2); - _mapTime = Reader_ReadInt32(reader); + _mapTime = Reader_ReadInt32(reader); for(int i = 0; i < MAXPLAYERS; ++i) { diff --git a/doomsday/plugins/doom/include/g_game.h b/doomsday/plugins/doom/include/g_game.h index 1c09d3bcfd..fd74cc2be8 100644 --- a/doomsday/plugins/doom/include/g_game.h +++ b/doomsday/plugins/doom/include/g_game.h @@ -78,7 +78,7 @@ void G_CommonShutdown(void); * Configure the given @a rules structure according to the @em current game rules. * @todo Refactor away. */ -void G_GetGameRules(gamerules_t *rules); +void G_GetGameRules(GameRuleset *rules); void R_InitRefresh(void); diff --git a/doomsday/plugins/doom/src/p_oldsvg.cpp b/doomsday/plugins/doom/src/p_oldsvg.cpp index cae8b7a9e0..27214ef785 100644 --- a/doomsday/plugins/doom/src/p_oldsvg.cpp +++ b/doomsday/plugins/doom/src/p_oldsvg.cpp @@ -846,7 +846,7 @@ int SV_LoadState_Dm_v19(Str const *path, SaveInfo *info) gameMap = info->map(); gameMapEntryPoint = 0; - gamerules_t const &newRules = info->gameRules(); + GameRuleset const &newRules = info->gameRules(); gameSkill = newRules.skill; // We don't want to see a briefing if we're loading a save game. diff --git a/doomsday/plugins/doom64/include/g_game.h b/doomsday/plugins/doom64/include/g_game.h index 30fba62b99..2e42511a19 100644 --- a/doomsday/plugins/doom64/include/g_game.h +++ b/doomsday/plugins/doom64/include/g_game.h @@ -78,7 +78,7 @@ void G_CommonShutdown(void); * Configure the given @a rules structure according to the @em current game rules. * @todo Refactor away. */ -void G_GetGameRules(gamerules_t *rules); +void G_GetGameRules(GameRuleset *rules); void R_InitRefresh(void); void G_DeathMatchSpawnPlayer(int playernum); diff --git a/doomsday/plugins/heretic/include/g_game.h b/doomsday/plugins/heretic/include/g_game.h index 7a0d8faf94..976d3e7c69 100644 --- a/doomsday/plugins/heretic/include/g_game.h +++ b/doomsday/plugins/heretic/include/g_game.h @@ -77,7 +77,7 @@ void G_CommonShutdown(void); * Configure the given @a rules structure according to the @em current game rules. * @todo Refactor away. */ -void G_GetGameRules(gamerules_t *rules); +void G_GetGameRules(GameRuleset *rules); void R_InitRefresh(void); void G_DeathMatchSpawnPlayer(int playernum); diff --git a/doomsday/plugins/heretic/src/p_oldsvg.cpp b/doomsday/plugins/heretic/src/p_oldsvg.cpp index 2e6d2c89d7..816cee4018 100644 --- a/doomsday/plugins/heretic/src/p_oldsvg.cpp +++ b/doomsday/plugins/heretic/src/p_oldsvg.cpp @@ -855,7 +855,7 @@ int SV_LoadState_Hr_v13(Str const *path, SaveInfo *info) gameMap = info->map(); gameMapEntryPoint = 0; - gamerules_t const &newRules = info->gameRules(); + GameRuleset const &newRules = info->gameRules(); gameSkill = newRules.skill; // We don't want to see a briefing if we're loading a save game. diff --git a/doomsday/plugins/hexen/include/g_game.h b/doomsday/plugins/hexen/include/g_game.h index ce1ed07c20..1797e1237b 100644 --- a/doomsday/plugins/hexen/include/g_game.h +++ b/doomsday/plugins/hexen/include/g_game.h @@ -70,7 +70,7 @@ void G_CommonShutdown(void); * Configure the given @a rules structure according to the @em current game rules. * @todo Refactor away. */ -void G_GetGameRules(gamerules_t *rules); +void G_GetGameRules(GameRuleset *rules); void R_InitRefresh(void); void R_GetTranslation(int plrClass, int plrColor, int* tclass, int* tmap); From 8cae7d43aede5824a90a6550d41e3c0dc43e21e6 Mon Sep 17 00:00:00 2001 From: danij Date: Tue, 4 Feb 2014 00:27:09 +0000 Subject: [PATCH 080/106] SaveInfo|libcommon: Cleanup --- doomsday/plugins/common/src/saveinfo.cpp | 108 ++++++++++++----------- 1 file changed, 56 insertions(+), 52 deletions(-) diff --git a/doomsday/plugins/common/src/saveinfo.cpp b/doomsday/plugins/common/src/saveinfo.cpp index 3bc1c37f7c..ae190931d7 100644 --- a/doomsday/plugins/common/src/saveinfo.cpp +++ b/doomsday/plugins/common/src/saveinfo.cpp @@ -28,6 +28,49 @@ #include #include +#if __JDOOM__ || __JHERETIC__ +static void translateLegacyGameMode(gamemode_t *mode, int saveVersion) +{ + DENG_ASSERT(mode != 0); + + static gamemode_t const oldGameModes[] = { +# if __JDOOM__ + doom_shareware, + doom, + doom2, + doom_ultimate +# else // __JHERETIC__ + heretic_shareware, + heretic, + heretic_extended +# endif + }; + + // Is translation unnecessary? +#if __JDOOM__ + if(saveVersion >= 9) return; +#elif __JHERETIC__ + if(saveVersion >= 8) return; +#endif + + *mode = oldGameModes[(int)(*mode)]; + +# if __JDOOM__ + /** + * @note Kludge: Older versions did not differentiate between versions + * of Doom2 (i.e., Plutonia and TNT are marked as Doom2). If we detect + * that this save is from some version of Doom2, replace the marked + * gamemode with the current gamemode. + */ + if((*mode) == doom2 && (gameModeBits & GM_ANY_DOOM2)) + { + (*mode) = gameMode; + } + /// kludge end. +# endif +} +#endif + SaveInfo::SaveInfo() : _gameId (0) , _magic (0) @@ -181,62 +224,20 @@ void SaveInfo::write(Writer *writer) const Writer_WriteByte(writer, _episode); Writer_WriteByte(writer, _map); - #if !__JHEXEN__ Writer_WriteInt32(writer, _mapTime); +#endif + GameRuleset_Write(&_gameRules, writer); +#if !__JHEXEN__ for(int i = 0; i < MAXPLAYERS; ++i) { Writer_WriteByte(writer, _players[i]); } #endif - Writer_WriteInt32(writer, _gameId); - - GameRuleset_Write(&_gameRules, writer); -} -#if __JDOOM__ || __JHERETIC__ -static void translateLegacyGameMode(gamemode_t *mode, int saveVersion) -{ - DENG_ASSERT(mode != 0); - - static gamemode_t const oldGameModes[] = { -# if __JDOOM__ - doom_shareware, - doom, - doom2, - doom_ultimate -# else // __JHERETIC__ - heretic_shareware, - heretic, - heretic_extended -# endif - }; - - // Is translation unnecessary? -#if __JDOOM__ - if(saveVersion >= 9) return; -#elif __JHERETIC__ - if(saveVersion >= 8) return; -#endif - - *mode = oldGameModes[(int)(*mode)]; - -# if __JDOOM__ - /** - * @note Kludge: Older versions did not differentiate between versions - * of Doom2 (i.e., Plutonia and TNT are marked as Doom2). If we detect - * that this save is from some version of Doom2, replace the marked - * gamemode with the current gamemode. - */ - if((*mode) == doom2 && (gameModeBits & GM_ANY_DOOM2)) - { - (*mode) = gameMode; - } - /// kludge end. -# endif + Writer_WriteInt32(writer, _gameId); } -#endif void SaveInfo::read(Reader *reader) { @@ -264,6 +265,9 @@ void SaveInfo::read(Reader *reader) { _episode = Reader_ReadByte(reader); _map = Reader_ReadByte(reader); +#if !__JHEXEN__ + _mapTime = Reader_ReadInt32(reader); +#endif GameRuleset_Read(&_gameRules, reader); } @@ -305,15 +309,15 @@ void SaveInfo::read(Reader *reader) #if !__JHEXEN__ _gameRules.respawnMonsters = Reader_ReadByte(reader); #endif - } - - #if !__JHEXEN__ - // Older formats serialize the unpacked saveheader_t struct; skip the junk values (alignment). - if(_version < 10) SV_Seek(2); + // Older formats serialize the unpacked saveheader_t struct; skip the junk values (alignment). + if(_version < 10) SV_Seek(2); - _mapTime = Reader_ReadInt32(reader); + _mapTime = Reader_ReadInt32(reader); +#endif + } +#if !__JHEXEN__ for(int i = 0; i < MAXPLAYERS; ++i) { _players[i] = Reader_ReadByte(reader); From 31f841910b0242299585062fb770487e85e30eff Mon Sep 17 00:00:00 2001 From: danij Date: Tue, 4 Feb 2014 01:36:05 +0000 Subject: [PATCH 081/106] SaveInfo|libcommon: Use 0-based logical episode and map numbers natively Also fixed a new regression with deserializing v.13 format info. --- doomsday/plugins/common/include/saveinfo.h | 24 +++++++--- doomsday/plugins/common/src/saveinfo.cpp | 51 +++++++++++++--------- doomsday/plugins/doom/src/p_oldsvg.cpp | 12 ++--- doomsday/plugins/heretic/src/p_oldsvg.cpp | 12 ++--- 4 files changed, 62 insertions(+), 37 deletions(-) diff --git a/doomsday/plugins/common/include/saveinfo.h b/doomsday/plugins/common/include/saveinfo.h index a1fd223976..3756dcfc26 100644 --- a/doomsday/plugins/common/include/saveinfo.h +++ b/doomsday/plugins/common/include/saveinfo.h @@ -54,8 +54,8 @@ class SaveInfo void configure(); /** - * Returns @a true if the game session is compatibile with the current game session - * and @em should therefore be loadable. + * Determines whether the saved game session is compatibile with the current + * game session (and @em should therefore be loadable). */ bool isLoadable(); @@ -77,11 +77,26 @@ class SaveInfo uint gameId() const; void setGameId(uint newGameId); + /** + * Returns the logical episode number for the game session. + */ uint episode() const; + + /** + * Returns the logical map number for the game session. + */ uint map() const; + #if !__JHEXEN__ + /** + * Returns the expired time in tics since the map begun. + */ int mapTime() const; #endif + + /** + * Returns the game ruleset for the game session. + */ GameRuleset const &gameRules() const; /** @@ -94,11 +109,10 @@ class SaveInfo */ void read(Reader *reader); -#if __JHEXEN__ /** - * @brief libhexen specific version of @ref SaveInfo_Read() for deserializing - * legacy version 9 game session info. + * Hexen-specific version for deserializing legacy v.9 game session info. */ +#if __JHEXEN__ void read_Hx_v9(Reader *reader); #endif }; diff --git a/doomsday/plugins/common/src/saveinfo.cpp b/doomsday/plugins/common/src/saveinfo.cpp index ae190931d7..5e9d4aa11e 100644 --- a/doomsday/plugins/common/src/saveinfo.cpp +++ b/doomsday/plugins/common/src/saveinfo.cpp @@ -161,12 +161,12 @@ void SaveInfo::setGameId(uint newGameId) uint SaveInfo::episode() const { - return _episode - 1; + return _episode; } uint SaveInfo::map() const { - return _map - 1; + return _map; } #if !__JHEXEN__ @@ -189,10 +189,10 @@ void SaveInfo::configure() #if __JHEXEN__ _episode = 1; #else - _episode = gameEpisode + 1; + _episode = gameEpisode; _mapTime = ::mapTime; #endif - _map = gameMap + 1; + _map = gameMap; // Make a copy of the current game rules. G_GetGameRules(&_gameRules); @@ -274,28 +274,39 @@ void SaveInfo::read(Reader *reader) else { #if !__JHEXEN__ - // In DOOM the high bit of the skill mode byte is also used for the - // "fast" game rule dd_bool. There is more confusion in that SM_NOTHINGS - // will result in 0xff and thus always set the fast bit. - // - // Here we decipher this assuming that if the skill mode is invalid then - // by default this means "spawn no things" and if so then the "fast" game - // rule is meaningless so it is forced off. - byte skillModePlusFastBit = Reader_ReadByte(reader); - _gameRules.skill = (skillmode_t) (skillModePlusFastBit & 0x7f); - if(_gameRules.skill < SM_BABY || _gameRules.skill >= NUM_SKILL_MODES) + if(_version < 13) { - _gameRules.skill = SM_NOTHINGS; - _gameRules.fast = 0; + // In DOOM the high bit of the skill mode byte is also used for the + // "fast" game rule dd_bool. There is more confusion in that SM_NOTHINGS + // will result in 0xff and thus always set the fast bit. + // + // Here we decipher this assuming that if the skill mode is invalid then + // by default this means "spawn no things" and if so then the "fast" game + // rule is meaningless so it is forced off. + byte skillModePlusFastBit = Reader_ReadByte(reader); + _gameRules.skill = (skillmode_t) (skillModePlusFastBit & 0x7f); + if(_gameRules.skill < SM_BABY || _gameRules.skill >= NUM_SKILL_MODES) + { + _gameRules.skill = SM_NOTHINGS; + _gameRules.fast = 0; + } + else + { + _gameRules.fast = (skillModePlusFastBit & 0x80) != 0; + } } else +#endif { - _gameRules.fast = (skillModePlusFastBit & 0x80) != 0; + _gameRules.skill = skillmode_t( Reader_ReadByte(reader) & 0x7f ); + + // Interpret skill levels outside the normal range as "spawn no things". + if(_gameRules.skill < SM_BABY || _gameRules.skill >= NUM_SKILL_MODES) + _gameRules.skill = SM_NOTHINGS; } -#endif - _episode = Reader_ReadByte(reader); - _map = Reader_ReadByte(reader); + _episode = Reader_ReadByte(reader) - 1; + _map = Reader_ReadByte(reader) - 1; _gameRules.deathmatch = Reader_ReadByte(reader); #if !__JHEXEN__ diff --git a/doomsday/plugins/doom/src/p_oldsvg.cpp b/doomsday/plugins/doom/src/p_oldsvg.cpp index 27214ef785..5e0a46849e 100644 --- a/doomsday/plugins/doom/src/p_oldsvg.cpp +++ b/doomsday/plugins/doom/src/p_oldsvg.cpp @@ -893,7 +893,7 @@ static void SaveInfo_Read_Dm_v19(SaveInfo *info, Reader *reader) Reader_Read(reader, vcheck, VERSIONSIZE); //DENG_ASSERT(!strncmp(vcheck, "version ", 8)); // Ensure save state format has been recognised by now. - info->_version = atoi(&vcheck[8]); + info->_version = atoi(&vcheck[8]); info->_gameRules.skill = (skillmode_t) Reader_ReadByte(reader); @@ -901,8 +901,8 @@ static void SaveInfo_Read_Dm_v19(SaveInfo *info, Reader *reader) if(info->_gameRules.skill < SM_BABY || info->_gameRules.skill >= NUM_SKILL_MODES) info->_gameRules.skill = SM_NOTHINGS; - info->_episode = Reader_ReadByte(reader); - info->_map = Reader_ReadByte(reader); + info->_episode = Reader_ReadByte(reader) - 1; + info->_map = Reader_ReadByte(reader) - 1; for(int i = 0; i < 4; ++i) { @@ -915,12 +915,12 @@ static void SaveInfo_Read_Dm_v19(SaveInfo *info, Reader *reader) int a = Reader_ReadByte(reader); int b = Reader_ReadByte(reader); int c = Reader_ReadByte(reader); - info->_mapTime = (a << 16) + (b << 8) + c; + info->_mapTime = (a << 16) + (b << 8) + c; - info->_magic = 0; // Initialize with *something*. + info->_magic = 0; // Initialize with *something*. /// @note Older formats do not contain all needed values: - info->_gameMode = gameMode; // Assume the current mode. + info->_gameMode = gameMode; // Assume the current mode. info->_gameRules.deathmatch = 0; info->_gameRules.noMonsters = 0; diff --git a/doomsday/plugins/heretic/src/p_oldsvg.cpp b/doomsday/plugins/heretic/src/p_oldsvg.cpp index 816cee4018..69896ebaba 100644 --- a/doomsday/plugins/heretic/src/p_oldsvg.cpp +++ b/doomsday/plugins/heretic/src/p_oldsvg.cpp @@ -901,7 +901,7 @@ static void SaveInfo_Read_Hr_v13(SaveInfo *info, Reader *reader) char vcheck[VERSIONSIZE]; Reader_Read(reader, vcheck, VERSIONSIZE); //DENG_ASSERT(!strncmp(vcheck, "version ", 8)); // Ensure save state format has been recognised by now. - info->_version = atoi(&vcheck[8]); + info->_version = atoi(&vcheck[8]); info->_gameRules.skill = (skillmode_t) Reader_ReadByte(reader); @@ -909,8 +909,8 @@ static void SaveInfo_Read_Hr_v13(SaveInfo *info, Reader *reader) if(info->_gameRules.skill < SM_BABY || info->_gameRules.skill >= NUM_SKILL_MODES) info->_gameRules.skill = SM_NOTHINGS; - info->_episode = Reader_ReadByte(reader); - info->_map = Reader_ReadByte(reader); + info->_episode = Reader_ReadByte(reader) - 1; + info->_map = Reader_ReadByte(reader) - 1; for(int i = 0; i < 4; ++i) { info->_players[i] = Reader_ReadByte(reader); @@ -921,12 +921,12 @@ static void SaveInfo_Read_Hr_v13(SaveInfo *info, Reader *reader) int a = Reader_ReadByte(reader); int b = Reader_ReadByte(reader); int c = Reader_ReadByte(reader); - info->_mapTime = (a << 16) + (b << 8) + c; + info->_mapTime = (a << 16) + (b << 8) + c; - info->_magic = 0; // Initialize with *something*. + info->_magic = 0; // Initialize with *something*. /// @note Older formats do not contain all needed values: - info->_gameMode = gameMode; // Assume the current mode. + info->_gameMode = gameMode; // Assume the current mode. info->_gameRules.deathmatch = 0; info->_gameRules.noMonsters = 0; From dc3f67c82f6e4ced846538bc3e97faaba1b21c4e Mon Sep 17 00:00:00 2001 From: danij Date: Tue, 4 Feb 2014 03:28:26 +0000 Subject: [PATCH 082/106] libcommon: Ensure game rule changes are fully applied when loading a savegame --- doomsday/plugins/common/include/gamerules.h | 4 +- doomsday/plugins/common/src/d_net.c | 28 +++---- doomsday/plugins/common/src/d_netcl.c | 23 +++--- doomsday/plugins/common/src/d_netsv.c | 28 +++---- doomsday/plugins/common/src/fi_lib.c | 2 +- doomsday/plugins/common/src/g_game.c | 88 ++++++++------------- doomsday/plugins/common/src/hu_automap.c | 5 +- doomsday/plugins/common/src/hu_stuff.cpp | 10 +-- doomsday/plugins/common/src/p_actor.cpp | 4 +- doomsday/plugins/common/src/p_inventory.c | 8 +- doomsday/plugins/common/src/p_map.cpp | 4 +- doomsday/plugins/common/src/p_mapsetup.cpp | 18 ++--- doomsday/plugins/common/src/p_player.c | 28 +++---- doomsday/plugins/common/src/p_saveg.cpp | 38 +++------ doomsday/plugins/common/src/p_start.cpp | 9 +-- doomsday/plugins/common/src/p_xgline.c | 8 +- doomsday/plugins/common/src/saveinfo.cpp | 2 +- doomsday/plugins/doom/include/g_game.h | 10 +-- doomsday/plugins/doom/src/d_main.c | 15 ++-- doomsday/plugins/doom/src/d_refresh.c | 2 +- doomsday/plugins/doom/src/m_cheat.c | 10 +-- doomsday/plugins/doom/src/p_enemy.c | 6 +- doomsday/plugins/doom/src/p_inter.c | 14 ++-- doomsday/plugins/doom/src/p_mobj.c | 17 ++-- doomsday/plugins/doom/src/p_oldsvg.cpp | 8 +- doomsday/plugins/doom/src/st_stuff.c | 16 ++-- doomsday/plugins/doom/src/wi_stuff.c | 6 +- doomsday/plugins/doom64/include/g_game.h | 10 +-- doomsday/plugins/doom64/src/d_main.c | 15 ++-- doomsday/plugins/doom64/src/d_refresh.c | 11 ++- doomsday/plugins/doom64/src/p_enemy.c | 4 +- doomsday/plugins/doom64/src/p_inter.c | 20 ++--- doomsday/plugins/doom64/src/p_mobj.c | 16 ++-- doomsday/plugins/doom64/src/st_stuff.c | 26 +++--- doomsday/plugins/doom64/src/wi_stuff.c | 6 +- doomsday/plugins/heretic/include/g_game.h | 10 +-- doomsday/plugins/heretic/src/h_main.c | 8 +- doomsday/plugins/heretic/src/h_refresh.c | 8 +- doomsday/plugins/heretic/src/in_lude.c | 2 +- doomsday/plugins/heretic/src/m_cheat.c | 18 ++--- doomsday/plugins/heretic/src/p_enemy.c | 6 +- doomsday/plugins/heretic/src/p_inter.c | 21 ++--- doomsday/plugins/heretic/src/p_mobj.c | 10 +-- doomsday/plugins/heretic/src/p_oldsvg.cpp | 8 +- doomsday/plugins/heretic/src/p_telept.c | 12 +-- doomsday/plugins/heretic/src/st_stuff.c | 18 ++--- doomsday/plugins/hexen/include/g_game.h | 9 +-- doomsday/plugins/hexen/src/a_action.c | 7 +- doomsday/plugins/hexen/src/acscript.cpp | 6 +- doomsday/plugins/hexen/src/h2_main.c | 10 ++- doomsday/plugins/hexen/src/hrefresh.c | 14 ++-- doomsday/plugins/hexen/src/in_lude.c | 7 +- doomsday/plugins/hexen/src/m_cheat.c | 24 +++--- doomsday/plugins/hexen/src/p_enemy.c | 37 ++++----- doomsday/plugins/hexen/src/p_inter.c | 65 ++++++++------- doomsday/plugins/hexen/src/p_maputl.c | 8 +- doomsday/plugins/hexen/src/p_mobj.c | 8 +- doomsday/plugins/hexen/src/p_pspr.c | 5 +- doomsday/plugins/hexen/src/p_spec.c | 2 +- doomsday/plugins/hexen/src/p_telept.c | 11 +-- doomsday/plugins/hexen/src/p_things.c | 8 +- doomsday/plugins/hexen/src/st_stuff.c | 24 +++--- 62 files changed, 427 insertions(+), 458 deletions(-) diff --git a/doomsday/plugins/common/include/gamerules.h b/doomsday/plugins/common/include/gamerules.h index deb553303d..af6ff23485 100644 --- a/doomsday/plugins/common/include/gamerules.h +++ b/doomsday/plugins/common/include/gamerules.h @@ -25,7 +25,9 @@ /** * @ingroup libcommon - */ + * + * @todo Separate behaviors so that each rule is singular. +*/ typedef struct gameruleset_s { skillmode_t skill; diff --git a/doomsday/plugins/common/src/d_net.c b/doomsday/plugins/common/src/d_net.c index f6c0628fea..3222b04cd8 100644 --- a/doomsday/plugins/common/src/d_net.c +++ b/doomsday/plugins/common/src/d_net.c @@ -103,16 +103,16 @@ void NetSv_ApplyGameRulesFromConfig(void) if(IS_CLIENT) return; - deathmatch = cfg.netDeathmatch; - noMonstersParm = cfg.netNoMonsters; + gameRules.deathmatch = cfg.netDeathmatch; + gameRules.noMonsters = cfg.netNoMonsters; cfg.jumpEnabled = cfg.netJumping; #if __JDOOM__ || __JHERETIC__ || __JDOOM64__ - respawnMonsters = cfg.netRespawn; + gameRules.respawnMonsters = cfg.netRespawn; #endif #if __JHEXEN__ - randomClassParm = cfg.netRandomClass; + gameRules.randomClasses = cfg.netRandomClass; #endif NetSv_UpdateGameConfigDescription(); @@ -180,10 +180,10 @@ int D_NetServerClose(int before) /// @todo fixme: "normal" is defined by the game rules config which may /// be changed from the command line (e.g., -fast, -nomonsters). /// In order to "restore normal" this logic is insufficient. - deathmatch = false; - noMonstersParm = false; + gameRules.deathmatch = false; + gameRules.noMonsters = false; #if __JHEXEN__ - randomClassParm = false; + gameRules.randomClasses = false; #endif D_NetMessage(CONSOLEPLAYER, "NETGAME ENDS"); @@ -215,10 +215,10 @@ int D_NetDisconnect(int before) return true; // Restore normal game state. - deathmatch = false; - noMonstersParm = false; + gameRules.deathmatch = false; + gameRules.noMonsters = false; #if __JHEXEN__ - randomClassParm = false; + gameRules.randomClasses = false; #endif D_NetClearBuffer(); @@ -378,14 +378,14 @@ int D_NetWorldEvent(int type, int parm, void* data) G_DemoEnds(); // Restore normal game state. - deathmatch = false; - noMonstersParm = false; + gameRules.deathmatch = false; + gameRules.noMonsters = false; #if __JDOOM__ || __JHERETIC__ || __JDOOM64__ - respawnMonsters = false; + gameRules.respawnMonsters = false; #endif #if __JHEXEN__ - randomClassParm = false; + gameRules.randomClasses = false; #endif break; #endif diff --git a/doomsday/plugins/common/src/d_netcl.c b/doomsday/plugins/common/src/d_netcl.c index 77221b8569..070c03edc3 100644 --- a/doomsday/plugins/common/src/d_netcl.c +++ b/doomsday/plugins/common/src/d_netcl.c @@ -109,32 +109,32 @@ void NetCl_UpdateGameState(Reader* msg) } } - deathmatch = gsDeathmatch; - noMonstersParm = !gsMonsters; + gameRules.deathmatch = gsDeathmatch; + gameRules.noMonsters = !gsMonsters; #if !__JHEXEN__ - respawnMonsters = gsRespawn; + gameRules.respawnMonsters = gsRespawn; #endif // Some statistics. #if __JHEXEN__ App_Log(DE2_LOG_NOTE, "Game state: Map=%u Skill=%i %s", gsMap+1, gsSkill, - deathmatch == 1 ? "Deathmatch" : - deathmatch == 2 ? "Deathmatch2" : "Co-op"); + gameRules.deathmatch == 1 ? "Deathmatch" : + gameRules.deathmatch == 2 ? "Deathmatch2" : "Co-op"); #else App_Log(DE2_LOG_NOTE, "Game state: Map=%u Episode=%u Skill=%i %s", gsMap+1, gsEpisode+1, gsSkill, - deathmatch == 1 ? "Deathmatch" : - deathmatch == 2 ? "Deathmatch2" : "Co-op"); + gameRules.deathmatch == 1 ? "Deathmatch" : + gameRules.deathmatch == 2 ? "Deathmatch2" : "Co-op"); #endif #if !__JHEXEN__ App_Log(DE2_LOG_NOTE, " Respawn=%s Monsters=%s Jumping=%s Gravity=%.1f", - respawnMonsters ? "yes" : "no", !noMonstersParm ? "yes" : "no", + gameRules.respawnMonsters ? "yes" : "no", !gameRules.noMonsters ? "yes" : "no", gsJumping ? "yes" : "no", gsGravity); #else App_Log(DE2_NET_NOTE, " Monsters=%s Jumping=%s Gravity=%.1f", - !noMonstersParm ? "yes" : "no", + !gameRules.noMonsters ? "yes" : "no", gsJumping ? "yes" : "no", gsGravity); #endif @@ -148,9 +148,10 @@ void NetCl_UpdateGameState(Reader* msg) } else { - gameSkill = gsSkill; gameEpisode = gsEpisode; - gameMap = gsMap; + gameMap = gsMap; + + gameRules.skill = gsSkill; /// @todo Not communicated to clients?? //gameMapEntryPoint = gsMapEntryPoint; diff --git a/doomsday/plugins/common/src/d_netsv.c b/doomsday/plugins/common/src/d_netsv.c index 9721f18668..0ca78f0c20 100644 --- a/doomsday/plugins/common/src/d_netsv.c +++ b/doomsday/plugins/common/src/d_netsv.c @@ -99,19 +99,19 @@ void NetSv_UpdateGameConfigDescription(void) memset(gameConfigString, 0, sizeof(gameConfigString)); - sprintf(gameConfigString, "skill%i", gameSkill + 1); + sprintf(gameConfigString, "skill%i", gameRules.skill + 1); - if(deathmatch > 1) - sprintf(gameConfigString, " dm%i", deathmatch); - else if(deathmatch) + if(gameRules.deathmatch > 1) + sprintf(gameConfigString, " dm%i", gameRules.deathmatch); + else if(gameRules.deathmatch) strcat(gameConfigString, " dm"); else strcat(gameConfigString, " coop"); - if(noMonstersParm) + if(gameRules.noMonsters) strcat(gameConfigString, " nomonst"); #if !__JHEXEN__ - if(respawnMonsters) + if(gameRules.respawnMonsters) strcat(gameConfigString, " respawn"); #endif @@ -586,18 +586,18 @@ void NetSv_NewPlayerEnters(int plrNum) NetSv_ResetPlayerFrags(plrNum); // Spawn the player into the world. - if(deathmatch) + if(gameRules.deathmatch) { G_DeathMatchSpawnPlayer(plrNum); } else { playerclass_t pClass = P_ClassForPlayerWhenRespawning(plrNum, false); - const playerstart_t* start; + playerstart_t const *start; if((start = P_GetPlayerStart(gameMapEntryPoint, plrNum, false))) { - const mapspot_t* spot = &mapSpots[start->spot]; + mapspot_t const *spot = &mapSpots[start->spot]; App_Log(DE2_DEV_MAP_MSG, "NetSv_NewPlayerEnters: Spawning player with angle:%x", spot->angle); @@ -764,17 +764,17 @@ void NetSv_SendGameState(int flags, int to) Writer_WriteByte(writer, gameEpisode); Writer_WriteByte(writer, gameMap); - Writer_WriteByte(writer, (deathmatch & 0x3) - | (!noMonstersParm? 0x4 : 0) + Writer_WriteByte(writer, (gameRules.deathmatch & 0x3) + | (!gameRules.noMonsters? 0x4 : 0) #if !__JHEXEN__ - | (respawnMonsters? 0x8 : 0) + | (gameRules.respawnMonsters? 0x8 : 0) #else | 0 #endif | (cfg.jumpEnabled? 0x10 : 0)); // Note that SM_NOTHINGS will result in a value of '7'. - Writer_WriteByte(writer, gameSkill & 0x7); + Writer_WriteByte(writer, gameRules.skill & 0x7); Writer_WriteFloat(writer, (float)P_GetGravity()); if(flags & GSF_CAMERA_INIT) @@ -1201,7 +1201,7 @@ void NetSv_KillMessage(player_t *killer, player_t *fragged, dd_bool stomping) #if __JDOOM__ || __JDOOM64__ char buf[500], *in, tmp[2]; - if(!cfg.killMessages || !deathmatch) + if(!cfg.killMessages || !gameRules.deathmatch) return; buf[0] = 0; diff --git a/doomsday/plugins/common/src/fi_lib.c b/doomsday/plugins/common/src/fi_lib.c index e40c1897ef..8e6d1dbdc3 100644 --- a/doomsday/plugins/common/src/fi_lib.c +++ b/doomsday/plugins/common/src/fi_lib.c @@ -533,7 +533,7 @@ int Hook_FinaleScriptEvalIf(int hookType, int finaleId, void* paramaters) if(!stricmp(p->token, "deathmatch")) { - p->returnVal = (deathmatch != false); + p->returnVal = (gameRules.deathmatch != false); return true; } diff --git a/doomsday/plugins/common/src/g_game.c b/doomsday/plugins/common/src/g_game.c index 0ccc25124f..e4468ce928 100644 --- a/doomsday/plugins/common/src/g_game.c +++ b/doomsday/plugins/common/src/g_game.c @@ -164,10 +164,10 @@ game_config_t cfg; // The global cfg. skillmode_t dSkill; // Default. dd_bool gameInProgress; -skillmode_t gameSkill; uint gameEpisode; uint gameMap; uint gameMapEntryPoint; // Position indicator for reborn. +GameRuleset gameRules; uint nextMap; #if __JHEXEN__ @@ -182,12 +182,8 @@ dd_bool secretExit; uint mapHub = 0; #endif -#if __JDOOM__ || __JHERETIC__ || __JDOOM64__ -dd_bool respawnMonsters; -#endif dd_bool monsterInfight; -dd_bool deathmatch; // Only if started as net death. player_t players[MAXPLAYERS]; int mapStartTic; // Game tic at map start. @@ -249,7 +245,7 @@ static gamestate_t gameState = GS_STARTUP; cvartemplate_t gamestatusCVars[] = { {"game-music", READONLYCVAR, CVT_INT, &gsvCurrentMusic, 0, 0}, - {"game-skill", READONLYCVAR, CVT_INT, &gameSkill, 0, 0}, + {"game-skill", READONLYCVAR, CVT_INT, &gameRules.skill, 0, 0}, {"game-state", READONLYCVAR, CVT_INT, &gameState, 0, 0}, {"game-state-map", READONLYCVAR, CVT_INT, &gsvInMap, 0, 0}, #if !__JHEXEN__ @@ -1819,7 +1815,7 @@ void G_PlayerLeaveMap(int player) memset(p->powers, 0, sizeof(p->powers)); #if __JHEXEN__ - if(!newCluster && !deathmatch) + if(!newCluster && !gameRules.deathmatch) p->powers[PT_FLIGHT] = flightPower; // Restore flight. #endif @@ -1828,7 +1824,7 @@ void G_PlayerLeaveMap(int player) p->update |= PSF_KEYS; memset(p->keys, 0, sizeof(p->keys)); #else - if(!deathmatch && newCluster) + if(!gameRules.deathmatch && newCluster) p->keys = 0; #endif @@ -2185,26 +2181,6 @@ static void G_InitNewGame(void) #endif } -void G_GetGameRules(GameRuleset *rules) -{ - DENG_ASSERT(rules != 0); -#if __JHEXEN__ - rules->skill = gameSkill; - rules->randomClasses = randomClassParm; -#else - rules->skill = gameSkill; - rules->fast = fastParm; -#endif - rules->deathmatch = deathmatch; - rules->noMonsters = noMonstersParm; - -#if __JHEXEN__ - rules->randomClasses = randomClassParm; -#else - rules->respawnMonsters = respawnMonsters; -#endif -} - #if __JDOOM__ || __JDOOM64__ static void G_ApplyGameRuleFastMonsters(dd_bool fast) { @@ -2252,33 +2228,35 @@ static void G_ApplyGameRules(skillmode_t skill) skill = SM_NOTHINGS; if(skill > NUM_SKILL_MODES - 1) skill = NUM_SKILL_MODES - 1; - gameSkill = skill; + gameRules.skill = skill; #if __JDOOM__ || __JHERETIC__ || __JDOOM64__ if(!IS_NETGAME) { - deathmatch = false; - respawnMonsters = false; + gameRules.deathmatch = false; + gameRules.respawnMonsters = false; noMonstersParm = CommandLine_Exists("-nomonsters")? true : false; + + gameRules.noMonsters = noMonstersParm; } #endif #if __JDOOM__ || __JHERETIC__ || __JDOOM64__ - respawnMonsters = respawnParm; + gameRules.respawnMonsters = respawnParm; #endif #if __JDOOM__ || __JHERETIC__ // Is respawning enabled at all in nightmare skill? - if(gameSkill == SM_NIGHTMARE) - respawnMonsters = cfg.respawnMonstersNightmare; + if(gameRules.skill == SM_NIGHTMARE) + gameRules.respawnMonsters = cfg.respawnMonstersNightmare; #endif // Fast monsters? #if __JDOOM__ || __JDOOM64__ { - dd_bool fastMonsters = fastParm; + dd_bool fastMonsters = gameRules.fast; # if __JDOOM__ - if(gameSkill == SM_NIGHTMARE) fastMonsters = true; + if(gameRules.skill == SM_NIGHTMARE) fastMonsters = true; # endif G_ApplyGameRuleFastMonsters(fastMonsters); } @@ -2287,9 +2265,9 @@ static void G_ApplyGameRules(skillmode_t skill) // Fast missiles? #if __JDOOM__ || __JHERETIC__ || __JDOOM64__ { - dd_bool fastMissiles = fastParm; + dd_bool fastMissiles = gameRules.fast; # if !__JDOOM64__ - if(gameSkill == SM_NIGHTMARE) fastMissiles = true; + if(gameRules.skill == SM_NIGHTMARE) fastMissiles = true; # endif G_ApplyGameRuleFastMissiles(fastMissiles); } @@ -2446,7 +2424,7 @@ void G_DoMapCompleted(void) } #elif __JHEXEN__ - if(!deathmatch) + if(!gameRules.deathmatch) { G_IntermissionDone(); return; @@ -2604,7 +2582,7 @@ void G_DoLeaveMap(void) { #if __JHEXEN__ playerbackup_t playerBackup[MAXPLAYERS]; - dd_bool oldRandomClassParm; + dd_bool oldRandomClassesRule; #endif loadmap_params_t p; ddfinale_t fin; @@ -2629,7 +2607,7 @@ void G_DoLeaveMap(void) * whether we need to load the archived map state. */ revisit = SV_HxHaveMapStateForSlot(BASE_SLOT, nextMap); - if(deathmatch) revisit = false; + if(gameRules.deathmatch) revisit = false; // Same cluster? { @@ -2637,7 +2615,7 @@ void G_DoLeaveMap(void) Uri *nextMapUri = G_ComposeMapUri(gameEpisode, nextMap); if(P_MapInfo(mapUri)->cluster == P_MapInfo(nextMapUri)->cluster) { - if(!deathmatch) + if(!gameRules.deathmatch) { // Save current map. SV_HxSaveClusterMap(); @@ -2645,14 +2623,14 @@ void G_DoLeaveMap(void) } else // Entering new cluster. { - if(!deathmatch) + if(!gameRules.deathmatch) { SV_ClearSlot(BASE_SLOT); } // Re-apply the game rules. /// @todo Necessary? - G_ApplyGameRules(gameSkill); + G_ApplyGameRules(gameRules.skill); } Uri_Delete(nextMapUri); @@ -2664,8 +2642,8 @@ void G_DoLeaveMap(void) SV_HxBackupPlayersInCluster(playerBackup); // Disable class randomization (all players must spawn as their existing class). - oldRandomClassParm = randomClassParm; - randomClassParm = false; + oldRandomClassesRule = gameRules.randomClasses; + gameRules.randomClasses = false; // We don't want to see a briefing if we've already visited this map. if(revisit) briefDisabled = true; @@ -2738,8 +2716,8 @@ void G_DoLeaveMap(void) SV_HxRestorePlayersInCluster(playerBackup, nextMapEntryPoint); - // Restore the random class option. - randomClassParm = oldRandomClassParm; + // Restore the random class rule. + gameRules.randomClasses = oldRandomClassesRule; // Launch waiting scripts. Game_ACScriptInterpreter_RunDeferredTasks(p.mapUri); @@ -2748,7 +2726,7 @@ void G_DoLeaveMap(void) Uri_Delete(p.mapUri); // In a non-network, non-deathmatch game, save immediately into the autosave slot. - if(!IS_NETGAME && !deathmatch) + if(!IS_NETGAME && !gameRules.deathmatch) { AutoStr *name = G_GenerateSaveGameName(); savestateworker_params_t p; @@ -3121,7 +3099,7 @@ char const *P_GetGameModeName(void) static char const *sp = "singleplayer"; if(IS_NETGAME) { - if(deathmatch) return dm; + if(gameRules.deathmatch) return dm; return coop; } return sp; @@ -3535,13 +3513,13 @@ int Hook_DemoStop(int hookType, int val, void* paramaters) if(IS_NETGAME && IS_CLIENT) { // Restore normal game state? - deathmatch = false; - noMonstersParm = false; + gameRules.deathmatch = false; + gameRules.noMonsters = false; #if __JDOOM__ || __JHERETIC__ || __JDOOM64__ - respawnMonsters = false; + gameRules.respawnMonsters = false; #endif #if __JHEXEN__ - randomClassParm = false; + gameRules.randomClasses = false; #endif } @@ -4025,7 +4003,7 @@ D_CMD(WarpMap) nextMapEntryPoint = 0; G_SetGameAction(GA_LEAVEMAP); #else - G_DeferredNewGame(gameSkill, epsd, map, 0/*default*/); + G_DeferredNewGame(gameRules.skill, epsd, map, 0/*default*/); #endif } else diff --git a/doomsday/plugins/common/src/hu_automap.c b/doomsday/plugins/common/src/hu_automap.c index 8a51d7e628..afd820c0b2 100644 --- a/doomsday/plugins/common/src/hu_automap.c +++ b/doomsday/plugins/common/src/hu_automap.c @@ -958,7 +958,10 @@ static void rendPlayerMarkers(uiwidget_t* obj) for(i = 0; i < MAXPLAYERS; ++i) { // Do not show markers for other players in deathmatch. - if(deathmatch && i != UIWidget_Player(obj)) continue; + if(gameRules.deathmatch && i != UIWidget_Player(obj)) + { + continue; + } drawPlayerMarker(i, am->mcfg); } diff --git a/doomsday/plugins/common/src/hu_stuff.cpp b/doomsday/plugins/common/src/hu_stuff.cpp index 43ccda05eb..cc5908cdac 100644 --- a/doomsday/plugins/common/src/hu_stuff.cpp +++ b/doomsday/plugins/common/src/hu_stuff.cpp @@ -410,15 +410,15 @@ void HU_DrawText(const char* str, float x, float y, float scale, } /// Predicate for sorting score infos. -int scoreInfoCompare(const void* a_, const void* b_) +int scoreInfoCompare(void const *a_, void const *b_) { - const scoreinfo_t* a = (scoreinfo_t*) a_; - const scoreinfo_t* b = (scoreinfo_t*) b_; + scoreinfo_t const *a = (scoreinfo_t *) a_; + scoreinfo_t const *b = (scoreinfo_t *) b_; if(a->kills > b->kills) return -1; if(b->kills > a->kills) return 1; - if(deathmatch) + if(gameRules.deathmatch) { // In deathmatch, suicides affect your place on the scoreboard. if(a->suicides < b->suicides) return -1; @@ -493,7 +493,7 @@ static int populateScoreInfo(scoreinfo_t* scoreBoard, int maxPlayers, int player } #endif - if(deathmatch) + if(gameRules.deathmatch) { for(int j = 0; j < maxPlayers; ++j) { diff --git a/doomsday/plugins/common/src/p_actor.cpp b/doomsday/plugins/common/src/p_actor.cpp index 11062e7ca3..4730bce15b 100644 --- a/doomsday/plugins/common/src/p_actor.cpp +++ b/doomsday/plugins/common/src/p_actor.cpp @@ -82,8 +82,8 @@ void P_MobjRemove(mobj_t *mo, dd_bool noRespawn) if( # if __JDOOM__ // Only respawn items in deathmatch 2 and optionally in coop. - !(deathmatch != 2 && (!cfg.coopRespawnItems || !IS_NETGAME || - deathmatch)) && + !(gameRules.deathmatch != 2 && (!cfg.coopRespawnItems || !IS_NETGAME || + gameRules.deathmatch)) && # endif /*#elif __JDOOM64__ (spot->flags & MTF_RESPAWN) && # endif*/ diff --git a/doomsday/plugins/common/src/p_inventory.c b/doomsday/plugins/common/src/p_inventory.c index 390f3e59d8..ecae761a75 100644 --- a/doomsday/plugins/common/src/p_inventory.c +++ b/doomsday/plugins/common/src/p_inventory.c @@ -217,14 +217,14 @@ static dd_bool useItem(playerinventory_t* inv, inventoryitemtype_t type, return didUseItem; } -static dd_bool giveItem(playerinventory_t* inv, inventoryitemtype_t type) +static dd_bool giveItem(playerinventory_t *inv, inventoryitemtype_t type) { - unsigned int count = countItems(inv, type); - inventoryitem_t* item; + unsigned int count = countItems(inv, type); + inventoryitem_t *item; #if __JHEXEN__ // Can't carry more than 1 puzzle item in coop netplay. - if(count && type >= IIT_FIRSTPUZZITEM && IS_NETGAME && !deathmatch) + if(count && type >= IIT_FIRSTPUZZITEM && IS_NETGAME && !gameRules.deathmatch) return false; #endif diff --git a/doomsday/plugins/common/src/p_map.cpp b/doomsday/plugins/common/src/p_map.cpp index c55146f502..170c309dfa 100644 --- a/doomsday/plugins/common/src/p_map.cpp +++ b/doomsday/plugins/common/src/p_map.cpp @@ -450,7 +450,7 @@ static int PIT_CheckThing(mobj_t *thing, void * /*context*/) { if((thing->flags & MF_SHOOTABLE) && thing != tmThing->target) { - if(IS_NETGAME && !deathmatch && thing->player) + if(IS_NETGAME && !gameRules.deathmatch && thing->player) { return false; // don't attack other co-op players } @@ -2034,7 +2034,7 @@ static int PTR_AimTraverse(Intercept const *icpt, void * /*context*/) #endif #if __JDOOM__ || __JHEXEN__ || __JDOOM64__ - if(th->player && IS_NETGAME && !deathmatch) + if(th->player && IS_NETGAME && !gameRules.deathmatch) { return false; // Don't aim at fellow co-op players. } diff --git a/doomsday/plugins/common/src/p_mapsetup.cpp b/doomsday/plugins/common/src/p_mapsetup.cpp index f922835d98..ac96d6b3b3 100644 --- a/doomsday/plugins/common/src/p_mapsetup.cpp +++ b/doomsday/plugins/common/src/p_mapsetup.cpp @@ -208,19 +208,19 @@ static dd_bool checkMapSpotSpawnFlags(mapspot_t const *spot) return false; // Don't spawn things flagged for Not Deathmatch if we're deathmatching. - if(deathmatch && (spot->flags & MSF_NOTDM)) + if(gameRules.deathmatch && (spot->flags & MSF_NOTDM)) return false; // Don't spawn things flagged for Not Coop if we're coop'in. - if(IS_NETGAME && !deathmatch && (spot->flags & MSF_NOTCOOP)) + if(IS_NETGAME && !gameRules.deathmatch && (spot->flags & MSF_NOTCOOP)) return false; // The special "spawn no things" skill mode means nothing is spawned. - if(gameSkill == SM_NOTHINGS) + if(gameRules.skill == SM_NOTHINGS) return false; // Check for appropriate skill level. - if(!(spot->skillModes & (1 << gameSkill))) + if(!(spot->skillModes & (1 << gameRules.skill))) return false; #if __JHEXEN__ @@ -234,7 +234,7 @@ static dd_bool checkMapSpotSpawnFlags(mapspot_t const *spot) return false; } } - else if(!deathmatch) + else if(!gameRules.deathmatch) { // Cooperative mode. @@ -478,7 +478,7 @@ static void initMapSpots() P_DealPlayerStarts(0); - if(deathmatch) + if(gameRules.deathmatch) { uint numDMStarts = P_GetNumPlayerStarts(true); uint playerCount = 0; @@ -622,7 +622,7 @@ static void spawnMapObjects() if(!IS_CLIENT && maceSpotCount) { // Sometimes the Firemace doesn't show up if not in deathmatch. - if(!(!deathmatch && P_Random() < 64)) + if(!(!gameRules.deathmatch && P_Random() < 64)) { if(mapspot_t const *spot = P_ChooseRandomMaceSpot()) { @@ -996,7 +996,7 @@ static void P_ResetWorldState() } timerGame = 0; - if(deathmatch) + if(gameRules.deathmatch) { int parm = CommandLine_Check("-timer"); if(parm && parm < CommandLine_Count() - 1) @@ -1018,7 +1018,7 @@ static void P_ResetWorldState() plr->playerState = PST_REBORN; #if __JHEXEN__ - if(!IS_NETGAME || (IS_NETGAME != 0 && deathmatch != 0) || firstFragReset == 1) + if(!IS_NETGAME || (IS_NETGAME != 0 && gameRules.deathmatch != 0) || firstFragReset == 1) { memset(plr->frags, 0, sizeof(plr->frags)); firstFragReset = 0; diff --git a/doomsday/plugins/common/src/p_player.c b/doomsday/plugins/common/src/p_player.c index d1c99e6810..4a1158ab96 100644 --- a/doomsday/plugins/common/src/p_player.c +++ b/doomsday/plugins/common/src/p_player.c @@ -354,19 +354,19 @@ dd_bool P_PlayerInWalkState(player_t* pl) * Subtract the appropriate amount of ammo from the player for firing * the current ready weapon. * - * @param player The player doing the firing. + * @param player The player doing the firing. */ void P_ShotAmmo(player_t *player) { - ammotype_t i; - int fireMode; - weaponinfo_t* wInfo = + ammotype_t i; + int fireMode; + weaponinfo_t *wInfo = &weaponInfo[player->readyWeapon][player->class_]; if(IS_CLIENT) return; // Server keeps track of this. #if __JHERETIC__ - if(deathmatch) + if(gameRules.deathmatch) fireMode = 0; // In deathmatch always use mode zero. else fireMode = (player->powers[PT_WEAPONLEVEL2]? 1 : 0); @@ -469,7 +469,7 @@ weapontype_t P_MaybeChangeWeapon(player_t *player, weapontype_t weapon, continue; // Weapon does not take this type of ammo. #if __JHERETIC__ // Heretic always uses lvl 0 ammo requirements in deathmatch - if(deathmatch && + if(gameRules.deathmatch && player->ammo[ammotype].owned < winf->mode[0].perShot[ammotype]) { // Not enough ammo of this type. Candidate is NOT good. good = false; @@ -607,22 +607,22 @@ weapontype_t P_MaybeChangeWeapon(player_t *player, weapontype_t weapon, * Checks if the player has enough ammo to fire their readied weapon. * If not, a weapon change is instigated. * - * @return @c true, if there is enough ammo to fire. + * @return @c true, if there is enough ammo to fire. */ -dd_bool P_CheckAmmo(player_t* plr) +dd_bool P_CheckAmmo(player_t *plr) { - int fireMode; - dd_bool good; - ammotype_t i; - weaponinfo_t* wInfo; + int fireMode; + dd_bool good; + ammotype_t i; + weaponinfo_t *wInfo = + &weaponInfo[plr->readyWeapon][plr->class_]; - wInfo = &weaponInfo[plr->readyWeapon][plr->class_]; #if __JDOOM__ || __JDOOM64__ || __JHEXEN__ fireMode = 0; #endif #if __JHERETIC__ // If deathmatch always use firemode two ammo requirements. - if(plr->powers[PT_WEAPONLEVEL2] && !deathmatch) + if(plr->powers[PT_WEAPONLEVEL2] && !gameRules.deathmatch) fireMode = 1; else fireMode = 0; diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index 6b74d8ee43..ee01f949c9 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -3670,22 +3670,10 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) */ curInfo = saveInfo; - gameEpisode = saveInfo->episode(); - gameMap = saveInfo->map(); - - // Apply the game rules: - GameRuleset const &newRules = saveInfo->gameRules(); - gameSkill = newRules.skill; -#if !__JHEXEN__ - fastParm = newRules.fast; -#endif - deathmatch = newRules.deathmatch; - noMonstersParm = newRules.noMonsters; -#if __JHEXEN__ - randomClassParm = newRules.randomClasses; -#else - respawnMonsters = newRules.respawnMonsters; -#endif + gameEpisode = saveInfo->episode(); + gameMap = saveInfo->map(); + gameMapEntryPoint = 0; /// @todo Not saved?? + gameRules = saveInfo->gameRules(); #if __JHEXEN__ Game_ACScriptInterpreter().readWorldScriptData(reader, saveInfo->version()); @@ -3695,7 +3683,7 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) * Load the map and configure some game settings. */ briefDisabled = true; - G_NewGame(gameSkill, gameEpisode, gameMap, 0/*gameMapEntryPoint*/); + G_NewGame(gameRules.skill, gameEpisode, gameMap, 0/*gameMapEntryPoint*/); G_SetGameAction(GA_NONE); /// @todo Necessary? @@ -4008,11 +3996,7 @@ void SV_LoadGameClient(uint gameId) return; } - GameRuleset const &newRules = saveInfo->gameRules(); - gameSkill = newRules.skill; - deathmatch = newRules.deathmatch; - noMonstersParm = newRules.noMonsters; - respawnMonsters = newRules.respawnMonsters; + gameRules = saveInfo->gameRules(); // Do we need to change the map? if(gameMap != saveInfo->map() || gameEpisode != saveInfo->episode()) @@ -4020,7 +4004,7 @@ void SV_LoadGameClient(uint gameId) gameEpisode = saveInfo->episode(); gameMap = saveInfo->map(); gameMapEntryPoint = 0; - G_NewGame(gameSkill, gameEpisode, gameMap, gameMapEntryPoint); + G_NewGame(gameRules.skill, gameEpisode, gameMap, gameMapEntryPoint); /// @todo Necessary? G_SetGameAction(GA_NONE); } @@ -4336,7 +4320,7 @@ void SV_HxRestorePlayersInCluster(playerbackup_t playerBackup[MAXPLAYERS], plr->attacker = NULL; plr->poisoner = NULL; - if(IS_NETGAME || deathmatch) + if(IS_NETGAME || gameRules.deathmatch) { // In a network game, force all players to be alive if(plr->playerState == PST_DEAD) @@ -4344,7 +4328,7 @@ void SV_HxRestorePlayersInCluster(playerbackup_t playerBackup[MAXPLAYERS], plr->playerState = PST_REBORN; } - if(!deathmatch) + if(!gameRules.deathmatch) { // Cooperative net-play; retain keys and weapons. oldKeys = plr->keys; @@ -4358,7 +4342,7 @@ void SV_HxRestorePlayersInCluster(playerbackup_t playerBackup[MAXPLAYERS], wasReborn = (plr->playerState == PST_REBORN); - if(deathmatch) + if(gameRules.deathmatch) { memset(plr->frags, 0, sizeof(plr->frags)); ddplr->mo = NULL; @@ -4382,7 +4366,7 @@ void SV_HxRestorePlayersInCluster(playerbackup_t playerBackup[MAXPLAYERS], } } - if(wasReborn && IS_NETGAME && !deathmatch) + if(wasReborn && IS_NETGAME && !gameRules.deathmatch) { // Restore keys and weapons when reborn in co-op. plr->keys = oldKeys; diff --git a/doomsday/plugins/common/src/p_start.cpp b/doomsday/plugins/common/src/p_start.cpp index 7dcd9ba7cf..9e91039952 100644 --- a/doomsday/plugins/common/src/p_start.cpp +++ b/doomsday/plugins/common/src/p_start.cpp @@ -502,7 +502,7 @@ void P_SpawnPlayer(int plrNum, playerclass_t pClass, coord_t x, coord_t y, coord p->viewOffset[VX] = p->viewOffset[VY] = p->viewOffset[VZ] = 0; // Give all cards in death match mode. - if(deathmatch) + if(gameRules.deathmatch) { #if __JHEXEN__ p->keys = 2047; @@ -657,7 +657,7 @@ void P_RebornPlayerInMultiplayer(int plrNum) } // Spawn at random spot if in death match. - if(deathmatch) + if(gameRules.deathmatch) { G_DeathMatchSpawnPlayer(plrNum); return; @@ -888,12 +888,11 @@ void P_SpawnPlayers() // Spawn the client anywhere. P_SpawnClient(i); } - return; } // If deathmatch, randomly spawn the active players. - if(deathmatch) + if(gameRules.deathmatch) { for(int i = 0; i < MAXPLAYERS; ++i) { @@ -992,7 +991,7 @@ void G_DeathMatchSpawnPlayer(int playerNum) playerclass_t pClass; #if __JHEXEN__ - if(randomClassParm) + if(gameRules.randomClasses) { pClass = playerclass_t(P_Random() % 3); if(pClass == cfg.playerClass[playerNum]) // Not the same class, please. diff --git a/doomsday/plugins/common/src/p_xgline.c b/doomsday/plugins/common/src/p_xgline.c index 1d53cb9fa0..7311ed1c6c 100644 --- a/doomsday/plugins/common/src/p_xgline.c +++ b/doomsday/plugins/common/src/p_xgline.c @@ -2383,17 +2383,17 @@ int XL_LineEvent(int evtype, int linetype, Line* line, int sidenum, // Check skill level. // SM_NOTHINGS will be interpreted as SM_BABY. - if(gameSkill < 1) + if(gameRules.skill < 1) i = 1; - else if(gameSkill > 3) + else if(gameRules.skill > 3) i = 4; else - i = 1 << (gameSkill - 1); + i = 1 << (gameRules.skill - 1); if(!(info->flags2 & (i << LTF2_SKILL_SHIFT))) { XG_Dev(" Line %i: ABORTING EVENT due to skill level (%i)", - P_ToIndex(line), gameSkill); + P_ToIndex(line), gameRules.skill); return false; } diff --git a/doomsday/plugins/common/src/saveinfo.cpp b/doomsday/plugins/common/src/saveinfo.cpp index 5e9d4aa11e..0eddf9ae89 100644 --- a/doomsday/plugins/common/src/saveinfo.cpp +++ b/doomsday/plugins/common/src/saveinfo.cpp @@ -195,7 +195,7 @@ void SaveInfo::configure() _map = gameMap; // Make a copy of the current game rules. - G_GetGameRules(&_gameRules); + _gameRules = ::gameRules; #if !__JHEXEN__ for(int i = 0; i < MAXPLAYERS; i++) diff --git a/doomsday/plugins/doom/include/g_game.h b/doomsday/plugins/doom/include/g_game.h index fd74cc2be8..acbcace080 100644 --- a/doomsday/plugins/doom/include/g_game.h +++ b/doomsday/plugins/doom/include/g_game.h @@ -49,16 +49,14 @@ extern int gaLoadGameSlot; extern player_t players[MAXPLAYERS]; extern dd_bool gameInProgress; -extern skillmode_t gameSkill; extern uint gameEpisode; extern uint gameMap; extern uint gameMapEntryPoint; +extern GameRuleset gameRules; extern uint nextMap; // If non zero this will be the next map. extern dd_bool secretExit; extern int totalKills, totalItems, totalSecret; -extern dd_bool deathmatch; -extern dd_bool respawnMonsters; extern dd_bool paused; extern dd_bool precache; extern dd_bool customPal; @@ -74,12 +72,6 @@ void G_CommonPreInit(void); void G_CommonPostInit(void); void G_CommonShutdown(void); -/** - * Configure the given @a rules structure according to the @em current game rules. - * @todo Refactor away. - */ -void G_GetGameRules(GameRuleset *rules); - void R_InitRefresh(void); void G_PrintMapList(void); diff --git a/doomsday/plugins/doom/src/d_main.c b/doomsday/plugins/doom/src/d_main.c index 91b0f6c773..5b5bb22e28 100644 --- a/doomsday/plugins/doom/src/d_main.c +++ b/doomsday/plugins/doom/src/d_main.c @@ -462,24 +462,29 @@ void D_PostInit(void) monsterInfight = GetDefInt("AI|Infight", 0); // Get skill / episode / map from parms. - gameSkill = startSkill = SM_MEDIUM; + gameRules.skill = startSkill = SM_MEDIUM; startEpisode = 0; startMap = 0; autoStart = false; // Command line options. noMonstersParm = CommandLine_Check("-nomonsters")? true : false; - respawnParm = CommandLine_Check("-respawn")? true : false; - fastParm = CommandLine_Check("-fast")? true : false; - devParm = CommandLine_Check("-devparm")? true : false; + respawnParm = CommandLine_Check("-respawn")? true : false; + fastParm = CommandLine_Check("-fast")? true : false; + devParm = CommandLine_Check("-devparm")? true : false; if(CommandLine_Check("-altdeath")) cfg.netDeathmatch = 2; else if(CommandLine_Check("-deathmatch")) cfg.netDeathmatch = 1; + // Apply these rules. + gameRules.noMonsters = noMonstersParm; + gameRules.respawnMonsters = respawnParm; + gameRules.fast = fastParm; + p = CommandLine_Check("-timer"); - if(p && p < myargc - 1 && deathmatch) + if(p && p < myargc - 1 && gameRules.deathmatch) { int time = atoi(CommandLine_At(p + 1)); App_Log(DE2_LOG_NOTE, "Maps will end after %d %s", time, time == 1? "minute" : "minutes"); diff --git a/doomsday/plugins/doom/src/d_refresh.c b/doomsday/plugins/doom/src/d_refresh.c index 5d2b4e3ada..f48b2f264d 100644 --- a/doomsday/plugins/doom/src/d_refresh.c +++ b/doomsday/plugins/doom/src/d_refresh.c @@ -125,7 +125,7 @@ dd_bool R_ViewFilterColor(float rgba[4], int filter) rgba[CR] = 1; rgba[CG] = 0; rgba[CB] = 0; - rgba[CA] = (deathmatch? 1.0f : cfg.filterStrength) * (filter+1) / (float)NUMREDPALS; + rgba[CA] = (gameRules.deathmatch? 1.0f : cfg.filterStrength) * (filter+1) / (float)NUMREDPALS; return true; } diff --git a/doomsday/plugins/doom/src/m_cheat.c b/doomsday/plugins/doom/src/m_cheat.c index 89a5fae33a..bd19ac7f80 100644 --- a/doomsday/plugins/doom/src/m_cheat.c +++ b/doomsday/plugins/doom/src/m_cheat.c @@ -143,7 +143,7 @@ CHEAT_FUNC(Reveal) DENG_UNUSED(args); DENG_ASSERT(player >= 0 && player < MAXPLAYERS); - if(IS_NETGAME && deathmatch) return false; + if(IS_NETGAME && gameRules.deathmatch) return false; // Dead players can't cheat. if(plr->health <= 0) return false; @@ -240,7 +240,7 @@ D_CMD(CheatGod) { NetCl_CheatRequest("god"); } - else if((IS_NETGAME && !netSvAllowCheats) || gameSkill == SM_NIGHTMARE) + else if((IS_NETGAME && !netSvAllowCheats) || gameRules.skill == SM_NIGHTMARE) { return false; } @@ -286,7 +286,7 @@ D_CMD(CheatNoClip) { NetCl_CheatRequest("noclip"); } - else if((IS_NETGAME && !netSvAllowCheats) || gameSkill == SM_NIGHTMARE) + else if((IS_NETGAME && !netSvAllowCheats) || gameRules.skill == SM_NIGHTMARE) { return false; } @@ -462,7 +462,7 @@ D_CMD(CheatGive) return true; } - if((IS_NETGAME && !netSvAllowCheats) || gameSkill == SM_NIGHTMARE) + if((IS_NETGAME && !netSvAllowCheats) || gameRules.skill == SM_NIGHTMARE) return false; plr = &players[player]; @@ -652,7 +652,7 @@ D_CMD(CheatMassacre) { NetCl_CheatRequest("kill"); } - else if((IS_NETGAME && !netSvAllowCheats) || gameSkill == SM_NIGHTMARE) + else if((IS_NETGAME && !netSvAllowCheats) || gameRules.skill == SM_NIGHTMARE) { return false; } diff --git a/doomsday/plugins/doom/src/p_enemy.c b/doomsday/plugins/doom/src/p_enemy.c index baaaed3377..63fb2142bf 100644 --- a/doomsday/plugins/doom/src/p_enemy.c +++ b/doomsday/plugins/doom/src/p_enemy.c @@ -675,7 +675,7 @@ void C_DECL A_Chase(mobj_t *actor) if(actor->flags & MF_JUSTATTACKED) { actor->flags &= ~MF_JUSTATTACKED; - if(gameSkill != SM_NIGHTMARE && !fastParm) + if(gameRules.skill != SM_NIGHTMARE && !gameRules.fast) { newChaseDir(actor); } @@ -698,7 +698,7 @@ void C_DECL A_Chase(mobj_t *actor) // Check for missile attack. if((state = P_GetState(actor->type, SN_MISSILE)) != S_NULL) { - if(!(gameSkill != SM_NIGHTMARE && !fastParm && actor->moveCount)) + if(!(gameRules.skill != SM_NIGHTMARE && !gameRules.fast && actor->moveCount)) { if(checkMissileRange(actor)) { @@ -1845,7 +1845,7 @@ void C_DECL A_BrainSpit(mobj_t* mo) return; // Ignore if no targets. brain.easy ^= 1; - if(gameSkill <= SM_EASY && (!brain.easy)) + if(gameRules.skill <= SM_EASY && (!brain.easy)) return; // Shoot a cube at current target. diff --git a/doomsday/plugins/doom/src/p_inter.c b/doomsday/plugins/doom/src/p_inter.c index 4eef74ca4a..bb090b6177 100644 --- a/doomsday/plugins/doom/src/p_inter.c +++ b/doomsday/plugins/doom/src/p_inter.c @@ -80,7 +80,7 @@ static dd_bool giveOneAmmo(player_t *plr, ammotype_t ammoType, int numClips) } // Give double the number of rounds at easy/nightmare skill levels. - if(gameSkill == SM_BABY || gameSkill == SM_NIGHTMARE) + if(gameRules.skill == SM_BABY || gameRules.skill == SM_NIGHTMARE) { numRounds *= 2; } @@ -123,7 +123,7 @@ dd_bool P_GiveAmmo(player_t *plr, ammotype_t ammoType, int numClips) static dd_bool shouldForceWeaponChange(dd_bool dropped) { - return IS_NETGAME && deathmatch == 1 && !dropped; + return IS_NETGAME && gameRules.deathmatch == 1 && !dropped; } static int numAmmoClipsToGiveWithWeapon(dd_bool dropped) @@ -132,7 +132,7 @@ static int numAmmoClipsToGiveWithWeapon(dd_bool dropped) if(dropped) return 1; // Give extra clips in deathmatch. - return (IS_NETGAME && deathmatch == 1)? 5 : 2; + return (IS_NETGAME && gameRules.deathmatch == 1)? 5 : 2; } static dd_bool giveOneWeapon(player_t *plr, weapontype_t weaponType, dd_bool dropped) @@ -172,7 +172,7 @@ static dd_bool giveOneWeapon(player_t *plr, weapontype_t weaponType, dd_bool dro plr->update |= PSF_OWNED_WEAPONS; // Animate a pickup bonus flash? - if(IS_NETGAME && deathmatch != 2 && !dropped) + if(IS_NETGAME && gameRules.deathmatch != 2 && !dropped) { plr->bonusCount += BONUSADD; } @@ -532,7 +532,7 @@ static dd_bool pickupWeapon(player_t *plr, weapontype_t weaponType, if(plr->weapons[weaponType].owned) { // Leave placed weapons forever on net games. - if(IS_NETGAME && deathmatch != 2 && !dropped) + if(IS_NETGAME && gameRules.deathmatch != 2 && !dropped) return false; } @@ -1130,7 +1130,7 @@ int P_DamageMobj2(mobj_t* target, mobj_t* inflictor, mobj_t* source, if(source && source->player && source->player != target->player) { // Co-op damage disabled? - if(IS_NETGAME && !deathmatch && cfg.noCoopDamage) + if(IS_NETGAME && !gameRules.deathmatch && cfg.noCoopDamage) return 0; // Same color, no damage? @@ -1147,7 +1147,7 @@ int P_DamageMobj2(mobj_t* target, mobj_t* inflictor, mobj_t* source, } player = target->player; - if(player && gameSkill == SM_BABY) + if(player && gameRules.skill == SM_BABY) damage /= 2; // Take half damage in trainer mode. // Use the cvar damage multiplier netMobDamageModifier only if the diff --git a/doomsday/plugins/doom/src/p_mobj.c b/doomsday/plugins/doom/src/p_mobj.c index 21795f7445..ab0079b81e 100644 --- a/doomsday/plugins/doom/src/p_mobj.c +++ b/doomsday/plugins/doom/src/p_mobj.c @@ -656,7 +656,7 @@ void P_MobjThinker(void *thinkerPtr) if(!(mo->flags & MF_COUNTKILL)) return; - if(!respawnMonsters) + if(!gameRules.respawnMonsters) return; mo->moveCount++; @@ -683,14 +683,14 @@ mobj_t* P_SpawnMobjXYZ(mobjtype_t type, coord_t x, coord_t y, coord_t z, angle_t info = &MOBJINFO[type]; // Not for deathmatch? - if(deathmatch && (info->flags & MF_NOTDMATCH)) + if(gameRules.deathmatch && (info->flags & MF_NOTDMATCH)) return NULL; // Check for specific disabled objects. if(IS_NETGAME) { // Cooperative weapons? - if(cfg.noCoopWeapons && !deathmatch && type >= MT_CLIP && + if(cfg.noCoopWeapons && !gameRules.deathmatch && type >= MT_CLIP && type <= MT_SUPERSHOTGUN) return NULL; @@ -730,8 +730,8 @@ mobj_t* P_SpawnMobjXYZ(mobjtype_t type, coord_t x, coord_t y, coord_t z, angle_t break; } - // Don't spawn any monsters if -noMonstersParm. - if(noMonstersParm && ((info->flags & MF_COUNTKILL) || type == MT_SKULL)) + // Don't spawn any monsters? + if(gameRules.noMonsters && ((info->flags & MF_COUNTKILL) || type == MT_SKULL)) return NULL; if(info->flags & MF_SOLID) @@ -757,7 +757,7 @@ mobj_t* P_SpawnMobjXYZ(mobjtype_t type, coord_t x, coord_t y, coord_t z, angle_t // Let the engine know about solid objects. P_SetDoomsdayFlags(mo); - if(gameSkill != SM_NIGHTMARE) + if(gameRules.skill != SM_NIGHTMARE) mo->reactionTime = info->reactionTime; mo->lastLook = P_Random() % MAXPLAYERS; @@ -974,8 +974,9 @@ mobj_t* P_SpawnMissile(mobjtype_t type, mobj_t* source, mobj_t* dest) th->mom[MY] = th->info->speed * FIX2FLT(finesine[an]); if(source->player) - { // Allow free-aim with the BFG in deathmatch? - if(deathmatch && cfg.netBFGFreeLook == 0 && type == MT_BFG) + { + // Allow free-aim with the BFG in deathmatch? + if(gameRules.deathmatch && cfg.netBFGFreeLook == 0 && type == MT_BFG) th->mom[MZ] = 0; else th->mom[MZ] = th->info->speed * slope; diff --git a/doomsday/plugins/doom/src/p_oldsvg.cpp b/doomsday/plugins/doom/src/p_oldsvg.cpp index 5e0a46849e..d5cc3c17bb 100644 --- a/doomsday/plugins/doom/src/p_oldsvg.cpp +++ b/doomsday/plugins/doom/src/p_oldsvg.cpp @@ -844,16 +844,14 @@ int SV_LoadState_Dm_v19(Str const *path, SaveInfo *info) gameEpisode = info->episode(); gameMap = info->map(); - gameMapEntryPoint = 0; - - GameRuleset const &newRules = info->gameRules(); - gameSkill = newRules.skill; + gameMapEntryPoint = 0; /// @todo Not saved?? + gameRules = info->gameRules(); // We don't want to see a briefing if we're loading a save game. briefDisabled = true; // Load a base map. - G_NewGame(gameSkill, gameEpisode, gameMap, gameMapEntryPoint); + G_NewGame(gameRules.skill, gameEpisode, gameMap, gameMapEntryPoint); /// @todo Necessary? G_SetGameAction(GA_NONE); diff --git a/doomsday/plugins/doom/src/st_stuff.c b/doomsday/plugins/doom/src/st_stuff.c index 2a5ddec5df..18b63f2f8f 100644 --- a/doomsday/plugins/doom/src/st_stuff.c +++ b/doomsday/plugins/doom/src/st_stuff.c @@ -303,7 +303,7 @@ void SBarBackground_Drawer(uiwidget_t* obj, const Point2Raw* offset) if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; - if(!deathmatch) + if(!gameRules.deathmatch) { haveArms = R_GetPatchInfo(pArmsBackground, &armsInfo); @@ -1249,7 +1249,7 @@ void SBarFrags_Drawer(uiwidget_t* obj, const Point2Raw* offset) //const float iconAlpha = (fullscreen == 0? 1 : uiRendState->pageAlpha * cfg.statusbarCounterAlpha); char buf[20]; - if(!deathmatch) return; + if(!gameRules.deathmatch) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; if(frags->value == 1994) return; @@ -1292,7 +1292,7 @@ void SBarFrags_UpdateGeometry(uiwidget_t* obj) Rect_SetWidthHeight(obj->geometry, 0, 0); - if(!deathmatch) return; + if(!gameRules.deathmatch) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; if(frags->value == 1994) return; @@ -1512,7 +1512,7 @@ void WeaponSlot_Drawer(uiwidget_t* obj, const Point2Raw* offset) const float textAlpha = (fullscreen == 0? 1 : uiRendState->pageAlpha * cfg.statusbarCounterAlpha); //const float iconAlpha = (fullscreen == 0? 1 : uiRendState->pageAlpha * cfg.statusbarCounterAlpha); - if(deathmatch) return; + if(gameRules.deathmatch) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; @@ -1553,7 +1553,7 @@ void WeaponSlot_UpdateGeometry(uiwidget_t* obj) Rect_SetWidthHeight(obj->geometry, 0, 0); - if(deathmatch) return; + if(gameRules.deathmatch) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; if(!text && !R_GetPatchInfo(wpns->patchId, &info)) return; @@ -1655,7 +1655,7 @@ void Frags_Drawer(uiwidget_t* obj, const Point2Raw* offset) char buf[20]; if(!cfg.hudShown[HUD_FRAGS]) return; - if(!deathmatch) return; + if(!gameRules.deathmatch) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; @@ -1685,7 +1685,7 @@ void Frags_UpdateGeometry(uiwidget_t* obj) Rect_SetWidthHeight(obj->geometry, 0, 0); if(!cfg.hudShown[HUD_FRAGS]) return; - if(!deathmatch) return; + if(!gameRules.deathmatch) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; @@ -2778,7 +2778,7 @@ static void initAutomapForCurrentMap(uiwidget_t* obj) UIAutomap_ClearPoints(obj); #if !__JHEXEN__ - if(gameSkill == SM_BABY && cfg.automapBabyKeys) + if(gameRules.skill == SM_BABY && cfg.automapBabyKeys) { int flags = UIAutomap_Flags(obj); UIAutomap_SetFlags(obj, flags|AMF_REND_KEYS); diff --git a/doomsday/plugins/doom/src/wi_stuff.c b/doomsday/plugins/doom/src/wi_stuff.c index acc9e19260..231ec33f51 100644 --- a/doomsday/plugins/doom/src/wi_stuff.c +++ b/doomsday/plugins/doom/src/wi_stuff.c @@ -1102,7 +1102,7 @@ static void initShowStats(void) static void tickShowStats(void) { - if(deathmatch) + if(gameRules.deathmatch) { updateDeathmatchStats(); return; @@ -1220,7 +1220,7 @@ static void tickShowStats(void) static void drawStats(void) { - if(deathmatch) + if(gameRules.deathmatch) { drawDeathmatchStats(); } @@ -1455,7 +1455,7 @@ void WI_Init(wbstartstruct_t* wbstartstruct) } } - if(deathmatch) + if(gameRules.deathmatch) { initDeathmatchStats(); beginAnimations(); diff --git a/doomsday/plugins/doom64/include/g_game.h b/doomsday/plugins/doom64/include/g_game.h index 2e42511a19..d13b233ca1 100644 --- a/doomsday/plugins/doom64/include/g_game.h +++ b/doomsday/plugins/doom64/include/g_game.h @@ -50,19 +50,17 @@ extern player_t players[MAXPLAYERS]; extern uint nextMap; extern dd_bool gameInProgress; -extern skillmode_t gameSkill; extern uint gameEpisode; extern uint gameMap; extern uint gameMapEntryPoint; +extern GameRuleset gameRules; extern uint nextMap; // If non zero this will be the next map. extern dd_bool secretExit; extern int totalKills, totalItems, totalSecret; -extern dd_bool respawnMonsters; extern wbstartstruct_t wmInfo; extern int mapStartTic; extern int bodyQueueSlot; -extern dd_bool deathmatch; extern dd_bool paused; extern dd_bool precache; extern dd_bool customPal; @@ -74,12 +72,6 @@ void G_CommonPreInit(void); void G_CommonPostInit(void); void G_CommonShutdown(void); -/** - * Configure the given @a rules structure according to the @em current game rules. - * @todo Refactor away. - */ -void G_GetGameRules(GameRuleset *rules); - void R_InitRefresh(void); void G_DeathMatchSpawnPlayer(int playernum); diff --git a/doomsday/plugins/doom64/src/d_main.c b/doomsday/plugins/doom64/src/d_main.c index eaa5fd6c98..9fd1590350 100644 --- a/doomsday/plugins/doom64/src/d_main.c +++ b/doomsday/plugins/doom64/src/d_main.c @@ -371,7 +371,7 @@ void D_PostInit(void) monsterInfight = GetDefInt("AI|Infight", 0); // Get skill / episode / map from parms. - gameSkill = startSkill = SM_MEDIUM; + gameRules.skill = startSkill = SM_MEDIUM; startEpisode = 0; startMap = 0; autoStart = false; @@ -381,17 +381,22 @@ void D_PostInit(void) // Command line options noMonstersParm = CommandLine_Check("-nomonsters"); - respawnParm = CommandLine_Check("-respawn"); - fastParm = CommandLine_Check("-fast"); - devParm = CommandLine_Check("-devparm"); + respawnParm = CommandLine_Check("-respawn"); + fastParm = CommandLine_Check("-fast"); + devParm = CommandLine_Check("-devparm"); if(CommandLine_Check("-altdeath")) cfg.netDeathmatch = 2; else if(CommandLine_Check("-deathmatch")) cfg.netDeathmatch = 1; + // Apply these rules. + gameRules.noMonsters = noMonstersParm; + gameRules.respawnMonsters = respawnParm; + gameRules.fast = fastParm; + p = CommandLine_Check("-timer"); - if(p && p < myargc - 1 && deathmatch) + if(p && p < myargc - 1 && gameRules.deathmatch) { int time = atoi(CommandLine_At(p + 1)); App_Log(DE2_LOG_NOTE, "Maps will end after %d %s", time, time == 1? "minute" : "minutes"); diff --git a/doomsday/plugins/doom64/src/d_refresh.c b/doomsday/plugins/doom64/src/d_refresh.c index f22ff037dd..e654efbe54 100644 --- a/doomsday/plugins/doom64/src/d_refresh.c +++ b/doomsday/plugins/doom64/src/d_refresh.c @@ -115,16 +115,18 @@ dd_bool R_ViewFilterColor(float rgba[4], int filter) // We have to choose the right color and alpha. if(filter >= STARTREDPALS && filter < STARTREDPALS + NUMREDPALS) - { // Red. + { + // Red. rgba[CR] = 1; rgba[CG] = 0; rgba[CB] = 0; - rgba[CA] = (deathmatch? 1.0f : cfg.filterStrength) * filter / 9.f; + rgba[CA] = (gameRules.deathmatch? 1.0f : cfg.filterStrength) * filter / 9.f; return true; } if(filter >= STARTBONUSPALS && filter < STARTBONUSPALS + NUMBONUSPALS) - { // Gold. + { + // Gold. rgba[CR] = 1; rgba[CG] = .8f; rgba[CB] = .5f; @@ -133,7 +135,8 @@ dd_bool R_ViewFilterColor(float rgba[4], int filter) } if(filter == 13) // RADIATIONPAL - { // Green. + { + // Green. rgba[CR] = 0; rgba[CG] = .7f; rgba[CB] = 0; diff --git a/doomsday/plugins/doom64/src/p_enemy.c b/doomsday/plugins/doom64/src/p_enemy.c index 5bb730077a..3153e753c4 100644 --- a/doomsday/plugins/doom64/src/p_enemy.c +++ b/doomsday/plugins/doom64/src/p_enemy.c @@ -1008,7 +1008,7 @@ void C_DECL A_Chase(mobj_t *actor) if(actor->flags & MF_JUSTATTACKED) { actor->flags &= ~MF_JUSTATTACKED; - if(!fastParm) + if(!gameRules.fast) { newChaseDir(actor); } @@ -1031,7 +1031,7 @@ void C_DECL A_Chase(mobj_t *actor) // Check for missile attack. if((state = P_GetState(actor->type, SN_MISSILE)) != S_NULL) { - if(!(!fastParm && actor->moveCount)) + if(!(!gameRules.fast && actor->moveCount)) { if(checkMissileRange(actor)) { diff --git a/doomsday/plugins/doom64/src/p_inter.c b/doomsday/plugins/doom64/src/p_inter.c index 65a9d99377..ed9ca1dfcf 100644 --- a/doomsday/plugins/doom64/src/p_inter.c +++ b/doomsday/plugins/doom64/src/p_inter.c @@ -94,7 +94,7 @@ dd_bool P_GiveAmmo(player_t *player, ammotype_t ammo, int num) else num = clipAmmo[ammo] / 2; - if(gameSkill == SM_BABY) + if(gameRules.skill == SM_BABY) { // Give double ammo in trainer mode. num <<= 1; @@ -121,12 +121,12 @@ dd_bool P_GiveAmmo(player_t *player, ammotype_t ammo, int num) */ dd_bool P_GiveWeapon(player_t *player, weapontype_t weapon, dd_bool dropped) { - ammotype_t i; - dd_bool gaveAmmo = false; - dd_bool gaveWeapon; - int numClips; + ammotype_t i; + dd_bool gaveAmmo = false; + dd_bool gaveWeapon; + int numClips; - if(IS_NETGAME && (deathmatch != 2) && !dropped) + if(IS_NETGAME && (gameRules.deathmatch != 2) && !dropped) { // leave placed weapons forever on net games if(player->weapons[weapon].owned) @@ -142,7 +142,7 @@ dd_bool P_GiveWeapon(player_t *player, weapontype_t weapon, dd_bool dropped) if(!weaponInfo[weapon][player->class_].mode[0].ammoType[i]) continue; // Weapon does not take this type of ammo. - if(deathmatch) + if(gameRules.deathmatch) numClips = 5; else numClips = 2; @@ -152,7 +152,7 @@ dd_bool P_GiveWeapon(player_t *player, weapontype_t weapon, dd_bool dropped) } // Should we change weapon automatically? - P_MaybeChangeWeapon(player, weapon, AT_NOAMMO, deathmatch == 1); + P_MaybeChangeWeapon(player, weapon, AT_NOAMMO, gameRules.deathmatch == 1); // Maybe unhide the HUD? ST_HUDUnHide(player - players, HUE_ON_PICKUP_WEAPON); @@ -1066,7 +1066,7 @@ int P_DamageMobj2(mobj_t* target, mobj_t* inflictor, mobj_t* source, if(source && source->player && source->player != target->player) { // Co-op damage disabled? - if(IS_NETGAME && !deathmatch && cfg.noCoopDamage) + if(IS_NETGAME && !gameRules.deathmatch && cfg.noCoopDamage) return 0; // Same color, no damage? @@ -1083,7 +1083,7 @@ int P_DamageMobj2(mobj_t* target, mobj_t* inflictor, mobj_t* source, } player = target->player; - if(player && gameSkill == SM_BABY) + if(player && gameRules.skill == SM_BABY) damage >>= 1; // take half damage in trainer mode // jd64 > diff --git a/doomsday/plugins/doom64/src/p_mobj.c b/doomsday/plugins/doom64/src/p_mobj.c index 3650a46c69..481dfb1f54 100644 --- a/doomsday/plugins/doom64/src/p_mobj.c +++ b/doomsday/plugins/doom64/src/p_mobj.c @@ -686,7 +686,7 @@ void P_MobjThinker(void *mobjThinkerPtr) if(!(mobj->flags & MF_COUNTKILL)) return; - if(!respawnMonsters) + if(!gameRules.respawnMonsters) return; mobj->moveCount++; @@ -704,13 +704,13 @@ void P_MobjThinker(void *mobjThinkerPtr) } } -mobj_t* P_SpawnMobjXYZ(mobjtype_t type, coord_t x, coord_t y, coord_t z, angle_t angle, +mobj_t *P_SpawnMobjXYZ(mobjtype_t type, coord_t x, coord_t y, coord_t z, angle_t angle, int spawnFlags) { - mobjinfo_t* info; + mobjinfo_t *info; int ddflags = 0; coord_t space; - mobj_t* mo; + mobj_t *mo; if(type < MT_FIRST || type >= Get(DD_NUMMOBJTYPES)) { @@ -725,14 +725,14 @@ mobj_t* P_SpawnMobjXYZ(mobjtype_t type, coord_t x, coord_t y, coord_t z, angle_t return NULL; // Not for deathmatch? - if(deathmatch && (info->flags & MF_NOTDMATCH)) + if(gameRules.deathmatch && (info->flags & MF_NOTDMATCH)) return NULL; // Check for specific disabled objects. if(IS_NETGAME) { // Cooperative weapons? - if(cfg.noCoopWeapons && !deathmatch && type >= MT_CLIP && + if(cfg.noCoopWeapons && !gameRules.deathmatch && type >= MT_CLIP && type <= MT_SUPERSHOTGUN) return NULL; @@ -751,8 +751,8 @@ mobj_t* P_SpawnMobjXYZ(mobjtype_t type, coord_t x, coord_t y, coord_t z, angle_t return NULL; } - // Don't spawn any monsters if -noMonstersParm. - if(noMonstersParm && ((info->flags & MF_COUNTKILL) || type == MT_SKULL)) + // Don't spawn any monsters? + if(gameRules.noMonsters && ((info->flags & MF_COUNTKILL) || type == MT_SKULL)) return NULL; if(info->flags & MF_SOLID) diff --git a/doomsday/plugins/doom64/src/st_stuff.c b/doomsday/plugins/doom64/src/st_stuff.c index d6a6899859..b80480b6c8 100644 --- a/doomsday/plugins/doom64/src/st_stuff.c +++ b/doomsday/plugins/doom64/src/st_stuff.c @@ -262,7 +262,7 @@ static void drawWidgets(hudstate_t* hud) { #define MAXDIGITS ST_FRAGSWIDTH - if(deathmatch) + if(gameRules.deathmatch) { char buf[20]; if(hud->currentFragsCount == 1994) @@ -349,30 +349,28 @@ void ST_drawHUDSprite(int sprite, float x, float y, hotloc_t hotspot, void ST_doFullscreenStuff(int player) { - static const int ammo_sprite[NUM_AMMO_TYPES] = { + static int const ammo_sprite[NUM_AMMO_TYPES] = { SPR_AMMO, SPR_SBOX, SPR_CELL, SPR_RCKT }; - hudstate_t* hud = &hudStates[player]; - player_t* plr = &players[player]; - char buf[20]; - int w, h, pos = 0, oldPos = 0, spr,i; - int h_width = 320 / cfg.hudScale; - int h_height = 200 / cfg.hudScale; - float textalpha = - hud->alpha - hud->hideAmount - ( 1 - cfg.hudColor[3]); - float iconalpha = - hud->alpha - hud->hideAmount - ( 1 - cfg.hudIconAlpha); + hudstate_t *hud = &hudStates[player]; + player_t *plr = &players[player]; + char buf[20]; + int w, h, pos = 0, oldPos = 0, spr,i; + int h_width = 320 / cfg.hudScale; + int h_height = 200 / cfg.hudScale; + float textalpha = hud->alpha - hud->hideAmount - ( 1 - cfg.hudColor[3]); + float iconalpha = hud->alpha - hud->hideAmount - ( 1 - cfg.hudIconAlpha); textalpha = MINMAX_OF(0.f, textalpha, 1.f); iconalpha = MINMAX_OF(0.f, iconalpha, 1.f); FR_LoadDefaultAttrib(); - if(IS_NETGAME && deathmatch && cfg.hudShown[HUD_FRAGS]) + if(IS_NETGAME && gameRules.deathmatch && cfg.hudShown[HUD_FRAGS]) { // Display the frag counter. i = 199 - HUDBORDERY; @@ -627,7 +625,7 @@ static void initAutomapForCurrentMap(uiwidget_t* obj) UIAutomap_ClearPoints(obj); #if !__JHEXEN__ - if(gameSkill == SM_BABY && cfg.automapBabyKeys) + if(gameRules.skill == SM_BABY && cfg.automapBabyKeys) { int flags = UIAutomap_Flags(obj); UIAutomap_SetFlags(obj, flags|AMF_REND_KEYS); diff --git a/doomsday/plugins/doom64/src/wi_stuff.c b/doomsday/plugins/doom64/src/wi_stuff.c index cc8078fab1..965037937a 100644 --- a/doomsday/plugins/doom64/src/wi_stuff.c +++ b/doomsday/plugins/doom64/src/wi_stuff.c @@ -746,7 +746,7 @@ static void initShowStats(void) static void tickShowStats(void) { - if(deathmatch) + if(gameRules.deathmatch) { updateDeathmatchStats(); return; @@ -860,7 +860,7 @@ static void tickShowStats(void) static void drawStats(void) { - if(deathmatch) + if(gameRules.deathmatch) { drawDeathmatchStats(); } @@ -1064,7 +1064,7 @@ void WI_Init(wbstartstruct_t* wbstartstruct) } } - if(deathmatch) + if(gameRules.deathmatch) { initDeathmatchStats(); } diff --git a/doomsday/plugins/heretic/include/g_game.h b/doomsday/plugins/heretic/include/g_game.h index 976d3e7c69..825537ac69 100644 --- a/doomsday/plugins/heretic/include/g_game.h +++ b/doomsday/plugins/heretic/include/g_game.h @@ -49,17 +49,15 @@ extern int gaLoadGameSaveSlot; extern player_t players[MAXPLAYERS]; extern dd_bool gameInProgress; -extern skillmode_t gameSkill; extern uint gameEpisode; extern uint gameMap; extern uint gameMapEntryPoint; +extern GameRuleset gameRules; extern uint nextMap; extern dd_bool secretExit; extern int mapStartTic; extern int totalKills, totalItems, totalSecret; -extern dd_bool deathmatch; -extern dd_bool respawnMonsters; extern dd_bool paused; extern dd_bool precache; extern wbstartstruct_t wmInfo; @@ -73,12 +71,6 @@ void G_CommonPreInit(void); void G_CommonPostInit(void); void G_CommonShutdown(void); -/** - * Configure the given @a rules structure according to the @em current game rules. - * @todo Refactor away. - */ -void G_GetGameRules(GameRuleset *rules); - void R_InitRefresh(void); void G_DeathMatchSpawnPlayer(int playernum); diff --git a/doomsday/plugins/heretic/src/h_main.c b/doomsday/plugins/heretic/src/h_main.c index bb548552db..372e2e7cd4 100644 --- a/doomsday/plugins/heretic/src/h_main.c +++ b/doomsday/plugins/heretic/src/h_main.c @@ -405,14 +405,18 @@ void H_PostInit(void) // Command line options. noMonstersParm = CommandLine_Check("-nomonsters"); - respawnParm = CommandLine_Check("-respawn"); - devParm = CommandLine_Check("-devparm"); + respawnParm = CommandLine_Check("-respawn"); + devParm = CommandLine_Check("-devparm"); if(CommandLine_Check("-deathmatch")) { cfg.netDeathmatch = true; } + // Apply these game rules. + gameRules.noMonsters = noMonstersParm; + gameRules.respawnMonsters = respawnParm; + // turbo option. p = CommandLine_Check("-turbo"); turboMul = 1.0f; diff --git a/doomsday/plugins/heretic/src/h_refresh.c b/doomsday/plugins/heretic/src/h_refresh.c index 94808851fb..981863d93b 100644 --- a/doomsday/plugins/heretic/src/h_refresh.c +++ b/doomsday/plugins/heretic/src/h_refresh.c @@ -89,15 +89,17 @@ dd_bool R_ViewFilterColor(float rgba[4], int filter) // We have to choose the right color and alpha. if(filter >= STARTREDPALS && filter < STARTREDPALS + NUMREDPALS) - { // Red. + { + // Red. rgba[CR] = 1; rgba[CG] = 0; rgba[CB] = 0; - rgba[CA] = (deathmatch? 1.0f : cfg.filterStrength) * filter / 8.f; // Full red with filter 8. + rgba[CA] = (gameRules.deathmatch? 1.0f : cfg.filterStrength) * filter / 8.f; // Full red with filter 8. return true; } else if(filter >= STARTBONUSPALS && filter < STARTBONUSPALS + NUMBONUSPALS) - { // Light Yellow. + { + // Light Yellow. rgba[CR] = 1; rgba[CG] = 1; rgba[CB] = .5f; diff --git a/doomsday/plugins/heretic/src/in_lude.c b/doomsday/plugins/heretic/src/in_lude.c index f457697ed9..eea78ebee2 100644 --- a/doomsday/plugins/heretic/src/in_lude.c +++ b/doomsday/plugins/heretic/src/in_lude.c @@ -273,7 +273,7 @@ void IN_InitStats(void) { gameType = SINGLE; } - else if( /*IS_NETGAME && */ !deathmatch) + else if( /*IS_NETGAME && */ !gameRules.deathmatch) { gameType = COOPERATIVE; memset(killPercent, 0, sizeof(killPercent)); diff --git a/doomsday/plugins/heretic/src/m_cheat.c b/doomsday/plugins/heretic/src/m_cheat.c index 7e1f339477..3c0f3f8f8d 100644 --- a/doomsday/plugins/heretic/src/m_cheat.c +++ b/doomsday/plugins/heretic/src/m_cheat.c @@ -105,7 +105,7 @@ CHEAT_FUNC(InvItem3) DENG_ASSERT(player >= 0 && player < MAXPLAYERS); - if(gameSkill == SM_NIGHTMARE) return false; + if(gameRules.skill == SM_NIGHTMARE) return false; // Dead players can't cheat. if(plr->health <= 0) return false; @@ -144,7 +144,7 @@ CHEAT_FUNC(IDKFA) DENG_UNUSED(args); DENG_ASSERT(player >= 0 && player < MAXPLAYERS); - if(gameSkill == SM_NIGHTMARE) return false; + if(gameRules.skill == SM_NIGHTMARE) return false; // Dead players can't cheat. if(plr->health <= 0) return false; if(plr->morphTics) return false; @@ -171,7 +171,7 @@ CHEAT_FUNC(IDDQD) DENG_UNUSED(args); DENG_ASSERT(player >= 0 && player < MAXPLAYERS); - if(gameSkill == SM_NIGHTMARE) return false; + if(gameRules.skill == SM_NIGHTMARE) return false; // Dead players can't cheat. if(plr->health <= 0) return false; @@ -190,7 +190,7 @@ CHEAT_FUNC(Reveal) DENG_UNUSED(args); DENG_ASSERT(player >= 0 && player < MAXPLAYERS); - if(IS_NETGAME && deathmatch) return false; + if(IS_NETGAME && gameRules.deathmatch) return false; // Dead players can't cheat. if(plr->health <= 0) return false; @@ -228,7 +228,7 @@ D_CMD(CheatGod) { NetCl_CheatRequest("god"); } - else if((IS_NETGAME && !netSvAllowCheats) || gameSkill == SM_NIGHTMARE) + else if((IS_NETGAME && !netSvAllowCheats) || gameRules.skill == SM_NIGHTMARE) { return false; } @@ -267,7 +267,7 @@ D_CMD(CheatNoClip) { NetCl_CheatRequest("noclip"); } - else if((IS_NETGAME && !netSvAllowCheats) || gameSkill == SM_NIGHTMARE) + else if((IS_NETGAME && !netSvAllowCheats) || gameRules.skill == SM_NIGHTMARE) { return false; } @@ -429,7 +429,7 @@ D_CMD(CheatGive) return true; } - if((IS_NETGAME && !netSvAllowCheats) || gameSkill == SM_NIGHTMARE) + if((IS_NETGAME && !netSvAllowCheats) || gameRules.skill == SM_NIGHTMARE) return false; plr = &players[player]; @@ -651,7 +651,7 @@ D_CMD(CheatMassacre) { NetCl_CheatRequest("kill"); } - else if((IS_NETGAME && !netSvAllowCheats) || gameSkill == SM_NIGHTMARE) + else if((IS_NETGAME && !netSvAllowCheats) || gameRules.skill == SM_NIGHTMARE) { return false; } @@ -731,7 +731,7 @@ D_CMD(CheatMorph) { NetCl_CheatRequest("chicken"); } - else if((IS_NETGAME && !netSvAllowCheats) || gameSkill == SM_NIGHTMARE) + else if((IS_NETGAME && !netSvAllowCheats) || gameRules.skill == SM_NIGHTMARE) { return false; } diff --git a/doomsday/plugins/heretic/src/p_enemy.c b/doomsday/plugins/heretic/src/p_enemy.c index 2aaaf9f748..51196608d0 100644 --- a/doomsday/plugins/heretic/src/p_enemy.c +++ b/doomsday/plugins/heretic/src/p_enemy.c @@ -614,7 +614,7 @@ void C_DECL A_Chase(mobj_t *actor) actor->threshold--; } - if(gameSkill == SM_NIGHTMARE || cfg.fastMonsters) + if(gameRules.skill == SM_NIGHTMARE || cfg.fastMonsters) { // Monsters move faster in nightmare mode. actor->tics -= actor->tics / 2; @@ -653,7 +653,7 @@ void C_DECL A_Chase(mobj_t *actor) if(actor->flags & MF_JUSTATTACKED) { actor->flags &= ~MF_JUSTATTACKED; - if(gameSkill != SM_NIGHTMARE) + if(gameRules.skill != SM_NIGHTMARE) { newChaseDir(actor); } @@ -674,7 +674,7 @@ void C_DECL A_Chase(mobj_t *actor) // Check for missile attack. if((state = P_GetState(actor->type, SN_MISSILE)) != S_NULL) { - if(!(gameSkill != SM_NIGHTMARE && actor->moveCount)) + if(!(gameRules.skill != SM_NIGHTMARE && actor->moveCount)) { if(P_CheckMissileRange(actor)) { diff --git a/doomsday/plugins/heretic/src/p_inter.c b/doomsday/plugins/heretic/src/p_inter.c index 302fb92eab..23a73c13c4 100644 --- a/doomsday/plugins/heretic/src/p_inter.c +++ b/doomsday/plugins/heretic/src/p_inter.c @@ -72,7 +72,7 @@ static dd_bool giveOneAmmo(player_t *plr, ammotype_t ammoType, int numRounds) } // Give extra rounds at easy/nightmare skill levels. - if(gameSkill == SM_BABY || gameSkill == SM_NIGHTMARE) + if(gameRules.skill == SM_BABY || gameRules.skill == SM_NIGHTMARE) { numRounds += numRounds / 1; } @@ -150,7 +150,7 @@ static dd_bool giveOneWeapon(player_t *plr, weapontype_t weaponType) plr->update |= PSF_OWNED_WEAPONS; // Animate a pickup bonus flash? - if(IS_NETGAME && !deathmatch) + if(IS_NETGAME && !gameRules.deathmatch) { plr->bonusCount += BONUSADD; } @@ -432,7 +432,7 @@ static void setDormantItem(mobj_t* mo) { mo->flags &= ~MF_SPECIAL; - if(deathmatch && (mo->type != MT_ARTIINVULNERABILITY) && + if(gameRules.deathmatch && (mo->type != MT_ARTIINVULNERABILITY) && (mo->type != MT_ARTIINVISIBILITY)) { P_MobjChangeState(mo, S_DORMANTARTI1); @@ -558,7 +558,7 @@ static dd_bool pickupWeapon(player_t *plr, weapontype_t weaponType, if(plr->weapons[weaponType].owned) { // Leave placed weapons forever on net games. - if(IS_NETGAME && !deathmatch) + if(IS_NETGAME && !gameRules.deathmatch) return false; } @@ -955,7 +955,7 @@ void P_TouchSpecialMobj(mobj_t *special, mobj_t *toucher) break; default: - if(deathmatch && !(special->flags & MF_DROPPED)) + if(gameRules.deathmatch && !(special->flags & MF_DROPPED)) { special->flags &= ~MF_SPECIAL; special->flags2 |= MF2_DONTDRAW; @@ -1206,7 +1206,7 @@ static void autoUseHealth(player_t *player, int saveHealth) if(!player->plr->mo) return; /// @todo Do this in the inventory code? - if(gameSkill == SM_BABY && normalCount * 25 >= saveHealth) + if(gameRules.skill == SM_BABY && normalCount * 25 >= saveHealth) { // Use quartz flasks. count = (saveHealth + 24) / 25; @@ -1226,7 +1226,7 @@ static void autoUseHealth(player_t *player, int saveHealth) P_InventoryTake(plrnum, IIT_SUPERHEALTH, false); } } - else if(gameSkill == SM_BABY && + else if(gameRules.skill == SM_BABY && superCount * 100 + normalCount * 25 >= saveHealth) { // Use mystic urns and quartz flasks. @@ -1294,7 +1294,7 @@ int P_DamageMobj2(mobj_t *target, mobj_t *inflictor, mobj_t *source, if(source && source->player && source->player != target->player) { // Co-op damage disabled? - if(IS_NETGAME && !deathmatch && cfg.noCoopDamage) + if(IS_NETGAME && !gameRules.deathmatch && cfg.noCoopDamage) return 0; // Same color, no damage? @@ -1316,7 +1316,7 @@ int P_DamageMobj2(mobj_t *target, mobj_t *inflictor, mobj_t *source, } player = target->player; - if(player && gameSkill == SM_BABY) + if(player && gameRules.skill == SM_BABY) damage /= 2; // Take half damage in trainer mode. // Use the cvar damage multiplier netMobDamageModifier only if the @@ -1544,7 +1544,8 @@ int P_DamageMobj2(mobj_t *target, mobj_t *inflictor, mobj_t *source, } if(damage >= player->health && - (gameSkill == SM_BABY || deathmatch) && !player->morphTics) + (gameRules.skill == SM_BABY || gameRules.deathmatch) && + !player->morphTics) { // Try to use some inventory health. autoUseHealth(player, damage - player->health + 1); diff --git a/doomsday/plugins/heretic/src/p_mobj.c b/doomsday/plugins/heretic/src/p_mobj.c index cbccae2e0d..363fa7f587 100644 --- a/doomsday/plugins/heretic/src/p_mobj.c +++ b/doomsday/plugins/heretic/src/p_mobj.c @@ -904,7 +904,7 @@ void P_MobjThinker(void *thinkerPtr) if(!(mobj->flags & MF_COUNTKILL)) return; - if(!respawnMonsters) + if(!gameRules.respawnMonsters) return; mobj->moveCount++; @@ -950,7 +950,7 @@ mobj_t* P_SpawnMobjXYZ(mobjtype_t type, coord_t x, coord_t y, coord_t z, */ // Not for deathmatch? - if(deathmatch && (info->flags & MF_NOTDMATCH)) + if(gameRules.deathmatch && (info->flags & MF_NOTDMATCH)) return NULL; // Check for specific disabled objects. @@ -977,8 +977,8 @@ mobj_t* P_SpawnMobjXYZ(mobjtype_t type, coord_t x, coord_t y, coord_t z, break; } - // Don't spawn any monsters if -noMonstersParm. - if(noMonstersParm && (info->flags & MF_COUNTKILL)) + // Don't spawn any monsters? + if(gameRules.noMonsters && (info->flags & MF_COUNTKILL)) return 0; if(info->flags & MF_SOLID) @@ -999,7 +999,7 @@ mobj_t* P_SpawnMobjXYZ(mobjtype_t type, coord_t x, coord_t y, coord_t z, mo->selector = 0; P_UpdateHealthBits(mo); // Set the health bits of the selector. - if(gameSkill != SM_NIGHTMARE) + if(gameRules.skill != SM_NIGHTMARE) mo->reactionTime = info->reactionTime; mo->lastLook = P_Random() % MAXPLAYERS; diff --git a/doomsday/plugins/heretic/src/p_oldsvg.cpp b/doomsday/plugins/heretic/src/p_oldsvg.cpp index 69896ebaba..6d29f145d8 100644 --- a/doomsday/plugins/heretic/src/p_oldsvg.cpp +++ b/doomsday/plugins/heretic/src/p_oldsvg.cpp @@ -853,16 +853,14 @@ int SV_LoadState_Hr_v13(Str const *path, SaveInfo *info) gameEpisode = info->episode(); gameMap = info->map(); - gameMapEntryPoint = 0; - - GameRuleset const &newRules = info->gameRules(); - gameSkill = newRules.skill; + gameMapEntryPoint = 0; /// @todo Not saved?? + gameRules = info->gameRules(); // We don't want to see a briefing if we're loading a save game. briefDisabled = true; // Load a base map. - G_NewGame(gameSkill, gameEpisode, gameMap, gameMapEntryPoint); + G_NewGame(gameRules.skill, gameEpisode, gameMap, gameMapEntryPoint); /// @todo Necessary? G_SetGameAction(GA_NONE); diff --git a/doomsday/plugins/heretic/src/p_telept.c b/doomsday/plugins/heretic/src/p_telept.c index 4d42dd78cd..21758c52f5 100644 --- a/doomsday/plugins/heretic/src/p_telept.c +++ b/doomsday/plugins/heretic/src/p_telept.c @@ -196,9 +196,9 @@ static mobj_t* getTeleportDestination(short tag) return NULL; } -dd_bool EV_Teleport(Line* line, int side, mobj_t* mo, dd_bool spawnFog) +dd_bool EV_Teleport(Line *line, int side, mobj_t *mo, dd_bool spawnFog) { - mobj_t* dest; + mobj_t *dest; // Clients cannot teleport on their own. if(IS_CLIENT) return 0; @@ -218,14 +218,14 @@ dd_bool EV_Teleport(Line* line, int side, mobj_t* mo, dd_bool spawnFog) } #if __JHERETIC__ || __JHEXEN__ -void P_ArtiTele(player_t* player) +void P_ArtiTele(player_t *player) { - const playerstart_t* start; + playerstart_t const *start; // Get a random deathmatch start. - if((start = P_GetPlayerStart(0, deathmatch? -1 : 0, deathmatch))) + if((start = P_GetPlayerStart(0, gameRules.deathmatch? -1 : 0, gameRules.deathmatch))) { - const mapspot_t* spot = &mapSpots[start->spot]; + mapspot_t const *spot = &mapSpots[start->spot]; P_Teleport(player->plr->mo, spot->origin[VX], spot->origin[VY], spot->angle, true); #if __JHEXEN__ diff --git a/doomsday/plugins/heretic/src/st_stuff.c b/doomsday/plugins/heretic/src/st_stuff.c index 776a274679..e8cb738cb8 100644 --- a/doomsday/plugins/heretic/src/st_stuff.c +++ b/doomsday/plugins/heretic/src/st_stuff.c @@ -470,7 +470,7 @@ void SBarBackground_Drawer(uiwidget_t* obj, const Point2Raw* offset) if(!Hu_InventoryIsOpen(obj->player)) { - if(deathmatch) + if(gameRules.deathmatch) GL_DrawPatchXY(pStatBar, ORIGINX+34, ORIGINY+2); else GL_DrawPatchXY(pLifeBar, ORIGINX+34, ORIGINY+2); @@ -518,7 +518,7 @@ void SBarBackground_Drawer(uiwidget_t* obj, const Point2Raw* offset) if(!Hu_InventoryIsOpen(obj->player)) { - if(deathmatch) + if(gameRules.deathmatch) GL_DrawPatchXY(pStatBar, ORIGINX+34, ORIGINY+2); else GL_DrawPatchXY(pLifeBar, ORIGINX+34, ORIGINY+2); @@ -714,7 +714,7 @@ void SBarFrags_Drawer(uiwidget_t* obj, const Point2Raw* offset) int yOffset = ST_HEIGHT*(1-hud->showBar); char buf[20]; - if(!deathmatch || Hu_InventoryIsOpen(obj->player)) return; + if(!gameRules.deathmatch || Hu_InventoryIsOpen(obj->player)) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; if(frags->value == 1994) return; @@ -755,7 +755,7 @@ void SBarFrags_UpdateGeometry(uiwidget_t* obj) Rect_SetWidthHeight(obj->geometry, 0, 0); - if(!deathmatch || Hu_InventoryIsOpen(obj->player)) return; + if(!gameRules.deathmatch || Hu_InventoryIsOpen(obj->player)) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; if(frags->value == 1994) return; @@ -795,7 +795,7 @@ void SBarHealth_Drawer(uiwidget_t* obj, const Point2Raw* offset) const float textAlpha = (fullscreen == 0? 1 : uiRendState->pageAlpha * cfg.statusbarCounterAlpha); char buf[20]; - if(deathmatch || Hu_InventoryIsOpen(obj->player)) return; + if(gameRules.deathmatch || Hu_InventoryIsOpen(obj->player)) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; if(hlth->value == 1994) return; @@ -836,7 +836,7 @@ void SBarHealth_UpdateGeometry(uiwidget_t* obj) Rect_SetWidthHeight(obj->geometry, 0, 0); - if(deathmatch || Hu_InventoryIsOpen(obj->player)) return; + if(gameRules.deathmatch || Hu_InventoryIsOpen(obj->player)) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; if(hlth->value == 1994) return; @@ -1854,7 +1854,7 @@ void Frags_Drawer(uiwidget_t* obj, const Point2Raw* offset) const float textAlpha = uiRendState->pageAlpha * cfg.hudColor[3]; char buf[20]; - if(!deathmatch) return; + if(!gameRules.deathmatch) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; if(frags->value == 1994) return; @@ -1889,7 +1889,7 @@ void Frags_UpdateGeometry(uiwidget_t* obj) Rect_SetWidthHeight(obj->geometry, 0, 0); - if(!deathmatch) return; + if(!gameRules.deathmatch) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; if(frags->value == 1994) return; @@ -2608,7 +2608,7 @@ static void initAutomapForCurrentMap(uiwidget_t* obj) UIAutomap_ClearPoints(obj); #if !__JHEXEN__ - if(gameSkill == SM_BABY && cfg.automapBabyKeys) + if(gameRules.skill == SM_BABY && cfg.automapBabyKeys) { int flags = UIAutomap_Flags(obj); UIAutomap_SetFlags(obj, flags|AMF_REND_KEYS); diff --git a/doomsday/plugins/hexen/include/g_game.h b/doomsday/plugins/hexen/include/g_game.h index 1797e1237b..b3730ac4d6 100644 --- a/doomsday/plugins/hexen/include/g_game.h +++ b/doomsday/plugins/hexen/include/g_game.h @@ -49,9 +49,8 @@ extern dd_bool gameInProgress; extern uint gameEpisode; extern uint gameMap; extern uint gameMapEntryPoint; -extern skillmode_t gameSkill; +extern GameRuleset gameRules; -extern dd_bool deathmatch; extern dd_bool paused; extern dd_bool precache; extern dd_bool customPal; @@ -66,12 +65,6 @@ extern int gsvMapMusic; void G_CommonShutdown(void); -/** - * Configure the given @a rules structure according to the @em current game rules. - * @todo Refactor away. - */ -void G_GetGameRules(GameRuleset *rules); - void R_InitRefresh(void); void R_GetTranslation(int plrClass, int plrColor, int* tclass, int* tmap); void Mobj_UpdateTranslationClassAndMap(mobj_t* mo); diff --git a/doomsday/plugins/hexen/src/a_action.c b/doomsday/plugins/hexen/src/a_action.c index f1227421b2..ed1582bc9c 100644 --- a/doomsday/plugins/hexen/src/a_action.c +++ b/doomsday/plugins/hexen/src/a_action.c @@ -87,10 +87,11 @@ void C_DECL A_PotteryExplode(mobj_t* actor) if(actor->args[0]) { // Spawn an item. - if(!noMonstersParm || + if(!gameRules.noMonsters || !(MOBJINFO[TranslateThingType[actor->args[0]]]. flags & MF_COUNTKILL)) - { // Only spawn monsters if not -nomonsters. + { + // Only spawn monsters if not -nomonsters. P_SpawnMobj(TranslateThingType[actor->args[0]], actor->origin, actor->angle, 0); } @@ -852,7 +853,7 @@ void C_DECL A_SoAExplode(mobj_t* actor) if(actor->args[0]) { // Spawn an item. - if(!noMonstersParm || + if(!gameRules.noMonsters || !(MOBJINFO[TranslateThingType[actor->args[0]]]. flags & MF_COUNTKILL)) { diff --git a/doomsday/plugins/hexen/src/acscript.cpp b/doomsday/plugins/hexen/src/acscript.cpp index 0a29d3d8d3..d44e3322e2 100644 --- a/doomsday/plugins/hexen/src/acscript.cpp +++ b/doomsday/plugins/hexen/src/acscript.cpp @@ -397,7 +397,7 @@ void ACScriptInterpreter::runDeferredTasks(Uri const *mapUri) { //DENG_ASSERT(mapUri != 0); - if(deathmatch) + if(gameRules.deathmatch) { /// @todo Do we really want to disallow deferred ACS tasks in deathmatch? /// What is the actual intention here? -ds @@ -1429,7 +1429,7 @@ ACS_COMMAND(GameType) { gametype = 0; // singleplayer } - else if(deathmatch) + else if(gameRules.deathmatch) { gametype = 2; // deathmatch } @@ -1444,7 +1444,7 @@ ACS_COMMAND(GameType) ACS_COMMAND(GameSkill) { - acs.locals.push((int)gameSkill); + acs.locals.push((int)gameRules.skill); return Continue; } diff --git a/doomsday/plugins/hexen/src/h2_main.c b/doomsday/plugins/hexen/src/h2_main.c index 345afde5ee..c72a848d76 100644 --- a/doomsday/plugins/hexen/src/h2_main.c +++ b/doomsday/plugins/hexen/src/h2_main.c @@ -343,13 +343,17 @@ void X_PostInit(void) /* None */ // Command line options. - noMonstersParm = CommandLine_Exists("-nomonsters"); - respawnParm = CommandLine_Exists("-respawn"); + noMonstersParm = CommandLine_Exists("-nomonsters"); + //respawnParm = CommandLine_Exists("-respawn"); randomClassParm = CommandLine_Exists("-randclass"); - devParm = CommandLine_Exists("-devparm"); + devParm = CommandLine_Exists("-devparm"); cfg.netDeathmatch = CommandLine_Exists("-deathmatch"); + // Apply these rules. + gameRules.noMonsters = noMonstersParm; + gameRules.randomClasses = randomClassParm; + // Turbo movement option. p = CommandLine_Check("-turbo"); turboMul = 1.0f; diff --git a/doomsday/plugins/hexen/src/hrefresh.c b/doomsday/plugins/hexen/src/hrefresh.c index 23d68f9d08..69cba5648f 100644 --- a/doomsday/plugins/hexen/src/hrefresh.c +++ b/doomsday/plugins/hexen/src/hrefresh.c @@ -49,15 +49,17 @@ dd_bool R_ViewFilterColor(float rgba[4], int filter) // We have to choose the right color and alpha. if(filter >= STARTREDPALS && filter < STARTREDPALS + NUMREDPALS) - { // Red. + { + // Red. rgba[CR] = 1; rgba[CG] = 0; rgba[CB] = 0; - rgba[CA] = (deathmatch? 1.0f : cfg.filterStrength) * filter / 8.f; // Full red with filter 8. + rgba[CA] = (gameRules.deathmatch? 1.0f : cfg.filterStrength) * filter / 8.f; // Full red with filter 8. return true; } else if(filter >= STARTBONUSPALS && filter < STARTBONUSPALS + NUMBONUSPALS) - { // Light Yellow. + { + // Light Yellow. rgba[CR] = 1; rgba[CG] = 1; rgba[CB] = .5f; @@ -65,7 +67,8 @@ dd_bool R_ViewFilterColor(float rgba[4], int filter) return true; } else if(filter >= STARTPOISONPALS && filter < STARTPOISONPALS + NUMPOISONPALS) - { // Green. + { + // Green. rgba[CR] = 0; rgba[CG] = 1; rgba[CB] = 0; @@ -73,7 +76,8 @@ dd_bool R_ViewFilterColor(float rgba[4], int filter) return true; } else if(filter >= STARTSCOURGEPAL) - { // Orange. + { + // Orange. rgba[CR] = 1; rgba[CG] = .5f; rgba[CB] = 0; diff --git a/doomsday/plugins/hexen/src/in_lude.c b/doomsday/plugins/hexen/src/in_lude.c index 9096695268..84a0a65914 100644 --- a/doomsday/plugins/hexen/src/in_lude.c +++ b/doomsday/plugins/hexen/src/in_lude.c @@ -167,7 +167,7 @@ void WI_initVariables(void /* wbstartstruct_t* wbstartstruct */) void IN_Init(void) { - assert(deathmatch); + DENG_ASSERT(gameRules.deathmatch); WI_initVariables(); loadPics(); @@ -333,8 +333,9 @@ static void CheckForSkip(void) } } - if(deathmatch && interTime < 140) - { // Wait for 4 seconds before allowing a skip. + if(gameRules.deathmatch && interTime < 140) + { + // Wait for 4 seconds before allowing a skip. if(skipIntermission == 1) { triedToSkip = true; diff --git a/doomsday/plugins/hexen/src/m_cheat.c b/doomsday/plugins/hexen/src/m_cheat.c index e223197e37..949fc16b35 100644 --- a/doomsday/plugins/hexen/src/m_cheat.c +++ b/doomsday/plugins/hexen/src/m_cheat.c @@ -95,7 +95,7 @@ CHEAT_FUNC(Init) DENG_ASSERT(player >= 0 && player < MAXPLAYERS); if(IS_NETGAME) return false; - if(gameSkill == SM_NIGHTMARE) return false; + if(gameRules.skill == SM_NIGHTMARE) return false; // Dead players can't cheat. if(plr->health <= 0) return false; @@ -114,7 +114,7 @@ CHEAT_FUNC(IDKFA) DENG_UNUSED(args); DENG_ASSERT(player >= 0 && player < MAXPLAYERS); - if(gameSkill == SM_NIGHTMARE) return false; + if(gameRules.skill == SM_NIGHTMARE) return false; // Dead players can't cheat. if(plr->health <= 0) return false; if(plr->morphTics) return false; @@ -160,7 +160,7 @@ CHEAT_FUNC(Quicken3) DENG_UNUSED(args); DENG_ASSERT(player >= 0 && player < MAXPLAYERS); - if(gameSkill == SM_NIGHTMARE) return false; + if(gameRules.skill == SM_NIGHTMARE) return false; // Dead players can't cheat. if(plr->health <= 0) return false; @@ -211,8 +211,8 @@ CHEAT_FUNC(Reveal) DENG_UNUSED(args); DENG_ASSERT(player >= 0 && player < MAXPLAYERS); - if(IS_NETGAME && deathmatch) return false; - if(gameSkill == SM_NIGHTMARE) return false; + if(IS_NETGAME && gameRules.deathmatch) return false; + if(gameRules.skill == SM_NIGHTMARE) return false; // Dead players can't cheat. if(plr->health <= 0) return false; @@ -252,7 +252,7 @@ D_CMD(CheatGod) { NetCl_CheatRequest("god"); } - else if((IS_NETGAME && !netSvAllowCheats) || gameSkill == SM_NIGHTMARE) + else if((IS_NETGAME && !netSvAllowCheats) || gameRules.skill == SM_NIGHTMARE) { return false; } @@ -291,7 +291,7 @@ D_CMD(CheatNoClip) { NetCl_CheatRequest("noclip"); } - else if((IS_NETGAME && !netSvAllowCheats) || gameSkill == SM_NIGHTMARE) + else if((IS_NETGAME && !netSvAllowCheats) || gameRules.skill == SM_NIGHTMARE) { return false; } @@ -464,7 +464,7 @@ D_CMD(CheatGive) return true; } - if((IS_NETGAME && !netSvAllowCheats) || gameSkill == SM_NIGHTMARE) + if((IS_NETGAME && !netSvAllowCheats) || gameRules.skill == SM_NIGHTMARE) return false; plr = &players[player]; @@ -650,7 +650,7 @@ D_CMD(CheatMassacre) { NetCl_CheatRequest("kill"); } - else if((IS_NETGAME && !netSvAllowCheats) || gameSkill == SM_NIGHTMARE) + else if((IS_NETGAME && !netSvAllowCheats) || gameRules.skill == SM_NIGHTMARE) { return false; } @@ -712,7 +712,7 @@ D_CMD(CheatMorph) { NetCl_CheatRequest("pig"); } - else if((IS_NETGAME && !netSvAllowCheats) || gameSkill == SM_NIGHTMARE) + else if((IS_NETGAME && !netSvAllowCheats) || gameRules.skill == SM_NIGHTMARE) { return false; } @@ -760,7 +760,7 @@ D_CMD(CheatShadowcaster) AutoStr *cmd = Str_Appendf(AutoStr_NewStd(), "class %i", (int)newClass); NetCl_CheatRequest(Str_Text(cmd)); } - else if((IS_NETGAME && !netSvAllowCheats) || gameSkill == SM_NIGHTMARE) + else if((IS_NETGAME && !netSvAllowCheats) || gameRules.skill == SM_NIGHTMARE) { return false; } @@ -799,7 +799,7 @@ D_CMD(CheatRunScript) AutoStr *cmd = Str_Appendf(AutoStr_NewStd(), "runscript %i", scriptNum); NetCl_CheatRequest(Str_Text(cmd)); } - else if((IS_NETGAME && !netSvAllowCheats) || gameSkill == SM_NIGHTMARE) + else if((IS_NETGAME && !netSvAllowCheats) || gameRules.skill == SM_NIGHTMARE) { return false; } diff --git a/doomsday/plugins/hexen/src/p_enemy.c b/doomsday/plugins/hexen/src/p_enemy.c index 48fd2178e8..ca02b65173 100644 --- a/doomsday/plugins/hexen/src/p_enemy.c +++ b/doomsday/plugins/hexen/src/p_enemy.c @@ -561,7 +561,7 @@ void C_DECL A_Chase(mobj_t* actor) actor->threshold--; } - if(gameSkill == SM_NIGHTMARE || (fastMonsters /*&& INCOMPAT_OK */ )) + if(gameRules.skill == SM_NIGHTMARE || (fastMonsters /*&& INCOMPAT_OK */ )) { // Monsters move faster in nightmare mode actor->tics -= actor->tics / 2; if(actor->tics < 3) @@ -600,7 +600,7 @@ void C_DECL A_Chase(mobj_t* actor) if(actor->flags & MF_JUSTATTACKED) { actor->flags &= ~MF_JUSTATTACKED; - if(gameSkill != SM_NIGHTMARE) + if(gameRules.skill != SM_NIGHTMARE) P_NewChaseDir(actor); return; } @@ -620,7 +620,7 @@ void C_DECL A_Chase(mobj_t* actor) // Check for missile attack. if((state = P_GetState(actor->type, SN_MISSILE)) != S_NULL) { - if(!(gameSkill != SM_NIGHTMARE && actor->moveCount)) + if(!(gameRules.skill != SM_NIGHTMARE && actor->moveCount)) { if(P_CheckMissileRange(actor)) { @@ -988,18 +988,19 @@ static int findMonster(thinker_t* th, void* context) /** * Look for enemy of player. */ -void C_DECL A_MinotaurLook(mobj_t* actor) +void C_DECL A_MinotaurLook(mobj_t *actor) { - mobj_t* master = actor->tracer; + mobj_t *master = actor->tracer; - actor->target = NULL; + actor->target = 0; - if(deathmatch) // Quick search for players. + if(gameRules.deathmatch) { + // Quick search for players. int i; coord_t dist; - player_t* player; - mobj_t* mo; + player_t *player; + mobj_t *mo; for(i = 0; i < MAXPLAYERS; ++i) { @@ -1708,7 +1709,7 @@ void C_DECL A_SerpentChase(mobj_t* actor) actor->threshold--; } - if(gameSkill == SM_NIGHTMARE || (fastMonsters)) + if(gameRules.skill == SM_NIGHTMARE || (fastMonsters)) { // Monsters move faster in nightmare mode. actor->tics -= actor->tics / 2; if(actor->tics < 3) @@ -1746,7 +1747,7 @@ void C_DECL A_SerpentChase(mobj_t* actor) if(actor->flags & MF_JUSTATTACKED) { actor->flags &= ~MF_JUSTATTACKED; - if(gameSkill != SM_NIGHTMARE) + if(gameRules.skill != SM_NIGHTMARE) P_NewChaseDir(actor); return; } @@ -1879,7 +1880,7 @@ void C_DECL A_SerpentWalk(mobj_t* actor) actor->threshold--; } - if(gameSkill == SM_NIGHTMARE || (fastMonsters)) + if(gameRules.skill == SM_NIGHTMARE || (fastMonsters)) { // Monsters move faster in nightmare mode. actor->tics -= actor->tics / 2; if(actor->tics < 3) @@ -1917,7 +1918,7 @@ void C_DECL A_SerpentWalk(mobj_t* actor) if(actor->flags & MF_JUSTATTACKED) { actor->flags &= ~MF_JUSTATTACKED; - if(gameSkill != SM_NIGHTMARE) + if(gameRules.skill != SM_NIGHTMARE) P_NewChaseDir(actor); return; } @@ -3905,7 +3906,7 @@ void C_DECL A_FastChase(mobj_t* mo) mo->threshold--; } - if(gameSkill == SM_NIGHTMARE || (fastMonsters)) + if(gameRules.skill == SM_NIGHTMARE || (fastMonsters)) { // Monsters move faster in nightmare mode. mo->tics -= mo->tics / 2; if(mo->tics < 3) @@ -3942,7 +3943,7 @@ void C_DECL A_FastChase(mobj_t* mo) if(mo->flags & MF_JUSTATTACKED) { mo->flags &= ~MF_JUSTATTACKED; - if(gameSkill != SM_NIGHTMARE) + if(gameRules.skill != SM_NIGHTMARE) P_NewChaseDir(mo); return; } @@ -3980,7 +3981,7 @@ void C_DECL A_FastChase(mobj_t* mo) // Check for missile attack. if((state = P_GetState(mo->type, SN_MISSILE)) != S_NULL) { - if(gameSkill != SM_NIGHTMARE && mo->moveCount) + if(gameRules.skill != SM_NIGHTMARE && mo->moveCount) goto nomissile; if(!P_CheckMissileRange(mo)) goto nomissile; @@ -4035,9 +4036,9 @@ void C_DECL A_MageAttack(mobj_t *mo) A_MStaffAttack2(mo); } -void C_DECL A_ClassBossHealth(mobj_t* mo) +void C_DECL A_ClassBossHealth(mobj_t *mo) { - if(IS_NETGAME && !deathmatch) // Co-op only. + if(IS_NETGAME && !gameRules.deathmatch) // Co-op only. { if(!mo->special1) { diff --git a/doomsday/plugins/hexen/src/p_inter.c b/doomsday/plugins/hexen/src/p_inter.c index eeb1219259..3a1960500a 100644 --- a/doomsday/plugins/hexen/src/p_inter.c +++ b/doomsday/plugins/hexen/src/p_inter.c @@ -305,7 +305,7 @@ static dd_bool giveOneAmmo(player_t *plr, ammotype_t ammoType, int numRounds) } // Give extra rounds at easy/nightmare skill levels. - if(gameSkill == SM_BABY || gameSkill == SM_NIGHTMARE) + if(gameRules.skill == SM_BABY || gameRules.skill == SM_NIGHTMARE) { numRounds += numRounds / 2; } @@ -369,7 +369,7 @@ static dd_bool giveOneWeapon(player_t *plr, weapontype_t weaponType, // Always attempt to give mana unless this a cooperative game and the // player already has this weapon piece. - if(!(IS_NETGAME && !deathmatch && plr->weapons[weaponType].owned)) + if(!(IS_NETGAME && !gameRules.deathmatch && plr->weapons[weaponType].owned)) { if(P_GiveAmmo(plr, ammoType, 25)) { @@ -429,7 +429,7 @@ dd_bool P_GiveWeaponPiece2(player_t *plr, int pieceValue, playerclass_t matchCla if(plr->class_ != matchClass) { // Can't pick up wrong-class weapons in coop netplay. - if(IS_NETGAME && !deathmatch) + if(IS_NETGAME && !gameRules.deathmatch) return false; return P_GiveAmmo(plr, AT_BLUEMANA, 20) | P_GiveAmmo(plr, AT_GREENMANA, 20); @@ -437,7 +437,7 @@ dd_bool P_GiveWeaponPiece2(player_t *plr, int pieceValue, playerclass_t matchCla // Always attempt to give mana unless this a cooperative game and the // player already has this weapon piece. - if(!((plr->pieces & pieceValue) && IS_NETGAME && !deathmatch)) + if(!((plr->pieces & pieceValue) && IS_NETGAME && !gameRules.deathmatch)) { gaveAmmo = P_GiveAmmo(plr, AT_BLUEMANA, 20) || P_GiveAmmo(plr, AT_GREENMANA, 20); @@ -446,7 +446,7 @@ dd_bool P_GiveWeaponPiece2(player_t *plr, int pieceValue, playerclass_t matchCla if(plr->pieces & pieceValue) { // Already has the piece. - if(IS_NETGAME && !deathmatch) // Cooperative net-game. + if(IS_NETGAME && !gameRules.deathmatch) // Cooperative net-game. return false; // Deathmatch or single player. @@ -456,7 +456,7 @@ dd_bool P_GiveWeaponPiece2(player_t *plr, int pieceValue, playerclass_t matchCla } // Check if fourth weapon assembled. - if(IS_NETGAME && !deathmatch) // Cooperative net-game. + if(IS_NETGAME && !gameRules.deathmatch) // Cooperative net-game. { static int pieceValueTrans[] = { 0, // 0: never @@ -721,7 +721,7 @@ dd_bool P_GiveItem(player_t *plr, inventoryitemtype_t item) static void setDormantItem(mobj_t *mo) { mo->flags &= ~MF_SPECIAL; - if(deathmatch && !(mo->flags2 & MF2_DROPPED)) + if(gameRules.deathmatch && !(mo->flags2 & MF2_DROPPED)) { if(mo->type == MT_ARTIINVULNERABILITY) { @@ -1122,7 +1122,7 @@ static dd_bool pickupWeapon(player_t *plr, weapontype_t weaponType, if(plr->class_ != matchClass) { // Leave placed weapons forever on net games. - if(IS_NETGAME && !deathmatch) + if(IS_NETGAME && !gameRules.deathmatch) return false; } @@ -1276,7 +1276,7 @@ static dd_bool giveItem(player_t *plr, itemtype_t item) void P_TouchSpecialMobj(mobj_t* special, mobj_t* toucher) { - player_t* player; + player_t *player; coord_t delta; itemtype_t item; dd_bool wasUsed = false, removeItem = false; @@ -1285,7 +1285,8 @@ void P_TouchSpecialMobj(mobj_t* special, mobj_t* toucher) delta = special->origin[VZ] - toucher->origin[VZ]; if(delta > toucher->height || delta < -32) - { // Out of reach. + { + // Out of reach. return; } @@ -1297,13 +1298,13 @@ void P_TouchSpecialMobj(mobj_t* special, mobj_t* toucher) // Identify by sprite. if((item = getItemTypeBySprite(special->sprite)) != IT_NONE) { - const iteminfo_t* info = &items[item]; + iteminfo_t const *info = &items[item]; if((wasUsed = giveItem(player, item))) { // Should we leave this item for others? - if(!((info->flags & IIF_LEAVE_COOP) && IS_NETGAME && !deathmatch) && - !((info->flags & IIF_LEAVE_DEATHMATCH) && IS_NETGAME && deathmatch)) + if(!((info->flags & IIF_LEAVE_COOP) && IS_NETGAME && !gameRules.deathmatch) && + !((info->flags & IIF_LEAVE_DEATHMATCH) && IS_NETGAME && gameRules.deathmatch)) removeItem = true; } } @@ -1371,7 +1372,7 @@ void P_TouchSpecialMobj(mobj_t* special, mobj_t* toucher) break; default: - if(deathmatch && !(special->flags2 & MF2_DROPPED)) + if(gameRules.deathmatch && !(special->flags2 & MF2_DROPPED)) P_HideSpecialThing(special); else P_MobjRemove(special, false); @@ -1457,7 +1458,7 @@ void P_KillMobj(mobj_t *source, mobj_t *target) if(source && source->player) { // Check for frag changes. - if(target->player && deathmatch) + if(target->player && gameRules.deathmatch) { if(target == source) { @@ -1565,7 +1566,7 @@ void P_KillMobj(mobj_t *source, mobj_t *target) * * @todo This should be a Thing definition flag. */ - if(IS_NETGAME && !deathmatch && source && source->player && + if(IS_NETGAME && !gameRules.deathmatch && source && source->player && source->player->plr && (target->type == MT_CENTAUR || target->type == MT_CENTAURLEADER || target->type == MT_DEMON || @@ -1856,7 +1857,7 @@ void P_AutoUseHealth(player_t* player, int saveHealth) if(!player->plr->mo) return; /// @todo Do this in the inventory code? - if(gameSkill == SM_BABY && normalCount * 25 >= saveHealth) + if(gameRules.skill == SM_BABY && normalCount * 25 >= saveHealth) { // Use quartz flasks. count = (saveHealth + 24) / 25; @@ -1876,7 +1877,7 @@ void P_AutoUseHealth(player_t* player, int saveHealth) P_InventoryTake(plrnum, IIT_SUPERHEALTH, false); } } - else if(gameSkill == SM_BABY && + else if(gameRules.skill == SM_BABY && superCount * 100 + normalCount * 25 >= saveHealth) { // Use mystic urns and quartz flasks. @@ -2027,7 +2028,7 @@ int P_DamageMobj2(mobj_t* target, mobj_t* inflictor, mobj_t* source, int damageP return 0; // Invulnerable, and won't wake up. player = target->player; - if(player && gameSkill == SM_BABY) + if(player && gameRules.skill == SM_BABY) damage /= 2; // Take half damage in trainer mode. // Use the cvar damage multiplier netMobDamageModifier only if the @@ -2067,7 +2068,7 @@ int P_DamageMobj2(mobj_t* target, mobj_t* inflictor, mobj_t* source, int damageP { if(target->player) { - if(deathmatch) + if(gameRules.deathmatch) P_TeleportToDeathmatchStarts(target); else P_TeleportToPlayerStarts(target); @@ -2266,8 +2267,10 @@ int P_DamageMobj2(mobj_t* target, mobj_t* inflictor, mobj_t* source, int damageP } if(damage >= player->health && - ((gameSkill == SM_BABY) || deathmatch) && !player->morphTics) - { // Try to use some inventory health. + ((gameRules.skill == SM_BABY) || gameRules.deathmatch) && + !player->morphTics) + { + // Try to use some inventory health. P_AutoUseHealth(player, damage - player->health + 1); } @@ -2452,11 +2455,10 @@ int P_FallingDamage(player_t* player) return P_DamageMobj(player->plr->mo, NULL, NULL, damage, false); } -int P_PoisonDamage(player_t* player, mobj_t* source, int damage, - dd_bool playPainSound) +int P_PoisonDamage(player_t *player, mobj_t *source, int damage, dd_bool playPainSound) { - int originalHealth; - mobj_t* target, *inflictor; + int originalHealth; + mobj_t *target, *inflictor; target = player->plr->mo; originalHealth = target->health; @@ -2468,8 +2470,9 @@ int P_PoisonDamage(player_t* player, mobj_t* source, int damage, if((target->flags2 & MF2_INVULNERABLE) && damage < 10000) return 0; // mobj is invulnerable. - if(gameSkill == SM_BABY) - { // Take half damage in trainer mode + if(gameRules.skill == SM_BABY) + { + // Take half damage in trainer mode damage /= 2; } @@ -2479,9 +2482,11 @@ int P_PoisonDamage(player_t* player, mobj_t* source, int damage, return 0; } - if(damage >= player->health && ((gameSkill == SM_BABY) || deathmatch) && + if(damage >= player->health && + (gameRules.skill == SM_BABY || gameRules.deathmatch) && !player->morphTics) - { // Try to use some inventory health. + { + // Try to use some inventory health. P_AutoUseHealth(player, damage - player->health + 1); } diff --git a/doomsday/plugins/hexen/src/p_maputl.c b/doomsday/plugins/hexen/src/p_maputl.c index ec594b895e..a76968ba97 100644 --- a/doomsday/plugins/hexen/src/p_maputl.c +++ b/doomsday/plugins/hexen/src/p_maputl.c @@ -40,7 +40,7 @@ int PIT_MobjTargetable(mobj_t *mo, void *data) if(!(mo->flags & MF_SHOOTABLE) || (mo->flags2 & MF2_DORMANT) || ((mo->type == MT_MINOTAUR) && (mo->tracer == params->source)) || - (IS_NETGAME && !deathmatch && mo->player)) + (IS_NETGAME && !gameRules.deathmatch && mo->player)) { return false; // Continue iteration. } @@ -63,7 +63,7 @@ int PIT_MobjTargetable(mobj_t *mo, void *data) if(!(mo->flags & MF_SHOOTABLE) || (mo->flags2 & MF2_DORMANT) || ((mo->type == MT_MINOTAUR) && (mo->tracer == params->source->tracer)) || - (IS_NETGAME && !deathmatch && mo->player)) + (IS_NETGAME && !gameRules.deathmatch && mo->player)) { return false; // Continue iteration. } @@ -83,7 +83,7 @@ int PIT_MobjTargetable(mobj_t *mo, void *data) !(mo->flags2 & MF2_DORMANT)) { if(!(mo->flags & MF_SHOOTABLE) || - (IS_NETGAME && !deathmatch && mo->player)) + (IS_NETGAME && !gameRules.deathmatch && mo->player)) { return false; // Continue iteration. } @@ -109,7 +109,7 @@ int PIT_MobjTargetable(mobj_t *mo, void *data) !(mo->flags2 & MF2_DORMANT)) { if(!(mo->flags & MF_SHOOTABLE) || - (IS_NETGAME && !deathmatch && mo->player) || + (IS_NETGAME && !gameRules.deathmatch && mo->player) || mo == params->source->target) { return false; // Continue iteration. diff --git a/doomsday/plugins/hexen/src/p_mobj.c b/doomsday/plugins/hexen/src/p_mobj.c index ffc9631be0..8ca423f6e9 100644 --- a/doomsday/plugins/hexen/src/p_mobj.c +++ b/doomsday/plugins/hexen/src/p_mobj.c @@ -1134,11 +1134,11 @@ mobj_t* P_SpawnMobjXYZ(mobjtype_t type, coord_t x, coord_t y, coord_t z, */ // Not for deathmatch? - if(deathmatch && (info->flags & MF_NOTDMATCH)) + if(gameRules.deathmatch && (info->flags & MF_NOTDMATCH)) return NULL; - // Don't spawn any monsters if -noMonstersParm. - if(noMonstersParm && (info->flags & MF_COUNTKILL)) + // Don't spawn any monsters? + if(gameRules.noMonsters && (info->flags & MF_COUNTKILL)) return NULL; if(info->flags & MF_SOLID) @@ -1160,7 +1160,7 @@ mobj_t* P_SpawnMobjXYZ(mobjtype_t type, coord_t x, coord_t y, coord_t z, mo->selector = 0; P_UpdateHealthBits(mo); // Set the health bits of the selector. - if(gameSkill != SM_NIGHTMARE) + if(gameRules.skill != SM_NIGHTMARE) { mo->reactionTime = info->reactionTime; } diff --git a/doomsday/plugins/hexen/src/p_pspr.c b/doomsday/plugins/hexen/src/p_pspr.c index 735b086210..94de1bfa8f 100644 --- a/doomsday/plugins/hexen/src/p_pspr.c +++ b/doomsday/plugins/hexen/src/p_pspr.c @@ -1565,8 +1565,9 @@ void C_DECL A_CHolyAttack2(mobj_t* mo) pmo->target = mo->target; pmo->args[0] = 10; // Initial turn value. pmo->args[1] = 0; // Initial look angle. - if(deathmatch) - { // Ghosts last slightly less longer in DeathMatch. + if(gameRules.deathmatch) + { + // Ghosts last slightly less longer in DeathMatch. pmo->health = 85; } diff --git a/doomsday/plugins/hexen/src/p_spec.c b/doomsday/plugins/hexen/src/p_spec.c index c03f7a5aa9..f226490bf4 100644 --- a/doomsday/plugins/hexen/src/p_spec.c +++ b/doomsday/plugins/hexen/src/p_spec.c @@ -515,7 +515,7 @@ dd_bool P_ExecuteLineSpecial(int special, byte args[5], Line *line, int side, mo if(!(mo && mo->player && mo->player->playerState == PST_DEAD)) { success = true; - if(deathmatch) + if(gameRules.deathmatch) { // Winning in deathmatch just goes back to map 1 G_LeaveMap(0, 0, false); diff --git a/doomsday/plugins/hexen/src/p_telept.c b/doomsday/plugins/hexen/src/p_telept.c index eb4f0f3ce9..2cfcb77bdc 100644 --- a/doomsday/plugins/hexen/src/p_telept.c +++ b/doomsday/plugins/hexen/src/p_telept.c @@ -246,18 +246,19 @@ dd_bool EV_Teleport(int tid, mobj_t* thing, dd_bool fog) } #if __JHERETIC__ || __JHEXEN__ -void P_ArtiTele(player_t* player) +void P_ArtiTele(player_t *player) { - const playerstart_t* start; + playerstart_t const *start; - if((start = P_GetPlayerStart(0, deathmatch? -1 : 0, deathmatch))) + if((start = P_GetPlayerStart(0, gameRules.deathmatch? -1 : 0, gameRules.deathmatch))) { - const mapspot_t* spot = &mapSpots[start->spot]; + mapspot_t const *spot = &mapSpots[start->spot]; P_Teleport(player->plr->mo, spot->origin[VX], spot->origin[VY], spot->angle, true); #if __JHEXEN__ if(player->morphTics) - { // Teleporting away will undo any morph effects (pig) + { + // Teleporting away will undo any morph effects (pig) P_UndoPlayerMorph(player); } #else diff --git a/doomsday/plugins/hexen/src/p_things.c b/doomsday/plugins/hexen/src/p_things.c index c48a920be9..8cdbba7119 100644 --- a/doomsday/plugins/hexen/src/p_things.c +++ b/doomsday/plugins/hexen/src/p_things.c @@ -153,7 +153,7 @@ dd_bool EV_ThingProjectile(byte* args, dd_bool gravity) searcher = -1; tid = args[0]; moType = TranslateThingType[args[1]]; - if(noMonstersParm && (MOBJINFO[moType].flags & MF_COUNTKILL)) + if(gameRules.noMonsters && (MOBJINFO[moType].flags & MF_COUNTKILL)) { // Don't spawn monsters if -nomonsters return false; @@ -191,11 +191,11 @@ dd_bool EV_ThingProjectile(byte* args, dd_bool gravity) return success; } -dd_bool EV_ThingSpawn(byte* args, dd_bool fog) +dd_bool EV_ThingSpawn(byte *args, dd_bool fog) { int tid, searcher; angle_t angle; - mobj_t* mobj, *newMobj, *fogMobj; + mobj_t *mobj, *newMobj, *fogMobj; mobjtype_t moType; dd_bool success; coord_t z; @@ -204,7 +204,7 @@ dd_bool EV_ThingSpawn(byte* args, dd_bool fog) searcher = -1; tid = args[0]; moType = TranslateThingType[args[1]]; - if(noMonstersParm && (MOBJINFO[moType].flags & MF_COUNTKILL)) + if(gameRules.noMonsters && (MOBJINFO[moType].flags & MF_COUNTKILL)) { // Don't spawn monsters if -nomonsters return false; diff --git a/doomsday/plugins/hexen/src/st_stuff.c b/doomsday/plugins/hexen/src/st_stuff.c index 5244118496..b65cd9ba19 100644 --- a/doomsday/plugins/hexen/src/st_stuff.c +++ b/doomsday/plugins/hexen/src/st_stuff.c @@ -808,7 +808,7 @@ void SBarBackground_Drawer(uiwidget_t* obj, const Point2Raw* offset) { GL_DrawPatchXY(pStatBar, ORIGINX+38, ORIGINY); - if(deathmatch) + if(gameRules.deathmatch) { GL_DrawPatchXY(pKills, ORIGINX+38, ORIGINY); } @@ -910,16 +910,16 @@ void SBarBackground_Drawer(uiwidget_t* obj, const Point2Raw* offset) patchinfo_t pStatBarInfo; if(R_GetPatchInfo(pStatBar, &pStatBarInfo)) { - x = ORIGINX + (deathmatch ? 68 : 38); + x = ORIGINX + (gameRules.deathmatch ? 68 : 38); y = ORIGINY; - w = deathmatch?214:244; + w = gameRules.deathmatch?214:244; h = 31; DGL_SetPatch(pStatBar, DGL_CLAMP_TO_EDGE, DGL_CLAMP_TO_EDGE); - DGL_DrawCutRectf2Tiled(x, y, w, h, pStatBarInfo.geometry.size.width, pStatBarInfo.geometry.size.height, deathmatch?30:0, 0, ORIGINX+190, ORIGINY, 57, 30); + DGL_DrawCutRectf2Tiled(x, y, w, h, pStatBarInfo.geometry.size.width, pStatBarInfo.geometry.size.height, gameRules.deathmatch?30:0, 0, ORIGINX+190, ORIGINY, 57, 30); } GL_DrawPatchXY(pWeaponSlot[pClass], ORIGINX+190, ORIGINY); - if(deathmatch) + if(gameRules.deathmatch) GL_DrawPatchXY(pKills, ORIGINX+38, ORIGINY); } else @@ -1229,7 +1229,7 @@ void SBarFrags_Drawer(uiwidget_t* obj, const Point2Raw* offset) //const float iconAlpha = (fullscreen == 0? 1 : uiRendState->pageAlpha * cfg.statusbarCounterAlpha); char buf[20]; - if(!deathmatch || Hu_InventoryIsOpen(obj->player) || ST_AutomapIsActive(obj->player)) return; + if(!gameRules.deathmatch || Hu_InventoryIsOpen(obj->player) || ST_AutomapIsActive(obj->player)) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; if(frags->value == 1994) return; @@ -1267,7 +1267,7 @@ void SBarFrags_UpdateGeometry(uiwidget_t* obj) Rect_SetWidthHeight(obj->geometry, 0, 0); - if(!deathmatch || Hu_InventoryIsOpen(obj->player) || ST_AutomapIsActive(obj->player)) return; + if(!gameRules.deathmatch || Hu_InventoryIsOpen(obj->player) || ST_AutomapIsActive(obj->player)) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; if(frags->value == 1994) return; @@ -1305,7 +1305,7 @@ void SBarHealth_Drawer(uiwidget_t* obj, const Point2Raw* offset) const float textAlpha = (fullscreen == 0? 1 : uiRendState->pageAlpha * cfg.statusbarCounterAlpha); //const float iconAlpha = (fullscreen == 0? 1 : uiRendState->pageAlpha * cfg.statusbarCounterAlpha); - if(deathmatch || Hu_InventoryIsOpen(obj->player) || ST_AutomapIsActive(obj->player)) return; + if(gameRules.deathmatch || Hu_InventoryIsOpen(obj->player) || ST_AutomapIsActive(obj->player)) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; if(hlth->value == 1994) return; @@ -1343,7 +1343,7 @@ void SBarHealth_UpdateGeometry(uiwidget_t* obj) Rect_SetWidthHeight(obj->geometry, 0, 0); - if(deathmatch || Hu_InventoryIsOpen(obj->player) || ST_AutomapIsActive(obj->player)) return; + if(gameRules.deathmatch || Hu_InventoryIsOpen(obj->player) || ST_AutomapIsActive(obj->player)) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; if(hlth->value == 1994) return; @@ -2344,7 +2344,7 @@ void Frags_Drawer(uiwidget_t* obj, const Point2Raw* offset) const float textAlpha = uiRendState->pageAlpha * cfg.hudColor[3]; char buf[20]; - if(!deathmatch) return; + if(!gameRules.deathmatch) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; if(frags->value == 1994) return; @@ -2380,7 +2380,7 @@ void Frags_UpdateGeometry(uiwidget_t* obj) Rect_SetWidthHeight(obj->geometry, 0, 0); - if(!deathmatch) return; + if(!gameRules.deathmatch) return; if(ST_AutomapIsActive(obj->player) && cfg.automapHudDisplay == 0) return; if(P_MobjIsCamera(players[obj->player].plr->mo) && Get(DD_PLAYBACK)) return; if(frags->value == 1994) return; @@ -2873,7 +2873,7 @@ static void initAutomapForCurrentMap(uiwidget_t* obj) UIAutomap_ClearPoints(obj); #if !__JHEXEN__ - if(gameSkill == SM_BABY && cfg.automapBabyKeys) + if(gameRules.skill == SM_BABY && cfg.automapBabyKeys) { int flags = UIAutomap_Flags(obj); UIAutomap_SetFlags(obj, flags|AMF_REND_KEYS); From aea339500b977b9cb36605a3371a8f8d658d8df1 Mon Sep 17 00:00:00 2001 From: danij Date: Tue, 4 Feb 2014 04:29:26 +0000 Subject: [PATCH 083/106] libcommon: Cleanup --- doomsday/plugins/common/include/g_common.h | 8 +-- doomsday/plugins/common/src/d_net.c | 8 +-- doomsday/plugins/common/src/d_netcl.c | 20 +++---- doomsday/plugins/common/src/d_netsv.c | 2 +- doomsday/plugins/common/src/g_game.c | 62 +++++++++++----------- doomsday/plugins/common/src/p_saveg.cpp | 18 +++---- doomsday/plugins/common/src/p_start.cpp | 8 +-- doomsday/plugins/doom/include/g_game.h | 3 +- doomsday/plugins/doom/src/p_oldsvg.cpp | 10 ++-- doomsday/plugins/doom64/include/g_game.h | 3 +- doomsday/plugins/heretic/include/g_game.h | 3 +- doomsday/plugins/heretic/src/p_oldsvg.cpp | 10 ++-- doomsday/plugins/hexen/include/g_game.h | 6 +-- doomsday/plugins/hexen/include/x_state.h | 1 - 14 files changed, 77 insertions(+), 85 deletions(-) diff --git a/doomsday/plugins/common/include/g_common.h b/doomsday/plugins/common/include/g_common.h index dad330e507..d0035ec55c 100644 --- a/doomsday/plugins/common/include/g_common.h +++ b/doomsday/plugins/common/include/g_common.h @@ -69,11 +69,11 @@ void G_EndGame(void); dd_bool G_QuitInProgress(void); /** - * @param map Logical map number (i.e., not a warp/translated number). - * @param mapEntryPoint Logical map entry point number. + * @param map Logical map number (i.e., not a warp/translated number). + * @param mapEntrance Logical map entry point number. */ -void G_NewGame(skillmode_t skill, uint episode, uint map, uint mapEntryPoint); -void G_DeferredNewGame(skillmode_t skill, uint episode, uint map, uint mapEntryPoint); +void G_NewGame(skillmode_t skill, uint episode, uint map, uint mapEntrance); +void G_DeferredNewGame(skillmode_t skill, uint episode, uint map, uint mapEntrance); /** * Signal that play on the current map may now begin. diff --git a/doomsday/plugins/common/src/d_net.c b/doomsday/plugins/common/src/d_net.c index 3222b04cd8..f7cf93838b 100644 --- a/doomsday/plugins/common/src/d_net.c +++ b/doomsday/plugins/common/src/d_net.c @@ -33,10 +33,10 @@ D_CMD(SetClass); #endif D_CMD(LocalMessage); -static void D_NetMessageEx(int player, const char* msg, dd_bool playSound); - extern int netSvAllowSendMsg; +static void D_NetMessageEx(int player, char const *msg, dd_bool playSound); + float netJumpPower = 9; static Writer *netWriter; @@ -68,7 +68,7 @@ void D_NetConsoleRegistration(void) C_CMD ("message", "s", LocalMessage); } -Writer* D_NetWrite(void) +Writer *D_NetWrite(void) { if(netWriter) { @@ -78,7 +78,7 @@ Writer* D_NetWrite(void) return netWriter; } -Reader* D_NetRead(const byte* buffer, size_t len) +Reader *D_NetRead(byte const *buffer, size_t len) { // Get rid of the old reader. if(netReader) diff --git a/doomsday/plugins/common/src/d_netcl.c b/doomsday/plugins/common/src/d_netcl.c index 070c03edc3..e67a2f0771 100644 --- a/doomsday/plugins/common/src/d_netcl.c +++ b/doomsday/plugins/common/src/d_netcl.c @@ -45,7 +45,7 @@ void NetCl_UpdateGameState(Reader* msg) Uri* mapUri; byte gsEpisode = 0; byte gsMap = 0; - byte gsMapEntryPoint = 0; + byte gsMapEntrance = 0; byte configFlags = 0; byte gsDeathmatch = 0; byte gsMonsters = 0; @@ -141,7 +141,7 @@ void NetCl_UpdateGameState(Reader* msg) // Do we need to change the map? if(gsFlags & GSF_CHANGE_MAP) { - G_NewGame(gsSkill, gsEpisode, gsMap, gameMapEntryPoint /*gsMapEntryPoint*/); + G_NewGame(gsSkill, gsEpisode, gsMap, gameMapEntrance /*gsMapEntrance*/); /// @todo Necessary? G_SetGameAction(GA_NONE); @@ -154,7 +154,7 @@ void NetCl_UpdateGameState(Reader* msg) gameRules.skill = gsSkill; /// @todo Not communicated to clients?? - //gameMapEntryPoint = gsMapEntryPoint; + //gameMapEntrance = gsMapEntrance; } // Set gravity. @@ -699,20 +699,20 @@ void NetCl_Intermission(Reader* msg) // @todo jHeretic does not transmit the intermission info! #if __JDOOM__ || __JDOOM64__ - wmInfo.maxKills = Reader_ReadUInt16(msg); - wmInfo.maxItems = Reader_ReadUInt16(msg); - wmInfo.maxSecret = Reader_ReadUInt16(msg); - wmInfo.nextMap = Reader_ReadByte(msg); + wmInfo.maxKills = Reader_ReadUInt16(msg); + wmInfo.maxItems = Reader_ReadUInt16(msg); + wmInfo.maxSecret = Reader_ReadUInt16(msg); + wmInfo.nextMap = Reader_ReadByte(msg); wmInfo.currentMap = Reader_ReadByte(msg); - wmInfo.didSecret = Reader_ReadByte(msg); + wmInfo.didSecret = Reader_ReadByte(msg); wmInfo.episode = gameEpisode; G_PrepareWIData(); #elif __JHERETIC__ wmInfo.episode = gameEpisode; #elif __JHEXEN__ - nextMap = Reader_ReadByte(msg); - nextMapEntryPoint = Reader_ReadByte(msg); + nextMap = Reader_ReadByte(msg); + nextMapEntrance = Reader_ReadByte(msg); #endif #if __JDOOM__ || __JDOOM64__ diff --git a/doomsday/plugins/common/src/d_netsv.c b/doomsday/plugins/common/src/d_netsv.c index 0ca78f0c20..a655e16fc2 100644 --- a/doomsday/plugins/common/src/d_netsv.c +++ b/doomsday/plugins/common/src/d_netsv.c @@ -595,7 +595,7 @@ void NetSv_NewPlayerEnters(int plrNum) playerclass_t pClass = P_ClassForPlayerWhenRespawning(plrNum, false); playerstart_t const *start; - if((start = P_GetPlayerStart(gameMapEntryPoint, plrNum, false))) + if((start = P_GetPlayerStart(gameMapEntrance, plrNum, false))) { mapspot_t const *spot = &mapSpots[start->spot]; diff --git a/doomsday/plugins/common/src/g_game.c b/doomsday/plugins/common/src/g_game.c index e4468ce928..070622a95d 100644 --- a/doomsday/plugins/common/src/g_game.c +++ b/doomsday/plugins/common/src/g_game.c @@ -161,17 +161,15 @@ static void G_InitNewGame(void); game_config_t cfg; // The global cfg. -skillmode_t dSkill; // Default. - dd_bool gameInProgress; uint gameEpisode; uint gameMap; -uint gameMapEntryPoint; // Position indicator for reborn. +uint gameMapEntrance; // Position indicator for reborn. GameRuleset gameRules; uint nextMap; #if __JHEXEN__ -uint nextMapEntryPoint; +uint nextMapEntrance; #endif #if __JDOOM__ || __JHERETIC__ || __JDOOM64__ @@ -186,7 +184,6 @@ dd_bool monsterInfight; player_t players[MAXPLAYERS]; -int mapStartTic; // Game tic at map start. int totalKills, totalItems, totalSecret; // For intermission. dd_bool singledemo; // Quit after playing a demo from cmdline. @@ -404,9 +401,11 @@ ccmdtemplate_t gameCmds[] = { { NULL } }; +// Deferred new game arguments: +static skillmode_t dSkill; static uint dEpisode; static uint dMap; -static uint dMapEntryPoint; +static uint dMapEntrance; static gameaction_t gameAction; static dd_bool quitInProgress; @@ -1190,7 +1189,6 @@ void G_BeginMap(void) G_UpdateGSVarsForMap(); // Time can now progress in this map. - mapStartTic = (int) GAMETIC; mapTime = actualMapTime = 0; printMapBanner(); @@ -1547,7 +1545,7 @@ static void runGameAction(void) { case GA_NEWGAME: G_InitNewGame(); - G_NewGame(dSkill, dEpisode, dMap, dMapEntryPoint); + G_NewGame(dSkill, dEpisode, dMap, dMapEntrance); G_SetGameAction(GA_NONE); break; @@ -2294,7 +2292,7 @@ void G_LeaveMap(uint newMap, uint _entryPoint, dd_bool _secretExit) #if __JHEXEN__ nextMap = newMap; - nextMapEntryPoint = _entryPoint; + nextMapEntrance = _entryPoint; #else secretExit = _secretExit; # if __JDOOM__ @@ -2338,7 +2336,7 @@ dd_bool G_IfVictory(void) } #elif __JHEXEN__ - if(nextMap == DDMAXINT && nextMapEntryPoint == DDMAXINT) + if(nextMap == DDMAXINT && nextMapEntrance == DDMAXINT) { return true; } @@ -2467,7 +2465,7 @@ void G_DoMapCompleted(void) #if __JDOOM__ || __JDOOM64__ || __JHERETIC__ NetSv_Intermission(IMF_BEGIN, 0, 0); #else /* __JHEXEN__ */ - NetSv_Intermission(IMF_BEGIN, (int) nextMap, (int) nextMapEntryPoint); + NetSv_Intermission(IMF_BEGIN, (int) nextMap, (int) nextMapEntrance); #endif S_PauseMusic(false); @@ -2674,9 +2672,9 @@ void G_DoLeaveMap(void) #endif #if __JHEXEN__ - gameMapEntryPoint = nextMapEntryPoint; + gameMapEntrance = nextMapEntrance; #else - gameMapEntryPoint = 0; + gameMapEntrance = 0; #endif p.mapUri = G_ComposeMapUri(gameEpisode, nextMap); @@ -2714,7 +2712,7 @@ void G_DoLeaveMap(void) P_RemoveAllPlayerMobjs(); } - SV_HxRestorePlayersInCluster(playerBackup, nextMapEntryPoint); + SV_HxRestorePlayersInCluster(playerBackup, nextMapEntrance); // Restore the random class rule. gameRules.randomClasses = oldRandomClassesRule; @@ -2748,7 +2746,7 @@ void G_DoRestartMap(void) // Restart the game session entirely. G_InitNewGame(); - G_NewGame(dSkill, dEpisode, dMap, dMapEntryPoint); + G_NewGame(dSkill, dEpisode, dMap, dMapEntrance); #else loadmap_params_t p; @@ -2959,17 +2957,17 @@ void G_DoSaveGame(void) G_SetGameAction(GA_NONE); } -void G_DeferredNewGame(skillmode_t skill, uint episode, uint map, uint mapEntryPoint) +void G_DeferredNewGame(skillmode_t skill, uint episode, uint map, uint mapEntrance) { - dSkill = skill; - dEpisode = episode; - dMap = map; - dMapEntryPoint = mapEntryPoint; + dSkill = skill; + dEpisode = episode; + dMap = map; + dMapEntrance = mapEntrance; G_SetGameAction(GA_NEWGAME); } -void G_NewGame(skillmode_t skill, uint episode, uint map, uint mapEntryPoint) +void G_NewGame(skillmode_t skill, uint episode, uint map, uint mapEntrance) { uint i; @@ -3016,9 +3014,9 @@ void G_NewGame(skillmode_t skill, uint episode, uint map, uint mapEntryPoint) // Make sure that the episode and map numbers are good. G_ValidateMap(&episode, &map); - gameEpisode = episode; - gameMap = map; - gameMapEntryPoint = mapEntryPoint; + gameEpisode = episode; + gameMap = map; + gameMapEntrance = mapEntrance; G_ApplyGameRules(skill); M_ResetRandom(); @@ -3027,14 +3025,14 @@ void G_NewGame(skillmode_t skill, uint episode, uint map, uint mapEntryPoint) { loadmap_params_t p; - dd_bool hasBrief; + dd_bool showBrief; ddfinale_t fin; p.mapUri = G_CurrentMapUri(); p.revisit = false; - hasBrief = G_BriefingEnabled(p.mapUri, &fin); - if(!hasBrief) + showBrief = G_BriefingEnabled(p.mapUri, &fin); + if(!showBrief) { G_QueMapMusic(p.mapUri); } @@ -3044,7 +3042,7 @@ void G_NewGame(skillmode_t skill, uint episode, uint map, uint mapEntryPoint) G_DoLoadMap(&p); - if(hasBrief) + if(showBrief) { G_StartFinale(fin.script, 0, FIMODE_BEFORE, 0); } @@ -3468,7 +3466,7 @@ int G_DebriefingEnabled(Uri const *mapUri, ddfinale_t *fin) #if __JHEXEN__ if(cfg.overrideHubMsg && G_GameState() == GS_MAP && - !(nextMap == DDMAXINT && nextMapEntryPoint == DDMAXINT)) + !(nextMap == DDMAXINT && nextMapEntrance == DDMAXINT)) { Uri *nextMapUri = G_ComposeMapUri(gameEpisode, nextMap); if(P_MapInfo(mapUri)->cluster != P_MapInfo(nextMapUri)->cluster) @@ -3999,8 +3997,8 @@ D_CMD(WarpMap) if(!forceNewGameSession && gameInProgress) { #if __JHEXEN__ - nextMap = map; - nextMapEntryPoint = 0; + nextMap = map; + nextMapEntrance = 0; G_SetGameAction(GA_LEAVEMAP); #else G_DeferredNewGame(gameRules.skill, epsd, map, 0/*default*/); @@ -4008,7 +4006,7 @@ D_CMD(WarpMap) } else { - G_DeferredNewGame(IS_SERVER? cfg.netSkill : dSkill, epsd, map, 0/*default*/); + G_DeferredNewGame(IS_SERVER? cfg.netSkill : gameRules.skill, epsd, map, 0/*default*/); } // If the command source was "us" the game library then it was probably in diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index ee01f949c9..bfa885ef74 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -3670,10 +3670,10 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) */ curInfo = saveInfo; - gameEpisode = saveInfo->episode(); - gameMap = saveInfo->map(); - gameMapEntryPoint = 0; /// @todo Not saved?? - gameRules = saveInfo->gameRules(); + gameEpisode = saveInfo->episode(); + gameMap = saveInfo->map(); + gameMapEntrance = 0; /// @todo Not saved?? + gameRules = saveInfo->gameRules(); #if __JHEXEN__ Game_ACScriptInterpreter().readWorldScriptData(reader, saveInfo->version()); @@ -3683,7 +3683,7 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) * Load the map and configure some game settings. */ briefDisabled = true; - G_NewGame(gameRules.skill, gameEpisode, gameMap, 0/*gameMapEntryPoint*/); + G_NewGame(gameRules.skill, gameEpisode, gameMap, gameMapEntrance); G_SetGameAction(GA_NONE); /// @todo Necessary? @@ -4001,10 +4001,10 @@ void SV_LoadGameClient(uint gameId) // Do we need to change the map? if(gameMap != saveInfo->map() || gameEpisode != saveInfo->episode()) { - gameEpisode = saveInfo->episode(); - gameMap = saveInfo->map(); - gameMapEntryPoint = 0; - G_NewGame(gameRules.skill, gameEpisode, gameMap, gameMapEntryPoint); + gameEpisode = saveInfo->episode(); + gameMap = saveInfo->map(); + gameMapEntrance = 0; + G_NewGame(gameRules.skill, gameEpisode, gameMap, gameMapEntrance); /// @todo Necessary? G_SetGameAction(GA_NONE); } diff --git a/doomsday/plugins/common/src/p_start.cpp b/doomsday/plugins/common/src/p_start.cpp index 9e91039952..9af8bc8762 100644 --- a/doomsday/plugins/common/src/p_start.cpp +++ b/doomsday/plugins/common/src/p_start.cpp @@ -321,7 +321,7 @@ playerstart_t const *P_GetPlayerStart(uint entryPoint, int pnum, dd_bool deathma { playerstart_t const *start = &playerStarts[i]; - if(start->entryPoint == nextMapEntryPoint && start->plrNum - 1 == pnum) + if(start->entryPoint == nextMapEntrance && start->plrNum - 1 == pnum) return start; if(!start->entryPoint && start->plrNum - 1 == pnum) def = start; @@ -691,7 +691,7 @@ void P_RebornPlayerInMultiplayer(int plrNum) int spawnFlags = 0; dd_bool makeCamera = false; - uint entryPoint = gameMapEntryPoint; + uint entryPoint = gameMapEntrance; dd_bool foundSpot = false; playerstart_t const *assigned = P_GetPlayerStart(entryPoint, plrNum, false); @@ -749,7 +749,7 @@ void P_RebornPlayerInMultiplayer(int plrNum) // Try to spawn at one of the other player start spots. for(int i = 0; i < MAXPLAYERS; ++i) { - if(playerstart_t const *start = P_GetPlayerStart(gameMapEntryPoint, i, false)) + if(playerstart_t const *start = P_GetPlayerStart(gameMapEntrance, i, false)) { mapspot_t const *spot = &mapSpots[start->spot]; @@ -778,7 +778,7 @@ void P_RebornPlayerInMultiplayer(int plrNum) if(!foundSpot) { // Player's going to be inside something. - if(playerstart_t const *start = P_GetPlayerStart(gameMapEntryPoint, plrNum, false)) + if(playerstart_t const *start = P_GetPlayerStart(gameMapEntrance, plrNum, false)) { mapspot_t const *spot = &mapSpots[start->spot]; diff --git a/doomsday/plugins/doom/include/g_game.h b/doomsday/plugins/doom/include/g_game.h index acbcace080..92aac3ac9c 100644 --- a/doomsday/plugins/doom/include/g_game.h +++ b/doomsday/plugins/doom/include/g_game.h @@ -51,7 +51,7 @@ extern player_t players[MAXPLAYERS]; extern dd_bool gameInProgress; extern uint gameEpisode; extern uint gameMap; -extern uint gameMapEntryPoint; +extern uint gameMapEntrance; extern GameRuleset gameRules; extern uint nextMap; // If non zero this will be the next map. @@ -62,7 +62,6 @@ extern dd_bool precache; extern dd_bool customPal; extern wbstartstruct_t wmInfo; extern int bodyQueueSlot; -extern int mapStartTic; extern dd_bool briefDisabled; extern int gsvMapMusic; diff --git a/doomsday/plugins/doom/src/p_oldsvg.cpp b/doomsday/plugins/doom/src/p_oldsvg.cpp index d5cc3c17bb..d51622c872 100644 --- a/doomsday/plugins/doom/src/p_oldsvg.cpp +++ b/doomsday/plugins/doom/src/p_oldsvg.cpp @@ -842,16 +842,16 @@ int SV_LoadState_Dm_v19(Str const *path, SaveInfo *info) delete tmp; } - gameEpisode = info->episode(); - gameMap = info->map(); - gameMapEntryPoint = 0; /// @todo Not saved?? - gameRules = info->gameRules(); + gameEpisode = info->episode(); + gameMap = info->map(); + gameMapEntrance = 0; /// @todo Not saved?? + gameRules = info->gameRules(); // We don't want to see a briefing if we're loading a save game. briefDisabled = true; // Load a base map. - G_NewGame(gameRules.skill, gameEpisode, gameMap, gameMapEntryPoint); + G_NewGame(gameRules.skill, gameEpisode, gameMap, gameMapEntrance); /// @todo Necessary? G_SetGameAction(GA_NONE); diff --git a/doomsday/plugins/doom64/include/g_game.h b/doomsday/plugins/doom64/include/g_game.h index d13b233ca1..0979b986a1 100644 --- a/doomsday/plugins/doom64/include/g_game.h +++ b/doomsday/plugins/doom64/include/g_game.h @@ -52,14 +52,13 @@ extern uint nextMap; extern dd_bool gameInProgress; extern uint gameEpisode; extern uint gameMap; -extern uint gameMapEntryPoint; +extern uint gameMapEntrance; extern GameRuleset gameRules; extern uint nextMap; // If non zero this will be the next map. extern dd_bool secretExit; extern int totalKills, totalItems, totalSecret; extern wbstartstruct_t wmInfo; -extern int mapStartTic; extern int bodyQueueSlot; extern dd_bool paused; extern dd_bool precache; diff --git a/doomsday/plugins/heretic/include/g_game.h b/doomsday/plugins/heretic/include/g_game.h index 825537ac69..6be1ac8f61 100644 --- a/doomsday/plugins/heretic/include/g_game.h +++ b/doomsday/plugins/heretic/include/g_game.h @@ -51,12 +51,11 @@ extern player_t players[MAXPLAYERS]; extern dd_bool gameInProgress; extern uint gameEpisode; extern uint gameMap; -extern uint gameMapEntryPoint; +extern uint gameMapEntrance; extern GameRuleset gameRules; extern uint nextMap; extern dd_bool secretExit; -extern int mapStartTic; extern int totalKills, totalItems, totalSecret; extern dd_bool paused; extern dd_bool precache; diff --git a/doomsday/plugins/heretic/src/p_oldsvg.cpp b/doomsday/plugins/heretic/src/p_oldsvg.cpp index 6d29f145d8..b056641c25 100644 --- a/doomsday/plugins/heretic/src/p_oldsvg.cpp +++ b/doomsday/plugins/heretic/src/p_oldsvg.cpp @@ -851,16 +851,16 @@ int SV_LoadState_Hr_v13(Str const *path, SaveInfo *info) delete tmp; } - gameEpisode = info->episode(); - gameMap = info->map(); - gameMapEntryPoint = 0; /// @todo Not saved?? - gameRules = info->gameRules(); + gameEpisode = info->episode(); + gameMap = info->map(); + gameMapEntrance = 0; /// @todo Not saved?? + gameRules = info->gameRules(); // We don't want to see a briefing if we're loading a save game. briefDisabled = true; // Load a base map. - G_NewGame(gameRules.skill, gameEpisode, gameMap, gameMapEntryPoint); + G_NewGame(gameRules.skill, gameEpisode, gameMap, gameMapEntrance); /// @todo Necessary? G_SetGameAction(GA_NONE); diff --git a/doomsday/plugins/hexen/include/g_game.h b/doomsday/plugins/hexen/include/g_game.h index b3730ac4d6..9917f93d2a 100644 --- a/doomsday/plugins/hexen/include/g_game.h +++ b/doomsday/plugins/hexen/include/g_game.h @@ -48,17 +48,15 @@ extern player_t players[MAXPLAYERS]; extern dd_bool gameInProgress; extern uint gameEpisode; extern uint gameMap; -extern uint gameMapEntryPoint; +extern uint gameMapEntrance; extern GameRuleset gameRules; extern dd_bool paused; extern dd_bool precache; extern dd_bool customPal; -extern skillmode_t dSkill; - extern uint nextMap; -extern uint nextMapEntryPoint; +extern uint nextMapEntrance; extern dd_bool briefDisabled; extern int gsvMapMusic; diff --git a/doomsday/plugins/hexen/include/x_state.h b/doomsday/plugins/hexen/include/x_state.h index 7f80e3a82e..d914448d38 100644 --- a/doomsday/plugins/hexen/include/x_state.h +++ b/doomsday/plugins/hexen/include/x_state.h @@ -54,7 +54,6 @@ extern dd_bool paused; // Game Pause? DENG_EXTERN_C int viewangleoffset; // Timer, for scores. -DENG_EXTERN_C int mapStartTic; // Game tic at map start. DENG_EXTERN_C int mapTime; // Tics in game play for par. // Quit after playing a demo from cmdline. From 638f51d67ce375b5b2cabc4033922d7771e4a5c4 Mon Sep 17 00:00:00 2001 From: danij Date: Tue, 4 Feb 2014 05:20:23 +0000 Subject: [PATCH 084/106] libcommon: Ensure game rule changes are fully applied when staring a new game --- doomsday/plugins/common/include/g_common.h | 6 ++- doomsday/plugins/common/src/d_net.c | 5 +- doomsday/plugins/common/src/d_netcl.c | 58 ++++++++++------------ doomsday/plugins/common/src/g_game.c | 43 +++++++++------- doomsday/plugins/common/src/hu_menu.c | 7 ++- doomsday/plugins/common/src/p_saveg.cpp | 41 ++++++--------- doomsday/plugins/doom/src/d_main.c | 14 +++--- doomsday/plugins/doom/src/p_oldsvg.cpp | 16 +++--- doomsday/plugins/doom64/src/d_main.c | 14 +++--- doomsday/plugins/heretic/src/p_oldsvg.cpp | 16 +++--- doomsday/plugins/hexen/src/h2_main.c | 2 +- 11 files changed, 106 insertions(+), 116 deletions(-) diff --git a/doomsday/plugins/common/include/g_common.h b/doomsday/plugins/common/include/g_common.h index d0035ec55c..189d1cf6dc 100644 --- a/doomsday/plugins/common/include/g_common.h +++ b/doomsday/plugins/common/include/g_common.h @@ -69,11 +69,13 @@ void G_EndGame(void); dd_bool G_QuitInProgress(void); /** + * @param episode Logical episode number. * @param map Logical map number (i.e., not a warp/translated number). * @param mapEntrance Logical map entry point number. + * @param rules Game rules to apply. */ -void G_NewGame(skillmode_t skill, uint episode, uint map, uint mapEntrance); -void G_DeferredNewGame(skillmode_t skill, uint episode, uint map, uint mapEntrance); +void G_NewGame(uint episode, uint map, uint mapEntrance, GameRuleset const *rules); +void G_DeferredNewGame(uint episode, uint map, uint mapEntrance, GameRuleset const *rules); /** * Signal that play on the current map may now begin. diff --git a/doomsday/plugins/common/src/d_net.c b/doomsday/plugins/common/src/d_net.c index f7cf93838b..ab79f14af1 100644 --- a/doomsday/plugins/common/src/d_net.c +++ b/doomsday/plugins/common/src/d_net.c @@ -127,6 +127,7 @@ void NetSv_ApplyGameRulesFromConfig(void) int D_NetServerStarted(int before) { uint netMap, netEpisode; + GameRuleset netRules = gameRules; // Make a copy of the current rules. if(before) return true; @@ -156,7 +157,9 @@ int D_NetServerStarted(int before) netEpisode = cfg.netEpisode; #endif - G_NewGame(cfg.netSkill, netEpisode, netMap, 0/*default*/); + netRules.skill = cfg.netSkill; + + G_NewGame(netEpisode, netMap, 0/*default*/, &netRules); /// @todo Necessary? G_SetGameAction(GA_NONE); diff --git a/doomsday/plugins/common/src/d_netcl.c b/doomsday/plugins/common/src/d_netcl.c index e67a2f0771..818cfa4f5b 100644 --- a/doomsday/plugins/common/src/d_netcl.c +++ b/doomsday/plugins/common/src/d_netcl.c @@ -47,12 +47,13 @@ void NetCl_UpdateGameState(Reader* msg) byte gsMap = 0; byte gsMapEntrance = 0; byte configFlags = 0; - byte gsDeathmatch = 0; - byte gsMonsters = 0; - byte gsRespawn = 0; + //byte gsDeathmatch = 0; + //byte gsMonsters = 0; + //byte gsRespawn = 0; byte gsJumping = 0; - byte gsSkill = 0; + //byte gsSkill = 0; coord_t gsGravity = 0; + GameRuleset gsRules = gameRules; // Make a copy of the current rules. BusyMode_FreezeGameForBusyMode(); @@ -73,15 +74,17 @@ void NetCl_UpdateGameState(Reader* msg) //gsMapEntryPoint = ??; configFlags = Reader_ReadByte(msg); - gsDeathmatch = configFlags & 0x3; - gsMonsters = (configFlags & 0x4? true : false); - gsRespawn = (configFlags & 0x8? true : false); + gsRules.deathmatch = configFlags & 0x3; + gsRules.noMonsters = !(configFlags & 0x4? true : false); +#if !__JHEXEN__ + gsRules.respawnMonsters = (configFlags & 0x8? true : false); +#endif gsJumping = (configFlags & 0x10? true : false); - gsSkill = Reader_ReadByte(msg); + gsRules.skill = Reader_ReadByte(msg); // Interpret skill modes outside the normal range as "spawn no things". - if(gsSkill < SM_BABY || gsSkill >= NUM_SKILL_MODES) - gsSkill = SM_NOTHINGS; + if(gsRules.skill < SM_BABY || gsRules.skill >= NUM_SKILL_MODES) + gsRules.skill = SM_NOTHINGS; gsGravity = Reader_ReadFloat(msg); @@ -109,39 +112,33 @@ void NetCl_UpdateGameState(Reader* msg) } } - gameRules.deathmatch = gsDeathmatch; - gameRules.noMonsters = !gsMonsters; -#if !__JHEXEN__ - gameRules.respawnMonsters = gsRespawn; -#endif - // Some statistics. #if __JHEXEN__ App_Log(DE2_LOG_NOTE, - "Game state: Map=%u Skill=%i %s", gsMap+1, gsSkill, - gameRules.deathmatch == 1 ? "Deathmatch" : - gameRules.deathmatch == 2 ? "Deathmatch2" : "Co-op"); + "Game state: Map=%u Skill=%i %s", gsMap+1, gsRules.skill, + gsRules.deathmatch == 1 ? "Deathmatch" : + gsRules.deathmatch == 2 ? "Deathmatch2" : "Co-op"); #else App_Log(DE2_LOG_NOTE, "Game state: Map=%u Episode=%u Skill=%i %s", gsMap+1, - gsEpisode+1, gsSkill, - gameRules.deathmatch == 1 ? "Deathmatch" : - gameRules.deathmatch == 2 ? "Deathmatch2" : "Co-op"); + gsEpisode+1, gsRules.skill, + gsRules.deathmatch == 1 ? "Deathmatch" : + gsRules.deathmatch == 2 ? "Deathmatch2" : "Co-op"); #endif #if !__JHEXEN__ App_Log(DE2_LOG_NOTE, " Respawn=%s Monsters=%s Jumping=%s Gravity=%.1f", - gameRules.respawnMonsters ? "yes" : "no", !gameRules.noMonsters ? "yes" : "no", + gsRules.respawnMonsters ? "yes" : "no", !gsRules.noMonsters ? "yes" : "no", gsJumping ? "yes" : "no", gsGravity); #else App_Log(DE2_NET_NOTE, " Monsters=%s Jumping=%s Gravity=%.1f", - !gameRules.noMonsters ? "yes" : "no", + !gsRules.noMonsters ? "yes" : "no", gsJumping ? "yes" : "no", gsGravity); #endif // Do we need to change the map? if(gsFlags & GSF_CHANGE_MAP) { - G_NewGame(gsSkill, gsEpisode, gsMap, gameMapEntrance /*gsMapEntrance*/); + G_NewGame(gsEpisode, gsMap, gameMapEntrance /*gsMapEntrance*/, &gsRules); /// @todo Necessary? G_SetGameAction(GA_NONE); @@ -150,11 +147,8 @@ void NetCl_UpdateGameState(Reader* msg) { gameEpisode = gsEpisode; gameMap = gsMap; - - gameRules.skill = gsSkill; - - /// @todo Not communicated to clients?? - //gameMapEntrance = gsMapEntrance; + //gameMapEntrance = gsMapEntrance; /// @todo Not communicated to clients?? + gameRules = gsRules; } // Set gravity. @@ -164,8 +158,8 @@ void NetCl_UpdateGameState(Reader* msg) // Camera init included? if(gsFlags & GSF_CAMERA_INIT) { - player_t* pl = &players[CONSOLEPLAYER]; - mobj_t* mo; + player_t *pl = &players[CONSOLEPLAYER]; + mobj_t *mo; mo = pl->plr->mo; if(mo) diff --git a/doomsday/plugins/common/src/g_game.c b/doomsday/plugins/common/src/g_game.c index 070622a95d..8832218d1b 100644 --- a/doomsday/plugins/common/src/g_game.c +++ b/doomsday/plugins/common/src/g_game.c @@ -402,10 +402,10 @@ ccmdtemplate_t gameCmds[] = { }; // Deferred new game arguments: -static skillmode_t dSkill; static uint dEpisode; static uint dMap; static uint dMapEntrance; +static GameRuleset dRules; static gameaction_t gameAction; static dd_bool quitInProgress; @@ -1545,7 +1545,7 @@ static void runGameAction(void) { case GA_NEWGAME: G_InitNewGame(); - G_NewGame(dSkill, dEpisode, dMap, dMapEntrance); + G_NewGame(dEpisode, dMap, dMapEntrance, &dRules); G_SetGameAction(GA_NONE); break; @@ -2220,13 +2220,16 @@ static void G_ApplyGameRuleFastMissiles(dd_bool fast) } #endif -static void G_ApplyGameRules(skillmode_t skill) +/** + * To be called when a new game begins to effect the game rules. Note that some + * of the rules may be overridden here (e.g., in a networked game). + */ +static void G_ApplyNewGameRules() { - if(skill < SM_NOTHINGS) - skill = SM_NOTHINGS; - if(skill > NUM_SKILL_MODES - 1) - skill = NUM_SKILL_MODES - 1; - gameRules.skill = skill; + if(gameRules.skill < SM_NOTHINGS) + gameRules.skill = SM_NOTHINGS; + if(gameRules.skill > NUM_SKILL_MODES - 1) + gameRules.skill = NUM_SKILL_MODES - 1; #if __JDOOM__ || __JHERETIC__ || __JDOOM64__ if(!IS_NETGAME) @@ -2625,10 +2628,6 @@ void G_DoLeaveMap(void) { SV_ClearSlot(BASE_SLOT); } - - // Re-apply the game rules. - /// @todo Necessary? - G_ApplyGameRules(gameRules.skill); } Uri_Delete(nextMapUri); @@ -2746,7 +2745,7 @@ void G_DoRestartMap(void) // Restart the game session entirely. G_InitNewGame(); - G_NewGame(dSkill, dEpisode, dMap, dMapEntrance); + G_NewGame(dEpisode, dMap, dMapEntrance, &dRules); #else loadmap_params_t p; @@ -2957,20 +2956,24 @@ void G_DoSaveGame(void) G_SetGameAction(GA_NONE); } -void G_DeferredNewGame(skillmode_t skill, uint episode, uint map, uint mapEntrance) +void G_DeferredNewGame(uint episode, uint map, uint mapEntrance, GameRuleset const *rules) { - dSkill = skill; + DENG_ASSERT(rules != 0); + dEpisode = episode; dMap = map; dMapEntrance = mapEntrance; + dRules = *rules; // make a copy. G_SetGameAction(GA_NEWGAME); } -void G_NewGame(skillmode_t skill, uint episode, uint map, uint mapEntrance) +void G_NewGame(uint episode, uint map, uint mapEntrance, GameRuleset const *rules) { uint i; + DENG_ASSERT(rules != 0); + G_StopDemo(); // Clear the menu if open. @@ -3017,8 +3020,10 @@ void G_NewGame(skillmode_t skill, uint episode, uint map, uint mapEntrance) gameEpisode = episode; gameMap = map; gameMapEntrance = mapEntrance; + gameRules = *rules; + + G_ApplyNewGameRules(); - G_ApplyGameRules(skill); M_ResetRandom(); NetSv_UpdateGameConfigDescription(); @@ -4001,12 +4006,12 @@ D_CMD(WarpMap) nextMapEntrance = 0; G_SetGameAction(GA_LEAVEMAP); #else - G_DeferredNewGame(gameRules.skill, epsd, map, 0/*default*/); + G_DeferredNewGame(epsd, map, 0/*default*/, &gameRules); #endif } else { - G_DeferredNewGame(IS_SERVER? cfg.netSkill : gameRules.skill, epsd, map, 0/*default*/); + G_DeferredNewGame(epsd, map, 0/*default*/, &gameRules); } // If the command source was "us" the game library then it was probably in diff --git a/doomsday/plugins/common/src/hu_menu.c b/doomsday/plugins/common/src/hu_menu.c index ce90e861bd..556687a0fe 100644 --- a/doomsday/plugins/common/src/hu_menu.c +++ b/doomsday/plugins/common/src/hu_menu.c @@ -6441,6 +6441,8 @@ int Hu_MenuConfirmInitNewGame(msgresponse_t response, int userValue, void* userP void Hu_MenuInitNewGame(dd_bool confirmed) { + GameRuleset newRules = gameRules; + #if __JDOOM__ if(!confirmed && SM_NIGHTMARE == mnSkillmode) { @@ -6455,10 +6457,11 @@ void Hu_MenuInitNewGame(dd_bool confirmed) cfg.playerClass[CONSOLEPLAYER] = mnPlrClass; #endif + newRules.skill = mnSkillmode; #if __JHEXEN__ - G_DeferredNewGame(mnSkillmode, mnEpisode, P_TranslateMap(0), 0/*default*/); + G_DeferredNewGame(mnEpisode, P_TranslateMap(0), 0/*default*/, &newRules); #else - G_DeferredNewGame(mnSkillmode, mnEpisode, 0, 0/*default*/); + G_DeferredNewGame(mnEpisode, 0, 0/*default*/, &newRules); #endif } diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index bfa885ef74..32b6500ce1 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -3646,9 +3646,9 @@ static bool openGameSaveFile(Str const *fileName, bool write) return SV_File() != 0; } -static int SV_LoadState(Str const *path, SaveInfo *saveInfo) +static int SV_LoadState(Str const *path, SaveInfo *info) { - DENG_ASSERT(path != 0 && saveInfo != 0); + DENG_ASSERT(path != 0 && info != 0); playerHeaderOK = false; // Uninitialized. @@ -3665,35 +3665,26 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) delete tmp; } - /* - * Configure global game state: - */ - curInfo = saveInfo; - - gameEpisode = saveInfo->episode(); - gameMap = saveInfo->map(); - gameMapEntrance = 0; /// @todo Not saved?? - gameRules = saveInfo->gameRules(); + curInfo = info; #if __JHEXEN__ - Game_ACScriptInterpreter().readWorldScriptData(reader, saveInfo->version()); + Game_ACScriptInterpreter().readWorldScriptData(reader, info->version()); #endif /* * Load the map and configure some game settings. */ briefDisabled = true; - G_NewGame(gameRules.skill, gameEpisode, gameMap, gameMapEntrance); - - G_SetGameAction(GA_NONE); /// @todo Necessary? + G_NewGame(info->episode(), info->map(), 0/*not saved??*/, &info->gameRules()); #if !__JHEXEN__ - // Set the time. - mapTime = saveInfo->mapTime(); + mapTime = info->mapTime(); #endif + G_SetGameAction(GA_NONE); /// @todo Necessary? + #if !__JHEXEN__ - initThingArchiveForLoad(saveInfo->version() >= 5? Reader_ReadInt32(reader) : 1024 /* num elements */); + initThingArchiveForLoad(info->version() >= 5? Reader_ReadInt32(reader) : 1024 /* num elements */); #endif readPlayerHeader(reader); @@ -3797,7 +3788,7 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo) #if !__JHEXEN__ // In netgames, the server tells the clients about this. - NetSv_LoadGame(saveInfo->gameId()); + NetSv_LoadGame(info->gameId()); #endif Reader_Delete(reader); @@ -3996,18 +3987,18 @@ void SV_LoadGameClient(uint gameId) return; } - gameRules = saveInfo->gameRules(); - // Do we need to change the map? if(gameMap != saveInfo->map() || gameEpisode != saveInfo->episode()) { - gameEpisode = saveInfo->episode(); - gameMap = saveInfo->map(); - gameMapEntrance = 0; - G_NewGame(gameRules.skill, gameEpisode, gameMap, gameMapEntrance); + G_NewGame(saveInfo->episode(), saveInfo->map(), 0/*default*/, &saveInfo->gameRules()); /// @todo Necessary? G_SetGameAction(GA_NONE); } + else + { + /// @todo Necessary? + gameRules = saveInfo->gameRules(); + } mapTime = saveInfo->mapTime(); P_MobjUnlink(mo); diff --git a/doomsday/plugins/doom/src/d_main.c b/doomsday/plugins/doom/src/d_main.c index 5b5bb22e28..b188659ce7 100644 --- a/doomsday/plugins/doom/src/d_main.c +++ b/doomsday/plugins/doom/src/d_main.c @@ -90,7 +90,7 @@ char* borderGraphics[] = { // PRIVATE DATA DEFINITIONS ------------------------------------------------ -static skillmode_t startSkill; +//static skillmode_t startSkill; static uint startEpisode; static uint startMap; static dd_bool autoStart; @@ -462,7 +462,7 @@ void D_PostInit(void) monsterInfight = GetDefInt("AI|Infight", 0); // Get skill / episode / map from parms. - gameRules.skill = startSkill = SM_MEDIUM; + gameRules.skill = /*startSkill =*/ SM_MEDIUM; startEpisode = 0; startMap = 0; autoStart = false; @@ -513,7 +513,7 @@ void D_PostInit(void) p = CommandLine_Check("-loadgame"); if(p && p < myargc - 1) { - const int saveSlot = SV_ParseSlotIdentifier(CommandLine_At(p + 1)); + int const saveSlot = SV_ParseSlotIdentifier(CommandLine_At(p + 1)); if(SV_IsUserWritableSlot(saveSlot) && G_LoadGame(saveSlot)) { // No further initialization is to be done. @@ -524,7 +524,7 @@ void D_PostInit(void) p = CommandLine_Check("-skill"); if(p && p < myargc - 1) { - startSkill = CommandLine_At(p + 1)[0] - '1'; + gameRules.skill = CommandLine_At(p + 1)[0] - '1'; autoStart = true; } @@ -556,9 +556,9 @@ void D_PostInit(void) if(autoStart) { if(gameModeBits & (GM_ANY_DOOM2|GM_DOOM_CHEX)) - App_Log(DE2_LOG_NOTE, "Autostart in Map %d, Skill %d", startMap+1, startSkill); + App_Log(DE2_LOG_NOTE, "Autostart in Map %d, Skill %d", startMap+1, gameRules.skill); else - App_Log(DE2_LOG_NOTE, "Autostart in Episode %d, Map %d, Skill %d", startEpisode+1, startMap+1, startSkill); + App_Log(DE2_LOG_NOTE, "Autostart in Episode %d, Map %d, Skill %d", startEpisode+1, startMap+1, gameRules.skill); } // Validate episode and map. @@ -573,7 +573,7 @@ void D_PostInit(void) if(autoStart || IS_NETGAME) { - G_DeferredNewGame(startSkill, startEpisode, startMap, 0/*default*/); + G_DeferredNewGame(startEpisode, startMap, 0/*default*/, &gameRules); } else { diff --git a/doomsday/plugins/doom/src/p_oldsvg.cpp b/doomsday/plugins/doom/src/p_oldsvg.cpp index d51622c872..a5f9fe93fb 100644 --- a/doomsday/plugins/doom/src/p_oldsvg.cpp +++ b/doomsday/plugins/doom/src/p_oldsvg.cpp @@ -842,21 +842,17 @@ int SV_LoadState_Dm_v19(Str const *path, SaveInfo *info) delete tmp; } - gameEpisode = info->episode(); - gameMap = info->map(); - gameMapEntrance = 0; /// @todo Not saved?? - gameRules = info->gameRules(); - // We don't want to see a briefing if we're loading a save game. - briefDisabled = true; + briefDisabled = true; // Load a base map. - G_NewGame(gameRules.skill, gameEpisode, gameMap, gameMapEntrance); - /// @todo Necessary? - G_SetGameAction(GA_NONE); + G_NewGame(info->episode(), info->map(), 0/*not saved??*/, &info->gameRules()); // Recreate map state. - mapTime = info->mapTime(); + mapTime = info->mapTime(); + + /// @todo Necessary? + G_SetGameAction(GA_NONE); P_v19_UnArchivePlayers(); P_v19_UnArchiveWorld(); diff --git a/doomsday/plugins/doom64/src/d_main.c b/doomsday/plugins/doom64/src/d_main.c index 9fd1590350..dc099b81ce 100644 --- a/doomsday/plugins/doom64/src/d_main.c +++ b/doomsday/plugins/doom64/src/d_main.c @@ -92,7 +92,7 @@ char* borderGraphics[] = { // PRIVATE DATA DEFINITIONS ------------------------------------------------ -static skillmode_t startSkill; +//static skillmode_t startSkill; static uint startEpisode; static uint startMap; static dd_bool autoStart; @@ -354,8 +354,8 @@ void D_PreInit(void) */ void D_PostInit(void) { - AutoStr* path; - Uri* uri; + AutoStr *path; + Uri *uri; int p; // Common post init routine. @@ -371,7 +371,7 @@ void D_PostInit(void) monsterInfight = GetDefInt("AI|Infight", 0); // Get skill / episode / map from parms. - gameRules.skill = startSkill = SM_MEDIUM; + gameRules.skill = /*startSkill =*/ SM_MEDIUM; startEpisode = 0; startMap = 0; autoStart = false; @@ -436,7 +436,7 @@ void D_PostInit(void) p = CommandLine_Check("-skill"); if(p && p < myargc - 1) { - startSkill = CommandLine_At(p + 1)[0] - '1'; + gameRules.skill = CommandLine_At(p + 1)[0] - '1'; autoStart = true; } @@ -451,7 +451,7 @@ void D_PostInit(void) if(autoStart) { App_Log(DE2_LOG_NOTE, "Warp to Episode %d, Map %d, Skill %d", startEpisode+1, - startMap+1, startSkill); + startMap+1, gameRules.skill); } // Validate episode and map. @@ -466,7 +466,7 @@ void D_PostInit(void) if(autoStart || IS_NETGAME) { - G_DeferredNewGame(startSkill, startEpisode, startMap, 0/*default*/); + G_DeferredNewGame(startEpisode, startMap, 0/*default*/, &gameRules); } else { diff --git a/doomsday/plugins/heretic/src/p_oldsvg.cpp b/doomsday/plugins/heretic/src/p_oldsvg.cpp index b056641c25..3101de5f5a 100644 --- a/doomsday/plugins/heretic/src/p_oldsvg.cpp +++ b/doomsday/plugins/heretic/src/p_oldsvg.cpp @@ -851,21 +851,17 @@ int SV_LoadState_Hr_v13(Str const *path, SaveInfo *info) delete tmp; } - gameEpisode = info->episode(); - gameMap = info->map(); - gameMapEntrance = 0; /// @todo Not saved?? - gameRules = info->gameRules(); - // We don't want to see a briefing if we're loading a save game. - briefDisabled = true; + briefDisabled = true; // Load a base map. - G_NewGame(gameRules.skill, gameEpisode, gameMap, gameMapEntrance); - /// @todo Necessary? - G_SetGameAction(GA_NONE); + G_NewGame(info->episode(), info->map(), 0/*not saved??*/, &info->gameRules()); // Recreate map state. - mapTime = info->mapTime(); + mapTime = info->mapTime(); + + /// @todo Necessary? + G_SetGameAction(GA_NONE); P_v13_UnArchivePlayers(); P_v13_UnArchiveWorld(); diff --git a/doomsday/plugins/hexen/src/h2_main.c b/doomsday/plugins/hexen/src/h2_main.c index c72a848d76..4302a37abe 100644 --- a/doomsday/plugins/hexen/src/h2_main.c +++ b/doomsday/plugins/hexen/src/h2_main.c @@ -459,7 +459,7 @@ void X_PostInit(void) if(autoStart || IS_NETGAME) { - G_DeferredNewGame(startSkill, startEpisode, startMap, 0/* default */); + G_DeferredNewGame(startEpisode, startMap, 0/*default*/, &gameRules); } else { From 0807ce1b82bfe62874f923116f70c049132055d8 Mon Sep 17 00:00:00 2001 From: danij Date: Tue, 4 Feb 2014 05:35:33 +0000 Subject: [PATCH 085/106] libcommon: Cleanup --- doomsday/plugins/doom/src/d_main.c | 66 ++++++---------------- doomsday/plugins/doom64/src/d_main.c | 71 +++++++---------------- doomsday/plugins/heretic/src/h_main.c | 81 +++++++++------------------ doomsday/plugins/hexen/src/h2_main.c | 30 +++++----- 4 files changed, 81 insertions(+), 167 deletions(-) diff --git a/doomsday/plugins/doom/src/d_main.c b/doomsday/plugins/doom/src/d_main.c index b188659ce7..e71f0d1b39 100644 --- a/doomsday/plugins/doom/src/d_main.c +++ b/doomsday/plugins/doom/src/d_main.c @@ -1,37 +1,25 @@ -/**\file d_main.c - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file d_main.c Doom-specific game initialization. * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2005-2013 Daniel Swanson - *\author Copyright © 2006 Jamie Jones - *\author Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 2006 Jamie Jones + * @authors Copyright © 1993-1996 id Software, Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -/** - * Game initialization (jDoom-specific). - */ - -// HEADER FILES ------------------------------------------------------------ - -#include - #include "jdoom.h" #include "d_netsv.h" @@ -40,20 +28,7 @@ #include "p_saveg.h" #include "am_map.h" #include "g_defs.h" - -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- +#include int verbose; @@ -88,15 +63,10 @@ char* borderGraphics[] = { "BRDR_BL" // Bottom left. }; -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -//static skillmode_t startSkill; static uint startEpisode; static uint startMap; static dd_bool autoStart; -// CODE -------------------------------------------------------------------- - /** * Get a 32-bit integer value. */ diff --git a/doomsday/plugins/doom64/src/d_main.c b/doomsday/plugins/doom64/src/d_main.c index dc099b81ce..3b59a7226f 100644 --- a/doomsday/plugins/doom64/src/d_main.c +++ b/doomsday/plugins/doom64/src/d_main.c @@ -1,36 +1,26 @@ -/**\file d_main.c - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file d_main.c Doom64-specific game initialization. * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2005-2013 Daniel Swanson - *\author Copyright © 2006 Jamie Jones - *\author Copyright © 2003-2005 Samuel Villarreal - *\author Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2006-2013 Daniel Swanson + * @authors Copyright © 2006 Jamie Jones + * @authors Copyright © 2003-2005 Samuel Villarreal + * @authors Copyright © 1993-1996 id Software, Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * Initialization - Doom64 specifc. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -// HEADER FILES ------------------------------------------------------------ - #include #include @@ -44,20 +34,6 @@ #include "p_saveg.h" #include "p_map.h" -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - int verbose; dd_bool devParm; // checkparm of -devparm @@ -73,8 +49,8 @@ gamemode_t gameMode; int gameModeBits; // Default font colors. -const float defFontRGB[] = { 1, 1, 1 }; -const float defFontRGB2[] = { .85f, 0, 0 }; +float const defFontRGB[] = { 1, 1, 1 }; +float const defFontRGB2[] = { .85f, 0, 0 }; // The patches used in drawing the view border. // Percent-encoded. @@ -90,15 +66,10 @@ char* borderGraphics[] = { "BRDR_BL" // Bottom left. }; -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -//static skillmode_t startSkill; static uint startEpisode; static uint startMap; static dd_bool autoStart; -// CODE -------------------------------------------------------------------- - /** * Get a 32-bit integer value. */ @@ -425,7 +396,7 @@ void D_PostInit(void) p = CommandLine_Check("-loadgame"); if(p && p < myargc - 1) { - const int saveSlot = SV_ParseSlotIdentifier(CommandLine_At(p + 1)); + int const saveSlot = SV_ParseSlotIdentifier(CommandLine_At(p + 1)); if(SV_IsUserWritableSlot(saveSlot) && G_LoadGame(saveSlot)) { // No further initialization is to be done. diff --git a/doomsday/plugins/heretic/src/h_main.c b/doomsday/plugins/heretic/src/h_main.c index 372e2e7cd4..d2c4c9a672 100644 --- a/doomsday/plugins/heretic/src/h_main.c +++ b/doomsday/plugins/heretic/src/h_main.c @@ -1,38 +1,25 @@ -/**\file h_main.c - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file h_main.c Heretic-specific game initialization. * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2005-2013 Daniel Swanson - *\author Copyright © 2006 Jamie Jones - *\author Copyright © 1993-1996 by id Software, Inc. + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 2006 Jamie Jones + * @authors Copyright © 1993-1996 id Software, Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -/** - * Game initialization - Heretic specific. - */ - -// HEADER FILES ------------------------------------------------------------ - -#include -#include - #include "jheretic.h" #include "d_netsv.h" @@ -42,20 +29,9 @@ #include "am_map.h" #include "g_defs.h" #include "p_inventory.h" +#include +#include -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- int verbose; @@ -72,9 +48,9 @@ gamemode_t gameMode; int gameModeBits; // Default font colours. -const float defFontRGB[] = { .425f, .986f, .378f }; -const float defFontRGB2[] = { 1, .65f, .275f }; -const float defFontRGB3[] = { 1.0f, 1.0f, 1.0f }; +float const defFontRGB[] = { .425f, .986f, .378f }; +float const defFontRGB2[] = { 1, .65f, .275f }; +float const defFontRGB3[] = { 1.0f, 1.0f, 1.0f }; // The patches used in drawing the view border. // Percent-encoded. @@ -90,15 +66,10 @@ char* borderGraphics[] = { "BORDBL" // Bottom left. }; -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -static skillmode_t startSkill; static uint startEpisode; static uint startMap; static dd_bool autoStart; -// CODE -------------------------------------------------------------------- - /** * Get a 32-bit integer value. */ @@ -395,7 +366,7 @@ void H_PostInit(void) monsterInfight = GetDefInt("AI|Infight", 0); // Defaults for skill, episode and map. - startSkill = SM_MEDIUM; + gameRules.skill = /*startSkill =*/ SM_MEDIUM; startEpisode = 0; startMap = 0; autoStart = false; @@ -451,7 +422,7 @@ void H_PostInit(void) p = CommandLine_Check("-skill"); if(p && p < myargc - 1) { - startSkill = CommandLine_At(p + 1)[0] - '1'; + gameRules.skill = CommandLine_At(p + 1)[0] - '1'; autoStart = true; } @@ -475,7 +446,7 @@ void H_PostInit(void) if(autoStart) { App_Log(DE2_LOG_NOTE, "Autostart in Episode %d, Map %d, Skill %d", - startEpisode + 1, startMap + 1, startSkill + 1); + startEpisode + 1, startMap + 1, gameRules.skill + 1); } // Validate episode and map. @@ -490,7 +461,7 @@ void H_PostInit(void) if(autoStart || IS_NETGAME) { - G_DeferredNewGame(startSkill, startEpisode, startMap, 0/*default*/); + G_DeferredNewGame(startEpisode, startMap, 0/*default*/, &gameRules); } else { diff --git a/doomsday/plugins/hexen/src/h2_main.c b/doomsday/plugins/hexen/src/h2_main.c index 4302a37abe..1c3336380b 100644 --- a/doomsday/plugins/hexen/src/h2_main.c +++ b/doomsday/plugins/hexen/src/h2_main.c @@ -51,9 +51,9 @@ gamemode_t gameMode; int gameModeBits; // Default font colours. -const float defFontRGB[] = { .9f, .0f, .0f }; -const float defFontRGB2[] = { 1.f, .65f, .275f }; -const float defFontRGB3[] = { .9f, .9f, .9f }; +float const defFontRGB[] = { .9f, .0f, .0f }; +float const defFontRGB2[] = { 1.f, .65f, .275f }; +float const defFontRGB3[] = { .9f, .9f, .9f }; // The patches used in drawing the view border. // Percent-encoded. @@ -69,15 +69,10 @@ char* borderGraphics[] = { "BORDBL" // Bottom left. }; -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -static dd_bool autoStart = false; -static uint startEpisode = 0; -static uint startMap = 0; -static playerclass_t startPlayerClass = PCLASS_NONE; -static skillmode_t startSkill = SM_MEDIUM; - -// CODE -------------------------------------------------------------------- +static dd_bool autoStart; +static uint startEpisode; +static uint startMap; +static playerclass_t startPlayerClass; /** * Get a 32-bit integer value. @@ -339,6 +334,13 @@ void X_PostInit(void) // Game parameters. /* None */ + // Defaults for skill, episode and map. + gameRules.skill = /*startSkill =*/ SM_MEDIUM; + startEpisode = 0; + startMap = 0; + startPlayerClass = PCLASS_NONE; + autoStart = false; + // Game mode specific settings. /* None */ @@ -400,7 +402,7 @@ void X_PostInit(void) if((p = CommandLine_CheckWith("-skill", 1)) != 0) { - startSkill = (skillmode_t)(CommandLine_At(p + 1)[0] - '1'); + gameRules.skill = (skillmode_t)(CommandLine_At(p + 1)[0] - '1'); autoStart = true; } @@ -445,7 +447,7 @@ void X_PostInit(void) // Are we autostarting? if(autoStart) { - App_Log(DE2_LOG_NOTE, "Autostart in Map %d (%d), Skill %d", warpMap+1, startMap+1, startSkill + 1); + App_Log(DE2_LOG_NOTE, "Autostart in Map %d (%d), Skill %d", warpMap+1, startMap+1, gameRules.skill + 1); } // Validate episode and map. From b6652fdd1a89ace732b62444488e1b601547148b Mon Sep 17 00:00:00 2001 From: danij Date: Tue, 4 Feb 2014 06:46:02 +0000 Subject: [PATCH 086/106] libcommon: Removed cvar 'game-fastmonsters' Enabling/disabling of fast monsters and/or projectiles must be done via the game rule mechanism. Game rules are applied on server side and communicated to the client when changed. Game rule set management will soon be done through a new UI. As this cvar has never worked correctly, we might as well dump it. --- doomsday/plugins/common/src/g_game.c | 20 ++++++----- doomsday/plugins/common/src/gamerules.c | 5 ++- doomsday/plugins/doom/include/d_config.h | 2 +- doomsday/plugins/doom/include/d_main.h | 10 +++--- doomsday/plugins/doom/src/d_console.c | 2 +- doomsday/plugins/doom/src/d_main.c | 25 +++++-------- doomsday/plugins/doom64/include/d_config.h | 2 +- doomsday/plugins/doom64/include/d_main.h | 10 +++--- doomsday/plugins/doom64/src/d_console.c | 2 +- doomsday/plugins/doom64/src/d_main.c | 25 +++++-------- doomsday/plugins/heretic/include/h_config.h | 2 +- doomsday/plugins/heretic/include/h_main.h | 10 +++--- doomsday/plugins/heretic/src/h_console.c | 2 +- doomsday/plugins/heretic/src/h_main.c | 23 +++++------- doomsday/plugins/heretic/src/p_enemy.c | 2 +- doomsday/plugins/hexen/include/x_config.h | 2 +- doomsday/plugins/hexen/include/x_main.h | 10 +++--- doomsday/plugins/hexen/src/h2_main.c | 23 +++++------- doomsday/plugins/hexen/src/hconsole.c | 2 +- doomsday/plugins/hexen/src/p_enemy.c | 40 +++++++++++---------- 20 files changed, 98 insertions(+), 121 deletions(-) diff --git a/doomsday/plugins/common/src/g_game.c b/doomsday/plugins/common/src/g_game.c index 8832218d1b..4724cbf4ea 100644 --- a/doomsday/plugins/common/src/g_game.c +++ b/doomsday/plugins/common/src/g_game.c @@ -1335,7 +1335,7 @@ int G_Responder(event_t* ev) return Hu_MenuResponder(ev); } -int G_PrivilegedResponder(event_t* ev) +int G_PrivilegedResponder(event_t *ev) { // Ignore all events once shutdown has begun. if(G_QuitInProgress()) return false; @@ -1343,12 +1343,15 @@ int G_PrivilegedResponder(event_t* ev) if(Hu_MenuPrivilegedResponder(ev)) return true; - // Process the screen shot key right away. - if(devParm && ev->type == EV_KEY && ev->data1 == DDKEY_F1) + // Process the screen shot key right away? + if(ev->type == EV_KEY && ev->data1 == DDKEY_F1) { - if(ev->state == EVS_DOWN) - G_ScreenShot(); - return true; // All F1 events are eaten. + if(CommandLine_Check("-devparm")) + { + if(ev->state == EVS_DOWN) + G_ScreenShot(); + return true; // All F1 events are eaten. + } } return false; // Not eaten. @@ -2236,14 +2239,13 @@ static void G_ApplyNewGameRules() { gameRules.deathmatch = false; gameRules.respawnMonsters = false; - noMonstersParm = CommandLine_Exists("-nomonsters")? true : false; - gameRules.noMonsters = noMonstersParm; + gameRules.noMonsters = CommandLine_Exists("-nomonsters")? true : false; } #endif #if __JDOOM__ || __JHERETIC__ || __JDOOM64__ - gameRules.respawnMonsters = respawnParm; + gameRules.respawnMonsters = CommandLine_Check("-respawn")? true : false; #endif #if __JDOOM__ || __JHERETIC__ diff --git a/doomsday/plugins/common/src/gamerules.c b/doomsday/plugins/common/src/gamerules.c index 0e8e39a2fa..d0c00a1068 100644 --- a/doomsday/plugins/common/src/gamerules.c +++ b/doomsday/plugins/common/src/gamerules.c @@ -42,7 +42,7 @@ void GameRuleset_Read(GameRuleset *rules, Reader *reader) DENG_ASSERT(rules != 0 && reader != 0); rules->skill = (skillmode_t) Reader_ReadByte(reader); - // Interpret skill levels outside the normal range as "spawn no things". + // Interpret skill modes outside the normal range as "spawn no things". if(rules->skill < SM_BABY || rules->skill >= NUM_SKILL_MODES) { rules->skill = SM_NOTHINGS; @@ -55,8 +55,7 @@ void GameRuleset_Read(GameRuleset *rules, Reader *reader) rules->noMonsters = Reader_ReadByte(reader); #if __JHEXEN__ rules->randomClasses = Reader_ReadByte(reader); -#endif -#if !__JHEXEN__ +#else rules->respawnMonsters = Reader_ReadByte(reader); #endif } diff --git a/doomsday/plugins/doom/include/d_config.h b/doomsday/plugins/doom/include/d_config.h index 26def8143a..63e67b41dc 100644 --- a/doomsday/plugins/doom/include/d_config.h +++ b/doomsday/plugins/doom/include/d_config.h @@ -93,7 +93,7 @@ typedef struct jdoom_config_s { int screenBlocks; byte deathLookUp; // look up when killed byte slidingCorpses; - byte fastMonsters; + //byte fastMonsters; byte echoMsg; int hudFog; diff --git a/doomsday/plugins/doom/include/d_main.h b/doomsday/plugins/doom/include/d_main.h index 638b86cdbc..5671bbca74 100644 --- a/doomsday/plugins/doom/include/d_main.h +++ b/doomsday/plugins/doom/include/d_main.h @@ -37,12 +37,12 @@ extern "C" { extern int verbose; -extern dd_bool noMonstersParm; // checkparm of -nomonsters -extern dd_bool respawnParm; // checkparm of -respawn -extern dd_bool turboParm; // checkparm of -turbo +//extern dd_bool noMonstersParm; // checkparm of -nomonsters +//extern dd_bool respawnParm; // checkparm of -respawn +//extern dd_bool turboParm; // checkparm of -turbo //extern dd_bool randomClassParm; // checkparm of -randclass -extern dd_bool devParm; // checkparm of -devparm -extern dd_bool fastParm; // checkparm of -fast +//extern dd_bool devParm; // checkparm of -devparm +//extern dd_bool fastParm; // checkparm of -fast extern float turboMul; // Multiplier for turbo. diff --git a/doomsday/plugins/doom/src/d_console.c b/doomsday/plugins/doom/src/d_console.c index b8449927a3..538a56113b 100644 --- a/doomsday/plugins/doom/src/d_console.c +++ b/doomsday/plugins/doom/src/d_console.c @@ -165,7 +165,7 @@ cvartemplate_t gameCVars[] = { {"game-zombiescanexit", 0, CVT_BYTE, &cfg.zombiesCanExit, 0, 1}, // Game state - {"game-fastmonsters", 0, CVT_BYTE, &cfg.fastMonsters, 0, 1}, + //{"game-fastmonsters", 0, CVT_BYTE, &cfg.fastMonsters, 0, 1}, // Gameplay {"game-corpse-time", CVF_NO_MAX, CVT_INT, &cfg.corpseTime, 0, 0}, diff --git a/doomsday/plugins/doom/src/d_main.c b/doomsday/plugins/doom/src/d_main.c index e71f0d1b39..10b3777c48 100644 --- a/doomsday/plugins/doom/src/d_main.c +++ b/doomsday/plugins/doom/src/d_main.c @@ -32,11 +32,11 @@ int verbose; -dd_bool devParm; // checkparm of -devparm -dd_bool noMonstersParm; // checkparm of -nomonsters -dd_bool respawnParm; // checkparm of -respawn -dd_bool fastParm; // checkparm of -fast -dd_bool turboParm; // checkparm of -turbo +//dd_bool devParm; // checkparm of -devparm +//dd_bool noMonstersParm; // checkparm of -nomonsters +//dd_bool respawnParm; // checkparm of -respawn +//dd_bool fastParm; // checkparm of -fast +//dd_bool turboParm; // checkparm of -turbo //dd_bool randomClassParm; // checkparm of -randclass float turboMul; // Multiplier for turbo. @@ -276,7 +276,7 @@ void D_PreInit(void) cfg.ammoAutoSwitch = 0; // never cfg.secretMsg = true; cfg.slidingCorpses = false; - cfg.fastMonsters = false; + //cfg.fastMonsters = false; cfg.netJumping = true; cfg.netEpisode = 0; cfg.netMap = 0; @@ -437,21 +437,15 @@ void D_PostInit(void) startMap = 0; autoStart = false; - // Command line options. - noMonstersParm = CommandLine_Check("-nomonsters")? true : false; - respawnParm = CommandLine_Check("-respawn")? true : false; - fastParm = CommandLine_Check("-fast")? true : false; - devParm = CommandLine_Check("-devparm")? true : false; - if(CommandLine_Check("-altdeath")) cfg.netDeathmatch = 2; else if(CommandLine_Check("-deathmatch")) cfg.netDeathmatch = 1; // Apply these rules. - gameRules.noMonsters = noMonstersParm; - gameRules.respawnMonsters = respawnParm; - gameRules.fast = fastParm; + gameRules.noMonsters = CommandLine_Check("-nomonsters")? true : false; + gameRules.respawnMonsters = CommandLine_Check("-respawn")? true : false; + gameRules.fast = CommandLine_Check("-fast")? true : false; p = CommandLine_Check("-timer"); if(p && p < myargc - 1 && gameRules.deathmatch) @@ -467,7 +461,6 @@ void D_PostInit(void) { int scale = 200; - turboParm = true; if(p < myargc - 1) scale = atoi(CommandLine_At(p + 1)); if(scale < 10) diff --git a/doomsday/plugins/doom64/include/d_config.h b/doomsday/plugins/doom64/include/d_config.h index cd633fd660..0df7303e16 100644 --- a/doomsday/plugins/doom64/include/d_config.h +++ b/doomsday/plugins/doom64/include/d_config.h @@ -95,7 +95,7 @@ typedef struct jdoom64_config_s { int screenBlocks; byte deathLookUp; // Look up when killed. byte slidingCorpses; - byte fastMonsters; + //byte fastMonsters; byte echoMsg; int hudFog; diff --git a/doomsday/plugins/doom64/include/d_main.h b/doomsday/plugins/doom64/include/d_main.h index 45699c3470..f020629d3e 100644 --- a/doomsday/plugins/doom64/include/d_main.h +++ b/doomsday/plugins/doom64/include/d_main.h @@ -37,12 +37,12 @@ extern "C" { extern int verbose; -extern dd_bool noMonstersParm; // checkparm of -nomonsters -extern dd_bool respawnParm; // checkparm of -respawn -extern dd_bool turboParm; // checkparm of -turbo +//extern dd_bool noMonstersParm; // checkparm of -nomonsters +//extern dd_bool respawnParm; // checkparm of -respawn +//extern dd_bool turboParm; // checkparm of -turbo //extern dd_bool randomClassParm; // checkparm of -randclass -extern dd_bool devParm; // checkparm of -devparm -extern dd_bool fastParm; // checkparm of -fast +//extern dd_bool devParm; // checkparm of -devparm +//extern dd_bool fastParm; // checkparm of -fast extern float turboMul; // Multiplier for turbo. diff --git a/doomsday/plugins/doom64/src/d_console.c b/doomsday/plugins/doom64/src/d_console.c index 1f495e5107..d8d2efe633 100644 --- a/doomsday/plugins/doom64/src/d_console.c +++ b/doomsday/plugins/doom64/src/d_console.c @@ -183,7 +183,7 @@ cvartemplate_t gameCVars[] = { {"game-zombiescanexit", 0, CVT_BYTE, &cfg.zombiesCanExit, 0, 1}, // Game state - {"game-fastmonsters", 0, CVT_BYTE, &fastParm, 0, 1}, + //{"game-fastmonsters", 0, CVT_BYTE, &fastParm, 0, 1}, // Gameplay {"game-corpse-time", CVF_NO_MAX, CVT_INT, &cfg.corpseTime, 0, 0}, diff --git a/doomsday/plugins/doom64/src/d_main.c b/doomsday/plugins/doom64/src/d_main.c index 3b59a7226f..4b24c0461b 100644 --- a/doomsday/plugins/doom64/src/d_main.c +++ b/doomsday/plugins/doom64/src/d_main.c @@ -36,11 +36,11 @@ int verbose; -dd_bool devParm; // checkparm of -devparm -dd_bool noMonstersParm; // checkparm of -nomonsters -dd_bool respawnParm; // checkparm of -respawn -dd_bool fastParm; // checkparm of -fast -dd_bool turboParm; // checkparm of -turbo +//dd_bool devParm; // checkparm of -devparm +//dd_bool noMonstersParm; // checkparm of -nomonsters +//dd_bool respawnParm; // checkparm of -respawn +//dd_bool fastParm; // checkparm of -fast +//dd_bool turboParm; // checkparm of -turbo //dd_bool randomClassParm; // checkparm of -randclass float turboMul; // Multiplier for turbo. @@ -197,7 +197,7 @@ void D_PreInit(void) cfg.ammoAutoSwitch = 0; // Never. cfg.secretMsg = true; cfg.slidingCorpses = false; - cfg.fastMonsters = false; + //cfg.fastMonsters = false; cfg.netJumping = true; cfg.netMap = 0; cfg.netSkill = SM_MEDIUM; @@ -350,21 +350,15 @@ void D_PostInit(void) // Game mode specific settings // None. - // Command line options - noMonstersParm = CommandLine_Check("-nomonsters"); - respawnParm = CommandLine_Check("-respawn"); - fastParm = CommandLine_Check("-fast"); - devParm = CommandLine_Check("-devparm"); - if(CommandLine_Check("-altdeath")) cfg.netDeathmatch = 2; else if(CommandLine_Check("-deathmatch")) cfg.netDeathmatch = 1; // Apply these rules. - gameRules.noMonsters = noMonstersParm; - gameRules.respawnMonsters = respawnParm; - gameRules.fast = fastParm; + gameRules.noMonsters = CommandLine_Check("-nomonsters")? true : false; + gameRules.respawnMonsters = CommandLine_Check("-respawn")? true : false; + gameRules.fast = CommandLine_Check("-fast")? true : false; p = CommandLine_Check("-timer"); if(p && p < myargc - 1 && gameRules.deathmatch) @@ -380,7 +374,6 @@ void D_PostInit(void) { int scale = 200; - turboParm = true; if(p < myargc - 1) scale = atoi(CommandLine_At(p + 1)); if(scale < 10) diff --git a/doomsday/plugins/heretic/include/h_config.h b/doomsday/plugins/heretic/include/h_config.h index 514bb64543..d54898ebc0 100644 --- a/doomsday/plugins/heretic/include/h_config.h +++ b/doomsday/plugins/heretic/include/h_config.h @@ -244,7 +244,7 @@ typedef struct jheretic_config_s { byte inventorySlotShowEmpty; byte inventorySelectMode; int tomeCounter, tomeSound; - byte fastMonsters; + //byte fastMonsters; } game_config_t; extern game_config_t cfg; // in g_game.c diff --git a/doomsday/plugins/heretic/include/h_main.h b/doomsday/plugins/heretic/include/h_main.h index 0cd1801e2f..433c4b9958 100644 --- a/doomsday/plugins/heretic/include/h_main.h +++ b/doomsday/plugins/heretic/include/h_main.h @@ -35,12 +35,12 @@ extern "C" { extern int verbose; -extern dd_bool noMonstersParm; // checkparm of -nomonsters -extern dd_bool respawnParm; // checkparm of -respawn -extern dd_bool turboParm; // checkparm of -turbo +//extern dd_bool noMonstersParm; // checkparm of -nomonsters +//extern dd_bool respawnParm; // checkparm of -respawn +//extern dd_bool turboParm; // checkparm of -turbo //extern dd_bool randomClassParm; // checkparm of -randclass -extern dd_bool devParm; // checkparm of -devparm -extern dd_bool fastParm; // checkparm of -fast +//extern dd_bool devParm; // checkparm of -devparm +//extern dd_bool fastParm; // checkparm of -fast extern float turboMul; // Multiplier for turbo. diff --git a/doomsday/plugins/heretic/src/h_console.c b/doomsday/plugins/heretic/src/h_console.c index 4ba25ee59a..38fa7b9d1d 100644 --- a/doomsday/plugins/heretic/src/h_console.c +++ b/doomsday/plugins/heretic/src/h_console.c @@ -149,7 +149,7 @@ cvartemplate_t gameCVars[] = { {"server-game-plane-fixmaterialscroll", 0, CVT_BYTE, &cfg.fixPlaneScrollMaterialsEastOnly, 0, 1}, // Game state - {"game-fastmonsters", 0, CVT_BYTE, &cfg.fastMonsters, 0, 1}, + //{"game-fastmonsters", 0, CVT_BYTE, &cfg.fastMonsters, 0, 1}, // Gameplay {"game-corpse-time", CVF_NO_MAX, CVT_INT, &cfg.corpseTime, 0, 0}, diff --git a/doomsday/plugins/heretic/src/h_main.c b/doomsday/plugins/heretic/src/h_main.c index d2c4c9a672..a26009b98a 100644 --- a/doomsday/plugins/heretic/src/h_main.c +++ b/doomsday/plugins/heretic/src/h_main.c @@ -32,14 +32,13 @@ #include #include - int verbose; -dd_bool devParm; // checkparm of -devparm -dd_bool noMonstersParm; // checkparm of -nomonsters -dd_bool respawnParm; // checkparm of -respawn -dd_bool fastParm; // checkparm of -fast -dd_bool turboParm; // checkparm of -turbo +//dd_bool devParm; // checkparm of -devparm +//dd_bool noMonstersParm; // checkparm of -nomonsters +//dd_bool respawnParm; // checkparm of -respawn +//dd_bool fastParm; // checkparm of -fast +//dd_bool turboParm; // checkparm of -turbo //dd_bool randomClassParm; // checkparm of -randclass float turboMul; // Multiplier for turbo. @@ -199,7 +198,7 @@ void H_PreInit(void) cfg.noWeaponAutoSwitchIfFiring = false; cfg.ammoAutoSwitch = 0; // Never. cfg.slidingCorpses = false; - cfg.fastMonsters = false; + //cfg.fastMonsters = false; cfg.secretMsg = true; cfg.netJumping = true; cfg.netEpisode = 0; @@ -374,19 +373,14 @@ void H_PostInit(void) // Game mode specific settings. /* None */ - // Command line options. - noMonstersParm = CommandLine_Check("-nomonsters"); - respawnParm = CommandLine_Check("-respawn"); - devParm = CommandLine_Check("-devparm"); - if(CommandLine_Check("-deathmatch")) { cfg.netDeathmatch = true; } // Apply these game rules. - gameRules.noMonsters = noMonstersParm; - gameRules.respawnMonsters = respawnParm; + gameRules.noMonsters = CommandLine_Exists("-nomonsters")? true : false; + gameRules.respawnMonsters = CommandLine_Check("-respawn")? true : false; // turbo option. p = CommandLine_Check("-turbo"); @@ -395,7 +389,6 @@ void H_PostInit(void) { int scale = 200; - turboParm = true; if(p < myargc - 1) scale = atoi(CommandLine_At(p + 1)); if(scale < 10) diff --git a/doomsday/plugins/heretic/src/p_enemy.c b/doomsday/plugins/heretic/src/p_enemy.c index 51196608d0..1820c8f9dd 100644 --- a/doomsday/plugins/heretic/src/p_enemy.c +++ b/doomsday/plugins/heretic/src/p_enemy.c @@ -614,7 +614,7 @@ void C_DECL A_Chase(mobj_t *actor) actor->threshold--; } - if(gameRules.skill == SM_NIGHTMARE || cfg.fastMonsters) + if(gameRules.skill == SM_NIGHTMARE || gameRules.fast) { // Monsters move faster in nightmare mode. actor->tics -= actor->tics / 2; diff --git a/doomsday/plugins/hexen/include/x_config.h b/doomsday/plugins/hexen/include/x_config.h index f412c3df69..766ea977bc 100644 --- a/doomsday/plugins/hexen/include/x_config.h +++ b/doomsday/plugins/hexen/include/x_config.h @@ -69,7 +69,7 @@ typedef struct { float lookSpeed; float turnSpeed; int quakeFly; - byte fastMonsters; + //byte fastMonsters; int useJLook; int screenBlocks; int setBlocks; diff --git a/doomsday/plugins/hexen/include/x_main.h b/doomsday/plugins/hexen/include/x_main.h index 174eb9a3ab..82c0c0dcf7 100644 --- a/doomsday/plugins/hexen/include/x_main.h +++ b/doomsday/plugins/hexen/include/x_main.h @@ -35,11 +35,11 @@ extern "C" { extern int verbose; -extern dd_bool noMonstersParm; // checkparm of -nomonsters -extern dd_bool respawnParm; // checkparm of -respawn -extern dd_bool turboParm; // checkparm of -turbo -extern dd_bool randomClassParm; // checkparm of -randclass -extern dd_bool devParm; // checkparm of -devparm +//extern dd_bool noMonstersParm; // checkparm of -nomonsters +//extern dd_bool respawnParm; // checkparm of -respawn +//extern dd_bool turboParm; // checkparm of -turbo +//extern dd_bool randomClassParm; // checkparm of -randclass +//extern dd_bool devParm; // checkparm of -devparm //extern dd_bool fastParm; // checkparm of -fast extern float turboMul; // Multiplier for turbo. diff --git a/doomsday/plugins/hexen/src/h2_main.c b/doomsday/plugins/hexen/src/h2_main.c index 1c3336380b..f7223ff917 100644 --- a/doomsday/plugins/hexen/src/h2_main.c +++ b/doomsday/plugins/hexen/src/h2_main.c @@ -38,12 +38,12 @@ int verbose; -dd_bool devParm; // checkparm of -devparm -dd_bool noMonstersParm; // checkparm of -nomonsters -dd_bool respawnParm; // checkparm of -respawn +//dd_bool devParm; // checkparm of -devparm +//dd_bool noMonstersParm; // checkparm of -nomonsters +//dd_bool respawnParm; // checkparm of -respawn //dd_bool fastParm; // checkparm of -fast -dd_bool turboParm; // checkparm of -turbo -dd_bool randomClassParm; // checkparm of -randclass +//dd_bool turboParm; // checkparm of -turbo +//dd_bool randomClassParm; // checkparm of -randclass float turboMul; // Multiplier for turbo. @@ -178,7 +178,7 @@ void X_PreInit(void) cfg.weaponAutoSwitch = 1; // IF BETTER cfg.noWeaponAutoSwitchIfFiring = false; cfg.ammoAutoSwitch = 0; // never - cfg.fastMonsters = false; + //cfg.fastMonsters = false; cfg.netMap = 0; cfg.netSkill = SM_MEDIUM; cfg.netColor = 8; // Use the default color by default. @@ -344,17 +344,11 @@ void X_PostInit(void) // Game mode specific settings. /* None */ - // Command line options. - noMonstersParm = CommandLine_Exists("-nomonsters"); - //respawnParm = CommandLine_Exists("-respawn"); - randomClassParm = CommandLine_Exists("-randclass"); - devParm = CommandLine_Exists("-devparm"); - cfg.netDeathmatch = CommandLine_Exists("-deathmatch"); // Apply these rules. - gameRules.noMonsters = noMonstersParm; - gameRules.randomClasses = randomClassParm; + gameRules.noMonsters = CommandLine_Check("-nomonsters")? true : false; + gameRules.randomClasses = CommandLine_Exists("-randclass")? true : false; // Turbo movement option. p = CommandLine_Check("-turbo"); @@ -363,7 +357,6 @@ void X_PostInit(void) { int scale = 200; - turboParm = true; if(p < CommandLine_Count() - 1) scale = atoi(CommandLine_At(p + 1)); if(scale < 10) diff --git a/doomsday/plugins/hexen/src/hconsole.c b/doomsday/plugins/hexen/src/hconsole.c index eab601708c..ebdddce8b3 100644 --- a/doomsday/plugins/hexen/src/hconsole.c +++ b/doomsday/plugins/hexen/src/hconsole.c @@ -136,7 +136,7 @@ cvartemplate_t gameCVars[] = { //{"game-monsters-floatoverblocking", 0, CVT_BYTE, &cfg.allowMonsterFloatOverBlocking, 0, 1}, // Game state - {"game-fastmonsters", 0, CVT_BYTE, &cfg.fastMonsters, 0, 1}, + //{"game-fastmonsters", 0, CVT_BYTE, &cfg.fastMonsters, 0, 1}, // Gameplay {"game-maulator-time", CVF_NO_MAX, CVT_INT, &maulatorSeconds, 1, 0}, diff --git a/doomsday/plugins/hexen/src/p_enemy.c b/doomsday/plugins/hexen/src/p_enemy.c index ca02b65173..d0e78bb600 100644 --- a/doomsday/plugins/hexen/src/p_enemy.c +++ b/doomsday/plugins/hexen/src/p_enemy.c @@ -108,7 +108,7 @@ void KSpiritInit(mobj_t *spirit, mobj_t *korax); // PUBLIC DATA DEFINITIONS ------------------------------------------------- int maulatorSeconds = 25; -dd_bool fastMonsters = false; +//dd_bool fastMonsters = false; // Eight directional movement speeds. #define MOVESPEED_DIAGONAL (0.71716309f) @@ -547,10 +547,10 @@ void C_DECL A_Look(mobj_t *actor) /** * Actor has a melee attack, so it tries to close as fast as possible. */ -void C_DECL A_Chase(mobj_t* actor) +void C_DECL A_Chase(mobj_t *actor) { - int delta; - statenum_t state; + int delta; + statenum_t state; if(actor->reactionTime) actor->reactionTime--; @@ -561,8 +561,9 @@ void C_DECL A_Chase(mobj_t* actor) actor->threshold--; } - if(gameRules.skill == SM_NIGHTMARE || (fastMonsters /*&& INCOMPAT_OK */ )) - { // Monsters move faster in nightmare mode + if(gameRules.skill == SM_NIGHTMARE /*|| gameRules.fast*/) + { + // Monsters move faster in nightmare mode actor->tics -= actor->tics / 2; if(actor->tics < 3) { @@ -1691,7 +1692,7 @@ void C_DECL A_SerpentHide(mobj_t* actor) actor->floorClip = 0; } -void C_DECL A_SerpentChase(mobj_t* actor) +void C_DECL A_SerpentChase(mobj_t *actor) { int delta; coord_t oldpos[3]; @@ -1709,8 +1710,9 @@ void C_DECL A_SerpentChase(mobj_t* actor) actor->threshold--; } - if(gameRules.skill == SM_NIGHTMARE || (fastMonsters)) - { // Monsters move faster in nightmare mode. + if(gameRules.skill == SM_NIGHTMARE /*|| gameRules.fast*/) + { + // Monsters move faster in nightmare mode. actor->tics -= actor->tics / 2; if(actor->tics < 3) { @@ -1864,10 +1866,10 @@ void C_DECL A_SerpentDiveSound(mobj_t *actor) /** * Similar to A_Chase, only has a hardcoded entering of meleestate. */ -void C_DECL A_SerpentWalk(mobj_t* actor) +void C_DECL A_SerpentWalk(mobj_t *actor) { - int delta; - statenum_t state; + int delta; + statenum_t state; if(actor->reactionTime) { @@ -1880,8 +1882,9 @@ void C_DECL A_SerpentWalk(mobj_t* actor) actor->threshold--; } - if(gameRules.skill == SM_NIGHTMARE || (fastMonsters)) - { // Monsters move faster in nightmare mode. + if(gameRules.skill == SM_NIGHTMARE /*|| gameRules.fast*/) + { + // Monsters move faster in nightmare mode. actor->tics -= actor->tics / 2; if(actor->tics < 3) { @@ -3884,7 +3887,7 @@ void C_DECL A_BounceCheck(mobj_t* mo) } } -void C_DECL A_FastChase(mobj_t* mo) +void C_DECL A_FastChase(mobj_t *mo) { #define CLASS_BOSS_STRAFE_RANGE (64*10) @@ -3892,7 +3895,7 @@ void C_DECL A_FastChase(mobj_t* mo) coord_t dist; angle_t angle; uint an; - mobj_t* target; + mobj_t *target; statenum_t state; if(mo->reactionTime) @@ -3906,8 +3909,9 @@ void C_DECL A_FastChase(mobj_t* mo) mo->threshold--; } - if(gameRules.skill == SM_NIGHTMARE || (fastMonsters)) - { // Monsters move faster in nightmare mode. + if(gameRules.skill == SM_NIGHTMARE /*|| gameRules.fast*/) + { + // Monsters move faster in nightmare mode. mo->tics -= mo->tics / 2; if(mo->tics < 3) { From ff82f69bc97e59d81bb2887274bf0c28ed901347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Tue, 4 Feb 2014 09:02:56 +0200 Subject: [PATCH 087/106] Fixed|FoldPanelWidget: Title is optional --- doomsday/client/src/ui/dialogs/logsettingsdialog.cpp | 1 - doomsday/libappfw/src/widgets/foldpanelwidget.cpp | 10 ++++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/doomsday/client/src/ui/dialogs/logsettingsdialog.cpp b/doomsday/client/src/ui/dialogs/logsettingsdialog.cpp index 96e0c0ef78..1ff2dbf3d5 100644 --- a/doomsday/client/src/ui/dialogs/logsettingsdialog.cpp +++ b/doomsday/client/src/ui/dialogs/logsettingsdialog.cpp @@ -83,7 +83,6 @@ DENG2_PIMPL(LogSettingsDialog) // Folding panel for the per-domain settings. self.area().add(fold = new FoldPanelWidget); fold->setContent(new GuiWidget); - fold->title().hide(); foldLayout.setLeftTop(fold->content().rule().left(), fold->content().rule().top()); diff --git a/doomsday/libappfw/src/widgets/foldpanelwidget.cpp b/doomsday/libappfw/src/widgets/foldpanelwidget.cpp index e18adb257d..330e38a340 100644 --- a/doomsday/libappfw/src/widgets/foldpanelwidget.cpp +++ b/doomsday/libappfw/src/widgets/foldpanelwidget.cpp @@ -144,7 +144,10 @@ void FoldPanelWidget::preparePanelForOpening() d->container = 0; } - d->title->setOpacity(1); + if(d->title) + { + d->title->setOpacity(1); + } PanelWidget::preparePanelForOpening(); } @@ -153,7 +156,10 @@ void FoldPanelWidget::panelDismissed() { PanelWidget::panelDismissed(); - d->title->setOpacity(.8f, .5f); + if(d->title) + { + d->title->setOpacity(.8f, .5f); + } content().notifySelfAndTree(&Widget::deinitialize); From db6a81814b513bac15f1f0bcf250f8176a06b2d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Tue, 4 Feb 2014 16:34:42 +0200 Subject: [PATCH 088/106] libdeng2|Debug: Monospace log formatting tweak --- doomsday/libdeng2/src/core/monospacelogsinkformatter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doomsday/libdeng2/src/core/monospacelogsinkformatter.cpp b/doomsday/libdeng2/src/core/monospacelogsinkformatter.cpp index 228075f907..45868585b9 100644 --- a/doomsday/libdeng2/src/core/monospacelogsinkformatter.cpp +++ b/doomsday/libdeng2/src/core/monospacelogsinkformatter.cpp @@ -231,7 +231,7 @@ MonospaceLogSinkFormatter::MonospaceLogSinkFormatter() #ifdef DENG2_DEBUG // Debug builds include a timestamp and msg type indicator. _maxLength = 110; - _minimumIndent = 23; + _minimumIndent = 21; #endif } From ed87bf43820b5b27805af65b1527bb2db0f6fdf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Tue, 4 Feb 2014 17:40:16 +0200 Subject: [PATCH 089/106] Fixed|GCC|All Games: Build and link errors Corrected the definitions of various thinkers to be compatible with g++. In short, one cannot define member functions into anonymous typedef'd structs. Also enabled the full C++ libdeng2 API for libheretic due to need for de::function_cast<> in p_oldsvg.cpp. --- doomsday/plugins/common/common.pri | 1 - doomsday/plugins/common/include/common.h | 4 ++++ doomsday/plugins/common/include/p_ceiling.h | 2 +- doomsday/plugins/common/include/p_door.h | 2 +- doomsday/plugins/common/include/p_floor.h | 2 +- doomsday/plugins/common/include/p_scroll.h | 2 +- doomsday/plugins/common/include/p_switch.h | 2 +- doomsday/plugins/common/include/p_xgsec.h | 2 +- doomsday/plugins/common/include/polyobjs.h | 4 ++-- doomsday/plugins/common/src/p_ceiling.cpp | 4 ++-- doomsday/plugins/common/src/p_door.cpp | 4 ++-- doomsday/plugins/common/src/p_floor.cpp | 4 ++-- doomsday/plugins/common/src/p_saveg.cpp | 12 ++++++------ doomsday/plugins/common/src/p_scroll.cpp | 4 ++-- doomsday/plugins/common/src/p_switch.cpp | 4 ++-- doomsday/plugins/common/src/p_xgsave.cpp | 4 ++-- doomsday/plugins/common/src/polyobjs.cpp | 8 ++++---- doomsday/plugins/doom/include/p_lights.h | 8 ++++---- doomsday/plugins/doom/src/p_lights.cpp | 16 ++++++++-------- doomsday/plugins/doom/src/p_oldsvg.cpp | 2 +- doomsday/plugins/doom64/include/p_lights.h | 10 +++++----- doomsday/plugins/doom64/src/p_lights.cpp | 20 ++++++++++---------- doomsday/plugins/heretic/heretic.pro | 2 ++ doomsday/plugins/heretic/include/p_lights.h | 6 +++--- doomsday/plugins/heretic/src/p_lights.cpp | 12 ++++++------ doomsday/plugins/heretic/src/p_oldsvg.cpp | 9 +++++---- doomsday/plugins/hexen/include/p_lights.h | 4 ++-- doomsday/plugins/hexen/include/p_pillar.h | 2 +- doomsday/plugins/hexen/include/p_waggle.h | 2 +- doomsday/plugins/hexen/src/p_lights.cpp | 8 ++++---- doomsday/plugins/hexen/src/p_pillar.cpp | 4 ++-- doomsday/plugins/hexen/src/p_waggle.cpp | 4 ++-- 32 files changed, 90 insertions(+), 84 deletions(-) diff --git a/doomsday/plugins/common/common.pri b/doomsday/plugins/common/common.pri index 8033d3ebf3..0a9741610f 100644 --- a/doomsday/plugins/common/common.pri +++ b/doomsday/plugins/common/common.pri @@ -82,7 +82,6 @@ SOURCES += \ $$common_src/g_eventsequence.cpp \ $$common_src/g_game.c \ $$common_src/g_update.c \ - $$common_src/g_update.c \ $$common_src/gamerules.c \ $$common_src/gl_drawpatch.c \ $$common_src/hexlex.cpp \ diff --git a/doomsday/plugins/common/include/common.h b/doomsday/plugins/common/include/common.h index a468733d6d..5055ca27c2 100644 --- a/doomsday/plugins/common/include/common.h +++ b/doomsday/plugins/common/include/common.h @@ -25,6 +25,10 @@ #include #include +#ifdef UNIX +# include +#endif + #define WEAPONBOTTOM (128) // from p_pspr.c #define IS_NETWORK_SERVER (DD_GetInteger(DD_SERVER) && DD_GetInteger(DD_NETGAME)) diff --git a/doomsday/plugins/common/include/p_ceiling.h b/doomsday/plugins/common/include/p_ceiling.h index a0198013c6..457787ae70 100644 --- a/doomsday/plugins/common/include/p_ceiling.h +++ b/doomsday/plugins/common/include/p_ceiling.h @@ -55,7 +55,7 @@ typedef enum { NUMCEILINGTYPES } ceilingtype_e; -typedef struct { +typedef struct ceiling_s { thinker_t thinker; ceilingtype_e type; Sector* sector; diff --git a/doomsday/plugins/common/include/p_door.h b/doomsday/plugins/common/include/p_door.h index 15d6d1354a..b5323565be 100644 --- a/doomsday/plugins/common/include/p_door.h +++ b/doomsday/plugins/common/include/p_door.h @@ -55,7 +55,7 @@ typedef enum { NUMDOORTYPES } doortype_e; -typedef struct { +typedef struct door_s { thinker_t thinker; doortype_e type; Sector *sector; diff --git a/doomsday/plugins/common/include/p_floor.h b/doomsday/plugins/common/include/p_floor.h index e3172e9e08..1f62d77821 100644 --- a/doomsday/plugins/common/include/p_floor.h +++ b/doomsday/plugins/common/include/p_floor.h @@ -83,7 +83,7 @@ typedef enum { NUMFLOORTYPES } floortype_e; -typedef struct { +typedef struct floor_s { thinker_t thinker; floortype_e type; dd_bool crush; diff --git a/doomsday/plugins/common/include/p_scroll.h b/doomsday/plugins/common/include/p_scroll.h index 0c10a13072..ee42f6b2bd 100644 --- a/doomsday/plugins/common/include/p_scroll.h +++ b/doomsday/plugins/common/include/p_scroll.h @@ -24,7 +24,7 @@ #include "doomsday.h" -typedef struct { +typedef struct scroll_s { thinker_t thinker; void *dmuObject; ///< Affected DMU object (either a sector or a side). int elementBits; ///< Identifies which subelements of the dmuObject are affected. diff --git a/doomsday/plugins/common/include/p_switch.h b/doomsday/plugins/common/include/p_switch.h index 0c03754f29..93324e933e 100644 --- a/doomsday/plugins/common/include/p_switch.h +++ b/doomsday/plugins/common/include/p_switch.h @@ -28,7 +28,7 @@ #define BUTTONTIME (TICSPERSEC) // 1 second, in ticks. -typedef struct { +typedef struct materialchanger_s { thinker_t thinker; int timer; Side *side; diff --git a/doomsday/plugins/common/include/p_xgsec.h b/doomsday/plugins/common/include/p_xgsec.h index 6b8deaa827..c9245a2c05 100644 --- a/doomsday/plugins/common/include/p_xgsec.h +++ b/doomsday/plugins/common/include/p_xgsec.h @@ -118,7 +118,7 @@ typedef struct { int chainTimer[DDLT_MAX_CHAINS]; } xgsector_t; -typedef struct { +typedef struct xgplanemover_s { thinker_t thinker; Sector *sector; diff --git a/doomsday/plugins/common/include/polyobjs.h b/doomsday/plugins/common/include/polyobjs.h index 2f0ab8c240..49004799df 100644 --- a/doomsday/plugins/common/include/polyobjs.h +++ b/doomsday/plugins/common/include/polyobjs.h @@ -30,7 +30,7 @@ typedef enum { PODOOR_SWING } podoortype_t; -typedef struct { +typedef struct polyevent_s { thinker_t thinker; int polyobj; // tag int intSpeed; @@ -44,7 +44,7 @@ typedef struct { #endif } polyevent_t; -typedef struct { +typedef struct polydoor_s { thinker_t thinker; int polyobj; // tag int intSpeed; diff --git a/doomsday/plugins/common/src/p_ceiling.cpp b/doomsday/plugins/common/src/p_ceiling.cpp index 13acc459ba..dd9092c4f7 100644 --- a/doomsday/plugins/common/src/p_ceiling.cpp +++ b/doomsday/plugins/common/src/p_ceiling.cpp @@ -228,7 +228,7 @@ void T_MoveCeiling(void *ceilingThinkerPtr) } } -void ceiling_t::write(Writer *writer) const +void ceiling_s::write(Writer *writer) const { Writer_WriteByte(writer, 2); // Write a version byte. @@ -246,7 +246,7 @@ void ceiling_t::write(Writer *writer) const Writer_WriteByte(writer, (byte) oldState); } -int ceiling_t::read(Reader *reader, int mapVersion) +int ceiling_s::read(Reader *reader, int mapVersion) { #if __JHEXEN__ if(mapVersion >= 4) diff --git a/doomsday/plugins/common/src/p_door.cpp b/doomsday/plugins/common/src/p_door.cpp index be7644e4fd..c212519144 100644 --- a/doomsday/plugins/common/src/p_door.cpp +++ b/doomsday/plugins/common/src/p_door.cpp @@ -285,7 +285,7 @@ void T_Door(void *doorThinkerPtr) } } -void door_t::write(Writer *writer) const +void door_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -304,7 +304,7 @@ void door_t::write(Writer *writer) const Writer_WriteInt32(writer, topCountDown); } -int door_t::read(Reader *reader, int mapVersion) +int door_s::read(Reader *reader, int mapVersion) { #if __JHEXEN__ if(mapVersion >= 4) diff --git a/doomsday/plugins/common/src/p_floor.cpp b/doomsday/plugins/common/src/p_floor.cpp index d1c8dcba55..e84a0ffc33 100644 --- a/doomsday/plugins/common/src/p_floor.cpp +++ b/doomsday/plugins/common/src/p_floor.cpp @@ -395,7 +395,7 @@ void T_MoveFloor(void *floorThinkerPtr) } } -void floor_t::write(Writer *writer) const +void floor_s::write(Writer *writer) const { Writer_WriteByte(writer, 3); // Write a version byte. @@ -427,7 +427,7 @@ void floor_t::write(Writer *writer) const #endif } -int floor_t::read(Reader *reader, int mapVersion) +int floor_s::read(Reader *reader, int mapVersion) { #if __JHEXEN__ if(mapVersion >= 4) diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index 32b6500ce1..9968d7eee3 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -299,9 +299,9 @@ static ThinkerClassInfo thinkerInfo[] = { TC_FLASH, (thinkfunc_t) T_LightFlash, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, - sizeof(lightflash_t) + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, + sizeof(lightflash_s) }, { TC_STROBE, @@ -344,9 +344,9 @@ static ThinkerClassInfo thinkerInfo[] = { TC_MATERIALCHANGER, T_MaterialChanger, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, - sizeof(materialchanger_t) + (WriteThinkerFunc)writeThinkerAs, + (ReadThinkerFunc)readThinkerAs, + sizeof(materialchanger_s) }, { TC_SCROLL, diff --git a/doomsday/plugins/common/src/p_scroll.cpp b/doomsday/plugins/common/src/p_scroll.cpp index 831dce7561..9778b7ee68 100644 --- a/doomsday/plugins/common/src/p_scroll.cpp +++ b/doomsday/plugins/common/src/p_scroll.cpp @@ -64,7 +64,7 @@ void T_Scroll(scroll_t *s) } } -void scroll_t::write(Writer *writer) const +void scroll_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -80,7 +80,7 @@ void scroll_t::write(Writer *writer) const Writer_WriteInt32(writer, FLT2FIX(offset[1])); } -int scroll_t::read(Reader *reader, int mapVersion) +int scroll_s::read(Reader *reader, int mapVersion) { /*int ver =*/ Reader_ReadByte(reader); // version byte. // Note: the thinker class byte has already been read. diff --git a/doomsday/plugins/common/src/p_switch.cpp b/doomsday/plugins/common/src/p_switch.cpp index 97d8a5c03a..c339a6d513 100644 --- a/doomsday/plugins/common/src/p_switch.cpp +++ b/doomsday/plugins/common/src/p_switch.cpp @@ -297,7 +297,7 @@ void T_MaterialChanger(void *materialChangerThinker) } } -void materialchanger_t::write(Writer *writer) const +void materialchanger_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -313,7 +313,7 @@ void materialchanger_t::write(Writer *writer) const Writer_WriteInt16(writer, MaterialArchive_FindUniqueSerialId(SV_MaterialArchive(), material)); } -int materialchanger_t::read(Reader *reader, int mapVersion) +int materialchanger_s::read(Reader *reader, int mapVersion) { /*int ver =*/ Reader_ReadByte(reader); // Note: the thinker class byte has already been read. diff --git a/doomsday/plugins/common/src/p_xgsave.cpp b/doomsday/plugins/common/src/p_xgsave.cpp index f4b67d9f2c..1f386a4814 100644 --- a/doomsday/plugins/common/src/p_xgsave.cpp +++ b/doomsday/plugins/common/src/p_xgsave.cpp @@ -172,7 +172,7 @@ void SV_ReadXGSector(Sector *sec, Reader *reader, int mapVersion) SV_ReadXGFunction(xg, &xg->light, reader, mapVersion); } -void xgplanemover_t::write(Writer *writer) const +void xgplanemover_s::write(Writer *writer) const { Writer_WriteByte(writer, 3); // Version. @@ -201,7 +201,7 @@ void xgplanemover_t::write(Writer *writer) const Writer_WriteInt32(writer, timer); } -int xgplanemover_t::read(Reader *reader, int /*mapVersion*/) +int xgplanemover_s::read(Reader *reader, int /*mapVersion*/) { byte ver = Reader_ReadByte(reader); // Version. diff --git a/doomsday/plugins/common/src/polyobjs.cpp b/doomsday/plugins/common/src/polyobjs.cpp index e0f3e40172..6ad8e29a97 100644 --- a/doomsday/plugins/common/src/polyobjs.cpp +++ b/doomsday/plugins/common/src/polyobjs.cpp @@ -276,7 +276,7 @@ void T_MovePoly(void *polyThinker) } } -void polyevent_t::write(Writer *writer) const +void polyevent_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -291,7 +291,7 @@ void polyevent_t::write(Writer *writer) const Writer_WriteInt32(writer, FLT2FIX(speed[VY])); } -int polyevent_t::read(Reader *reader, int mapVersion) +int polyevent_s::read(Reader *reader, int mapVersion) { if(mapVersion >= 4) { @@ -525,7 +525,7 @@ void T_PolyDoor(void *polyDoorThinker) } } -void polydoor_t::write(Writer *writer) const +void polydoor_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -546,7 +546,7 @@ void polydoor_t::write(Writer *writer) const Writer_WriteByte(writer, close); } -int polydoor_t::read(Reader *reader, int mapVersion) +int polydoor_s::read(Reader *reader, int mapVersion) { if(mapVersion >= 4) { diff --git a/doomsday/plugins/doom/include/p_lights.h b/doomsday/plugins/doom/include/p_lights.h index e360fd6180..f2af8ddf90 100644 --- a/doomsday/plugins/doom/include/p_lights.h +++ b/doomsday/plugins/doom/include/p_lights.h @@ -31,7 +31,7 @@ #define FASTDARK (15) #define SLOWDARK (35) -typedef struct { +typedef struct fireflicker_s { thinker_t thinker; Sector *sector; int count; @@ -44,7 +44,7 @@ typedef struct { #endif } fireflicker_t; -typedef struct { +typedef struct lightflash_s { thinker_t thinker; Sector *sector; int count; @@ -59,7 +59,7 @@ typedef struct { #endif } lightflash_t; -typedef struct { +typedef struct strobe_s { thinker_t thinker; Sector *sector; int count; @@ -74,7 +74,7 @@ typedef struct { #endif } strobe_t; -typedef struct { +typedef struct glow_s { thinker_t thinker; Sector *sector; float minLight; diff --git a/doomsday/plugins/doom/src/p_lights.cpp b/doomsday/plugins/doom/src/p_lights.cpp index f9948f087d..2434ca0101 100644 --- a/doomsday/plugins/doom/src/p_lights.cpp +++ b/doomsday/plugins/doom/src/p_lights.cpp @@ -48,7 +48,7 @@ void T_FireFlicker(void *flickPtr) flick->count = 4; } -void fireflicker_t::write(Writer *writer) const +void fireflicker_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -65,7 +65,7 @@ void fireflicker_t::write(Writer *writer) const * T_FireFlicker was added to save games in ver5, therefore we don't have * an old format to support. */ -int fireflicker_t::read(Reader *reader, int /*mapVersion*/) +int fireflicker_s::read(Reader *reader, int /*mapVersion*/) { /*int ver =*/ Reader_ReadByte(reader); // version byte. @@ -129,7 +129,7 @@ void T_LightFlash(lightflash_t *flash) } } -void lightflash_t::write(Writer *writer) const +void lightflash_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -145,7 +145,7 @@ void lightflash_t::write(Writer *writer) const Writer_WriteInt32(writer, minTime); } -int lightflash_t::read(Reader *reader, int mapVersion) +int lightflash_s::read(Reader *reader, int mapVersion) { if(mapVersion >= 5) { @@ -239,7 +239,7 @@ void T_StrobeFlash(strobe_t *flash) } } -void strobe_t::write(Writer *writer) const +void strobe_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -255,7 +255,7 @@ void strobe_t::write(Writer *writer) const Writer_WriteInt32(writer, brightTime); } -int strobe_t::read(Reader *reader, int mapVersion) +int strobe_s::read(Reader *reader, int mapVersion) { if(mapVersion >= 5) { @@ -440,7 +440,7 @@ void T_Glow(glow_t *g) P_SetFloatp(g->sector, DMU_LIGHT_LEVEL, lightLevel); } -void glow_t::write(Writer *writer) const +void glow_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -454,7 +454,7 @@ void glow_t::write(Writer *writer) const Writer_WriteInt32(writer, direction); } -int glow_t::read(Reader *reader, int mapVersion) +int glow_s::read(Reader *reader, int mapVersion) { if(mapVersion >= 5) { diff --git a/doomsday/plugins/doom/src/p_oldsvg.cpp b/doomsday/plugins/doom/src/p_oldsvg.cpp index a5f9fe93fb..ae51aa0a2e 100644 --- a/doomsday/plugins/doom/src/p_oldsvg.cpp +++ b/doomsday/plugins/doom/src/p_oldsvg.cpp @@ -83,7 +83,7 @@ static void srd(Reader *r, char *data, int len) if(!r) return; if(data) { - std::memcpy(data, savePtr, len); + memcpy(data, savePtr, len); } savePtr += len; } diff --git a/doomsday/plugins/doom64/include/p_lights.h b/doomsday/plugins/doom64/include/p_lights.h index 09598f58bd..dbb53b1096 100644 --- a/doomsday/plugins/doom64/include/p_lights.h +++ b/doomsday/plugins/doom64/include/p_lights.h @@ -34,7 +34,7 @@ #define FASTDARK (15) #define SLOWDARK (35) -typedef struct { +typedef struct fireflicker_s { thinker_t thinker; Sector *sector; int count; @@ -47,7 +47,7 @@ typedef struct { #endif } fireflicker_t; -typedef struct { +typedef struct lightflash_s { thinker_t thinker; Sector *sector; int count; @@ -62,7 +62,7 @@ typedef struct { #endif } lightflash_t; -typedef struct { +typedef struct lightblink_s { thinker_t thinker; Sector *sector; int count; @@ -77,7 +77,7 @@ typedef struct { #endif } lightblink_t; -typedef struct { +typedef struct strobe_s { thinker_t thinker; Sector *sector; int count; @@ -92,7 +92,7 @@ typedef struct { #endif } strobe_t; -typedef struct { +typedef struct glow_s { thinker_t thinker; Sector *sector; float minLight; diff --git a/doomsday/plugins/doom64/src/p_lights.cpp b/doomsday/plugins/doom64/src/p_lights.cpp index 3c30ec4587..ec8717acfd 100644 --- a/doomsday/plugins/doom64/src/p_lights.cpp +++ b/doomsday/plugins/doom64/src/p_lights.cpp @@ -45,7 +45,7 @@ void T_FireFlicker(fireflicker_t *flick) flick->count = 4; } -void fireflicker_t::write(Writer *writer) const +void fireflicker_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -62,7 +62,7 @@ void fireflicker_t::write(Writer *writer) const * T_FireFlicker was added to save games in ver5, therefore we don't have * an old format to support. */ -int fireflicker_t::read(Reader *reader, int /*mapVersion*/) +int fireflicker_s::read(Reader *reader, int /*mapVersion*/) { /*int ver =*/ Reader_ReadByte(reader); // version byte. @@ -126,7 +126,7 @@ void T_LightFlash(lightflash_t *flash) } } -void lightflash_t::write(Writer *writer) const +void lightflash_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -142,7 +142,7 @@ void lightflash_t::write(Writer *writer) const Writer_WriteInt32(writer, minTime); } -int lightflash_t::read(Reader *reader, int mapVersion) +int lightflash_s::read(Reader *reader, int mapVersion) { if(mapVersion >= 5) { @@ -235,7 +235,7 @@ void T_LightBlink(lightblink_t *flash) } } -void lightblink_t::write(Writer *writer) const +void lightblink_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -255,7 +255,7 @@ void lightblink_t::write(Writer *writer) const * T_LightBlink was added to save games in ver5, therefore we don't have an * old format to support */ -int lightblink_t::read(Reader *reader, int /*mapVersion*/) +int lightblink_s::read(Reader *reader, int /*mapVersion*/) { /*int ver =*/ Reader_ReadByte(reader); // version byte. @@ -313,7 +313,7 @@ void T_StrobeFlash(strobe_t *flash) } } -void strobe_t::write(Writer *writer) const +void strobe_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -329,7 +329,7 @@ void strobe_t::write(Writer *writer) const Writer_WriteInt32(writer, brightTime); } -int strobe_t::read(Reader *reader, int mapVersion) +int strobe_s::read(Reader *reader, int mapVersion) { if(mapVersion >= 5) { @@ -505,7 +505,7 @@ void T_Glow(glow_t *g) P_SetFloatp(g->sector, DMU_LIGHT_LEVEL, lightLevel); } -void glow_t::write(Writer *writer) const +void glow_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -519,7 +519,7 @@ void glow_t::write(Writer *writer) const Writer_WriteInt32(writer, direction); } -int glow_t::read(Reader *reader, int mapVersion) +int glow_s::read(Reader *reader, int mapVersion) { if(mapVersion >= 5) { diff --git a/doomsday/plugins/heretic/heretic.pro b/doomsday/plugins/heretic/heretic.pro index 56c6f0265e..c72b887b5e 100644 --- a/doomsday/plugins/heretic/heretic.pro +++ b/doomsday/plugins/heretic/heretic.pro @@ -2,6 +2,8 @@ # Copyright (c) 2011-2013 Jaakko Keränen # Copyright (c) 2011-2013 Daniel Swanson +CONFIG += dengplugin_libdeng2_full + include(../config_plugin.pri) include(../common/common.pri) include(../../dep_lzss.pri) diff --git a/doomsday/plugins/heretic/include/p_lights.h b/doomsday/plugins/heretic/include/p_lights.h index a55e23d921..c7676f0cd9 100644 --- a/doomsday/plugins/heretic/include/p_lights.h +++ b/doomsday/plugins/heretic/include/p_lights.h @@ -31,7 +31,7 @@ #define FASTDARK (15) #define SLOWDARK (35) -typedef struct { +typedef struct lightflash_s { thinker_t thinker; Sector *sector; int count; @@ -46,7 +46,7 @@ typedef struct { #endif } lightflash_t; -typedef struct { +typedef struct strobe_s { thinker_t thinker; Sector *sector; int count; @@ -61,7 +61,7 @@ typedef struct { #endif } strobe_t; -typedef struct { +typedef struct glow_s { thinker_t thinker; Sector *sector; float minLight; diff --git a/doomsday/plugins/heretic/src/p_lights.cpp b/doomsday/plugins/heretic/src/p_lights.cpp index f67dcc1a92..f321f7b5d7 100644 --- a/doomsday/plugins/heretic/src/p_lights.cpp +++ b/doomsday/plugins/heretic/src/p_lights.cpp @@ -49,7 +49,7 @@ void T_LightFlash(lightflash_t *flash) } } -void lightflash_t::write(Writer *writer) const +void lightflash_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -65,7 +65,7 @@ void lightflash_t::write(Writer *writer) const Writer_WriteInt32(writer, minTime); } -int lightflash_t::read(Reader *reader, int mapVersion) +int lightflash_s::read(Reader *reader, int mapVersion) { if(mapVersion >= 5) { @@ -158,7 +158,7 @@ void T_StrobeFlash(strobe_t *flash) } } -void strobe_t::write(Writer *writer) const +void strobe_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -174,7 +174,7 @@ void strobe_t::write(Writer *writer) const Writer_WriteInt32(writer, brightTime); } -int strobe_t::read(Reader *reader, int mapVersion) +int strobe_s::read(Reader *reader, int mapVersion) { if(mapVersion >= 5) { @@ -355,7 +355,7 @@ void T_Glow(glow_t *g) P_SetFloatp(g->sector, DMU_LIGHT_LEVEL, lightlevel); } -void glow_t::write(Writer *writer) const +void glow_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -369,7 +369,7 @@ void glow_t::write(Writer *writer) const Writer_WriteInt32(writer, direction); } -int glow_t::read(Reader *reader, int mapVersion) +int glow_s::read(Reader *reader, int mapVersion) { if(mapVersion >= 5) { diff --git a/doomsday/plugins/heretic/src/p_oldsvg.cpp b/doomsday/plugins/heretic/src/p_oldsvg.cpp index 3101de5f5a..0d817dd241 100644 --- a/doomsday/plugins/heretic/src/p_oldsvg.cpp +++ b/doomsday/plugins/heretic/src/p_oldsvg.cpp @@ -36,6 +36,7 @@ #include "hu_inventory.h" #include #include +#include // Do NOT change this: #define V13_SAVE_VERSION 130 ///< Version number associated with a recognised heretic.exe game save state. @@ -518,7 +519,7 @@ typedef struct { if(!(temp + V13_THINKER_T_FUNC_OFFSET)) Thinker_SetStasis(&ceiling->thinker, true); - P_ToXSector(ceiling->sector)->specialData = T_MoveCeiling; + P_ToXSector(ceiling->sector)->specialData = de::function_cast(T_MoveCeiling); return true; // Add this thinker. } @@ -556,7 +557,7 @@ typedef struct { door->thinker.function = T_Door; - P_ToXSector(door->sector)->specialData = T_Door; + P_ToXSector(door->sector)->specialData = de::function_cast(T_Door); return true; // Add this thinker. } @@ -600,7 +601,7 @@ typedef struct { floor->thinker.function = T_MoveFloor; - P_ToXSector(floor->sector)->specialData = T_MoveFloor; + P_ToXSector(floor->sector)->specialData = de::function_cast(T_MoveFloor); return true; // Add this thinker. } @@ -647,7 +648,7 @@ typedef struct { if(!(temp + V13_THINKER_T_FUNC_OFFSET)) Thinker_SetStasis(&plat->thinker, true); - P_ToXSector(plat->sector)->specialData = T_PlatRaise; + P_ToXSector(plat->sector)->specialData = de::function_cast(T_PlatRaise); return true; // Add this thinker. } diff --git a/doomsday/plugins/hexen/include/p_lights.h b/doomsday/plugins/hexen/include/p_lights.h index 9bc6feede4..387243a5a1 100644 --- a/doomsday/plugins/hexen/include/p_lights.h +++ b/doomsday/plugins/hexen/include/p_lights.h @@ -42,7 +42,7 @@ typedef enum { LITE_STROBE } lighttype_t; -typedef struct { +typedef struct light_s { thinker_t thinker; Sector *sector; lighttype_t type; @@ -58,7 +58,7 @@ typedef struct { #endif } light_t; -typedef struct { +typedef struct phase_s { thinker_t thinker; Sector *sector; int index; diff --git a/doomsday/plugins/hexen/include/p_pillar.h b/doomsday/plugins/hexen/include/p_pillar.h index 3864dc4827..a69f753bd7 100644 --- a/doomsday/plugins/hexen/include/p_pillar.h +++ b/doomsday/plugins/hexen/include/p_pillar.h @@ -28,7 +28,7 @@ # error "Using jHexen headers without __JHEXEN__" #endif -typedef struct { +typedef struct pillar_s { thinker_t thinker; Sector *sector; float ceilingSpeed; diff --git a/doomsday/plugins/hexen/include/p_waggle.h b/doomsday/plugins/hexen/include/p_waggle.h index be41fcfe80..739f28e3e4 100644 --- a/doomsday/plugins/hexen/include/p_waggle.h +++ b/doomsday/plugins/hexen/include/p_waggle.h @@ -34,7 +34,7 @@ typedef enum { WS_REDUCE } wagglestate_e; -typedef struct { +typedef struct waggle_s { thinker_t thinker; Sector *sector; coord_t originalHeight; diff --git a/doomsday/plugins/hexen/src/p_lights.cpp b/doomsday/plugins/hexen/src/p_lights.cpp index dbe011e505..89047cc685 100644 --- a/doomsday/plugins/hexen/src/p_lights.cpp +++ b/doomsday/plugins/hexen/src/p_lights.cpp @@ -114,7 +114,7 @@ void T_Light(light_t *light) } } -void light_t::write(Writer *writer) const +void light_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -132,7 +132,7 @@ void light_t::write(Writer *writer) const Writer_WriteInt32(writer, count); } -int light_t::read(Reader *reader, int mapVersion) +int light_s::read(Reader *reader, int mapVersion) { if(mapVersion >= 4) { @@ -295,7 +295,7 @@ void T_Phase(phase_t *phase) phase->baseValue + phaseTable[phase->index]); } -void phase_t::write(Writer *writer) const +void phase_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -308,7 +308,7 @@ void phase_t::write(Writer *writer) const Writer_WriteInt32(writer, (int) (255.0f * baseValue)); } -int phase_t::read(Reader *reader, int mapVersion) +int phase_s::read(Reader *reader, int mapVersion) { if(mapVersion >= 4) { diff --git a/doomsday/plugins/hexen/src/p_pillar.cpp b/doomsday/plugins/hexen/src/p_pillar.cpp index 36fbf3662c..fe423c7609 100644 --- a/doomsday/plugins/hexen/src/p_pillar.cpp +++ b/doomsday/plugins/hexen/src/p_pillar.cpp @@ -43,7 +43,7 @@ void T_BuildPillar(pillar_t *pillar) } } -void pillar_t::write(Writer *writer) const +void pillar_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -60,7 +60,7 @@ void pillar_t::write(Writer *writer) const Writer_WriteInt32(writer, crush); } -int pillar_t::read(Reader *reader, int mapVersion) +int pillar_s::read(Reader *reader, int mapVersion) { if(mapVersion >= 4) { diff --git a/doomsday/plugins/hexen/src/p_waggle.cpp b/doomsday/plugins/hexen/src/p_waggle.cpp index 77e80234b2..d26009125a 100644 --- a/doomsday/plugins/hexen/src/p_waggle.cpp +++ b/doomsday/plugins/hexen/src/p_waggle.cpp @@ -75,7 +75,7 @@ void T_FloorWaggle(waggle_t *waggle) P_ChangeSector(waggle->sector, 1 /*crush damage*/); } -void waggle_t::write(Writer *writer) const +void waggle_s::write(Writer *writer) const { Writer_WriteByte(writer, 1); // Write a version byte. @@ -94,7 +94,7 @@ void waggle_t::write(Writer *writer) const Writer_WriteInt32(writer, state); } -int waggle_t::read(Reader *reader, int mapVersion) +int waggle_s::read(Reader *reader, int mapVersion) { if(mapVersion >= 4) { From 6553ea8d95bd1873740d39035c6869152a66c9e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Tue, 4 Feb 2014 18:04:53 +0200 Subject: [PATCH 090/106] qmake: Enable libdeng2 C++ API in all plugins --- doomsday/plugins/config_plugin.pri | 3 +++ doomsday/plugins/heretic/heretic.pro | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doomsday/plugins/config_plugin.pri b/doomsday/plugins/config_plugin.pri index 165590c87b..3bab140eec 100644 --- a/doomsday/plugins/config_plugin.pri +++ b/doomsday/plugins/config_plugin.pri @@ -1,5 +1,8 @@ include(../config.pri) + # Use the full API for all plugins. +CONFIG += dengplugin_libdeng2_full + deng_noclient { CONFIG += libgui_headers_only } diff --git a/doomsday/plugins/heretic/heretic.pro b/doomsday/plugins/heretic/heretic.pro index c72b887b5e..56c6f0265e 100644 --- a/doomsday/plugins/heretic/heretic.pro +++ b/doomsday/plugins/heretic/heretic.pro @@ -2,8 +2,6 @@ # Copyright (c) 2011-2013 Jaakko Keränen # Copyright (c) 2011-2013 Daniel Swanson -CONFIG += dengplugin_libdeng2_full - include(../config_plugin.pri) include(../common/common.pri) include(../../dep_lzss.pri) From a50af7d43d6972d5baba71897553167d8b1f6cf6 Mon Sep 17 00:00:00 2001 From: danij Date: Tue, 4 Feb 2014 16:44:26 +0000 Subject: [PATCH 091/106] Fixed|libheretic: Heretic v1.3 saved game thinker translation XSector's specialData should point to the new thinker_t instance. --- doomsday/plugins/heretic/src/p_oldsvg.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/doomsday/plugins/heretic/src/p_oldsvg.cpp b/doomsday/plugins/heretic/src/p_oldsvg.cpp index 0d817dd241..4760dda37a 100644 --- a/doomsday/plugins/heretic/src/p_oldsvg.cpp +++ b/doomsday/plugins/heretic/src/p_oldsvg.cpp @@ -36,7 +36,6 @@ #include "hu_inventory.h" #include #include -#include // Do NOT change this: #define V13_SAVE_VERSION 130 ///< Version number associated with a recognised heretic.exe game save state. @@ -519,7 +518,7 @@ typedef struct { if(!(temp + V13_THINKER_T_FUNC_OFFSET)) Thinker_SetStasis(&ceiling->thinker, true); - P_ToXSector(ceiling->sector)->specialData = de::function_cast(T_MoveCeiling); + P_ToXSector(ceiling->sector)->specialData = ceiling; return true; // Add this thinker. } @@ -557,7 +556,7 @@ typedef struct { door->thinker.function = T_Door; - P_ToXSector(door->sector)->specialData = de::function_cast(T_Door); + P_ToXSector(door->sector)->specialData = door; return true; // Add this thinker. } @@ -601,7 +600,7 @@ typedef struct { floor->thinker.function = T_MoveFloor; - P_ToXSector(floor->sector)->specialData = de::function_cast(T_MoveFloor); + P_ToXSector(floor->sector)->specialData = floor; return true; // Add this thinker. } @@ -648,7 +647,7 @@ typedef struct { if(!(temp + V13_THINKER_T_FUNC_OFFSET)) Thinker_SetStasis(&plat->thinker, true); - P_ToXSector(plat->sector)->specialData = de::function_cast(T_PlatRaise); + P_ToXSector(plat->sector)->specialData = plat; return true; // Add this thinker. } From f053b0dc62ff3c54894c5a2adc084bf70a880dd7 Mon Sep 17 00:00:00 2001 From: danij Date: Wed, 5 Feb 2014 00:59:29 +0000 Subject: [PATCH 092/106] Fixed|libheretic: Heretic v1.3 saved game reader --- doomsday/plugins/heretic/src/p_oldsvg.cpp | 69 +++++++++++++---------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/doomsday/plugins/heretic/src/p_oldsvg.cpp b/doomsday/plugins/heretic/src/p_oldsvg.cpp index 4760dda37a..32f8533ae5 100644 --- a/doomsday/plugins/heretic/src/p_oldsvg.cpp +++ b/doomsday/plugins/heretic/src/p_oldsvg.cpp @@ -97,6 +97,7 @@ static void SV_v13_ReadPlayer(player_t *pl) Reader_ReadInt32(svReader); // mo pl->playerState = playerstate_t(Reader_ReadInt32(svReader)); + DENG_ASSERT(pl->playerState >= PST_LIVE && pl->playerState <= PST_REBORN); byte junk[12]; Reader_Read(svReader, junk, 10); // ticcmd_t @@ -116,6 +117,7 @@ static void SV_v13_ReadPlayer(player_t *pl) for(int i = 0; i < 14; ++i) { inventoryitemtype_t type = inventoryitemtype_t(Reader_ReadInt32(svReader)); + DENG_ASSERT(type >= IIT_NONE && type < NUM_INVENTORYITEM_TYPES); int count = Reader_ReadInt32(svReader); for(int k = 0; k < count; ++k) @@ -126,22 +128,23 @@ static void SV_v13_ReadPlayer(player_t *pl) P_InventorySetReadyItem(plrnum, inventoryitemtype_t(Reader_ReadInt32(svReader))); Hu_InventorySelect(plrnum, P_InventoryReadyItem(plrnum)); - Reader_ReadInt32(svReader); // current inventory item count? + /*pl->artifactCount =*/ Reader_ReadInt32(svReader); /*pl->inventorySlotNum =*/ Reader_ReadInt32(svReader); memset(pl->powers, 0, sizeof(pl->powers)); - pl->powers[PT_INVULNERABILITY] = !!Reader_ReadInt32(svReader); - pl->powers[PT_INVISIBILITY] = !!Reader_ReadInt32(svReader); - pl->powers[PT_ALLMAP] = !!Reader_ReadInt32(svReader); + /*pl->powers[pw_NONE] =*/ Reader_ReadInt32(svReader); + pl->powers[PT_INVULNERABILITY] = Reader_ReadInt32(svReader); + pl->powers[PT_INVISIBILITY] = Reader_ReadInt32(svReader); + pl->powers[PT_ALLMAP] = Reader_ReadInt32(svReader); if(pl->powers[PT_ALLMAP]) { ST_RevealAutomap(pl - players, true); } - pl->powers[PT_INFRARED] = !!Reader_ReadInt32(svReader); - pl->powers[PT_WEAPONLEVEL2] = !!Reader_ReadInt32(svReader); - pl->powers[PT_FLIGHT] = !!Reader_ReadInt32(svReader); - pl->powers[PT_SHIELD] = !!Reader_ReadInt32(svReader); - pl->powers[PT_HEALTH2] = !!Reader_ReadInt32(svReader); + pl->powers[PT_INFRARED] = Reader_ReadInt32(svReader); + pl->powers[PT_WEAPONLEVEL2] = Reader_ReadInt32(svReader); + pl->powers[PT_FLIGHT] = Reader_ReadInt32(svReader); + pl->powers[PT_SHIELD] = Reader_ReadInt32(svReader); + pl->powers[PT_HEALTH2] = Reader_ReadInt32(svReader); memset(pl->keys, 0, sizeof(pl->keys)); pl->keys[KT_YELLOW] = !!Reader_ReadInt32(svReader); @@ -156,8 +159,11 @@ static void SV_v13_ReadPlayer(player_t *pl) pl->frags[2] = Reader_ReadInt32(svReader); pl->frags[3] = Reader_ReadInt32(svReader); - pl->readyWeapon = weapontype_t(Reader_ReadInt32(svReader)); - pl->pendingWeapon = weapontype_t(Reader_ReadInt32(svReader)); + int readyWeapon = Reader_ReadInt32(svReader); + pl->readyWeapon = readyWeapon == 10? WT_NOCHANGE : weapontype_t(readyWeapon); + + int pendingWeapon = Reader_ReadInt32(svReader); + pl->pendingWeapon = pendingWeapon == 10? WT_NOCHANGE : weapontype_t(pendingWeapon); // Owned weapons. memset(pl->weapons, 0, sizeof(pl->weapons)); @@ -169,6 +175,7 @@ static void SV_v13_ReadPlayer(player_t *pl) pl->weapons[WT_SIXTH ].owned = !!Reader_ReadInt32(svReader); pl->weapons[WT_SEVENTH].owned = !!Reader_ReadInt32(svReader); pl->weapons[WT_EIGHTH ].owned = !!Reader_ReadInt32(svReader); + /*pl->weapons[wp_beak ].owned = !!*/ Reader_ReadInt32(svReader); memset(pl->ammo, 0, sizeof(pl->ammo)); pl->ammo[AT_CRYSTAL].owned = Reader_ReadInt32(svReader); @@ -191,13 +198,16 @@ static void SV_v13_ReadPlayer(player_t *pl) pl->killCount = Reader_ReadInt32(svReader); pl->itemCount = Reader_ReadInt32(svReader); pl->secretCount = Reader_ReadInt32(svReader); - Reader_ReadInt32(svReader); // message, char* + /*pl->message =*/ Reader_ReadInt32(svReader); // char* + /*pl->messageTics =*/ Reader_ReadInt32(svReader); // int32 pl->damageCount = Reader_ReadInt32(svReader); pl->bonusCount = Reader_ReadInt32(svReader); pl->flameCount = Reader_ReadInt32(svReader); - Reader_ReadInt32(svReader); // attacker + /*pl->attacker =*/ Reader_ReadInt32(svReader); // mobj_t* + ddpl->extraLight = Reader_ReadInt32(svReader); ddpl->fixedColorMap = Reader_ReadInt32(svReader); + pl->colorMap = Reader_ReadInt32(svReader); for(int i = 0; i < 2; ++i) @@ -205,17 +215,16 @@ static void SV_v13_ReadPlayer(player_t *pl) pspdef_t *psp = &pl->pSprites[i]; psp->state = INT2PTR(state_t, Reader_ReadInt32(svReader)); - psp->pos[VX] = Reader_ReadInt32(svReader); - psp->pos[VY] = Reader_ReadInt32(svReader); psp->tics = Reader_ReadInt32(svReader); + psp->pos[VX] = FIX2FLT(Reader_ReadInt32(svReader)); + psp->pos[VY] = FIX2FLT(Reader_ReadInt32(svReader)); } - pl->didSecret = Reader_ReadInt32(svReader); + pl->didSecret = !!Reader_ReadInt32(svReader); pl->morphTics = Reader_ReadInt32(svReader); pl->chickenPeck = Reader_ReadInt32(svReader); - - Reader_ReadInt32(svReader); // rain1 - Reader_ReadInt32(svReader); // rain2 + /*pl->rain1 =*/ Reader_ReadInt32(svReader); // mobj_t* + /*pl->rain2 =*/ Reader_ReadInt32(svReader); // mobj_t* } static void SV_v13_ReadMobj() @@ -236,6 +245,7 @@ static void SV_v13_ReadMobj() angle_t angle = (angle_t) (ANG45 * (Reader_ReadInt32(svReader) / 45)); spritenum_t sprite = Reader_ReadInt32(svReader); + int frame = Reader_ReadInt32(svReader); frame &= ~FF_FRAMEMASK; // not used anymore. @@ -259,6 +269,7 @@ static void SV_v13_ReadMobj() int valid = Reader_ReadInt32(svReader); int type = Reader_ReadInt32(svReader); + DENG_ASSERT(type >= 0 && type < Get(DD_NUMMOBJTYPES)); mobjinfo_t *info = &MOBJINFO[type]; int ddflags = 0; @@ -322,13 +333,13 @@ static void SV_v13_ReadMobj() mo->player = INT2PTR(player_t, Reader_ReadInt32(svReader)); mo->lastLook = Reader_ReadInt32(svReader); - mo->spawnSpot.origin[VX] = (coord_t) Reader_ReadInt32(svReader); - mo->spawnSpot.origin[VY] = (coord_t) Reader_ReadInt32(svReader); + mo->spawnSpot.origin[VX] = (coord_t) Reader_ReadInt16(svReader); + mo->spawnSpot.origin[VY] = (coord_t) Reader_ReadInt16(svReader); mo->spawnSpot.origin[VZ] = 0; // Initialize with "something". - mo->spawnSpot.angle = (angle_t) (ANG45 * (Reader_ReadInt32(svReader) / 45)); - /*mo->spawnSpot.type = (int)*/ Reader_ReadInt32(svReader); + mo->spawnSpot.angle = (angle_t) (ANG45 * (Reader_ReadInt16(svReader) / 45)); + /*mo->spawnSpot.type = (int)*/ Reader_ReadInt16(svReader); - int spawnFlags = ((int) Reader_ReadInt32(svReader)) & ~MASK_UNKNOWN_MSF_FLAGS; + int spawnFlags = ((int) Reader_ReadInt16(svReader)) & ~MASK_UNKNOWN_MSF_FLAGS; // Spawn on the floor by default unless the mobjtype flags override. spawnFlags |= MSF_Z_FLOOR; mo->spawnSpot.flags = spawnFlags; @@ -489,13 +500,13 @@ typedef struct { fixed_t speed; dd_bool crush; int direction; /// 1= up, 0= waiting, -1= down - int tag' + int tag; int olddirection; } v13_ceiling_t; */ - byte temp[SIZEOF_V13_THINKER_T]; // Padding at the start (an old thinker_t struct) + byte temp[SIZEOF_V13_THINKER_T]; Reader_Read(svReader, &temp, SIZEOF_V13_THINKER_T); // Start of used data members. @@ -504,7 +515,7 @@ typedef struct { // A 32bit pointer to sector, serialized. ceiling->sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); if(!ceiling->sector) - Con_Error("tc_ceiling: bad sector number\n"); + Con_Error("tc_ceiling: bad sector number"); ceiling->bottomHeight = FIX2FLT(Reader_ReadInt32(svReader)); ceiling->topHeight = FIX2FLT(Reader_ReadInt32(svReader)); @@ -546,7 +557,7 @@ typedef struct { // A 32bit pointer to sector, serialized. door->sector = (Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader)); if(!door->sector) - Con_Error("tc_door: bad sector number\n"); + Con_Error("tc_door: bad sector number"); door->topHeight = FIX2FLT(Reader_ReadInt32(svReader)); door->speed = FIX2FLT(Reader_ReadInt32(svReader)); @@ -830,7 +841,7 @@ static void P_v13_UnArchiveSpecials() break; } default: - Con_Error("P_UnarchiveSpecials:Unknown tclass %i " "in savegame", tclass); + Con_Error("P_UnarchiveSpecials: Unknown tclass %i in savegame", tclass); } } } From e28539e90a9f46888d4ff10e2ec1ca6b229883a4 Mon Sep 17 00:00:00 2001 From: danij Date: Wed, 5 Feb 2014 01:00:55 +0000 Subject: [PATCH 093/106] Fixed|libdoom: DOOM v1.9 saved game interpretation --- doomsday/plugins/doom/src/p_oldsvg.cpp | 48 +++++++++++++------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/doomsday/plugins/doom/src/p_oldsvg.cpp b/doomsday/plugins/doom/src/p_oldsvg.cpp index ae51aa0a2e..efaad72869 100644 --- a/doomsday/plugins/doom/src/p_oldsvg.cpp +++ b/doomsday/plugins/doom/src/p_oldsvg.cpp @@ -106,22 +106,22 @@ static void SV_v19_ReadPlayer(player_t *pl) pl->armorType = Reader_ReadInt32(svReader); memset(pl->powers, 0, sizeof(pl->powers)); - pl->powers[PT_INVULNERABILITY] = (Reader_ReadInt32(svReader)? true : false); - pl->powers[PT_STRENGTH] = (Reader_ReadInt32(svReader)? true : false); - pl->powers[PT_INVISIBILITY] = (Reader_ReadInt32(svReader)? true : false); - pl->powers[PT_IRONFEET] = (Reader_ReadInt32(svReader)? true : false); - pl->powers[PT_ALLMAP] = (Reader_ReadInt32(svReader)? true : false); + pl->powers[PT_INVULNERABILITY] = Reader_ReadInt32(svReader); + pl->powers[PT_STRENGTH] = Reader_ReadInt32(svReader); + pl->powers[PT_INVISIBILITY] = Reader_ReadInt32(svReader); + pl->powers[PT_IRONFEET] = Reader_ReadInt32(svReader); + pl->powers[PT_ALLMAP] = Reader_ReadInt32(svReader); if(pl->powers[PT_ALLMAP]) ST_RevealAutomap(pl - players, true); - pl->powers[PT_INFRARED] = (Reader_ReadInt32(svReader)? true : false); + pl->powers[PT_INFRARED] = Reader_ReadInt32(svReader); memset(pl->keys, 0, sizeof(pl->keys)); - pl->keys[KT_BLUECARD] = (Reader_ReadInt32(svReader)? true : false); - pl->keys[KT_YELLOWCARD] = (Reader_ReadInt32(svReader)? true : false); - pl->keys[KT_REDCARD] = (Reader_ReadInt32(svReader)? true : false); - pl->keys[KT_BLUESKULL] = (Reader_ReadInt32(svReader)? true : false); - pl->keys[KT_YELLOWSKULL] = (Reader_ReadInt32(svReader)? true : false); - pl->keys[KT_REDSKULL] = (Reader_ReadInt32(svReader)? true : false); + pl->keys[KT_BLUECARD] = !!Reader_ReadInt32(svReader); + pl->keys[KT_YELLOWCARD] = !!Reader_ReadInt32(svReader); + pl->keys[KT_REDCARD] = !!Reader_ReadInt32(svReader); + pl->keys[KT_BLUESKULL] = !!Reader_ReadInt32(svReader); + pl->keys[KT_YELLOWSKULL] = !!Reader_ReadInt32(svReader); + pl->keys[KT_REDSKULL] = !!Reader_ReadInt32(svReader); pl->backpack = Reader_ReadInt32(svReader); @@ -135,15 +135,15 @@ static void SV_v19_ReadPlayer(player_t *pl) pl->pendingWeapon = weapontype_t(Reader_ReadInt32(svReader)); memset(pl->weapons, 0, sizeof(pl->weapons)); - pl->weapons[WT_FIRST].owned = (Reader_ReadInt32(svReader)? true : false); - pl->weapons[WT_SECOND].owned = (Reader_ReadInt32(svReader)? true : false); - pl->weapons[WT_THIRD].owned = (Reader_ReadInt32(svReader)? true : false); - pl->weapons[WT_FOURTH].owned = (Reader_ReadInt32(svReader)? true : false); - pl->weapons[WT_FIFTH].owned = (Reader_ReadInt32(svReader)? true : false); - pl->weapons[WT_SIXTH].owned = (Reader_ReadInt32(svReader)? true : false); - pl->weapons[WT_SEVENTH].owned = (Reader_ReadInt32(svReader)? true : false); - pl->weapons[WT_EIGHTH].owned = (Reader_ReadInt32(svReader)? true : false); - pl->weapons[WT_NINETH].owned = (Reader_ReadInt32(svReader)? true : false); + pl->weapons[WT_FIRST].owned = !!Reader_ReadInt32(svReader); + pl->weapons[WT_SECOND].owned = !!Reader_ReadInt32(svReader); + pl->weapons[WT_THIRD].owned = !!Reader_ReadInt32(svReader); + pl->weapons[WT_FOURTH].owned = !!Reader_ReadInt32(svReader); + pl->weapons[WT_FIFTH].owned = !!Reader_ReadInt32(svReader); + pl->weapons[WT_SIXTH].owned = !!Reader_ReadInt32(svReader); + pl->weapons[WT_SEVENTH].owned = !!Reader_ReadInt32(svReader); + pl->weapons[WT_EIGHTH].owned = !!Reader_ReadInt32(svReader); + pl->weapons[WT_NINETH].owned = !!Reader_ReadInt32(svReader); memset(pl->ammo, 0, sizeof(pl->ammo)); pl->ammo[AT_CLIP].owned = Reader_ReadInt32(svReader); @@ -183,12 +183,12 @@ static void SV_v19_ReadPlayer(player_t *pl) pspdef_t *psp = &pl->pSprites[i]; psp->state = INT2PTR(state_t, Reader_ReadInt32(svReader)); - psp->pos[VX] = Reader_ReadInt32(svReader); - psp->pos[VY] = Reader_ReadInt32(svReader); psp->tics = Reader_ReadInt32(svReader); + psp->pos[VX] = FIX2FLT(Reader_ReadInt32(svReader)); + psp->pos[VY] = FIX2FLT(Reader_ReadInt32(svReader)); } - pl->didSecret = Reader_ReadInt32(svReader); + pl->didSecret = !!Reader_ReadInt32(svReader); } static void SV_v19_ReadMobj() From 0451b69ad5fcdab9793d4612b74a8ed8442555a4 Mon Sep 17 00:00:00 2001 From: danij Date: Wed, 5 Feb 2014 01:28:23 +0000 Subject: [PATCH 094/106] libcommon: Continued remodeling savegame writing/reading All high level map state write/read logic is performed by the new MapStateWriter/MapStateReader classes. --- doomsday/plugins/common/src/p_saveg.cpp | 1154 ++++++++++++----------- doomsday/plugins/doom/include/p_enemy.h | 52 +- doomsday/plugins/doom/src/p_enemy.c | 59 ++ 3 files changed, 667 insertions(+), 598 deletions(-) diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index 9968d7eee3..1f2918a8db 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -124,9 +124,9 @@ static int SV_ReadMovePoly(polyevent_t *movepoly, Reader *reader, int mapVersion #endif #if __JHEXEN__ -static void readMapState(Reader *reader, Str const *path); +static void readMapState(Reader *reader, int saveVersion, Str const *path); #else -static void readMapState(Reader *reader); +static void readMapState(Reader *reader, int saveVersion); #endif static bool inited = false; @@ -141,15 +141,13 @@ static SaveInfo *baseSaveInfo; #endif static SaveInfo *nullSaveInfo; -#if __JHEXEN__ -static int mapVersion; -#endif static SaveInfo const *curInfo; static playerheader_t playerHeader; static dd_bool playerHeaderOK; static mobj_t **thingArchive; +static int thingArchiveVersion; static uint thingArchiveSize; static bool thingArchiveExcludePlayers; @@ -362,16 +360,16 @@ static ThinkerClassInfo thinkerInfo[] = { void SV_Register() { #if !__JHEXEN__ - C_VAR_BYTE("game-save-auto-loadonreborn", &cfg.loadAutoSaveOnReborn, 0, 0, 1); + C_VAR_BYTE("game-save-auto-loadonreborn", &cfg.loadAutoSaveOnReborn, 0, 0, 1); #endif - C_VAR_BYTE("game-save-confirm", &cfg.confirmQuickGameSave, 0, 0, 1); - C_VAR_BYTE("game-save-confirm-loadonreborn",&cfg.confirmRebornLoad, 0, 0, 1); - C_VAR_BYTE("game-save-last-loadonreborn", &cfg.loadLastSaveOnReborn, 0, 0, 1); - C_VAR_INT ("game-save-last-slot", &cvarLastSlot, CVF_NO_MIN|CVF_NO_MAX|CVF_NO_ARCHIVE|CVF_READ_ONLY, 0, 0); - C_VAR_INT ("game-save-quick-slot", &cvarQuickSlot, CVF_NO_MAX|CVF_NO_ARCHIVE, -1, 0); + C_VAR_BYTE("game-save-confirm", &cfg.confirmQuickGameSave, 0, 0, 1); + C_VAR_BYTE("game-save-confirm-loadonreborn", &cfg.confirmRebornLoad, 0, 0, 1); + C_VAR_BYTE("game-save-last-loadonreborn", &cfg.loadLastSaveOnReborn, 0, 0, 1); + C_VAR_INT ("game-save-last-slot", &cvarLastSlot, CVF_NO_MIN|CVF_NO_MAX|CVF_NO_ARCHIVE|CVF_READ_ONLY, 0, 0); + C_VAR_INT ("game-save-quick-slot", &cvarQuickSlot, CVF_NO_MAX|CVF_NO_ARCHIVE, -1, 0); // Aliases for obsolete cvars: - C_VAR_BYTE("menu-quick-ask", &cfg.confirmQuickGameSave, 0, 0, 1); + C_VAR_BYTE("menu-quick-ask", &cfg.confirmQuickGameSave, 0, 0, 1); } /** @@ -382,7 +380,7 @@ void SV_Register() * @param map If @c >= 0 include this logical map index in the composed path. * @return The composed path if reachable (else a zero-length string). */ -static AutoStr *composeGameSavePathForSlot2(int slot, int map) +static AutoStr *composeGameSavePathForSlot(int slot, int map = -1) { DENG_ASSERT(inited); @@ -407,11 +405,6 @@ static AutoStr *composeGameSavePathForSlot2(int slot, int map) return path; } -static AutoStr *composeGameSavePathForSlot(int slot) -{ - return composeGameSavePathForSlot2(slot, -1); -} - #if !__JHEXEN__ /** * Compose the (possibly relative) path to the game-save associated @@ -610,7 +603,7 @@ void SV_ClearSlot(int slot) for(int i = 0; i < MAX_HUB_MAPS; ++i) { - AutoStr *path = composeGameSavePathForSlot2(slot, i); + AutoStr *path = composeGameSavePathForSlot(slot, i); SV_RemoveFile(path); } @@ -816,7 +809,7 @@ dd_bool SV_IsSlotUsed(int slot) #if __JHEXEN__ dd_bool SV_HxHaveMapStateForSlot(int slot, uint map) { - AutoStr *path = composeGameSavePathForSlot2(slot, (int)map+1); + AutoStr *path = composeGameSavePathForSlot(slot, (int)map+1); if(!path || Str_IsEmpty(path)) return false; return SV_ExistingFile(path); } @@ -844,8 +837,8 @@ void SV_CopySlot(int sourceSlot, int destSlot) AutoStr *src, *dst; for(int i = 0; i < MAX_HUB_MAPS; ++i) { - src = composeGameSavePathForSlot2(sourceSlot, i); - dst = composeGameSavePathForSlot2(destSlot, i); + src = composeGameSavePathForSlot(sourceSlot, i); + dst = composeGameSavePathForSlot(destSlot, i); SV_CopyFile(src, dst); } @@ -937,7 +930,7 @@ static void insertThingInArchive(mobj_t const *mo, ThingSerialId thingId) DENG_ASSERT(mo != 0); #if __JHEXEN__ - if(mapVersion >= 4) + if(thingArchiveVersion >= 1) #endif { thingId -= 1; @@ -1057,7 +1050,7 @@ mobj_t *SV_GetArchiveThing(ThingSerialId thingId, void *address) DENG_ASSERT(thingArchive != 0); #if __JHEXEN__ - if(mapVersion < 4) + if(thingArchiveVersion < 1) { // Old format (base 0). @@ -1093,23 +1086,6 @@ static playerheader_t *getPlayerHeader() return &playerHeader; } -/** - * Returns the material archive version for the save state which is - * @em presently being read. - */ -static inline int materialArchiveVersion() -{ -#if __JHEXEN__ - if(mapVersion < 6) -#else - if(curInfo->version() < 6) -#endif - { - return 0; - } - return -1; -} - /** * Writes the given player's data (not including the ID number). */ @@ -2170,12 +2146,12 @@ static void writePlayerHeader(Writer *writer) /** * Read player header info from the game state. */ -static void readPlayerHeader(Reader *reader) +static void readPlayerHeader(Reader *reader, int saveVersion) { #if __JHEXEN__ - if(curInfo->version() >= 4) + if(saveVersion >= 4) #else - if(curInfo->version() >= 5) + if(saveVersion >= 5) #endif { SV_AssertSegment(ASEG_PLAYER_HEADER); @@ -2260,9 +2236,10 @@ static void writePlayers(Writer *writer) SV_EndSegment(); } -static void readPlayers(dd_bool *infile, dd_bool *loaded, Reader *reader) +static void readPlayers(SaveInfo &info, dd_bool *infile, dd_bool *loaded, + Reader *reader) { - DENG_ASSERT(infile && loaded); + DENG_ASSERT(infile != 0 && loaded != 0); // Setup the dummy. ddplayer_t dummyDDPlayer; @@ -2273,7 +2250,7 @@ static void readPlayers(dd_bool *infile, dd_bool *loaded, Reader *reader) { loaded[i] = 0; #if !__JHEXEN__ - infile[i] = curInfo->_players[i]; + infile[i] = info._players[i]; #endif } @@ -2323,6 +2300,10 @@ static void readPlayers(dd_bool *infile, dd_bool *loaded, Reader *reader) } } SV_AssertSegment(ASEG_END); + +#if __JHEXEN__ + DENG_UNUSED(info); +#endif } static void SV_WriteSector(Sector *sec, Writer *writer) @@ -2436,7 +2417,7 @@ static void SV_ReadSector(Sector *sec, Reader *reader, int mapVersion) type = sc_ploff; else #else - if(curInfo->version() <= 1) + if(mapVersion <= 1) type = sc_normal; else #endif @@ -2446,7 +2427,7 @@ static void SV_ReadSector(Sector *sec, Reader *reader, int mapVersion) #if __JHEXEN__ if(mapVersion > 2) #else - if(curInfo->version() > 4) + if(mapVersion > 4) #endif ver = Reader_ReadByte(reader); @@ -2465,7 +2446,7 @@ static void SV_ReadSector(Sector *sec, Reader *reader, int mapVersion) #endif #if !__JHEXEN__ - if(curInfo->version() == 1) + if(mapVersion == 1) { // The flat numbers are absolute lump indices. Uri* uri = Uri_NewWithPath2("Flats:", RC_NULL); @@ -2476,7 +2457,7 @@ static void SV_ReadSector(Sector *sec, Reader *reader, int mapVersion) ceilingMaterial = (Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(uri)); Uri_Delete(uri); } - else if(curInfo->version() >= 4) + else if(mapVersion >= 4) #endif { // The flat numbers are actually archive numbers. @@ -2497,15 +2478,19 @@ static void SV_ReadSector(Sector *sec, Reader *reader, int mapVersion) lightlevel = (byte) Reader_ReadInt16(reader); #else // In Ver1 the light level is a short - if(curInfo->version() == 1) + if(mapVersion == 1) + { lightlevel = (byte) Reader_ReadInt16(reader); + } else + { lightlevel = Reader_ReadByte(reader); + } #endif P_SetFloatp(sec, DMU_LIGHT_LEVEL, (float) lightlevel / 255.f); #if !__JHEXEN__ - if(curInfo->version() > 1) + if(mapVersion > 1) #endif { Reader_Read(reader, rgb, 3); @@ -2881,59 +2866,6 @@ static int SV_ReadPolyObj(Reader *reader, int mapVersion) } #endif -static void writeMapElements(Writer *writer) -{ - SV_BeginSegment(ASEG_MAP_ELEMENTS); - - for(int i = 0; i < numsectors; ++i) - { - SV_WriteSector((Sector *)P_ToPtr(DMU_SECTOR, i), writer); - } - - for(int i = 0; i < numlines; ++i) - { - SV_WriteLine((Line *)P_ToPtr(DMU_LINE, i), writer); - } - -#if __JHEXEN__ - SV_BeginSegment(ASEG_POLYOBJS); - Writer_WriteInt32(writer, numpolyobjs); - for(int i = 0; i < numpolyobjs; ++i) - { - SV_WritePolyObj(Polyobj_ById(i), writer); - } -#endif -} - -static void readMapElements(Reader *reader, int mapVersion) -{ - SV_AssertSegment(ASEG_MAP_ELEMENTS); - - // Load sectors. - for(int i = 0; i < numsectors; ++i) - { - SV_ReadSector((Sector *)P_ToPtr(DMU_SECTOR, i), reader, mapVersion); - } - - // Load lines. - for(int i = 0; i < numlines; ++i) - { - SV_ReadLine((Line *)P_ToPtr(DMU_LINE, i), reader, mapVersion); - } - -#if __JHEXEN__ - // Load polyobjects. - SV_AssertSegment(ASEG_POLYOBJS); - - long const writtenPolyobjCount = Reader_ReadInt32(reader); - DENG_ASSERT(writtenPolyobjCount == numpolyobjs); - for(int i = 0; i < writtenPolyobjCount; ++i) - { - SV_ReadPolyObj(reader, mapVersion); - } -#endif -} - #if __JHEXEN__ static void SV_WriteMovePoly(polyevent_t const *th, Writer *writer) { @@ -2991,585 +2923,667 @@ static int SV_ReadMovePoly(polyevent_t *th, Reader *reader, int mapVersion) } #endif // __JHEXEN__ -/** - * Serializes the specified thinker and writes it to save state. - * - * @param th The thinker to be serialized. - */ -static int writeThinker(thinker_t *th, void *context) +class MapStateWriter { - DENG_ASSERT(th != 0 && context != 0); - Writer *writer = (Writer *) context; - - // We are only concerned with thinkers we have save info for. - ThinkerClassInfo *thInfo = infoForThinker(*th); - if(!thInfo) return false; - - // Are we excluding players? - if(thingArchiveExcludePlayers) +public: + MapStateWriter(Writer *writer) + : _writer(writer) { - if(th->function == (thinkfunc_t) P_MobjThinker && ((mobj_t *) th)->player) - return false; // Continue iteration. + DENG_ASSERT(_writer != 0); } - // Only the server saves this class of thinker? - if((thInfo->flags & TSF_SERVERONLY) && IS_CLIENT) - return false; - - // Write the header block for this thinker. - Writer_WriteByte(writer, thInfo->thinkclass); // Thinker type byte. - Writer_WriteByte(writer, th->inStasis? 1 : 0); // In stasis? - - // Write the thinker data. - thInfo->writeFunc(th, writer); - - return false; // Continue iteration. -} + void write() + { + beginMapSegment(); + { + writeElements(); + writePolyobjs(); + writeThinkers(); + writeACScriptData(); + writeSoundSequences(); + writeMisc(); + writeBrain(); + writeSoundTargets(); + } + endMapSegment(); + } -/** - * Serializes thinkers for both client and server. - * - * @note Clients do not save data for all thinkers. In some cases the server - * will send it anyway (so saving it would just bloat client save states). - * - * @note Some thinker classes are NEVER saved by clients. - */ -static void writeThinkers(Writer *writer) -{ - SV_BeginSegment(ASEG_THINKERS); +private: + void beginMapSegment() { -#if __JHEXEN__ - Writer_WriteInt32(writer, thingArchiveSize); // number of mobjs. +#if !__JHEXEN__ + // Clear the sound target count (determined while saving sectors). + numSoundTargets = 0; #endif - // Serialize qualifying thinkers. - Thinker_Iterate(0/*all thinkers*/, writeThinker, writer); - } - Writer_WriteByte(writer, TC_END); -} + SV_BeginSegment(ASEG_MAP_HEADER2); -static int restoreMobjLinks(thinker_t *th, void *parameters) -{ - DENG_UNUSED(parameters); +#if __JHEXEN__ + Writer_WriteByte(_writer, MY_SAVE_VERSION); // Map version also. - if(th->function != (thinkfunc_t) P_MobjThinker) - return false; // Continue iteration. + // Write the map timer + Writer_WriteInt32(_writer, mapTime); +#endif + MaterialArchive_Write(materialArchive, _writer); + } - mobj_t *mo = (mobj_t *) th; - mo->target = SV_GetArchiveThing(PTR2INT(mo->target), &mo->target); - mo->onMobj = SV_GetArchiveThing(PTR2INT(mo->onMobj), &mo->onMobj); + void endMapSegment() + { + SV_EndSegment(); + } -#if __JHEXEN__ - switch(mo->type) + void writeElements() { - // Just tracer - case MT_BISH_FX: - case MT_HOLY_FX: - case MT_DRAGON: - case MT_THRUSTFLOOR_UP: - case MT_THRUSTFLOOR_DOWN: - case MT_MINOTAUR: - case MT_SORCFX1: - if(mapVersion >= 3) + SV_BeginSegment(ASEG_MAP_ELEMENTS); + + for(int i = 0; i < numsectors; ++i) { - mo->tracer = SV_GetArchiveThing(PTR2INT(mo->tracer), &mo->tracer); + SV_WriteSector((Sector *)P_ToPtr(DMU_SECTOR, i), _writer); } - else + + for(int i = 0; i < numlines; ++i) { - mo->tracer = SV_GetArchiveThing(mo->special1, &mo->tracer); - mo->special1 = 0; + SV_WriteLine((Line *)P_ToPtr(DMU_LINE, i), _writer); } - break; + } - // Just special2 - case MT_LIGHTNING_FLOOR: - case MT_LIGHTNING_ZAP: - mo->special2 = PTR2INT(SV_GetArchiveThing(mo->special2, &mo->special2)); - break; + void writePolyobjs() + { +#if __JHEXEN__ + SV_BeginSegment(ASEG_POLYOBJS); - // Both tracer and special2 - case MT_HOLY_TAIL: - case MT_LIGHTNING_CEILING: - if(mapVersion >= 3) + Writer_WriteInt32(_writer, numpolyobjs); + for(int i = 0; i < numpolyobjs; ++i) { - mo->tracer = SV_GetArchiveThing(PTR2INT(mo->tracer), &mo->tracer); + SV_WritePolyObj(Polyobj_ById(i), _writer); } - else +#endif + } + + /** + * Serializes the specified thinker and writes it to save state. + * + * @param th The thinker to be serialized. + */ + static int writeThinkerWorker(thinker_t *th, void *context) + { + DENG_ASSERT(th != 0 && context != 0); + Writer *writer = (Writer *) context; + + // We are only concerned with thinkers we have save info for. + ThinkerClassInfo *thInfo = infoForThinker(*th); + if(!thInfo) return false; + + // Are we excluding players? + if(thingArchiveExcludePlayers) { - mo->tracer = SV_GetArchiveThing(mo->special1, &mo->tracer); - mo->special1 = 0; + if(th->function == (thinkfunc_t) P_MobjThinker && ((mobj_t *) th)->player) + return false; // Continue iteration. } - mo->special2 = PTR2INT(SV_GetArchiveThing(mo->special2, &mo->special2)); - break; - default: - break; - } -#else -# if __JDOOM__ || __JDOOM64__ - mo->tracer = SV_GetArchiveThing(PTR2INT(mo->tracer), &mo->tracer); -# endif -# if __JHERETIC__ - mo->generator = SV_GetArchiveThing(PTR2INT(mo->generator), &mo->generator); -# endif -#endif + // Only the server saves this class of thinker? + if((thInfo->flags & TSF_SERVERONLY) && IS_CLIENT) + return false; - return false; // Continue iteration. -} + // Write the header block for this thinker. + Writer_WriteByte(writer, thInfo->thinkclass); // Thinker type byte. + Writer_WriteByte(writer, th->inStasis? 1 : 0); // In stasis? -static int removeThinkerWorker(thinker_t *th, void *context) -{ - DENG_UNUSED(context); + // Write the thinker data. + thInfo->writeFunc(th, writer); - if(th->function == (thinkfunc_t) P_MobjThinker) - P_MobjRemove((mobj_t *) th, true); - else - Z_Free(th); + return false; // Continue iteration. + } - return false; // Continue iteration. -} + /** + * Serializes thinkers for both client and server. + * + * @note Clients do not save data for all thinkers. In some cases the server + * will send it anyway (so saving it would just bloat client save states). + * + * @note Some thinker classes are NEVER saved by clients. + */ + void writeThinkers() + { + SV_BeginSegment(ASEG_THINKERS); -static void removeLoadSpawnedThinkers() -{ -#if !__JHEXEN__ - if(!IS_SERVER) return; // Not for us. +#if __JHEXEN__ + Writer_WriteInt32(_writer, thingArchiveSize); // number of mobjs. #endif - Thinker_Iterate(0 /*all thinkers*/, removeThinkerWorker, 0/*no parameters*/); - Thinker_Init(); -} + // Serialize qualifying thinkers. + Thinker_Iterate(0/*all thinkers*/, writeThinkerWorker, _writer); -#if __JHEXEN__ -static bool mobjtypeHasCorpse(mobjtype_t type) -{ - // Only corpses that call A_QueueCorpse from death routine. - /// @todo fixme: What about mods? Look for this action in the death - /// state sequence? - switch(type) - { - case MT_CENTAUR: - case MT_CENTAURLEADER: - case MT_DEMON: - case MT_DEMON2: - case MT_WRAITH: - case MT_WRAITHB: - case MT_BISHOP: - case MT_ETTIN: - case MT_PIG: - case MT_CENTAUR_SHIELD: - case MT_CENTAUR_SWORD: - case MT_DEMONCHUNK1: - case MT_DEMONCHUNK2: - case MT_DEMONCHUNK3: - case MT_DEMONCHUNK4: - case MT_DEMONCHUNK5: - case MT_DEMON2CHUNK1: - case MT_DEMON2CHUNK2: - case MT_DEMON2CHUNK3: - case MT_DEMON2CHUNK4: - case MT_DEMON2CHUNK5: - case MT_FIREDEMON_SPLOTCH1: - case MT_FIREDEMON_SPLOTCH2: - return true; - - default: return false; + // Mark the end of the thinkers. + Writer_WriteByte(_writer, TC_END); } -} -static int rebuildCorpseQueueWorker(thinker_t *th, void *parameters) -{ - DENG_UNUSED(parameters); + void writeACScriptData() + { +#if __JHEXEN__ + Game_ACScriptInterpreter().writeMapScriptData(_writer); +#endif + } - mobj_t *mo = (mobj_t *) th; + void writeSoundSequences() + { +#if __JHEXEN__ + SN_WriteSequences(_writer); +#endif + } - // Must be a non-iced corpse. - if((mo->flags & MF_CORPSE) && !(mo->flags & MF_ICECORPSE) && - mobjtypeHasCorpse(mobjtype_t(mo->type))) + void writeBrain() { - P_AddCorpseToQueue(mo); +#if __JDOOM__ + P_BrainWrite(_writer); +#endif } - return false; // Continue iteration. -} + void writeSoundTargets() + { +#if !__JHEXEN__ + // Not for us? + if(!IS_SERVER) return; -/** - * @todo fixme: the corpse queue should be serialized (original order unknown). - */ -static void rebuildCorpseQueue() -{ - P_InitCorpseQueue(); - // Search the thinker list for corpses and place them in the queue. - Thinker_Iterate((thinkfunc_t) P_MobjThinker, rebuildCorpseQueueWorker, NULL/*no params*/); -} -#endif + // Write the total number. + Writer_WriteInt32(_writer, numSoundTargets); -/** - * Update the references between thinkers. To be called during the load - * process to finalize the loaded thinkers. - */ -static void relinkThinkers() -{ -#if __JHEXEN__ - Thinker_Iterate((thinkfunc_t) P_MobjThinker, restoreMobjLinks, 0/*no params*/); + // Write the mobj references using the mobj archive. + for(int i = 0; i < numsectors; ++i) + { + xsector_t *xsec = P_ToXSector((Sector *)P_ToPtr(DMU_SECTOR, i)); - P_CreateTIDList(); - rebuildCorpseQueue(); + if(xsec->soundTarget) + { + Writer_WriteInt32(_writer, i); + Writer_WriteInt16(_writer, SV_ThingArchiveId(xsec->soundTarget)); + } + } +#endif + } -#else - if(IS_SERVER) + void writeMisc() { - Thinker_Iterate((thinkfunc_t) P_MobjThinker, restoreMobjLinks, 0/*no params*/); +#if __JHEXEN__ + SV_BeginSegment(ASEG_MISC); - for(int i = 0; i < numlines; ++i) + for(int i = 0; i < MAXPLAYERS; ++i) { - xline_t *xline = P_ToXLine((Line *)P_ToPtr(DMU_LINE, i)); - if(!xline->xg) continue; - - xline->xg->activator = SV_GetArchiveThing(PTR2INT(xline->xg->activator), - &xline->xg->activator); + Writer_WriteInt32(_writer, localQuakeHappening[i]); } - } #endif -} + } -/** - * Deserializes and then spawns thinkers for both client and server. - */ -static void readThinkers(Reader *reader, int mapVersion) + Writer *_writer; +}; + +class MapStateReader { - bool const formatHasStasisInfo = (mapVersion >= 6); +public: + MapStateReader(Reader *reader, int saveVersion) + : _reader(reader) + , _saveVersion(saveVersion) + , _mapVersion(saveVersion) // Default: mapVersion == saveVersion + { + DENG_ASSERT(_reader != 0); + } - removeLoadSpawnedThinkers(); + void read() + { + beginMapSegment(); + { + readElements(); + readPolyobjs(); + readThinkers(); + readACScriptData(); + readSoundSequences(); + readMisc(); + readBrain(); + readSoundTargets(); + } + endMapSegment(); + } -#if __JHEXEN__ - if(mapVersion < 4) - SV_AssertSegment(ASEG_MOBJS); - else -#endif - SV_AssertSegment(ASEG_THINKERS); +private: + void beginMapSegment() + { + savestatesegment_t segId; + SV_AssertMapSegment(&segId); #if __JHEXEN__ - initTargetPlayers(); - initThingArchiveForLoad(Reader_ReadInt32(reader) /* num elements */); -#endif + // Maps have their own version number, in Hexen. + _mapVersion = (segId == ASEG_MAP_HEADER2? Reader_ReadByte(_reader) : 2); - // Read in saved thinkers. -#if __JHEXEN__ - int i = 0; - bool reachedSpecialsBlock = (mapVersion >= 4); -#else - bool reachedSpecialsBlock = (mapVersion >= 5); + thingArchiveVersion = _mapVersion >= 4? 1 : 0; #endif - byte tClass = 0; - for(;;) - { #if __JHEXEN__ - if(reachedSpecialsBlock) + // Read the map timer. + mapTime = Reader_ReadInt32(_reader); #endif - tClass = Reader_ReadByte(reader); - -#if __JHEXEN__ - if(mapVersion < 4) - { - if(reachedSpecialsBlock) // Have we started on the specials yet? - { - // Versions prior to 4 used a different value to mark - // the end of the specials data and the thinker class ids - // are differrent, so we need to manipulate the thinker - // class identifier value. - if(tClass != TC_END) - tClass += 2; - } - else - { - tClass = TC_MOBJ; - } - if(tClass == TC_MOBJ && (uint)i == thingArchiveSize) - { - SV_AssertSegment(ASEG_THINKERS); - // We have reached the begining of the "specials" block. - reachedSpecialsBlock = true; - continue; - } - } -#else - if(mapVersion < 5) + // Read the material archive for the map. +#if !__JHEXEN__ + if(_mapVersion >= 4) +#endif { - if(reachedSpecialsBlock) - { - // Versions prior to 5 used a different value to mark - // the end of the specials data so we need to manipulate - // the thinker class identifier value. - if(tClass == PRE_VER5_END_SPECIALS) - tClass = TC_END; - else - tClass += 3; - } - else if(tClass == TC_END) - { - // We have reached the begining of the "specials" block. - reachedSpecialsBlock = true; - continue; - } + MaterialArchive_Read(materialArchive, _reader, _mapVersion < 6? 0 : -1); } -#endif - if(tClass == TC_END) - break; // End of the list. - ThinkerClassInfo *thInfo = infoForThinkerClass(thinkerclass_t(tClass)); - DENG_ASSERT(thInfo != 0); - // Not for us? (it shouldn't be here anyway!). - DENG_ASSERT(!((thInfo->flags & TSF_SERVERONLY) && IS_CLIENT)); + sideArchive = new SideArchive; + } - // Mobjs use a special engine-side allocator. - thinker_t *th = 0; - if(thInfo->thinkclass == TC_MOBJ) - { - th = reinterpret_cast(Mobj_CreateXYZ((thinkfunc_t) P_MobjThinker, 0, 0, 0, 0, 64, 64, 0)); - } - else - { - th = reinterpret_cast(Z_Calloc(thInfo->size, PU_MAP, 0)); - } + void endMapSegment() + { + SV_AssertSegment(ASEG_END); - bool putThinkerInStasis = (formatHasStasisInfo? CPP_BOOL(Reader_ReadByte(reader)) : false); + delete sideArchive; sideArchive = 0; + } - if(thInfo->readFunc(th, reader, mapVersion)) + void readElements() + { + SV_AssertSegment(ASEG_MAP_ELEMENTS); + + // Sectors. + for(int i = 0; i < numsectors; ++i) { - Thinker_Add(th); + SV_ReadSector((Sector *)P_ToPtr(DMU_SECTOR, i), _reader, _mapVersion); } - if(putThinkerInStasis) + // Lines. + for(int i = 0; i < numlines; ++i) { - Thinker_SetStasis(th, true); + SV_ReadLine((Line *)P_ToPtr(DMU_LINE, i), _reader, _mapVersion); } + } + void readPolyobjs() + { #if __JHEXEN__ - if(tClass == TC_MOBJ) - i++; + SV_AssertSegment(ASEG_POLYOBJS); + + int const writtenPolyobjCount = Reader_ReadInt32(_reader); + DENG_ASSERT(writtenPolyobjCount == numpolyobjs); + for(int i = 0; i < writtenPolyobjCount; ++i) + { + SV_ReadPolyObj(_reader, _mapVersion); + } #endif } - // Update references between thinkers. - relinkThinkers(); -} - -static void writeBrain(Writer *writer) -{ -#if __JDOOM__ - // Not for us? - if(!IS_SERVER) return; - - Writer_WriteByte(writer, 1); // Write a version byte. + static int removeThinkerWorker(thinker_t *th, void * /*context*/) + { + if(th->function == (thinkfunc_t) P_MobjThinker) + P_MobjRemove((mobj_t *) th, true); + else + Z_Free(th); - Writer_WriteInt16(writer, brain.numTargets); - Writer_WriteInt16(writer, brain.targetOn); - Writer_WriteByte(writer, brain.easy!=0? 1:0); + return false; // Continue iteration. + } - // Write the mobj references using the mobj archive. - for(int i = 0; i < brain.numTargets; ++i) + void removeLoadSpawnedThinkers() { - Writer_WriteInt16(writer, SV_ThingArchiveId(brain.targets[i])); - } -#else - DENG_UNUSED(writer); +#if !__JHEXEN__ + if(!IS_SERVER) return; // Not for us. #endif -} - -static void readBrain(Reader *reader, int mapVersion) -{ -#if __JDOOM__ - // Not for us? - if(!IS_SERVER) return; - // No brain data before version 3. - if(mapVersion < 3) return; - - P_BrainClearTargets(); + Thinker_Iterate(0 /*all thinkers*/, removeThinkerWorker, 0/*no parameters*/); + Thinker_Init(); + } - int ver = (mapVersion >= 8? Reader_ReadByte(reader) : 0); - int numTargets; - if(ver >= 1) +#if __JHEXEN__ + static bool mobjtypeHasCorpse(mobjtype_t type) { - numTargets = Reader_ReadInt16(reader); - brain.targetOn = Reader_ReadInt16(reader); - brain.easy = (dd_bool)Reader_ReadByte(reader); + // Only corpses that call A_QueueCorpse from death routine. + /// @todo fixme: What about mods? Look for this action in the death + /// state sequence? + switch(type) + { + case MT_CENTAUR: + case MT_CENTAURLEADER: + case MT_DEMON: + case MT_DEMON2: + case MT_WRAITH: + case MT_WRAITHB: + case MT_BISHOP: + case MT_ETTIN: + case MT_PIG: + case MT_CENTAUR_SHIELD: + case MT_CENTAUR_SWORD: + case MT_DEMONCHUNK1: + case MT_DEMONCHUNK2: + case MT_DEMONCHUNK3: + case MT_DEMONCHUNK4: + case MT_DEMONCHUNK5: + case MT_DEMON2CHUNK1: + case MT_DEMON2CHUNK2: + case MT_DEMON2CHUNK3: + case MT_DEMON2CHUNK4: + case MT_DEMON2CHUNK5: + case MT_FIREDEMON_SPLOTCH1: + case MT_FIREDEMON_SPLOTCH2: + return true; + + default: return false; + } } - else + + static int rebuildCorpseQueueWorker(thinker_t *th, void * /*context*/) { - numTargets = Reader_ReadByte(reader); - brain.targetOn = Reader_ReadByte(reader); - brain.easy = false; + mobj_t *mo = (mobj_t *) th; + + // Must be a non-iced corpse. + if((mo->flags & MF_CORPSE) && !(mo->flags & MF_ICECORPSE) && + mobjtypeHasCorpse(mobjtype_t(mo->type))) + { + P_AddCorpseToQueue(mo); + } + + return false; // Continue iteration. } - for(int i = 0; i < numTargets; ++i) + /** + * @todo fixme: the corpse queue should be serialized (original order unknown). + */ + void rebuildCorpseQueue() { - P_BrainAddTarget(SV_GetArchiveThing((int) Reader_ReadInt16(reader), 0)); + P_InitCorpseQueue(); + // Search the thinker list for corpses and place them in the queue. + Thinker_Iterate((thinkfunc_t) P_MobjThinker, rebuildCorpseQueueWorker, NULL/*no params*/); } -#else - DENG_UNUSED(reader); - DENG_UNUSED(mapVersion); #endif -} -static void writeSoundTargets(Writer *writer) -{ -#if !__JHEXEN__ - // Not for us? - if(!IS_SERVER) return; + static int restoreMobjLinksWorker(thinker_t *th, void *context) + { + int const mapVersion = *static_cast(context); - // Write the total number. - Writer_WriteInt32(writer, numSoundTargets); + if(th->function != (thinkfunc_t) P_MobjThinker) + return false; // Continue iteration. - // Write the mobj references using the mobj archive. - for(int i = 0; i < numsectors; ++i) - { - xsector_t *xsec = P_ToXSector((Sector *)P_ToPtr(DMU_SECTOR, i)); + mobj_t *mo = (mobj_t *) th; + mo->target = SV_GetArchiveThing(PTR2INT(mo->target), &mo->target); + mo->onMobj = SV_GetArchiveThing(PTR2INT(mo->onMobj), &mo->onMobj); - if(xsec->soundTarget) +#if __JHEXEN__ + switch(mo->type) { - Writer_WriteInt32(writer, i); - Writer_WriteInt16(writer, SV_ThingArchiveId(xsec->soundTarget)); + // Just tracer + case MT_BISH_FX: + case MT_HOLY_FX: + case MT_DRAGON: + case MT_THRUSTFLOOR_UP: + case MT_THRUSTFLOOR_DOWN: + case MT_MINOTAUR: + case MT_SORCFX1: + if(mapVersion >= 3) + { + mo->tracer = SV_GetArchiveThing(PTR2INT(mo->tracer), &mo->tracer); + } + else + { + mo->tracer = SV_GetArchiveThing(mo->special1, &mo->tracer); + mo->special1 = 0; + } + break; + + // Just special2 + case MT_LIGHTNING_FLOOR: + case MT_LIGHTNING_ZAP: + mo->special2 = PTR2INT(SV_GetArchiveThing(mo->special2, &mo->special2)); + break; + + // Both tracer and special2 + case MT_HOLY_TAIL: + case MT_LIGHTNING_CEILING: + if(mapVersion >= 3) + { + mo->tracer = SV_GetArchiveThing(PTR2INT(mo->tracer), &mo->tracer); + } + else + { + mo->tracer = SV_GetArchiveThing(mo->special1, &mo->tracer); + mo->special1 = 0; + } + mo->special2 = PTR2INT(SV_GetArchiveThing(mo->special2, &mo->special2)); + break; + + default: + break; } - } #else - DENG_UNUSED(writer); +# if __JDOOM__ || __JDOOM64__ + mo->tracer = SV_GetArchiveThing(PTR2INT(mo->tracer), &mo->tracer); +# endif +# if __JHERETIC__ + mo->generator = SV_GetArchiveThing(PTR2INT(mo->generator), &mo->generator); +# endif #endif -} -static void readSoundTargets(Reader *reader, int mapVersion) -{ + return false; // Continue iteration. + #if !__JHEXEN__ - // Not for us? - if(!IS_SERVER) return; + DENG_UNUSED(mapVersion); +#endif + } - // Sound Target data was introduced in ver 5 - if(mapVersion < 5) return; + /** + * Update the references between thinkers. To be called during the load + * process to finalize the loaded thinkers. + */ + void relinkThinkers() + { +#if __JHEXEN__ + Thinker_Iterate((thinkfunc_t) P_MobjThinker, restoreMobjLinksWorker, &_mapVersion); - // Read the number of targets - int numsoundtargets = Reader_ReadInt32(reader); + P_CreateTIDList(); + rebuildCorpseQueue(); - // Read in the sound targets. - for(int i = 0; i < numsoundtargets; ++i) - { - xsector_t *xsec = P_ToXSector((Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(reader))); - DENG_ASSERT(xsec != 0); - if(!xsec) +#else + if(IS_SERVER) { - DENG_UNUSED(Reader_ReadInt16(reader)); - continue; - } + Thinker_Iterate((thinkfunc_t) P_MobjThinker, restoreMobjLinksWorker, &_mapVersion); + + for(int i = 0; i < numlines; ++i) + { + xline_t *xline = P_ToXLine((Line *)P_ToPtr(DMU_LINE, i)); + if(!xline->xg) continue; - xsec->soundTarget = INT2PTR(mobj_t, Reader_ReadInt16(reader)); - xsec->soundTarget = - SV_GetArchiveThing(PTR2INT(xsec->soundTarget), &xsec->soundTarget); + xline->xg->activator = SV_GetArchiveThing(PTR2INT(xline->xg->activator), + &xline->xg->activator); + } + } +#endif } -#else - DENG_UNUSED(reader); - DENG_UNUSED(mapVersion); + + /** + * Deserialize and then spawns thinkers for both client and server. + */ + void readThinkers() + { + bool const formatHasStasisInfo = (_mapVersion >= 6); + + removeLoadSpawnedThinkers(); + +#if __JHEXEN__ + if(_mapVersion < 4) + SV_AssertSegment(ASEG_MOBJS); + else #endif -} + SV_AssertSegment(ASEG_THINKERS); -static void writeMisc(Writer *writer) -{ #if __JHEXEN__ - SV_BeginSegment(ASEG_MISC); + initTargetPlayers(); + initThingArchiveForLoad(Reader_ReadInt32(_reader) /* num elements */); +#endif - for(int i = 0; i < MAXPLAYERS; ++i) - { - Writer_WriteInt32(writer, localQuakeHappening[i]); - } + // Read in saved thinkers. +#if __JHEXEN__ + int i = 0; + bool reachedSpecialsBlock = (_mapVersion >= 4); #else - DENG_UNUSED(writer); + bool reachedSpecialsBlock = (_mapVersion >= 5); #endif -} -static void readMisc(Reader *reader, int /*mapVersion*/) -{ + byte tClass = 0; + for(;;) + { #if __JHEXEN__ - SV_AssertSegment(ASEG_MISC); + if(reachedSpecialsBlock) +#endif + tClass = Reader_ReadByte(_reader); - for(int i = 0; i < MAXPLAYERS; ++i) - { - localQuakeHappening[i] = Reader_ReadInt32(reader); - } +#if __JHEXEN__ + if(_mapVersion < 4) + { + if(reachedSpecialsBlock) // Have we started on the specials yet? + { + // Versions prior to 4 used a different value to mark + // the end of the specials data and the thinker class ids + // are differrent, so we need to manipulate the thinker + // class identifier value. + if(tClass != TC_END) + tClass += 2; + } + else + { + tClass = TC_MOBJ; + } + + if(tClass == TC_MOBJ && (uint)i == thingArchiveSize) + { + SV_AssertSegment(ASEG_THINKERS); + // We have reached the begining of the "specials" block. + reachedSpecialsBlock = true; + continue; + } + } #else - DENG_UNUSED(reader); + if(_mapVersion < 5) + { + if(reachedSpecialsBlock) + { + // Versions prior to 5 used a different value to mark + // the end of the specials data so we need to manipulate + // the thinker class identifier value. + if(tClass == PRE_VER5_END_SPECIALS) + tClass = TC_END; + else + tClass += 3; + } + else if(tClass == TC_END) + { + // We have reached the begining of the "specials" block. + reachedSpecialsBlock = true; + continue; + } + } #endif -} + if(tClass == TC_END) + break; // End of the list. -static void writeMap(Writer *writer) -{ -#if !__JHEXEN__ - // Clear the sound target count (determined while saving sectors). - numSoundTargets = 0; + ThinkerClassInfo *thInfo = infoForThinkerClass(thinkerclass_t(tClass)); + DENG_ASSERT(thInfo != 0); + // Not for us? (it shouldn't be here anyway!). + DENG_ASSERT(!((thInfo->flags & TSF_SERVERONLY) && IS_CLIENT)); + + // Mobjs use a special engine-side allocator. + thinker_t *th = 0; + if(thInfo->thinkclass == TC_MOBJ) + { + th = reinterpret_cast(Mobj_CreateXYZ((thinkfunc_t) P_MobjThinker, 0, 0, 0, 0, 64, 64, 0)); + } + else + { + th = reinterpret_cast(Z_Calloc(thInfo->size, PU_MAP, 0)); + } + + bool putThinkerInStasis = (formatHasStasisInfo? CPP_BOOL(Reader_ReadByte(_reader)) : false); + + if(thInfo->readFunc(th, _reader, _mapVersion)) + { + Thinker_Add(th); + } + + if(putThinkerInStasis) + { + Thinker_SetStasis(th, true); + } + +#if __JHEXEN__ + if(tClass == TC_MOBJ) + i++; #endif + } + + // Update references between thinkers. + relinkThinkers(); + } - SV_BeginSegment(ASEG_MAP_HEADER2); + void readACScriptData() { #if __JHEXEN__ - Writer_WriteByte(writer, MY_SAVE_VERSION); // Map version also. - - // Write the map timer - Writer_WriteInt32(writer, mapTime); + Game_ACScriptInterpreter().readMapScriptData(_reader, _mapVersion); #endif + } - MaterialArchive_Write(materialArchive, writer); - writeMapElements(writer); - writeThinkers(writer); + void readSoundSequences() + { #if __JHEXEN__ - Game_ACScriptInterpreter().writeMapScriptData(writer); - SN_WriteSequences(writer); + SN_ReadSequences(_reader, _mapVersion); #endif - writeMisc(writer); - writeBrain(writer); - writeSoundTargets(writer); } - SV_EndSegment(); -} - -static void readMap(Reader *reader) -{ - sideArchive = new SideArchive; - savestatesegment_t mapSegmentId; - SV_AssertMapSegment(&mapSegmentId); + void readMisc() { #if __JHEXEN__ - mapVersion = (mapSegmentId == ASEG_MAP_HEADER2? Reader_ReadByte(reader) : 2); -#else - int const mapVersion = curInfo->version(); + SV_AssertSegment(ASEG_MISC); + + for(int i = 0; i < MAXPLAYERS; ++i) + { + localQuakeHappening[i] = Reader_ReadInt32(_reader); + } #endif + } -#if __JHEXEN__ - // Read the map timer. - mapTime = Reader_ReadInt32(reader); + void readBrain() + { +#if __JDOOM__ + P_BrainRead(_reader, _mapVersion); #endif + } - // Read the material archive for the map. + void readSoundTargets() + { #if !__JHEXEN__ - if(mapVersion >= 4) -#endif + // Not for us? + if(!IS_SERVER) return; + + // Sound target data was introduced in ver 5 + if(_mapVersion < 5) return; + + int numTargets = Reader_ReadInt32(_reader); + for(int i = 0; i < numTargets; ++i) { - MaterialArchive_Read(materialArchive, reader, materialArchiveVersion()); - } + xsector_t *xsec = P_ToXSector((Sector *)P_ToPtr(DMU_SECTOR, Reader_ReadInt32(_reader))); + DENG_ASSERT(xsec != 0); - readMapElements(reader, mapVersion); - readThinkers(reader, mapVersion); -#if __JHEXEN__ - Game_ACScriptInterpreter().readMapScriptData(reader, mapVersion); - SN_ReadSequences(reader, mapVersion); + if(!xsec) + { + DENG_UNUSED(Reader_ReadInt16(_reader)); + continue; + } + + xsec->soundTarget = INT2PTR(mobj_t, Reader_ReadInt16(_reader)); + xsec->soundTarget = + SV_GetArchiveThing(PTR2INT(xsec->soundTarget), &xsec->soundTarget); + } #endif - readMisc(reader, mapVersion); - readBrain(reader, mapVersion); - readSoundTargets(reader, mapVersion); } - SV_AssertSegment(ASEG_END); - delete sideArchive; sideArchive = 0; -} + Reader *_reader; + int _saveVersion; + int _mapVersion; +}; void SV_Initialize() { @@ -3687,7 +3701,7 @@ static int SV_LoadState(Str const *path, SaveInfo *info) initThingArchiveForLoad(info->version() >= 5? Reader_ReadInt32(reader) : 1024 /* num elements */); #endif - readPlayerHeader(reader); + readPlayerHeader(reader, info->version()); // Read the player structures // We don't have the right to say which players are in the game. The @@ -3696,7 +3710,7 @@ static int SV_LoadState(Str const *path, SaveInfo *info) // players who were saved but are not currently in the game will be // discarded. dd_bool loaded[MAXPLAYERS], infile[MAXPLAYERS]; - readPlayers(infile, loaded, reader); + readPlayers(*info, infile, loaded, reader); #if __JHEXEN__ Z_Free(saveBuffer); @@ -3711,9 +3725,9 @@ static int SV_LoadState(Str const *path, SaveInfo *info) // Load the current map state. #if __JHEXEN__ - readMapState(reader, composeGameSavePathForSlot2(BASE_SLOT, gameMap+1)); + readMapState(reader, info->version(), composeGameSavePathForSlot(BASE_SLOT, gameMap+1)); #else - readMapState(reader); + readMapState(reader, info->version()); #endif #if !__JHEXEN__ @@ -3901,15 +3915,13 @@ void SV_SaveGameClient(uint gameId) player_t *pl = &players[CONSOLEPLAYER]; mobj_t *mo = pl->plr->mo; - AutoStr *gameSavePath; - SaveInfo *saveInfo; if(!IS_CLIENT || !mo) return; playerHeaderOK = false; // Uninitialized. - gameSavePath = composeGameSavePathForClientGameId(gameId); + AutoStr *gameSavePath = composeGameSavePathForClientGameId(gameId); if(!SV_OpenFile(gameSavePath, "wp")) { App_Log(DE2_RES_WARNING, "SV_SaveGameClient: Failed opening \"%s\" for writing", Str_Text(gameSavePath)); @@ -3917,12 +3929,12 @@ void SV_SaveGameClient(uint gameId) } // Prepare the header. - saveInfo = new SaveInfo; - saveInfo->setGameId(gameId); - saveInfo->configure(); + SaveInfo *info = new SaveInfo; + info->setGameId(gameId); + info->configure(); Writer *writer = SV_NewWriter(); - saveInfo->write(writer); + info->write(writer); // Some important information. // Our position and look angles. @@ -3939,14 +3951,14 @@ void SV_SaveGameClient(uint gameId) // Create and populate the MaterialArchive. materialArchive = MaterialArchive_New(false); - writeMap(writer); + MapStateWriter(writer).write(); /// @todo No consistency bytes in client saves? clearMaterialArchive(); SV_CloseFile(); Writer_Delete(writer); - delete saveInfo; + delete info; #else DENG_UNUSED(gameId); #endif @@ -4011,7 +4023,7 @@ void SV_LoadGameClient(uint gameId) mo->angle = Reader_ReadInt32(reader); /* $unifiedangles */ cpl->plr->lookDir = Reader_ReadFloat(reader); /* $unifiedangles */ - readPlayerHeader(reader); + readPlayerHeader(reader, saveInfo->version()); SV_ReadPlayer(cpl, reader); /** @@ -4023,7 +4035,7 @@ void SV_LoadGameClient(uint gameId) */ materialArchive = MaterialArchive_New(false); - readMap(reader); + MapStateReader(reader, saveInfo->version()).read(); clearMaterialArchive(); @@ -4036,9 +4048,9 @@ void SV_LoadGameClient(uint gameId) } #if __JHEXEN__ -static void readMapState(Reader *reader, Str const *path) +static void readMapState(Reader *reader, int saveVersion, Str const *path) #else -static void readMapState(Reader *reader) +static void readMapState(Reader *reader, int saveVersion) #endif { #if __JHEXEN__ @@ -4047,7 +4059,7 @@ static void readMapState(Reader *reader) App_Log(DE2_DEV_MAP_MSG, "readMapState: Opening file \"%s\"\n", Str_Text(path)); // Load the file - size_t bufferSize = M_ReadFile(Str_Text(path), (char**)&saveBuffer); + size_t bufferSize = M_ReadFile(Str_Text(path), (char **)&saveBuffer); if(!bufferSize) { App_Log(DE2_RES_ERROR, "readMapState: Failed opening \"%s\" for reading", Str_Text(path)); @@ -4058,7 +4070,7 @@ static void readMapState(Reader *reader) SV_HxSetSaveEndPtr(saveBuffer + bufferSize); #endif - readMap(reader); + MapStateReader(reader, saveVersion).read(); #if __JHEXEN__ clearThingArchive(); @@ -4119,10 +4131,10 @@ static int saveStateWorker(Str const *path, SaveInfo *saveInfo) */ #if __JHEXEN__ // ...map state is actually written to a separate file. - SV_OpenFile(composeGameSavePathForSlot2(BASE_SLOT, gameMap+1), "wp"); + SV_OpenFile(composeGameSavePathForSlot(BASE_SLOT, gameMap+1), "wp"); #endif - writeMap(writer); + MapStateWriter(writer).write(); SV_WriteConsistencyBytes(); // To be absolutely sure... SV_CloseFile(); @@ -4214,7 +4226,7 @@ void SV_HxSaveClusterMap() { playerHeaderOK = false; // Uninitialized. - SV_OpenFile(composeGameSavePathForSlot2(BASE_SLOT, gameMap+1), "wp"); + SV_OpenFile(composeGameSavePathForSlot(BASE_SLOT, gameMap+1), "wp"); // Set the mobj archive numbers initThingArchiveForSave(true /*exclude players*/); @@ -4224,7 +4236,7 @@ void SV_HxSaveClusterMap() // Create and populate the MaterialArchive. materialArchive = MaterialArchive_New(true); - writeMap(writer); + MapStateWriter(writer).write(); clearMaterialArchive(); @@ -4236,6 +4248,10 @@ void SV_HxSaveClusterMap() void SV_HxLoadClusterMap() { + /// @todo fixme: do not assume this pointer is still valid! + DENG_ASSERT(curInfo != 0); + SaveInfo const *info = curInfo; + // Only readMap() uses targetPlayerAddrs, so it's NULLed here for the // following check (player mobj redirection). targetPlayerAddrs = 0; @@ -4248,7 +4264,7 @@ void SV_HxLoadClusterMap() Reader *reader = SV_NewReader(); // Been here before, load the previous map state. - readMapState(reader, composeGameSavePathForSlot2(BASE_SLOT, gameMap+1)); + readMapState(reader, info->version(), composeGameSavePathForSlot(BASE_SLOT, gameMap+1)); clearMaterialArchive(); diff --git a/doomsday/plugins/doom/include/p_enemy.h b/doomsday/plugins/doom/include/p_enemy.h index 3c4040f468..14b6afc2ff 100644 --- a/doomsday/plugins/doom/include/p_enemy.h +++ b/doomsday/plugins/doom/include/p_enemy.h @@ -1,32 +1,24 @@ -/**\file p_enemy.h - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html +/** @file p_enemy.h Doom-specific enemy AI. * - *\author Copyright © 2009-2013 Daniel Swanson + * @authors Copyright © 2009-2013 Daniel Swanson * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * Enemy thinking, AI (jDoom-specific). + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA */ -#ifndef LIBDOOM_P_ENEMY_H -#define LIBDOOM_P_ENEMY_H +#ifndef LIBDOOM_PLAY_ENEMY_H +#define LIBDOOM_PLAY_ENEMY_H #ifndef __JDOOM__ # error "Using jDoom headers without __JDOOM__" @@ -42,7 +34,7 @@ typedef struct braindata_s { int targetOn; int numTargets; int maxTargets; - mobj_t** targets; + mobj_t **targets; } braindata_t; DENG_EXTERN_C braindata_t brain; @@ -54,12 +46,14 @@ extern "C" { void P_BrainInitForMap(void); void P_BrainShutdown(void); void P_BrainClearTargets(void); -void P_BrainAddTarget(mobj_t* mo); -void P_NoiseAlert(mobj_t *target, mobj_t *emmiter); -int P_Massacre(void); +void P_BrainWrite(Writer *writer); +void P_BrainRead(Reader *reader, int mapVersion); +void P_BrainAddTarget(mobj_t *mo); +void P_NoiseAlert(mobj_t *target, mobj_t *emmiter); +int P_Massacre(void); #ifdef __cplusplus } // extern "C" #endif -#endif /* LIBDOOM_ENEMY_H */ +#endif // LIBDOOM_PLAY_ENEMY_H diff --git a/doomsday/plugins/doom/src/p_enemy.c b/doomsday/plugins/doom/src/p_enemy.c index 63fb2142bf..4c611f637f 100644 --- a/doomsday/plugins/doom/src/p_enemy.c +++ b/doomsday/plugins/doom/src/p_enemy.c @@ -36,6 +36,7 @@ #include "p_mapspec.h" #include "p_door.h" #include "p_floor.h" +#include "p_saveg.h" #define FATSPREAD (ANG90/8) #define SKULLSPEED (20) @@ -1742,6 +1743,64 @@ void P_BrainClearTargets(void) brain.targetOn = 0; } +void P_BrainWrite(Writer *writer) +{ + int i; + + DENG_ASSERT(writer != 0); + + // Not for us? + if(!IS_SERVER) return; + + Writer_WriteByte(writer, 1); // Write a version byte. + + Writer_WriteInt16(writer, brain.numTargets); + Writer_WriteInt16(writer, brain.targetOn); + Writer_WriteByte(writer, brain.easy!=0? 1:0); + + // Write the mobj references using the mobj archive. + for(i = 0; i < brain.numTargets; ++i) + { + Writer_WriteInt16(writer, SV_ThingArchiveId(brain.targets[i])); + } +} + +void P_BrainRead(Reader *reader, int mapVersion) +{ + int ver, numTargets; + int i; + + DENG_ASSERT(reader != 0); + + // Not for us? + if(!IS_SERVER) return; + + // No brain data before version 3. + if(mapVersion < 3) return; + + P_BrainClearTargets(); + + ver = (mapVersion >= 8? Reader_ReadByte(reader) : 0); + numTargets; + if(ver >= 1) + { + numTargets = Reader_ReadInt16(reader); + brain.targetOn = Reader_ReadInt16(reader); + brain.easy = (dd_bool)Reader_ReadByte(reader); + } + else + { + numTargets = Reader_ReadByte(reader); + brain.targetOn = Reader_ReadByte(reader); + brain.easy = false; + } + + for(i = 0; i < numTargets; ++i) + { + P_BrainAddTarget(SV_GetArchiveThing((int) Reader_ReadInt16(reader), 0)); + } +} + void P_BrainShutdown(void) { if(brain.targets) From 6fac3e321e0c0bf410ef21fdeb05505557b22b76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Wed, 5 Feb 2014 11:30:39 +0200 Subject: [PATCH 095/106] UI|Client: Game selection groups appear and are hidden as needed Also, when a fold is closed, show the number of items in parentheses as part of the title. --- .../include/ui/widgets/gameselectionwidget.h | 5 +- .../include/ui/widgets/mpselectionwidget.h | 1 + .../src/ui/widgets/gameselectionwidget.cpp | 59 ++++++++++++++++--- .../src/ui/widgets/mpselectionwidget.cpp | 22 +++---- 4 files changed, 66 insertions(+), 21 deletions(-) diff --git a/doomsday/client/include/ui/widgets/gameselectionwidget.h b/doomsday/client/include/ui/widgets/gameselectionwidget.h index 5846acd2f1..fe37b31d19 100644 --- a/doomsday/client/include/ui/widgets/gameselectionwidget.h +++ b/doomsday/client/include/ui/widgets/gameselectionwidget.h @@ -36,9 +36,12 @@ class GameSelectionWidget : public de::ScrollAreaWidget // Events. void update(); -signals: +signals: void gameSessionSelected(); +protected slots: + void updateSubsetLayout(); + private: DENG2_PRIVATE(d) }; diff --git a/doomsday/client/include/ui/widgets/mpselectionwidget.h b/doomsday/client/include/ui/widgets/mpselectionwidget.h index b35c6198ab..0c0cf12c06 100644 --- a/doomsday/client/include/ui/widgets/mpselectionwidget.h +++ b/doomsday/client/include/ui/widgets/mpselectionwidget.h @@ -36,6 +36,7 @@ class MPSelectionWidget : public de::MenuWidget void setColumns(int numberOfColumns); signals: + void availabilityChanged(); void gameSelected(); private: diff --git a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp index 55d610b2bb..209511f6b1 100644 --- a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp +++ b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp @@ -72,11 +72,12 @@ DENG_GUI_PIMPL(GameSelectionWidget) MultiplayerGames }; + String titleText; Type type; MenuWidget *menu; Subset(Type selType, String const &headingText, GameSelectionWidget::Instance *owner) - : type(selType) + : titleText(headingText), type(selType) { owner->self.add(makeTitle(headingText)); title().setFont("title"); @@ -94,6 +95,7 @@ DENG_GUI_PIMPL(GameSelectionWidget) case MultiplayerGames: menu = new MPSelectionWidget; QObject::connect(menu, SIGNAL(gameSelected()), owner->thisPublic, SIGNAL(gameSessionSelected())); + QObject::connect(menu, SIGNAL(availabilityChanged()), owner->thisPublic, SLOT(updateSubsetLayout())); break; } @@ -125,6 +127,18 @@ DENG_GUI_PIMPL(GameSelectionWidget) { return menu->itemWidget(item); } + + void preparePanelForOpening() + { + FoldPanelWidget::preparePanelForOpening(); + title().setText(titleText); + } + + void panelClosing() + { + FoldPanelWidget::panelClosing(); + title().setText(QString("%1 (%2)").arg(titleText).arg(menu->items().size())); + } }; FIFO pendingGames; @@ -154,14 +168,7 @@ DENG_GUI_PIMPL(GameSelectionWidget) available->title().margins().setTop(""); - superLayout << available->title() - << *available - << multi->title() - << *multi - << incomplete->title() - << *incomplete; - - self.setContentSize(superLayout.width(), superLayout.height()); + updateSubsetLayout(); App_Games().audienceForAddition += this; App::app().audienceForStartupComplete += this; @@ -173,6 +180,33 @@ DENG_GUI_PIMPL(GameSelectionWidget) App::app().audienceForStartupComplete -= this; } + /** + * Subsets are visible only when they have games in them. The title and content + * of a subset are hidden when empty. + */ + void updateSubsetLayout() + { + superLayout.clear(); + + QList order; + order << available << multi << incomplete; + + foreach(Subset *s, order) + { + if(!s->items().isEmpty()) + { + s->title().show(); + superLayout << s->title() << *s; + } + else + { + s->title().hide(); + } + } + + self.setContentSize(superLayout.width(), superLayout.height()); + } + void gameAdded(Game &game) { // Called from a non-UI thread. @@ -206,6 +240,7 @@ DENG_GUI_PIMPL(GameSelectionWidget) } sortGames(); + updateSubsetLayout(); } struct LoadGameAction : public CommandAction @@ -319,6 +354,7 @@ DENG_GUI_PIMPL(GameSelectionWidget) } sortGames(); + updateSubsetLayout(); } void updateLayoutForWidth(int width) @@ -369,3 +405,8 @@ void GameSelectionWidget::update() d->updateLayoutForWidth(rect.width()); } } + +void GameSelectionWidget::updateSubsetLayout() +{ + d->updateSubsetLayout(); +} diff --git a/doomsday/client/src/ui/widgets/mpselectionwidget.cpp b/doomsday/client/src/ui/widgets/mpselectionwidget.cpp index 754dbdd9b5..feacaf4058 100644 --- a/doomsday/client/src/ui/widgets/mpselectionwidget.cpp +++ b/doomsday/client/src/ui/widgets/mpselectionwidget.cpp @@ -182,6 +182,8 @@ DENG_GUI_PIMPL(MPSelectionWidget) void linkDiscoveryUpdate(ServerLink const &link) { + bool changed = false; + // Remove obsolete entries. for(ui::Data::Pos idx = 0; idx < self.items().size(); ++idx) { @@ -189,6 +191,7 @@ DENG_GUI_PIMPL(MPSelectionWidget) if(!link.isFound(Address::parse(id))) { self.items().remove(idx--); + changed = true; } } @@ -203,6 +206,7 @@ DENG_GUI_PIMPL(MPSelectionWidget) { // Needs to be added. self.items().append(new ServerListItem(info)); + changed = true; } else { @@ -210,18 +214,14 @@ DENG_GUI_PIMPL(MPSelectionWidget) self.items().at(found).as().setInfo(info); } } - } - - /* - void updateLayoutForWidth(int width) - { - // If the view is too small, we'll want to reduce the number of items in the menu. - int const maxWidth = style().rules().rule("mpselection.max.width").valuei(); - qDebug() << maxWidth << width; - - int suitable = clamp(1, 3 * width / maxWidth, 3); - }*/ + if(changed) + { + // Let others know that one or more games have appeared or disappeared + // from the menu. + emit self.availabilityChanged(); + } + } }; MPSelectionWidget::MPSelectionWidget() From 78f813052db1607c45a203527f733bc00cd4caf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Wed, 5 Feb 2014 16:14:48 +0200 Subject: [PATCH 096/106] UI|Client: Game selection menu behaves differently when game loaded Order groups differently and use different titles. --- .../src/ui/widgets/gameselectionwidget.cpp | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp index 209511f6b1..c1f2dac8b5 100644 --- a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp +++ b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp @@ -128,16 +128,27 @@ DENG_GUI_PIMPL(GameSelectionWidget) return menu->itemWidget(item); } + String textForTitle(bool whenOpen) const + { + if(whenOpen) return titleText; + return QString("%1 (%2)").arg(titleText).arg(menu->items().size()); + } + void preparePanelForOpening() { FoldPanelWidget::preparePanelForOpening(); - title().setText(titleText); + title().setText(textForTitle(true)); } void panelClosing() { FoldPanelWidget::panelClosing(); - title().setText(QString("%1 (%2)").arg(titleText).arg(menu->items().size())); + title().setText(textForTitle(false)); + } + + void updateTitleText() + { + title().setText(textForTitle(isOpen())); } }; @@ -154,7 +165,7 @@ DENG_GUI_PIMPL(GameSelectionWidget) { // Menu of available games. self.add(available = new Subset(Subset::NormalGames, - tr("Available Games"), this)); + App_GameLoaded()? tr("Switch Game") : tr("Available Games"), this)); // Menu of incomplete games. self.add(incomplete = new Subset(Subset::NormalGames, @@ -166,8 +177,6 @@ DENG_GUI_PIMPL(GameSelectionWidget) superLayout.setOverrideWidth(self.rule().width() - self.margins().width()); - available->title().margins().setTop(""); - updateSubsetLayout(); App_Games().audienceForAddition += this; @@ -189,12 +198,23 @@ DENG_GUI_PIMPL(GameSelectionWidget) superLayout.clear(); QList order; - order << available << multi << incomplete; + if(!App_GameLoaded()) + { + order << available << multi << incomplete; + } + else + { + order << multi << available << incomplete; + } foreach(Subset *s, order) { + // The first group should not have extra space above it. + s->title().margins().setTop(s == order.first()? "" : "gap"); + if(!s->items().isEmpty()) { + s->updateTitleText(); s->title().show(); superLayout << s->title() << *s; } From 0836ce87897b548c7ff36c1f17de92a928daad6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Wed, 5 Feb 2014 18:27:33 +0200 Subject: [PATCH 097/106] libappfw|ButtonWidget: Button text hover coloring modes Buttons can now have a hover text color applied in two different ways: replacing the normal color, or modulating with it. --- .../include/de/widgets/buttonwidget.h | 7 +++- .../libappfw/src/widgets/buttonwidget.cpp | 32 +++++++++++++++++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/doomsday/libappfw/include/de/widgets/buttonwidget.h b/doomsday/libappfw/include/de/widgets/buttonwidget.h index 9312a8fa89..491b1df6d9 100644 --- a/doomsday/libappfw/include/de/widgets/buttonwidget.h +++ b/doomsday/libappfw/include/de/widgets/buttonwidget.h @@ -61,13 +61,18 @@ class LIBAPPFW_PUBLIC ButtonWidget : public LabelWidget public: ButtonWidget(String const &name = ""); + enum HoverColorMode { + ReplaceColor, + ModulateColor + }; + /** * Text color to use in the Hover state. The default is to use the normal text * color of the button (label). * * @param hoverTextId Style color identifier. */ - void setHoverTextColor(DotPath const &hoverTextId); + void setHoverTextColor(DotPath const &hoverTextId, HoverColorMode mode = ModulateColor); /** * Sets the action of the button. It gets triggered when the button is diff --git a/doomsday/libappfw/src/widgets/buttonwidget.cpp b/doomsday/libappfw/src/widgets/buttonwidget.cpp index eee7b0aff0..9e6fcf65dc 100644 --- a/doomsday/libappfw/src/widgets/buttonwidget.cpp +++ b/doomsday/libappfw/src/widgets/buttonwidget.cpp @@ -29,6 +29,8 @@ DENG2_OBSERVES(Action, Triggered) { State state; DotPath hoverTextColor; + DotPath originalTextColor; + HoverColorMode hoverColorMode; Action *action; Animation scale; Animation frameOpacity; @@ -37,6 +39,7 @@ DENG2_OBSERVES(Action, Triggered) Instance(Public *i) : Base(i) , state(Up) + , hoverColorMode(Replace) , action(0) , scale(1.f) , frameOpacity(.08f, Animation::Linear) @@ -55,6 +58,12 @@ DENG2_OBSERVES(Action, Triggered) { if(state == st) return; + if(st == Hover && state == Up) + { + // Remember the original text color. + originalTextColor = self.textColorId(); + } + State const prev = state; state = st; animating = true; @@ -68,7 +77,15 @@ DENG2_OBSERVES(Action, Triggered) if(!hoverTextColor.isEmpty()) { // Restore old color. - self.setTextModulationColorf(Vector4f(1, 1, 1, 1)); + switch(hoverColorMode) + { + case Modulate: + self.setTextModulationColorf(Vector4f(1, 1, 1, 1)); + break; + case Replace: + self.setTextColor(originalTextColor); + break; + } } break; @@ -76,7 +93,15 @@ DENG2_OBSERVES(Action, Triggered) frameOpacity.setValue(.4f, .15f); if(!hoverTextColor.isEmpty()) { - self.setTextModulationColorf(style().colors().colorf(hoverTextColor)); + switch(hoverColorMode) + { + case Modulate: + self.setTextModulationColorf(style().colors().colorf(hoverTextColor)); + break; + case Replace: + self.setTextColor(hoverTextColor); + break; + } } break; @@ -153,9 +178,10 @@ DENG2_OBSERVES(Action, Triggered) ButtonWidget::ButtonWidget(String const &name) : LabelWidget(name), d(new Instance(this)) {} -void ButtonWidget::setHoverTextColor(DotPath const &hoverTextId) +void ButtonWidget::setHoverTextColor(DotPath const &hoverTextId, HoverColorMode mode) { d->hoverTextColor = hoverTextId; + d->hoverColorMode = mode; } void ButtonWidget::setAction(RefArg action) From d9a960b8efdded5aeeccbad660985121e26d31ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Wed, 5 Feb 2014 18:28:52 +0200 Subject: [PATCH 098/106] Fixed|UI|Client: Fold title hover coloring Fold title hover coloring (e.g., in the Renderer Appearance editor) has been broken since ButtonWidget was changed to apply hover color with modulation. Now fold titles are specifically requested to use a replacement color. --- .../include/ui/widgets/gameselectionwidget.h | 6 +++- .../client/src/ui/dialogs/gamesdialog.cpp | 3 +- .../ui/editors/rendererappearanceeditor.cpp | 1 + .../src/ui/widgets/gameselectionwidget.cpp | 34 ++++++++++++++++--- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/doomsday/client/include/ui/widgets/gameselectionwidget.h b/doomsday/client/include/ui/widgets/gameselectionwidget.h index fe37b31d19..6b9662b703 100644 --- a/doomsday/client/include/ui/widgets/gameselectionwidget.h +++ b/doomsday/client/include/ui/widgets/gameselectionwidget.h @@ -20,6 +20,7 @@ #define DENG_CLIENT_GAMESELECTIONWIDGET_H #include +#include /** * Menu for selecting @@ -31,7 +32,10 @@ class GameSelectionWidget : public de::ScrollAreaWidget public: GameSelectionWidget(de::String const &name = "gameselection"); - void setTitleColor(de::DotPath const &colorId); + void setTitleColor(de::DotPath const &colorId, + de::DotPath const &hoverColorId, + de::ButtonWidget::HoverColorMode mode = de::ButtonWidget::ModulateColor); + void setTitleFont(de::DotPath const &fontId); // Events. void update(); diff --git a/doomsday/client/src/ui/dialogs/gamesdialog.cpp b/doomsday/client/src/ui/dialogs/gamesdialog.cpp index f0f3b2f125..3c9e3a827a 100644 --- a/doomsday/client/src/ui/dialogs/gamesdialog.cpp +++ b/doomsday/client/src/ui/dialogs/gamesdialog.cpp @@ -35,7 +35,8 @@ DENG_GUI_PIMPL(GamesDialog) self.area().add(gameSel = new GameSelectionWidget("games")); gameSel->enableScrolling(false); - gameSel->setTitleColor("text"); + gameSel->setTitleFont("heading"); + gameSel->setTitleColor("accent", "text", ButtonWidget::ReplaceColor); gameSel->rule().setInput(Rule::Height, gameSel->contentRule().height()); } }; diff --git a/doomsday/client/src/ui/editors/rendererappearanceeditor.cpp b/doomsday/client/src/ui/editors/rendererappearanceeditor.cpp index 6fe24e100c..43a592c725 100644 --- a/doomsday/client/src/ui/editors/rendererappearanceeditor.cpp +++ b/doomsday/client/src/ui/editors/rendererappearanceeditor.cpp @@ -97,6 +97,7 @@ DENG2_OBSERVES(App, GameChange) makeTitle(titleText); title().setText(titleText); title().setTextColor("accent"); + title().setHoverTextColor("text", ButtonWidget::ReplaceColor); // Set up a context menu for right-clicking. title().addEventHandler(new RightClickHandler(d)); diff --git a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp index c1f2dac8b5..6514fb6ad0 100644 --- a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp +++ b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp @@ -40,6 +40,7 @@ using namespace de; DENG_GUI_PIMPL(GameSelectionWidget) , DENG2_OBSERVES(Games, Addition) , DENG2_OBSERVES(App, StartupComplete) +, DENG2_OBSERVES(App, GameChange) , public ChildWidgetOrganizer::IWidgetFactory { /// ActionItem with a Game member, for loading a particular game. @@ -181,12 +182,14 @@ DENG_GUI_PIMPL(GameSelectionWidget) App_Games().audienceForAddition += this; App::app().audienceForStartupComplete += this; + App::app().audienceForGameChange += this; } ~Instance() { App_Games().audienceForAddition -= this; App::app().audienceForStartupComplete -= this; + App::app().audienceForGameChange -= this; } /** @@ -210,7 +213,8 @@ DENG_GUI_PIMPL(GameSelectionWidget) foreach(Subset *s, order) { // The first group should not have extra space above it. - s->title().margins().setTop(s == order.first()? "" : "gap"); + s->title().margins().setTop(""); + if(s != order.first()) superLayout << style().rules().rule("gap"); if(!s->items().isEmpty()) { @@ -227,6 +231,11 @@ DENG_GUI_PIMPL(GameSelectionWidget) self.setContentSize(superLayout.width(), superLayout.height()); } + void currentGameChanged(game::Game const &) + { + updateSubsetLayout(); + } + void gameAdded(Game &game) { // Called from a non-UI thread. @@ -393,9 +402,12 @@ DENG_GUI_PIMPL(GameSelectionWidget) GameSelectionWidget::GameSelectionWidget(String const &name) : ScrollAreaWidget(name), d(new Instance(this)) { - d->available->open(); d->multi->open(); - d->incomplete->open(); + if(!App_GameLoaded()) + { + d->available->open(); + d->incomplete->open(); + } // We want the full menu to be visible even when it doesn't fit the // designated area. @@ -405,11 +417,25 @@ GameSelectionWidget::GameSelectionWidget(String const &name) d->addExistingGames(); } -void GameSelectionWidget::setTitleColor(DotPath const &colorId) +void GameSelectionWidget::setTitleColor(DotPath const &colorId, + DotPath const &hoverColorId, + ButtonWidget::HoverColorMode mode) { d->available->title().setTextColor(colorId); + d->available->title().setHoverTextColor(hoverColorId, mode); + d->multi->title().setTextColor(colorId); + d->multi->title().setHoverTextColor(hoverColorId, mode); + d->incomplete->title().setTextColor(colorId); + d->incomplete->title().setHoverTextColor(hoverColorId, mode); +} + +void GameSelectionWidget::setTitleFont(DotPath const &fontId) +{ + d->available->title().setFont(fontId); + d->multi->title().setFont(fontId); + d->incomplete->title().setFont(fontId); } void GameSelectionWidget::update() From f0bce31230ef42e8a5752d9819d6677d48fb3c1c Mon Sep 17 00:00:00 2001 From: danij Date: Wed, 5 Feb 2014 17:15:27 +0000 Subject: [PATCH 099/106] libappfw: Fix build (refactoring oversight) --- doomsday/libappfw/src/widgets/buttonwidget.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doomsday/libappfw/src/widgets/buttonwidget.cpp b/doomsday/libappfw/src/widgets/buttonwidget.cpp index 9e6fcf65dc..a0d45f0510 100644 --- a/doomsday/libappfw/src/widgets/buttonwidget.cpp +++ b/doomsday/libappfw/src/widgets/buttonwidget.cpp @@ -39,7 +39,7 @@ DENG2_OBSERVES(Action, Triggered) Instance(Public *i) : Base(i) , state(Up) - , hoverColorMode(Replace) + , hoverColorMode(ReplaceColor) , action(0) , scale(1.f) , frameOpacity(.08f, Animation::Linear) @@ -79,10 +79,10 @@ DENG2_OBSERVES(Action, Triggered) // Restore old color. switch(hoverColorMode) { - case Modulate: + case ModulateColor: self.setTextModulationColorf(Vector4f(1, 1, 1, 1)); break; - case Replace: + case ReplaceColor: self.setTextColor(originalTextColor); break; } @@ -95,10 +95,10 @@ DENG2_OBSERVES(Action, Triggered) { switch(hoverColorMode) { - case Modulate: + case ModulateColor: self.setTextModulationColorf(style().colors().colorf(hoverTextColor)); break; - case Replace: + case ReplaceColor: self.setTextColor(hoverTextColor); break; } From 5f8509561dee3bbbd7547e1c3336f25717738933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Wed, 5 Feb 2014 19:39:51 +0200 Subject: [PATCH 100/106] Cleanup --- .../client/src/ui/editors/rendererappearanceeditor.cpp | 3 --- doomsday/client/src/ui/widgets/gameselectionwidget.cpp | 1 + doomsday/libappfw/src/widgets/foldpanelwidget.cpp | 7 ++++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/doomsday/client/src/ui/editors/rendererappearanceeditor.cpp b/doomsday/client/src/ui/editors/rendererappearanceeditor.cpp index 43a592c725..ba9513528f 100644 --- a/doomsday/client/src/ui/editors/rendererappearanceeditor.cpp +++ b/doomsday/client/src/ui/editors/rendererappearanceeditor.cpp @@ -95,9 +95,6 @@ DENG2_OBSERVES(App, GameChange) _group = new GuiWidget; setContent(_group); makeTitle(titleText); - title().setText(titleText); - title().setTextColor("accent"); - title().setHoverTextColor("text", ButtonWidget::ReplaceColor); // Set up a context menu for right-clicking. title().addEventHandler(new RightClickHandler(d)); diff --git a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp index 6514fb6ad0..5169f19d21 100644 --- a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp +++ b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp @@ -83,6 +83,7 @@ DENG_GUI_PIMPL(GameSelectionWidget) owner->self.add(makeTitle(headingText)); title().setFont("title"); title().setTextColor("inverted.text"); + title().setHoverTextColor("inverted.accent", ButtonWidget::ReplaceColor); title().setAlignment(ui::AlignLeft); title().margins().setLeft(""); diff --git a/doomsday/libappfw/src/widgets/foldpanelwidget.cpp b/doomsday/libappfw/src/widgets/foldpanelwidget.cpp index 330e38a340..f07a235699 100644 --- a/doomsday/libappfw/src/widgets/foldpanelwidget.cpp +++ b/doomsday/libappfw/src/widgets/foldpanelwidget.cpp @@ -75,11 +75,12 @@ ButtonWidget *FoldPanelWidget::makeTitle(String const &text) { d->title = new ButtonWidget; - d->title->setText(text); d->title->setSizePolicy(Expand, Expand); - d->title->set(Background()); // no frame or background - d->title->setHoverTextColor("text"); + d->title->setText(text); + d->title->setTextColor("accent"); + d->title->setHoverTextColor("text", ButtonWidget::ReplaceColor); d->title->setFont("heading"); + d->title->set(Background()); // no frame or background d->title->setAction(new SignalAction(this, SLOT(toggleFold()))); d->title->setOpacity(.8f); From 7884ced65881aab712c52cbe40dc84078d0a838f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Wed, 5 Feb 2014 19:54:07 +0200 Subject: [PATCH 101/106] UI|Task Bar: Moved "Unload Game" next to "Games..." --- doomsday/client/src/ui/widgets/taskbarwidget.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doomsday/client/src/ui/widgets/taskbarwidget.cpp b/doomsday/client/src/ui/widgets/taskbarwidget.cpp index 76eb7d2ac7..3a412778dd 100644 --- a/doomsday/client/src/ui/widgets/taskbarwidget.cpp +++ b/doomsday/client/src/ui/widgets/taskbarwidget.cpp @@ -60,8 +60,8 @@ enum MenuItemPositions { // DE menu: POS_GAMES = 0, - POS_GAMES_SEPARATOR = 1, - POS_UNLOAD = 5, + POS_UNLOAD = 1, + POS_GAMES_SEPARATOR = 2, // Config menu: POS_RENDERER_SETTINGS = 0, @@ -260,8 +260,8 @@ DENG_GUI_PIMPL(TaskBarWidget) updateStatus(); itemWidget(mainMenu, POS_GAMES) .show(!newGame.isNull()); - itemWidget(mainMenu, POS_GAMES_SEPARATOR).show(!newGame.isNull()); itemWidget(mainMenu, POS_UNLOAD) .show(!newGame.isNull()); + itemWidget(mainMenu, POS_GAMES_SEPARATOR).show(!newGame.isNull()); itemWidget(configMenu, POS_RENDERER_SETTINGS).show(!newGame.isNull()); itemWidget(configMenu, POS_VR_SETTINGS) .show(!newGame.isNull()); @@ -408,16 +408,16 @@ TaskBarWidget::TaskBarWidget() : GuiWidget("taskbar"), d(new Instance(this)) d->mainMenu->items() << new ui::ActionItem(tr("Games..."), new SignalAction(this, SLOT(showGames()))) + << unloadMenu // hidden with null-game << new ui::Item(ui::Item::Separator) << new ui::ActionItem(tr("Check for Updates..."), new CommandAction("updateandnotify")) << new ui::ActionItem(tr("About Doomsday"), new SignalAction(this, SLOT(showAbout()))) << new ui::Item(ui::Item::Separator) - << unloadMenu // hidden with null-game << new ui::ActionItem(tr("Quit Doomsday"), new CommandAction("quit")); d->itemWidget(d->mainMenu, POS_GAMES).hide(); - d->itemWidget(d->mainMenu, POS_GAMES_SEPARATOR).hide(); d->itemWidget(d->mainMenu, POS_UNLOAD).hide(); + d->itemWidget(d->mainMenu, POS_GAMES_SEPARATOR).hide(); d->itemWidget(d->configMenu, POS_RENDERER_SETTINGS).hide(); d->itemWidget(d->configMenu, POS_VR_SETTINGS).hide(); From 94bfb43999a70abd04d91441150e5ad286278ad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Wed, 5 Feb 2014 20:55:54 +0200 Subject: [PATCH 102/106] Client|UI|Network: Game selection menu fetches games from master server The client's ServerFinder can now fetch servers from the master server. Currently this is done when MPSelectionWidget is created, however it should also be doable manually. --- doomsday/client/include/network/serverlink.h | 5 ++ doomsday/client/src/network/masterserver.cpp | 2 +- doomsday/client/src/network/serverlink.cpp | 66 +++++++++++++++++-- .../src/ui/widgets/gameselectionwidget.cpp | 2 +- .../src/ui/widgets/mpselectionwidget.cpp | 2 + 5 files changed, 69 insertions(+), 8 deletions(-) diff --git a/doomsday/client/include/network/serverlink.h b/doomsday/client/include/network/serverlink.h index 9202d3896d..0c99046a40 100644 --- a/doomsday/client/include/network/serverlink.h +++ b/doomsday/client/include/network/serverlink.h @@ -61,6 +61,11 @@ class ServerLink : public de::shell::AbstractLink */ void discover(de::String const &domain); + /** + * Asks the master server for information about currently running servers. + */ + void discoverUsingMaster(); + bool isDiscovering() const; int foundServerCount() const; diff --git a/doomsday/client/src/network/masterserver.cpp b/doomsday/client/src/network/masterserver.cpp index 682d3510de..7bbac7f76b 100644 --- a/doomsday/client/src/network/masterserver.cpp +++ b/doomsday/client/src/network/masterserver.cpp @@ -241,7 +241,7 @@ bool MasterWorker::parseResponse(const QByteArray& response) } } - LOG_NET_MSG("Received %i servers") << serverCount(); + LOG_NET_MSG("Received %i servers from master") << serverCount(); Str_Free(&line); Str_Free(&msg); diff --git a/doomsday/client/src/network/serverlink.cpp b/doomsday/client/src/network/serverlink.cpp index 69db720e58..0b1bcb7aae 100644 --- a/doomsday/client/src/network/serverlink.cpp +++ b/doomsday/client/src/network/serverlink.cpp @@ -18,14 +18,18 @@ #include "de_platform.h" #include "network/serverlink.h" - +#include "network/masterserver.h" #include "network/net_main.h" #include "network/net_buf.h" #include "network/net_demo.h" +#include "network/net_event.h" #include "network/protocol.h" #include "client/cl_def.h" #include "dd_def.h" + +#include #include +#include #include #include #include @@ -45,19 +49,25 @@ enum LinkState }; DENG2_PIMPL(ServerLink) +, DENG2_OBSERVES(Loop, Iteration) { shell::ServerFinder finder; ///< Finding local servers. LinkState state; + bool fetching; typedef QMap Servers; Servers discovered; + Servers fromMaster; Instance(Public *i) - : Base(i), - state(None) + : Base(i) + , state(None) + , fetching(false) {} ~Instance() - {} + { + Loop::appLoop().audienceForIteration -= this; + } void notifyDiscoveryUpdate() { @@ -166,12 +176,50 @@ DENG2_PIMPL(ServerLink) return true; } + void fetchFromMaster() + { + if(fetching) return; + + fetching = true; + N_MAPost(MAC_REQUEST); + N_MAPost(MAC_WAIT); + Loop::appLoop().audienceForIteration += this; + } + + void loopIteration() + { + DENG2_ASSERT(fetching); + + if(N_MADone()) + { + fetching = false; + Loop::appLoop().audienceForIteration -= this; + + fromMaster.clear(); + int const count = N_MasterGet(0, 0); + for(int i = 0; i < count; i++) + { + serverinfo_t info; + N_MasterGet(i, &info); + fromMaster.insert(Address::parse(info.address, info.port), info); + } + + notifyDiscoveryUpdate(); + } + } + Servers allFound() const { Servers all = discovered; + // Append from master (if available). + DENG2_FOR_EACH_CONST(Servers, i, fromMaster) + { + all.insert(i.key(), i.value()); + } + // Append the ones from the server finder. - foreach(Address sv, finder.foundServers()) + foreach(Address const &sv, finder.foundServers()) { serverinfo_t info; ServerInfo_FromRecord(&info, finder.messageFromServer(sv)); @@ -271,9 +319,15 @@ void ServerLink::discover(String const &domain) d->state = Discovering; } +void ServerLink::discoverUsingMaster() +{ + d->fetchFromMaster(); +} + bool ServerLink::isDiscovering() const { - return (d->state == Discovering || d->state == WaitingForInfoResponse); + return (d->state == Discovering || d->state == WaitingForInfoResponse || + d->fetching); } int ServerLink::foundServerCount() const diff --git a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp index 5169f19d21..d672b918a9 100644 --- a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp +++ b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp @@ -83,7 +83,7 @@ DENG_GUI_PIMPL(GameSelectionWidget) owner->self.add(makeTitle(headingText)); title().setFont("title"); title().setTextColor("inverted.text"); - title().setHoverTextColor("inverted.accent", ButtonWidget::ReplaceColor); + title().setHoverTextColor("inverted.text", ButtonWidget::ReplaceColor); title().setAlignment(ui::AlignLeft); title().margins().setLeft(""); diff --git a/doomsday/client/src/ui/widgets/mpselectionwidget.cpp b/doomsday/client/src/ui/widgets/mpselectionwidget.cpp index feacaf4058..8bc0c93010 100644 --- a/doomsday/client/src/ui/widgets/mpselectionwidget.cpp +++ b/doomsday/client/src/ui/widgets/mpselectionwidget.cpp @@ -228,6 +228,8 @@ MPSelectionWidget::MPSelectionWidget() : MenuWidget("mp-selection"), d(new Instance(this)) { setGridSize(3, ui::Filled, 0, ui::Expand); + + d->link().discoverUsingMaster(); } void MPSelectionWidget::setColumns(int numberOfColumns) From 82e8c4b6ad602c6a1d95f32b11edbb17875c81b7 Mon Sep 17 00:00:00 2001 From: danij Date: Wed, 5 Feb 2014 20:14:15 +0000 Subject: [PATCH 103/106] libcommon|SaveInfo: Added method of returning the current map URI from SaveInfo --- doomsday/plugins/common/include/saveinfo.h | 29 +++++++++++++--------- doomsday/plugins/common/src/p_saveg.cpp | 4 +-- doomsday/plugins/common/src/saveinfo.cpp | 27 ++++++++++++++------ doomsday/plugins/doom/src/p_oldsvg.cpp | 1 + doomsday/plugins/heretic/src/p_oldsvg.cpp | 2 ++ 5 files changed, 42 insertions(+), 21 deletions(-) diff --git a/doomsday/plugins/common/include/saveinfo.h b/doomsday/plugins/common/include/saveinfo.h index 3756dcfc26..fca01947d2 100644 --- a/doomsday/plugins/common/include/saveinfo.h +++ b/doomsday/plugins/common/include/saveinfo.h @@ -36,8 +36,9 @@ class SaveInfo int _magic; int _version; gamemode_t _gameMode; - byte _episode; - byte _map; + uint _episode; + uint _map; + Uri *_mapUri; ///< Not currently saved. #if !__JHEXEN__ int _mapTime; byte _players[MAXPLAYERS]; @@ -51,7 +52,12 @@ class SaveInfo SaveInfo &operator = (SaveInfo const &other); - void configure(); + /** + * Update the metadata associated with the save using values derived from the + * current game session. Note that this does @em not affect the copy of this save + * on disk. + */ + void applyCurrentSessionMetadata(); /** * Determines whether the saved game session is compatibile with the current @@ -63,7 +69,6 @@ class SaveInfo * Returns the logical version of the serialized game session state. */ int version() const; - int magic() const; /** * Returns the textual description of the game session (provided by the user). @@ -78,18 +83,13 @@ class SaveInfo void setGameId(uint newGameId); /** - * Returns the logical episode number for the game session. - */ - uint episode() const; - - /** - * Returns the logical map number for the game session. + * Returns the URI of the @em current map of the game session. */ - uint map() const; + Uri const *mapUri() const; #if !__JHEXEN__ /** - * Returns the expired time in tics since the map begun. + * Returns the expired time in tics since the @em current map of the game session began. */ int mapTime() const; #endif @@ -115,6 +115,11 @@ class SaveInfo #if __JHEXEN__ void read_Hx_v9(Reader *reader); #endif + +public: /// @todo refactor away: + int magic() const; + uint episode() const; + uint map() const; }; #endif // __cplusplus diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index 1f2918a8db..71946248cf 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -3931,7 +3931,7 @@ void SV_SaveGameClient(uint gameId) // Prepare the header. SaveInfo *info = new SaveInfo; info->setGameId(gameId); - info->configure(); + info->applyCurrentSessionMetadata(); Writer *writer = SV_NewWriter(); info->write(writer); @@ -4158,7 +4158,7 @@ static SaveInfo *createSaveInfo(char const *name) SaveInfo *info = new SaveInfo; info->setDescription(Str_InitStatic(&nameStr, name)); info->setGameId(SV_GenerateGameId()); - info->configure(); + info->applyCurrentSessionMetadata(); return info; } diff --git a/doomsday/plugins/common/src/saveinfo.cpp b/doomsday/plugins/common/src/saveinfo.cpp index 0eddf9ae89..44f79e6b39 100644 --- a/doomsday/plugins/common/src/saveinfo.cpp +++ b/doomsday/plugins/common/src/saveinfo.cpp @@ -21,6 +21,7 @@ #include "common.h" #include "saveinfo.h" +#include "g_common.h" #include "p_tick.h" #include "p_saveg.h" #include "p_saveio.h" @@ -78,6 +79,7 @@ SaveInfo::SaveInfo() , _gameMode(NUM_GAME_MODES) , _episode (0) , _map (0) + , _mapUri (Uri_New()) #if !__JHEXEN__ , _mapTime (0) #endif @@ -101,6 +103,7 @@ SaveInfo::SaveInfo(SaveInfo const &other) #endif { Str_Copy(Str_InitStd(&_description), &other._description); + Uri_Copy(_mapUri, other._mapUri); #if !__JHEXEN__ std::memcpy(&_players, &other._players, sizeof(_players)); #endif @@ -110,6 +113,7 @@ SaveInfo::SaveInfo(SaveInfo const &other) SaveInfo::~SaveInfo() { Str_Free(&_description); + Uri_Delete(_mapUri); } SaveInfo &SaveInfo::operator = (SaveInfo const &other) @@ -121,6 +125,7 @@ SaveInfo &SaveInfo::operator = (SaveInfo const &other) _gameMode = other._gameMode; _episode = other._episode; _map = other._map; + Uri_Copy(_mapUri, other._mapUri); #if !__JHEXEN__ _mapTime = other._mapTime; std::memcpy(&_players, &other._players, sizeof(_players)); @@ -169,6 +174,11 @@ uint SaveInfo::map() const return _map; } +Uri const *SaveInfo::mapUri() const +{ + return _mapUri; +} + #if !__JHEXEN__ int SaveInfo::mapTime() const { @@ -181,18 +191,17 @@ GameRuleset const &SaveInfo::gameRules() const return _gameRules; } -void SaveInfo::configure() +void SaveInfo::applyCurrentSessionMetadata() { _magic = IS_NETWORK_CLIENT? MY_CLIENT_SAVE_MAGIC : MY_SAVE_MAGIC; _version = MY_SAVE_VERSION; _gameMode = gameMode; -#if __JHEXEN__ - _episode = 1; -#else _episode = gameEpisode; + _map = gameMap; + Uri_Copy(_mapUri, G_ComposeMapUri(_episode, _map)); +#if !__JHEXEN__ _mapTime = ::mapTime; #endif - _map = gameMap; // Make a copy of the current game rules. _gameRules = ::gameRules; @@ -265,6 +274,7 @@ void SaveInfo::read(Reader *reader) { _episode = Reader_ReadByte(reader); _map = Reader_ReadByte(reader); + Uri_Copy(_mapUri, G_ComposeMapUri(_episode, _map)); #if !__JHEXEN__ _mapTime = Reader_ReadInt32(reader); #endif @@ -307,6 +317,7 @@ void SaveInfo::read(Reader *reader) _episode = Reader_ReadByte(reader) - 1; _map = Reader_ReadByte(reader) - 1; + Uri_Copy(_mapUri, G_ComposeMapUri(_episode, _map)); _gameRules.deathmatch = Reader_ReadByte(reader); #if !__JHEXEN__ @@ -361,11 +372,13 @@ void SaveInfo::read_Hx_v9(Reader *reader) /*Skip junk*/ SV_Seek(4); - _episode = 1; - _map = Reader_ReadByte(reader); _magic = MY_SAVE_MAGIC; // Lets pretend... _gameMode = gameMode; // Assume the current mode. + _episode = 0; + _map = Reader_ReadByte(reader) - 1; + Uri_Copy(_mapUri, G_ComposeMapUri(_episode, _map)); + _gameRules.skill = (skillmode_t) (Reader_ReadByte(reader) & 0x7f); // Interpret skill modes outside the normal range as "spawn no things". diff --git a/doomsday/plugins/doom/src/p_oldsvg.cpp b/doomsday/plugins/doom/src/p_oldsvg.cpp index efaad72869..f929cc3bb3 100644 --- a/doomsday/plugins/doom/src/p_oldsvg.cpp +++ b/doomsday/plugins/doom/src/p_oldsvg.cpp @@ -897,6 +897,7 @@ static void SaveInfo_Read_Dm_v19(SaveInfo *info, Reader *reader) info->_episode = Reader_ReadByte(reader) - 1; info->_map = Reader_ReadByte(reader) - 1; + Uri_Copy(info->_mapUri, G_ComposeMapUri(info->_episode, info->_map)); for(int i = 0; i < 4; ++i) { diff --git a/doomsday/plugins/heretic/src/p_oldsvg.cpp b/doomsday/plugins/heretic/src/p_oldsvg.cpp index 32f8533ae5..64e0fa430f 100644 --- a/doomsday/plugins/heretic/src/p_oldsvg.cpp +++ b/doomsday/plugins/heretic/src/p_oldsvg.cpp @@ -916,6 +916,8 @@ static void SaveInfo_Read_Hr_v13(SaveInfo *info, Reader *reader) info->_episode = Reader_ReadByte(reader) - 1; info->_map = Reader_ReadByte(reader) - 1; + Uri_Copy(info->_mapUri, G_ComposeMapUri(info->_episode, info->_map)); + for(int i = 0; i < 4; ++i) { info->_players[i] = Reader_ReadByte(reader); From ae649711739a0dca4a07e9434234c3b38f103a87 Mon Sep 17 00:00:00 2001 From: skyjake Date: Thu, 6 Feb 2014 14:47:16 +0200 Subject: [PATCH 104/106] Fixed|qmake|OS X: Using the OpenGL framework in Snow Leopard In the 10.6 build, OpenGL headers were accessed from the X11 include directory even though the correct headers are in the OpenGL framework. --- doomsday/client/include/gl/sys_opengl.h | 11 +++-------- doomsday/config_macx.pri | 1 - 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/doomsday/client/include/gl/sys_opengl.h b/doomsday/client/include/gl/sys_opengl.h index 2d801cc700..297ce43049 100644 --- a/doomsday/client/include/gl/sys_opengl.h +++ b/doomsday/client/include/gl/sys_opengl.h @@ -46,14 +46,9 @@ #if defined(UNIX) && defined(MACOSX) # define GL_GLEXT_PROTOTYPES -# if defined(MACOSX_NATIVESDK) || defined(MACOS_10_7) -# include -# include -# include -# else -# include -# include -# endif +# include +# include +# include # define GL_CALL #endif diff --git a/doomsday/config_macx.pri b/doomsday/config_macx.pri index ca885de08f..0bdb7f30a3 100644 --- a/doomsday/config_macx.pri +++ b/doomsday/config_macx.pri @@ -64,7 +64,6 @@ else:deng_macx6_32bit_64bit { QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.5 QMAKE_CFLAGS += -mmacosx-version-min=10.5 QMAKE_CXXFLAGS += -mmacosx-version-min=10.5 - INCLUDEPATH = $$QMAKE_MAC_SDK/usr/X11/include $$INCLUDEPATH } else:deng_nativesdk { echo(Using native SDK.) From ebfd5ed08a37b83999ef949d8252484a8b320a81 Mon Sep 17 00:00:00 2001 From: skyjake Date: Thu, 6 Feb 2014 14:49:16 +0200 Subject: [PATCH 105/106] Fixed|GCC: Build failure casting templated functions When applying a C style cast, gcc 4.2 loses track of some vital "contextual information" and fails to build these casts. de::function_cast<> seems to work around the issue. (gcc 4.2 is being used in Snow Leopard.) --- doomsday/plugins/common/src/p_saveg.cpp | 80 ++++++++++++------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/doomsday/plugins/common/src/p_saveg.cpp b/doomsday/plugins/common/src/p_saveg.cpp index 71946248cf..a6f0fe2ff1 100644 --- a/doomsday/plugins/common/src/p_saveg.cpp +++ b/doomsday/plugins/common/src/p_saveg.cpp @@ -190,8 +190,8 @@ static ThinkerClassInfo thinkerInfo[] = { TC_XGMOVER, (thinkfunc_t) XS_PlaneMover, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(xgplanemover_t) }, #endif @@ -199,32 +199,32 @@ static ThinkerClassInfo thinkerInfo[] = { TC_CEILING, T_MoveCeiling, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(ceiling_t) }, { TC_DOOR, T_Door, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(door_t) }, { TC_FLOOR, T_MoveFloor, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(floor_t) }, { TC_PLAT, T_PlatRaise, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(plat_t) }, #if __JHEXEN__ @@ -232,64 +232,64 @@ static ThinkerClassInfo thinkerInfo[] = { TC_INTERPRET_ACS, (thinkfunc_t) ACScript_Thinker, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(ACScript) }, { TC_FLOOR_WAGGLE, (thinkfunc_t) T_FloorWaggle, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(waggle_t) }, { TC_LIGHT, (thinkfunc_t) T_Light, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(light_t) }, { TC_PHASE, (thinkfunc_t) T_Phase, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(phase_t) }, { TC_BUILD_PILLAR, (thinkfunc_t) T_BuildPillar, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(pillar_t) }, { TC_ROTATE_POLY, T_RotatePoly, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(polyevent_t) }, { TC_MOVE_POLY, T_MovePoly, 0, - (WriteThinkerFunc)SV_WriteMovePoly, - (ReadThinkerFunc)SV_ReadMovePoly, + de::function_cast(SV_WriteMovePoly), + de::function_cast(SV_ReadMovePoly), sizeof(polyevent_t) }, { TC_POLY_DOOR, T_PolyDoor, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(polydoor_t) }, #else @@ -297,24 +297,24 @@ static ThinkerClassInfo thinkerInfo[] = { TC_FLASH, (thinkfunc_t) T_LightFlash, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(lightflash_s) }, { TC_STROBE, (thinkfunc_t) T_StrobeFlash, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(strobe_t) }, { TC_GLOW, (thinkfunc_t) T_Glow, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(glow_t) }, # if __JDOOM__ || __JDOOM64__ @@ -322,8 +322,8 @@ static ThinkerClassInfo thinkerInfo[] = { TC_FLICKER, (thinkfunc_t) T_FireFlicker, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(fireflicker_t) }, # endif @@ -332,8 +332,8 @@ static ThinkerClassInfo thinkerInfo[] = { TC_BLINK, (thinkfunc_t) T_LightBlink, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(lightblink_t) }, # endif @@ -342,16 +342,16 @@ static ThinkerClassInfo thinkerInfo[] = { TC_MATERIALCHANGER, T_MaterialChanger, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(materialchanger_s) }, { TC_SCROLL, (thinkfunc_t) T_Scroll, 0, - (WriteThinkerFunc)writeThinkerAs, - (ReadThinkerFunc)readThinkerAs, + de::function_cast(writeThinkerAs), + de::function_cast(readThinkerAs), sizeof(scroll_t) }, { TC_NULL, NULL, 0, NULL, NULL, 0 } From d3af95337ba57d99dafa4d84b81ff53767fd1a34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Thu, 6 Feb 2014 15:03:58 +0200 Subject: [PATCH 106/106] qmake|OS X: Using the OpenGL framework in Lion Untested, but should work. --- doomsday/config_macx.pri | 1 - 1 file changed, 1 deletion(-) diff --git a/doomsday/config_macx.pri b/doomsday/config_macx.pri index 0bdb7f30a3..d945b69fdd 100644 --- a/doomsday/config_macx.pri +++ b/doomsday/config_macx.pri @@ -55,7 +55,6 @@ else:deng_macx7_64bit { QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6 QMAKE_CFLAGS += -mmacosx-version-min=10.6 QMAKE_CXXFLAGS += -mmacosx-version-min=10.6 - INCLUDEPATH = $$QMAKE_MAC_SDK/usr/X11/include $$INCLUDEPATH } else:deng_macx6_32bit_64bit { echo(Using Mac OS 10.6 SDK.)