619 lines
16 KiB
Diff
619 lines
16 KiB
Diff
Index: lib/Interprocess.h
|
|
===================================================================
|
|
--- lib/Interprocess.h (revision 2170)
|
|
+++ lib/Interprocess.h (working copy)
|
|
@@ -1,3 +1,4 @@
|
|
+/*
|
|
#include <boost/interprocess/sync/interprocess_mutex.hpp>
|
|
#include <boost/interprocess/sync/interprocess_condition.hpp>
|
|
#include <boost/interprocess/mapped_region.hpp>
|
|
@@ -2,2 +3,3 @@
|
|
#include <boost/interprocess/shared_memory_object.hpp>
|
|
+*/
|
|
|
|
@@ -13,6 +15,7 @@
|
|
*
|
|
*/
|
|
|
|
+/*
|
|
struct ServerReady
|
|
{
|
|
bool ready;
|
|
@@ -51,4 +54,48 @@
|
|
delete mr;
|
|
boost::interprocess::shared_memory_object::remove("vcmi_memory");
|
|
}
|
|
-};
|
|
\ No newline at end of file
|
|
+};
|
|
+*/
|
|
+
|
|
+#include <stdio.h>
|
|
+#ifdef WIN32
|
|
+#include <windows.h>
|
|
+#else
|
|
+#include <unistd.h>
|
|
+#endif
|
|
+#include "VCMIDirs.h"
|
|
+
|
|
+#define SERVER_READY_FILENAME "/VcmiServerReadyFlag.lock"
|
|
+
|
|
+void clearServerReady()
|
|
+{
|
|
+ unlink((GVCMIDirs.UserPath + SERVER_READY_FILENAME).c_str());
|
|
+}
|
|
+
|
|
+void waitServerReady()
|
|
+{
|
|
+ while(true)
|
|
+ {
|
|
+ FILE * ff = fopen((GVCMIDirs.UserPath + SERVER_READY_FILENAME).c_str(), "r");
|
|
+ if(ff)
|
|
+ {
|
|
+ fclose(ff);
|
|
+ clearServerReady();
|
|
+ break;
|
|
+ }
|
|
+#ifdef WIN32
|
|
+ Sleep(200);
|
|
+#else
|
|
+ usleep(200000);
|
|
+#endif
|
|
+ }
|
|
+}
|
|
+
|
|
+void notifyServerReady()
|
|
+{
|
|
+ FILE * ff = fopen((GVCMIDirs.UserPath + SERVER_READY_FILENAME).c_str(), "w");
|
|
+ if(!ff)
|
|
+ return;
|
|
+ fwrite("1", 1, 1, ff);
|
|
+ fclose(ff);
|
|
+}
|
|
Index: lib/VCMIDirs.h
|
|
===================================================================
|
|
--- lib/VCMIDirs.h (revision 2170)
|
|
+++ lib/VCMIDirs.h (working copy)
|
|
@@ -1,3 +1,6 @@
|
|
+#ifndef __VCMI__DIRS_H__
|
|
+#define __VCMI__DIRS_H__
|
|
+
|
|
/*
|
|
* UserHome.h, part of VCMI engine
|
|
*
|
|
@@ -13,7 +16,6 @@
|
|
using namespace boost::filesystem;
|
|
#endif
|
|
|
|
-
|
|
/// Where to find the various VCMI files. This is mostly usefull for linux.
|
|
class VCMIDirs {
|
|
public:
|
|
@@ -24,14 +26,25 @@
|
|
#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;
|
|
+
|
|
+#endif
|
|
Index: server/stdafx.h
|
|
===================================================================
|
|
--- server/stdafx.h (revision 2170)
|
|
+++ server/stdafx.h (working copy)
|
|
@@ -15,8 +15,8 @@
|
|
#include "../global.h"
|
|
|
|
#include <boost/crc.hpp>
|
|
-#include <boost/interprocess/mapped_region.hpp>
|
|
-#include <boost/interprocess/shared_memory_object.hpp>
|
|
+//#include <boost/interprocess/mapped_region.hpp>
|
|
+//#include <boost/interprocess/shared_memory_object.hpp>
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <boost/asio.hpp>
|
|
Index: server/CVCMIServer.cpp
|
|
===================================================================
|
|
--- server/CVCMIServer.cpp (revision 2170)
|
|
+++ server/CVCMIServer.cpp (working copy)
|
|
@@ -29,7 +29,7 @@
|
|
using namespace boost;
|
|
using namespace boost::asio;
|
|
using namespace boost::asio::ip;
|
|
-namespace intpr = boost::interprocess;
|
|
+//namespace intpr = boost::interprocess;
|
|
bool end2 = false;
|
|
int port = 3030;
|
|
VCMIDirs GVCMIDirs;
|
|
@@ -379,6 +379,7 @@
|
|
|
|
void CVCMIServer::start()
|
|
{
|
|
+ /*
|
|
ServerReady *sr = NULL;
|
|
intpr::mapped_region *mr;
|
|
try
|
|
@@ -395,13 +396,17 @@
|
|
mr = new intpr::mapped_region(smo,intpr::read_write);
|
|
sr = new(mr->get_address())ServerReady();
|
|
}
|
|
+ */
|
|
+ notifyServerReady();
|
|
|
|
boost::system::error_code error;
|
|
tlog0<<"Listening for connections at port " << acceptor->local_endpoint().port() << std::endl;
|
|
tcp::socket * s = new tcp::socket(acceptor->io_service());
|
|
boost::thread acc(boost::bind(vaccept,acceptor,s,&error));
|
|
+ /*
|
|
sr->setToTrueAndNotify();
|
|
delete mr;
|
|
+ */
|
|
|
|
acc.join();
|
|
if (error)
|
|
Index: server/CGameHandler.cpp
|
|
===================================================================
|
|
--- server/CGameHandler.cpp (revision 2170)
|
|
+++ server/CGameHandler.cpp (working copy)
|
|
@@ -1786,7 +1786,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: 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 <boost/cstdint.hpp>
|
|
#include <assert.h>
|
|
+#ifdef ANDROID
|
|
+#include <android/log.h>
|
|
+#include <sstream>
|
|
+#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<typename T>
|
|
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/Client.cpp
|
|
===================================================================
|
|
--- client/Client.cpp (revision 2170)
|
|
+++ client/Client.cpp (working copy)
|
|
@@ -39,7 +39,7 @@
|
|
#include "../lib/RegisterTypes.cpp"
|
|
|
|
extern std::string NAME;
|
|
-namespace intpr = boost::interprocess;
|
|
+//namespace intpr = boost::interprocess;
|
|
|
|
/*
|
|
* Client.cpp, part of VCMI engine
|
|
@@ -616,18 +616,22 @@
|
|
startServer();
|
|
|
|
th.update();
|
|
+ /*
|
|
intpr::scoped_lock<intpr::interprocess_mutex> slock(shared->sr->mutex);
|
|
while(!shared->sr->ready)
|
|
{
|
|
shared->sr->cond.wait(slock);
|
|
}
|
|
+ */
|
|
+ tlog0 << "Waiting for server..." << std::endl;
|
|
+ waitServerReady();
|
|
if(verbose)
|
|
tlog0 << "Waiting for server: " << th.getDif() << std::endl;
|
|
}
|
|
|
|
CConnection * CServerHandler::connectToServer()
|
|
{
|
|
- if(!shared->sr->ready)
|
|
+ if(!serverThread)
|
|
waitForServer();
|
|
|
|
th.update();
|
|
@@ -642,27 +646,31 @@
|
|
CServerHandler::CServerHandler(bool runServer /*= false*/)
|
|
{
|
|
serverThread = NULL;
|
|
- shared = NULL;
|
|
+ //shared = NULL;
|
|
port = boost::lexical_cast<std::string>(conf.cc.port);
|
|
verbose = false;
|
|
|
|
+ /*
|
|
boost::interprocess::shared_memory_object::remove("vcmi_memory"); //if the application has previously crashed, the memory may not have been removed. to avoid problems - try to destroy it
|
|
try
|
|
{
|
|
shared = new SharedMem();
|
|
} HANDLE_EXCEPTIONC(tlog1 << "Cannot open interprocess memory: ";)
|
|
+ */
|
|
}
|
|
|
|
CServerHandler::~CServerHandler()
|
|
{
|
|
- delete shared;
|
|
+ //delete shared;
|
|
delete serverThread; //detaches, not kills thread
|
|
}
|
|
|
|
void CServerHandler::callServer()
|
|
{
|
|
+ clearServerReady();
|
|
setThreadName(-1, "CServerHandler::callServer");
|
|
std::string comm = std::string(BIN_DIR PATH_SEPARATOR SERVER_NAME " ") + port + " > server_log.txt";
|
|
+ tlog0 << "Invoking VCMI server : " << comm << std::endl;
|
|
std::system(comm.c_str());
|
|
tlog0 << "Server finished\n";
|
|
}
|
|
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 <boost/lexical_cast.hpp>
|
|
+
|
|
|
|
/*
|
|
* 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 +90,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 +128,7 @@
|
|
GDefaultOptions.settingsChanged();
|
|
}
|
|
}
|
|
+
|
|
THC tlog0<<"\tLoading default system settings: "<<pomtime.getDif()<<std::endl;
|
|
|
|
//initializing audio
|
|
@@ -135,10 +138,12 @@
|
|
CCS->soundh->init();
|
|
CCS->soundh->setVolume(GDefaultOptions.soundVolume);
|
|
CCS->musich = new CMusicHandler;
|
|
+
|
|
//CGI->musich->init();
|
|
//CGI->musich->setVolume(GDefaultOptions.musicVolume);
|
|
tlog0<<"\tInitializing sound: "<<pomtime.getDif()<<std::endl;
|
|
tlog0<<"Initializing screen and sound handling: "<<tmh.getDif()<<std::endl;
|
|
+
|
|
|
|
initDLL(::console,logfile);
|
|
const_cast<CGameInfo*>(CGI)->setFromLib();
|
|
@@ -184,11 +189,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 +244,6 @@
|
|
console->start();
|
|
atexit(dispose);
|
|
tlog0 <<"Creating console and logfile: "<<pomtime.getDif() << std::endl;
|
|
-
|
|
conf.init();
|
|
tlog0 <<"Loading settings: "<<pomtime.getDif() << std::endl;
|
|
tlog0 << NAME << std::endl;
|
|
@@ -260,14 +268,18 @@
|
|
tlog0<<"\tInitializing video: "<<pomtime.getDif()<<std::endl;
|
|
|
|
//we can properly play intro only in the main thread, so we have to move loading to the separate thread
|
|
- boost::thread loading(init);
|
|
-
|
|
+#ifdef ANDROID
|
|
+ init();
|
|
if(!vm.count("battle") && !vm.count("nointro"))
|
|
playIntro();
|
|
+#else
|
|
+ boost::thread loading(init);
|
|
|
|
+
|
|
SDL_FillRect(screen,NULL,0);
|
|
CSDL_Ext::update(screen);
|
|
loading.join();
|
|
+#endif
|
|
tlog0<<"Initialization of VCMI (together): "<<total.getDif()<<std::endl;
|
|
|
|
if(!vm.count("battle"))
|
|
@@ -284,8 +296,16 @@
|
|
si->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 +555,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 +605,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 +644,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 +653,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 +683,7 @@
|
|
}
|
|
|
|
delete ev;
|
|
- continue;
|
|
+ return true;
|
|
}
|
|
|
|
//tlog0 << " pushing ";
|
|
@@ -656,7 +691,7 @@
|
|
events.push(ev);
|
|
eventsM.unlock();
|
|
//tlog0 << " done\n";
|
|
- }
|
|
+ return true;
|
|
}
|
|
|
|
void startGame(StartInfo * options, CConnection *serv/* = NULL*/)
|
|
@@ -717,3 +752,4 @@
|
|
ev.user.code = 1;
|
|
SDL_PushEvent(&ev);
|
|
}
|
|
+
|
|
Index: client/Client.h
|
|
===================================================================
|
|
--- client/Client.h (revision 2170)
|
|
+++ client/Client.h (working copy)
|
|
@@ -42,7 +42,7 @@
|
|
public:
|
|
timeHandler th;
|
|
boost::thread *serverThread; //thread that called system to run server
|
|
- SharedMem *shared; //interprocess memory (for waiting for server)
|
|
+ //SharedMem *shared; //interprocess memory (for waiting for server)
|
|
bool verbose; //whether to print log msgs
|
|
std::string port; //port number in text form
|
|
|
|
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
|