Index: server/CGameHandler.cpp =================================================================== --- server/CGameHandler.cpp (revision 2170) +++ server/CGameHandler.cpp (working copy) @@ -1786,7 +1787,7 @@ iw.player = h1->tempOwner; iw.components.push_back(Component(Component::SEC_SKILL, 18, ScholarLevel, 0)); - iw.text.addTxt(MetaString::GENERAL_TXT, 139);//"%s, who has studied magic extensively, + iw.text.addTxt(MetaString::GENERAL_TXT, 139);//%s, who has studied magic extensively, iw.text.addReplacement(h1->name); if (cs2.spells.size())//if found new spell - apply Index: lib/VCMIDirs.h =================================================================== --- lib/VCMIDirs.h (revision 2170) +++ lib/VCMIDirs.h (working copy) @@ -12,6 +12,7 @@ #include using namespace boost::filesystem; #endif +#include /// Where to find the various VCMI files. This is mostly usefull for linux. @@ -24,14 +25,23 @@ #ifdef _WIN32 UserPath = DATA_DIR; #else - // Find vcmi user directory and create it if necessary - std::string home_dir = getenv("HOME"); - UserPath = path(home_dir + "/.vcmi").string(); - - create_directory(UserPath); - create_directory(UserPath + "/config"); - create_directory(UserPath + "/Games"); + try { + // Find vcmi user directory and create it if necessary + std::string home_dir = "."; + if( getenv("HOME") != NULL ) + home_dir = getenv("HOME"); + UserPath = path(home_dir + "/.vcmi").string(); +#ifdef ANDROID + UserPath = DATA_DIR; #endif + create_directory(UserPath); + create_directory(UserPath + "/config"); + create_directory(UserPath + "/Games"); + } + catch(const std::exception & e) + { + } +#endif } }; extern VCMIDirs GVCMIDirs; Index: CConsoleHandler.cpp =================================================================== --- CConsoleHandler.cpp (revision 2170) +++ CConsoleHandler.cpp (working copy) @@ -143,6 +143,7 @@ void CConsoleHandler::setColor(int level) { +#ifndef ANDROID TColor color; switch(level) { @@ -179,6 +180,7 @@ #else std::cout << color; #endif +#endif } int CConsoleHandler::run() Index: global.h =================================================================== --- global.h (revision 2170) +++ global.h (working copy) @@ -10,6 +10,10 @@ using boost::logic::tribool; #include #include +#ifdef ANDROID +#include +#include +#endif //filesystem version 3 causes problems (and it's default as of boost 1.46) #define BOOST_FILESYSTEM_VERSION 2 typedef boost::uint64_t ui64; //unsigned int 64 bits (8 bytes) @@ -618,20 +622,45 @@ class CLogger //logger, prints log info to console and saves in file { const int lvl; +#ifdef ANDROID + std::ostringstream buf; + int androidloglevel; + void outputAndroid() + { + int pos = buf.str().find("\n"); + while( pos >= 0 ) + { + __android_log_print(androidloglevel, "VCMI", "%s", buf.str().substr(0, pos).c_str() ); + buf.str( buf.str().substr(pos+1) ); + pos = buf.str().find("\n"); + } + } +#endif public: CLogger& operator<<(std::ostream& (*fun)(std::ostream&)) { +#ifdef ANDROID + buf << fun; + outputAndroid(); +#else if(lvl < CONSOLE_LOGGING_LEVEL) + { std::cout << fun; + } if((lvl < FILE_LOGGING_LEVEL) && logfile) *logfile << fun; +#endif return *this; } template CLogger & operator<<(const T & data) { +#ifdef ANDROID + buf << data; + outputAndroid(); +#else if(lvl < CONSOLE_LOGGING_LEVEL) { if(console) @@ -641,10 +670,25 @@ } if((lvl < FILE_LOGGING_LEVEL) && logfile) *logfile << data << std::flush; +#endif return *this; } - CLogger(const int Lvl) : lvl(Lvl) {} + CLogger(const int Lvl) : lvl(Lvl) + { +#ifdef ANDROID + androidloglevel = ANDROID_LOG_INFO; + switch(lvl) { + case 0: androidloglevel = ANDROID_LOG_INFO; break; + case 1: androidloglevel = ANDROID_LOG_FATAL; break; + case 2: androidloglevel = ANDROID_LOG_ERROR; break; + case 3: androidloglevel = ANDROID_LOG_WARN; break; + case 4: androidloglevel = ANDROID_LOG_INFO; break; + case 5: androidloglevel = ANDROID_LOG_DEBUG; break; + case 6: case -2: androidloglevel = ANDROID_LOG_VERBOSE; break; + } +#endif + } }; extern DLL_EXPORT CLogger tlog0; //green - standard progress info Index: client/GUIBase.cpp =================================================================== --- client/GUIBase.cpp (revision 2170) +++ client/GUIBase.cpp (working copy) @@ -11,6 +11,7 @@ #include "../CThreadHelper.h" #include "CConfigHandler.h" #include + /* * GUIBase.cpp, part of VCMI engine @@ -364,6 +365,26 @@ } } HANDLE_EXCEPTION } + +void CGuiHandler::loopInitFromMainThread() +{ + setThreadName(-1, "CGuiHandler::run"); + CCS->curh->centerCursor(); + mainFPSmng->init(); // resets internal clock, needed for FPS manager +} + +bool CGuiHandler::loopFromMainThread() +{ + if(terminate) + return false; + if(curInt) + curInt->update(); // calls a update and drawing process of the loaded game interface object at the moment + + mainFPSmng->framerateDelay(); // holds a constant FPS + return true; +} + + CGuiHandler::CGuiHandler() :lastClick(-500, -500) Index: client/CMT.cpp =================================================================== --- client/CMT.cpp (revision 2170) +++ client/CMT.cpp (working copy) @@ -90,8 +92,10 @@ void dispose(); void playIntro(); static void listenForEvents(); +static bool loopListenForEvents(bool block); void requestChangingResolution(); void startGame(StartInfo * options, CConnection *serv = NULL); + #ifndef _WIN32 #ifndef _GNU_SOURCE @@ -126,6 +130,7 @@ GDefaultOptions.settingsChanged(); } } + THC tlog0<<"\tLoading default system settings: "<soundh->init(); CCS->soundh->setVolume(GDefaultOptions.soundVolume); CCS->musich = new CMusicHandler; + //CGI->musich->init(); //CGI->musich->setVolume(GDefaultOptions.musicVolume); tlog0<<"\tInitializing sound: "<(CGI)->setFromLib(); @@ -184,11 +191,15 @@ } +#ifdef ANDROID +int SDL_main(int argc, char** argv) +#else #ifdef _WIN32 int _tmain(int argc, _TCHAR* argv[]) #else int main(int argc, char** argv) #endif +#endif { tlog0 << "Starting... " << std::endl; po::options_description opts("Allowed options"); @@ -235,7 +246,6 @@ console->start(); atexit(dispose); tlog0 <<"Creating console and logfile: "<playerInfos[1].color = 1; startGame(si); } +#ifdef ANDROID + GH.loopInitFromMainThread(); + while( GH.loopFromMainThread() ) + { + while( loopListenForEvents(false) ); + } +#else mainGUIThread = new boost::thread(&CGuiHandler::run, boost::ref(GH)); listenForEvents(); +#endif return 0; } @@ -535,10 +557,12 @@ tlog2 << "Warning: SDL says that " << bpp << "bpp is wrong and suggests " << suggestedBpp << std::endl; } +#ifndef ANDROID if(screen) //screen has been already initialized SDL_QuitSubSystem(SDL_INIT_VIDEO); SDL_InitSubSystem(SDL_INIT_VIDEO); +#endif if((screen = SDL_SetVideoMode(w, h, suggestedBpp, SDL_SWSURFACE|(fullscreen?SDL_FULLSCREEN:0))) == NULL) { @@ -583,14 +607,27 @@ setResolution = true; } + static void listenForEvents() { - while(1) //main SDL events loop - { + while(loopListenForEvents(true)); //main SDL events loop +} + +static bool loopListenForEvents(bool block) +{ SDL_Event *ev = new SDL_Event(); //tlog0 << "Waiting... "; - int ret = SDL_WaitEvent(ev); + int ret = 1; + if( block ) + ret = SDL_WaitEvent(ev); + else + { + if(!SDL_PollEvent(ev)) { + delete ev; + return false; + } + } //tlog0 << "got " << (int)ev->type; if (ret == 0 || (ev->type==SDL_QUIT) || (ev->type == SDL_KEYDOWN && ev->key.keysym.sym==SDLK_F4 && (ev->key.keysym.mod & KMOD_ALT))) @@ -609,7 +646,7 @@ SDL_Delay(750); SDL_Quit(); tlog0 << "Ending...\n"; - break; + return false; } else if(LOCPLINT && ev->type == SDL_KEYDOWN && ev->key.keysym.sym==SDLK_F4) { @@ -618,7 +655,7 @@ setScreenRes(conf.cc.screenx, conf.cc.screeny, conf.cc.bpp, full); GH.totalRedraw(); delete ev; - continue; + return true; } else if(ev->type == SDL_USEREVENT) { @@ -648,7 +685,7 @@ } delete ev; - continue; + return true; } //tlog0 << " pushing "; @@ -656,7 +693,7 @@ events.push(ev); eventsM.unlock(); //tlog0 << " done\n"; - } + return true; } void startGame(StartInfo * options, CConnection *serv/* = NULL*/) @@ -717,3 +754,4 @@ ev.user.code = 1; SDL_PushEvent(&ev); } + Index: client/GUIBase.h =================================================================== --- client/GUIBase.h (revision 2170) +++ client/GUIBase.h (working copy) @@ -546,6 +546,8 @@ CGuiHandler(); ~CGuiHandler(); void run(); // holds the main loop for the whole program after initialization and manages the update/rendering system + void loopInitFromMainThread(); + bool loopFromMainThread(); void totalRedraw(); //forces total redraw (using showAll), sets a flag, method gets called at the end of the rendering void simpleRedraw(); //update only top interface and draw background from buffer, sets a flag, method gets called at the end of the rendering