summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/Makefile.am4
-rw-r--r--src/client.cpp105
-rw-r--r--src/client.h25
-rw-r--r--src/main.cpp24
-rw-r--r--src/test/testlauncher.cpp170
-rw-r--r--src/test/testlauncher.h54
-rw-r--r--src/test/testmain.cpp287
-rw-r--r--src/test/testmain.h64
9 files changed, 722 insertions, 15 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b7005b144..18379fdf0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -459,6 +459,10 @@ SET(SRCS
utils/mkdir.h
utils/xml.cpp
utils/xml.h
+ test/testlauncher.cpp
+ test/testlauncher.h
+ test/testmain.cpp
+ test/testmain.h
actor.cpp
actor.h
actorsprite.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index 527893598..ead1224d6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -466,6 +466,10 @@ manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \
utils/mutex.h \
utils/xml.cpp \
utils/xml.h \
+ test/testlauncher.cpp \
+ test/testlauncher.h \
+ test/testmain.cpp \
+ test/testmain.h \
actor.cpp \
actor.h \
actorsprite.cpp \
diff --git a/src/client.cpp b/src/client.cpp
index b5cbffd40..4b0319954 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -101,6 +101,9 @@
#include "utils/paths.h"
#include "utils/stringutils.h"
+#include "test/testlauncher.h"
+#include "test/testmain.h"
+
#ifdef __APPLE__
#include <CoreFoundation/CFBundle.h>
#endif
@@ -269,7 +272,25 @@ Client::Client(const Options &options):
mGuiAlpha(1.0f)
{
mInstance = this;
+}
+
+void Client::testsInit()
+{
+ printf ("testInit\n");
+ if (!mOptions.test.empty())
+ {
+ gameInit();
+ }
+ else
+ {
+ logger = new Logger;
+ initLocalDataDir();
+ initConfigDir();
+ }
+}
+void Client::gameInit()
+{
logger = new Logger;
// Load branding information
@@ -644,7 +665,31 @@ Client::Client(const Options &options):
Client::~Client()
{
- logger->log1("Quitting1");
+ if (!mOptions.testMode)
+ gameClear();
+ else
+ testsClear();
+}
+
+void Client::testsClear()
+{
+ if (!mOptions.test.empty())
+ {
+ gameClear();
+ }
+ else
+ {
+ BeingInfo::clear();
+
+ delete logger;
+ logger = nullptr;
+ }
+}
+
+void Client::gameClear()
+{
+ if (logger)
+ logger->log1("Quitting1");
config.removeListener("fpslimit", this);
config.removeListener("guialpha", this);
@@ -681,39 +726,46 @@ Client::~Client()
player_relations.store();
- logger->log1("Quitting2");
+ if (logger)
+ logger->log1("Quitting2");
delete gui;
gui = nullptr;
- logger->log1("Quitting3");
+ if (logger)
+ logger->log1("Quitting3");
delete mainGraphics;
mainGraphics = nullptr;
- logger->log1("Quitting4");
+ if (logger)
+ logger->log1("Quitting4");
// Shutdown libxml
xmlCleanupParser();
- logger->log1("Quitting5");
+ if (logger)
+ logger->log1("Quitting5");
BeingInfo::clear();
// Shutdown sound
sound.close();
- logger->log1("Quitting6");
+ if (logger)
+ logger->log1("Quitting6");
ActorSprite::unload();
ResourceManager::deleteInstance();
- logger->log1("Quitting8");
+ if (logger)
+ logger->log1("Quitting8");
SDL_FreeSurface(mIcon);
- logger->log1("Quitting9");
+ if (logger)
+ logger->log1("Quitting9");
delete userPalette;
userPalette = nullptr;
@@ -721,7 +773,8 @@ Client::~Client()
delete joystick;
joystick = nullptr;
- logger->log1("Quitting10");
+ if (logger)
+ logger->log1("Quitting10");
config.write();
serverConfig.write();
@@ -729,7 +782,8 @@ Client::~Client()
config.clear();
serverConfig.clear();
- logger->log1("Quitting11");
+ if (logger)
+ logger->log1("Quitting11");
delete chatLogger;
chatLogger = nullptr;
@@ -740,7 +794,22 @@ Client::~Client()
mInstance = nullptr;
}
-int Client::exec()
+int Client::testsExec()
+{
+ if (mOptions.test.empty())
+ {
+ TestMain test;
+ return test.exec();
+ }
+ else
+ {
+ TestLauncher launcher(mOptions.test);
+ return launcher.exec();
+ }
+ return 0;
+}
+
+int Client::gameExec()
{
int lastTickTime = tick_time;
@@ -1481,6 +1550,12 @@ void Client::initRootDir()
*/
void Client::initHomeDir()
{
+ initLocalDataDir();
+ initConfigDir();
+}
+
+void Client::initLocalDataDir()
+{
mLocalDataDir = mOptions.localDataDir;
if (mLocalDataDir.empty())
@@ -1509,7 +1584,10 @@ void Client::initHomeDir()
logger->error(strprintf(_("%s doesn't exist and can't be created! "
"Exiting."), mLocalDataDir.c_str()));
}
+}
+void Client::initConfigDir()
+{
mConfigDir = mOptions.configDir;
if (mConfigDir.empty())
@@ -1623,7 +1701,10 @@ void Client::initConfiguration()
// bool oldConfig = false;
// int emptySize = config.getSize();
- configPath = mConfigDir + "/config.xml";
+ if (mOptions.test.empty())
+ configPath = mConfigDir + "/config.xml";
+ else
+ configPath = mConfigDir + "/test.xml";
configFile = fopen(configPath.c_str(), "r");
diff --git a/src/client.h b/src/client.h
index fcb14a660..22eb406eb 100644
--- a/src/client.h
+++ b/src/client.h
@@ -163,6 +163,7 @@ public:
chooseDefault(false),
noOpenGL(false),
safeMode(false),
+ testMode(false),
serverPort(0)
{}
@@ -184,6 +185,8 @@ public:
std::string localDataDir;
std::string screenshotDir;
bool safeMode;
+ bool testMode;
+ std::string test;
std::string serverName;
short serverPort;
@@ -198,7 +201,13 @@ public:
static Client *instance()
{ return mInstance; }
- int exec();
+ void gameInit();
+
+ void testsInit();
+
+ int gameExec();
+
+ int testsExec();
static void setState(State state)
{ instance()->mState = state; }
@@ -280,19 +289,33 @@ public:
private:
void initRootDir();
+
void initHomeDir();
+
void initConfiguration();
+
+ void initLocalDataDir();
+
+ void initConfigDir();
+
void initUpdatesDir();
+
void initScreenshotDir();
+
void initServerConfig(std::string serverName);
bool copyFile(std::string &configPath, std::string &oldConfigPath);
+
bool createConfig(std::string &configPath);
void accountLogin(LoginData *data);
void storeSafeParameters();
+ void gameClear();
+
+ void testsClear();
+
static Client *mInstance;
Options mOptions;
diff --git a/src/main.cpp b/src/main.cpp
index 281687809..31d88082f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -71,6 +71,7 @@ static void printHelp()
" directory") << endl
<< _(" --screenshot-dir : Directory to store screenshots") << endl
<< _(" --safemode : Start game in safe mode") << endl
+ << _(" -T --tests : Start testing drivers and auto configuring") << endl
#ifdef USE_OPENGL
<< _(" --no-opengl : Disable OpenGL for this session") << endl
#endif
@@ -84,7 +85,7 @@ static void printVersion()
static void parseOptions(int argc, char *argv[], Client::Options &options)
{
- const char *optstring = "hvud:U:P:Dc:p:l:L:C:s:";
+ const char *optstring = "hvud:U:P:Dc:p:l:L:C:s:t:T";
const struct option long_options[] =
{
@@ -107,6 +108,8 @@ static void parseOptions(int argc, char *argv[], Client::Options &options)
{ "chat-log-dir", required_argument, 0, 'L' },
{ "screenshot-dir", required_argument, 0, 'i' },
{ "safemode", no_argument, 0, 'm' },
+ { "tests", no_argument, 0, 'T' },
+ { "test", required_argument, 0, 't' },
{ nullptr, 0, 0, 0 }
};
@@ -174,6 +177,14 @@ static void parseOptions(int argc, char *argv[], Client::Options &options)
case 'm':
options.safeMode = true;
break;
+ case 'T':
+ options.testMode = true;
+ options.test = "";
+ break;
+ case 't':
+ options.testMode = true;
+ options.test = std::string(optarg);
+ break;
default:
break;
}
@@ -247,5 +258,14 @@ int main(int argc, char *argv[])
SetCurrentDirectory(PHYSFS_getBaseDir());
#endif
Client client(options);
- return client.exec();
+ if (!options.testMode)
+ {
+ client.gameInit();
+ return client.gameExec();
+ }
+ else
+ {
+ client.testsInit();
+ return client.testsExec();
+ }
}
diff --git a/src/test/testlauncher.cpp b/src/test/testlauncher.cpp
new file mode 100644
index 000000000..5c532a42c
--- /dev/null
+++ b/src/test/testlauncher.cpp
@@ -0,0 +1,170 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * 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
+ * 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 "test/testlauncher.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "graphics.h"
+#include "localconsts.h"
+#include "logger.h"
+#include "sound.h"
+
+#include "gui/theme.h"
+
+#include "utils/gettext.h"
+#include "utils/mkdir.h"
+#include "utils/stringutils.h"
+
+#include "resources/image.h"
+#include "resources/wallpaper.h"
+
+#ifdef WIN32
+#include <windows.h>
+#define sleep(seconds) Sleep((seconds) * 1000)
+#endif
+
+//#include <unistd.h>
+
+#include "debug.h"
+
+TestLauncher::TestLauncher(std::string test) :
+ mTest(test)
+{
+ file.open((Client::getLocalDataDirectory()
+ + std::string("/test.log")).c_str(), std::ios::out);
+}
+
+TestLauncher::~TestLauncher()
+{
+ file.close();
+}
+
+int TestLauncher::exec()
+{
+ if (mTest == "1" || mTest == "2" || mTest == "3")
+ return testBackend();
+ else if (mTest == "4")
+ return testSound();
+ else if (mTest == "5" || mTest == "6" || mTest == "7")
+ return testRescale();
+ else if (mTest == "8" || mTest == "9" || mTest == "10")
+ return testFps();
+
+ return -1;
+}
+
+int TestLauncher::testBackend()
+{
+ Image *img = Theme::getImageFromTheme("graphics/sprites/arrow_up.gif");
+ if (!img)
+ return 1;
+ int cnt = 100;
+
+ for (int f = 0; f < cnt; f ++)
+ {
+ mainGraphics->drawImage(img, cnt * 7, cnt * 5);
+ mainGraphics->updateScreen();
+ }
+
+ sleep(1);
+ return 0;
+}
+
+int TestLauncher::testSound()
+{
+ sound.playGuiSfx("system/newmessage.ogg");
+ sleep(1);
+ sound.playSfx("system/newmessage.ogg", 0, 0);
+ sound.playMusic("sfx/system/newmessage.ogg");
+ sleep(3);
+ sound.stopMusic();
+ return 0;
+}
+
+int TestLauncher::testRescale()
+{
+ Wallpaper::loadWallpapers();
+ const std::string wallpaperName = Wallpaper::getWallpaper(800, 600);
+ Image *img = Theme::getImageFromTheme(wallpaperName);
+ if (!img)
+ return 1;
+
+ sleep(1);
+ return 0;
+}
+
+int TestLauncher::testFps()
+{
+ timeval start;
+ timeval end;
+
+ Wallpaper::loadWallpapers();
+ const std::string wallpaperName = Wallpaper::getWallpaper(800, 600);
+ Image *img[4];
+
+ img[0] = Theme::getImageFromTheme("graphics/sprites/arrow_up.gif");
+ img[1] = Theme::getImageFromTheme("graphics/sprites/arrow_down.gif");
+ img[2] = Theme::getImageFromTheme("graphics/sprites/arrow_left.gif");
+ img[3] = Theme::getImageFromTheme("graphics/sprites/arrow_right.gif");
+ int idx = 0;
+
+ int cnt = 500;
+
+ gettimeofday(&start, NULL);
+ for (int k = 0; k < cnt; k ++)
+ {
+ for (int x = 0; x < 800; x += 20)
+ {
+ for (int y = 0; y < 600; y += 25)
+ {
+ mainGraphics->drawImage(img[idx], x, y);
+ idx ++;
+ if (idx > 3)
+ idx = 0;
+ }
+ }
+ mainGraphics->updateScreen();
+ }
+
+ gettimeofday(&end, NULL);
+ int tFps = calcFps(&start, &end, cnt);
+ file << mTest << std::endl;
+ file << tFps << std::endl;
+
+ sleep(1);
+ return 0;
+}
+
+int TestLauncher::calcFps(timeval *start, timeval *end, int calls)
+{
+ long mtime;
+ long seconds;
+ long useconds;
+
+ seconds = end->tv_sec - start->tv_sec;
+ useconds = end->tv_usec - start->tv_usec;
+
+ mtime = (seconds * 1000 + useconds / 1000.0) + 0.5;
+ if (mtime == 0)
+ return 100000;
+
+ return static_cast<long>(calls) * 1000 / mtime;
+}
diff --git a/src/test/testlauncher.h b/src/test/testlauncher.h
new file mode 100644
index 000000000..19a057722
--- /dev/null
+++ b/src/test/testlauncher.h
@@ -0,0 +1,54 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * 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
+ * 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 TEST_TESTLAUNCHER_H
+#define TEST_TESTLAUNCHER_H
+
+#include "logger.h"
+
+#include <string>
+#include <sys/time.h>
+
+class TestLauncher
+{
+ public:
+ TestLauncher(std::string test);
+
+ ~TestLauncher();
+
+ int exec();
+
+ int calcFps(timeval *start, timeval *end, int calls);
+
+ int testBackend();
+
+ int testSound();
+
+ int testRescale();
+
+ int testFps();
+
+ private:
+ std::string mTest;
+
+ std::ofstream file;
+};
+
+#endif // TEST_TESTLAUNCHER_H
diff --git a/src/test/testmain.cpp b/src/test/testmain.cpp
new file mode 100644
index 000000000..db82592b3
--- /dev/null
+++ b/src/test/testmain.cpp
@@ -0,0 +1,287 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * 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
+ * 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 "test/testmain.h"
+
+#include "utils/gettext.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "localconsts.h"
+
+#include "utils/gettext.h"
+#include "utils/mkdir.h"
+#include "utils/stringutils.h"
+#include "utils/process.h"
+
+#include <iostream>
+
+#include "debug.h"
+
+#ifdef WIN32
+ const std::string fileName = "manaplus.exe";
+#else
+ const std::string fileName = "manaplus";
+#endif
+
+TestMain::TestMain()
+{
+ log = new Logger;
+// log->setLogFile(Client::getLocalDataDirectory()
+// + std::string("/test.log"));
+ log->setLogFile(Client::getLocalDataDirectory()
+ + std::string("/manaplustest.log"));
+}
+
+void TestMain::initConfig()
+{
+ config.init(Client::getConfigDirectory() + "/test.xml");
+// config.setDefaultValues(getConfigDefaults());
+
+ config.setValue("hwaccel", false);
+ config.setValue("screen", false);
+ config.setValue("sound", false);
+ config.setValue("guialpha", 0.8f);
+ config.setValue("remember", true);
+ config.setValue("sfxVolume", 50);
+ config.setValue("musicVolume", 60);
+ config.setValue("fpslimit", 0);
+ config.setValue("customcursor", true);
+ config.setValue("useScreenshotDirectorySuffix", true);
+ config.setValue("ChatLogLength", 128);
+ config.setValue("screenwidth", 800);
+ config.setValue("screenheight", 600);
+}
+
+int TestMain::exec()
+{
+ initConfig();
+ int softwareTest = invokeSoftwareRenderTest("1");
+ int fastOpenGLTest = invokeFastOpenGLRenderTest("2");
+ int safeOpenGLTest = invokeSafeOpenGLRenderTest("3");
+ int soundTest = invokeTest4();
+ int rescaleTest[3];
+ int softFpsTest = -1;
+ int fastOpenGLFpsTest = -1;
+ int safeOpenGLFpsTest = -1;
+ int softFps = 0;
+ int fastOpenGLFps = 0;
+ int safeOpenGLFps = 0;
+
+ int openGLMode = 0;
+ int maxFps = 0;
+ rescaleTest[0] = -1;
+ rescaleTest[1] = -1;
+ rescaleTest[2] = -1;
+ std::string info;
+
+ info += strprintf("%d.%d,%d,%d.", soundTest, softwareTest,
+ fastOpenGLTest, safeOpenGLTest);
+
+ if (!softwareTest)
+ {
+ softFpsTest = invokeSoftwareRenderTest("8");
+ info += strprintf ("%d", softFpsTest);
+ if (!softFpsTest)
+ {
+ softFps = readValue(8);
+ info += strprintf (",%d", softFps);
+ if (!softFps)
+ {
+ softwareTest = -1;
+ softFpsTest = -1;
+ }
+ else
+ {
+ rescaleTest[0] = invokeSoftwareRenderTest("5");
+ info += strprintf (",%d", rescaleTest[0]);
+ }
+ }
+ else
+ {
+ softwareTest = -1;
+ }
+ }
+ info += ".";
+ if (!fastOpenGLTest)
+ {
+ fastOpenGLFpsTest = invokeFastOpenGLRenderTest("9");
+ info += strprintf ("%d", fastOpenGLFpsTest);
+ if (!fastOpenGLFpsTest)
+ {
+ fastOpenGLFps = readValue(9);
+ info += strprintf (",%d", fastOpenGLFps);
+ if (!fastOpenGLFps)
+ {
+ fastOpenGLTest = -1;
+ fastOpenGLFpsTest = -1;
+ }
+ else
+ {
+ rescaleTest[1] = invokeFastOpenGLRenderTest("6");
+ info += strprintf (",%d", rescaleTest[1]);
+ }
+ }
+ else
+ {
+ fastOpenGLTest = -1;
+ }
+ }
+ info += ".";
+ if (!safeOpenGLTest)
+ {
+ safeOpenGLFpsTest = invokeSafeOpenGLRenderTest("10");
+ info += strprintf ("%d", safeOpenGLFpsTest);
+ if (!safeOpenGLFpsTest)
+ {
+ safeOpenGLFps = readValue(10);
+ info += strprintf (",%d", safeOpenGLFps);
+ if (!safeOpenGLFps)
+ {
+ safeOpenGLTest = -1;
+ safeOpenGLFpsTest = -1;
+ }
+ else
+ {
+ rescaleTest[2] = invokeSafeOpenGLRenderTest("7");
+ info += strprintf (",%d", rescaleTest[2]);
+ }
+ }
+ else
+ {
+ safeOpenGLTest = -1;
+ }
+ }
+ info += ".";
+
+ maxFps = softFps;
+ if (maxFps < fastOpenGLFps)
+ {
+ openGLMode = 1;
+ maxFps = fastOpenGLFps;
+ }
+ if (maxFps < safeOpenGLFps)
+ {
+ openGLMode = 2;
+ maxFps = safeOpenGLFps;
+ }
+
+ writeConfig(openGLMode, rescaleTest[openGLMode], soundTest, info);
+ return 0;
+}
+
+void TestMain::writeConfig(int openGLMode, int rescale,
+ int sound, std::string info)
+{
+ config.init(Client::getConfigDirectory() + "/config.xml");
+
+ // searched values
+ config.setValue("opengl", openGLMode);
+ config.setValue("showBackground", !rescale);
+ config.setValue("sound", !sound);
+
+ // better perfomance
+ config.setValue("hwaccel", true);
+ config.setValue("fpslimit", 60);
+ config.setValue("altfpslimit", 2);
+ config.setValue("safemode", false);
+ config.setValue("enableMapReduce", true);
+
+ // stats
+ config.setValue("testInfo", info);
+
+ config.write();
+}
+
+int TestMain::readValue(int ver, int def)
+{
+ std::string tmp;
+ int var;
+ file.open((Client::getLocalDataDirectory()
+ + std::string("/test.log")).c_str(), std::ios::in);
+ if (!getline(file, tmp))
+ {
+ file.close();
+ return def;
+ }
+ var = atoi(tmp.c_str());
+ if (ver != var || !getline(file, tmp))
+ {
+ file.close();
+ return def;
+ }
+ def = atoi(tmp.c_str());
+ file.close();
+ log->log("value for %d = %d", ver, def);
+ return def;
+}
+
+int TestMain::invokeTest(std::string test)
+{
+ config.setValue("opengl", 0);
+
+ config.write();
+ int ret = execFile(fileName, fileName, "-t", test);
+ return ret;
+}
+
+int TestMain::invokeTest4()
+{
+ config.setValue("sound", true);
+ int ret = invokeTest("4");
+
+ log->log("4: %d", ret);
+ return ret;
+}
+
+int TestMain::invokeSoftwareRenderTest(std::string test)
+{
+ config.setValue("opengl", 0);
+ config.write();
+ int ret = execFile(fileName, fileName, "-t", test, 30);
+ log->log("%s: %d", test.c_str(), ret);
+ return ret;
+}
+
+int TestMain::invokeFastOpenGLRenderTest(std::string test)
+{
+#if defined USE_OPENGL
+ config.setValue("opengl", 1);
+#else
+ return -1;
+#endif
+ config.write();
+ int ret = execFile(fileName, fileName, "-t", test, 30);
+ log->log("%s: %d", test.c_str(), ret);
+ return ret;
+}
+
+int TestMain::invokeSafeOpenGLRenderTest(std::string test)
+{
+#if defined USE_OPENGL
+ config.setValue("opengl", 2);
+#else
+ return -1;
+#endif
+ config.write();
+ int ret = execFile(fileName, fileName, "-t", test, 30);
+ log->log("%s: %d", test.c_str(), ret);
+ return ret;
+}
diff --git a/src/test/testmain.h b/src/test/testmain.h
new file mode 100644
index 000000000..de1229454
--- /dev/null
+++ b/src/test/testmain.h
@@ -0,0 +1,64 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * 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
+ * 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 TEST_TESTMAIN_H
+#define TEST_TESTMAIN_H
+
+#include "logger.h"
+
+#include <string>
+
+class TestMain
+{
+ public:
+ TestMain();
+
+ int exec();
+
+ private:
+ void initConfig();
+
+ int readValue(int ver, int def = 0);
+
+ int invokeTest(std::string test);
+
+ int invokeTest3();
+
+ int invokeTest4();
+
+ int invokeTest7();
+
+ int invokeSoftwareRenderTest(std::string test);
+
+ int invokeFastOpenGLRenderTest(std::string test);
+
+ int invokeSafeOpenGLRenderTest(std::string test);
+
+ void testsMain();
+
+ void writeConfig(int openGLMode, int rescale,
+ int sound, std::string info);
+
+ Logger *log;
+
+ std::ifstream file;
+};
+
+#endif // TEST_TESTMAIN_H