From 33d4b989c9ef6fc9c20982f6eba550c652c84388 Mon Sep 17 00:00:00 2001 From: danij Date: Sat, 4 Jan 2014 02:18:23 +0000 Subject: [PATCH] Refactor|Game: Game now uses de::String and de::Path to represent attributes --- doomsday/api/api_base.h | 35 ++-- doomsday/client/include/client/cl_def.h | 7 +- doomsday/client/include/game.h | 46 +++--- doomsday/client/include/games.h | 41 ++--- doomsday/client/src/client/cl_main.cpp | 12 +- doomsday/client/src/con_config.cpp | 2 +- doomsday/client/src/con_data.cpp | 53 +++--- doomsday/client/src/con_main.cpp | 7 +- doomsday/client/src/dd_main.cpp | 32 ++-- doomsday/client/src/dd_pinit.cpp | 21 +-- doomsday/client/src/def_read.cpp | 4 +- doomsday/client/src/edit_bias.cpp | 2 +- doomsday/client/src/game.cpp | 156 +++++++----------- doomsday/client/src/games.cpp | 93 ++++++----- doomsday/client/src/network/ui_mpi.cpp | 8 +- doomsday/client/src/ui/finaleinterpreter.cpp | 2 +- .../src/ui/widgets/gameselectionwidget.cpp | 6 +- .../client/src/ui/widgets/taskbarwidget.cpp | 2 +- doomsday/client/src/uri.cpp | 2 +- doomsday/client/src/world/world.cpp | 7 +- doomsday/plugins/common/src/d_netcl.c | 4 +- doomsday/plugins/common/src/d_netsv.c | 6 +- doomsday/plugins/common/src/g_game.c | 2 +- doomsday/plugins/common/src/p_mapsetup.cpp | 2 +- doomsday/plugins/common/src/p_saveio.c | 2 +- doomsday/server/src/server/sv_main.cpp | 4 +- doomsday/server/src/shelluser.cpp | 2 +- 27 files changed, 264 insertions(+), 296 deletions(-) diff --git a/doomsday/api/api_base.h b/doomsday/api/api_base.h index 69da74fc51..75ff71bc03 100644 --- a/doomsday/api/api_base.h +++ b/doomsday/api/api_base.h @@ -21,6 +21,7 @@ #ifndef DOOMSDAY_API_BASE_H #define DOOMSDAY_API_BASE_H +#include #include "apis.h" #include "api_uri.h" #include "api_resourceclass.h" @@ -29,27 +30,27 @@ /// @{ /** - * Defines the numerous high-level properties of a logical game component. - * Note that this is POD; no construction or destruction is needed. + * Defines the high-level properties of a logical game component. Note that this + * is POD; no construction or destruction is needed. * @see DD_DefineGame() @ingroup game */ typedef struct gamedef_s { - /** + /* * Unique game mode key/identifier, 16 chars max (e.g., "doom1-ultimate"). * - Used during resource location for mode-specific assets. * - Sent out in netgames (a client can't connect unless mode strings match). */ - const char* identityKey; + char const *identityKey; /// Name of the config directory. - const char* configDir; + char const *configDir; /// Default title. May be overridden later. - const char* defaultTitle; + char const *defaultTitle; /// Default author. May be overridden later. /// Used for (e.g.) the map author name if not specified in a Map Info definition. - const char* defaultAuthor; + char const *defaultAuthor; } GameDef; /** @@ -57,9 +58,9 @@ typedef struct gamedef_s { * @see DD_GameInfo() @ingroup game */ typedef struct gameinfo_s { - const char* title; - const char* author; - const char* identityKey; + AutoStr *title; + AutoStr *author; + AutoStr *identityKey; } GameInfo; /// @} @@ -73,8 +74,8 @@ DENG_API_TYPEDEF(Base) // v1 int (*GetInteger)(int ddvalue); void (*SetInteger)(int ddvalue, int parm); - void* (*GetVariable)(int ddvalue); - void (*SetVariable)(int ddvalue, void* ptr); + void *(*GetVariable)(int ddvalue); + void (*SetVariable)(int ddvalue, void *ptr); /** * Register a new game. @@ -86,7 +87,7 @@ DENG_API_TYPEDEF(Base) // v1 * @note Game registration order defines the order of the automatic game * identification/selection logic. */ - gameid_t (*DefineGame)(GameDef const* definition); + gameid_t (*DefineGame)(GameDef const *definition); /** * Retrieves the game identifier for a previously defined game. @@ -96,7 +97,7 @@ DENG_API_TYPEDEF(Base) // v1 * * @return Game identifier. */ - gameid_t (*GameIdForKey)(char const* identityKey); + gameid_t (*GameIdForKey)(char const *identityKey); /** * Adds a new resource to the list for the identified @a game. @@ -118,7 +119,7 @@ DENG_API_TYPEDEF(Base) // v1 * semicolon delimited list of identity keys. */ void (*AddGameResource)(gameid_t game, resourceclassid_t classId, int fFlags, - const char* names, void* params); + char const *names, void *params); /** * Retrieve extended info about the current game. @@ -127,7 +128,7 @@ DENG_API_TYPEDEF(Base) // v1 * * @return @c true if successful else @c false (i.e., no game loaded). */ - boolean (*gameInfo)(GameInfo* info); + boolean (*gameInfo)(GameInfo *info); /** * Determines whether the current run of the thinkers should be considered a @@ -151,7 +152,7 @@ DENG_API_TYPEDEF(Base) // v1 * @param data Data of the packet. * @param length Length of the data. */ - void (*SendPacket)(int to_player, int type, const void* data, size_t length); + void (*SendPacket)(int to_player, int type, void const *data, size_t length); /** * To be called by the game after loading a save state to instruct the engine diff --git a/doomsday/client/include/client/cl_def.h b/doomsday/client/include/client/cl_def.h index 26ba9cbabe..7e6c89e93c 100644 --- a/doomsday/client/include/client/cl_def.h +++ b/doomsday/client/include/client/cl_def.h @@ -45,7 +45,12 @@ void Cl_CleanUp(void); void Cl_GetPackets(void); void Cl_Ticker(timespan_t ticLength); int Cl_GameReady(void); -void Cl_SendHello(void); + +/** + * Sends a hello packet. + * PCL_HELLO2 includes the Game ID (16 chars). + */ +void Cl_SendHello(); #ifdef __cplusplus } // extern "C" diff --git a/doomsday/client/include/game.h b/doomsday/client/include/game.h index bd3f6263b1..02e0d09fab 100644 --- a/doomsday/client/include/game.h +++ b/doomsday/client/include/game.h @@ -21,12 +21,12 @@ #ifndef DENG_GAME_H #define DENG_GAME_H -#include - #include "api_plugin.h" -#include #include +#include +#include #include +#include /** * @defgroup printGameFlags Print Game Flags @@ -64,31 +64,39 @@ class Game : public de::game::Game /** * @param identityKey Unique game mode key/identifier, 16 chars max (e.g., "doom1-ultimate"). * @param configDir Name of the config directory. - * @param title Default game title. - * @param author Default game author. */ - Game(char const *identityKey, char const *configDir, - char const *title = "Unnamed", char const *author = "Unknown"); + Game(String const &identityKey, Path const &configDir, + String const &title = "Unnamed", String const &author = "Unknown"); virtual ~Game(); /// @return Unique plugin identifier attributed to that which registered this. pluginid_t pluginId() const; - /// @return String containing the identity key. - ddstring_t const *identityKey() const; + /** + * Returns the unique identity key of the game. + */ + de::String const &identityKey() const; - /// @return String containing the default title. - ddstring_t const *title() const; + /** + * Returns the title of the game, as text. + */ + de::String const &title() const; - /// @return String containing the default author. - ddstring_t const *author() const; + /** + * Returns the author of the game, as text. + */ + de::String const &author() const; - /// @return String containing the name of the main config file. - ddstring_t const *mainConfig() const; + /** + * Returns the name of the main config file for the game. + */ + de::Path const &mainConfig() const; - /// @return String containing the name of the binding config file. - ddstring_t const *bindingConfig() const; + /** + * Returns the name of the binding config file for the game. + */ + de::Path const &bindingConfig() const; /** * Change the identfier of the plugin associated with this. @@ -180,11 +188,11 @@ class NullGame : public Game public: NullGame(); - Game& addManifest(struct manifest_s& /*record*/) { + Game &addManifest(struct manifest_s & /*record*/) { throw NullObjectError("NullGame::addResource", "Invalid action on null-object"); } - bool isRequiredResource(char const* /*absolutePath*/) { + bool isRequiredResource(char const * /*absolutePath*/) { return false; // Never. } diff --git a/doomsday/client/include/games.h b/doomsday/client/include/games.h index ede8629da0..89f5d4499a 100644 --- a/doomsday/client/include/games.h +++ b/doomsday/client/include/games.h @@ -1,7 +1,7 @@ -/** @file games.h Specialized collection for a set of logical Games. +/** @file games.h Specialized collection for a set of logical Games. * - * @authors Copyright © 2012-2013 Daniel Swanson - * @authors Copyright © 2012-2013 Jaakko Keränen + * @authors Copyright © 2012-2013 Daniel Swanson + * @authors Copyright © 2012-2013 Jaakko Keränen * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -48,31 +48,24 @@ class Games { Game *game; - GameListItem(Game *_game = 0) : game(_game) + GameListItem(Game *game = 0) : game(game) {} /// @return @c true= this game's title is lexically less than that of @a other. - bool operator < (GameListItem const &other) const - { - return Str_CompareIgnoreCase(game->title(), Str_Text(other.game->title())) < 0; + bool operator < (GameListItem const &other) const { + return game->title().compareWithoutCase(other.game->title()) < 0; } }; - typedef QList GameList; - /// Game instances. + typedef QList GameList; typedef QList All; - /** - * Notified when a new game is added. - */ + /// Notified when a new game is added. DENG2_DEFINE_AUDIENCE(Addition, void gameAdded(Game &game)) public: Games(); - /// Register the console commands, variables, etc..., of this module. - static void consoleRegister(); - /// @return The special "null" Game instance. Game &nullGame() const; @@ -93,7 +86,7 @@ class Games * * @throws NotFoundError if no game is associated with @a identityKey. */ - Game &byIdentityKey(char const *identityKey) const; + Game &byIdentityKey(String identityKey) const; /** * @return Game associated with @a gameId. @@ -148,20 +141,14 @@ class Games */ void locateStartupResources(Game &game); +public: + /// Register the console commands, variables, etc..., of this module. + static void consoleRegister(); + private: DENG2_PRIVATE(d) }; } // namespace de -#ifdef __cplusplus -extern "C" { -#endif - -D_CMD(ListGames); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif /* LIBDENG_GAMES_H */ +#endif // LIBDENG_GAMES_H diff --git a/doomsday/client/src/client/cl_main.cpp b/doomsday/client/src/client/cl_main.cpp index d7f91efea8..65311f87d5 100644 --- a/doomsday/client/src/client/cl_main.cpp +++ b/doomsday/client/src/client/cl_main.cpp @@ -102,20 +102,14 @@ void Cl_CleanUp() GL_SetFilter(false); } -/** - * Sends a hello packet. - * PCL_HELLO2 includes the Game ID (16 chars). - */ -void Cl_SendHello(void) +void Cl_SendHello() { - char buf[256]; - Msg_Begin(PCL_HELLO2); Writer_WriteUInt32(msgWriter, clientID); // The game mode is included in the hello packet. - memset(buf, 0, sizeof(buf)); - strncpy(buf, Str_Text(App_CurrentGame().identityKey()), sizeof(buf) - 1); + char buf[256]; zap(buf); + strncpy(buf, App_CurrentGame().identityKey().toUtf8().constData(), sizeof(buf) - 1); #ifdef _DEBUG Con_Message("Cl_SendHello: game mode = %s", buf); diff --git a/doomsday/client/src/con_config.cpp b/doomsday/client/src/con_config.cpp index d2fa95ace5..df985d6c1d 100644 --- a/doomsday/client/src/con_config.cpp +++ b/doomsday/client/src/con_config.cpp @@ -275,7 +275,7 @@ boolean Con_WriteState(const char* fileName, const char* bindingsFileName) void Con_SaveDefaults() { Con_WriteState(cfgFile, (!isDedicated && App_GameLoaded()? - Str_Text(App_CurrentGame().bindingConfig()) : 0)); + App_CurrentGame().bindingConfig().toUtf8().constData() : 0)); } D_CMD(WriteConsole) diff --git a/doomsday/client/src/con_data.cpp b/doomsday/client/src/con_data.cpp index d591293ec5..5b4d1496e9 100644 --- a/doomsday/client/src/con_data.cpp +++ b/doomsday/client/src/con_data.cpp @@ -237,22 +237,19 @@ static void clearKnownWords(void) knownWordsNeedUpdate = false; } -static int compareKnownWordByName(void const* a, void const* b) +static int compareKnownWordByName(void const *a, void const *b) { - knownword_t const* wA = (knownword_t const*)a; - knownword_t const* wB = (knownword_t const*)b; - AutoStr* textAString = NULL, *textBString = NULL; - char const* textA, *textB; + knownword_t const *wA = (knownword_t const *)a; + knownword_t const *wB = (knownword_t const *)b; + AutoStr *textA = 0, *textB = 0; switch(wA->type) { - case WT_CALIAS: textA = ((calias_t*)wA->data)->name; break; - case WT_CCMD: textA = ((ccmd_t*)wA->data)->name; break; - case WT_CVAR: - textAString = CVar_ComposePath((cvar_t*)wA->data); - textA = Str_Text(textAString); - break; - case WT_GAME: textA = Str_Text(reinterpret_cast(wA->data)->identityKey()); break; + case WT_CALIAS: textA = AutoStr_FromTextStd(((calias_t *)wA->data)->name); break; + case WT_CCMD: textA = AutoStr_FromTextStd(((ccmd_t *)wA->data)->name); break; + case WT_CVAR: textA = CVar_ComposePath((cvar_t *)wA->data); break; + case WT_GAME: textA = AutoStr_FromTextStd(reinterpret_cast(wA->data)->identityKey().toUtf8().constData()); break; + default: Con_Error("compareKnownWordByName: Invalid type %i for word A.", wA->type); exit(1); // Unreachable @@ -260,19 +257,17 @@ static int compareKnownWordByName(void const* a, void const* b) switch(wB->type) { - case WT_CALIAS: textB = ((calias_t*)wB->data)->name; break; - case WT_CCMD: textB = ((ccmd_t*)wB->data)->name; break; - case WT_CVAR: - textBString = CVar_ComposePath((cvar_t*)wB->data); - textB = Str_Text(textBString); - break; - case WT_GAME: textB = Str_Text(reinterpret_cast(wB->data)->identityKey()); break; + case WT_CALIAS: textB = AutoStr_FromTextStd(((calias_t *)wB->data)->name); break; + case WT_CCMD: textB = AutoStr_FromTextStd(((ccmd_t *)wB->data)->name); break; + case WT_CVAR: textB = CVar_ComposePath((cvar_t *)wB->data); break; + case WT_GAME: textB = AutoStr_FromTextStd(reinterpret_cast(wB->data)->identityKey().toUtf8().constData()); break; + default: Con_Error("compareKnownWordByName: Invalid type %i for word B.", wB->type); exit(1); // Unreachable } - return stricmp(textA, textB); + return Str_CompareIgnoreCase(textA, Str_Text(textB)); } static boolean removeFromKnownWords(knownwordtype_t type, void* data) @@ -1287,16 +1282,17 @@ void Con_DeleteAlias(calias_t* cal) /** * @return New AutoStr with the text of the known word. Caller gets ownership. */ -static AutoStr* textForKnownWord(knownword_t const* word) +static AutoStr *textForKnownWord(knownword_t const *word) { - AutoStr* text = 0; + AutoStr *text = 0; switch(word->type) { - case WT_CALIAS: Str_Set(text = AutoStr_NewStd(), ((calias_t*)word->data)->name); break; - case WT_CCMD: Str_Set(text = AutoStr_NewStd(), ((ccmd_t*)word->data)->name); break; - case WT_CVAR: text = CVar_ComposePath((cvar_t*)word->data); break; - case WT_GAME: Str_Set(text = AutoStr_NewStd(), Str_Text(reinterpret_cast(word->data)->identityKey())); break; + case WT_CALIAS: text = AutoStr_FromTextStd(((calias_t *)word->data)->name); break; + case WT_CCMD: text = AutoStr_FromTextStd(((ccmd_t *)word->data)->name); break; + case WT_CVAR: text = CVar_ComposePath((cvar_t *)word->data); break; + case WT_GAME: text = AutoStr_FromTextStd(reinterpret_cast(word->data)->identityKey().toUtf8().constData()); break; + default: Con_Error("textForKnownWord: Invalid type %i for word.", word->type); exit(1); // Unreachable @@ -1477,7 +1473,7 @@ static int aproposPrinter(knownword_t const* word, void* matching) } else if(word->type == WT_GAME) { - tmp = Str_Text(reinterpret_cast(word->data)->title()); + tmp = reinterpret_cast(word->data)->title(); } os << tmp; @@ -1618,7 +1614,8 @@ de::String Con_AliasAsStyledText(calias_t *alias) de::String Con_GameAsStyledText(de::Game *game) { - return de::String(_E(1)) + Str_Text(game->identityKey()) + _E(.); + DENG2_ASSERT(game != 0); + return de::String(_E(1)) + game->identityKey() + _E(.); } static int printKnownWordWorker(knownword_t const *word, void *parameters) diff --git a/doomsday/client/src/con_main.cpp b/doomsday/client/src/con_main.cpp index 0eaa14cefd..df4b37d842 100644 --- a/doomsday/client/src/con_main.cpp +++ b/doomsday/client/src/con_main.cpp @@ -226,9 +226,6 @@ void Con_Register(void) C_VAR_BYTE("con-snapback", &consoleSnapBackOnPrint, 0, 0, 1); */ - // Games - C_CMD("listgames", "", ListGames); - // File C_VAR_CHARPTR("file-startup", &startupFiles, 0, 0, 0); @@ -1287,7 +1284,7 @@ static int completeWord(int mode) } case WT_GAME: { Game *game = (Game *)(*match)->data; - foundWord = Str_Text(game->identityKey()); + foundWord = game->identityKey().toUtf8().constData(); if(printCompletions) Con_FPrintf(CPF_LIGHT|CPF_BLUE, " %s\n", foundWord); break; @@ -1323,7 +1320,7 @@ static int completeWord(int mode) AutoStr* foundName = CVar_ComposePath((cvar_t*)completeWord->data); str = Str_Text(foundName); break; } - case WT_GAME: str = Str_Text(reinterpret_cast(completeWord->data)->identityKey()); break; + case WT_GAME: str = reinterpret_cast(completeWord->data)->identityKey().toUtf8().constData(); break; default: Con_Error("completeWord: Invalid word type %i.", (int)completeWord->type); exit(1); // Unreachable. diff --git a/doomsday/client/src/dd_main.cpp b/doomsday/client/src/dd_main.cpp index 001bd074e4..e739ee3bdd 100644 --- a/doomsday/client/src/dd_main.cpp +++ b/doomsday/client/src/dd_main.cpp @@ -1074,23 +1074,18 @@ static int DD_ActivateGameWorker(void *context) // Parse the game's main config file. // If a custom top-level config is specified; let it override. - ddstring_t const *configFileName = 0; - ddstring_t tmp; + Path configFile; if(CommandLine_CheckWith("-config", 1)) { - Str_Init(&tmp); Str_Set(&tmp, CommandLine_Next()); - F_FixSlashes(&tmp, &tmp); - configFileName = &tmp; + configFile = NativePath(CommandLine_NextAsPath()).withSeparators('/'); } else { - configFileName = App_CurrentGame().mainConfig(); + configFile = App_CurrentGame().mainConfig(); } - LOG_MSG("Parsing primary config \"%s\"...") << F_PrettyPath(Str_Text(configFileName)); - Con_ParseCommands2(Str_Text(configFileName), CPCF_SET_DEFAULT | CPCF_ALLOW_SAVE_STATE); - if(configFileName == &tmp) - Str_Free(&tmp); + LOG_MSG("Parsing primary config \"%s\"...") << NativePath(configFile).pretty(); + Con_ParseCommands2(configFile.toUtf8().constData(), CPCF_SET_DEFAULT | CPCF_ALLOW_SAVE_STATE); #ifdef __CLIENT__ if(App_GameLoaded()) @@ -1099,7 +1094,7 @@ static int DD_ActivateGameWorker(void *context) B_BindGameDefaults(); // Read bindings for this game and merge with the working set. - Con_ParseCommands2(Str_Text(App_CurrentGame().bindingConfig()), CPCF_ALLOW_SAVE_BINDINGS); + Con_ParseCommands2(App_CurrentGame().bindingConfig().toUtf8().constData(), CPCF_ALLOW_SAVE_BINDINGS); } #endif @@ -1189,9 +1184,9 @@ void DD_DestroyGames() static void populateGameInfo(GameInfo &info, de::Game &game) { - info.identityKey = Str_Text(game.identityKey()); - info.title = Str_Text(game.title()); - info.author = Str_Text(game.author()); + info.identityKey = AutoStr_FromTextStd(game.identityKey().toUtf8().constData()); + info.title = AutoStr_FromTextStd(game.title().toUtf8().constData()); + info.author = AutoStr_FromTextStd(game.author().toUtf8().constData()); } /// @note Part of the Doomsday public API. @@ -1318,7 +1313,7 @@ bool App_ChangeGame(Game &game, bool allowReload) if(App_GameLoaded()) { LOG_MSG("%s (%s) - already loaded.") - << Str_Text(game.title()) << Str_Text(game.identityKey()); + << game.title() << game.identityKey(); } return true; } @@ -1458,7 +1453,7 @@ bool App_ChangeGame(Game &game, bool allowReload) if(!game.isNull()) { - LOG_VERBOSE("Selecting game '%s'...") << Str_Text(game.identityKey()); + LOG_VERBOSE("Selecting game '%s'...") << game.identityKey(); } else if(!isReload) { @@ -2714,7 +2709,7 @@ D_CMD(Load) LOG_WARNING("Failed to locate all required startup resources:"); Game::printFiles(game, FF_STARTUP); LOG_MSG("%s (%s) cannot be loaded.") - << Str_Text(game.title()) << Str_Text(game.identityKey()); + << game.title() << game.identityKey(); return true; } @@ -2852,7 +2847,7 @@ D_CMD(Unload) return App_ChangeGame(App_Games().nullGame()); } - LOG_MSG("%s is not currently loaded.") << Str_Text(game.identityKey()); + LOG_MSG("%s is not currently loaded.") << game.identityKey(); return true; } catch(Games::NotFoundError const &) @@ -2958,6 +2953,7 @@ static void consoleRegister() DD_RegisterLoop(); F_Register(); Con_Register(); + Games::consoleRegister(); DH_Register(); S_Register(); #ifdef __CLIENT__ diff --git a/doomsday/client/src/dd_pinit.cpp b/doomsday/client/src/dd_pinit.cpp index 54bf8a93b3..04668fa7e2 100644 --- a/doomsday/client/src/dd_pinit.cpp +++ b/doomsday/client/src/dd_pinit.cpp @@ -26,8 +26,6 @@ # include #endif -#include - #include "de_base.h" #include "de_console.h" #include "de_system.h" @@ -48,6 +46,9 @@ #include "api_internaldata.h" #include +#include + +using namespace de; /* * The game imports and exports. @@ -70,25 +71,25 @@ de::String DD_ComposeMainWindowTitle() if(App_GameLoaded() && gx.GetVariable) { - title = de::String(Str_Text(App_CurrentGame().title())) + " - " + title; + title = App_CurrentGame().title() + " - " + title; } return title; } #endif -void DD_InitAPI(void) +void DD_InitAPI() { GETGAMEAPI GetGameAPI = app.GetGameAPI; - memset(&__gx, 0, sizeof(__gx)); + zap(__gx); if(GetGameAPI) { - game_export_t* gameExPtr = GetGameAPI(); - memcpy(&__gx, gameExPtr, MIN_OF(sizeof(__gx), gameExPtr->apiSize)); + game_export_t *gameExPtr = GetGameAPI(); + std::memcpy(&__gx, gameExPtr, MIN_OF(sizeof(__gx), gameExPtr->apiSize)); } } -void DD_InitCommandLine(void) +void DD_InitCommandLine() { CommandLine_Alias("-game", "-g"); CommandLine_Alias("-defs", "-d"); @@ -114,7 +115,7 @@ void DD_InitCommandLine(void) CommandLine_Alias("-verbose", "-v"); } -void DD_ConsoleInit(void) +void DD_ConsoleInit() { // Get the console online ASAP. Con_Init(); @@ -129,7 +130,7 @@ void DD_ConsoleInit(void) } } -void DD_ShutdownAll(void) +void DD_ShutdownAll() { FI_Shutdown(); UI_Shutdown(); diff --git a/doomsday/client/src/def_read.cpp b/doomsday/client/src/def_read.cpp index 977940b679..b9cdeed4c4 100644 --- a/doomsday/client/src/def_read.cpp +++ b/doomsday/client/src/def_read.cpp @@ -679,7 +679,7 @@ static void DED_CloseReader(void) * or a game mode. * @return @c true if the condition passes. */ -static boolean DED_CheckCondition(const char* cond, boolean expected) +static boolean DED_CheckCondition(char const *cond, boolean expected) { boolean value = false; @@ -691,7 +691,7 @@ static boolean DED_CheckCondition(const char* cond, boolean expected) else if(isalnum(cond[0]) && App_GameLoaded()) { // A game mode. - value = !stricmp(cond, Str_Text(App_CurrentGame().identityKey())); + value = !String(cond).compareWithoutCase(App_CurrentGame().identityKey()); } return value == expected; diff --git a/doomsday/client/src/edit_bias.cpp b/doomsday/client/src/edit_bias.cpp index 7af083f916..6cf6d59c1f 100644 --- a/doomsday/client/src/edit_bias.cpp +++ b/doomsday/client/src/edit_bias.cpp @@ -307,7 +307,7 @@ static bool SBE_Save(char const *name = 0) // Since there can be quite a lot of these, make sure we'll skip // the ones that are definitely not suitable. - fprintf(file, "SkipIf Not %s\n", Str_Text(App_CurrentGame().identityKey())); + fprintf(file, "SkipIf Not %s\n", App_CurrentGame().identityKey().toUtf8().constData()); foreach(BiasSource *src, map.biasSources()) { diff --git a/doomsday/client/src/game.cpp b/doomsday/client/src/game.cpp index 578260d00b..fa52a68191 100644 --- a/doomsday/client/src/game.cpp +++ b/doomsday/client/src/game.cpp @@ -1,4 +1,4 @@ -/** @file game.cpp Game mode configuration (metadata, resource files, etc...). +/** @file game.cpp Game mode configuration (metadata, resource files, etc...). * * @authors Copyright © 2003-2013 Jaakko Keränen * @authors Copyright © 2005-2013 Daniel Swanson @@ -19,83 +19,49 @@ */ #include "de_base.h" -#include "de_console.h" -#include "de_filesys.h" +#include "game.h" + #include "filesys/manifest.h" #include #include #include -#include "game.h" - namespace de { DENG2_PIMPL(Game) { - /// Unique identifier of the plugin which registered this game. - pluginid_t pluginId; + pluginid_t pluginId; ///< Unique identifier of the registering plugin. + Manifests manifests; ///< Required resource files (e.g., doomu.wad). + String identityKey; ///< Unique game mode identifier (e.g., "doom1-ultimate"). - /// Records for required game files (e.g., doomu.wad). - Game::Manifests manifests; + String title; ///< Formatted default title, suitable for printing (e.g., "The Ultimate DOOM"). + String author; ///< Formatted default author suitable for printing (e.g., "id Software"). - /// Unique identifier string (e.g., "doom1-ultimate"). - ddstring_t identityKey; + Path mainConfig; ///< Config file name (e.g., "configs/doom/game.cfg"). + Path bindingConfig; ///< Control binding file name (set automatically). - /// Formatted default title suitable for printing (e.g., "The Ultimate DOOM"). - ddstring_t title; - - /// Formatted default author suitable for printing (e.g., "id Software"). - ddstring_t author; - - /// Name of the main config file (e.g., "configs/doom/game.cfg"). - ddstring_t mainConfig; - - /// Name of the file used for control bindings, set automatically at creation time. - ddstring_t bindingConfig; - - Instance(Public &a, char const *_identityKey, char const *configDir) - : Base(a), pluginId(0), manifests() - { - Str_Set(Str_InitStd(&identityKey), _identityKey); - //DENG_ASSERT(!Str_IsEmpty(&identityKey)); - - Str_InitStd(&title); - Str_InitStd(&author); - - Str_Appendf(Str_InitStd(&mainConfig), "configs/%s", configDir); - Str_Strip(&mainConfig); - F_FixSlashes(&mainConfig, &mainConfig); - F_AppendMissingSlash(&mainConfig); - Str_Append(&mainConfig, "game.cfg"); - - Str_Appendf(Str_InitStd(&bindingConfig), "configs/%s", configDir); - Str_Strip(&bindingConfig); - F_FixSlashes(&bindingConfig, &bindingConfig); - F_AppendMissingSlash(&bindingConfig); - Str_Append(&bindingConfig, "player/bindings.cfg"); - } + Instance(Public &a, String const &identityKey, Path const &configDir, + String const &title, String const &author) + : Base(a) + , pluginId (0) // Not yet assigned. + , identityKey (identityKey) + , title (title) + , author (author) + , mainConfig (Path("configs") / configDir / "game.cfg") + , bindingConfig(Path("configs") / configDir / "player/bindings.cfg") + {} ~Instance() { qDeleteAll(manifests); - manifests.clear(); - - Str_Free(&identityKey); - Str_Free(&mainConfig); - Str_Free(&bindingConfig); - Str_Free(&title); - Str_Free(&author); } }; -Game::Game(char const *identityKey, char const *configDir, - char const *title, char const *author) - : game::Game(identityKey), - d(new Instance(*this, identityKey, configDir)) -{ - if(title) Str_Set(&d->title, title); - if(author) Str_Set(&d->author, author); -} +Game::Game(String const &identityKey, Path const &configDir, String const &title, + String const &author) + : game::Game(identityKey) + , d(new Instance(*this, identityKey, configDir, title, author)) +{} Game::~Game() {} @@ -134,29 +100,29 @@ pluginid_t Game::pluginId() const return d->pluginId; } -ddstring_t const *Game::identityKey() const +String const &Game::identityKey() const { - return &d->identityKey; + return d->identityKey; } -ddstring_t const *Game::mainConfig() const +Path const &Game::mainConfig() const { - return &d->mainConfig; + return d->mainConfig; } -ddstring_t const *Game::bindingConfig() const +Path const &Game::bindingConfig() const { - return &d->bindingConfig; + return d->bindingConfig; } -ddstring_t const *Game::title() const +String const &Game::title() const { - return &d->title; + return d->title; } -ddstring_t const *Game::author() const +String const &Game::author() const { - return &d->author; + return d->author; } Game::Manifests const &Game::manifests() const @@ -193,14 +159,15 @@ bool Game::isRequiredFile(File1 &file) Game *Game::fromDef(GameDef const &def) { - return new Game(def.identityKey, def.configDir, def.defaultTitle, def.defaultAuthor); + return new Game(def.identityKey, NativePath(def.configDir).expand().withSeparators('/'), + def.defaultTitle, def.defaultAuthor); } void Game::printBanner(Game const &game) { - Con_PrintRuler(); - Con_FPrintf(CPF_WHITE | CPF_CENTER, "%s\n", Str_Text(game.title())); - Con_PrintRuler(); + LOG_MSG(_E(R) "\n"); + LOG_MSG(_E(1)) << game.title(); + LOG_MSG(_E(R) "\n"); } void Game::printFiles(Game const &game, int rflags, bool printStatus) @@ -226,51 +193,54 @@ void Game::printFiles(Game const &game, int rflags, bool printStatus) if(numPrinted == 0) { - Con_Printf(" None\n"); + LOG_MSG(" None"); } } void Game::print(Game const &game, int flags) { if(game.isNull()) + { flags &= ~PGF_BANNER; - -#ifdef DENG_DEBUG - Con_Printf("pluginid:%i\n", int(game.pluginId())); -#endif + } if(flags & PGF_BANNER) + { printBanner(game); - - if(!(flags & PGF_BANNER)) - Con_Printf("Game: %s - ", Str_Text(game.title())); + LOG_MSG("Author: ") << game.author(); + } else - Con_Printf("Author: "); - Con_Printf("%s\n", Str_Text(game.author())); - Con_Printf("IdentityKey: %s\n", Str_Text(game.identityKey())); + { + LOG_MSG("Game: %s - %s") << game.title() << game.author(); + } + + LOG_MSG("IdentityKey: ") << game.identityKey(); +#ifdef DENG_DEBUG + LOG_MSG("pluginid: ") << int(game.pluginId()); +#endif if(flags & PGF_LIST_STARTUP_RESOURCES) { - Con_Printf("Startup resources:\n"); + LOG_MSG("Startup resources:"); printFiles(game, FF_STARTUP, (flags & PGF_STATUS) != 0); } if(flags & PGF_LIST_OTHER_RESOURCES) { - Con_Printf("Other resources:\n"); - Con_Printf(" "); + LOG_MSG("Other resources:"); printFiles(game, 0, /*(flags & PGF_STATUS) != 0*/false); } if(flags & PGF_STATUS) - Con_Printf("Status: %s\n", - &App_CurrentGame() == &game? "Loaded" : - game.allStartupFilesFound()? "Complete/Playable" : - "Incomplete/Not playable"); + { + LOG_MSG("Status: ") + << (&App_CurrentGame() == &game? "Loaded" : + game.allStartupFilesFound()? "Complete/Playable" : + "Incomplete/Not playable"); + } } -NullGame::NullGame() - : Game("" /*null*/, "doomsday", "null-game", "null-game") +NullGame::NullGame() : Game("" /*null*/, "doomsday", "null-game", "null-game") {} } // namespace de diff --git a/doomsday/client/src/games.cpp b/doomsday/client/src/games.cpp index 21fbf8badf..01eef7628d 100644 --- a/doomsday/client/src/games.cpp +++ b/doomsday/client/src/games.cpp @@ -1,7 +1,7 @@ -/** @file games.cpp Specialized collection for a set of logical Games. +/** @file games.cpp Specialized collection for a set of logical Games. * - * @authors Copyright © 2012-2013 Daniel Swanson - * @authors Copyright © 2012-2013 Jaakko Keränen + * @authors Copyright © 2012-2013 Daniel Swanson + * @authors Copyright © 2012-2013 Jaakko Keränen * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -19,14 +19,20 @@ */ #include "de_base.h" -#include "de_console.h" -#include "de_filesys.h" +#include "games.h" + +#include "dd_main.h" +#include "con_main.h" +#include "con_bar.h" + +#include "filesys/fs_main.h" #include "filesys/manifest.h" + #include "resource/zip.h" -#include -#include -#include "games.h" +#include +#include +#include namespace de { @@ -75,8 +81,10 @@ int Games::numPlayable() const int count = 0; foreach(Game *game, d->games) { - if(!game->allStartupFilesFound()) continue; - ++count; + if(game->allStartupFilesFound()) + { + count += 1; + } } return count; } @@ -112,19 +120,18 @@ Game &Games::byId(gameid_t gameId) const return *d->games[gameId-1]; } -Game &Games::byIdentityKey(char const *identityKey) const +Game &Games::byIdentityKey(String identityKey) const { - if(identityKey && identityKey[0]) + if(!identityKey.isEmpty()) { foreach(Game *game, d->games) { - if(!Str_CompareIgnoreCase(game->identityKey(), identityKey)) + if(!game->identityKey().compareWithoutCase(identityKey)) return *game; } } /// @throw NotFoundError The specified @a identityKey string is not associated with a game in the collection. - throw NotFoundError("Games::byIdentityKey", - QString("There is no Game with identity key \"%1\"").arg(identityKey)); + throw NotFoundError("Games::byIdentityKey", "No game exists with identity key '" + identityKey + "'"); } Game &Games::byIndex(int idx) const @@ -202,13 +209,13 @@ void Games::locateStartupResources(Game &game) } } -static int locateAllResourcesWorker(void *parameters) +static int locateAllResourcesWorker(void *context) { - Games *games = (Games *) parameters; + Games *games = (Games *) context; int n = 0; foreach(Game *game, games->all()) { - Con_Message("Locating \"%s\"...", Str_Text(game->title())); + LOG_MSG("Locating \"%s\"...") << game->title(); games->locateStartupResources(*game); Con_SetProgress((n + 1) * 200 / games->count() - 1); @@ -226,62 +233,66 @@ void Games::locateAllResources() locateAllResourcesWorker, (void *)this, "Locating game resources..."); } -} // namespace de - D_CMD(ListGames) { - DENG_UNUSED(src); DENG_UNUSED(argc); DENG_UNUSED(argv); + DENG2_UNUSED3(src, argc, argv); - de::Games &games = App_Games(); + Games &games = App_Games(); if(!games.count()) { - Con_Printf("No Registered Games.\n"); + LOG_MSG("No game is currently registered."); return true; } - //Con_FPrintf(CPF_YELLOW, "Registered Games:\n"); - //Con_Printf("Key: '!'= Incomplete/Not playable '*'= Loaded\n"); - LOG_MSG(_E(1) "Registered Games:"); LOG_VERBOSE("Key: %s'!'=Incomplete/Not playable %s'*'=Loaded") << _E(>) _E(D) << _E(B); - Con_PrintRuler(); + LOG_MSG(_E(R) "\n"); - de::Games::GameList found; + Games::GameList found; games.collectAll(found); // Sort so we get a nice alphabetical list. qSort(found.begin(), found.end()); - de::String list; + String list; int numCompleteGames = 0; - DENG2_FOR_EACH_CONST(de::Games::GameList, i, found) + DENG2_FOR_EACH_CONST(Games::GameList, i, found) { - de::Game *game = i->game; + Game *game = i->game; bool isCurrent = (&App_CurrentGame() == game); if(!list.isEmpty()) list += "\n"; - list += de::String(_E(0) - _E(Ta) "%1%2 " - _E(Tb) "%3 " - _E(Tc) _E(2) "%4 " _E(i) "(%5)") + list += String(_E(0) + _E(Ta) "%1%2 " + _E(Tb) "%3 " + _E(Tc) _E(2) "%4 " _E(i) "(%5)") .arg(isCurrent? _E(B) _E(b) : !game->allStartupFilesFound()? _E(D) : "") .arg(isCurrent? "*" : !game->allStartupFilesFound()? "!" : " ") - .arg(Str_Text(game->identityKey())) - .arg(Str_Text(game->title())) - .arg(Str_Text(game->author())); + .arg(game->identityKey()) + .arg(game->title()) + .arg(game->author()); if(game->allStartupFilesFound()) + { numCompleteGames++; + } } LOG_MSG("%s") << list; - Con_PrintRuler(); - Con_Printf("%i of %i games playable.\n", numCompleteGames, games.count()); - Con_Printf("Use the 'load' command to load a game. For example: \"load gamename\".\n"); + LOG_MSG(_E(R) "\n"); + LOG_MSG("%i of %i games playable.") << numCompleteGames << games.count(); + LOG_MSG("Use the " _E(b) "load" _E(.) "command to load a game. For example: \"load gamename\"."); return true; } + +void Games::consoleRegister() //static +{ + C_CMD("listgames", "", ListGames); +} + +} // namespace de diff --git a/doomsday/client/src/network/ui_mpi.cpp b/doomsday/client/src/network/ui_mpi.cpp index 11770d762a..9c1c7dcd24 100644 --- a/doomsday/client/src/network/ui_mpi.cpp +++ b/doomsday/client/src/network/ui_mpi.cpp @@ -336,11 +336,11 @@ void MPIUpdateServerInfo(ui_object_t *) "Errors may occur during game play.", info.loadedFilesCRC, myCrc); // Show IWAD warning? - if(strcmp(info.gameIdentityKey, Str_Text(App_CurrentGame().identityKey()))) + if(de::String(info.gameIdentityKey).compare(App_CurrentGame().identityKey())) { UI_FlagGroup(ob_client, 5, UIF_DISABLED, false); sprintf(str_sinfo.warning, "Different game in use (you have %s).", - Str_Text(App_CurrentGame().identityKey())); + App_CurrentGame().identityKey().toUtf8().constData()); } else if(!(lst_found.count >= 1 && lst_found.selection >= 0 && lstit_found[lst_found.selection].data != -1 && @@ -457,7 +457,7 @@ static bool isServerSuitable(serverinfo_t const *info) { return info->canJoin && info->version == DOOMSDAY_VERSION && - !stricmp(info->gameIdentityKey, Str_Text(App_CurrentGame().identityKey())); + !de::String(info->gameIdentityKey).compareWithoutCase(App_CurrentGame().identityKey()); } /* @@ -516,7 +516,7 @@ void MPIUpdateServerList(void) { Con_Message("Server %s filtered out:", info.name); Con_Message(" remote = %i, local = %i", info.version, DOOMSDAY_VERSION); - Con_Message(" remote = %s, local = %s", info.gameIdentityKey, Str_Text(App_CurrentGame().identityKey())); + Con_Message(" remote = %s, local = %s", info.gameIdentityKey, App_CurrentGame().identityKey().toUtf8().constData()); Con_Message(" can join = %i", info.canJoin); continue; } diff --git a/doomsday/client/src/ui/finaleinterpreter.cpp b/doomsday/client/src/ui/finaleinterpreter.cpp index e02c133e92..bb1926296f 100644 --- a/doomsday/client/src/ui/finaleinterpreter.cpp +++ b/doomsday/client/src/ui/finaleinterpreter.cpp @@ -1495,7 +1495,7 @@ DEFFC(If) else if(!strnicmp(token, "mode:", 5)) { if(App_GameLoaded()) - val = !stricmp(token + 5, Str_Text(App_CurrentGame().identityKey())); + val = !de::String(token + 5).compareWithoutCase(App_CurrentGame().identityKey()); else val = 0; } diff --git a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp index 29be741116..4b245ef7ca 100644 --- a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp +++ b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp @@ -60,13 +60,13 @@ DENG2_OBSERVES(ChildWidgetOrganizer, WidgetCreation) ui::Item *makeItemForGame(Game &game) { - String const idKey = Str_Text(game.identityKey()); + 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(.)_E(l)_E(D) "%3") - .arg(Str_Text(game.title())) - .arg(Str_Text(game.author())) + .arg(game.title()) + .arg(game.author()) .arg(idKey); GameItem *item = new GameItem(game, label, loadAction); diff --git a/doomsday/client/src/ui/widgets/taskbarwidget.cpp b/doomsday/client/src/ui/widgets/taskbarwidget.cpp index ab4ff9df3c..6371316ac5 100644 --- a/doomsday/client/src/ui/widgets/taskbarwidget.cpp +++ b/doomsday/client/src/ui/widgets/taskbarwidget.cpp @@ -264,7 +264,7 @@ DENG_GUI_PIMPL(TaskBarWidget) { if(App_GameLoaded()) { - status->setText(Str_Text(App_CurrentGame().identityKey())); + status->setText(App_CurrentGame().identityKey()); } else { diff --git a/doomsday/client/src/uri.cpp b/doomsday/client/src/uri.cpp index b6965007fc..37bf95fcfd 100644 --- a/doomsday/client/src/uri.cpp +++ b/doomsday/client/src/uri.cpp @@ -144,7 +144,7 @@ DENG2_PIMPL_NOREF(Uri) throw ResolveSymbolError("Uri::resolveSymbol", "Symbol 'Game' did not resolve (no game loaded)"); } - return Str_Text(App_CurrentGame().identityKey()); + return App_CurrentGame().identityKey(); } else if(!symbol.compare("GamePlugin.Name", Qt::CaseInsensitive)) { diff --git a/doomsday/client/src/world/world.cpp b/doomsday/client/src/world/world.cpp index 47779f05a4..45a9c549a0 100644 --- a/doomsday/client/src/world/world.cpp +++ b/doomsday/client/src/world/world.cpp @@ -265,7 +265,7 @@ static String composeUniqueMapId(de::File1 &markerLump) .arg(markerLump.name().fileNameWithoutExtension()) .arg(markerLump.container().name().fileNameWithoutExtension()) .arg(markerLump.container().hasCustom()? "pwad" : "iwad") - .arg(Str_Text(App_CurrentGame().identityKey())) + .arg(App_CurrentGame().identityKey()) .toLower(); } @@ -335,8 +335,9 @@ DENG2_PIMPL(World) if(sourcePath.isEmpty()) return String(); // Compose the final path. - return mapCacheDir + String(Str_Text(App_CurrentGame().identityKey())) - / sourcePath.fileNameWithoutExtension() + '-' + cacheIdForMap(sourcePath); + return mapCacheDir + App_CurrentGame().identityKey() + / sourcePath.fileNameWithoutExtension() + + '-' + cacheIdForMap(sourcePath); } /** diff --git a/doomsday/plugins/common/src/d_netcl.c b/doomsday/plugins/common/src/d_netcl.c index e8d7b0825a..79e99c0e03 100644 --- a/doomsday/plugins/common/src/d_netcl.c +++ b/doomsday/plugins/common/src/d_netcl.c @@ -99,10 +99,10 @@ void NetCl_UpdateGameState(Reader* msg) { GameInfo gameInfo; DD_GameInfo(&gameInfo); - if(strcmp(gameInfo.identityKey, gsGameIdentity)) + if(Str_Compare(gameInfo.identityKey, gsGameIdentity)) { Con_Message("NetCl_UpdateGameState: Server's game mode (%s) is different than yours (%s).", - gsGameIdentity, gameInfo.identityKey); + gsGameIdentity, Str_Text(gameInfo.identityKey)); DD_Execute(false, "net disconnect"); return; } diff --git a/doomsday/plugins/common/src/d_netsv.c b/doomsday/plugins/common/src/d_netsv.c index 4476138a22..6df3edfe68 100644 --- a/doomsday/plugins/common/src/d_netsv.c +++ b/doomsday/plugins/common/src/d_netsv.c @@ -745,7 +745,7 @@ void NetSv_SendGameState(int flags, int to) str = Uri_Resolved(mapUri); #ifdef _DEBUG Con_Message("NetSv_SendGameState: Game setup: %s %s %s", - gameInfo.identityKey, Str_Text(str), gameConfigString); + Str_Text(gameInfo.identityKey), Str_Text(str), gameConfigString); #endif // Send an update to all the players in the game. @@ -758,8 +758,8 @@ void NetSv_SendGameState(int flags, int to) Writer_WriteByte(writer, flags); // Game identity key. - Writer_WriteByte(writer, strlen(gameInfo.identityKey)); - Writer_Write(writer, gameInfo.identityKey, strlen(gameInfo.identityKey)); + Writer_WriteByte(writer, Str_Length(gameInfo.identityKey)); + Writer_Write(writer, Str_Text(gameInfo.identityKey), Str_Length(gameInfo.identityKey)); // The current map. Uri_Write(mapUri, writer); diff --git a/doomsday/plugins/common/src/g_game.c b/doomsday/plugins/common/src/g_game.c index 9d47aff49b..2dc8d3f2aa 100644 --- a/doomsday/plugins/common/src/g_game.c +++ b/doomsday/plugins/common/src/g_game.c @@ -3617,7 +3617,7 @@ static AutoStr* composeScreenshotFileName(void) return 0; // Unreachable. } - name = Str_Appendf(AutoStr_NewStd(), "%s-", gameInfo.identityKey); + name = Str_Appendf(AutoStr_NewStd(), "%s-", Str_Text(gameInfo.identityKey)); numPos = Str_Length(name); { int i; for(i = 0; i < 1e6; ++i) // Stop eventually... diff --git a/doomsday/plugins/common/src/p_mapsetup.cpp b/doomsday/plugins/common/src/p_mapsetup.cpp index 1b23fe9498..1aaf8c0b73 100644 --- a/doomsday/plugins/common/src/p_mapsetup.cpp +++ b/doomsday/plugins/common/src/p_mapsetup.cpp @@ -1092,7 +1092,7 @@ char const *P_GetMapAuthor(boolean supressGameAuthor) GameInfo gameInfo; DD_GameInfo(&gameInfo); - if((mapIsCustom || supressGameAuthor) && !stricmp(gameInfo.author, author)) + if((mapIsCustom || supressGameAuthor) && !Str_CompareIgnoreCase(gameInfo.author, author)) return 0; return author; diff --git a/doomsday/plugins/common/src/p_saveio.c b/doomsday/plugins/common/src/p_saveio.c index 2ad3ada9fc..fd5cafde5c 100644 --- a/doomsday/plugins/common/src/p_saveio.c +++ b/doomsday/plugins/common/src/p_saveio.c @@ -73,7 +73,7 @@ static AutoStr* composeSaveDir(void) { GameInfo gameInfo; if(DD_GameInfo(&gameInfo)) { - Str_Appendf(dir, SAVEGAME_DEFAULT_DIR "/%s/", gameInfo.identityKey); + Str_Appendf(dir, SAVEGAME_DEFAULT_DIR "/%s/", Str_Text(gameInfo.identityKey)); return dir; }} diff --git a/doomsday/server/src/server/sv_main.cpp b/doomsday/server/src/server/sv_main.cpp index f9d19cc050..37825b85eb 100644 --- a/doomsday/server/src/server/sv_main.cpp +++ b/doomsday/server/src/server/sv_main.cpp @@ -71,7 +71,7 @@ void Sv_GetInfo(serverinfo_t *info) // Let's figure out what we want to tell about ourselves. info->version = DOOMSDAY_VERSION; dd_snprintf(info->plugin, sizeof(info->plugin) - 1, "%s %s", (char*) gx.GetVariable(DD_PLUGIN_NAME), (char*) gx.GetVariable(DD_PLUGIN_VERSION_SHORT)); - strncpy(info->gameIdentityKey, Str_Text(App_CurrentGame().identityKey()), sizeof(info->gameIdentityKey) - 1); + strncpy(info->gameIdentityKey, App_CurrentGame().identityKey().toUtf8().constData(), sizeof(info->gameIdentityKey) - 1); strncpy(info->gameConfig, (char const *) gx.GetVariable(DD_GAME_CONFIG), sizeof(info->gameConfig) - 1); strncpy(info->name, serverName, sizeof(info->name) - 1); strncpy(info->description, serverInfo, sizeof(info->description) - 1); @@ -290,7 +290,7 @@ void Sv_HandlePacket(void) { // Check the game mode (max 16 chars). Reader_Read(msgReader, buf, 16); - if(strnicmp(buf, Str_Text(App_CurrentGame().identityKey()), 16)) + if(strnicmp(buf, App_CurrentGame().identityKey().toUtf8().constData(), 16)) { Con_Printf(" Bad Game ID: %-.16s\n", buf); N_TerminateClient(from); diff --git a/doomsday/server/src/shelluser.cpp b/doomsday/server/src/shelluser.cpp index 09d77ac401..a109926754 100644 --- a/doomsday/server/src/shelluser.cpp +++ b/doomsday/server/src/shelluser.cpp @@ -94,7 +94,7 @@ void ShellUser::sendInitialUpdate() void ShellUser::sendGameState() { de::Game &game = App_CurrentGame(); - String mode = (App_GameLoaded()? Str_Text(game.identityKey()) : ""); + String mode = (App_GameLoaded()? game.identityKey() : ""); /** * @todo The server is not the right place to compose a packet about