diff --git a/changeAppSettings.sh b/changeAppSettings.sh index 5401e5dc1..fb52f35fe 100755 --- a/changeAppSettings.sh +++ b/changeAppSettings.sh @@ -662,6 +662,7 @@ echo CompatibilityHacksStaticInit=$CompatibilityHacksStaticInit >> AndroidAppSet echo CompatibilityHacksTextInputEmulatesHwKeyboard=$CompatibilityHacksTextInputEmulatesHwKeyboard >> AndroidAppSettings.cfg echo CompatibilityHacksPreventAudioChopping=$CompatibilityHacksPreventAudioChopping >> AndroidAppSettings.cfg echo CompatibilityHacksAppIgnoresAudioBufferSize=$CompatibilityHacksAppIgnoresAudioBufferSize >> AndroidAppSettings.cfg +echo CompatibilityHacksAdditionalPreloadedSharedLibraries=\"$CompatibilityHacksAdditionalPreloadedSharedLibraries\" >> AndroidAppSettings.cfg echo AppUsesMouse=$AppUsesMouse >> AndroidAppSettings.cfg echo AppNeedsTwoButtonMouse=$AppNeedsTwoButtonMouse >> AndroidAppSettings.cfg echo ShowMouseCursor=$ShowMouseCursor >> AndroidAppSettings.cfg @@ -879,7 +880,7 @@ fi LibrariesToLoad="\\\"sdl-$LibSdlVersion\\\"" StaticLibraries=`grep 'APP_AVAILABLE_STATIC_LIBS' project/jni/SettingsTemplate.mk | sed 's/.*=\(.*\)/\1/'` -for lib in $CompiledLibraries; do +for lib in $CompiledLibraries $CompatibilityHacksAdditionalPreloadedSharedLibraries; do process=true for lib1 in $StaticLibraries; do if [ "$lib" = "$lib1" ]; then process=false; fi diff --git a/project/jni/application/ballfield/AndroidAppSettings.cfg b/project/jni/application/ballfield/AndroidAppSettings.cfg index 9d57bb463..c09e6df42 100644 --- a/project/jni/application/ballfield/AndroidAppSettings.cfg +++ b/project/jni/application/ballfield/AndroidAppSettings.cfg @@ -35,7 +35,7 @@ RedefinedKeysScreenKb="0 1 2 3 4 5 6 7 8 9" StartupMenuButtonTimeout=3000 HiddenMenuOptions='OptionalDownloadConfig' FirstStartMenuOptions='' -MultiABI=n +MultiABI=y AppMinimumRAM=0 AppVersionCode=101 AppVersionName="1.01" diff --git a/project/jni/application/vcmi-r2387/AndroidAppSettings.cfg b/project/jni/application/vcmi-r2387/AndroidAppSettings.cfg index f45e99ef5..6d3cc6b9f 100644 --- a/project/jni/application/vcmi-r2387/AndroidAppSettings.cfg +++ b/project/jni/application/vcmi-r2387/AndroidAppSettings.cfg @@ -18,6 +18,7 @@ CompatibilityHacksStaticInit=n CompatibilityHacksTextInputEmulatesHwKeyboard=n CompatibilityHacksPreventAudioChopping=n CompatibilityHacksAppIgnoresAudioBufferSize=n +CompatibilityHacksAdditionalPreloadedSharedLibraries="vcmi" AppUsesMouse=y AppNeedsTwoButtonMouse=y ShowMouseCursor=n diff --git a/project/jni/application/vcmi-r2387/Makefile b/project/jni/application/vcmi-r2387/Makefile index 2c7729603..9a8cd2c02 100644 --- a/project/jni/application/vcmi-r2387/Makefile +++ b/project/jni/application/vcmi-r2387/Makefile @@ -29,7 +29,7 @@ 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 +AndroidData/binaries-$(ARCH).zip: $(ARCH)/vcmiserver $(ARCH)/AI/libGeniusAI.so $(ARCH)/AI/libStupidAI.so $(ARCH)/Scripting/libvcmiERM.so # $(ARCH)/libvcmi.so rm -f $@ cd $(ARCH) && zip -r ../$@ $(foreach F, $^, $(patsubst $(ARCH)/%,%,$(F))) @@ -45,41 +45,51 @@ $(OBJS_SERVER) $(OBJS_LIB) $(OBJS_GENIUSAI) $(OBJS_STUPIDAI) $(OBJS_CLIENT) $(OB $< -o $@" # -Werror=strict-aliasing -Werror=cast-align -Werror=pointer-arith -Werror=address -$(ARCH)/libvcmi.a: $(OBJS_LIB) - ar rcs $@ $^ - +#ALLOW_UNRESOLVED_SYMBOLS=1 LINK_LIB= \ - env NO_SHARED_LIBS=1 ../setEnvironment-$(ARCH).sh sh -c \ - "\$$CXX \ + env NO_SHARED_LIBS=1 SHARED_LIBRARY_NAME=`basename $@` ../setEnvironment-$(ARCH).sh sh -c \ + "echo SHARED_LIBRARY_NAME \$$SHARED_LIBRARY_NAME && \$$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 && \ + \$$LDFLAGS -L$(ARCH) \ + -lboost_filesystem -lboost_iostreams -lboost_system -lboost_thread && \ cp $@ debug/$@ && \ \$$STRIP --strip-unneeded $@" -$(ARCH)/AI/libGeniusAI.so: $(ARCH)/libvcmi.a $(OBJS_GENIUSAI) +#$(ARCH)/libvcmi.a: $(OBJS_LIB) +# ar rcs $@ $^ + +$(ARCH)/libvcmi.so: $(OBJS_LIB) $(LINK_LIB) -$(ARCH)/AI/libStupidAI.so: $(ARCH)/libvcmi.a $(OBJS_STUPIDAI) +-lvcmi: $(ARCH)/libvcmi.so + cp -f $^ ../../../libs/$^ + +.PHONY: -lvcmi + +$(ARCH)/AI/libGeniusAI.so: $(OBJS_GENIUSAI) -lvcmi $(LINK_LIB) -$(ARCH)/Scripting/libvcmiERM.so: $(ARCH)/libvcmi.a $(OBJS_ERM) +$(ARCH)/AI/libStupidAI.so: $(OBJS_STUPIDAI) -lvcmi $(LINK_LIB) -$(ARCH)/vcmiserver: $(ARCH)/libvcmi.a $(OBJS_SERVER) +$(ARCH)/Scripting/libvcmiERM.so: $(OBJS_ERM) -lvcmi + $(LINK_LIB) + +$(ARCH)/vcmiserver: $(OBJS_SERVER) -lvcmi 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 && \ + \$$LDFLAGS -L$(ARCH) -Wl,-rpath,/data/data/eu.vcmi/lib \ + -lboost_filesystem -lboost_iostreams -lboost_system -lboost_thread && \ cp $@ debug/$@ && \ \$$STRIP --strip-unneeded $@" -libapplication-$(ARCH).so: $(ARCH)/libvcmi.a $(OBJS_CLIENT) +libapplication-$(ARCH).so: $(OBJS_CLIENT) -lvcmi 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 && \ + \$$LDFLAGS -L$(ARCH) \ + -lboost_filesystem -lboost_iostreams -lboost_system -lboost_thread -lboost_program_options && \ cp $@ debug/$@" # No need to strip, it's done inside build.sh script diff --git a/project/jni/application/vcmi-r2387/vcmi-android.diff b/project/jni/application/vcmi-r2387/vcmi-android.diff index 726469e1b..c0a866d9b 100644 --- a/project/jni/application/vcmi-r2387/vcmi-android.diff +++ b/project/jni/application/vcmi-r2387/vcmi-android.diff @@ -1,3 +1,16 @@ +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: AI/GeniusAI/neuralNetwork.cpp =================================================================== --- AI/GeniusAI/neuralNetwork.cpp (revision 2387) @@ -32,30 +45,793 @@ Index: AI/GeniusAI/CGeniusAI.cpp } +#endif -Index: client/CDefHandler.h +Index: lib/Interprocess.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]; +--- 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: lib/CGameInterface.cpp +=================================================================== +--- lib/CGameInterface.cpp (revision 2387) ++++ lib/CGameInterface.cpp (working copy) +@@ -26,6 +26,7 @@ + rett * ret=NULL; + rett*(*getAI)(); + void(*getName)(char*); ++ const char * errorMsg = NULL; + + #ifdef _WIN32 + HINSTANCE dll = LoadLibraryA(dllname.c_str()); +@@ -36,6 +37,7 @@ + } + #else + void *dll = dlopen(dllname.c_str(), RTLD_LOCAL | RTLD_LAZY); ++ errorMsg = dlerror(); + if (dll) + { + getName = (void(*)(char*))dlsym(dll,"GetAiName"); +@@ -44,13 +46,14 @@ + #endif + if (!dll) + { +- tlog1 << "Cannot open dynamic library ("<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; + } }; - // Def entry in file. Integer fields are all little endian and will -@@ -94,9 +93,9 @@ +Index: client/CCreatureAnimation.cpp +=================================================================== +--- client/CCreatureAnimation.cpp (revision 2387) ++++ client/CCreatureAnimation.cpp (working copy) +@@ -37,15 +37,23 @@ + } + } - 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(); ++#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; - static CDefHandler * giveDef(const std::string & defName); + //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/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/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/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/SDL_Extensions.cpp +=================================================================== +--- client/SDL_Extensions.cpp (revision 2387) ++++ client/SDL_Extensions.cpp (working copy) +@@ -119,8 +119,8 @@ + if(incrementPtr == -1) + ptr -= 2; + +- Uint16 * const px = (Uint16*)ptr; +- *px = (B>>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/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/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/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.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"; ++ std::string comm = std::string("LD_LIBRARY_PATH=" LIB_DIR "/../lib " 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/CMT.cpp =================================================================== --- client/CMT.cpp (revision 2387) @@ -244,6 +1020,19 @@ Index: client/CMT.cpp SDL_PushEvent(&ev); } + +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/CDefHandler.cpp =================================================================== --- client/CDefHandler.cpp (revision 2387) @@ -573,577 +1362,6 @@ Index: client/CDefHandler.cpp 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) @@ -1195,80 +1413,50 @@ Index: client/Graphics.cpp if(len < 10000 || (magic != 589598 && magic != 589599)) { tlog1 << "Suspicious font file (length " << len <<", fname " << name << "), logging to suspicious_" << name << ".fnt\n"; -Index: client/SDL_Extensions.cpp +Index: client/CDefHandler.h =================================================================== ---- client/SDL_Extensions.cpp (revision 2387) -+++ client/SDL_Extensions.cpp (working copy) -@@ -119,8 +119,8 @@ - if(incrementPtr == -1) - ptr -= 2; +--- client/CDefHandler.h (revision 2387) ++++ client/CDefHandler.h (working copy) +@@ -30,7 +30,6 @@ + ui32 totalInBlock; + ui32 unknown2; + ui32 unknown3; +- unsigned char data[0]; + }; -- Uint16 * const px = (Uint16*)ptr; -- *px = (B>>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)); + // Def entry in file. Integer fields are all little endian and will +@@ -94,9 +93,9 @@ - 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; + 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(); -- 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 + static CDefHandler * giveDef(const std::string & defName); +Index: CConsoleHandler.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 +--- CConsoleHandler.cpp (revision 2387) ++++ CConsoleHandler.cpp (working copy) +@@ -143,6 +143,7 @@ - #include - #include -Index: server/stdafx.h -=================================================================== ---- server/stdafx.h (revision 2387) -+++ server/stdafx.h (working copy) -@@ -15,8 +15,8 @@ - #include "../global.h" + void CConsoleHandler::setColor(int level) + { ++#ifndef ANDROID + TColor color; + switch(level) + { +@@ -179,6 +180,7 @@ + #else + std::cout << color; + #endif ++#endif + } - #include --#include --#include -+//#include -+//#include - #include - #include - #include + int CConsoleHandler::run() Index: server/CGameHandler.cpp =================================================================== --- server/CGameHandler.cpp (revision 2387) @@ -1337,6 +1525,21 @@ Index: server/CVCMIServer.cpp acc.join(); if (error) +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: global.h =================================================================== --- global.h (revision 2387) @@ -1385,169 +1588,3 @@ Index: global.h //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()