summaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp268
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