diff --git a/project/jni/application/commandergenius/commandergenius b/project/jni/application/commandergenius/commandergenius index 9c3f6dab2..d1b8a7ae0 160000 --- a/project/jni/application/commandergenius/commandergenius +++ b/project/jni/application/commandergenius/commandergenius @@ -1 +1 @@ -Subproject commit 9c3f6dab2c39372aa6bcc6d6eccd8cf78d2f4be7 +Subproject commit d1b8a7ae03b1a0960722abbab38bbb8fca98e7cd diff --git a/project/jni/application/openarena/engine b/project/jni/application/openarena/engine index 82513e886..9104eb974 160000 --- a/project/jni/application/openarena/engine +++ b/project/jni/application/openarena/engine @@ -1 +1 @@ -Subproject commit 82513e88619941eef9649a0ef73c2b866d3fd005 +Subproject commit 9104eb9749bd9ef21805cc1ac0d5a1840adf46d8 diff --git a/project/jni/application/openarena/vm b/project/jni/application/openarena/vm index 5c6363076..26cafdcda 160000 --- a/project/jni/application/openarena/vm +++ b/project/jni/application/openarena/vm @@ -1 +1 @@ -Subproject commit 5c6363076d61fecfa97889f5c45ec422ba890d99 +Subproject commit 26cafdcdab7099d4992e747649f98ac42a3a8be8 diff --git a/project/jni/application/openttd/AndroidAppSettings.cfg b/project/jni/application/openttd/AndroidAppSettings.cfg index b63ad949d..7bf0af636 100644 --- a/project/jni/application/openttd/AndroidAppSettings.cfg +++ b/project/jni/application/openttd/AndroidAppSettings.cfg @@ -17,6 +17,7 @@ CompatibilityHacks=n CompatibilityHacksStaticInit=n CompatibilityHacksTextInputEmulatesHwKeyboard=n CompatibilityHacksPreventAudioChopping=n +CompatibilityHacksAppIgnoresAudioBufferSize=n AppUsesMouse=y AppNeedsTwoButtonMouse=y ShowMouseCursor=n diff --git a/project/jni/application/vcmi-r2387/.gitignore b/project/jni/application/vcmi-r2387/.gitignore new file mode 100644 index 000000000..11ed32df9 --- /dev/null +++ b/project/jni/application/vcmi-r2387/.gitignore @@ -0,0 +1,10 @@ +libvcmi.so +libvcmi.a +AI +Scripting +debug +out +vcmiserver +vcmiserver.zip +build.log +AndroidData/binaries.zip diff --git a/project/jni/application/vcmi-r2387/AndroidAppSettings.cfg b/project/jni/application/vcmi-r2387/AndroidAppSettings.cfg new file mode 100644 index 000000000..f45e99ef5 --- /dev/null +++ b/project/jni/application/vcmi-r2387/AndroidAppSettings.cfg @@ -0,0 +1,54 @@ +# The application settings for Android libSDL port +AppSettingVersion=17 +LibSdlVersion=1.2 +AppName="VCMI" +AppFullName=eu.vcmi +ScreenOrientation=h +InhibitSuspend=n +AppDataDownloadUrl="!Data files|data1.zip^!Data files|data2.zip^!Data files|data3.zip^" +VideoDepthBpp=16 +NeedDepthBuffer=n +NeedStencilBuffer=n +NeedGles2=n +SwVideoMode=y +SdlVideoResize=y +SdlVideoResizeKeepAspect=n +CompatibilityHacks=y +CompatibilityHacksStaticInit=n +CompatibilityHacksTextInputEmulatesHwKeyboard=n +CompatibilityHacksPreventAudioChopping=n +CompatibilityHacksAppIgnoresAudioBufferSize=n +AppUsesMouse=y +AppNeedsTwoButtonMouse=y +ShowMouseCursor=n +ForceRelativeMouseMode=n +AppNeedsArrowKeys=n +AppNeedsTextInput=y +AppUsesJoystick=n +AppUsesAccelerometer=n +AppUsesMultitouch=n +NonBlockingSwapBuffers=n +RedefinedKeys="LALT RETURN NO_REMAP NO_REMAP E" +AppTouchscreenKeyboardKeysAmount=0 +AppTouchscreenKeyboardKeysAmountAutoFire=0 +RedefinedKeysScreenKb="LALT RETURN KP_PLUS KP_MINUS SPACE DELETE KP_PLUS KP_MINUS 1 2" +StartupMenuButtonTimeout=3000 +HiddenMenuOptions='OptionalDownloadConfig' +FirstStartMenuOptions='' +MultiABI=y +AppMinimumRAM=64 +AppVersionCode=08605 +AppVersionName="0.86.05" +ResetSdlConfigForThisVersion=y +DeleteFilesOnUpgrade="libsdl-DownloadFinished-0.flag libsdl-DownloadFinished-1.flag libsdl-DownloadFinished-2.flag libsdl-DownloadFinished-3.flag libsdl-DownloadFinished-4.flag libsdl-DownloadFinished-5.flag" +CompiledLibraries="mad sdl_mixer sdl_image sdl_ttf avutil avcore avcodec avformat swscale boost_program_options boost_filesystem boost_iostreams boost_system boost_thread android" +CustomBuildScript=y +AppCflags='' +AppLdflags='' +AppSubdirsBuild='' +AppCmdline='' +ReadmeText='^You may press "Home" now - the data will be downloaded in background' +MinimumScreenSize=s +AdmobPublisherId=n +AdmobTestDeviceId= +AdmobBannerSize= diff --git a/project/jni/application/vcmi-r2387/AndroidBuild.sh b/project/jni/application/vcmi-r2387/AndroidBuild.sh new file mode 100755 index 000000000..d42619359 --- /dev/null +++ b/project/jni/application/vcmi-r2387/AndroidBuild.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +# For some reason I'm getting errors with "make -j4" +make -k ARCH=$1 || exit 1 +[ -f libapplication-$1.so ] || exit 1 +[ -e libapplication.so ] || ln -s libapplication-armeabi.so libapplication.so +exit 0 diff --git a/project/jni/application/vcmi-r2387/AndroidData/data1.zip b/project/jni/application/vcmi-r2387/AndroidData/data1.zip new file mode 100644 index 000000000..be8147f11 Binary files /dev/null and b/project/jni/application/vcmi-r2387/AndroidData/data1.zip differ diff --git a/project/jni/application/vcmi-r2387/AndroidData/data2.zip b/project/jni/application/vcmi-r2387/AndroidData/data2.zip new file mode 100644 index 000000000..54bfa22a4 Binary files /dev/null and b/project/jni/application/vcmi-r2387/AndroidData/data2.zip differ diff --git a/project/jni/application/vcmi-r2387/AndroidData/data3.zip b/project/jni/application/vcmi-r2387/AndroidData/data3.zip new file mode 100644 index 000000000..2f275aeb7 Binary files /dev/null and b/project/jni/application/vcmi-r2387/AndroidData/data3.zip differ diff --git a/project/jni/application/vcmi-r2387/Makefile b/project/jni/application/vcmi-r2387/Makefile new file mode 100644 index 000000000..2c7729603 --- /dev/null +++ b/project/jni/application/vcmi-r2387/Makefile @@ -0,0 +1,89 @@ +ifeq ($(ARCH),) +ARCH:=armeabi +endif + +$(shell mkdir -p $(ARCH)/AI debug/$(ARCH)/AI $(ARCH)/Scripting debug/$(ARCH)/Scripting \ + $(ARCH)/out/vcmi/lib $(ARCH)/out/vcmi/server $(ARCH)/out/vcmi/AI/StupidAI \ + $(ARCH)/out/vcmi/AI/GeniusAI $(ARCH)/out/vcmi/client $(ARCH)/out/vcmi/Scripting/ERM) + +LOCAL_PATH:=$(shell dirname $0) +LOCAL_PATH:=`cd $LOCAL_PATH && pwd` + +SOURCES_LIB:=$(wildcard vcmi/lib/*.cpp vcmi/CConsoleHandler.cpp vcmi/CThreadHelper.cpp) +OBJS_LIB:=$(patsubst %.cpp, $(ARCH)/out/%.o, $(SOURCES_LIB)) + +SOURCES_SERVER:=$(wildcard vcmi/server/*.cpp) +OBJS_SERVER:=$(patsubst %.cpp, $(ARCH)/out/%.o, $(SOURCES_SERVER)) + +SOURCES_STUPIDAI:=$(wildcard vcmi/AI/StupidAI/*.cpp) +OBJS_STUPIDAI:=$(patsubst %.cpp, $(ARCH)/out/%.o, $(SOURCES_STUPIDAI)) + +SOURCES_GENIUSAI:=$(filter-out %/ExpertSystem.cpp, $(wildcard vcmi/AI/GeniusAI/*.cpp)) +OBJS_GENIUSAI:=$(patsubst %.cpp, $(ARCH)/out/%.o, $(SOURCES_GENIUSAI)) + +SOURCES_ERM:=$(wildcard vcmi/Scripting/ERM/*.cpp) +OBJS_ERM:=$(patsubst %.cpp, $(ARCH)/out/%.o, $(SOURCES_ERM)) + +SOURCES_CLIENT:=$(wildcard vcmi/client/*.cpp vcmi/CCallback.cpp) +OBJS_CLIENT:=$(patsubst %.cpp, $(ARCH)/out/%.o, $(SOURCES_CLIENT)) + +all: AndroidData/binaries-$(ARCH).zip libapplication-$(ARCH).so + +AndroidData/binaries-$(ARCH).zip: $(ARCH)/vcmiserver $(ARCH)/AI/libGeniusAI.so $(ARCH)/AI/libStupidAI.so $(ARCH)/Scripting/libvcmiERM.so + rm -f $@ + cd $(ARCH) && zip -r ../$@ $(foreach F, $^, $(patsubst $(ARCH)/%,%,$(F))) + +$(OBJS_SERVER) $(OBJS_LIB) $(OBJS_GENIUSAI) $(OBJS_STUPIDAI) $(OBJS_CLIENT) $(OBJS_ERM): $(ARCH)/out/%.o: %.cpp + ../setEnvironment-$(ARCH).sh sh -c \ + "\$$CXX \ + -c \$$CXXFLAGS -Ivcmi -Ivcmi/lib \ + -DDATA_DIR=\\\"/sdcard/Android/data/eu.vcmi/files\\\" \ + -DBIN_DIR=\\\"/data/data/eu.vcmi/files\\\" \ + -DLIB_DIR=\\\"/data/data/eu.vcmi/files\\\" \ + -DWITH_AVCODEC_DECODE_VIDEO2=1 \ + -Wstrict-aliasing -Wcast-align -Wpointer-arith -Waddress \ + $< -o $@" +# -Werror=strict-aliasing -Werror=cast-align -Werror=pointer-arith -Werror=address + +$(ARCH)/libvcmi.a: $(OBJS_LIB) + ar rcs $@ $^ + +LINK_LIB= \ + env NO_SHARED_LIBS=1 ../setEnvironment-$(ARCH).sh sh -c \ + "\$$CXX \ + -Wl,--whole-archive $^ -Wl,--no-whole-archive -o $@ \ + -shared \$$LDFLAGS \ + -lboost_filesystem-1.45 -lboost_iostreams-1.45 -lboost_system-1.45 -lboost_thread-1.45 && \ + cp $@ debug/$@ && \ + \$$STRIP --strip-unneeded $@" + +$(ARCH)/AI/libGeniusAI.so: $(ARCH)/libvcmi.a $(OBJS_GENIUSAI) + $(LINK_LIB) + +$(ARCH)/AI/libStupidAI.so: $(ARCH)/libvcmi.a $(OBJS_STUPIDAI) + $(LINK_LIB) + +$(ARCH)/Scripting/libvcmiERM.so: $(ARCH)/libvcmi.a $(OBJS_ERM) + $(LINK_LIB) + +$(ARCH)/vcmiserver: $(ARCH)/libvcmi.a $(OBJS_SERVER) + env BUILD_EXECUTABLE=1 NO_SHARED_LIBS=1 ../setEnvironment-$(ARCH).sh sh -c \ + "\$$CXX \ + -Wl,--whole-archive $^ -Wl,--no-whole-archive -o $@ \ + \$$LDFLAGS \ + -lboost_filesystem-1.45 -lboost_iostreams-1.45 -lboost_system-1.45 -lboost_thread-1.45 && \ + cp $@ debug/$@ && \ + \$$STRIP --strip-unneeded $@" + +libapplication-$(ARCH).so: $(ARCH)/libvcmi.a $(OBJS_CLIENT) + env ../setEnvironment-$(ARCH).sh sh -c \ + "\$$CXX \ + -Wl,--whole-archive $^ -Wl,--no-whole-archive -o $@ \ + \$$LDFLAGS -lboost_filesystem-1.45 -lboost_iostreams-1.45 -lboost_system-1.45 -lboost_thread-1.45 -lboost_program_options-1.45 && \ + cp $@ debug/$@" +# No need to strip, it's done inside build.sh script + +clean: + rm -rf armeabi* debug AndroidData/binaries-*.zip libapplication*.so + +.PHONY: clean diff --git a/project/jni/application/vcmi-r2387/icon.png b/project/jni/application/vcmi-r2387/icon.png new file mode 100644 index 000000000..970b73138 Binary files /dev/null and b/project/jni/application/vcmi-r2387/icon.png differ diff --git a/project/jni/application/vcmi-r2387/readme.txt b/project/jni/application/vcmi-r2387/readme.txt new file mode 100644 index 000000000..4de332a52 --- /dev/null +++ b/project/jni/application/vcmi-r2387/readme.txt @@ -0,0 +1,14 @@ +Quick compilation guide: +Download my GIT repo from https://github.com/pelya/commandergenius, +then install Android SDK from http://developer.android.com, +NDK r8d from http://crystax.net/ and "ant" tool, then launch commands + android update project -p project + rm project/jni/application/src + ln -s vcmi project/jni/application/src + echo > project/jni/application/vcmi/libvcmi.so +then download VCMI revision 2387 into the dir project/jni/application/vcmi/vcmi +(or create a symlink to it if you already have downloaded it), then apply patch vcmi-android.diff, +then launch build.sh. + +To run it you should have complete installation of Heroes 3: Wake of Gods on your SD card on your device, +in the directory Android/data/eu.vcmi/files diff --git a/project/jni/application/vcmi-r2387/vcmi b/project/jni/application/vcmi-r2387/vcmi new file mode 120000 index 000000000..bb55c5f92 --- /dev/null +++ b/project/jni/application/vcmi-r2387/vcmi @@ -0,0 +1 @@ +../../../../../vcmi \ No newline at end of file diff --git a/project/jni/application/vcmi-r2387/vcmi-android.diff b/project/jni/application/vcmi-r2387/vcmi-android.diff new file mode 100644 index 000000000..726469e1b --- /dev/null +++ b/project/jni/application/vcmi-r2387/vcmi-android.diff @@ -0,0 +1,1553 @@ +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: AI/GeniusAI/CGeniusAI.cpp +=================================================================== +--- AI/GeniusAI/CGeniusAI.cpp (revision 2387) ++++ AI/GeniusAI/CGeniusAI.cpp (working copy) +@@ -1393,6 +1393,7 @@ + } + + ++#ifndef ANDROID + //WTF?!? why is this needed?!?!?! + BattleAction CGlobalAI::activeStack( const CStack * stack ) + { +@@ -1400,4 +1401,5 @@ + ba.stackNumber = stack->ID; + return ba; + } ++#endif + +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/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/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; + +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/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/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/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: 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: server/stdafx.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/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: 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: 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: lib/Connection.h +=================================================================== +--- 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: 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 + { + 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/CLodHandler.cpp +=================================================================== +--- 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; + } +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() diff --git a/project/jni/vcmi b/project/jni/vcmi deleted file mode 120000 index f9de72653..000000000 --- a/project/jni/vcmi +++ /dev/null @@ -1 +0,0 @@ -application/vcmi \ No newline at end of file