1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-26 22:57:00 +02:00

Android port.

Conflicts:
	lib/vcmi_endian.h
This commit is contained in:
Ilya Zhuravlev 2014-02-20 22:53:18 +04:00 committed by Ilya Zhuravlev
parent ccc5c69fa2
commit db7cd79cf7
11 changed files with 128 additions and 16 deletions

View File

@ -8,7 +8,7 @@
#include "../../lib/VCMI_Lib.h" #include "../../lib/VCMI_Lib.h"
using boost::optional; using boost::optional;
shared_ptr<CBattleCallback> cbc; static shared_ptr<CBattleCallback> cbc;
#define LOGL(text) print(text) #define LOGL(text) print(text)
#define LOGFL(text, formattingEl) print(boost::str(boost::format(text) % formattingEl)) #define LOGFL(text, formattingEl) print(boost::str(boost::format(text) % formattingEl))
@ -28,8 +28,12 @@ struct Priorities
range::copy(VLC->objh->resVals, std::back_inserter(resourceTypeBaseValues)); range::copy(VLC->objh->resVals, std::back_inserter(resourceTypeBaseValues));
stackEvaluator = [](const CStack*){ return 1.0; }; stackEvaluator = [](const CStack*){ return 1.0; };
} }
} priorities; };
Priorities *priorities = nullptr;
namespace {
int distToNearestNeighbour(BattleHex hex, const ReachabilityInfo::TDistances& dists, BattleHex *chosenHex = nullptr) int distToNearestNeighbour(BattleHex hex, const ReachabilityInfo::TDistances& dists, BattleHex *chosenHex = nullptr)
{ {
@ -52,6 +56,8 @@ bool isCloser(const EnemyInfo & ei1, const EnemyInfo & ei2, const ReachabilityIn
return distToNearestNeighbour(ei1.s->position, dists) < distToNearestNeighbour(ei2.s->position, dists); return distToNearestNeighbour(ei1.s->position, dists) < distToNearestNeighbour(ei2.s->position, dists);
} }
}
template <typename Container, typename Pred> template <typename Container, typename Pred>
auto sum(const Container & c, Pred p) -> decltype(p(*std::begin(c))) auto sum(const Container & c, Pred p) -> decltype(p(*std::begin(c)))
{ {
@ -624,8 +630,10 @@ const TBonusListPtr StackWithBonuses::getAllBonuses(const CSelector &selector, c
int AttackPossibility::damageDiff() const int AttackPossibility::damageDiff() const
{ {
const auto dealtDmgValue = priorities.stackEvaluator(enemy) * damageDealt; if (!priorities)
const auto receivedDmgValue = priorities.stackEvaluator(attack.attacker) * damageReceived; priorities = new Priorities;
const auto dealtDmgValue = priorities->stackEvaluator(enemy) * damageDealt;
const auto receivedDmgValue = priorities->stackEvaluator(attack.attacker) * damageReceived;
return dealtDmgValue - receivedDmgValue; return dealtDmgValue - receivedDmgValue;
} }

View File

@ -7,7 +7,13 @@
#define strcpy_s(a, b, c) strncpy(a, c, b) #define strcpy_s(a, b, c) strncpy(a, c, b)
#endif #endif
const char *g_cszAiName = "Battle AI"; #ifdef __ANDROID__
#define GetGlobalAiVersion BattleAI_GetGlobalAiVersion
#define GetAiName BattleAI_GetAiName
#define GetNewBattleAI BattleAI_GetNewBattleAI
#endif
static const char *g_cszAiName = "Battle AI";
extern "C" DLL_EXPORT int GetGlobalAiVersion() extern "C" DLL_EXPORT int GetGlobalAiVersion()
{ {

View File

@ -5,7 +5,7 @@
#include "../../CCallback.h" #include "../../CCallback.h"
#include "../../lib/CCreatureHandler.h" #include "../../lib/CCreatureHandler.h"
shared_ptr<CBattleCallback> cbc; static shared_ptr<CBattleCallback> cbc;
CStupidAI::CStupidAI(void) CStupidAI::CStupidAI(void)
: side(-1) : side(-1)
@ -60,6 +60,8 @@ bool isMoreProfitable(const EnemyInfo &ei1, const EnemyInfo& ei2)
return (ei1.adi-ei1.adr) < (ei2.adi - ei2.adr); return (ei1.adi-ei1.adr) < (ei2.adi - ei2.adr);
} }
namespace {
int distToNearestNeighbour(BattleHex hex, const ReachabilityInfo::TDistances& dists, BattleHex *chosenHex = nullptr) int distToNearestNeighbour(BattleHex hex, const ReachabilityInfo::TDistances& dists, BattleHex *chosenHex = nullptr)
{ {
int ret = 1000000; int ret = 1000000;
@ -81,6 +83,8 @@ bool isCloser(const EnemyInfo & ei1, const EnemyInfo & ei2, const ReachabilityIn
return distToNearestNeighbour(ei1.s->position, dists) < distToNearestNeighbour(ei2.s->position, dists); return distToNearestNeighbour(ei1.s->position, dists) < distToNearestNeighbour(ei2.s->position, dists);
} }
}
static bool willSecondHexBlockMoreEnemyShooters(const BattleHex &h1, const BattleHex &h2) static bool willSecondHexBlockMoreEnemyShooters(const BattleHex &h1, const BattleHex &h2)
{ {
int shooters[2] = {0}; //count of shooters on hexes int shooters[2] = {0}; //count of shooters on hexes
@ -328,4 +332,3 @@ void CStupidAI::loadGame(CISer<CLoadFile> &h, const int version)
//TODO to be implemented with saving/loading during the battles //TODO to be implemented with saving/loading during the battles
assert(0); assert(0);
} }

View File

@ -7,7 +7,13 @@
#define strcpy_s(a, b, c) strncpy(a, c, b) #define strcpy_s(a, b, c) strncpy(a, c, b)
#endif #endif
const char *g_cszAiName = "Stupid AI 0.1"; #ifdef __ANDROID__
#define GetGlobalAiVersion StupidAI_GetGlobalAiVersion
#define GetAiName StupidAI_GetAiName
#define GetNewBattleAI StupidAI_GetNewBattleAI
#endif
static const char *g_cszAiName = "Stupid AI 0.1";
extern "C" DLL_EXPORT int GetGlobalAiVersion() extern "C" DLL_EXPORT int GetGlobalAiVersion()
{ {

View File

@ -5,7 +5,13 @@
#define strcpy_s(a, b, c) strncpy(a, c, b) #define strcpy_s(a, b, c) strncpy(a, c, b)
#endif #endif
const char *g_cszAiName = "VCAI"; #ifdef __ANDROID__
#define GetGlobalAiVersion VCAI_GetGlobalAiVersion
#define GetAiName VCAI_GetAiName
#define GetNewAI VCAI_GetNewAI
#endif
static const char *g_cszAiName = "VCAI";
extern "C" DLL_EXPORT int GetGlobalAiVersion() extern "C" DLL_EXPORT int GetGlobalAiVersion()
{ {

View File

@ -284,6 +284,10 @@ int main(int argc, char** argv)
logGlobal->infoStream() << "Creating console and configuring logger: " << pomtime.getDiff(); logGlobal->infoStream() << "Creating console and configuring logger: " << pomtime.getDiff();
logGlobal->infoStream() << "The log file will be saved to " << logPath; logGlobal->infoStream() << "The log file will be saved to " << logPath;
#ifdef __ANDROID__
// boost will crash without this
setenv("LANG", "C", 1);
#endif
// Init filesystem and settings // Init filesystem and settings
preinitDLL(::console); preinitDLL(::console);
settings.init(); settings.init();
@ -361,8 +365,13 @@ int main(int argc, char** argv)
#ifndef __ANDROID__
//we can properly play intro only in the main thread, so we have to move loading to the separate thread //we can properly play intro only in the main thread, so we have to move loading to the separate thread
boost::thread loading(init); boost::thread loading(init);
#else
// on Android threaded init is broken
init();
#endif
if(!gNoGUI ) if(!gNoGUI )
{ {
@ -372,7 +381,9 @@ int main(int argc, char** argv)
} }
CSDL_Ext::update(screen); CSDL_Ext::update(screen);
#ifndef __ANDROID__
loading.join(); loading.join();
#endif
logGlobal->infoStream()<<"Initialization of VCMI (together): "<<total.getDiff(); logGlobal->infoStream()<<"Initialization of VCMI (together): "<<total.getDiff();
if(!vm.count("battle")) if(!vm.count("battle"))

View File

@ -19,7 +19,9 @@
#include "../lib/CBuildingHandler.h" #include "../lib/CBuildingHandler.h"
#include "../lib/CSpellHandler.h" #include "../lib/CSpellHandler.h"
#include "../lib/Connection.h" #include "../lib/Connection.h"
#ifndef __ANDROID__
#include "../lib/Interprocess.h" #include "../lib/Interprocess.h"
#endif
#include "../lib/NetPacks.h" #include "../lib/NetPacks.h"
#include "../lib/VCMI_Lib.h" #include "../lib/VCMI_Lib.h"
#include "../lib/VCMIDirs.h" #include "../lib/VCMIDirs.h"
@ -37,7 +39,9 @@
#include "CMT.h" #include "CMT.h"
extern std::string NAME; extern std::string NAME;
#ifndef __ANDROID__
namespace intpr = boost::interprocess; namespace intpr = boost::interprocess;
#endif
/* /*
* Client.cpp, part of VCMI engine * Client.cpp, part of VCMI engine
@ -809,19 +813,25 @@ void CServerHandler::waitForServer()
startServer(); startServer();
th.update(); th.update();
#ifndef __ANDROID__
intpr::scoped_lock<intpr::interprocess_mutex> slock(shared->sr->mutex); intpr::scoped_lock<intpr::interprocess_mutex> slock(shared->sr->mutex);
while(!shared->sr->ready) while(!shared->sr->ready)
{ {
shared->sr->cond.wait(slock); shared->sr->cond.wait(slock);
} }
#endif
if(verbose) if(verbose)
logNetwork->infoStream() << "Waiting for server: " << th.getDiff(); logNetwork->infoStream() << "Waiting for server: " << th.getDiff();
} }
CConnection * CServerHandler::connectToServer() CConnection * CServerHandler::connectToServer()
{ {
#ifndef __ANDROID__
if(!shared->sr->ready) if(!shared->sr->ready)
waitForServer(); waitForServer();
#else
waitForServer();
#endif
th.update(); //put breakpoint here to attach to server before it does something stupid th.update(); //put breakpoint here to attach to server before it does something stupid
CConnection *ret = justConnectToServer(settings["server"]["server"].String(), port); CConnection *ret = justConnectToServer(settings["server"]["server"].String(), port);
@ -839,11 +849,13 @@ CServerHandler::CServerHandler(bool runServer /*= false*/)
port = boost::lexical_cast<std::string>(settings["server"]["port"].Float()); port = boost::lexical_cast<std::string>(settings["server"]["port"].Float());
verbose = true; verbose = true;
#ifndef __ANDROID__
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 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 try
{ {
shared = new SharedMem(); shared = new SharedMem();
} HANDLE_EXCEPTIONC(logNetwork->errorStream() << "Cannot open interprocess memory: ";) } HANDLE_EXCEPTIONC(logNetwork->errorStream() << "Cannot open interprocess memory: ";)
#endif
} }
CServerHandler::~CServerHandler() CServerHandler::~CServerHandler()

View File

@ -22,7 +22,17 @@
* *
*/ */
#ifdef __ANDROID__
// we can't use shared libraries on Android so here's a hack
extern "C" DLL_EXPORT void VCAI_GetAiName(char* name);
extern "C" DLL_EXPORT void VCAI_GetNewAI(shared_ptr<CGlobalAI> &out);
extern "C" DLL_EXPORT void StupidAI_GetAiName(char* name);
extern "C" DLL_EXPORT void StupidAI_GetNewBattleAI(shared_ptr<CGlobalAI> &out);
extern "C" DLL_EXPORT void BattleAI_GetAiName(char* name);
extern "C" DLL_EXPORT void BattleAI_GetNewBattleAI(shared_ptr<CBattleGameInterface> &out);
#endif
template<typename rett> template<typename rett>
shared_ptr<rett> createAny(std::string dllname, std::string methodName) shared_ptr<rett> createAny(std::string dllname, std::string methodName)
@ -35,6 +45,21 @@ shared_ptr<rett> createAny(std::string dllname, std::string methodName)
TGetAIFun getAI = nullptr; TGetAIFun getAI = nullptr;
TGetNameFun getName = nullptr; TGetNameFun getName = nullptr;
#ifdef __ANDROID__
// this is awful but it seems using shared libraries on some devices is even worse
if (dllname.find("libVCAI.so") != std::string::npos) {
getName = (TGetNameFun)VCAI_GetAiName;
getAI = (TGetAIFun)VCAI_GetNewAI;
} else if (dllname.find("libStupidAI.so") != std::string::npos) {
getName = (TGetNameFun)StupidAI_GetAiName;
getAI = (TGetAIFun)StupidAI_GetNewBattleAI;
} else if (dllname.find("libBattleAI.so") != std::string::npos) {
getName = (TGetNameFun)BattleAI_GetAiName;
getAI = (TGetAIFun)BattleAI_GetNewBattleAI;
} else {
throw std::runtime_error("Don't know what to do with " + dllname + " and method " + methodName);
}
#else
#ifdef _WIN32 #ifdef _WIN32
HINSTANCE dll = LoadLibraryA(dllname.c_str()); HINSTANCE dll = LoadLibraryA(dllname.c_str());
@ -69,6 +94,8 @@ shared_ptr<rett> createAny(std::string dllname, std::string methodName)
throw std::runtime_error("Cannot find method " + methodName); throw std::runtime_error("Cannot find method " + methodName);
} }
#endif // __ANDROID__
getName(temp); getName(temp);
logGlobal->infoStream() << "Loaded " << temp; logGlobal->infoStream() << "Loaded " << temp;

View File

@ -158,11 +158,16 @@ std::string VCMIDirs::serverPath() const
// $XDG_DATA_HOME, default: $HOME/.local/share // $XDG_DATA_HOME, default: $HOME/.local/share
std::string VCMIDirs::userDataPath() const std::string VCMIDirs::userDataPath() const
{ {
#ifdef __ANDROID__
// on Android HOME will be set to something like /sdcard/data/Android/is.xyz.vcmi/files/
return std::string(getenv("HOME"));
#else
if (getenv("XDG_DATA_HOME") != nullptr ) if (getenv("XDG_DATA_HOME") != nullptr )
return std::string(getenv("XDG_DATA_HOME")) + "/vcmi"; return std::string(getenv("XDG_DATA_HOME")) + "/vcmi";
if (getenv("HOME") != nullptr ) if (getenv("HOME") != nullptr )
return std::string(getenv("HOME")) + "/.local/share" + "/vcmi"; return std::string(getenv("HOME")) + "/.local/share" + "/vcmi";
return "."; return ".";
#endif
} }
std::string VCMIDirs::userSavePath() const std::string VCMIDirs::userSavePath() const
@ -173,21 +178,29 @@ std::string VCMIDirs::userSavePath() const
// $XDG_CACHE_HOME, default: $HOME/.cache // $XDG_CACHE_HOME, default: $HOME/.cache
std::string VCMIDirs::userCachePath() const std::string VCMIDirs::userCachePath() const
{ {
#ifdef __ANDROID__
return userDataPath() + "/cache";
#else
if (getenv("XDG_CACHE_HOME") != nullptr ) if (getenv("XDG_CACHE_HOME") != nullptr )
return std::string(getenv("XDG_CACHE_HOME")) + "/vcmi"; return std::string(getenv("XDG_CACHE_HOME")) + "/vcmi";
if (getenv("HOME") != nullptr ) if (getenv("HOME") != nullptr )
return std::string(getenv("HOME")) + "/.cache" + "/vcmi"; return std::string(getenv("HOME")) + "/.cache" + "/vcmi";
return "."; return ".";
#endif
} }
// $XDG_CONFIG_HOME, default: $HOME/.config // $XDG_CONFIG_HOME, default: $HOME/.config
std::string VCMIDirs::userConfigPath() const std::string VCMIDirs::userConfigPath() const
{ {
#ifdef __ANDROID__
return userDataPath() + "/config";
#else
if (getenv("XDG_CONFIG_HOME") != nullptr ) if (getenv("XDG_CONFIG_HOME") != nullptr )
return std::string(getenv("XDG_CONFIG_HOME")) + "/vcmi"; return std::string(getenv("XDG_CONFIG_HOME")) + "/vcmi";
if (getenv("HOME") != nullptr ) if (getenv("HOME") != nullptr )
return std::string(getenv("HOME")) + "/.config" + "/vcmi"; return std::string(getenv("HOME")) + "/.config" + "/vcmi";
return "."; return ".";
#endif
} }
// $XDG_DATA_DIRS, default: /usr/local/share/:/usr/share/ // $XDG_DATA_DIRS, default: /usr/local/share/:/usr/share/
@ -198,7 +211,9 @@ std::vector<std::string> VCMIDirs::dataPaths() const
// in vcmi fs last directory has highest priority // in vcmi fs last directory has highest priority
std::vector<std::string> ret; std::vector<std::string> ret;
#ifdef __ANDROID__
ret.push_back(userDataPath());
#else
if (getenv("HOME") != nullptr ) // compatibility, should be removed after 0.96 if (getenv("HOME") != nullptr ) // compatibility, should be removed after 0.96
ret.push_back(std::string(getenv("HOME")) + "/.vcmi"); ret.push_back(std::string(getenv("HOME")) + "/.vcmi");
ret.push_back(M_DATA_DIR); ret.push_back(M_DATA_DIR);
@ -216,6 +231,7 @@ std::vector<std::string> VCMIDirs::dataPaths() const
ret.push_back("/usr/share/"); ret.push_back("/usr/share/");
ret.push_back("/usr/local/share/"); ret.push_back("/usr/local/share/");
} }
#endif
return ret; return ret;
} }

