diff --git a/source/g3d_viewer/renderer.cpp b/source/g3d_viewer/renderer.cpp index 8b4755b9..1f9ea2e2 100644 --- a/source/g3d_viewer/renderer.cpp +++ b/source/g3d_viewer/renderer.cpp @@ -328,7 +328,7 @@ void Renderer::reset(int w, int h, PlayerColor playerColor) { glLoadIdentity(); glTranslatef(0, -1.5, -5); - Texture2D *customTexture; + Texture2D *customTexture=NULL; switch(playerColor) { case pcRed: customTexture= customTextureRed; @@ -462,7 +462,7 @@ void Renderer::renderParticleManager() { } Texture2D * Renderer::getPlayerColorTexture(PlayerColor playerColor) { - Texture2D *customTexture; + Texture2D *customTexture=NULL; switch(playerColor){ case pcRed: customTexture= customTextureRed; diff --git a/source/glest_game/ai/ai.cpp b/source/glest_game/ai/ai.cpp index 3a92d8f4..101a0485 100644 --- a/source/glest_game/ai/ai.cpp +++ b/source/glest_game/ai/ai.cpp @@ -1001,7 +1001,7 @@ bool Ai::haveBlockedUnits() { // If this building is a store if(u->isAlive() && ut->isMobile() && u->getPath() != NULL && (u->getPath()->isBlocked() || u->getPath()->getBlockCount())) { - Vec2i unitPos = u->getPos(); + Vec2i unitPos = u->getPosNotThreadSafe(); //printf("#1 AI found blocked unit [%d - %s]\n",u->getId(),u->getFullName().c_str()); @@ -1042,7 +1042,7 @@ bool Ai::getAdjacentUnits(std::map > &signalA bool result = false; Map *map = aiInterface->getMap(); - Vec2i unitPos = unit->getPos(); + Vec2i unitPos = unit->getPosNotThreadSafe(); for(int i = -1; i <= 1; ++i) { for(int j = -1; j <= 1; ++j) { Vec2i pos = unitPos + Vec2i(i, j); @@ -1094,7 +1094,7 @@ void Ai::unblockUnits() { // If this building is a store if(u->isAlive() && ut->isMobile() && u->getPath() != NULL && (u->getPath()->isBlocked() || u->getPath()->getBlockCount())) { - Vec2i unitPos = u->getPos(); + Vec2i unitPos = u->getPosNotThreadSafe(); //printf("#2 AI found blocked unit [%d - %s]\n",u->getId(),u->getFullName().c_str()); @@ -1142,9 +1142,9 @@ void Ai::unblockUnits() { Vec2i pos= Vec2i( random.randRange(-villageRadius*2, villageRadius*2), random.randRange(-villageRadius*2, villageRadius*2)) + - adjacentUnit->getPos(); + adjacentUnit->getPosNotThreadSafe(); - bool canUnitMoveToCell = map->aproxCanMove(adjacentUnit, adjacentUnit->getPos(), pos); + bool canUnitMoveToCell = map->aproxCanMove(adjacentUnit, adjacentUnit->getPosNotThreadSafe(), pos); if(canUnitMoveToCell == true) { if(ct != NULL) { diff --git a/source/glest_game/ai/ai_rule.cpp b/source/glest_game/ai/ai_rule.cpp index 429cdeb4..867c926a 100644 --- a/source/glest_game/ai/ai_rule.cpp +++ b/source/glest_game/ai/ai_rule.cpp @@ -1163,7 +1163,7 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){ if(ai->outputAIBehaviourToConsole()) printf("produceSpecific giveCommand to unit [%s] commandType [%s]\n",aiInterface->getMyUnit(producerIndex)->getType()->getName().c_str(),defCt->getName().c_str()); if(aiInterface->isLogLevelEnabled(4) == true) { char szBuf[8096]=""; - snprintf(szBuf,8096,"produceSpecific giveCommand to unit [%s] commandType [%s]",aiInterface->getMyUnit(producerIndex)->getType()->getName().c_str(),defCt->getName().c_str()); + snprintf(szBuf,8096,"produceSpecific giveCommand to unit [%s] commandType [%s]",aiInterface->getMyUnit(producerIndex)->getType()->getName().c_str(),(defCt != NULL ? defCt->getName().c_str() : "(null)")); aiInterface->printLog(4, szBuf); } aiInterface->giveCommand(producerIndex, defCt); @@ -1668,7 +1668,7 @@ bool AiRuleExpand::test() { // If this building is a store if(ut->getStore(rt) > 0) { storeType = ut; - int distance= static_cast (u->getPos().dist(expandPos)); + int distance= static_cast (u->getPosNotThreadSafe().dist(expandPos)); if(distance < minDistance) { minDistance = distance; } diff --git a/source/glest_game/ai/path_finder.cpp b/source/glest_game/ai/path_finder.cpp index 046f9c87..b041bdb0 100644 --- a/source/glest_game/ai/path_finder.cpp +++ b/source/glest_game/ai/path_finder.cpp @@ -50,6 +50,7 @@ const int PathFinder::pathFindExtendRefreshNodeCountMax = 40; PathFinder::PathFinder() { minorDebugPathfinder = false; + factionMutex = new Mutex(); for(int i = 0; i < GameConstants::maxPlayers; ++i) { factions.push_back(FactionState()); //factions.resize(GameConstants::maxPlayers); @@ -64,6 +65,7 @@ int PathFinder::getPathFindExtendRefreshNodeCount(int factionIndex) { PathFinder::PathFinder(const Map *map) { minorDebugPathfinder = false; + factionMutex = new Mutex(); for(int i = 0; i < GameConstants::maxPlayers; ++i) { factions.push_back(FactionState()); //factions.resize(GameConstants::maxPlayers); @@ -89,9 +91,15 @@ PathFinder::~PathFinder() { } factions.clear(); map=NULL; + + delete factionMutex; + factionMutex = NULL; } void PathFinder::clearUnitPrecache(Unit *unit) { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(factionMutex,mutexOwnerId); + factions[unit->getFactionIndex()].precachedTravelState[unit->getId()] = tsImpossible; factions[unit->getFactionIndex()].precachedPath[unit->getId()].clear(); @@ -99,6 +107,9 @@ void PathFinder::clearUnitPrecache(Unit *unit) { } void PathFinder::removeUnitPrecache(Unit *unit) { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(factionMutex,mutexOwnerId); + if(factions.size() > unit->getFactionIndex()) { if(factions[unit->getFactionIndex()].precachedTravelState.find(unit->getId()) != factions[unit->getFactionIndex()].precachedTravelState.end()) { factions[unit->getFactionIndex()].precachedTravelState.erase(unit->getId()); @@ -427,6 +438,10 @@ bool PathFinder::addToOpenSet(Unit *unit, Node *node,const Vec2i finalPos, Vec2i sucNode->prev= node; sucNode->next= NULL; sucNode->exploredCell= map->getSurfaceCell(Map::toSurfCoords(sucPos))->isExplored(unit->getTeam()); + + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(factionMutex,mutexOwnerId); + if(factions[unit->getFactionIndex()].openNodesList.find(sucNode->heuristic) == factions[unit->getFactionIndex()].openNodesList.end()) { factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].clear(); } @@ -1352,7 +1367,7 @@ Vec2i PathFinder::computeNearestFreePos(const Unit *unit, const Vec2i &finalPos) } //find nearest pos - Vec2i unitPos= unit->getPos(); + Vec2i unitPos= unit->getPosNotThreadSafe(); Vec2i nearestPos= unitPos; float nearestDist= unitPos.dist(finalPos); diff --git a/source/glest_game/ai/path_finder.h b/source/glest_game/ai/path_finder.h index a9ea3a1b..af0900c0 100644 --- a/source/glest_game/ai/path_finder.h +++ b/source/glest_game/ai/path_finder.h @@ -149,6 +149,7 @@ private: static int pathFindNodesMax; static int pathFindNodesAbsoluteMax; + Mutex *factionMutex; FactionStateList factions; const Map *map; bool minorDebugPathfinder; diff --git a/source/glest_game/game/commander.cpp b/source/glest_game/game/commander.cpp index bcd8bffd..0dab6338 100644 --- a/source/glest_game/game/commander.cpp +++ b/source/glest_game/game/commander.cpp @@ -207,7 +207,7 @@ std::pair Commander::tryGiveCommand(const Selection *selec bool canSubmitCommand = canSubmitCommandType(unit, commandType); if(canSubmitCommand == true) { int unitId= unit->getId(); - Vec2i currPos= world->getMap()->computeDestPos(refPos, unit->getPos(), pos); + Vec2i currPos= world->getMap()->computeDestPos(refPos, unit->getPosNotThreadSafe(), pos); Vec2i usePos = currPos; const CommandType *useCommandtype = commandType; @@ -313,7 +313,7 @@ std::pair Commander::tryGiveCommand(const Selection *selec int targetId= targetUnit==NULL? Unit::invalidId: targetUnit->getId(); int unitId= selection->getUnit(i)->getId(); Vec2i currPos= world->getMap()->computeDestPos(refPos, - selection->getUnit(i)->getPos(), pos); + selection->getUnit(i)->getPosNotThreadSafe(), pos); NetworkCommand networkCommand(this->world,nctGiveCommand, unitId, ct->getId(), currPos, -1, targetId, -1, tryQueue,cst_None,-1,unitCommandGroupId); @@ -361,7 +361,7 @@ std::pair Commander::tryGiveCommand(const Selection *selec if(canSubmitCommand == true) { int targetId= targetUnit==NULL? Unit::invalidId: targetUnit->getId(); int unitId= unit->getId(); - Vec2i currPos= world->getMap()->computeDestPos(refPos, unit->getPos(), pos); + Vec2i currPos= world->getMap()->computeDestPos(refPos, unit->getPosNotThreadSafe(), pos); NetworkCommand networkCommand(this->world,nctGiveCommand, unitId, commandType->getId(), currPos, -1, targetId, -1, tryQueue, cst_None, -1, unitCommandGroupId); @@ -401,7 +401,7 @@ std::pair Commander::tryGiveCommand(const Selection *selec const Unit *unit = selection->getUnit(i); assert(unit != NULL); - currPos= world->getMap()->computeDestPos(refPos, unit->getPos(), pos); + currPos= world->getMap()->computeDestPos(refPos, unit->getPosNotThreadSafe(), pos); //get command type const CommandType *commandType= unit->computeCommandType(pos, targetUnit); @@ -543,7 +543,7 @@ std::pair Commander::pushNetworkCommand(const NetworkComma gameNetworkInterface->requestCommand(networkCommand); //calculate the result of the command - if(networkCommand->getNetworkCommandType() == nctGiveCommand) { + if(unit != NULL && networkCommand->getNetworkCommandType() == nctGiveCommand) { Command* command= buildCommand(networkCommand); result= unit->checkCommand(command); delete command; diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 91039a31..1f683d6b 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -4026,7 +4026,7 @@ void Game::exitGameState(Program *program, Stats &endStats) { game->endGame(); } - if(game->isMasterserverMode() == true || + if(game != NULL && game->isMasterserverMode() == true || Config::getInstance().getBool("AutoTest") == true) { printf("Game ending with stats:\n"); printf("-----------------------\n"); diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index 26d0816b..87bbbe33 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -8488,7 +8488,7 @@ void Renderer::renderUnitTitles3D(Font3D *font, Vec3f color) { //unitRenderedList[unit->getId()] = true; } else { - string str = unit->getFullName() + " - " + intToStr(unit->getId()) + " [" + unit->getPos().getString() + "]"; + string str = unit->getFullName() + " - " + intToStr(unit->getId()) + " [" + unit->getPosNotThreadSafe().getString() + "]"; Vec3f screenPos = unit->getScreenPos(); #ifdef USE_STREFLOP renderText3D(str, font, color, streflop::fabs(static_cast(screenPos.x)) + 5, streflop::fabs(static_cast(screenPos.y)) + 5, false); @@ -8550,7 +8550,7 @@ void Renderer::renderUnitTitles(Font2D *font, Vec3f color) { //unitRenderedList[unit->getId()] = true; } else { - string str = unit->getFullName() + " - " + intToStr(unit->getId()) + " [" + unit->getPos().getString() + "]"; + string str = unit->getFullName() + " - " + intToStr(unit->getId()) + " [" + unit->getPosNotThreadSafe().getString() + "]"; Vec3f screenPos = unit->getScreenPos(); #ifdef USE_STREFLOP renderText(str, font, color, streflop::fabs(static_cast(screenPos.x)) + 5, streflop::fabs(static_cast(screenPos.y)) + 5, false); diff --git a/source/glest_game/gui/gui.cpp b/source/glest_game/gui/gui.cpp index e4093e84..5866fa81 100644 --- a/source/glest_game/gui/gui.cpp +++ b/source/glest_game/gui/gui.cpp @@ -1042,7 +1042,7 @@ void Gui::computeSelected(bool doubleClick, bool force){ int factionIndex= refUnit->getFactionIndex(); for(int i=0; igetFaction(factionIndex)->getUnitCount(); ++i){ Unit *unit= world->getFaction(factionIndex)->getUnit(i); - if(unit->getPos().dist(refUnit->getPos())getPos().dist(refUnit->getPosNotThreadSafe())getType()==refUnit->getType()) { units.push_back(unit); @@ -1081,7 +1081,7 @@ bool Gui::computeTarget(const Vec2i &screenPos, Vec2i &targetPos, const Unit *&t if(uc.empty() == false){ targetUnit= getRelevantObjectFromSelection(&uc); - targetPos= targetUnit->getPos(); + targetPos= targetUnit->getPosNotThreadSafe(); highlightedUnitId=targetUnit->getId(); getHighlightedUnit()->resetHighlight(); return true; diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index a8d54319..38e1f587 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -82,7 +82,8 @@ #include "conversion.h" #include "leak_dumper.h" -#if defined(WIN32) && !defined(HAVE_GOOGLE_BREAKPAD) +//#if defined(WIN32) && !defined(HAVE_GOOGLE_BREAKPAD) +#if defined(WIN32) #ifndef _DEBUG #ifndef __GNUC__ @@ -431,8 +432,14 @@ T * exception_cast(const UntypedException & e) { return reinterpret_cast(exception_cast_worker(e, ti)); } void stackdumper(unsigned int type, EXCEPTION_POINTERS *ep, bool fatalExit) { - if(!ep) { +#ifdef HAVE_GOOGLE_BREAKPAD + if(errorHandlerPtr.get() != NULL) { + errorHandlerPtr->WriteMinidump(); + } +#endif + if(!ep) { fatal("unknown type"); + return; } EXCEPTION_RECORD *er = ep->ExceptionRecord; CONTEXT *context = ep->ContextRecord; @@ -5205,7 +5212,8 @@ static bool MinidumpCallback(const wchar_t *dump_path, if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { wchar_t szBuf[8096]; - _snwprintf(szBuf,8096,L"An unhandled error was detected.\n\nA crash dump file has been created in the folder:\n%s\nCrash dump filename is: %s.dmp",dump_path,minidump_id); + int bufBytes = _snwprintf(szBuf,8096,L"An unhandled error was detected.\n\nA crash dump file has been created in the folder:\n%s\nCrash dump filename is: %s.dmp",dump_path,minidump_id); + szBuf[bufBytes] = '\0'; MessageBox(NULL, szBuf, L"Unhandled error", MB_OK|MB_SYSTEMMODAL); } @@ -5241,70 +5249,22 @@ void EnableCrashingOnCrashes() { typedef BOOL (WINAPI *tSetPolicy)(DWORD dwFlags); const DWORD EXCEPTION_SWALLOWING = 0x1; - HMODULE kernel32 = LoadLibraryA("kernel32.dll"); - tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32, "GetProcessUserModeExceptionPolicy"); - tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32, "SetProcessUserModeExceptionPolicy"); - if (pGetPolicy && pSetPolicy) { - DWORD dwFlags; - if (pGetPolicy(&dwFlags)) { - // Turn off the filter - pSetPolicy(dwFlags & ~EXCEPTION_SWALLOWING); - } - } + HMODULE kernel32 = LoadLibraryA("kernel32.dll"); + if(kernel32 != 0) { + tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32, "GetProcessUserModeExceptionPolicy"); + tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32, "SetProcessUserModeExceptionPolicy"); + if (pGetPolicy && pSetPolicy) { + DWORD dwFlags; + if (pGetPolicy(&dwFlags)) { + // Turn off the filter + pSetPolicy(dwFlags & ~EXCEPTION_SWALLOWING); + } + } + } } #endif -int glestMainWrapper(int argc, char** argv) { - //setlocale(LC_ALL, "zh_TW.UTF-8"); - //setlocale(LC_ALL, ""); - -#ifdef WIN32 - EnableCrashingOnCrashes(); -#endif - -#if defined(HAVE_GOOGLE_BREAKPAD) -/* - handler = new ExceptionHandler(const wstring& dump_path, - FilterCallback filter, - MinidumpCallback callback, - void* callback_context, - int handler_types, - MINIDUMP_TYPE dump_type, - const wchar_t* pipe_name, - const CustomClientInfo* custom_info); -*/ - - // See this link about swallowed exceptions in Win 7: http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/ - //DWORD dwFlags; - //if (GetProcessUserModeExceptionPolicy(&dwFlags)) { - // SetProcessUserModeExceptionPolicy(dwFlags & ~PROCESS_CALLBACK_FILTER_ENABLED); // turn off bit 1 - //} - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Hooking up google_breakpad::ExceptionHandler...\n"); - -#if defined(WIN32) - wstring dumpfilepath = utf8_decode("."); - //google_breakpad::ExceptionHandler handler(dumpfilepath, NULL, MinidumpCallback, NULL, true); - errorHandlerPtr.reset(new google_breakpad::ExceptionHandler(dumpfilepath, NULL, MinidumpCallback, NULL, google_breakpad::ExceptionHandler::HANDLER_ALL)); -#else - google_breakpad::MinidumpDescriptor descriptor("."); - errorHandlerPtr.reset(new google_breakpad::ExceptionHandler(descriptor, NULL, MinidumpCallback, NULL, true,-1)); -#endif -// ExceptionHandler(const wstring& dump_path, -// FilterCallback filter, -// MinidumpCallback callback, -// void* callback_context, -// int handler_types); - -#endif - -#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD) -//#ifdef DEBUG - //printf("MTRACE will be called...\n"); - //mtrace (); -//#endif -#endif - +int glestMainSEHWrapper(int argc, char** argv) { #ifdef WIN32_STACK_TRACE printf("Hooking up WIN32_STACK_TRACE...\n"); __try { @@ -5339,10 +5299,67 @@ __try { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); return result; - #ifdef WIN32_STACK_TRACE } __except(stackdumper(0, GetExceptionInformation(),true), EXCEPTION_CONTINUE_SEARCH) { return 0; } #endif + +} + +int glestMainWrapper(int argc, char** argv) { + //setlocale(LC_ALL, "zh_TW.UTF-8"); + //setlocale(LC_ALL, ""); + +#ifdef WIN32 + EnableCrashingOnCrashes(); +#endif + +#if defined(HAVE_GOOGLE_BREAKPAD) +/* + handler = new ExceptionHandler(const wstring& dump_path, + FilterCallback filter, + MinidumpCallback callback, + void* callback_context, + int handler_types, + MINIDUMP_TYPE dump_type, + const wchar_t* pipe_name, + const CustomClientInfo* custom_info); +*/ + + // See this link about swallowed exceptions in Win 7: http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/ + //DWORD dwFlags; + //if (GetProcessUserModeExceptionPolicy(&dwFlags)) { + // SetProcessUserModeExceptionPolicy(dwFlags & ~PROCESS_CALLBACK_FILTER_ENABLED); // turn off bit 1 + //} + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Hooking up google_breakpad::ExceptionHandler...\n"); + +#if defined(WIN32) + wstring dumpfilepath = utf8_decode("."); + //google_breakpad::ExceptionHandler handler(dumpfilepath, NULL, MinidumpCallback, NULL, true); + errorHandlerPtr.reset(new google_breakpad::ExceptionHandler(dumpfilepath, NULL, MinidumpCallback, + NULL, google_breakpad::ExceptionHandler::HANDLER_ALL)); +#else + google_breakpad::MinidumpDescriptor descriptor("."); + errorHandlerPtr.reset(new google_breakpad::ExceptionHandler(descriptor, NULL, MinidumpCallback, NULL, true,-1)); +#endif + +// ExceptionHandler(const wstring& dump_path, +// FilterCallback filter, +// MinidumpCallback callback, +// void* callback_context, +// int handler_types); + +#endif + +#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD) +//#ifdef DEBUG + //printf("MTRACE will be called...\n"); + //mtrace (); +//#endif +#endif + + int result = glestMainSEHWrapper(argc, argv); + return result; } }}//end namespace diff --git a/source/glest_game/menu/main_menu.cpp b/source/glest_game/menu/main_menu.cpp index 6e0a2ca0..619ff3c5 100644 --- a/source/glest_game/menu/main_menu.cpp +++ b/source/glest_game/menu/main_menu.cpp @@ -267,7 +267,9 @@ void MainMenu::setState(MenuState *newstate) { this->state= newstate; GraphicComponent::resetFade(); - menuBackground.setTargetCamera(newstate->getCamera()); + if(newstate) { + menuBackground.setTargetCamera(newstate->getCamera()); + } } bool MainMenu::isInSpecialKeyCaptureEvent() { diff --git a/source/glest_game/menu/menu_state_connected_game.cpp b/source/glest_game/menu/menu_state_connected_game.cpp index a40c1121..31835264 100644 --- a/source/glest_game/menu/menu_state_connected_game.cpp +++ b/source/glest_game/menu/menu_state_connected_game.cpp @@ -1732,7 +1732,7 @@ void MenuStateConnectedGame::mouseClickAdmin(int x, int y, MouseButton mouseButt needToBroadcastServerSettings=true; broadcastServerSettingsDelayTimer=time(NULL); } - else if(clientInterface->getGameSettings()->getStartLocationIndex(clientInterface->getGameSettings()->getThisFactionIndex()) != i && + else if(clientInterface != NULL && clientInterface->getGameSettings()->getStartLocationIndex(clientInterface->getGameSettings()->getThisFactionIndex()) != i && listBoxFactions[i].mouseClick(x, y,advanceToItemStartingWith)) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); // Disallow CPU players to be observers @@ -1746,7 +1746,7 @@ void MenuStateConnectedGame::mouseClickAdmin(int x, int y, MouseButton mouseButt needToBroadcastServerSettings=true; broadcastServerSettingsDelayTimer=time(NULL); } - else if(clientInterface->getGameSettings()->getStartLocationIndex(clientInterface->getGameSettings()->getThisFactionIndex()) != i && + else if(clientInterface != NULL && clientInterface->getGameSettings()->getStartLocationIndex(clientInterface->getGameSettings()->getThisFactionIndex()) != i && listBoxTeams[i].mouseClick(x, y)) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); if(factionFiles[listBoxFactions[i].getSelectedItemIndex()] != formatString(GameConstants::OBSERVER_SLOTNAME)) { @@ -3187,25 +3187,27 @@ void MenuStateConnectedGame::update() { console.update(); // check for need to switch music on again - GameSettings *gameSettings = clientInterface->getGameSettingsPtr(); - int currentConnectionCount=0; - for(int i=0; i < GameConstants::maxPlayers; ++i) { - if(gameSettings->getFactionControl(i)==ctNetwork && - gameSettings->getNetworkPlayerName(i) != "" && - gameSettings->getNetworkPlayerName(i) != GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) - { - currentConnectionCount++; + if(clientInterface != NULL) { + GameSettings *gameSettings = clientInterface->getGameSettingsPtr(); + int currentConnectionCount=0; + for(int i=0; i < GameConstants::maxPlayers; ++i) { + if(gameSettings->getFactionControl(i)==ctNetwork && + gameSettings->getNetworkPlayerName(i) != "" && + gameSettings->getNetworkPlayerName(i) != GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) + { + currentConnectionCount++; + } } - } - if(currentConnectionCount > soundConnectionCount){ + if(currentConnectionCount > soundConnectionCount){ + soundConnectionCount = currentConnectionCount; + SoundRenderer::getInstance().playFx(CoreData::getInstance().getAttentionSound()); + //switch on music again!! + Config &config = Config::getInstance(); + float configVolume = (config.getInt("SoundVolumeMusic") / 100.f); + CoreData::getInstance().getMenuMusic()->setVolume(configVolume); + } soundConnectionCount = currentConnectionCount; - SoundRenderer::getInstance().playFx(CoreData::getInstance().getAttentionSound()); - //switch on music again!! - Config &config = Config::getInstance(); - float configVolume = (config.getInt("SoundVolumeMusic") / 100.f); - CoreData::getInstance().getMenuMusic()->setVolume(configVolume); - } - soundConnectionCount = currentConnectionCount; + } } diff --git a/source/glest_game/type_instances/faction.cpp b/source/glest_game/type_instances/faction.cpp index e7bd6208..c03f3de9 100644 --- a/source/glest_game/type_instances/faction.cpp +++ b/source/glest_game/type_instances/faction.cpp @@ -219,8 +219,10 @@ FactionThread::FactionThread(Faction *faction) : BaseThread() { } FactionThread::~FactionThread() { - delete triggerIdMutex; - triggerIdMutex = NULL; + this->faction = NULL; + this->masterController = NULL; + delete this->triggerIdMutex; + this->triggerIdMutex = NULL; } void FactionThread::setQuitStatus(bool value) { @@ -271,10 +273,11 @@ bool FactionThread::isSignalPathfinderCompleted(int frameIndex) { if(getRunningStatus() == false) { return true; } + bool result = false; static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); MutexSafeWrapper safeMutex(triggerIdMutex,mutexOwnerId); //bool result = (event != NULL ? event->eventCompleted : true); - bool result = (this->frameIndex.first == frameIndex && this->frameIndex.second == true); + result = (this->frameIndex.first == frameIndex && this->frameIndex.second == true); //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] worker thread this = %p, this->frameIndex.first = %d, this->frameIndex.second = %d\n",__FILE__,__FUNCTION__,__LINE__,this,this->frameIndex.first,this->frameIndex.second); @@ -311,9 +314,11 @@ void FactionThread::execute() { break; } + int currentTriggeredFrameIndex = 0; static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); MutexSafeWrapper safeMutex(triggerIdMutex,mutexOwnerId); - bool executeTask = (frameIndex.first >= 0); + bool executeTask = (this->frameIndex.first >= 0); + currentTriggeredFrameIndex = this->frameIndex.first; //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] frameIndex = %d this = %p executeTask = %d\n",__FILE__,__FUNCTION__,__LINE__,frameIndex.first, this, executeTask); @@ -324,25 +329,32 @@ void FactionThread::execute() { if(executeTask == true) { ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); - World *world = faction->getWorld(); + if(this->faction == NULL) { + throw megaglest_runtime_error("this->faction == NULL"); + } + World *world = this->faction->getWorld(); + if(world == NULL) { + throw megaglest_runtime_error("world == NULL"); + } //Config &config= Config::getInstance(); //bool sortedUnitsAllowed = config.getBool("AllowGroupedUnitCommands","true"); bool sortedUnitsAllowed = false; - if(sortedUnitsAllowed) { - faction->sortUnitsByCommandGroups(); + if(sortedUnitsAllowed == true) { + this->faction->sortUnitsByCommandGroups(); } - MutexSafeWrapper safeMutex(faction->getUnitMutex(),string(__FILE__) + "_" + intToStr(__LINE__)); + static string mutexOwnerId2 = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(faction->getUnitMutex(),mutexOwnerId2); //if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); if(minorDebugPerformance) chrono.start(); //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - int unitCount = faction->getUnitCount(); + int unitCount = this->faction->getUnitCount(); for(int j = 0; j < unitCount; ++j) { - Unit *unit = faction->getUnit(j); + Unit *unit = this->faction->getUnit(j); if(unit == NULL) { throw megaglest_runtime_error("unit == NULL"); } @@ -352,7 +364,7 @@ void FactionThread::execute() { bool update = unit->needToUpdate(); - if(minorDebugPerformance && (chrono.getMillis() - elapsed1) >= 1) printf("Faction [%d - %s] #1-unit threaded updates on frame: %d for [%d] unit # %d, unitCount = %d, took [%lld] msecs\n",faction->getStartLocationIndex(),faction->getType()->getName().c_str(),frameIndex.first,faction->getUnitPathfindingListCount(),j,unitCount,(long long int)chrono.getMillis() - elapsed1); + if(minorDebugPerformance && (chrono.getMillis() - elapsed1) >= 1) printf("Faction [%d - %s] #1-unit threaded updates on frame: %d for [%d] unit # %d, unitCount = %d, took [%lld] msecs\n",faction->getStartLocationIndex(),faction->getType()->getName().c_str(),currentTriggeredFrameIndex,faction->getUnitPathfindingListCount(),j,unitCount,(long long int)chrono.getMillis() - elapsed1); //update = true; if(update == true) { @@ -360,13 +372,17 @@ void FactionThread::execute() { int64 elapsed2 = 0; if(minorDebugPerformance) elapsed2 = chrono.getMillis(); - world->getUnitUpdater()->updateUnitCommand(unit,frameIndex.first); + if(world->getUnitUpdater() == NULL) { + throw megaglest_runtime_error("world->getUnitUpdater() == NULL"); + } - if(minorDebugPerformance && (chrono.getMillis() - elapsed2) >= 1) printf("Faction [%d - %s] #2-unit threaded updates on frame: %d for [%d] unit # %d, unitCount = %d, took [%lld] msecs\n",faction->getStartLocationIndex(),faction->getType()->getName().c_str(),frameIndex.first,faction->getUnitPathfindingListCount(),j,unitCount,(long long int)chrono.getMillis() - elapsed2); + world->getUnitUpdater()->updateUnitCommand(unit,currentTriggeredFrameIndex); + + if(minorDebugPerformance && (chrono.getMillis() - elapsed2) >= 1) printf("Faction [%d - %s] #2-unit threaded updates on frame: %d for [%d] unit # %d, unitCount = %d, took [%lld] msecs\n",faction->getStartLocationIndex(),faction->getType()->getName().c_str(),currentTriggeredFrameIndex,faction->getUnitPathfindingListCount(),j,unitCount,(long long int)chrono.getMillis() - elapsed2); } } - if(minorDebugPerformance && chrono.getMillis() >= 1) printf("Faction [%d - %s] threaded updates on frame: %d for [%d] units took [%lld] msecs\n",faction->getStartLocationIndex(),faction->getType()->getName().c_str(),frameIndex.first,faction->getUnitPathfindingListCount(),(long long int)chrono.getMillis()); + if(minorDebugPerformance && chrono.getMillis() >= 1) printf("Faction [%d - %s] threaded updates on frame: %d for [%d] units took [%lld] msecs\n",faction->getStartLocationIndex(),faction->getType()->getName().c_str(),currentTriggeredFrameIndex,faction->getUnitPathfindingListCount(),(long long int)chrono.getMillis()); //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -374,7 +390,7 @@ void FactionThread::execute() { //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - setTaskCompleted(frameIndex.first); + setTaskCompleted(currentTriggeredFrameIndex); //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } @@ -398,6 +414,13 @@ void FactionThread::execute() { throw megaglest_runtime_error(ex.what()); } + catch(...) { + char szBuf[8096]=""; + snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); + throw megaglest_runtime_error(szBuf); + } + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); } diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index 1e0e9353..52960299 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -1064,6 +1064,9 @@ void Unit::setPos(const Vec2i &pos, bool clearPathFinder) { throw megaglest_runtime_error("#3 Invalid path position = " + pos.getString()); } + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); + if(clearPathFinder == true && this->unitPath != NULL) { this->unitPath->clear(); } @@ -1106,6 +1109,8 @@ void Unit::setPos(const Vec2i &pos, bool clearPathFinder) { this->meetingPos= pos - Vec2i(1); map->clampPos(this->meetingPos); + safeMutex.ReleaseLock(); + // Attempt to improve performance this->exploreCells(); @@ -1122,7 +1127,7 @@ FowAlphaCellsLookupItem Unit::getFogOfWarRadius(bool useCache) const { FowAlphaCellsLookupItem result; //iterate through all cells int sightRange= this->getType()->getSight(); - PosCircularIterator pci(map, this->getPos(), sightRange + World::indirectSightRange); + PosCircularIterator pci(map, this->getPosNotThreadSafe(), sightRange + World::indirectSightRange); while(pci.next()){ const Vec2i sightpos= pci.getPos(); Vec2i surfPos= Map::toSurfCoords(sightpos); @@ -1138,7 +1143,7 @@ FowAlphaCellsLookupItem Unit::getFogOfWarRadius(bool useCache) const { //compute alpha float alpha = maxAlpha; - float dist = this->getPos().dist(sightpos); + float dist = this->getPosNotThreadSafe().dist(sightpos); if(dist > sightRange) { alpha= clamp(1.f-(dist - sightRange) / (World::indirectSightRange), 0.f, maxAlpha); } @@ -1152,6 +1157,9 @@ void Unit::calculateFogOfWarRadius() { if(game->getWorld()->getFogOfWar() == true) { if(Config::getInstance().getBool("EnableFowCache","true") == true && this->pos != this->cachedFowPos) { cachedFow = getFogOfWarRadius(false); + + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); this->cachedFowPos = this->pos; } } @@ -1805,7 +1813,13 @@ const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *target bool Unit::needToUpdate() { - assert(progress <= 1.f); + //assert(progress <= 1.f); + if(progress > 1.f) { + char szBuf[8096]=""; + snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: progress > 1.f, progress = [%f]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,progress); + throw megaglest_runtime_error(szBuf); + } + if(currSkill == NULL) { char szBuf[8096]=""; snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); @@ -1832,12 +1846,29 @@ bool Unit::needToUpdate() { } //if moving to an higher cell move slower else move faster - float heightDiff= map->getCell(pos)->getHeight() - map->getCell(targetPos)->getHeight(); + Cell *unitCell = map->getCell(pos); + if(unitCell == NULL) { + throw megaglest_runtime_error("unitCell == NULL"); + } + + Cell *targetCell = map->getCell(targetPos); + if(targetCell == NULL) { + throw megaglest_runtime_error("targetCell == NULL"); + } + + float heightDiff= unitCell->getHeight() - targetCell->getHeight(); heightFactor= clamp(1.f + heightDiff / 5.f, 0.2f, 5.f); } //update progresses const Game *game = Renderer::getInstance().getGame(); + if(game == NULL) { + throw megaglest_runtime_error("game == NULL"); + } + if(game->getWorld() == NULL) { + throw megaglest_runtime_error("game->getWorld() == NULL"); + } + float speedDenominator = (speedDivider * game->getWorld()->getUpdateFps(this->getFactionIndex())); float newProgress = progress; newProgress += (speed * diagonalFactor * heightFactor) / speedDenominator; @@ -3566,6 +3597,17 @@ string Unit::getUniquePickName() const { return result; } +Vec2i Unit::getPos() { + Vec2i result; + + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); + result = this->pos; + safeMutex.ReleaseLock(); + + return result; +} + std::string Unit::toString() const { std::string result = ""; diff --git a/source/glest_game/type_instances/unit.h b/source/glest_game/type_instances/unit.h index 140d89a2..fa28bebb 100644 --- a/source/glest_game/type_instances/unit.h +++ b/source/glest_game/type_instances/unit.h @@ -541,7 +541,8 @@ public: inline void setCauseOfDeath(CauseOfDeathType cause) { causeOfDeath = cause; } //pos - inline Vec2i getPos() const {return pos;} + inline Vec2i getPosNotThreadSafe() const {return pos;} + Vec2i getPos(); Vec2i getPosWithCellMapSet() const; inline Vec2i getLastPos() const {return lastPos;} Vec2i getCenteredPos() const; diff --git a/source/glest_game/types/skill_type.cpp b/source/glest_game/types/skill_type.cpp index be9ad062..136123f2 100644 --- a/source/glest_game/types/skill_type.cpp +++ b/source/glest_game/types/skill_type.cpp @@ -563,7 +563,7 @@ Model *SkillType::getAnimation(float animProgress, const Unit *unit, if(foundSpecificAnimation == false) { //int modelIndex = random.randRange(0,animations.size()-1); Chrono seed(true); - srand((unsigned int)seed.getCurTicks() + unit->getId()); + srand((unsigned int)seed.getCurTicks() + (unit != NULL ? unit->getId() : 0)); modelIndex = rand() % animations.size(); diff --git a/source/glest_game/world/map.cpp b/source/glest_game/world/map.cpp index 62f5cded..8cdf821c 100644 --- a/source/glest_game/world/map.cpp +++ b/source/glest_game/world/map.cpp @@ -650,13 +650,15 @@ bool Map::isResourceNear(const Vec2i &pos, const ResourceType *rt, Vec2i &resour (distanceFromUnit < 0 || unit->getCenteredPos().dist(resPos) <= (distanceFromUnit + 2.0))) { if(resourceClickPos->dist(resPos) <= 1.0) { - FindBestPos bestPosItem; + if(unit != NULL) { + FindBestPos bestPosItem; - bestPosItem.distanceFromUnitNoAdjustment = unit->getCenteredPos().dist(resPos); - bestPosItem.distanceFromClickNoAdjustment =distanceFromClick = resourceClickPos->dist(resPos); - bestPosItem.resourcePosNoAdjustment = resPos; + bestPosItem.distanceFromUnitNoAdjustment = unit->getCenteredPos().dist(resPos); + bestPosItem.distanceFromClickNoAdjustment =distanceFromClick = resourceClickPos->dist(resPos); + bestPosItem.resourcePosNoAdjustment = resPos; - bestPosList.push_back(bestPosItem); + bestPosList.push_back(bestPosItem); + } } //printf("!!!! unit [%s - %d] resPos = [%s] resourceClickPos->dist(resPos) [%f] distanceFromClick [%f] unit->getCenteredPos().dist(resPos) [%f] distanceFromUnit [%f]\n",unit->getFullName().c_str(),unit->getId(),resPos.getString().c_str(),resourceClickPos->dist(resPos),distanceFromClick,unit->getCenteredPos().dist(resPos),distanceFromUnit); @@ -1079,7 +1081,7 @@ Vec2i Map::computeRefPos(const Selection *selection) const { if(selection == NULL || selection->getUnit(i) == NULL) { throw megaglest_runtime_error("selection == NULL || selection->getUnit(i) == NULL"); } - total = total + selection->getUnit(i)->getPos(); + total = total + selection->getUnit(i)->getPosNotThreadSafe(); } return Vec2i(total.x / selection->getCount(), total.y / selection->getCount()); @@ -1111,7 +1113,7 @@ std::pair Map::getUnitDistanceToPos(const Unit *unit,Vec2i pos,cons std::pair result(-1,Vec2i(0)); //int unitId= unit->getId(); - Vec2i unitPos= computeDestPos(unit->getPos(), unit->getPos(), pos); + Vec2i unitPos= computeDestPos(unit->getPosNotThreadSafe(), unit->getPosNotThreadSafe(), pos); Vec2i start = pos - Vec2i(1); int unitTypeSize = 0; @@ -1156,7 +1158,7 @@ const Unit * Map::findClosestUnitToPos(const Selection *selection, Vec2i origina for(int i = 0; i < selection->getCount(); ++i) { const Unit *unit = selection->getUnit(i); //int unitId= unit->getId(); - Vec2i unitBuilderPos= computeDestPos(refPos, unit->getPos(), pos); + Vec2i unitBuilderPos= computeDestPos(refPos, unit->getPosNotThreadSafe(), pos); for(int i = start.x; i <= end.x; ++i) { for(int j = start.y; j <= end.y; ++j){ @@ -1177,7 +1179,7 @@ const Unit * Map::findClosestUnitToPos(const Selection *selection, Vec2i origina } Vec2i Map::findBestBuildApproach(const Unit *unit, Vec2i originalBuildPos,const UnitType *ut) const { - Vec2i unitBuilderPos = unit->getPos(); + Vec2i unitBuilderPos = unit->getPosNotThreadSafe(); Vec2i pos = originalBuildPos; float bestRange = -1; @@ -1442,7 +1444,7 @@ bool Map::isNextTo(const Vec2i &pos, const Unit *unit) const { //return if unit is next to pos bool Map::isNextTo(const Unit *unit1, const Unit *unit2) const { - Vec2i pos = unit1->getPos(); + Vec2i pos = unit1->getPosNotThreadSafe(); const UnitType *ut = unit1->getType(); for (int y=-1; y < ut->getSize()+1; ++y) { for (int x=-1; x < ut->getSize()+1; ++x) { @@ -1516,7 +1518,7 @@ void Map::flatternTerrain(const Unit *unit){ float refHeight= getSurfaceCell(toSurfCoords(unit->getCenteredPos()))->getHeight(); for(int i=-1; i<=unit->getType()->getSize(); ++i){ for(int j=-1; j<=unit->getType()->getSize(); ++j){ - Vec2i pos= unit->getPos()+Vec2i(i, j); + Vec2i pos= unit->getPosNotThreadSafe()+Vec2i(i, j); if(isInside(pos) && isInsideSurface(toSurfCoords(pos))) { Cell *c= getCell(pos); SurfaceCell *sc= getSurfaceCell(toSurfCoords(pos)); diff --git a/source/glest_game/world/map.h b/source/glest_game/world/map.h index 52a9f1c0..71de63eb 100644 --- a/source/glest_game/world/map.h +++ b/source/glest_game/world/map.h @@ -417,14 +417,14 @@ public: //single cell units if(size == 1) { - if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),pos2, field, teamIndex) == false) { + if(isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(),pos2, field, teamIndex) == false) { //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false); return false; } if(pos1.x != pos2.x && pos1.y != pos2.y) { - if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),Vec2i(pos1.x, pos2.y), field, teamIndex) == false) { + if(isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(),Vec2i(pos1.x, pos2.y), field, teamIndex) == false) { //Unit *cellUnit = getCell(Vec2i(pos1.x, pos2.y))->getUnit(field); //Object * obj = getSurfaceCell(toSurfCoords(Vec2i(pos1.x, pos2.y)))->getObject(); @@ -434,7 +434,7 @@ public: unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false); return false; } - if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),Vec2i(pos2.x, pos1.y), field, teamIndex) == false) { + if(isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(),Vec2i(pos2.x, pos1.y), field, teamIndex) == false) { //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false); return false; @@ -470,7 +470,7 @@ public: Vec2i cellPos = Vec2i(i,j); if(isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) { if(getCell(cellPos)->getUnit(unit->getCurrField()) != unit) { - if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),cellPos, field, teamIndex) == false) { + if(isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(),cellPos, field, teamIndex) == false) { //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false); diff --git a/source/glest_game/world/unit_updater.cpp b/source/glest_game/world/unit_updater.cpp index 3eabc352..71737ac1 100644 --- a/source/glest_game/world/unit_updater.cpp +++ b/source/glest_game/world/unit_updater.cpp @@ -939,7 +939,9 @@ void UnitUpdater::updateHarvest(Unit *unit, int frameIndex) { if(clickPos != command->getOriginalPos()) { //printf("%%----------- unit [%s - %d] CHANGING RESOURCE POS from [%s] to [%s]\n",unit->getFullName().c_str(),unit->getId(),command->getOriginalPos().getString().c_str(),clickPos.getString().c_str()); - command->setPos(clickPos); + if(frameIndex < 0) { + command->setPos(clickPos); + } } } } @@ -2365,7 +2367,7 @@ vector UnitUpdater::enemyUnitsOnRange(const Unit *unit,const AttackSkillT //aux vars int size = unit->getType()->getSize(); - Vec2i center = unit->getPos(); + Vec2i center = unit->getPosNotThreadSafe(); Vec2f floatCenter = unit->getFloatCenteredPos(); //bool foundInCache = true; @@ -2423,11 +2425,11 @@ vector UnitUpdater::findUnitsInRange(const Unit *unit, int radius) { //aux vars int size = unit->getType()->getSize(); - Vec2i center = unit->getPos(); + Vec2i center = unit->getPosNotThreadSafe(); Vec2f floatCenter = unit->getFloatCenteredPos(); //nearby cells - UnitRangeCellsLookupItem cacheItem; + //UnitRangeCellsLookupItem cacheItem; for(int i = center.x - range; i < center.x + range + size; ++i) { for(int j = center.y - range; j < center.y + range + size; ++j) { //cells inside map and in range @@ -2453,7 +2455,7 @@ string UnitUpdater::getUnitRangeCellsLookupItemCacheStats() { int rangeCount = 0; int rangeCountCellCount = 0; - Mutex mutexUnitRangeCellsLookupItemCache; + MutexSafeWrapper safeMutex(&mutexUnitRangeCellsLookupItemCache,string(__FILE__) + "_" + intToStr(__LINE__)); //std::map > > UnitRangeCellsLookupItemCache; for(std::map > >::iterator iterMap1 = UnitRangeCellsLookupItemCache.begin(); iterMap1 != UnitRangeCellsLookupItemCache.end(); ++iterMap1) { diff --git a/source/glest_game/world/world.cpp b/source/glest_game/world/world.cpp index 76792473..f40db5bc 100644 --- a/source/glest_game/world/world.cpp +++ b/source/glest_game/world/world.cpp @@ -950,7 +950,7 @@ void World::moveUnitCells(Unit *unit) { void World::addAttackEffects(const Unit *unit) { attackEffects.addWaterSplash( - Vec2f(unit->getPos().x, unit->getPos().y),1); + Vec2f(unit->getPosNotThreadSafe().x, unit->getPosNotThreadSafe().y),1); } //returns the nearest unit that can store a type of resource given a position and a faction @@ -981,7 +981,7 @@ bool World::toRenderUnit(const Unit *unit, const Quad2i &visibleQuad) const { } //a unit is rendered if it is in a visible cell or is attacking a unit in a visible cell - return visibleQuad.isInside(unit->getPos()) && toRenderUnit(unit); + return visibleQuad.isInside(unit->getPosNotThreadSafe()) && toRenderUnit(unit); } bool World::toRenderUnit(const Unit *unit) const { diff --git a/source/shared_lib/include/feathery_ftp/ftpTypes.h b/source/shared_lib/include/feathery_ftp/ftpTypes.h index b9312dab..89310228 100644 --- a/source/shared_lib/include/feathery_ftp/ftpTypes.h +++ b/source/shared_lib/include/feathery_ftp/ftpTypes.h @@ -26,7 +26,7 @@ // if the compiler is c99 complient, we don't need to define our own types -#if __STDC_VERSION__ == 199901L +#if __STDC_VERSION__ == 199901L || (defined(WIN32) && defined(_MSC_VER) && _MSC_VER >= 1600) # include #else diff --git a/source/shared_lib/include/platform/common/cache_manager.h b/source/shared_lib/include/platform/common/cache_manager.h index 2e84467e..ef33b90b 100644 --- a/source/shared_lib/include/platform/common/cache_manager.h +++ b/source/shared_lib/include/platform/common/cache_manager.h @@ -74,14 +74,16 @@ protected: } } - try { - Mutex &mutexCache = manageCachedItemMutex(cacheKey); - MutexSafeWrapper safeMutex(&mutexCache); - itemCache[cacheKey] = *value; - safeMutex.ReleaseLock(); - } - catch(const std::exception &ex) { - throw megaglest_runtime_error(ex.what()); + if(value != NULL) { + try { + Mutex &mutexCache = manageCachedItemMutex(cacheKey); + MutexSafeWrapper safeMutex(&mutexCache); + itemCache[cacheKey] = *value; + safeMutex.ReleaseLock(); + } + catch(const std::exception &ex) { + throw megaglest_runtime_error(ex.what()); + } } } // If this is the first access we return a default object of the type diff --git a/source/shared_lib/include/platform/sdl/data_types.h b/source/shared_lib/include/platform/sdl/data_types.h index 3d43cfc1..052d5637 100644 --- a/source/shared_lib/include/platform/sdl/data_types.h +++ b/source/shared_lib/include/platform/sdl/data_types.h @@ -212,6 +212,8 @@ typedef uint32_t uint_least32_t; typedef uint64_t uint_least64_t; // 7.18.1.3 Fastest minimum-width integer types +#if (_MSC_VER < 1700) + typedef int8_t int_fast8_t; typedef int16_t int_fast16_t; typedef int32_t int_fast32_t; @@ -221,6 +223,8 @@ typedef uint16_t uint_fast16_t; typedef uint32_t uint_fast32_t; typedef uint64_t uint_fast64_t; +#endif + // 7.18.1.4 Integer types capable of holding object pointers #ifdef _WIN64 // [ typedef signed __int64 intptr_t; diff --git a/source/shared_lib/include/util/util.h b/source/shared_lib/include/util/util.h index 0c8c78a4..b1b63e1f 100644 --- a/source/shared_lib/include/util/util.h +++ b/source/shared_lib/include/util/util.h @@ -166,6 +166,9 @@ public: if(result != NULL) { return *result; } + else if(SystemFlags::debugLogFileList == NULL) { + throw std::exception("unknown return value for SystemFlagsType!"); + } } return (*debugLogFileList)[type]; diff --git a/source/shared_lib/sources/feathery_ftp/ftpCmds.c b/source/shared_lib/sources/feathery_ftp/ftpCmds.c index d55f613b..aaa252e8 100644 --- a/source/shared_lib/sources/feathery_ftp/ftpCmds.c +++ b/source/shared_lib/sources/feathery_ftp/ftpCmds.c @@ -202,7 +202,7 @@ LOCAL int ftpCmdSyst(int sessionId, const char* args, int len) LOCAL int ftpCmdPort(int sessionId, const char* args, int len) { char clientIp[16]; - uint16_t clientPort; + uint16_t clientPort=0; int commaCnt = 0; int n; diff --git a/source/shared_lib/sources/graphics/JPGReader.cpp b/source/shared_lib/sources/graphics/JPGReader.cpp index eed70703..479b75a9 100644 --- a/source/shared_lib/sources/graphics/JPGReader.cpp +++ b/source/shared_lib/sources/graphics/JPGReader.cpp @@ -84,6 +84,9 @@ Pixmap2D* JPGReader::read(ifstream& is, const string& path, Pixmap2D* ret) const if(bigEndianSystem == true) { Shared::PlatformByteOrder::fromEndianTypeArray(buffer,(size_t)length); } + if(length < 2) { + throw megaglest_runtime_error("length < 2",true); + } //Check buffer (weak jpeg check) //if (buffer[0] != 0x46 || buffer[1] != 0xA0) { // Proper header check found from: http://www.fastgraph.com/help/jpeg_header_format.html diff --git a/source/shared_lib/sources/graphics/pixmap.cpp b/source/shared_lib/sources/graphics/pixmap.cpp index 7bc36414..31927760 100644 --- a/source/shared_lib/sources/graphics/pixmap.cpp +++ b/source/shared_lib/sources/graphics/pixmap.cpp @@ -678,12 +678,14 @@ void PixmapIoJpg::write(uint8 *pixels) { if(components == 4) { int n = w * h; unsigned char *dst = tmpbytes = (unsigned char *) malloc(n*3); - const unsigned char *src = pixels; - for (int i = 0; i < n; i++) { - *dst++ = *src++; - *dst++ = *src++; - *dst++ = *src++; - src++; + if(dst != NULL) { + const unsigned char *src = pixels; + for (int i = 0; i < n; i++) { + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + src++; + } } components = 3; } @@ -718,25 +720,29 @@ void PixmapIoJpg::write(uint8 *pixels) { // flip lines. uint8 *flip = (uint8 *)malloc(sizeof(uint8) * w * h * 3); - for (int y = 0;y < h; ++y) { - for (int x = 0;x < w; ++x) { - flip[(y * w + x) * 3] = pixels[((h - 1 - y) * w + x) * 3]; - flip[(y * w + x) * 3 + 1] = pixels[((h - 1 - y) * w + x) * 3 + 1]; - flip[(y * w + x) * 3 + 2] = pixels[((h - 1 - y) * w + x) * 3 + 2]; + if(pixels != NULL && flip != NULL) { + for (int y = 0;y < h; ++y) { + for (int x = 0;x < w; ++x) { + flip[(y * w + x) * 3] = pixels[((h - 1 - y) * w + x) * 3]; + flip[(y * w + x) * 3 + 1] = pixels[((h - 1 - y) * w + x) * 3 + 1]; + flip[(y * w + x) * 3 + 2] = pixels[((h - 1 - y) * w + x) * 3 + 2]; + } + } + + /* like reading a file, this time write one row at a time */ + while( cinfo.next_scanline < cinfo.image_height ) { + row_pointer[0] = &flip[ cinfo.next_scanline * cinfo.image_width * cinfo.input_components]; + jpeg_write_scanlines( &cinfo, row_pointer, 1 ); } - } - - /* like reading a file, this time write one row at a time */ - while( cinfo.next_scanline < cinfo.image_height ) { - row_pointer[0] = &flip[ cinfo.next_scanline * cinfo.image_width * cinfo.input_components]; - jpeg_write_scanlines( &cinfo, row_pointer, 1 ); } if (tmpbytes) { free(tmpbytes); tmpbytes=NULL; } - free(flip); - flip=NULL; + if(flip) { + free(flip); + flip=NULL; + } /* similar to read file, clean up after we're done compressing */ jpeg_finish_compress( &cinfo ); diff --git a/source/shared_lib/sources/graphics/video_player.cpp b/source/shared_lib/sources/graphics/video_player.cpp index 5801eb21..2a3fd5f1 100644 --- a/source/shared_lib/sources/graphics/video_player.cpp +++ b/source/shared_lib/sources/graphics/video_player.cpp @@ -1413,7 +1413,12 @@ bool VideoPlayer::playFrame(bool swapBuffers) { } } - return ctxPtr->needToQuit; + if(ctxPtr != NULL) { + return ctxPtr->needToQuit; + } + else { + return false; + } } void VideoPlayer::RestartVideo() { diff --git a/source/shared_lib/sources/platform/miniupnpc/connecthostport.c b/source/shared_lib/sources/platform/miniupnpc/connecthostport.c index 83142b0f..edef489a 100644 --- a/source/shared_lib/sources/platform/miniupnpc/connecthostport.c +++ b/source/shared_lib/sources/platform/miniupnpc/connecthostport.c @@ -143,7 +143,8 @@ int connecthostport(const char * host, unsigned short port, hints.ai_socktype = SOCK_STREAM; hints.ai_family = AF_UNSPEC; /* AF_INET, AF_INET6 or AF_UNSPEC */ /* hints.ai_protocol = IPPROTO_TCP; */ - snprintf(port_str, sizeof(port_str), "%hu", port); + snprintf(port_str, 7, "%hu", port); + port_str[7] = '\0'; if(host[0] == '[') { /* literal ip v6 address */ diff --git a/source/shared_lib/sources/platform/posix/socket.cpp b/source/shared_lib/sources/platform/posix/socket.cpp index a45cb777..cfe21014 100644 --- a/source/shared_lib/sources/platform/posix/socket.cpp +++ b/source/shared_lib/sources/platform/posix/socket.cpp @@ -2465,7 +2465,7 @@ int UPNP_Tools::upnp_init(void *param) { } dev = devlist; - while (dev) { + while (dev && dev->st) { if (strstr(dev->st, "InternetGatewayDevice")) { break; } diff --git a/source/shared_lib/sources/platform/win32/glob.cpp b/source/shared_lib/sources/platform/win32/glob.cpp index 89ac771c..f323109d 100644 --- a/source/shared_lib/sources/platform/win32/glob.cpp +++ b/source/shared_lib/sources/platform/win32/glob.cpp @@ -297,6 +297,9 @@ int glob( char const *pattern cbAlloc = new_cbAlloc; } + if(buffer == NULL) { + throw exception("buffer == NULL"); + } (void)lstrcpynA(buffer + cbCurr, szRelative, 1 + (int)(file_part - effectivePattern)); (void)lstrcatA(buffer + cbCurr, sFileName.c_str()); cbCurr += cch + 1; diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_expf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_expf.cpp index 1204263f..8ac566e5 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_expf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_expf.cpp @@ -52,8 +52,8 @@ P5 = 4.1381369442e-08f; /* 0x3331bb4c */ Simple x; #endif { - Simple y,hi,lo,c,t; - int32_t k,xsb; + Simple y,hi,lo=0,c,t; + int32_t k=0,xsb=0; u_int32_t hx; GET_FLOAT_WORD(hx,x); diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_j0f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_j0f.cpp index 090c83c0..d814476f 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_j0f.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_j0f.cpp @@ -301,6 +301,8 @@ static Simple pS2[5] = { else if(ix>=0x40f71c58){p = pR5; q= pS5;} else if(ix>=0x4036db68){p = pR3; q= pS3;} else if(ix>=0x40000000){p = pR2; q= pS2;} + //else throw std::exception("unknown state for pointers p and q!"); + else throw "unknown state for pointers p and q!"; z = one/(x*x); r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); @@ -437,6 +439,8 @@ static Simple qS2[6] = { else if(ix>=0x40f71c58){p = qR5; q= qS5;} else if(ix>=0x4036db68){p = qR3; q= qS3;} else if(ix>=0x40000000){p = qR2; q= qS2;} + //else throw std::exception("unknown state for pointer p!"); + else throw "unknown state for pointers p and q!"; z = one/(x*x); r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_j1f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_j1f.cpp index f151ba42..eaa7573b 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_j1f.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_j1f.cpp @@ -300,6 +300,8 @@ static Simple ps2[5] = { else if(ix>=0x40f71c58){p = pr5; q= ps5;} else if(ix>=0x4036db68){p = pr3; q= ps3;} else if(ix>=0x40000000){p = pr2; q= ps2;} + //else throw std::exception("unknown state for pointer p!"); + else throw "unknown state for pointers p and q!"; z = one/(x*x); r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); @@ -437,6 +439,8 @@ static Simple qs2[6] = { else if(ix>=0x40f71c58){p = qr5; q= qs5;} else if(ix>=0x4036db68){p = qr3; q= qs3;} else if(ix>=0x40000000){p = qr2; q= qs2;} + //else throw std::exception("unknown state for pointer p!"); + else throw "unknown state for pointers p and q!"; z = one/(x*x); r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); diff --git a/source/shared_lib/sources/util/string_utils.cpp b/source/shared_lib/sources/util/string_utils.cpp index 6166b90a..d3bbce0d 100644 --- a/source/shared_lib/sources/util/string_utils.cpp +++ b/source/shared_lib/sources/util/string_utils.cpp @@ -218,12 +218,14 @@ namespace Shared { namespace Util { void strrev(char *p) { - char *q = p; - while(q && *q) ++q; - for(--q; p < q; ++p, --q) - *p = *p ^ *q, - *q = *p ^ *q, - *p = *p ^ *q; + if(p != NULL) { + char *q = p; + while(q && *q) ++q; + for(--q; p < q; ++p, --q) + *p = *p ^ *q, + *q = *p ^ *q, + *p = *p ^ *q; + } } #define SWP(x,y) (x^=y, y^=x, x^=y)