1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +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"
using boost::optional;
shared_ptr<CBattleCallback> cbc;
static shared_ptr<CBattleCallback> cbc;
#define LOGL(text) print(text)
#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));
stackEvaluator = [](const CStack*){ return 1.0; };
}
} priorities;
};
Priorities *priorities = nullptr;
namespace {
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);
}
}
template <typename Container, typename Pred>
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
{
const auto dealtDmgValue = priorities.stackEvaluator(enemy) * damageDealt;
const auto receivedDmgValue = priorities.stackEvaluator(attack.attacker) * damageReceived;
if (!priorities)
priorities = new Priorities;
const auto dealtDmgValue = priorities->stackEvaluator(enemy) * damageDealt;
const auto receivedDmgValue = priorities->stackEvaluator(attack.attacker) * damageReceived;
return dealtDmgValue - receivedDmgValue;
}

View File

@ -7,7 +7,13 @@
#define strcpy_s(a, b, c) strncpy(a, c, b)
#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()
{
@ -22,4 +28,4 @@ extern "C" DLL_EXPORT void GetAiName(char* name)
extern "C" DLL_EXPORT void GetNewBattleAI(shared_ptr<CBattleGameInterface> &out)
{
out = make_shared<CBattleAI>();
}
}

View File

@ -5,7 +5,7 @@
#include "../../CCallback.h"
#include "../../lib/CCreatureHandler.h"
shared_ptr<CBattleCallback> cbc;
static shared_ptr<CBattleCallback> cbc;
CStupidAI::CStupidAI(void)
: side(-1)
@ -60,6 +60,8 @@ bool isMoreProfitable(const EnemyInfo &ei1, const EnemyInfo& ei2)
return (ei1.adi-ei1.adr) < (ei2.adi - ei2.adr);
}
namespace {
int distToNearestNeighbour(BattleHex hex, const ReachabilityInfo::TDistances& dists, BattleHex *chosenHex = nullptr)
{
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);
}
}
static bool willSecondHexBlockMoreEnemyShooters(const BattleHex &h1, const BattleHex &h2)
{
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
assert(0);
}

View File

@ -7,7 +7,13 @@
#define strcpy_s(a, b, c) strncpy(a, c, b)
#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()
{
@ -22,4 +28,4 @@ extern "C" DLL_EXPORT void GetAiName(char* name)
extern "C" DLL_EXPORT void GetNewBattleAI(shared_ptr<CBattleGameInterface> &out)
{
out = make_shared<CStupidAI>();
}
}

View File

@ -5,7 +5,13 @@
#define strcpy_s(a, b, c) strncpy(a, c, b)
#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()
{
@ -20,4 +26,4 @@ extern "C" DLL_EXPORT void GetAiName(char* name)
extern "C" DLL_EXPORT void GetNewAI(shared_ptr<CGlobalAI> &out)
{
out = make_shared<VCAI>();
}
}

View File

@ -284,6 +284,10 @@ int main(int argc, char** argv)
logGlobal->infoStream() << "Creating console and configuring logger: " << pomtime.getDiff();
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
preinitDLL(::console);
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
boost::thread loading(init);
#else
// on Android threaded init is broken
init();
#endif
if(!gNoGUI )
{
@ -372,7 +381,9 @@ int main(int argc, char** argv)
}
CSDL_Ext::update(screen);
#ifndef __ANDROID__
loading.join();
#endif
logGlobal->infoStream()<<"Initialization of VCMI (together): "<<total.getDiff();
if(!vm.count("battle"))

View File

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

View File

@ -158,11 +158,16 @@ std::string VCMIDirs::serverPath() const
// $XDG_DATA_HOME, default: $HOME/.local/share
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 )
return std::string(getenv("XDG_DATA_HOME")) + "/vcmi";
if (getenv("HOME") != nullptr )
return std::string(getenv("HOME")) + "/.local/share" + "/vcmi";
return ".";
#endif
}
std::string VCMIDirs::userSavePath() const
@ -173,21 +178,29 @@ std::string VCMIDirs::userSavePath() const
// $XDG_CACHE_HOME, default: $HOME/.cache
std::string VCMIDirs::userCachePath() const
{
#ifdef __ANDROID__
return userDataPath() + "/cache";
#else
if (getenv("XDG_CACHE_HOME") != nullptr )
return std::string(getenv("XDG_CACHE_HOME")) + "/vcmi";
if (getenv("HOME") != nullptr )
return std::string(getenv("HOME")) + "/.cache" + "/vcmi";
return ".";
#endif
}
// $XDG_CONFIG_HOME, default: $HOME/.config
std::string VCMIDirs::userConfigPath() const
{
#ifdef __ANDROID__
return userDataPath() + "/config";
#else
if (getenv("XDG_CONFIG_HOME") != nullptr )
return std::string(getenv("XDG_CONFIG_HOME")) + "/vcmi";
if (getenv("HOME") != nullptr )
return std::string(getenv("HOME")) + "/.config" + "/vcmi";
return ".";
#endif
}
// $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
std::vector<std::string> ret;
#ifdef __ANDROID__
ret.push_back(userDataPath());
#else
if (getenv("HOME") != nullptr ) // compatibility, should be removed after 0.96
ret.push_back(std::string(getenv("HOME")) + "/.vcmi");
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/local/share/");
}
#endif
return ret;
}

View File

@ -1,3 +1,7 @@
#ifdef __ANDROID__
#include <android/log.h>
#endif
#include "StdInc.h"
#include "CLogger.h"
@ -398,6 +402,11 @@ void CLogConsoleTarget::write(const LogRecord & record)
if(threshold > record.level) return;
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;
if(console)
{

View File

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