From 758a9658d266b3bdd2a82abfef0ea640e34b43e5 Mon Sep 17 00:00:00 2001 From: Gerhard Stein Date: Wed, 20 Feb 2013 16:13:12 +0100 Subject: [PATCH] vcmi-android.diff patch update --- .../jni/application/vcmi/vcmi-android.diff | 1636 ++--------------- 1 file changed, 107 insertions(+), 1529 deletions(-) diff --git a/project/jni/application/vcmi/vcmi-android.diff b/project/jni/application/vcmi/vcmi-android.diff index aea113997..bb9072e47 100644 --- a/project/jni/application/vcmi/vcmi-android.diff +++ b/project/jni/application/vcmi/vcmi-android.diff @@ -1,1535 +1,113 @@ -Index: lib/CLodHandler.cpp +Index: client/CVideoHandler.h =================================================================== ---- lib/CLodHandler.cpp (revision 2387) -+++ lib/CLodHandler.cpp (working copy) -@@ -87,13 +87,15 @@ - Entry ourEntry = *en_it; - - if(length) *length = ourEntry.realSize; -+ enum { SAFETY_MARGIN = 4096 }; // VCMI functions tend to read past the array end, crashing at random - mutex->lock(); - - unsigned char * outp; - if (ourEntry.offset<0) //file is in the sprites/ folder; no compression - { - int result; -- outp = new unsigned char[ourEntry.realSize]; -+ outp = new unsigned char[ourEntry.realSize+SAFETY_MARGIN]; -+ memset(outp+ourEntry.realSize, 0, SAFETY_MARGIN); - FILE * f = fopen((myDir + "/" + ourEntry.realName).c_str(), "rb"); - if (f) - { -@@ -109,16 +111,21 @@ - delete[] outp; - return NULL; - } -- else -+ else -+ { -+ //tlog0 << "Loaded file: " << fname << " size " << ourEntry.realSize << " ptr " << (void *)outp << " safety " << (int)SAFETY_MARGIN << std::endl; - return outp; -+ } - } - else if (ourEntry.size==0) //file is not compressed - { -- outp = new unsigned char[ourEntry.realSize]; -+ outp = new unsigned char[ourEntry.realSize+SAFETY_MARGIN]; -+ memset(outp+ourEntry.realSize, 0, SAFETY_MARGIN); - - LOD.seekg(ourEntry.offset, std::ios::beg); - LOD.read((char*)outp, ourEntry.realSize); - mutex->unlock(); -+ //tlog0 << "Loaded file: " << fname << " size " << ourEntry.realSize << " ptr " << (void *)outp << " safety " << (int)SAFETY_MARGIN << std::endl; - return outp; - } - else //we will decompress file -@@ -131,7 +138,12 @@ - infs2(outp, ourEntry.size, ourEntry.realSize, decomp); - mutex->unlock(); - delete[] outp; -- return decomp; -+ outp = new unsigned char[ourEntry.realSize+SAFETY_MARGIN]; -+ memset(outp+ourEntry.realSize, 0, SAFETY_MARGIN); -+ memcpy(outp, decomp, ourEntry.realSize); -+ delete [] decomp; -+ //tlog0 << "Loaded file: " << fname << " size " << ourEntry.realSize << " ptr " << (void *)outp << " safety " << (int)SAFETY_MARGIN << std::endl; -+ return outp; - } - return NULL; +--- client/CVideoHandler.h (Revision 3221) ++++ client/CVideoHandler.h (Arbeitskopie) +@@ -236,6 +236,7 @@ + #include } -Index: lib/Interprocess.h -=================================================================== ---- lib/Interprocess.h (revision 2387) -+++ lib/Interprocess.h (working copy) -@@ -1,3 +1,4 @@ -+/* - #include - #include - #include -@@ -2,2 +3,3 @@ - #include -+*/ -@@ -13,6 +15,7 @@ - * - */ - -+/* - struct ServerReady ++ + class CVideoPlayer : public IMainVideoPlayer { - bool ready; -@@ -51,4 +54,48 @@ - delete mr; - boost::interprocess::shared_memory_object::remove("vcmi_memory"); - } --}; -\ No newline at end of file -+}; -+*/ -+ -+#include -+#ifdef WIN32 -+#include -+#else -+#include -+#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/Connection.h + private: +@@ -247,7 +248,7 @@ + struct SwsContext *sws; + + unsigned char* buffer; +- AVIOContext * context; ++ ByteIOContext * context; + + // Destination. Either overlay or dest. + SDL_Overlay *overlay; +Index: rpm/vcmi.spec =================================================================== ---- lib/Connection.h (revision 2387) -+++ lib/Connection.h (working copy) -@@ -82,7 +82,9 @@ - { - bool operator()(const std::type_info *a, const std::type_info *b) const - { -- return a->before(*b); -+ // Comparing pointers is bad bad practice, because type_info pointers to the same types -+ // are different inside shared library and the executable that links to that library -+ return strcmp(a->name(), b->name()) > 0; - } - }; - -Index: server/stdafx.h +--- rpm/vcmi.spec (Revision 3221) ++++ rpm/vcmi.spec (Arbeitskopie) +@@ -1,19 +1,19 @@ +-Summary: VCMI is an open-source project aiming to reimplement the entire H3:WoG game engine, giving it new and extended possibilities ++Summary: VCMI is an open-source project aiming to reimplement HMM3:WoG game engine, giving it new and extended possibilities. + Name: vcmi +-Version: 0.9.1 ++Version: 0.9 + Release: 2%{?dist} + License: GPLv2+ ++Group: Amusements/Games + + # The source for this package was pulled from upstream's vcs. Use the + # following commands to generate the tarball: +-# svn export -r HEAD https://vcmi.svn.sourceforge.net/svnroot/vcmi/tags/0.91 vcmi-0.9.1-2 +-# tar -cJf vcmi-0.9.1-2.tar.xz vcmi-0.9.1-2 +-Source: vcmi-0.9.1-2.tar.xz ++# svn export -r HEAD https://vcmi.svn.sourceforge.net/svnroot/vcmi/tags/0.9 vcmi-0.9-2 ++# tar -cJf vcmi-0.9-2.tar.xz vcmi-0.9-2 ++Source: vcmi-0.9-2.tar.xz + + URL: http://forum.vcmi.eu/portal.php +-BuildRequires: cmake + BuildRequires: gcc-c++ >= 4.7.2 +-BuildRequires: SDL-devel ++BuildRequires: SDL-devel + BuildRequires: SDL_image-devel + BuildRequires: SDL_ttf-devel + BuildRequires: SDL_mixer-devel >= 1.2.8 +@@ -29,15 +29,11 @@ + BuildRequires: ffmpeg-libs + + %description +-The purpose of VCMI project is to rewrite the entire H3:WoG engine from scratch, +-giving it new and extended possibilities. ++The purpose of VCMI project is to rewrite entire HOMM 3: WoG engine from scratch, giving it new and extended possibilities. We hope to support mods and new towns already made by fans but abandoned because of game code limitations. + +-VCMI is fan-made open-source project in progress. We already allow support for +-maps of any sizes, higher resolutions, extended engine limits, modding support +-for custom towns, artifacts, heroes, etc... ++VCMI is fan-made open-source project in progress. We already allow support for maps of any sizes, higher resolutions and extended engine limits. However, although working, the game is not finished. There are still many features and functionalities to add, both old and brand new. + +-As yet VCMI is not a standalone program, it uses Wake of Gods files and +-graphics. You need to install WoG before running VCMI. ++As yet VCMI is not standalone program, it uses Wake of Gods files and graphics. You need to install WoG before running VCMI. + + %prep + %setup -q -n %{name}-%{version}-2 +@@ -47,13 +43,13 @@ + make %{?_smp_mflags} + + %install ++rm -rf %{buildroot} + make DESTDIR=%{buildroot} install + + %files +-%doc README COPYING AUTHORS ChangeLog ++%doc README README.linux COPYING AUTHORS ChangeLog + %{_bindir}/vcmiclient + %{_bindir}/vcmiserver +-%{_bindir}/vcmibuilder + %{_libdir}/%{name}/* + + %{_datadir}/%{name}/* +@@ -61,12 +57,6 @@ + %{_datadir}/icons/* + + %changelog +-* Fri Feb 01 2013 VCMI - 0.9.1-2 +-- New upstream release +- +-* Wed Jan 30 2013 VCMI - 0.9.1-1 +-- Development release +- + * Sun Oct 21 2012 VCMI - 0.9-2 + - Second release of 0.9, Fixed battles crash + +Index: lib/VCMIDirs.h =================================================================== ---- server/stdafx.h (revision 2387) -+++ server/stdafx.h (working copy) -@@ -15,8 +15,8 @@ - #include "../global.h" - - #include --#include --#include -+//#include -+//#include - #include - #include - #include -Index: server/CVCMIServer.cpp -=================================================================== ---- server/CVCMIServer.cpp (revision 2387) -+++ 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->get_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 2387) -+++ server/CGameHandler.cpp (working copy) -@@ -638,6 +638,7 @@ - (packType != typeList.getTypeID() || !isAllowedArrangePack((ArrangeStacks*)pack)) && // for dialogs like garrison - states[getCurrentPlayer()].queries.size()) - { -+ tlog0<<__FUNCTION__ << " at " << __FILE__ << ":" << __LINE__ << std::endl; - complain("Answer the query before attempting any further actions!"); - PackageApplied applied; - applied.result = false; -@@ -650,6 +651,7 @@ - else if(apply) - { - bool result = apply->applyOnGH(this,&c,pack); -+ tlog0<<__FUNCTION__ << " at " << __FILE__ << ":" << __LINE__ << std::endl; - tlog5 << "Message successfully applied (result=" << result << ")!\n"; - - //send confirmation that we've applied the package -@@ -1833,7 +1835,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 2387) -+++ 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 2387) -+++ global.h (working copy) -@@ -4,6 +4,7 @@ - #include - #include - #include //std::find -+#include //memcpy - #include //std::find - #include - #include -@@ -725,29 +726,21 @@ - } - - --#if defined(linux) && defined(sparc) --/* SPARC does not support unaligned memory access. Let gcc know when -- * to emit the right code. */ --struct unaligned_Uint16 { ui16 val __attribute__(( packed )); }; --struct unaligned_Uint32 { ui32 val __attribute__(( packed )); }; - - static inline ui16 read_unaligned_u16(const void *p) - { -- const struct unaligned_Uint16 *v = (const struct unaligned_Uint16 *)p; -- return v->val; -+ ui16 out; -+ memcpy(&out, p, sizeof(out)); -+ return out; - } - - static inline ui32 read_unaligned_u32(const void *p) - { -- const struct unaligned_Uint32 *v = (const struct unaligned_Uint32 *)p; -- return v->val; -+ ui32 out; -+ memcpy(&out, p, sizeof(out)); -+ return out; - } - --#else --#define read_unaligned_u16(p) (* reinterpret_cast(p)) --#define read_unaligned_u32(p) (* reinterpret_cast(p)) --#endif -- - //for explicit overrides - #ifdef _MSC_VER - #define OVERRIDE override -Index: AI/GeniusAI/neuralNetwork.cpp -=================================================================== ---- AI/GeniusAI/neuralNetwork.cpp (revision 2387) -+++ AI/GeniusAI/neuralNetwork.cpp (working copy) -@@ -14,9 +14,9 @@ - static bool in = 0; - if(!in) - { -- float x = (rand()+1)/float(RAND_MAX+1); -+ float x = (rand())/float(RAND_MAX); - float f = sqrtf( - 2.0f * log(x) ); -- x = (rand()+1)/float(RAND_MAX+1); -+ x = (rand())/float(RAND_MAX); - kept = f * cosf( 2.0f * M_PI * x ); - in = true; - return f * sinf( 2.0f * M_PI * x ); -Index: Scripting/ERM/ERMParser.cpp -=================================================================== ---- Scripting/ERM/ERMParser.cpp (revision 2387) -+++ Scripting/ERM/ERMParser.cpp (working copy) -@@ -2,7 +2,7 @@ - #include - //To make compilation with older boost versions possible - //Don't know exact version - 1.46 works while 1.42 not --#if BOOST_VERSION >= 104600 -+#if BOOST_VERSION >= 104500 - - #include - #include -Index: client/Graphics.cpp -=================================================================== ---- client/Graphics.cpp (revision 2387) -+++ client/Graphics.cpp (working copy) -@@ -315,8 +315,15 @@ - tasks += GET_SURFACE(backgroundsm[id], b["bg120"].String()); - } - -+#ifdef ANDROID -+ // For debug make it single-threaded -+ for(int i=0;iourImages.size(); ++y) - { -@@ -508,13 +515,20 @@ - pr[3].first = &Graphics::flags4; - pr[3].second+=("AF00.DEF"),("AF01.DEF"),("AF02.DEF"),("AF03.DEF"),("AF04.DEF"), - ("AF05.DEF"),("AF06.DEF"),("AF07.DEF"); -+#ifdef ANDROID -+ // We ain't no need any filthy multithreading -+ for(int g=0; g<4; g++) -+ { -+ loadHeroFlags(pr[g],true); -+ } -+#else - boost::thread_group grupa; - for(int g=3; g>=0; --g) - { - grupa.create_thread(boost::bind(&Graphics::loadHeroFlags,this,boost::ref(pr[g]),true)); - } - grupa.join_all(); -- tlog0 << "Loading and transforming heroes' flags: "<>3) + ((G>>2) << 5) + ((R>>3) << 11); //drop least significant bits of 24 bpp encoded color -+ Uint16 px = (B>>3) + ((G>>2) << 5) + ((R>>3) << 11); //drop least significant bits of 24 bpp encoded color -+ memcpy(ptr, &px, sizeof(px)); - - if(incrementPtr == 1) - ptr += 2; //bpp -@@ -150,9 +150,9 @@ - const int rmask = 0xF800, gmask = 0x7E0, bmask = 0x1F; - const int rshift = 11, gshift = 5, bshift = 0; - -- const Uint8 r5 = (*((Uint16 *)ptr) & rmask) >> rshift, -- b5 = (*((Uint16 *)ptr) & bmask) >> bshift, -- g5 = (*((Uint16 *)ptr) & gmask) >> gshift; -+ const Uint8 r5 = (read_unaligned_u16(ptr) & rmask) >> rshift, -+ b5 = (read_unaligned_u16(ptr) & bmask) >> bshift, -+ g5 = (read_unaligned_u16(ptr) & gmask) >> gshift; - - const Uint32 r8 = (r5 << (8 - rbit)) | (r5 >> (2*rbit - 8)), - g8 = (g5 << (8 - gbit)) | (g5 >> (2*gbit - 8)), -@@ -649,7 +649,7 @@ - return *p; - - case 2: -- return *(Uint16 *)p; -+ return read_unaligned_u16(p); - - case 3: - /* -@@ -661,7 +661,7 @@ - //#endif - - case 4: -- return *(Uint32 *)p; -+ return read_unaligned_u32(p); - - default: - return 0; // shouldn't happen, but avoids warnings -Index: client/Client.cpp -=================================================================== ---- client/Client.cpp (revision 2387) -+++ client/Client.cpp (working copy) -@@ -41,7 +41,7 @@ - #include "../lib/RegisterTypes.cpp" - - extern std::string NAME; --namespace intpr = boost::interprocess; -+//namespace intpr = boost::interprocess; - - /* - * Client.cpp, part of VCMI engine -@@ -476,9 +476,9 @@ - - void CClient::handlePack( CPack * pack ) - { -- CBaseForCLApply *apply = applier->apps[typeList.getTypeID(pack)]; //find the applier -- if(apply) -+ if(applier->apps.find(typeList.getTypeID(pack)) != applier->apps.end()) - { -+ CBaseForCLApply *apply = applier->apps[typeList.getTypeID(pack)]; //find the applier - apply->applyOnClBefore(this,pack); - tlog5 << "\tMade first apply on cl\n"; - gs->apply(pack); -@@ -639,18 +639,22 @@ - startServer(); - - th.update(); -+ /* - intpr::scoped_lock 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(); -@@ -665,27 +669,31 @@ - CServerHandler::CServerHandler(bool runServer /*= false*/) - { - serverThread = NULL; -- shared = NULL; -+ //shared = NULL; - port = boost::lexical_cast(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 2387) -+++ client/GUIBase.cpp (working copy) -@@ -11,6 +11,7 @@ - #include "../CThreadHelper.h" - #include "CConfigHandler.h" - #include -+ - - /* - * GUIBase.cpp, part of VCMI engine -@@ -365,6 +366,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/CAnimation.h -=================================================================== ---- client/CAnimation.h (revision 2387) -+++ client/CAnimation.h (working copy) -@@ -47,6 +47,8 @@ - std::map > offset; - - unsigned char * data; -+ int lodLength; -+ std::string fname; - SDL_Color * palette; - - public: -@@ -125,6 +127,8 @@ - * 2nd byte = size of segment - * raw data (if any) - */ -+// Buggy, disabled for Android -+/* - class CompImage : public IImage - { - //x,y - margins, w,h - sprite size -@@ -158,8 +162,8 @@ - - friend class CompImageLoader; - }; -+*/ - -- - /// Class for handling animation - class CAnimation - { -Index: client/CDefHandler.h -=================================================================== ---- client/CDefHandler.h (revision 2387) -+++ client/CDefHandler.h (working copy) -@@ -30,7 +30,6 @@ - ui32 totalInBlock; - ui32 unknown2; - ui32 unknown3; -- unsigned char data[0]; - }; - - // Def entry in file. Integer fields are all little endian and will -@@ -94,9 +93,9 @@ - - CDefHandler(); //c-tor - ~CDefHandler(); //d-tor -- SDL_Surface * getSprite (int SIndex, const unsigned char * FDef, const BMPPalette * palette) const; //saves picture with given number to "testtt.bmp" -+ SDL_Surface * getSprite (int SIndex, const unsigned char * FDef, const BMPPalette * palette, const std::string & name, int lodLength) const; //saves picture with given number to "testtt.bmp" - static void expand(unsigned char N,unsigned char & BL, unsigned char & BR); -- void openFromMemory(unsigned char * table, const std::string & name); -+ void openFromMemory(unsigned char * table, const std::string & name, int lodLength); - CDefEssential * essentialize(); - - static CDefHandler * giveDef(const std::string & defName); -Index: client/CCreatureAnimation.h -=================================================================== ---- client/CCreatureAnimation.h (revision 2387) -+++ client/CCreatureAnimation.h (working copy) -@@ -66,6 +66,8 @@ - int curFrame, internalFrame; //number of currently displayed frame - unsigned int frames; //number of frames - CCreatureAnim::EAnimType type; //type of animation being displayed (-1 - whole animation, >0 - specified part [default: -1]) -+ int lodLength; -+ std::string fname; - - template - int nextFrameT(SDL_Surface * dest, int x, int y, bool attacker, unsigned char animCount, bool incrementFrame = true, bool yellowBorder = false, bool blueBorder = false, SDL_Rect * destRect = NULL); //0 - success, any other - error //print next -Index: client/CMT.cpp -=================================================================== ---- client/CMT.cpp (revision 2387) -+++ client/CMT.cpp (working copy) -@@ -92,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 -@@ -128,6 +130,7 @@ - GDefaultOptions.settingsChanged(); - } - } -+ - THC tlog0<<"\tLoading default system settings: "<musich->setVolume(GDefaultOptions.musicVolume); - tlog0<<"\tInitializing sound: "<(CGI)->setFromLib(); -@@ -154,7 +158,9 @@ - CCS->curh->show(); - tlog0<<"Screen handler: "<loadHeroAnims(); - tlog0<<"\tMain graphics: "<start(); - atexit(dispose); - tlog0 <<"Creating console and logfile: "<playerInfos[1].color = 1; - startGame(si); - } -+ // Drawing and running event loop from non-main thread does not work at all on Andorid and crashes often on Linux -+#if defined(ANDROID) || defined(LINUX) -+ GH.loopInitFromMainThread(); -+ while( GH.loopFromMainThread() ) -+ { -+ while( loopListenForEvents(false) ); -+ } -+#else - mainGUIThread = new boost::thread(&CGuiHandler::run, boost::ref(GH)); - listenForEvents(); -+#endif - - return 0; - } -@@ -561,10 +585,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) - { -@@ -609,14 +635,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))) -@@ -635,7 +674,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) - { -@@ -644,7 +683,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) - { -@@ -674,7 +713,7 @@ - } - - delete ev; -- continue; -+ return true; - } - - //tlog0 << " pushing "; -@@ -682,7 +721,7 @@ - events.push(ev); - eventsM.unlock(); - //tlog0 << " done\n"; -- } -+ return true; - } - - void startGame(StartInfo * options, CConnection *serv/* = NULL*/) -@@ -742,3 +781,4 @@ - ev.user.code = 1; - SDL_PushEvent(&ev); - } -+ -Index: client/Client.h -=================================================================== ---- client/Client.h (revision 2387) -+++ client/Client.h (working copy) -@@ -43,7 +43,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/CDefHandler.cpp -=================================================================== ---- client/CDefHandler.cpp (revision 2387) -+++ client/CDefHandler.cpp (working copy) -@@ -50,10 +50,19 @@ - SDL_FreeSurface(ourImages[i].bitmap); - } - --void CDefHandler::openFromMemory(unsigned char *table, const std::string & name) -+#define CHECK_LOD_MEM_BLOCK_SIZE1(S, FF, F, L) { \ -+ if( lodLength < (S) ) \ -+ tlog1<<"ERROR in " << FF << " " << F << ":" << L << ": reading past the end of LOD mem block by " << \ -+ (S) - lodLength << " bytes, fname " << name << " size " << lodLength << std::endl; } -+#define CHECK_LOD_MEM_BLOCK_SIZE(S) CHECK_LOD_MEM_BLOCK_SIZE1(S, __FUNCTION__, __FILE__, __LINE__) -+ -+void CDefHandler::openFromMemory(unsigned char *table, const std::string & name, int lodLength) - { -+ //tlog0<<"openFromMemory ptr " << (void *)table <(table); -+ SDefEntry de; -+ memcpy(&de, table, sizeof(de)); - unsigned char *p; - - defName = name; -@@ -61,6 +70,8 @@ - width = SDL_SwapLE32(de.width); - height = SDL_SwapLE32(de.height); - unsigned int totalBlocks = SDL_SwapLE32(de.totalBlocks); -+ -+ //tlog0<<"openFromMemory w " << width << " h " << height << " totalBlocks " << totalBlocks <(&de); -+ p = table; - p += sizeof(de); -- -+ - int totalEntries=0; - for (unsigned int z=0; z(p); -+ //tlog0<<"Megadebug 443 - read size " << p - table <(FDef + BaseOffset); -+ SSpriteDef sd; -+ CHECK_LOD_MEM_BLOCK_SIZE(BaseOffset + sizeof(sd)); -+ -+ memcpy(&sd, FDef + BaseOffset, sizeof(sd)); - - prSize = SDL_SwapLE32(sd.prSize); //TODO use me - defType2 = SDL_SwapLE32(sd.defType2); -@@ -170,12 +206,14 @@ - if (add==4) - add=0; - -+ //tlog0<<"getSprite: 11: SDL_CreateRGBSurface " << FullWidth << ":" << FullHeight << std::endl; - ret = SDL_CreateRGBSurface(SDL_SWSURFACE, FullWidth, FullHeight, 8, 0, 0, 0, 0); - //int tempee2 = readNormalNr(0,4,((unsigned char *)tempee.c_str())); - - BaseOffset += sizeof(SSpriteDef); - int BaseOffsetor = BaseOffset; - -+ //tlog0<<"getSprite: 12: set palette" << std::endl; - for(int i=0; i<256; ++i) - { - SDL_Color pr; -@@ -188,6 +226,7 @@ - - int ftcp=0; - -+ //tlog0<<"getSprite: 13" << std::endl; - // If there's a margin anywhere, just blank out the whole surface. - if (TopMargin > 0 || BottomMargin > 0 || LeftMargin > 0 || RightMargin > 0) { - memset( reinterpret_cast(ret->pixels), 0, FullHeight*FullWidth); -@@ -197,6 +236,7 @@ - if (TopMargin > 0) - ftcp += TopMargin*(FullWidth+add); - -+ //tlog0<<"getSprite: 14: defType2 " << defType2 << std::endl; - switch(defType2) - { - case 0: -@@ -206,7 +246,10 @@ - if (LeftMargin>0) - ftcp += LeftMargin; - -- memcpy(reinterpret_cast(ret->pixels)+ftcp, &FDef[BaseOffset], SpriteWidth); -+ CHECK_LOD_MEM_BLOCK_SIZE(BaseOffset + SpriteWidth); -+ CHECK_OUTBUF_MEM_BLOCK_SIZE(ftcp + SpriteWidth) -+ else -+ memcpy(reinterpret_cast(ret->pixels)+ftcp, &FDef[BaseOffset], SpriteWidth); - ftcp += SpriteWidth; - BaseOffset += SpriteWidth; - -@@ -218,11 +261,12 @@ - - case 1: - { -- const unsigned int * RWEntriesLoc = reinterpret_cast(FDef+BaseOffset); -+ unsigned int RWEntriesLoc = BaseOffset; - BaseOffset += sizeof(int) * SpriteHeight; - for (unsigned int i=0;i0) - ftcp += LeftMargin; - -@@ -230,18 +274,25 @@ - do - { - unsigned int SegmentLength; -+ -+ CHECK_LOD_MEM_BLOCK_SIZE(BaseOffset + 4); - - SegmentType=FDef[BaseOffset++]; - SegmentLength=FDef[BaseOffset++] + 1; -- -+ - if (SegmentType==0xFF) - { -- memcpy(reinterpret_cast(ret->pixels)+ftcp, FDef + BaseOffset, SegmentLength); -+ CHECK_LOD_MEM_BLOCK_SIZE(BaseOffset + SegmentLength); -+ CHECK_OUTBUF_MEM_BLOCK_SIZE(ftcp + SegmentLength) -+ else -+ memcpy(reinterpret_cast(ret->pixels)+ftcp, FDef + BaseOffset, SegmentLength); - BaseOffset+=SegmentLength; - } - else - { -- memset(reinterpret_cast(ret->pixels)+ftcp, SegmentType, SegmentLength); -+ CHECK_OUTBUF_MEM_BLOCK_SIZE(ftcp + SegmentLength) -+ else -+ memset(reinterpret_cast(ret->pixels)+ftcp, SegmentType, SegmentLength); - } - ftcp += SegmentLength; - TotalRowLength += SegmentLength; -@@ -260,6 +311,7 @@ - - case 2: - { -+ CHECK_LOD_MEM_BLOCK_SIZE(BaseOffsetor+2); - BaseOffset = BaseOffsetor + SDL_SwapLE16(read_unaligned_u16(FDef + BaseOffsetor)); - - for (unsigned int i=0;i(ret->pixels)+ftcp, &FDef[BaseOffset], value); -+ CHECK_LOD_MEM_BLOCK_SIZE(BaseOffset + value); -+ CHECK_OUTBUF_MEM_BLOCK_SIZE(ftcp + value) -+ else -+ memcpy(reinterpret_cast(ret->pixels)+ftcp, &FDef[BaseOffset], value); - ftcp += value; - BaseOffset += value; - } - else - { -- memset(reinterpret_cast(ret->pixels)+ftcp, code, value); -+ CHECK_OUTBUF_MEM_BLOCK_SIZE(ftcp + value) -+ else -+ memset(reinterpret_cast(ret->pixels)+ftcp, code, value); - ftcp += value; - } - TotalRowLength+=value; -@@ -304,6 +362,7 @@ - { - for (unsigned int i=0;i0) - ftcp += LeftMargin; -@@ -312,6 +371,7 @@ - - do - { -+ CHECK_LOD_MEM_BLOCK_SIZE(BaseOffset+1); - SegmentType=FDef[BaseOffset++]; - unsigned char code = SegmentType / 32; - unsigned char value = (SegmentType & 31) + 1; -@@ -321,13 +381,18 @@ - - if(code==7) - { -- memcpy((ui8*)ret->pixels + ftcp, FDef + BaseOffset, len); -+ CHECK_LOD_MEM_BLOCK_SIZE(BaseOffset + len); -+ CHECK_OUTBUF_MEM_BLOCK_SIZE(ftcp + len) -+ else -+ memcpy((ui8*)ret->pixels + ftcp, FDef + BaseOffset, len); - ftcp += len; - BaseOffset += len; - } - else - { -- memset((ui8*)ret->pixels + ftcp, code, len); -+ CHECK_OUTBUF_MEM_BLOCK_SIZE(ftcp + len) -+ else -+ memset((ui8*)ret->pixels + ftcp, code, len); - ftcp += len; - } - TotalRowLength+=( LeftMargin>=0 ? value : value+LeftMargin ); -@@ -345,6 +410,7 @@ - break; - - default: -+ tlog1<<"getSprite: Unknown sprite format."<< std::endl; - throw std::string("Unknown sprite format."); - break; - } -@@ -365,11 +431,15 @@ - - CDefHandler * CDefHandler::giveDef(const std::string & defName) - { -- unsigned char * data = spriteh->giveFile(defName, FILE_ANIMATION); -- if(!data) -- throw "bad def name!"; -+ //tlog0<<"giveDef " << defName <giveFile(defName, FILE_ANIMATION, &lodLength); -+ if(!data) { -+ tlog0<<"Bad def name: " << defName <openFromMemory(data, defName); -+ nh->openFromMemory(data, defName, lodLength); - delete [] data; - return nh; - } -Index: client/CCreatureAnimation.cpp -=================================================================== ---- client/CCreatureAnimation.cpp (revision 2387) -+++ client/CCreatureAnimation.cpp (working copy) -@@ -37,15 +37,23 @@ - } - } - -+#define CHECK_LOD_MEM_BLOCK_SIZE1(S, FF, F, L) { \ -+ if( lodLength < (S) ) \ -+ tlog1<<"ERROR in " << FF << " " << F << ":" << L << ": reading past the end of LOD mem block by " << \ -+ (S) - lodLength << " bytes, fname " << fname << " size " << lodLength << std::endl; } -+#define CHECK_LOD_MEM_BLOCK_SIZE(S) CHECK_LOD_MEM_BLOCK_SIZE1(S, __FUNCTION__, __FILE__, __LINE__) -+ - CCreatureAnimation::CCreatureAnimation(std::string name) : internalFrame(0), once(false) - { -- FDef = spriteh->giveFile(name, FILE_ANIMATION); //load main file -+ FDef = spriteh->giveFile(name, FILE_ANIMATION, &lodLength); //load main file -+ fname = name; - - //init anim data - int i,j, totalInBlock; - - defName=name; - i = 0; -+ CHECK_LOD_MEM_BLOCK_SIZE(i+0x310); - DEFType = readNormalNr<4>(i,FDef); i+=4; - fullWidth = readNormalNr<4>(i,FDef); i+=4; - fullHeight = readNormalNr<4>(i,FDef); i+=4; -@@ -64,6 +72,7 @@ - totalEntries=0; - for (int z=0; z frameIDs; - int group = readNormalNr<4>(i,FDef); i+=4; //block ID - totalInBlock = readNormalNr<4>(i,FDef); i+=4; -@@ -76,6 +85,7 @@ - /*int unknown2 = readNormalNr<4>(i,FDef);*/ i+=4; //TODO use me - /*int unknown3 = readNormalNr<4>(i,FDef);*/ i+=4; //TODO use me - i+=13*totalInBlock; //ommiting names -+ CHECK_LOD_MEM_BLOCK_SIZE(i+totalInBlock*4); - for (j=0; j(i,FDef); i+=4; -@@ -173,6 +183,7 @@ - unsigned char SegmentType, SegmentLength; - - i = BaseOffset = SEntries[SIndex].offset; -+ CHECK_LOD_MEM_BLOCK_SIZE(i+32); - /*int prSize = readNormalNr<4>(i, FDef);*/ i += 4; //TODO use me - int defType2 = readNormalNr<4>(i, FDef); i += 4; - FullWidth = readNormalNr<4>(i, FDef); i += 4; -@@ -194,11 +205,12 @@ - { - ftcp += FullWidth * TopMargin; - } -- int *RLEntries = (int*)(FDef + BaseOffset); -+ unsigned char *RLEntries = (FDef + BaseOffset); - BaseOffset += sizeof(int) * SpriteHeight; - for (int i = 0; i < SpriteHeight; i++) - { -- BaseOffset = BaseOffsetor + RLEntries[i]; -+ CHECK_LOD_MEM_BLOCK_SIZE(RLEntries+i*4-FDef); -+ BaseOffset = BaseOffsetor + read_unaligned_u32(RLEntries+i*4); - if (LeftMargin > 0) - { - ftcp += LeftMargin; -@@ -213,6 +225,7 @@ - - do - { -+ CHECK_LOD_MEM_BLOCK_SIZE(BaseOffset+2); - SegmentType = FDef[BaseOffset++]; - SegmentLength = FDef[BaseOffset++]; - -@@ -227,6 +240,8 @@ - { - if(!destRect || (destRect->x <= xB && destRect->x + destRect->w > xB && destRect->y <= yB && destRect->y + destRect->h > yB)) - { -+ if(SegmentType == 0xff) -+ CHECK_LOD_MEM_BLOCK_SIZE(BaseOffset+k+1); - const ui8 colorNr = SegmentType == 0xff ? FDef[BaseOffset+k] : SegmentType; - putPixel(dest, xB, yB, palette[colorNr], colorNr, yellowBorder, blueBorder, aCountMod); - } -Index: client/CAnimation.cpp -=================================================================== ---- client/CAnimation.cpp (revision 2387) -+++ client/CAnimation.cpp (working copy) -@@ -46,6 +46,8 @@ - ~SDLImageLoader(); - }; - -+// It's buggy, disabled for Android build -+/* - class CompImageLoader - { - CompImage * image; -@@ -69,11 +71,18 @@ - CompImageLoader(CompImage * Img); - ~CompImageLoader(); - }; -- -+*/ - /************************************************************************* - * DefFile, class used for def loading * - *************************************************************************/ - -+ -+#define CHECK_LOD_MEM_BLOCK_SIZE1(S, FF, F, L) { \ -+ if( lodLength < (S) ) \ -+ tlog1<<"ERROR in " << FF << " " << F << ":" << L << ": reading past the end of LOD mem block by " << \ -+ (S) - lodLength << " bytes, fname " << fname << " size " << lodLength << std::endl; } -+#define CHECK_LOD_MEM_BLOCK_SIZE(S) CHECK_LOD_MEM_BLOCK_SIZE1(S, __FUNCTION__, __FILE__, __LINE__) -+ - CDefFile::CDefFile(std::string Name): - data(NULL), - palette(NULL) -@@ -91,15 +100,18 @@ - { 0, 0, 0, 192} // 75% - shadow border below selection - }; - -- data = spriteh->giveFile(Name, FILE_ANIMATION); -+ fname = Name; -+ data = spriteh->giveFile(Name, FILE_ANIMATION, &lodLength); - palette = new SDL_Color[256]; - int it = 0; - -+ CHECK_LOD_MEM_BLOCK_SIZE(it+4); - unsigned int type = readNormalNr(data, it); - it+=4; - //int width = readNormalNr(data, it); it+=4;//not used - //int height = readNormalNr(data, it); it+=4; - it+=8; -+ CHECK_LOD_MEM_BLOCK_SIZE(it+4); - unsigned int totalBlocks = readNormalNr(data, it); - it+=4; - -@@ -117,6 +129,7 @@ - - for (unsigned int i=0; isecond[frame]; - -- const SSpriteDef sd = * reinterpret_cast(FDef); -+ SSpriteDef sd; -+ CHECK_LOD_MEM_BLOCK_SIZE((FDef-data)+sizeof(sd)); -+ memcpy(&sd, FDef, sizeof(sd)); - SSpriteDef sprite; - - //sprite.size = SDL_SwapLE32(sd.size);//unused -@@ -170,6 +186,7 @@ - //pixel data is not compressed, copy data to surface - for (unsigned int i=0; i(FDef+currentOffset); -+ const unsigned char * RWEntriesLoc = FDef+currentOffset; - currentOffset += sizeof(ui32) * sprite.height; - - for (unsigned int i=0; isurf->pixels + image->surf->h*image->surf->pitch >= position + size ) - { - memcpy((void *)position, data, size); - position += size; -@@ -323,7 +357,7 @@ - - inline void SDLImageLoader::Load(size_t size, ui8 color) - { -- if (size) -+ if (size && (ui8 *)image->surf->pixels + image->surf->h*image->surf->pitch >= position + size) - { - memset((void *)position, color, size); - position += size; -@@ -345,6 +379,7 @@ - - //////////////////////////////////////////////////////////////////////////////// - -+/* - CompImageLoader::CompImageLoader(CompImage * Img): - image(Img), - position(NULL), -@@ -518,6 +553,7 @@ - image->surf = newPtr; - } - -+*/ - /************************************************************************* - * Classes for images, support loading from file and drawing on surface * - *************************************************************************/ -@@ -625,6 +661,8 @@ - SDL_FreeSurface(surf); - } - -+// Buggy, disabled for Android -+/* - CompImage::CompImage(const CDefFile *data, size_t frame, size_t group): - surf(NULL), - line(NULL), -@@ -845,6 +883,7 @@ - delete [] line; - delete [] palette; - } -+*/ - - /************************************************************************* - * CAnimation for animations handling, can load part of file if needed * -@@ -889,9 +928,11 @@ - //try to get image from def - if (source[group][frame].getType() == JsonNode::DATA_NULL) - { -+ /* - if (compressed) - images[group][frame] = new CompImage(file, frame, group); - else -+ */ - images[group][frame] = new SDLImage(file, frame, group); - } - else //load from separate file -Index: client/GUIBase.h -=================================================================== ---- client/GUIBase.h (revision 2387) -+++ client/GUIBase.h (working copy) -@@ -558,6 +558,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 -Index: client/CSndHandler.cpp -=================================================================== ---- client/CSndHandler.cpp (revision 2387) -+++ client/CSndHandler.cpp (working copy) -@@ -151,16 +151,17 @@ - } - - const char *data = mfile->data(); -- unsigned int numFiles = SDL_SwapLE32(*(Uint32 *)&data[0]); -- struct soundEntry *se = (struct soundEntry *)&data[4]; -+ unsigned int numFiles = SDL_SwapLE32(read_unaligned_u32(&data[0])); -+ struct soundEntry se; - -- for (unsigned int i=0; ifilename; -- entry.offset = SDL_SwapLE32(se->offset); -- entry.size = SDL_SwapLE32(se->size); -+ entry.name = se.filename; -+ entry.offset = SDL_SwapLE32(se.offset); -+ entry.size = SDL_SwapLE32(se.size); - entry.data = mfile->data() + entry.offset; - - entries.push_back(entry); -@@ -186,24 +187,26 @@ - return; - } - const unsigned char *data = (const unsigned char *)mfile->data(); -- unsigned int numFiles = SDL_SwapLE32(*(Uint32 *)&data[0]); -- struct videoEntry *ve = (struct videoEntry *)&data[4]; -+ unsigned int numFiles = SDL_SwapLE32(read_unaligned_u32(&data[0])); -+ struct videoEntry ve; - -- for (unsigned int i=0; ifilename; -- entry.offset = SDL_SwapLE32(ve->offset); -+ entry.name = ve.filename; -+ entry.offset = SDL_SwapLE32(ve.offset); - entry.name.erase(entry.name.find_last_of('.')); - - // There is no size, so check where the next file is - if (i == numFiles - 1) { - entry.size = mfile->size() - entry.offset; - } else { -- struct videoEntry *ve_next = ve+1; -+ struct videoEntry ve_next; -+ memcpy(&ve_next, &data[4+(i+1)*sizeof(ve)], sizeof(ve)); - -- entry.size = SDL_SwapLE32(ve_next->offset) - entry.offset; -+ entry.size = SDL_SwapLE32(ve_next.offset) - entry.offset; - } - entry.data = mfile->data() + entry.offset; - +--- lib/VCMIDirs.h (Revision 3221) ++++ lib/VCMIDirs.h (Arbeitskopie) +@@ -30,7 +30,7 @@ + #else + try { + #ifdef ANDROID +- UserPath = DATA_DIR; ++ UserPath = GameConstants::DATA_DIR; + #else + // Find vcmi user directory and create it if necessary + std::string home_dir = ".";