View File

@ -1,3 +1,7 @@
#ifdef __ANDROID__
#include <android/log.h>
#endif
#include "StdInc.h" #include "StdInc.h"
#include "CLogger.h" #include "CLogger.h"
@ -398,6 +402,11 @@ void CLogConsoleTarget::write(const LogRecord & record)
if(threshold > record.level) return; if(threshold > record.level) return;
std::string message = formatter.format(record); std::string message = formatter.format(record);
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_INFO, "VCMI", "%s", message.c_str());
#endif
bool printToStdErr = record.level >= ELogLevel::WARN; bool printToStdErr = record.level >= ELogLevel::WARN;
if(console) if(console)
{ {

View File

@ -19,7 +19,9 @@
#include "CVCMIServer.h" #include "CVCMIServer.h"
#include "../lib/StartInfo.h" #include "../lib/StartInfo.h"
#include "../lib/mapping/CMap.h" #include "../lib/mapping/CMap.h"
#ifndef __ANDROID__
#include "../lib/Interprocess.h" #include "../lib/Interprocess.h"
#endif
#include "../lib/VCMI_Lib.h" #include "../lib/VCMI_Lib.h"
#include "../lib/VCMIDirs.h" #include "../lib/VCMIDirs.h"
#include "CGameHandler.h" #include "CGameHandler.h"
@ -32,7 +34,7 @@
#include "../lib/UnlockGuard.h" #include "../lib/UnlockGuard.h"
#if defined(__GNUC__) && !defined (__MINGW32__) #if defined(__GNUC__) && !defined (__MINGW32__) && !defined(__ANDROID__)
#include <execinfo.h> #include <execinfo.h>
#endif #endif
@ -41,7 +43,9 @@ std::string NAME = GameConstants::VCMI_VERSION + std::string(" (") + NAME_AFFIX
using namespace boost; using namespace boost;
using namespace boost::asio; using namespace boost::asio;
using namespace boost::asio::ip; using namespace boost::asio::ip;
#ifndef __ANDROID__
namespace intpr = boost::interprocess; namespace intpr = boost::interprocess;
#endif
bool end2 = false; bool end2 = false;
int port = 3030; int port = 3030;
@ -391,6 +395,7 @@ void CVCMIServer::newPregame()
void CVCMIServer::start() void CVCMIServer::start()
{ {
#ifndef __ANDROID__
ServerReady *sr = nullptr; ServerReady *sr = nullptr;
intpr::mapped_region *mr; intpr::mapped_region *mr;
try try
@ -407,13 +412,16 @@ void CVCMIServer::start()
mr = new intpr::mapped_region(smo,intpr::read_write); mr = new intpr::mapped_region(smo,intpr::read_write);
sr = new(mr->get_address())ServerReady(); sr = new(mr->get_address())ServerReady();
} }
#endif
boost::system::error_code error; boost::system::error_code error;
logNetwork->infoStream()<<"Listening for connections at port " << acceptor->local_endpoint().port(); logNetwork->infoStream()<<"Listening for connections at port " << acceptor->local_endpoint().port();
auto s = new tcp::socket(acceptor->get_io_service()); auto s = new tcp::socket(acceptor->get_io_service());
boost::thread acc(boost::bind(vaccept,acceptor,s,&error)); boost::thread acc(boost::bind(vaccept,acceptor,s,&error));
#ifndef __ANDROID__
sr->setToTrueAndNotify(); sr->setToTrueAndNotify();
delete mr; delete mr;
#endif
acc.join(); acc.join();
if (error) if (error)
@ -554,7 +562,7 @@ static void handleCommandOptions(int argc, char *argv[])
} }
} }
#if defined(__GNUC__) && !defined (__MINGW32__) #if defined(__GNUC__) && !defined (__MINGW32__) && !defined(__ANDROID__)
void handleLinuxSignal(int sig) void handleLinuxSignal(int sig)
{ {
const int STACKTRACE_SIZE = 100; const int STACKTRACE_SIZE = 100;
@ -585,7 +593,7 @@ int main(int argc, char** argv)
{ {
// Installs a sig sev segmentation violation handler // Installs a sig sev segmentation violation handler
// to log stacktrace // to log stacktrace
#if defined(__GNUC__) && !defined (__MINGW32__) #if defined(__GNUC__) && !defined (__MINGW32__) && !defined(__ANDROID__)
signal(SIGSEGV, handleLinuxSignal); signal(SIGSEGV, handleLinuxSignal);
#endif #endif