diff options
Diffstat (limited to 'src/main.cpp')
-rw-r--r-- | src/main.cpp | 268 |
1 files changed, 172 insertions, 96 deletions
diff --git a/src/main.cpp b/src/main.cpp index e246b6a9..4049aa78 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -19,46 +19,41 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "main.h" - #include <getopt.h> #include <iostream> #include <physfs.h> +#include <SDL_image.h> #include <unistd.h> #include <vector> -#include <SDL_image.h> #include <guichan/actionlistener.hpp> + #include <guichan/sdl/sdlinput.hpp> + #include <guichan/widgets/label.hpp> #include <libxml/parser.h> -#ifndef WIN32 -#include <cerrno> -#include <sys/stat.h> -#endif -#if defined __APPLE__ -#include <CoreFoundation/CFBundle.h> -#endif - #include "configuration.h" -#include "keyboardconfig.h" -#include "player_relations.h" #include "game.h" #include "graphics.h" #include "itemshortcut.h" -#include "lockedarray.h" +#include "keyboardconfig.h" #include "localplayer.h" +#include "lockedarray.h" #include "log.h" #include "logindata.h" +#include "main.h" #ifdef USE_OPENGL #include "openglgraphics.h" #endif +#include "player_relations.h" +#include "serverinfo.h" #include "sound.h" #include "gui/char_server.h" #include "gui/char_select.h" +#include "gui/colour.h" #include "gui/gui.h" #include "gui/login.h" #include "gui/ok_dialog.h" @@ -67,6 +62,7 @@ #include "gui/setup.h" #include "gui/updatewindow.h" #include "gui/textfield.h" +#include "gui/updatewindow.h" #include "net/charserverhandler.h" #include "net/loginhandler.h" @@ -74,6 +70,7 @@ #include "net/messageout.h" #include "net/network.h" +#include "resources/colordb.h" #include "resources/image.h" #include "resources/itemdb.h" #include "resources/monsterdb.h" @@ -83,8 +80,20 @@ #include "utils/dtor.h" #include "utils/tostring.h" +#ifdef __APPLE__ +#include <CoreFoundation/CFBundle.h> +#endif + +#ifdef __MINGW32__ +#include <windows.h> +#define usleep(usec) (Sleep ((usec) / 1000), 0) +#endif + #ifdef WIN32 #include <SDL_syswm.h> +#else +#include <cerrno> +#include <sys/stat.h> #endif namespace { @@ -123,6 +132,7 @@ CharServerHandler charServerHandler; LoginData loginData; LockedArray<LocalPlayer*> charInfo(MAX_SLOT + 1); +Colour *textColour; // This anonymous namespace hides whatever is inside from other modules. namespace { @@ -168,10 +178,12 @@ struct Options */ void setUpdatesDir() { + std::stringstream updates; + // If updatesHost is currently empty, fill it from config file if (updateHost.empty()) { updateHost = - config.getValue("updatehost", "http://updates.themanaworld.org"); + config.getValue("updatehost", "http://www.aethyra.org/updates"); } // Remove any trailing slash at the end of the update host @@ -183,8 +195,9 @@ void setUpdatesDir() pos = updateHost.find("://"); if (pos != updateHost.npos) { if (pos + 3 < updateHost.length()) { - updatesDir = - "updates/" + updateHost.substr(pos + 3); + updates << "updates/" << updateHost.substr(pos + 3) + << "/" << loginData.port; + updatesDir = updates.str(); } else { logger->log("Error: Invalid update host: %s", updateHost.c_str()); errorMessage = "Invalid update host: " + updateHost; @@ -192,7 +205,8 @@ void setUpdatesDir() } } else { logger->log("Warning: no protocol was specified for the update host"); - updatesDir = "updates/" + updateHost; + updates << "updates/" << updateHost << "/" << loginData.port; + updatesDir = updates.str(); } ResourceManager *resman = ResourceManager::getInstance(); @@ -213,18 +227,18 @@ void setUpdatesDir() */ void init_engine(const Options &options) { - homeDir = std::string(PHYSFS_getUserDir()) + "/.tmw"; + homeDir = std::string(PHYSFS_getUserDir()) + "/.aethyra"; #if defined WIN32 if (!CreateDirectory(homeDir.c_str(), 0) && GetLastError() != ERROR_ALREADY_EXISTS) #elif defined __APPLE__ - // Use Application Directory instead of .tmw - homeDir = std::string(PHYSFS_getUserDir()) + - "/Library/Application Support/The Mana World"; + // Use Application Directory instead of .aethyra + homeDir = std::string(PHYSFS_getUserDir()) + + "/Library/Application Support/Aethyra"; if ((mkdir(homeDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) && (errno != EEXIST)) #else - // Checking if /home/user/.tmw folder exists. + // Checking if /home/user/.Aethyra folder exists. if ((mkdir(homeDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) && (errno != EEXIST)) #endif @@ -236,12 +250,12 @@ void init_engine(const Options &options) } // Set log file - logger->setLogFile(homeDir + std::string("/tmw.log")); + logger->setLogFile(homeDir + std::string("/aethyra.log")); #ifdef PACKAGE_VERSION - logger->log("Starting The Mana World Version %s", PACKAGE_VERSION); + logger->log("Starting Aethyra Version %s", PACKAGE_VERSION); #else - logger->log("Starting The Mana World - Version not defined"); + logger->log("Starting Aethyra - Version not defined"); #endif // Initialize SDL @@ -286,13 +300,13 @@ void init_engine(const Options &options) strncat(path, "/data", PATH_MAX - 1); resman->addToSearchPath(path, true); #else - resman->addToSearchPath(TMW_DATADIR "data", true); + resman->addToSearchPath(AETHYRA_DATADIR "data", true); #endif // Fill configuration with defaults logger->log("Initializing configuration..."); - config.setValue("host", "server.themanaworld.org"); - config.setValue("port", 6901); + config.setValue("host", "www.aethyra.org"); + config.setValue("port", 21001); config.setValue("hwaccel", 0); #if (defined __APPLE__ || defined WIN32) && defined USE_OPENGL config.setValue("opengl", 1); @@ -306,34 +320,34 @@ void init_engine(const Options &options) config.setValue("sfxVolume", 100); config.setValue("musicVolume", 60); config.setValue("fpslimit", 60); - config.setValue("updatehost", "http://updates.themanaworld.org"); + config.setValue("updatehost", "http://www.aethyra.org/updates"); config.setValue("customcursor", 1); config.setValue("ChatLogLength", 128); // Checking if the configuration file exists... otherwise creates it with // default options ! - FILE *tmwFile = 0; + FILE *aethyraFile = 0; std::string configPath = options.configPath; if (configPath.empty()) configPath = homeDir + "/config.xml"; - tmwFile = fopen(configPath.c_str(), "r"); + aethyraFile = fopen(configPath.c_str(), "r"); // If we can't read it, it doesn't exist ! - if (tmwFile == NULL) { + if (aethyraFile == NULL) { // We reopen the file in write mode and we create it - tmwFile = fopen(configPath.c_str(), "wt"); + aethyraFile = fopen(configPath.c_str(), "wt"); } - if (tmwFile == NULL) { + if (aethyraFile == NULL) { std::cout << "Can't create " << configPath << ". " "Using Defaults." << std::endl; } else { - fclose(tmwFile); + fclose(aethyraFile); config.init(configPath); } - SDL_WM_SetCaption("The Mana World", NULL); + SDL_WM_SetCaption("Aethyra", NULL); #ifdef WIN32 static SDL_SysWMinfo pInfo; SDL_GetWMInfo(&pInfo); @@ -343,7 +357,7 @@ void init_engine(const Options &options) SetClassLong(pInfo.window, GCL_HICON, (LONG) icon); } #else - SDL_Surface *icon = IMG_Load(TMW_DATADIR "data/icons/tmw.png"); + SDL_Surface *icon = IMG_Load(AETHYRA_DATADIR "data/icons/aethyra.png"); if (icon) { SDL_SetAlpha(icon, SDL_SRCALPHA, SDL_ALPHA_OPAQUE); @@ -429,6 +443,7 @@ void exit_engine() sound.close(); // Unload XML databases + ColorDB::unload(); ItemDB::unload(); MonsterDB::unload(); NPCDB::unload(); @@ -440,26 +455,28 @@ void exit_engine() void printHelp() { std::cout - << "tmw" << std::endl << std::endl + << "aethyra" << std::endl << std::endl << "Options: " << std::endl - << " -h --help : Display this help" << std::endl - << " -v --version : Display the version" << std::endl - << " -u --skipupdate : Skip the update process" << std::endl + << " -C --configfile : Configuration file to use" << std::endl << " -d --data : Directory to load game data from" << std::endl - << " -U --username : Login with this username" << std::endl - << " -P --password : Login with this password" << std::endl - << " -D --default : Bypass the login process with default settings" << std::endl + << " -D --default : Bypass the login process with default " + "settings" << std::endl + << " -h --help : Display this help" << std::endl + << " -H --updatehost : Use this update host" << std::endl << " -p --playername : Login with this player" << std::endl - << " -C --configfile : Configuration file to use" << std::endl - << " -H --updatehost : Use this update host" << std::endl; + << " -P --password : Login with this password" << std::endl + << " -u --skipupdate : Skip the update downloads" << std::endl + << " -U --username : Login with this username" << std::endl + << " -v --version : Display the version" << std::endl; } void printVersion() { #ifdef PACKAGE_VERSION - std::cout << "The Mana World version " << PACKAGE_VERSION << std::endl; + std::cout << "Aethyra version " << PACKAGE_VERSION << + std::endl; #else - std::cout << "The Mana World version " << + std::cout << "Aethyra version " << "(local build?, PACKAGE_VERSION is not defined)" << std::endl; #endif } @@ -469,16 +486,16 @@ void parseOptions(int argc, char *argv[], Options &options) const char *optstring = "hvud:U:P:Dp:C:H:"; const struct option long_options[] = { - { "help", no_argument, 0, 'h' }, - { "version", no_argument, 0, 'v' }, - { "skipupdate", no_argument, 0, 'u' }, + { "configfile", required_argument, 0, 'C' }, { "data", required_argument, 0, 'd' }, - { "username", required_argument, 0, 'U' }, - { "password", required_argument, 0, 'P' }, { "default", no_argument, 0, 'D' }, { "playername", required_argument, 0, 'p' }, - { "configfile", required_argument, 0, 'C' }, + { "password", required_argument, 0, 'P' }, + { "help", no_argument, 0, 'h' }, { "updatehost", required_argument, 0, 'H' }, + { "skipupdate", no_argument, 0, 'u' }, + { "username", required_argument, 0, 'U' }, + { "version", no_argument, 0, 'v' }, { 0 } }; @@ -490,36 +507,36 @@ void parseOptions(int argc, char *argv[], Options &options) break; switch (result) { - default: // Unknown option - case 'h': - options.printHelp = true; - break; - case 'v': - options.printVersion = true; - break; - case 'u': - options.skipUpdate = true; + case 'C': + options.configPath = optarg; break; case 'd': options.dataPath = optarg; break; - case 'U': - options.username = optarg; - break; - case 'P': - options.password = optarg; - break; case 'D': options.chooseDefault = true; break; + default: // Unknown option + case 'h': + options.printHelp = true; + break; + case 'H': + options.updateHost = optarg; + break; case 'p': options.playername = optarg; break; - case 'C': - options.configPath = optarg; + case 'P': + options.password = optarg; break; - case 'H': - options.updateHost = optarg; + case 'u': + options.skipUpdate = true; + break; + case 'U': + options.username = optarg; + break; + case 'v': + options.printVersion = true; break; } } @@ -597,6 +614,18 @@ void accountLogin(Network *network, LoginData *loginData) config.setValue("remember", loginData->remember); } +inline int MIN(int x, int y) +{ + return x < y ? x : y; +} + +void positionDialog(Window *dialog, int screenWidth, int screenHeight) +{ + dialog->setPosition( + MIN(screenWidth * 5 / 8, screenWidth - dialog->getWidth()), + MIN(screenHeight * 5 / 8, screenHeight - dialog->getHeight())); +} + void charLogin(Network *network, LoginData *loginData) { logger->log("Trying to connect to char server..."); @@ -716,13 +745,39 @@ int main(int argc, char *argv[]) if (!options.password.empty()) { loginData.password = options.password; } - loginData.hostname = config.getValue("host", "server.themanaworld.org"); - loginData.port = (short)config.getValue("port", 0); + loginData.hostname = config.getValue("host", "www.aethyra.org"); + loginData.port = (short)config.getValue("port", 21001); loginData.remember = config.getValue("remember", 0); loginData.registerLogin = false; SDLNet_Init(); Network *network = new Network(); + + // Set the most appropriate wallpaper, based on screen width + int screenWidth = (int) config.getValue("screenwidth", defaultScreenWidth); + int screenHeight = static_cast<int>(config.getValue("screenheight", + defaultScreenHeight)); + std::string wallpaperName; + + if (screenWidth <= 800) + wallpaperName = "graphics/images/login_wallpaper.png"; + else if (screenWidth <= 1024) + wallpaperName = "graphics/images/login_wallpaper_1024x768.png"; + else if (screenWidth <= 1280) + wallpaperName = "graphics/images/login_wallpaper_1280x960.png"; + else if (screenWidth <= 1440) + wallpaperName = "graphics/images/login_wallpaper_1440x1080.png"; + else + wallpaperName = "graphics/images/login_wallpaper_1600x1200.png"; + + login_wallpaper = ResourceManager::getInstance()-> getImage(wallpaperName); + + if (!login_wallpaper) + logger->log("Couldn't load %s as wallpaper", wallpaperName.c_str()); + + // Needs to be created in main, as the updater uses it + textColour = new Colour(); + while (state != EXIT_STATE) { // Handle SDL events @@ -758,16 +813,6 @@ int main(int argc, char *argv[]) } } - if (!login_wallpaper) - { - login_wallpaper = ResourceManager::getInstance()-> - getImage("graphics/images/login_wallpaper.png"); - if (!login_wallpaper) - { - logger->error("Couldn't load login_wallpaper.png"); - } - } - if (progressBar->isVisible()) { progressBar->setProgress(progressBar->getProgress() + 0.005f); @@ -796,7 +841,7 @@ int main(int argc, char *argv[]) // Reload the wallpaper in case that it was updated login_wallpaper->decRef(); login_wallpaper = ResourceManager::getInstance()-> - getImage("graphics/images/login_wallpaper.png"); + getImage(wallpaperName); break; // Those states don't cause a network disconnect @@ -835,6 +880,7 @@ int main(int argc, char *argv[]) false); // Load XML databases + ColorDB::load(); ItemDB::load(); MonsterDB::load(); NPCDB::load(); @@ -849,33 +895,48 @@ int main(int argc, char *argv[]) state = ACCOUNT_STATE; } else { currentDialog = new LoginDialog(&loginData); + positionDialog(currentDialog, screenWidth, + screenHeight); } break; case REGISTER_STATE: logger->log("State: REGISTER"); currentDialog = new RegisterDialog(&loginData); + positionDialog(currentDialog, screenWidth, screenHeight); break; case CHAR_SERVER_STATE: logger->log("State: CHAR_SERVER"); + + if (n_server == 1) + { + SERVER_INFO *si = *server_info; + loginData.hostname = iptostring(si->address); + loginData.port = si->port; + loginData.updateHost = si->updateHost; + state = UPDATE_STATE; + } + else { int nextState = (options.skipUpdate) ? LOADDATA_STATE : UPDATE_STATE; currentDialog = new ServerSelectDialog(&loginData, - nextState); - } - if (options.chooseDefault || options.playername != "") { - ((ServerSelectDialog*) currentDialog)->action( - gcn::ActionEvent(NULL, "ok")); + nextState); + positionDialog(currentDialog, screenWidth, + screenHeight); + if (options.chooseDefault || options.playername != "") + { + ((ServerSelectDialog*) currentDialog)->action( + gcn::ActionEvent(NULL, "ok")); + } } break; - case CHAR_SELECT_STATE: logger->log("State: CHAR_SELECT"); currentDialog = new CharSelectDialog(network, &charInfo, 1 - loginData.sex); - + positionDialog(currentDialog, screenWidth, screenHeight); if (((CharSelectDialog*) currentDialog)-> selectByName(options.playername)) options.chooseDefault = true; @@ -923,13 +984,21 @@ int main(int argc, char *argv[]) setUpdatesDir(); logger->log("State: UPDATE"); - currentDialog = new UpdaterWindow(updateHost, - homeDir + "/" + updatesDir); + + if (options.skipUpdate) { + state = LOADDATA_STATE; + } else { + currentDialog = new UpdaterWindow(updateHost, + homeDir + "/" + updatesDir); + positionDialog(currentDialog, screenWidth, + screenHeight); + } break; case ERROR_STATE: logger->log("State: ERROR"); currentDialog = new OkDialog("Error", errorMessage); + positionDialog(currentDialog, screenWidth, screenHeight); currentDialog->addActionListener(&errorListener); currentDialog = NULL; // OkDialog deletes itself network->disconnect(); @@ -965,8 +1034,15 @@ int main(int argc, char *argv[]) break; } } + /* + * This loop can really stress the CPU, for no reason since it's + * just constantly redrawing the wallpaper. Added the following + * usleep to limit it to 20 FPS during the login sequence + */ + usleep(50000); } + delete textColour; #ifdef PACKAGE_VERSION delete versionLabel; #endif |