MegaGlest/source/glest_game/main/main.cpp

3936 lines
152 KiB
C++

// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "math_wrapper.h"
#include "main.h"
#include <string>
#include <cstdlib>
#include "game.h"
#include "main_menu.h"
#include "program.h"
#include "config.h"
#include "metrics.h"
#include "game_util.h"
#include "platform_util.h"
#include "platform_main.h"
#include "network_interface.h"
#include "ImageReaders.h"
#include "renderer.h"
#include "simple_threads.h"
#include <memory>
#include "font.h"
#include <curl/curl.h>
#include "menu_state_masterserver.h"
#include "checksum.h"
#include <algorithm>
#include "sound_renderer.h"
#include "font_gl.h"
#include "FileReader.h"
#include "cache_manager.h"
#include <iterator>
#include "core_data.h"
#include "font_text.h"
//#include "FileReader.h"
//#include "JPGReader.h"
//#include "sound.h"
//#include "unicode/uclean.h"
#include <locale.h>
#include "string_utils.h"
// For gcc backtrace on crash!
#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD)
//#include <mcheck.h>
#include <execinfo.h>
#include <cxxabi.h>
#include <signal.h>
#endif
#ifdef WIN32
#if defined(__WIN32__) && !defined(__GNUC__)
#include <eh.h>
#endif
#include <dbghelp.h>
#endif
#include <stdlib.h>
#include "leak_dumper.h"
#ifndef WIN32
#include <poll.h>
#define stricmp strcasecmp
#define strnicmp strncasecmp
#define _strnicmp strncasecmp
#endif
#ifdef WIN32
#ifndef _DEBUG
#ifndef __GNUC__
#define WIN32_STACK_TRACE
#endif
#endif
#endif
using namespace std;
using namespace Shared::Platform;
using namespace Shared::Util;
using namespace Shared::Graphics;
using namespace Shared::Graphics::Gl;
using namespace Shared::Xml;
using namespace Shared;
namespace Glest{ namespace Game{
bool disableheadless_console = false;
bool disableBacktrace = false;
bool gameInitialized = false;
//static string application_binary="";
static string application_binary="";
static string mg_app_name = "";
static string mailStringSupport = "";
static bool sdl_quitCalled = false;
//static bool isMasterServerModeEnabled = false;
FileCRCPreCacheThread *preCacheThread=NULL;
string runtimeErrorMsg = "";
void cleanupCRCThread() {
if(preCacheThread != NULL) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
time_t elapsed = time(NULL);
preCacheThread->signalQuit();
for(;preCacheThread->canShutdown(false) == false &&
difftime(time(NULL),elapsed) <= 45;) {
//sleep(150);
}
if(preCacheThread->canShutdown(false)) {
if(preCacheThread->shutdownAndWait() == true) {
delete preCacheThread;
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
else {
if(preCacheThread->shutdownAndWait() == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
delete preCacheThread;
//printf("Stopping broadcast thread [%p] - C\n",broadCastThread);
}
}
preCacheThread = NULL;
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
static void cleanupProcessObjects() {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
showCursor(true);
restoreVideoMode(true);
}
cleanupCRCThread();
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(Renderer::isEnded() == false) {
Renderer::getInstance().end();
CoreData &coreData= CoreData::getInstance();
coreData.cleanup();
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::Close();
SystemFlags::SHUTDOWN_PROGRAM_MODE=true;
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("start running threads = %lu\n",Thread::getThreadList().size());
time_t elapsed = time(NULL);
for(;Thread::getThreadList().size() > 0 &&
difftime(time(NULL),elapsed) <= 10;) {
//sleep(0);
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("end running threads = %lu\n",Thread::getThreadList().size());
std::map<int,Texture2D *> &crcPlayerTextureCache = CacheManager::getCachedItem< std::map<int,Texture2D *> >(GameConstants::playerTextureCacheLookupKey);
//deleteMapValues(crcPlayerTextureCache.begin(),crcPlayerTextureCache.end());
crcPlayerTextureCache.clear();
std::map<string,Texture2D *> &crcFactionPreviewTextureCache = CacheManager::getCachedItem< std::map<string,Texture2D *> >(GameConstants::factionPreviewTextureCacheLookupKey);
//deleteMapValues(crcFactionPreviewTextureCache.begin(),crcFactionPreviewTextureCache.end());
crcFactionPreviewTextureCache.clear();
std::map<string, vector<FileReader<Pixmap2D> const * >* > &list2d = FileReader<Pixmap2D>::getFileReadersMap();
//printf("list2d = %lu\n",list2d.size());
deleteMapValues(list2d.begin(),list2d.end());
std::map<string, vector<FileReader<Pixmap3D> const * >* > &list3d = FileReader<Pixmap3D>::getFileReadersMap();
//printf("list3d = %lu\n",list3d.size());
deleteMapValues(list3d.begin(),list3d.end());
XmlIo::getInstance().cleanup();
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::globalCleanupHTTP();
CacheManager::cleanupMutexes();
}
#if defined(WIN32) && !defined(_DEBUG) && !defined(__GNUC__)
void fatal(const char *s, ...) // failure exit
{
static int errors = 0;
errors++;
if(errors <= 5) { // print up to two extra recursive errors
defvformatstring(msg,s,s);
string errText = string(msg) + " [" + runtimeErrorMsg + "]";
//puts(msg);
string sErr = string(mg_app_name) + " fatal error";
SystemFlags::OutputDebug(SystemFlags::debugError,"%s\n",errText.c_str());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",errText.c_str());
if(errors <= 1) { // avoid recursion
if(SDL_WasInit(SDL_INIT_VIDEO)) {
SDL_ShowCursor(1);
SDL_WM_GrabInput(SDL_GRAB_OFF);
//SDL_SetGamma(1, 1, 1);
}
#ifdef WIN32
LPWSTR wstr = Ansi2WideString(errText.c_str());
LPWSTR wstr1 = Ansi2WideString(sErr.c_str());
MessageBox(NULL, wstr, wstr1, MB_OK|MB_SYSTEMMODAL);
delete [] wstr;
delete [] wstr1;
#endif
//SDL_Quit();
}
}
// Now try to shutdown threads if possible
Program *program = Program::getInstance();
delete program;
program = NULL;
// END
if(sdl_quitCalled == false) {
sdl_quitCalled = true;
SDL_Quit();
}
exit(EXIT_FAILURE);
}
void stackdumper(unsigned int type, EXCEPTION_POINTERS *ep) {
if(!ep) fatal("unknown type");
EXCEPTION_RECORD *er = ep->ExceptionRecord;
CONTEXT *context = ep->ContextRecord;
stringType out, t;
formatstring(out)("%s Exception: 0x%x [0x%x]\n\n", mg_app_name, er->ExceptionCode, er->ExceptionCode==EXCEPTION_ACCESS_VIOLATION ? er->ExceptionInformation[1] : -1);
STACKFRAME sf = {{context->Eip, 0, AddrModeFlat}, {}, {context->Ebp, 0, AddrModeFlat}, {context->Esp, 0, AddrModeFlat}, 0};
SymInitialize(GetCurrentProcess(), NULL, TRUE);
while(::StackWalk(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), GetCurrentThread(), &sf, context, NULL, ::SymFunctionTableAccess, ::SymGetModuleBase, NULL)) {
struct { IMAGEHLP_SYMBOL sym; stringType n; }
si = { { sizeof( IMAGEHLP_SYMBOL ), 0, 0, 0, sizeof(stringType) } };
IMAGEHLP_LINE li = { sizeof( IMAGEHLP_LINE ) };
DWORD off=0;
DWORD dwDisp=0;
if( SymGetSymFromAddr(GetCurrentProcess(), (DWORD)sf.AddrPC.Offset, &off, &si.sym) &&
SymGetLineFromAddr(GetCurrentProcess(), (DWORD)sf.AddrPC.Offset, &dwDisp, &li)) {
char *del = strrchr(li.FileName, '\\');
formatstring(t)("%s - %s [%d]\n", si.sym.Name, del ? del + 1 : li.FileName, li.LineNumber+dwDisp);
concatstring(out, t);
}
}
fatal(out);
}
#endif
// =====================================================
// class ExceptionHandler
// =====================================================
class ExceptionHandler: public PlatformExceptionHandler{
public:
virtual void handle() {
string msg = "#1 An error occurred and " + string(mg_app_name) + " will close.\nPlease report this bug to: " + string(mailString);
#ifdef WIN32
msg += ", attaching the generated " + getCrashDumpFileName()+ " file.";
#endif
SystemFlags::OutputDebug(SystemFlags::debugError,"%s\n",msg.c_str());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",msg.c_str());
Program *program = Program::getInstance();
if(program && gameInitialized == true) {
program->showMessage(msg.c_str());
}
message(msg.c_str());
}
#if defined(__GNUC__) && !defined(__FreeBSD__) && !defined(BSD)
static int getFileAndLine(void *address, char *file, size_t flen) {
int line=-1;
const int maxbufSize = 1024;
static char buf[maxbufSize+1]="";
//char *p=NULL;
// prepare command to be executed
// our program need to be passed after the -e parameter
//sprintf (buf, "/usr/bin/addr2line -C -e ./a.out -f -i %lx", addr);
sprintf(buf, "addr2line -C -e %s -f -i %p",application_binary.c_str(),address);
FILE* f = popen (buf, "r");
if (f == NULL) {
perror (buf);
return 0;
}
// get function name
char *ret = fgets (buf, maxbufSize, f);
if(ret == NULL) {
pclose(f);
return 0;
}
// get file and line
ret = fgets (buf, maxbufSize, f);
if(ret == NULL) {
pclose(f);
return 0;
}
if(strlen(buf) > 0 && buf[0] != '?') {
//int l;
char *p = buf;
// file name is until ':'
while(*p != 0 && *p != ':') {
p++;
}
*p++ = 0;
// after file name follows line number
strcpy (file , buf);
sscanf (p,"%d", &line);
}
else {
strcpy (file,"unknown");
line = 0;
}
pclose(f);
return line;
}
#endif
static void logError(const char *msg, bool confirmToConsole) {
string errorLogFile = "error.log";
if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
errorLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + errorLogFile;
}
else {
string userData = Config::getInstance().getString("UserData_Root","");
if(userData != "") {
endPathWithSlash(userData);
}
errorLogFile = userData + errorLogFile;
}
//printf("Attempting to write error to file [%s]\n",errorLogFile.c_str());
#if defined(WIN32) && !defined(__MINGW32__)
FILE *fp = _wfopen(utf8_decode(errorLogFile).c_str(), L"w");
std::ofstream logFile(fp);
#else
std::ofstream logFile;
logFile.open(errorLogFile.c_str(), ios_base::out | ios_base::trunc);
#endif
if(logFile.is_open() == true) {
time_t curtime = time (NULL);
struct tm *loctime = localtime (&curtime);
char szBuf2[100]="";
strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",loctime);
logFile << "[" << szBuf2 << "] Runtime Error information:" << std::endl;
logFile << "======================================================" << std::endl;
logFile << (msg != NULL ? msg : "null") << std::endl;
logFile.close();
#if defined(WIN32) && !defined(__MINGW32__)
if(fp) {
fclose(fp);
}
#endif
if(confirmToConsole == true) {
printf("Error saved to logfile [%s]\n",errorLogFile.c_str());
fflush(stdout);
}
}
else {
if(confirmToConsole == true) {
printf("COULD NOT SAVE TO ERROR logfile [%s]\n",errorLogFile.c_str());
fflush(stdout);
}
}
}
static void handleRuntimeError(const char *msg) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
static bool inErrorNow = false;
if(inErrorNow == true) {
printf("\n** Already in error handler, msg [%s]\n",msg);
fflush(stdout);
abort();
return;
}
inErrorNow = true;
logError(msg,true);
Program *program = Program::getInstance();
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] program = %p gameInitialized = %d msg [%s]\n",__FILE__,__FUNCTION__,__LINE__,program,gameInitialized,msg);
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] [%s] gameInitialized = %d, program = %p\n",__FILE__,__FUNCTION__,__LINE__,msg,gameInitialized,program);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%s] gameInitialized = %d, program = %p\n",__FILE__,__FUNCTION__,__LINE__,msg,gameInitialized,program);
string errMsg = (msg != NULL ? msg : "null");
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD)
if(disableBacktrace == false && sdl_quitCalled == false) {
errMsg += "\nStack Trace:\n";
//errMsg += "To find line #'s use:\n";
//errMsg += "readelf --debug-dump=decodedline %s | egrep 0xaddress-of-stack\n";
const size_t max_depth = 15;
void *stack_addrs[max_depth];
size_t stack_depth = backtrace(stack_addrs, max_depth);
char **stack_strings = backtrace_symbols(stack_addrs, stack_depth);
//for (size_t i = 1; i < stack_depth; i++) {
// errMsg += string(stack_strings[i]) + "\n";
//}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
char szBuf[4096]="";
for(size_t i = 1; i < stack_depth; i++) {
//const unsigned int stackIndex = i-1;
//printf("In [%s::%s Line: %d] [%s] gameInitialized = %d, i = %d, stack_depth = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,gameInitialized,i,stack_depth);
void *lineAddress = stack_addrs[i]; //getStackAddress(stackIndex);
//printf("In [%s::%s Line: %d] [%s] gameInitialized = %d, i = %d, stack_depth = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,gameInitialized,i,stack_depth);
size_t sz = 1024; // just a guess, template names will go much wider
char *function = static_cast<char *>(malloc(sz));
char *begin = 0;
char *end = 0;
// find the parentheses and address offset surrounding the mangled name
for (char *j = stack_strings[i]; *j; ++j) {
if (*j == '(') {
begin = j;
}
else if (*j == '+') {
end = j;
}
}
if (begin && end) {
*begin++ = '\0';
*end = '\0';
// found our mangled name, now in [begin, end)
int status;
char *ret = abi::__cxa_demangle(begin, function, &sz, &status);
if (ret) {
// return value may be a realloc() of the input
function = ret;
}
else {
// demangling failed, just pretend it's a C function with no args
strncpy(function, begin, sz);
strncat(function, "()", sz);
function[sz-1] = '\0';
}
//fprintf(out, " %s:%s\n", stack.strings[i], function);
sprintf(szBuf,"%s:%s address [%p]",stack_strings[i],function,lineAddress);
}
else {
// didn't find the mangled name, just print the whole line
//fprintf(out, " %s\n", stack.strings[i]);
sprintf(szBuf,"%s address [%p]",stack_strings[i],lineAddress);
}
errMsg += string(szBuf);
char file[4096]="";
int line = getFileAndLine(lineAddress, file, 4096);
if(line >= 0) {
errMsg += " line: " + intToStr(line);
}
errMsg += "\n";
free(function);
}
free(stack_strings); // malloc()ed by backtrace_symbols
}
#endif
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
logError(errMsg.c_str(),false);
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] [%s]\n",__FILE__,__FUNCTION__,__LINE__,errMsg.c_str());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%s]\n",__FILE__,__FUNCTION__,__LINE__,errMsg.c_str());
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//abort();
if(program && gameInitialized == true) {
//printf("\nprogram->getState() [%p]\n",program->getState());
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(program->getState() != NULL) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
program->showMessage(errMsg.c_str());
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
for(;GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false && program->isMessageShowing();) {
//program->getState()->render();
Window::handleEvent();
program->loop();
//printf("\nhandle error #1\n");
}
}
else {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
program->showMessage(errMsg.c_str());
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
for(;GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false && program->isMessageShowing();) {
//program->renderProgramMsgBox();
Window::handleEvent();
program->loop();
//printf("\nhandle error #2\n");
}
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
else {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
string err = "#2 An error occurred and ";
if(sdl_quitCalled == false) {
err += mg_app_name;
}
err += " will close.\nError msg = [" + errMsg + "]\n\nPlease report this bug to ";
if(sdl_quitCalled == false) {
err += mailStringSupport;
}
#ifdef WIN32
err += string(", attaching the generated ") + getCrashDumpFileName() + string(" file.");
#endif
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
message(err);
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
// Now try to shutdown threads if possible
delete program;
program = NULL;
// END
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
#ifdef WIN32
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
showCursor(true);
restoreVideoMode(true);
}
runtimeErrorMsg = errMsg;
inErrorNow = false;
throw runtimeErrorMsg;
#endif
//printf("In [%s::%s Line: %d] [%s] gameInitialized = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,gameInitialized);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
cleanupProcessObjects();
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(sdl_quitCalled == false) {
sdl_quitCalled = true;
SDL_Quit();
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
inErrorNow = false;
abort();
}
static int DisplayMessage(const char *msg, bool exitApp) {
//printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
Program *program = Program::getInstance();
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
if(program && gameInitialized == true) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
program->showMessage(msg);
}
else {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
message(msg);
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
if(exitApp == true) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",msg);
// Now try to shutdown threads if possible
Program *program = Program::getInstance();
delete program;
program = NULL;
// END
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
cleanupProcessObjects();
if(sdl_quitCalled == false) {
sdl_quitCalled = true;
SDL_Quit();
}
exit(-1);
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
return 0;
}
};
#if defined(__GNUC__) && !defined(__FreeBSD__) && !defined(BSD)
void handleSIGSEGV(int sig) {
char szBuf[4096]="";
sprintf(szBuf, "In [%s::%s Line: %d] Error detected: signal %d:\n",__FILE__,__FUNCTION__,__LINE__, sig);
printf("%s",szBuf);
//abort();
ExceptionHandler::handleRuntimeError(szBuf);
}
#endif
// =====================================================
// class MainWindow
// =====================================================
MainWindow::MainWindow(Program *program) : WindowGl() {
this->program= program;
this->popupMenu.setEnabled(false);
this->popupMenu.setVisible(false);
this->triggerLanguageToggle = false;
this->triggerLanguage = "";
this->cancelLanguageSelection = -1;
}
MainWindow::~MainWindow(){
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
delete program;
program = NULL;
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void MainWindow::eventMouseDown(int x, int y, MouseButton mouseButton){
const Metrics &metrics = Metrics::getInstance();
int vx = metrics.toVirtualX(x);
int vy = metrics.toVirtualY(getH() - y);
if(program == NULL) {
throw runtime_error("In [MainWindow::eventMouseDown] ERROR, program == NULL!");
}
//printf("eventMouseDown popupMenu.getVisible() = %d\n",popupMenu.getVisible());
if(popupMenu.getVisible() == true && popupMenu.mouseClick(vx, vy)) {
std::pair<int,string> result = popupMenu.mouseClickedMenuItem(vx, vy);
//printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first);
popupMenu.setEnabled(false);
popupMenu.setVisible(false);
//printf("result.first = %d [%s] cancelLanguageSelection = %d\n",result.first,result.second.c_str(),cancelLanguageSelection);
// Exit game
if(result.first != cancelLanguageSelection) {
//toggleLanguage(result.second);
this->triggerLanguageToggle = true;
this->triggerLanguage = result.second;
}
return;
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
switch(mouseButton) {
case mbLeft:
program->mouseDownLeft(vx, vy);
break;
case mbRight:
//program->mouseDownRight(vx, vy);
break;
case mbCenter:
//program->mouseDownCenter(vx, vy);
break;
default:
break;
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
ProgramState *programState = program->getState();
if(programState != NULL) {
switch(mouseButton) {
case mbLeft:
programState->mouseDownLeft(vx, vy);
break;
case mbRight:
programState->mouseDownRight(vx, vy);
break;
case mbCenter:
programState->mouseDownCenter(vx, vy);
break;
default:
break;
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void MainWindow::eventMouseUp(int x, int y, MouseButton mouseButton){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
const Metrics &metrics = Metrics::getInstance();
int vx = metrics.toVirtualX(x);
int vy = metrics.toVirtualY(getH() - y);
if(program == NULL) {
throw runtime_error("In [MainWindow::eventMouseUp] ERROR, program == NULL!");
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
ProgramState *programState = program->getState();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(programState != NULL) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
switch(mouseButton) {
case mbLeft:
programState->mouseUpLeft(vx, vy);
break;
case mbRight:
programState->mouseUpRight(vx, vy);
break;
case mbCenter:
programState->mouseUpCenter(vx, vy);
break;
default:
break;
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void MainWindow::eventMouseDoubleClick(int x, int y, MouseButton mouseButton) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
const Metrics &metrics= Metrics::getInstance();
int vx = metrics.toVirtualX(x);
int vy = metrics.toVirtualY(getH() - y);
if(program == NULL) {
throw runtime_error("In [MainWindow::eventMouseDoubleClick] ERROR, program == NULL!");
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
ProgramState *programState = program->getState();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(programState != NULL) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
switch(mouseButton){
case mbLeft:
programState->mouseDoubleClickLeft(vx, vy);
break;
case mbRight:
programState->mouseDoubleClickRight(vx, vy);
break;
case mbCenter:
programState->mouseDoubleClickCenter(vx, vy);
break;
default:
break;
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void MainWindow::eventMouseMove(int x, int y, const MouseState *ms){
const Metrics &metrics= Metrics::getInstance();
int vx = metrics.toVirtualX(x);
int vy = metrics.toVirtualY(getH() - y);
if(program == NULL) {
throw runtime_error("In [MainWindow::eventMouseMove] ERROR, program == NULL!");
}
program->eventMouseMove(vx, vy, ms);
ProgramState *programState = program->getState();
if(programState != NULL) {
programState->mouseMove(vx, vy, ms);
}
}
void MainWindow::eventMouseWheel(int x, int y, int zDelta) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
const Metrics &metrics= Metrics::getInstance();
int vx = metrics.toVirtualX(x);
int vy = metrics.toVirtualY(getH() - y);
if(program == NULL) {
throw runtime_error("In [MainWindow::eventMouseMove] ERROR, program == NULL!");
}
ProgramState *programState = program->getState();
if(programState != NULL) {
programState->eventMouseWheel(vx, vy, zDelta);
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void MainWindow::render() {
if(popupMenu.getVisible() == true) {
Renderer &renderer= Renderer::getInstance();
renderer.renderPopupMenu(&popupMenu);
//printf("Render lang popup\n");
}
}
void MainWindow::showLanguages() {
Lang &lang= Lang::getInstance();
//PopupMenu popupMenu;
std::vector<string> menuItems;
vector<string> langResults;
string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
string userDataPath = getGameCustomCoreDataPath(data_path, "");
findAll(userDataPath + "data/lang/*.lng", langResults, true, false);
for(unsigned int i = 0; i < langResults.size(); ++i) {
string testLanguage = langResults[i];
menuItems.push_back(testLanguage);
}
vector<string> langResults2;
findAll(data_path + "data/lang/*.lng", langResults2, true);
if(langResults2.empty() && langResults.empty()) {
throw runtime_error("There are no lang files");
}
for(unsigned int i = 0; i < langResults2.size(); ++i) {
string testLanguage = langResults2[i];
if(std::find(menuItems.begin(),menuItems.end(),testLanguage) == menuItems.end()) {
menuItems.push_back(testLanguage);
}
}
menuItems.push_back(lang.get("Exit"));
cancelLanguageSelection = menuItems.size()-1;
popupMenu.setW(100);
popupMenu.setH(100);
popupMenu.init(lang.get("GameMenuTitle"),menuItems);
popupMenu.setEnabled(true);
popupMenu.setVisible(true);
}
void MainWindow::toggleLanguage(string language) {
popupMenu.setEnabled(false);
popupMenu.setVisible(false);
this->triggerLanguageToggle = false;
this->triggerLanguage = "";
Lang &lang= Lang::getInstance();
string currentLanguage = lang.getLanguage();
string newLanguageSelected = language;
if(language == "") {
newLanguageSelected = currentLanguage;
vector<string> langResults;
string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
string userDataPath = getGameCustomCoreDataPath(data_path, "");
findAll(userDataPath + "data/lang/*.lng", langResults, true, false);
vector<string> langResults2;
findAll(data_path + "data/lang/*.lng", langResults2, true);
if(langResults2.empty() && langResults.empty()) {
throw runtime_error("There are no lang files");
}
for(unsigned int i = 0; i < langResults2.size(); ++i) {
string testLanguage = langResults2[i];
if(std::find(langResults.begin(),langResults.end(),testLanguage) == langResults.end()) {
langResults.push_back(testLanguage);
}
}
for(unsigned int i = 0; i < langResults.size(); ++i) {
string testLanguage = langResults[i];
if(testLanguage == currentLanguage) {
if( i+1 < langResults.size()) {
newLanguageSelected = langResults[i+1];
}
else {
newLanguageSelected = langResults[0];
}
break;
}
}
}
if(newLanguageSelected != currentLanguage) {
lang.loadStrings(newLanguageSelected);
program->reloadUI();
program->consoleAddLine(lang.get("Language") + " " + newLanguageSelected);
}
}
void MainWindow::eventKeyDown(SDL_KeyboardEvent key) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%d]\n",__FILE__,__FUNCTION__,__LINE__,key.keysym.sym);
//SDL_keysym keystate = Window::getKeystate();
SDL_keysym keystate = key.keysym;
//printf("keystate.mod = %d key = %d lalt [%d] ralt [%d] alt [%d]\n",keystate.mod,key.keysym.unicode,(keystate.mod & KMOD_LALT),(keystate.mod & KMOD_RALT),(keystate.mod & KMOD_ALT));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%c][%d]\n",__FILE__,__FUNCTION__,__LINE__,key,key);
if(program == NULL) {
throw runtime_error("In [MainWindow::eventKeyDown] ERROR, program == NULL!");
}
if(popupMenu.getVisible() == true && isKeyPressed(SDLK_ESCAPE,key) == true) {
this->popupMenu.setEnabled(false);
this->popupMenu.setVisible(false);
return;
}
//{
//Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
//printf("----------------------- key [%d] CameraModeLeft [%d]\n",key,configKeys.getCharKey("CameraModeLeft"));
//}
program->keyDown(key);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(keystate.mod & (KMOD_LALT | KMOD_RALT)) {
//if(key == vkReturn) {
if(isKeyPressed(SDLK_RETURN,key) == true) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ALT-ENTER pressed\n",__FILE__,__FUNCTION__,__LINE__);
// This stupidity only required in win32.
// We reload the textures so that the canvas paints textures properly
#ifdef WIN32
if(Window::getAllowAltEnterFullscreenToggle() == true) {
Renderer &renderer= Renderer::getInstance();
renderer.reinitAll();
}
#endif
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
}
if(program != NULL && program->isInSpecialKeyCaptureEvent() == false) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
//if(key == configKeys.getCharKey("HotKeyShowDebug")) {
if(isKeyPressed(configKeys.getSDLKey("HotKeyShowDebug"),key) == true) {
//printf("debug key pressed keystate.mod = %d [%d]\n",keystate.mod,keystate.mod & (KMOD_LALT | KMOD_RALT));
Renderer &renderer= Renderer::getInstance();
//if(keystate.mod & (KMOD_LCTRL | KMOD_RCTRL)) {
if(keystate.mod & (KMOD_LALT | KMOD_RALT)) {
renderer.cycleShowDebugUILevel();
}
else {
bool showDebugUI = renderer.getShowDebugUI();
renderer.setShowDebugUI(!showDebugUI);
}
}
else if(keystate.mod & (KMOD_LCTRL | KMOD_RCTRL) &&
isKeyPressed(configKeys.getSDLKey("SwitchLanguage"),key) == true) {
if(keystate.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) {
//toggleLanguage("");
this->triggerLanguageToggle = true;
this->triggerLanguage = "";
}
else {
showLanguages();
}
}
//else if(key == configKeys.getCharKey("ReloadINI")) {
else if(isKeyPressed(configKeys.getSDLKey("ReloadINI"),key) == true) {
Config &config = Config::getInstance();
config.reload();
}
//else if(key == configKeys.getCharKey("Screenshot")) {
else if(isKeyPressed(configKeys.getSDLKey("Screenshot"),key) == true) {
string userData = Config::getInstance().getString("UserData_Root","");
if(userData != "") {
endPathWithSlash(userData);
}
string path = userData + GameConstants::folder_path_screenshots;
if(isdir(path.c_str()) == true) {
Config &config= Config::getInstance();
string fileFormat = config.getString("ScreenShotFileType","jpg");
unsigned int queueSize = Renderer::getInstance().getSaveScreenQueueSize();
for(int i=0; i < 5000; ++i) {
path = userData + GameConstants::folder_path_screenshots;
path += string("screen") + intToStr(i + queueSize) + string(".") + fileFormat;
#ifdef WIN32
FILE *f= _wfopen(utf8_decode(path).c_str(), L"rb");
#else
FILE *f= fopen(path.c_str(), "rb");
#endif
if(f == NULL) {
Lang &lang= Lang::getInstance();
char szBuf[1024]="";
if(lang.get("ScreenshotSavedTo").length() > 0 && lang.get("ScreenshotSavedTo")[0] != '?') {
sprintf(szBuf,lang.get("ScreenshotSavedTo").c_str(),path.c_str());
}
else {
sprintf(szBuf,"Screenshot will be saved to: %s",path.c_str());
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,szBuf);
if(Config::getInstance().getBool("DisableScreenshotConsoleText","false") == false) {
program->consoleAddLine(szBuf);
}
Renderer::getInstance().saveScreen(path);
break;
}
else {
fclose(f);
}
}
}
}
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void MainWindow::eventKeyUp(SDL_KeyboardEvent key) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%d]\n",__FILE__,__FUNCTION__,__LINE__,key);
if(program == NULL) {
throw runtime_error("In [MainWindow::eventKeyUp] ERROR, program == NULL!");
}
program->keyUp(key);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%d]\n",__FILE__,__FUNCTION__,__LINE__,key);
}
void MainWindow::eventKeyPress(SDL_KeyboardEvent c) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%d]\n",__FILE__,__FUNCTION__,__LINE__,c);
if(program == NULL) {
throw runtime_error("In [MainWindow::eventKeyPress] ERROR, program == NULL!");
}
program->keyPress(c);
if(program != NULL && program->isInSpecialKeyCaptureEvent() == false) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
//if(c == configKeys.getCharKey("HotKeyToggleOSMouseEnabled")) {
if(isKeyPressed(configKeys.getSDLKey("HotKeyToggleOSMouseEnabled"),c) == true) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
bool showCursorState = false;
int state = SDL_ShowCursor(SDL_QUERY);
if(state == SDL_DISABLE) {
showCursorState = true;
}
showCursor(showCursorState);
Renderer &renderer= Renderer::getInstance();
renderer.setNo2DMouseRendering(showCursorState);
Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Window::lastShowMouseState = %d\n",__FILE__,__FUNCTION__,__LINE__,Window::lastShowMouseState);
}
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%d]\n",__FILE__,__FUNCTION__,__LINE__,c);
}
void MainWindow::eventActivate(bool active) {
if(!active){
//minimize();
}
}
void MainWindow::eventResize(SizeState sizeState) {
if(program == NULL) {
throw runtime_error("In [MainWindow::eventResize] ERROR, program == NULL!");
}
program->resize(sizeState);
}
void MainWindow::eventClose(){
delete program;
program= NULL;
}
void MainWindow::setProgram(Program *program) {
this->program= program;
}
// =====================================================
// Main
// =====================================================
SystemFlags debugger;
void print_SDL_version(const char *preamble, SDL_version *v) {
printf("%s %u.%u.%u\n", preamble, v->major, v->minor, v->patch);
}
int setupGameItemPaths(int argc, char** argv, Config *config) {
// Setup path cache for files and folders used in the game
std::map<string,string> &pathCache = CacheManager::getCachedItem< std::map<string,string> >(GameConstants::pathCacheLookupKey);
//GAME_ARG_DATA_PATH
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DATA_PATH]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_DATA_PATH]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_DATA_PATH]),&foundParamIndIndex);
}
string customPath = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(customPath,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string customPathValue = paramPartTokens[1];
Properties::applyTagsToValue(customPathValue);
if(customPathValue != "") {
endPathWithSlash(customPathValue);
}
pathCache[GameConstants::path_data_CacheLookupKey]=customPathValue;
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using custom data path [%s]\n",customPathValue.c_str());
}
else {
printf("\nInvalid path specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
printParameterHelp(argv[0],false);
return -1;
}
}
else if(config != NULL) {
if(config->getString("DataPath","") != "") {
string customPathValue = config->getString("DataPath","");
if(customPathValue != "") {
endPathWithSlash(customPathValue);
}
pathCache[GameConstants::path_data_CacheLookupKey] = config->getString("DataPath","");
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using ini specified data path [%s]\n",config->getString("DataPath","").c_str());
}
}
//GAME_ARG_INI_PATH
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_INI_PATH]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_INI_PATH]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_INI_PATH]),&foundParamIndIndex);
}
string customPath = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(customPath,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string customPathValue = paramPartTokens[1];
Properties::applyTagsToValue(customPathValue);
pathCache[GameConstants::path_ini_CacheLookupKey]=customPathValue;
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using custom ini path [%s]\n",customPathValue.c_str());
}
else {
printf("\nInvalid path specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
printParameterHelp(argv[0],false);
return -1;
}
}
//GAME_ARG_LOG_PATH
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LOG_PATH]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LOG_PATH]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LOG_PATH]),&foundParamIndIndex);
}
string customPath = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(customPath,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string customPathValue = paramPartTokens[1];
Properties::applyTagsToValue(customPathValue);
pathCache[GameConstants::path_logs_CacheLookupKey]=customPathValue;
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using custom logs path [%s]\n",customPathValue.c_str());
}
else {
printf("\nInvalid path specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
printParameterHelp(argv[0],false);
return -1;
}
}
else if(config != NULL) {
if(config->getString("LogPath","") != "") {
pathCache[GameConstants::path_logs_CacheLookupKey] = config->getString("LogPath","");
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using ini specified logs path [%s]\n",config->getString("LogPath","").c_str());
}
}
Text::DEFAULT_FONT_PATH = pathCache[GameConstants::path_data_CacheLookupKey];
return 0;
}
void setupLogging(Config &config, bool haveSpecialOutputCommandLineOption) {
SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled = config.getBool("DebugMode","false");
SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled = config.getBool("DebugNetwork","false");
SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled = config.getBool("DebugPerformance","false");
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled = config.getBool("DebugWorldSynch","false");
SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled = config.getBool("DebugUnitCommands","false");
SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled = config.getBool("DebugPathFinder","false");
SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled = config.getBool("DebugLUA","false");
SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled = config.getBool("DebugSound","false");
SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled = config.getBool("DebugError","true");
string userData = config.getString("UserData_Root","");
if(userData != "") {
endPathWithSlash(userData);
}
string debugLogFile = config.getString("DebugLogFile","");
if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
debugLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugLogFile;
}
else {
debugLogFile = userData + debugLogFile;
}
//printf("debugLogFile [%s]\n",debugLogFile.c_str());
string debugWorldSynchLogFile = config.getString("DebugLogFileWorldSynch","");
if(debugWorldSynchLogFile == "") {
debugWorldSynchLogFile = debugLogFile;
}
else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
debugWorldSynchLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugWorldSynchLogFile;
}
else {
debugWorldSynchLogFile = userData + debugWorldSynchLogFile;
}
string debugPerformanceLogFile = config.getString("DebugLogFilePerformance","");
if(debugPerformanceLogFile == "") {
debugPerformanceLogFile = debugLogFile;
}
else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
debugPerformanceLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugPerformanceLogFile;
}
else {
debugPerformanceLogFile = userData + debugPerformanceLogFile;
}
string debugNetworkLogFile = config.getString("DebugLogFileNetwork","");
if(debugNetworkLogFile == "") {
debugNetworkLogFile = debugLogFile;
}
else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
debugNetworkLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugNetworkLogFile;
}
else {
debugNetworkLogFile = userData + debugNetworkLogFile;
}
string debugUnitCommandsLogFile = config.getString("DebugLogFileUnitCommands","");
if(debugUnitCommandsLogFile == "") {
debugUnitCommandsLogFile = debugLogFile;
}
else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
debugUnitCommandsLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugUnitCommandsLogFile;
}
else {
debugUnitCommandsLogFile = userData + debugUnitCommandsLogFile;
}
string debugPathFinderLogFile = config.getString("DebugLogFilePathFinder","");
if(debugPathFinderLogFile == "") {
debugPathFinderLogFile = debugLogFile;
}
else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
debugPathFinderLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugPathFinderLogFile;
}
else {
debugPathFinderLogFile = userData + debugPathFinderLogFile;
}
string debugLUALogFile = config.getString("DebugLogFileLUA","");
if(debugLUALogFile == "") {
debugLUALogFile = debugLogFile;
}
else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
debugLUALogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugLUALogFile;
}
else {
debugLUALogFile = userData + debugLUALogFile;
}
string debugSoundLogFile = config.getString("DebugLogFileSound","");
if(debugSoundLogFile == "") {
debugSoundLogFile = debugLogFile;
}
else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
debugSoundLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugSoundLogFile;
}
else {
debugSoundLogFile = userData + debugSoundLogFile;
}
string debugErrorLogFile = config.getString("DebugLogFileError","");
SystemFlags::getSystemSettingType(SystemFlags::debugSystem).debugLogFileName = debugLogFile;
SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).debugLogFileName = debugNetworkLogFile;
SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).debugLogFileName = debugPerformanceLogFile;
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).debugLogFileName = debugWorldSynchLogFile;
SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).debugLogFileName = debugUnitCommandsLogFile;
SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).debugLogFileName = debugPathFinderLogFile;
SystemFlags::getSystemSettingType(SystemFlags::debugLUA).debugLogFileName = debugLUALogFile;
SystemFlags::getSystemSettingType(SystemFlags::debugSound).debugLogFileName = debugSoundLogFile;
SystemFlags::getSystemSettingType(SystemFlags::debugError).debugLogFileName = debugErrorLogFile;
if(haveSpecialOutputCommandLineOption == false) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("--- Startup log settings are ---\ndebugSystem [%d][%s]\ndebugNetwork [%d][%s]\ndebugPerformance [%d][%s]\ndebugWorldSynch [%d][%s]\ndebugUnitCommands[%d][%s]\ndebugPathFinder[%d][%s]\ndebugLUA [%d][%s]\ndebugSound [%d][%s]\ndebugError [%d][%s]\n",
SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled,
debugLogFile.c_str(),
SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled,
debugNetworkLogFile.c_str(),
SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled,
debugPerformanceLogFile.c_str(),
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled,
debugWorldSynchLogFile.c_str(),
SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled,
debugUnitCommandsLogFile.c_str(),
SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled,
debugPathFinderLogFile.c_str(),
SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled,
debugLUALogFile.c_str(),
SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled,
debugSoundLogFile.c_str(),
SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled,
debugErrorLogFile.c_str());
}
}
void runTechValidationForPath(string techPath, string techName,
const std::vector<string> &filteredFactionList, World &world,
bool purgeUnusedFiles,bool purgeDuplicateFiles, bool showDuplicateFiles,
bool svnPurgeFiles,double &purgedMegaBytes) {
//Config &config = Config::getInstance();
vector<string> factionsList;
findDirs(techPath + techName + "/factions/", factionsList, false, false);
if(factionsList.empty() == false) {
Checksum checksum;
set<string> factions;
for(int j = 0; j < factionsList.size(); ++j) {
if( filteredFactionList.empty() == true ||
std::find(filteredFactionList.begin(),filteredFactionList.end(),factionsList[j]) != filteredFactionList.end()) {
factions.insert(factionsList[j]);
}
}
printf("\n----------------------------------------------------------------");
printf("\nChecking techPath [%s] techName [%s] total faction count = %d\n",techPath.c_str(), techName.c_str(),(int)factionsList.size());
for(int j = 0; j < factionsList.size(); ++j) {
if( filteredFactionList.empty() == true ||
std::find(filteredFactionList.begin(),filteredFactionList.end(),factionsList[j]) != filteredFactionList.end()) {
printf("Using faction [%s]\n",factionsList[j].c_str());
}
}
if(factions.empty() == false) {
bool techtree_errors = false;
std::map<string,vector<pair<string, string> > > loadedFileList;
//vector<string> pathList = config.getPathListForType(ptTechs,"");
vector<string> pathList;
pathList.push_back(techPath);
world.loadTech(pathList, techName, factions, &checksum, loadedFileList);
// Fixup paths with ..
{
std::map<string,vector<pair<string, string> > > newLoadedFileList;
for( std::map<string,vector<pair<string, string> > >::iterator iterMap = loadedFileList.begin();
iterMap != loadedFileList.end(); ++iterMap) {
string loadedFile = iterMap->first;
replaceAll(loadedFile,"//","/");
replaceAll(loadedFile,"\\\\","\\");
updatePathClimbingParts(loadedFile);
if(newLoadedFileList.find(loadedFile) != newLoadedFileList.end()) {
for(unsigned int xx1 = 0; xx1 < iterMap->second.size(); ++xx1) {
pair<string, string> &newVal = iterMap->second[xx1];
replaceAll(newVal.first,"//","/");
replaceAll(newVal.first,"\\\\","\\");
updatePathClimbingParts(newVal.first);
replaceAll(newVal.second,"//","/");
replaceAll(newVal.second,"\\\\","\\");
updatePathClimbingParts(newVal.second);
newLoadedFileList[loadedFile].push_back(newVal);
}
}
else {
for(unsigned int xx1 = 0; xx1 < iterMap->second.size(); ++xx1) {
pair<string, string> &newVal = iterMap->second[xx1];
replaceAll(newVal.first,"//","/");
replaceAll(newVal.first,"\\\\","\\");
updatePathClimbingParts(newVal.first);
replaceAll(newVal.second,"//","/");
replaceAll(newVal.second,"\\\\","\\");
updatePathClimbingParts(newVal.second);
}
newLoadedFileList[loadedFile] = iterMap->second;
}
}
loadedFileList = newLoadedFileList;
}
// Validate the faction setup to ensure we don't have any bad associations
std::vector<std::string> resultErrors = world.validateFactionTypes();
if(resultErrors.empty() == false) {
techtree_errors = true;
// Display the validation errors
string errorText = "\nErrors were detected:\n=====================\n";
for(int i = 0; i < resultErrors.size(); ++i) {
if(i > 0) {
errorText += "\n";
}
errorText = errorText + resultErrors[i];
}
errorText += "\n=====================\n";
//throw runtime_error(errorText);
printf("%s",errorText.c_str());
}
// Validate the faction resource setup to ensure we don't have any bad associations
printf("\nChecking resources, count = %d\n",world.getTechTree()->getResourceTypeCount());
for(int i = 0; i < world.getTechTree()->getResourceTypeCount(); ++i) {
printf("Found techtree resource [%s]\n",world.getTechTree()->getResourceType(i)->getName().c_str());
}
resultErrors = world.validateResourceTypes();
if(resultErrors.empty() == false) {
techtree_errors = true;
// Display the validation errors
string errorText = "\nErrors were detected:\n=====================\n";
for(int i = 0; i < resultErrors.size(); ++i) {
if(i > 0) {
errorText += "\n";
}
errorText = errorText + resultErrors[i];
}
errorText += "\n=====================\n";
//throw runtime_error(errorText);
printf("%s",errorText.c_str());
}
// Now check for unused files in the techtree
std::map<string,vector<pair<string, string> > > foundFileList;
for(unsigned int i = 0; i < pathList.size(); ++i) {
string path = pathList[i];
endPathWithSlash(path);
path = path + techName + "/";
replaceAll(path, "//", "/");
replaceAll(path, "\\\\", "\\");
vector<string> foundFiles = getFolderTreeContentsListRecursively(path + "*.", "");
for(unsigned int j = 0; j < foundFiles.size(); ++j) {
string file = foundFiles[j];
replaceAll(file, "//", "/");
replaceAll(file, "\\\\", "\\");
if( file.find("loading_screen") != string::npos ||
file.find("preview_screen") != string::npos ||
file.find("hud") != string::npos) {
continue;
}
if(file.find("/factions/") != string::npos) {
bool includeFaction = false;
for ( set<string>::iterator it = factions.begin(); it != factions.end(); ++it ) {
string currentFaction = *it;
if(file.find("/factions/" + currentFaction) != string::npos) {
includeFaction = true;
break;
}
}
if(includeFaction == false) {
continue;
}
}
replaceAll(file,"//","/");
replaceAll(file,"\\\\","\\");
foundFileList[file].push_back(make_pair(path,path));
}
}
printf("Found techtree filecount = %lu, used = %lu\n",(unsigned long)foundFileList.size(),(unsigned long)loadedFileList.size());
// for( std::map<string,vector<string> >::iterator iterMap = loadedFileList.begin();
// iterMap != loadedFileList.end(); ++iterMap) {
// string foundFile = iterMap->first;
//
// if(foundFile.find("golem_ack1.wav") != string::npos) {
// printf("FOUND file [%s]\n",foundFile.c_str());
// }
// }
int purgeCount = 0;
bool foundUnusedFile = false;
for( std::map<string,vector<pair<string, string> > >::iterator iterMap = foundFileList.begin();
iterMap != foundFileList.end(); ++iterMap) {
string foundFile = iterMap->first;
replaceAll(foundFile, "//", "/");
replaceAll(foundFile, "\\\\", "\\");
if(loadedFileList.find(foundFile) == loadedFileList.end()) {
if(foundUnusedFile == false) {
printf("\nWarning, unused files were detected - START:\n=====================\n");
}
foundUnusedFile = true;
printf("[%s]\n",foundFile.c_str());
string fileName = extractFileFromDirectoryPath(foundFile);
if(loadedFileList.find(fileName) != loadedFileList.end()) {
printf("possible match on [%s] ?\n",loadedFileList.find(fileName)->first.c_str());
}
else if(purgeUnusedFiles == true) {
off_t fileSize = getFileSize(foundFile);
// convert to MB
purgedMegaBytes += ((double)fileSize / 1048576.0);
purgeCount++;
if(svnPurgeFiles == true) {
char szBuf[4096]="";
sprintf(szBuf,"svn delete \"%s\"",foundFile.c_str());
bool svnOk = executeShellCommand(szBuf,0);
if(svnOk == false) {
throw runtime_error("Call to command failed [" + string(szBuf) + "]");
}
}
else {
removeFile(foundFile);
}
}
}
}
if(foundUnusedFile == true) {
if(purgedMegaBytes > 0) {
printf("Purged %.2f MB (%d) in files\n",purgedMegaBytes,purgeCount);
}
printf("\nWarning, unused files were detected - END:\n");
}
if(showDuplicateFiles == true) {
std::map<int32,vector<string> > mapDuplicateFiles;
// Now check for duplicate data content
for(std::map<string,vector<pair<string, string> > >::iterator iterMap = loadedFileList.begin();
iterMap != loadedFileList.end(); ++iterMap) {
string fileName = iterMap->first;
Checksum checksum;
checksum.addFile(fileName);
int32 crcValue = checksum.getSum();
// if(crcValue == 0) {
// char szBuf[4096]="";
// sprintf(szBuf,"Error calculating CRC for file [%s]",fileName.c_str());
// throw runtime_error(szBuf);
// }
// else {
// printf("** CRC for file [%s] is [%d] and has %d parents\n",fileName.c_str(),crcValue,(int)iterMap->second.size());
// }
mapDuplicateFiles[crcValue].push_back(fileName);
}
double duplicateMegaBytesPurged=0;
int duplicateCountPurged=0;
double duplicateMegaBytes=0;
int duplicateCount=0;
bool foundDuplicates = false;
for(std::map<int32,vector<string> >::iterator iterMap = mapDuplicateFiles.begin();
iterMap != mapDuplicateFiles.end(); ++iterMap) {
vector<string> &fileList = iterMap->second;
if(fileList.size() > 1) {
if(foundDuplicates == false) {
foundDuplicates = true;
printf("\nWarning, duplicate files were detected - START:\n=====================\n");
}
map<string,int> parentList;
for(unsigned int idx = 0; idx < fileList.size(); ++idx) {
string duplicateFile = fileList[idx];
if(idx > 0) {
off_t fileSize = getFileSize(duplicateFile);
// convert to MB
duplicateMegaBytes += ((double)fileSize / 1048576.0);
duplicateCount++;
}
else {
printf("\n");
}
printf("[%s]\n",duplicateFile.c_str());
std::map<string,vector<pair<string, string> > >::iterator iterFind = loadedFileList.find(duplicateFile);
if(iterFind != loadedFileList.end()) {
for(unsigned int jdx = 0; jdx < iterFind->second.size(); jdx++) {
parentList[iterFind->second[jdx].first]++;
}
}
}
for(map<string,int>::iterator iterMap1 = parentList.begin();
iterMap1 != parentList.end(); ++iterMap1) {
if(iterMap1 == parentList.begin()) {
printf("\tParents:\n");
}
printf("\t[%s]\n",iterMap1->first.c_str());
}
if(purgeDuplicateFiles == true) {
//printf("\nPurge Duplicate Files detected - START:\n=====================\n");
string newCommonFileName = "";
for(unsigned int idx = 0; idx < fileList.size(); ++idx) {
string duplicateFile = fileList[idx];
string fileExt = extractExtension(duplicateFile);
if(fileExt == "wav" || fileExt == "ogg") {
off_t fileSize = getFileSize(duplicateFile);
if(idx == 0) {
newCommonFileName = "$COMMONDATAPATH/sounds/" + extractFileFromDirectoryPath(duplicateFile);
string expandedNewCommonFileName = newCommonFileName;
std::map<string,string> mapExtraTagReplacementValues;
string techCommonData = techPath + techName + "/commondata/";
replaceAll(techCommonData, "//", "/");
mapExtraTagReplacementValues["$COMMONDATAPATH"] = techCommonData;
mapExtraTagReplacementValues = Properties::getTagReplacementValues(&mapExtraTagReplacementValues);
Properties::applyTagsToValue(expandedNewCommonFileName,&mapExtraTagReplacementValues);
createDirectoryPaths(extractDirectoryPathFromFile(expandedNewCommonFileName));
if(svnPurgeFiles == true) {
copyFileTo(duplicateFile, expandedNewCommonFileName);
char szBuf[4096]="";
sprintf(szBuf,"svn delete \"%s\"",duplicateFile.c_str());
bool svnOk = executeShellCommand(szBuf,0);
if(svnOk == false) {
throw runtime_error("Call to command failed [" + string(szBuf) + "]");
}
printf("*** Duplicate file:\n[%s]\nwas svn deleted and copied to:\n[%s]\n",duplicateFile.c_str(),expandedNewCommonFileName.c_str());
}
else {
//int result = 0;
int result = rename(duplicateFile.c_str(),expandedNewCommonFileName.c_str());
if(result != 0) {
char szBuf[4096]="";
char *errmsg = strerror(errno);
sprintf(szBuf,"!!! Error [%s] Could not rename [%s] to [%s]!",errmsg,duplicateFile.c_str(),expandedNewCommonFileName.c_str());
throw runtime_error(szBuf);
}
else {
printf("*** Duplicate file:\n[%s]\nwas renamed to:\n[%s]\n",duplicateFile.c_str(),expandedNewCommonFileName.c_str());
}
}
}
else {
if(svnPurgeFiles == true) {
char szBuf[4096]="";
sprintf(szBuf,"svn delete \"%s\"",duplicateFile.c_str());
bool svnOk = executeShellCommand(szBuf,0);
if(svnOk == false) {
throw runtime_error("Call to command failed [" + string(szBuf) + "]");
}
printf("*** Duplicate file:\n[%s]\nwas svn deleted\n",duplicateFile.c_str());
}
else {
removeFile(duplicateFile);
}
printf("*** Duplicate file:\n[%s]\nwas removed\n",duplicateFile.c_str());
// convert to MB
duplicateMegaBytesPurged += ((double)fileSize / 1048576.0);
duplicateCountPurged++;
}
}
}
std::map<string,int> mapUniqueParentList;
for(unsigned int idx = 0; idx < fileList.size(); ++idx) {
string duplicateFile = fileList[idx];
string fileExt = extractExtension(duplicateFile);
if(fileExt == "wav" || fileExt == "ogg") {
std::map<string,vector<pair<string, string> > >::iterator iterFind2 = loadedFileList.find(duplicateFile);
if(iterFind2 != loadedFileList.end()) {
for(unsigned int jdx1 = 0; jdx1 < iterFind2->second.size(); jdx1++) {
string parentFile = iterFind2->second[jdx1].first;
string searchText = iterFind2->second[jdx1].second;
if(mapUniqueParentList.find(parentFile) == mapUniqueParentList.end()) {
printf("*** Searching parent file:\n[%s]\nfor duplicate file reference:\n[%s]\nto replace with newname:\n[%s]\n",parentFile.c_str(),searchText.c_str(),newCommonFileName.c_str());
bool foundText = searchAndReplaceTextInFile(parentFile, searchText, newCommonFileName, false);
printf("foundText = %d\n",foundText);
if(foundText == false) {
char szBuf[4096]="";
sprintf(szBuf,"Error finding text [%s] in file [%s]",searchText.c_str(),parentFile.c_str());
throw runtime_error(szBuf);
}
mapUniqueParentList[parentFile]++;
}
}
}
}
}
//printf("\nPurge Duplicate Files detected - END:\n=====================\n");
}
else {
//printf("\nPurge Duplicate Files DISABLED - START:\n=====================\n");
string newCommonFileName = "";
for(unsigned int idx = 0; idx < fileList.size(); ++idx) {
string duplicateFile = fileList[idx];
string fileExt = extractExtension(duplicateFile);
if(fileExt == "wav" || fileExt == "ogg") {
off_t fileSize = getFileSize(duplicateFile);
if(idx == 0) {
newCommonFileName = "$COMMONDATAPATH/sounds/" + extractFileFromDirectoryPath(duplicateFile);
break;
}
}
}
//printf("\nPurge Duplicate Files #2 DISABLED [%lu] - START:\n=====================\n",fileList.size());
for(unsigned int idx = 0; idx < fileList.size(); ++idx) {
string duplicateFile = fileList[idx];
string fileExt = extractExtension(duplicateFile);
if(fileExt == "wav" || fileExt == "ogg") {
std::map<string,vector<pair<string, string> > >::iterator iterFind4 = loadedFileList.find(duplicateFile);
if(iterFind4 != loadedFileList.end()) {
for(unsigned int jdx = 0; jdx < iterFind4->second.size(); jdx++) {
string parentFile = iterFind4->second[jdx].first;
string searchText = iterFind4->second[jdx].second;
//replaceAll(parentFile, "//", "/");
//replaceAll(parentFile, "\\\\", "\\");
//printf("*** Searching parent file:\n[%s]\nfor duplicate file reference:\n[%s]\nto replace with newname:\n[%s]\n",parentFile.c_str(),searchText.c_str(),newCommonFileName.c_str());
bool foundText = searchAndReplaceTextInFile(parentFile, searchText, newCommonFileName, true);
//printf("foundText = %d\n",foundText);
if(foundText == false) {
string techCommonData = techPath + techName + "/commondata/";
replaceAll(techCommonData, "//", "/");
//printf("ERROR techCommonData check\n[%s]\n[%s]\n",techCommonData.c_str(),searchText.c_str());
if(StartsWith(searchText, techCommonData) == true) {
replaceAll(searchText, techCommonData, "$COMMONDATAPATH/");
foundText = searchAndReplaceTextInFile(parentFile, searchText, newCommonFileName, true);
}
if(foundText == false) {
//printf("Error finding text [%s] in file [%s]",searchText.c_str(),parentFile.c_str());
char szBuf[8096]="";
sprintf(szBuf,"Error finding text\n[%s]\nin file\n[%s]\nnew Common File [%s]\n",searchText.c_str(),parentFile.c_str(),newCommonFileName.c_str());
printf("\n\n=================================================\n%s",szBuf);
throw runtime_error(szBuf);
}
}
}
}
}
}
//printf("\nPurge Duplicate Files DISABLED - END:\n=====================\n");
}
}
}
if(foundDuplicates == true) {
printf("Duplicates %.2f MB (%d) in files\n",duplicateMegaBytes,duplicateCount);
printf("Duplicates purged %.2f MB (%d) in files\n",duplicateMegaBytesPurged,duplicateCountPurged);
printf("\nWarning, duplicate files were detected - END:\n");
}
}
if(techtree_errors == false) {
printf("\nValidation found NO ERRORS for techPath [%s] techName [%s] factions checked (count = %d):\n",techPath.c_str(), techName.c_str(),(int)factions.size());
for ( set<string>::iterator it = factions.begin(); it != factions.end(); ++it ) {
printf("Faction [%s]\n",(*it).c_str());
}
}
}
printf("----------------------------------------------------------------");
}
}
void runTechValidationReport(int argc, char** argv) {
//disableBacktrace=true;
printf("====== Started Validation ======\n");
bool purgeDuplicateFiles = false;
bool showDuplicateFiles = true;
bool purgeUnusedFiles = false;
bool svnPurgeFiles = false;
double purgedMegaBytes=0;
Config &config = Config::getInstance();
// Did the user pass a specific scenario to validate?
if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) + string("=")) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) + string("="),&foundParamIndIndex);
string filterList = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(filterList,paramPartTokens,"=");
if(paramPartTokens.size() >= 2) {
vector<string> optionList;
string validateScenarioName = paramPartTokens[1];
printf("Filtering scenario: %s\n",validateScenarioName.c_str());
if(paramPartTokens.size() >= 3) {
if(paramPartTokens[2] == "purgeunused") {
purgeUnusedFiles = true;
printf("*NOTE All unused scenario files will be deleted!\n");
}
}
{
printf("\n---------------- Loading scenario inside world ----------------\n");
World world;
double purgedMegaBytes=0;
std::vector<string> filteredFactionList;
vector<string> scenarioPaths = config.getPathListForType(ptScenarios);
for(int idx = 0; idx < scenarioPaths.size(); idx++) {
string &scenarioPath = scenarioPaths[idx];
endPathWithSlash(scenarioPath);
//printf("techPath [%s]\n",techPath.c_str());
vector<string> scenarioList;
findDirs(scenarioPath, scenarioList, false, false);
for(int idx2 = 0; idx2 < scenarioList.size(); idx2++) {
string &scenarioName = scenarioList[idx2];
//printf("Found Scenario [%s] looking for [%s]\n",scenarioName.c_str(),validateScenarioName.c_str());
if(scenarioName == validateScenarioName) {
string file = scenarioPath + scenarioName + "/" + scenarioName + ".xml";
XmlTree xmlTree;
xmlTree.load(file,Properties::getTagReplacementValues());
const XmlNode *scenarioNode= xmlTree.getRootNode();
string techName = scenarioNode->getChild("tech-tree")->getAttribute("value")->getValue();
// Self Contained techtree?
string scenarioTechtree = scenarioPath + scenarioName + "/" + techName + "/" + techName + ".xml";
if(fileExists(scenarioTechtree) == true) {
string techPath = scenarioPath + scenarioName + "/";
printf("Found Scenario [%s] with custom techtree [%s] validating...\n",scenarioName.c_str(),techName.c_str());
runTechValidationForPath(techPath, techName, filteredFactionList,
world, purgeUnusedFiles, showDuplicateFiles, false, false, purgedMegaBytes);
}
//
//
// runTechValidationForPath(techPath, techName, filteredFactionList,
// world, purgeUnusedFiles,purgedMegaBytes);
}
}
}
printf("\n====== Finished Validation ======\n");
}
return;
}
else {
printf("\nInvalid missing scenario specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
//printParameterHelp(argv[0],false);
return;
}
}
// Did the user pass a specific list of factions to validate?
std::vector<string> filteredFactionList;
if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) + string("=")) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) + string("="),&foundParamIndIndex);
string filterList = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(filterList,paramPartTokens,"=");
if(paramPartTokens.size() >= 2) {
string factionList = paramPartTokens[1];
Tokenize(factionList,filteredFactionList,",");
if(filteredFactionList.empty() == false) {
printf("Filtering factions and only looking for the following:\n");
for(int idx = 0; idx < filteredFactionList.size(); ++idx) {
filteredFactionList[idx] = trim(filteredFactionList[idx]);
printf("%s\n",filteredFactionList[idx].c_str());
}
}
if(paramPartTokens.size() >= 3) {
if(paramPartTokens[2] == "purgeunused") {
purgeUnusedFiles = true;
printf("*NOTE All unused faction files will be deleted!\n");
}
}
}
}
vector<string> results;
findDirs(config.getPathListForType(ptTechs), results);
vector<string> techTreeFiles = results;
// Did the user pass a specific list of techtrees to validate?
std::vector<string> filteredTechTreeList;
if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) + string("=")) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) + string("="),&foundParamIndIndex);
string filterList = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(filterList,paramPartTokens,"=");
if(paramPartTokens.size() >= 2) {
string techtreeList = paramPartTokens[1];
Tokenize(techtreeList,filteredTechTreeList,",");
if(filteredTechTreeList.empty() == false) {
printf("Filtering techtrees and only looking for the following:\n");
for(int idx = 0; idx < filteredTechTreeList.size(); ++idx) {
filteredTechTreeList[idx] = trim(filteredTechTreeList[idx]);
printf("%s\n",filteredTechTreeList[idx].c_str());
}
}
if(paramPartTokens.size() >= 3) {
if(paramPartTokens[2] == "purgeunused") {
purgeUnusedFiles = true;
printf("*NOTE All unused techtree files will be deleted!\n");
}
else if(paramPartTokens[2] == "purgeduplicates") {
purgeDuplicateFiles = true;
printf("*NOTE All duplicate techtree files will be merged!\n");
}
else if(paramPartTokens[2] == "svndelete") {
svnPurgeFiles = true;
printf("*NOTE All unused / duplicate techtree files will be removed from svn!\n");
}
else if(paramPartTokens[2] == "hideduplicates") {
showDuplicateFiles = false;
printf("*NOTE All duplicate techtree files will NOT be shown!\n");
}
}
if(paramPartTokens.size() >= 4) {
if(paramPartTokens[3] == "purgeunused") {
purgeUnusedFiles = true;
printf("*NOTE All unused techtree files will be deleted!\n");
}
else if(paramPartTokens[3] == "purgeduplicates") {
purgeDuplicateFiles = true;
printf("*NOTE All duplicate techtree files will be merged!\n");
}
else if(paramPartTokens[3] == "svndelete") {
svnPurgeFiles = true;
printf("*NOTE All unused / duplicate techtree files will be removed from svn!\n");
}
else if(paramPartTokens[3] == "hideduplicates") {
showDuplicateFiles = false;
printf("*NOTE All duplicate techtree files will NOT be shown!\n");
}
}
if(paramPartTokens.size() >= 5) {
if(paramPartTokens[4] == "purgeunused") {
purgeUnusedFiles = true;
printf("*NOTE All unused techtree files will be deleted!\n");
}
else if(paramPartTokens[4] == "purgeduplicates") {
purgeDuplicateFiles = true;
printf("*NOTE All duplicate techtree files will be merged!\n");
}
else if(paramPartTokens[4] == "svndelete") {
svnPurgeFiles = true;
printf("*NOTE All unused / duplicate techtree files will be removed from svn!\n");
}
else if(paramPartTokens[4] == "hideduplicates") {
showDuplicateFiles = false;
printf("*NOTE All duplicate techtree files will NOT be shown!\n");
}
}
}
}
{
printf("\n---------------- Loading factions inside world ----------------");
World world;
vector<string> techPaths = config.getPathListForType(ptTechs);
for(int idx = 0; idx < techPaths.size(); idx++) {
string &techPath = techPaths[idx];
endPathWithSlash(techPath);
//printf("techPath [%s]\n",techPath.c_str());
for(int idx2 = 0; idx2 < techTreeFiles.size(); idx2++) {
string &techName = techTreeFiles[idx2];
if( filteredTechTreeList.empty() == true ||
std::find(filteredTechTreeList.begin(),filteredTechTreeList.end(),techName) != filteredTechTreeList.end()) {
runTechValidationForPath(techPath, techName, filteredFactionList,
world, purgeUnusedFiles,purgeDuplicateFiles,
showDuplicateFiles,svnPurgeFiles,purgedMegaBytes);
}
}
}
printf("\n====== Finished Validation ======\n");
}
}
void ShowINISettings(int argc, char **argv,Config &config,Config &configKeys) {
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true) {
vector<string> filteredPropertyList;
if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) + string("=")) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) + string("="),&foundParamIndIndex);
string filterList = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(filterList,paramPartTokens,"=");
if(paramPartTokens.size() >= 2) {
string tokenList = paramPartTokens[1];
Tokenize(tokenList,filteredPropertyList,",");
if(filteredPropertyList.empty() == false) {
printf("Filtering properties and only looking for the following:\n");
for(int idx = 0; idx < filteredPropertyList.size(); ++idx) {
filteredPropertyList[idx] = trim(filteredPropertyList[idx]);
printf("%s\n",filteredPropertyList[idx].c_str());
}
}
}
}
printf("\nMain settings report\n");
printf("====================\n");
vector<pair<string,string> > mergedMainSettings = config.getMergedProperties();
vector<pair<string,string> > mergedKeySettings = configKeys.getMergedProperties();
// Figure out the max # of tabs we need to format display nicely
int tabCount = 1;
for(int i = 0; i < mergedMainSettings.size(); ++i) {
const pair<string,string> &nameValue = mergedMainSettings[i];
bool displayProperty = false;
if(filteredPropertyList.empty() == false) {
if(find(filteredPropertyList.begin(),filteredPropertyList.end(),nameValue.first) != filteredPropertyList.end()) {
displayProperty = true;
}
}
else {
displayProperty = true;
}
if(displayProperty == true) {
int requredTabs = (nameValue.first.length() / 8)+1;
if(nameValue.first.length() % 8) {
requredTabs++;
}
if(requredTabs > tabCount) {
tabCount = requredTabs;
}
}
}
for(int i = 0; i < mergedKeySettings.size(); ++i) {
const pair<string,string> &nameValue = mergedKeySettings[i];
bool displayProperty = false;
if(filteredPropertyList.empty() == false) {
if(find(filteredPropertyList.begin(),filteredPropertyList.end(),nameValue.first) != filteredPropertyList.end()) {
displayProperty = true;
}
}
else {
displayProperty = true;
}
if(displayProperty == true) {
int requredTabs = (nameValue.first.length() / 8)+1;
if(nameValue.first.length() % 8) {
requredTabs++;
}
if(requredTabs > tabCount) {
tabCount = requredTabs;
}
}
}
// Output the properties
for(int i = 0; i < mergedMainSettings.size(); ++i) {
const pair<string,string> &nameValue = mergedMainSettings[i];
bool displayProperty = false;
if(filteredPropertyList.empty() == false) {
if(find(filteredPropertyList.begin(),filteredPropertyList.end(),nameValue.first) != filteredPropertyList.end()) {
displayProperty = true;
}
}
else {
displayProperty = true;
}
if(displayProperty == true) {
printf("Property Name [%s]",nameValue.first.c_str());
int tabs = (nameValue.first.length() / 8) + 1;
for(int j = 0; j < (tabCount - tabs); ++j) {
printf("\t");
}
printf("Value [%s]\n",nameValue.second.c_str());
}
}
printf("\n\nMain key binding settings report\n");
printf("====================================\n");
for(int i = 0; i < mergedKeySettings.size(); ++i) {
const pair<string,string> &nameValue = mergedKeySettings[i];
bool displayProperty = false;
if(filteredPropertyList.empty() == false) {
if(find(filteredPropertyList.begin(),filteredPropertyList.end(),nameValue.first) != filteredPropertyList.end()) {
displayProperty = true;
}
}
else {
displayProperty = true;
}
if(displayProperty == true) {
printf("Property Name [%s]",nameValue.first.c_str());
int tabs = (nameValue.first.length() / 8) + 1;
for(int j = 0; j < (tabCount - tabs); ++j) {
printf("\t");
}
printf("Value [%s]\n",nameValue.second.c_str());
}
}
}
}
void CheckForDuplicateData() {
Config &config = Config::getInstance();
string duplicateWarnings="";
{
vector<string> results;
string scenarioDir = "";
vector<string> pathList = config.getPathListForType(ptMaps,scenarioDir);
vector<string> invalidMapList;
vector<string> maps = MapPreview::findAllValidMaps(pathList,scenarioDir,false,true,&invalidMapList);
std::sort(maps.begin(),maps.end());
if(maps.empty() == true) {
throw runtime_error("No maps were found!");
}
else if(invalidMapList.size() > 0) {
string errorMsg = "Warning invalid maps were detected (will be ignored):\n";
for(int i = 0; i < invalidMapList.size(); ++i) {
char szBuf[4096]="";
sprintf(szBuf,"map [%s]\n",invalidMapList[i].c_str());
errorMsg += szBuf;
}
duplicateWarnings += errorMsg;
}
vector<string> duplicateMapsToRename;
for(int i = 0; i < maps.size(); ++i) {
string map1 = maps[i];
for(int j = 0; j < maps.size(); ++j) {
if(i != j) {
string map2 = maps[j];
//printf("i = %d map1 [%s] j = %d map2 [%s]\n",i,map1.c_str(),j,map2.c_str());
if(map1 == map2) {
if(std::find(duplicateMapsToRename.begin(),duplicateMapsToRename.end(),map1) == duplicateMapsToRename.end()) {
duplicateMapsToRename.push_back(map1);
}
}
}
}
}
if(duplicateMapsToRename.empty() == false) {
string errorMsg = "Warning duplicate maps were detected and renamed:\n";
for(int i = 0; i < duplicateMapsToRename.size(); ++i) {
string currentPath = pathList[1];
endPathWithSlash(currentPath);
string oldFile = currentPath + duplicateMapsToRename[i];
string newFile = currentPath + duplicateMapsToRename[i];
string ext = extractExtension(newFile);
newFile = newFile.substr( 0, newFile.length()-ext.length()-1);
newFile = newFile + "_custom." + ext;
char szBuf[4096]="";
int result = rename(oldFile.c_str(),newFile.c_str());
if(result != 0) {
char *errmsg = strerror(errno);
sprintf(szBuf,"Error [%s]\nCould not rename [%s] to [%s]!",errmsg,oldFile.c_str(),newFile.c_str());
throw runtime_error(szBuf);
}
else {
sprintf(szBuf,"map [%s] in [%s]\nwas renamed to [%s]",duplicateMapsToRename[i].c_str(),oldFile.c_str(),newFile.c_str());
}
errorMsg += szBuf;
}
duplicateWarnings += errorMsg;
// Program *program = Program::getInstance();
// if(program) {
// program->getState()->setForceMouseRender(true);
// }
// ExceptionHandler::DisplayMessage(errorMsg.c_str(), false);
}
}
{
//tilesets
std::vector<std::string> tileSets;
vector<string> tilesetPaths = config.getPathListForType(ptTilesets);
findDirs(tilesetPaths, tileSets, false, true);
if (tileSets.empty()) {
throw runtime_error("No tilesets were found!");
}
vector<string> duplicateTilesetsToRename;
for(int i = 0; i < tileSets.size(); ++i) {
string tileSet1 = tileSets[i];
for(int j = 0; j < tileSets.size(); ++j) {
if(i != j) {
string tileSet2= tileSets[j];
if(tileSet1 == tileSet2) {
if(std::find(duplicateTilesetsToRename.begin(),duplicateTilesetsToRename.end(),tileSet1) == duplicateTilesetsToRename.end()) {
duplicateTilesetsToRename.push_back(tileSet1);
}
}
}
}
}
if(duplicateTilesetsToRename.empty() == false) {
string errorMsg = "Warning duplicate tilesets were detected and renamed:\n";
for(int i = 0; i < duplicateTilesetsToRename.size(); ++i) {
string currentPath = tilesetPaths[1];
endPathWithSlash(currentPath);
string oldFile = currentPath + duplicateTilesetsToRename[i];
string newFile = currentPath + duplicateTilesetsToRename[i];
newFile = newFile + "_custom";
char szBuf[4096]="";
int result = rename(oldFile.c_str(),newFile.c_str());
if(result != 0) {
char *errmsg = strerror(errno);
sprintf(szBuf,"Error [%s]\nCould not rename [%s] to [%s]!",errmsg,oldFile.c_str(),newFile.c_str());
throw runtime_error(szBuf);
}
else {
sprintf(szBuf,"tileset [%s] in [%s]\nwas renamed to [%s]",duplicateTilesetsToRename[i].c_str(),oldFile.c_str(),newFile.c_str());
string tilesetName = extractFileFromDirectoryPath(oldFile);
oldFile = newFile + "/" + tilesetName + ".xml";
newFile = newFile + "/" + tilesetName + "_custom.xml";
//printf("\n\n\n###### RENAME [%s] to [%s]\n\n",oldFile.c_str(),newFile.c_str());
rename(oldFile.c_str(),newFile.c_str());
}
errorMsg += szBuf;
}
duplicateWarnings += errorMsg;
// Program *program = Program::getInstance();
// if(program) {
// program->getState()->setForceMouseRender(true);
// }
// ExceptionHandler::DisplayMessage(errorMsg.c_str(), false);
}
}
{
vector<string> techPaths = config.getPathListForType(ptTechs);
vector<string> techTrees;
findDirs(techPaths, techTrees, false, true);
if(techTrees.empty()) {
throw runtime_error("No tech-trees were found!");
}
vector<string> duplicateTechtreesToRename;
for(int i = 0; i < techTrees.size(); ++i) {
string techtree1 = techTrees[i];
for(int j = 0; j < techTrees.size(); ++j) {
if(i != j) {
string techtree2 = techTrees[j];
if(techtree1 == techtree2) {
if(std::find(duplicateTechtreesToRename.begin(),duplicateTechtreesToRename.end(),techtree1) == duplicateTechtreesToRename.end()) {
duplicateTechtreesToRename.push_back(techtree1);
}
}
}
}
}
if(duplicateTechtreesToRename.empty() == false) {
string errorMsg = "Warning duplicate techtrees were detected and renamed:\n";
for(int i = 0; i < duplicateTechtreesToRename.size(); ++i) {
string currentPath = techPaths[1];
endPathWithSlash(currentPath);
string oldFile = currentPath + duplicateTechtreesToRename[i];
string newFile = currentPath + duplicateTechtreesToRename[i];
newFile = newFile + "_custom";
char szBuf[4096]="";
int result = rename(oldFile.c_str(),newFile.c_str());
if(result != 0) {
char *errmsg = strerror(errno);
sprintf(szBuf,"Error [%s]\nCould not rename [%s] to [%s]!",errmsg,oldFile.c_str(),newFile.c_str());
throw runtime_error(szBuf);
}
else {
sprintf(szBuf,"techtree [%s] in [%s]\nwas renamed to [%s]",duplicateTechtreesToRename[i].c_str(),oldFile.c_str(),newFile.c_str());
string tilesetName = extractFileFromDirectoryPath(oldFile);
oldFile = newFile + "/" + tilesetName + ".xml";
newFile = newFile + "/" + tilesetName + "_custom.xml";
//printf("\n\n\n###### RENAME [%s] to [%s]\n\n",oldFile.c_str(),newFile.c_str());
rename(oldFile.c_str(),newFile.c_str());
}
errorMsg += szBuf;
}
duplicateWarnings += errorMsg;
// Program *program = Program::getInstance();
// if(program) {
// program->getState()->setForceMouseRender(true);
// }
// ExceptionHandler::DisplayMessage(errorMsg.c_str(), false);
}
}
if(duplicateWarnings != "") {
Program *program = Program::getInstance();
if(program) {
program->getState()->setForceMouseRender(true);
}
ExceptionHandler::DisplayMessage(duplicateWarnings.c_str(), false);
}
}
int glestMain(int argc, char** argv) {
#ifdef SL_LEAK_DUMP
AllocRegistry memoryLeaks = AllocRegistry::getInstance();
#endif
application_binary= executable_path(argv[0],true);
mg_app_name = GameConstants::application_name;
mailStringSupport = mailString;
SystemFlags::ENABLE_THREADED_LOGGING = false;
disableBacktrace = false;
bool foundInvalidArgs = false;
preCacheThread=NULL;
Properties::setApplicationPath(executable_path(argv[0]));
Properties::setGameVersion(glestVersionString);
ServerSocket::setMaxPlayerCount(GameConstants::maxPlayers);
SystemFlags::VERBOSE_MODE_ENABLED = false;
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VERBOSE_MODE]) == true) {
SystemFlags::VERBOSE_MODE_ENABLED = true;
}
//vector<string> results;
//findAll("/home/softcoder/Code/megaglest/trunk/mk/linux//äöüß/maps/*.gbm", results, false, true);
//findAll("C:\\Documents and Settings\\SoftCoder\\Application Data\\人間五\\maps\\*", results, false, true);
//for(unsigned int i = 0; i < results.size(); ++i) {
// string file = results[i];
// printf("FILE: [%s]\n",file.c_str());
//}
//return -1;
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DISABLE_BACKTRACE]) == true) {
disableBacktrace = true;
}
// UErrorCode status = U_ZERO_ERROR;
// u_init(&status);
// if (U_SUCCESS(status)) {
// printf("everything is OK\n");
// }
// else {
// printf("error %s opening resource\n", u_errorName(status));
// }
// TEST:
//string testfile = "/home/softcoder/Code/megaglest/trunk/mk/linux/techs/megapack/factions/egypt/units/desert_camp/../../upgrades/spear_weapons/images/piercing.bmp";
//updatePathClimbingParts(testfile);
//return -1;
//CHANGED relative path from [/home/softcoder/Code/megaglest/trunk/mk/linux/techs/megapack/factions/egypt/units/desert_camp/../../upgrades/spear_weapons/images/piercing.bmp] to [/home/softcoder/Code/megaglest/trunk/mk/linux/techs/megapack/factions/egypt/units/desert_camp/upgrades/spear_weapons/images/piercing.bmp]
#if defined(CUSTOM_DATA_INSTALL_PATH)
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nCUSTOM_DATA_INSTALL_PATH = [%s]\n\n",formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)).c_str());
#endif
const int knownArgCount = sizeof(GAME_ARGS) / sizeof(GAME_ARGS[0]);
for(int idx = 1; idx < argc; ++idx) {
if( hasCommandArgument(knownArgCount, (char **)&GAME_ARGS[0], argv[idx], NULL, 0, true) == false) {
foundInvalidArgs = true;
printf("\nInvalid argument: %s",argv[idx]);
}
}
if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_HELP]) == true ||
foundInvalidArgs == true) {
printParameterHelp(argv[0],foundInvalidArgs);
return -1;
}
if( hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) {
//isMasterServerModeEnabled = true;
//Window::setMasterserverMode(isMasterServerModeEnabled);
GlobalStaticFlags::setIsNonGraphicalModeEnabled(true);
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE]),&foundParamIndIndex);
}
string paramValue = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(paramValue,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string headless_command_list = paramPartTokens[1];
vector<string> paramHeadlessCommandList;
Tokenize(headless_command_list,paramHeadlessCommandList,",");
for(unsigned int i = 0; i < paramHeadlessCommandList.size(); ++i) {
string headless_command = paramHeadlessCommandList[i];
if(headless_command == "exit") {
printf("Forcing quit after game has completed [%s]\n",headless_command.c_str());
Program::setWantShutdownApplicationAfterGame(true);
}
else if(headless_command == "vps") {
printf("Disabled reading from console [%s]\n",headless_command.c_str());
disableheadless_console = true;
}
}
}
}
//off_t fileSize = getFileSize(argv[0]);
//double fSize = ((double)fileSize / 1048576.0);
//printf("[%ld] [%.2f]\n",fileSize,fSize);
//return -1;
#ifdef WIN32
SocketManager winSockManager;
#endif
bool haveSpecialOutputCommandLineOption = false;
if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_OPENGL_INFO]) == true ||
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SDL_INFO]) == true ||
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LUA_INFO]) == true ||
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CURL_INFO]) == true ||
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_XERCES_INFO]) == true ||
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VERSION]) == true ||
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true ||
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == true ||
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == true ||
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == true) {
haveSpecialOutputCommandLineOption = true;
}
if( haveSpecialOutputCommandLineOption == false ||
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VERSION]) == true) {
printf("%s %s",extractFileFromDirectoryPath(argv[0]).c_str(),getNetworkPlatformFreeVersionString().c_str());
printf("\nCompiled using: %s on: %s",getCompilerNameString().c_str(),getCompileDateTime().c_str());
printf("\nSVN: [%s]",getSVNRevisionString().c_str());
#ifdef USE_STREFLOP
//# define STREFLOP_NO_DENORMALS
// streflop_init<streflop::Simple>();
const char *instruction_set = "[none]";
const char *denormals = "[denormals]";
#if defined(STREFLOP_SSE)
instruction_set = "[SSE]";
#elif defined(STREFLOP_X87)
instruction_set = "[X87]";
#elif defined(STREFLOP_SOFT)
instruction_set = "[SOFTFLOAT]";
#endif
#if defined(STREFLOP_NO_DENORMALS)
denormals = "[no-denormals]";
#endif
printf(" - using STREFLOP %s - %s\n",instruction_set,denormals);
#endif
}
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SDL_INFO]) == true) {
SDL_version ver;
// Prints the compile time version
SDL_VERSION(&ver);
print_SDL_version("SDL compile-time version", &ver);
// Prints the run-time version
ver = *SDL_Linked_Version();
print_SDL_version("SDL runtime version", &ver);
}
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LUA_INFO]) == true) {
printf("LUA version: %s\n", LUA_RELEASE);
}
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CURL_INFO]) == true) {
curl_version_info_data *curlVersion= curl_version_info(CURLVERSION_NOW);
printf("CURL version: %s\n", curlVersion->version);
}
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_XERCES_INFO]) == true) {
printf("XERCES version: %s\n", XERCES_FULLVERSIONDOT);
}
if( (hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VERSION]) == true ||
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SDL_INFO]) == true ||
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LUA_INFO]) == true ||
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CURL_INFO]) == true ||
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_XERCES_INFO]) == true) &&
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_OPENGL_INFO]) == false &&
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == false &&
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == false &&
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == false) {
return -1;
}
if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MOD])) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MOD]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MOD]),&foundParamIndIndex);
}
string scenarioName = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(scenarioName,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string autoloadModName = paramPartTokens[1];
if(Properties::applyTagsToValue(autoloadModName) == true) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Property key [%s] now has value [%s]\n",Config::ACTIVE_MOD_PROPERTY_NAME,autoloadModName.c_str());
}
Config::setCustomRuntimeProperty(Config::ACTIVE_MOD_PROPERTY_NAME,autoloadModName);
printf("Setting mod active [%s]\n",autoloadModName.c_str());
}
else {
printf("\nInvalid mod pathname specified on commandline [%s] mod [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
printParameterHelp(argv[0],foundInvalidArgs);
return -1;
}
}
SystemFlags::init(haveSpecialOutputCommandLineOption);
//SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled = true;
//SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled = true;
MainWindow *mainWindow= NULL;
Program *program= NULL;
ExceptionHandler exceptionHandler;
exceptionHandler.install( getCrashDumpFileName() );
int shutdownFadeSoundMilliseconds = 1000;
Chrono chronoshutdownFadeSound;
SimpleTaskThread *soundThreadManager = NULL;
try {
// Setup paths to game items (like data, logs, ini etc)
int setupResult = setupGameItemPaths(argc, argv, NULL);
if(setupResult != 0) {
return setupResult;
}
// Attempt to read ini files
Config &config = Config::getInstance();
setupGameItemPaths(argc, argv, &config);
Socket::disableNagle = config.getBool("DisableNagle","false");
if(Socket::disableNagle) {
printf("*WARNING users wants to disable the socket nagle algorithm.\n");
}
Socket::DEFAULT_SOCKET_SENDBUF_SIZE = config.getInt("DefaultSocketSendBufferSize",intToStr(Socket::DEFAULT_SOCKET_SENDBUF_SIZE).c_str());
if(Socket::DEFAULT_SOCKET_SENDBUF_SIZE >= 0) {
printf("*WARNING users wants to set default socket send buffer size to: %d\n",Socket::DEFAULT_SOCKET_SENDBUF_SIZE);
}
Socket::DEFAULT_SOCKET_RECVBUF_SIZE = config.getInt("DefaultSocketReceiveBufferSize",intToStr(Socket::DEFAULT_SOCKET_RECVBUF_SIZE).c_str());
if(Socket::DEFAULT_SOCKET_RECVBUF_SIZE >= 0) {
printf("*WARNING users wants to set default socket receive buffer size to: %d\n",Socket::DEFAULT_SOCKET_RECVBUF_SIZE);
}
shutdownFadeSoundMilliseconds = config.getInt("ShutdownFadeSoundMilliseconds",intToStr(shutdownFadeSoundMilliseconds).c_str());
string userData = config.getString("UserData_Root","");
if(userData != "") {
endPathWithSlash(userData);
if(isdir(userData.c_str()) == false) {
createDirectoryPaths(userData);
}
}
string crcCachePath = userData + "cache/";
if(isdir(crcCachePath.c_str()) == false) {
createDirectoryPaths(crcCachePath);
}
setCRCCacheFilePath(crcCachePath);
string tempDataPath = userData + "temp/";
if(isdir(tempDataPath.c_str()) == true) {
removeFolder(tempDataPath);
}
createDirectoryPaths(tempDataPath);
if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DISABLE_SOUND]) == true ||
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) {
config.setString("FactorySound","None");
if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) {
//Logger::getInstance().setMasterserverMode(true);
//Model::setMasterserverMode(true);
//Shared::Sound::Sound::setMasterserverMode(true);
}
}
bool enableATIHacks = config.getBool("EnableATIHacks","false");
if(enableATIHacks == true) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**WARNING** Enabling ATI video card hacks\n");
TextureGl::setEnableATIHacks(enableATIHacks);
}
if(config.getBool("ForceFTGLFonts","false") == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_FORCE_FTGLFONTS]) == true) {
Font::forceFTGLFonts = true;
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**WARNING** Forcing Legacy Fonts Enabled\n");
printf("**WARNING** Forcing use of FTGL Fonts\n");
}
else {
Renderer::renderText3DEnabled = config.getBool("Enable3DFontRendering",intToStr(Renderer::renderText3DEnabled).c_str());
}
if(config.getBool("EnableLegacyFonts","false") == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_ENABLE_LEGACYFONTS]) == true) {
Font::forceLegacyFonts = true;
Renderer::renderText3DEnabled = false;
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**WARNING** Forcing Legacy Fonts Enabled\n");
printf("**WARNING** Forcing Legacy Fonts Enabled\n");
}
else {
Renderer::renderText3DEnabled = config.getBool("Enable3DFontRendering",intToStr(Renderer::renderText3DEnabled).c_str());
}
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_RESOLUTION]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_RESOLUTION]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_RESOLUTION]),&foundParamIndIndex);
}
string paramValue = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(paramValue,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string settings = paramPartTokens[1];
printf("Forcing resolution [%s]\n",settings.c_str());
paramPartTokens.clear();
Tokenize(settings,paramPartTokens,"x");
if(paramPartTokens.size() >= 2) {
int newScreenWidth = strToInt(paramPartTokens[0]);
config.setInt("ScreenWidth",newScreenWidth);
int newScreenHeight = strToInt(paramPartTokens[1]);
config.setInt("ScreenHeight",newScreenHeight);
}
else {
printf("\nInvalid missing resolution settings specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
//printParameterHelp(argv[0],false);
return -1;
}
}
else {
printf("\nInvalid missing resolution setting specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
//printParameterHelp(argv[0],false);
return -1;
}
}
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_COLORBITS]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_COLORBITS]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_COLORBITS]),&foundParamIndIndex);
}
string paramValue = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(paramValue,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string settings = paramPartTokens[1];
printf("Forcing colorbits [%s]\n",settings.c_str());
int newColorBits = strToInt(settings);
config.setInt("ColorBits",newColorBits);
}
else {
printf("\nInvalid missing colorbits settings specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
//printParameterHelp(argv[0],false);
return -1;
}
}
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_DEPTHBITS]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_DEPTHBITS]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_DEPTHBITS]),&foundParamIndIndex);
}
string paramValue = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(paramValue,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string settings = paramPartTokens[1];
printf("Forcing depthbits [%s]\n",settings.c_str());
int newDepthBits = strToInt(settings);
config.setInt("DepthBits",newDepthBits);
}
else {
printf("\nInvalid missing depthbits setting specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
//printParameterHelp(argv[0],false);
return -1;
}
}
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_FULLSCREEN]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_FULLSCREEN]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_FULLSCREEN]),&foundParamIndIndex);
}
string paramValue = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(paramValue,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string settings = paramPartTokens[1];
printf("Forcing fullscreen [%s]\n",settings.c_str());
bool newFullScreenMode = strToBool(settings);
config.setBool("Windowed",!newFullScreenMode);
}
else {
printf("\nInvalid missing fullscreen setting specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
//printParameterHelp(argv[0],false);
return -1;
}
}
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SET_GAMMA]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SET_GAMMA]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SET_GAMMA]),&foundParamIndIndex);
}
string paramValue = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(paramValue,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string settings = paramPartTokens[1];
printf("Forcing gamma [%s]\n",settings.c_str());
float newGammaValue = strToFloat(settings);
config.setFloat("GammaValue",newGammaValue);
}
else {
printf("\nInvalid missing gamma setting specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
//printParameterHelp(argv[0],false);
return -1;
}
}
// Set some statics based on ini entries
SystemFlags::ENABLE_THREADED_LOGGING = config.getBool("ThreadedLogging","true");
FontGl::setDefault_fontType(config.getString("DefaultFont",FontGl::getDefault_fontType().c_str()));
UPNP_Tools::isUPNP = !config.getBool("DisableUPNP","false");
Texture::useTextureCompression = config.getBool("EnableTextureCompression","false");
// 256 for English
// 30000 for Chinese
Font::charCount = config.getInt("FONT_CHARCOUNT",intToStr(Font::charCount).c_str());
Font::fontTypeName = config.getString("FONT_TYPENAME",Font::fontTypeName.c_str());
Font::fontIsMultibyte = config.getBool("FONT_MULTIBYTE",intToStr(Font::fontIsMultibyte).c_str());
Font::fontIsRightToLeft = config.getBool("FONT_RIGHTTOLEFT",intToStr(Font::fontIsRightToLeft).c_str());
Font::baseSize = config.getInt("FONT_BASE_SIZE",intToStr(Font::baseSize).c_str());
Font::scaleFontValue = config.getFloat("FONT_SCALE_SIZE",floatToStr(Font::scaleFontValue).c_str());
Font::scaleFontValueCenterHFactor = config.getFloat("FONT_SCALE_CENTERH_FACTOR",floatToStr(Font::scaleFontValueCenterHFactor).c_str());
Font::langHeightText = config.getString("FONT_HEIGHT_TEXT",Font::langHeightText.c_str());
// Example values:
// DEFAULT_CHARSET (English) = 1
// GB2312_CHARSET (Chinese) = 134
Shared::Platform::charSet = config.getInt("FONT_CHARSET",intToStr(Shared::Platform::charSet).c_str());
if(config.getBool("No2DMouseRendering","false") == false) {
showCursor(false);
}
if(config.getInt("DEFAULT_HTTP_TIMEOUT",intToStr(SystemFlags::DEFAULT_HTTP_TIMEOUT).c_str()) >= 0) {
SystemFlags::DEFAULT_HTTP_TIMEOUT = config.getInt("DEFAULT_HTTP_TIMEOUT",intToStr(SystemFlags::DEFAULT_HTTP_TIMEOUT).c_str());
}
bool allowAltEnterFullscreenToggle = config.getBool("AllowAltEnterFullscreenToggle",boolToStr(Window::getAllowAltEnterFullscreenToggle()).c_str());
Window::setAllowAltEnterFullscreenToggle(allowAltEnterFullscreenToggle);
if(config.getBool("noTeamColors","false") == true) {
MeshCallbackTeamColor::noTeamColors = true;
}
// Setup debug logging etc
setupLogging(config, haveSpecialOutputCommandLineOption);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::charSet = %d, Font::fontIsMultibyte = %d, fontIsRightToLeft = %d\n",__FILE__,__FUNCTION__,__LINE__,Font::charCount,Font::fontTypeName.c_str(),Shared::Platform::charSet,Font::fontIsMultibyte, Font::fontIsRightToLeft);
NetworkInterface::setDisplayMessageFunction(ExceptionHandler::DisplayMessage);
MenuStateMasterserver::setDisplayMessageFunction(ExceptionHandler::DisplayMessage);
#ifdef USE_STREFLOP
SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s, STREFLOP enabled.\n",getNetworkVersionString().c_str());
#else
SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s, STREFLOP NOT enabled.\n",getNetworkVersionString().c_str());
#endif
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"START\n");
SystemFlags::OutputDebug(SystemFlags::debugPathFinder,"START\n");
// Setup hotkeys from key ini files
Config &configKeys = Config::getInstance(
std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys),
std::pair<string,string>(Config::glestkeys_ini_filename,Config::glestuserkeys_ini_filename),
std::pair<bool,bool>(true,false));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true) {
ShowINISettings(argc,argv,config,configKeys);
return -1;
}
//setVBOSupported(false);
// Explicitly disable VBO's
if(config.getBool("DisableVBO","false") == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DISABLE_VBO]) == true) {
setVBOSupported(false);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**WARNING** Disabling VBO's\n");
}
if(config.getBool("EnableVSynch","false") == true) {
Window::setTryVSynch(true);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**ENABLED OPENGL VSYNCH**\n");
}
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_PORTS]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_PORTS]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_PORTS]),&foundParamIndIndex);
}
string paramValue = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(paramValue,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string portsToUse = paramPartTokens[1];
vector<string> paramPartPortsTokens;
Tokenize(portsToUse,paramPartPortsTokens,",");
if(paramPartPortsTokens.size() >= 2 && paramPartPortsTokens[1].length() > 0) {
int internalPort = strToInt(paramPartPortsTokens[0]);
int externalPort = strToInt(paramPartPortsTokens[1]);
printf("Forcing internal port# %d, external port# %d\n",internalPort,externalPort);
config.setInt("ServerPort",internalPort);
config.setInt("MasterServerExternalPort",externalPort);
config.setInt("FTPServerPort",internalPort+1);
}
else {
printf("\nInvalid ports specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
//printParameterHelp(argv[0],false);
return -1;
}
}
else {
printf("\nInvalid missing ports specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
//printParameterHelp(argv[0],false);
return -1;
}
}
//float pingTime = Socket::getAveragePingMS("soft-haus.com");
//printf("Ping time = %f\n",pingTime);
// Load the language strings
Lang &lang= Lang::getInstance();
string language = config.getString("Lang");
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_LANGUAGE]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_LANGUAGE]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_LANGUAGE]),&foundParamIndIndex);
}
string paramValue = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(paramValue,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
language = paramPartTokens[1];
printf("Forcing language [%s]\n",language.c_str());
}
else {
printf("\nInvalid missing language specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
//printParameterHelp(argv[0],false);
return -1;
}
}
else {
#ifdef _WIN32
int localeBufferSize = GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME, NULL, 0);
wchar_t *sysLocale = new wchar_t[localeBufferSize];
GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME, sysLocale,localeBufferSize);
//String langValue(sysLocale);
//const char *lang_locale = langValue.c_str();
char langValue[1024]="";
wcstombs(langValue,sysLocale, 1023);
const char *lang_locale = &langValue[0];
#else
const char *lang_locale = setlocale(LC_ALL,"");
#endif
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Locale is: [%s]\n", lang_locale);
if(lang_locale != NULL && strlen(lang_locale) >= 2) {
if(config.getBool("AutoLocaleLanguageDetect","true") == true) {
language = lang_locale;
language = language.substr(0,2);
printf("Auto setting language [%s]\n",language.c_str());
config.setString("AutoLocaleLanguageDetect","false");
config.save();
}
}
}
Renderer &renderer= Renderer::getInstance();
lang.loadStrings(language,false, true);
if( lang.hasString("FONT_HEIGHT_TEXT")) {
Font::langHeightText = config.getString("FONT_HEIGHT_TEXT",Font::langHeightText.c_str());
}
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_FONT_BASESIZE]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_FONT_BASESIZE]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_FONT_BASESIZE]),&foundParamIndIndex);
}
string paramValue = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(paramValue,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string newfontBaseSize = paramPartTokens[1];
//printf("#1 Forcing font [%s] paramPartTokens.size() = %d, paramValue [%s]\n",newfont.c_str(),paramPartTokens.size(),paramValue.c_str());
printf("Forcing font base size[%s]\n",newfontBaseSize.c_str());
Font::baseSize = strToInt(newfontBaseSize);
}
else {
printf("\nInvalid missing font base size specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
//printParameterHelp(argv[0],false);
return -1;
}
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::charSet = %d, Font::fontIsMultibyte = %d, Font::fontIsRightToLeft = %d\n",__FILE__,__FUNCTION__,__LINE__,Font::charCount,Font::fontTypeName.c_str(),Shared::Platform::charSet,Font::fontIsMultibyte,Font::fontIsRightToLeft);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::charSet = %d, Font::fontIsMultibyte = %d, Font::fontIsRightToLeft = %d\n",Font::charCount,Font::fontTypeName.c_str(),Shared::Platform::charSet,Font::fontIsMultibyte,Font::fontIsRightToLeft);
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_FONT]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_FONT]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_FONT]),&foundParamIndIndex);
}
string paramValue = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(paramValue,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string newfont = paramPartTokens[1];
//printf("#1 Forcing font [%s] paramPartTokens.size() = %d, paramValue [%s]\n",newfont.c_str(),paramPartTokens.size(),paramValue.c_str());
Properties::applyTagsToValue(newfont);
printf("Forcing font [%s]\n",newfont.c_str());
#if defined(WIN32)
string newEnvValue = "MEGAGLEST_FONT=" + newfont;
_putenv(newEnvValue.c_str());
#else
setenv("MEGAGLEST_FONT",newfont.c_str(),1);
#endif
}
else {
printf("\nInvalid missing font specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
//printParameterHelp(argv[0],false);
return -1;
}
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]),&foundParamIndIndex);
}
string paramValue = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(paramValue,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string itemName = paramPartTokens[1];
string file = Map::getMapPath(itemName,"",false);
if(file != "") {
Checksum checksum;
checksum.addFile(file);
int32 crcValue = checksum.getSum();
printf("CRC value for map [%s] file [%s] is [%d]\n",itemName.c_str(),file.c_str(),crcValue);
}
else {
printf("Map [%s] was NOT FOUND\n",itemName.c_str());
}
return -1;
}
else {
printf("\nInvalid missing map specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
//printParameterHelp(argv[0],false);
return -1;
}
}
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]),&foundParamIndIndex);
}
string paramValue = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(paramValue,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string itemName = paramPartTokens[1];
int32 crcValue = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,""), string("/") + itemName + string("/*"), ".xml", NULL, true);
if(crcValue != 0) {
printf("CRC value for tileset [%s] is [%d]\n",itemName.c_str(),crcValue);
}
else {
printf("Tileset [%s] was NOT FOUND\n",itemName.c_str());
}
return -1;
}
else {
printf("\nInvalid missing tileset specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
//printParameterHelp(argv[0],false);
return -1;
}
}
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]),&foundParamIndIndex);
}
string paramValue = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(paramValue,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string itemName = paramPartTokens[1];
int32 crcValue = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + itemName + "/*", ".xml", NULL, true);
if(crcValue != 0) {
printf("CRC value for techtree [%s] is [%d]\n",itemName.c_str(),crcValue);
}
else {
printf("Techtree [%s] was NOT FOUND\n",itemName.c_str());
}
return -1;
}
else {
printf("\nInvalid missing techtree specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
//printParameterHelp(argv[0],false);
return -1;
}
}
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]),&foundParamIndIndex);
}
string paramValue = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(paramValue,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string itemName = paramPartTokens[1];
int32 crcValue = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptScenarios,""), "/" + itemName + "/*", ".xml", NULL, true);
if(crcValue != 0) {
printf("CRC value for scenario [%s] is [%d]\n",itemName.c_str(),crcValue);
}
else {
printf("Scenario [%s] was NOT FOUND\n",itemName.c_str());
}
return -1;
}
else {
printf("\nInvalid missing scenario specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
//printParameterHelp(argv[0],false);
return -1;
}
}
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]),&foundParamIndIndex);
}
string paramValue = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(paramValue,paramPartTokens,"=");
if(paramPartTokens.size() >= 3 && paramPartTokens[1].length() > 0) {
string itemName = paramPartTokens[1];
string itemNameFilter = paramPartTokens[2];
//printf("\n\nitemName [%s] itemNameFilter [%s]\n",itemName.c_str(),itemNameFilter.c_str());
int32 crcValue = getFolderTreeContentsCheckSumRecursively(itemName, itemNameFilter, NULL, true);
printf("CRC value for path [%s] filter [%s] is [%d]\n",itemName.c_str(),itemNameFilter.c_str(),crcValue);
return -1;
}
else {
if(paramPartTokens.size() < 2) {
printf("\nInvalid missing path and filter specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
}
if(paramPartTokens.size() < 3) {
printf("\nInvalid missing filter specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 3 ? paramPartTokens[2].c_str() : NULL));
}
//printParameterHelp(argv[0],false);
return -1;
}
}
//vector<string> techPaths;
//vector<string> techDataPaths = config.getPathListForType(ptTechs);
//findDirs(techDataPaths, techPaths);
//int32 techCRC = getFolderTreeContentsCheckSumRecursively(techDataPaths, string("/") + "megapack" + string("/*"), ".xml", NULL, true);
//return -1;
//
//removeFolder("/home/softcoder/Code/megaglest/trunk/mk/linux/mydata/tilesets/mother_board");
//return -1;
//
program= new Program();
renderer.setProgram(program);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
mainWindow= new MainWindow(program);
mainWindow->setUseDefaultCursorOnly(config.getBool("No2DMouseRendering","false"));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
GameSettings startupGameSettings;
//parse command line
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SERVER]) == true) {
program->initServer(mainWindow,false,true);
}
else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) {
program->initServer(mainWindow,false,true,true);
}
else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTOSTART_LASTGAME])) == true) {
program->initServer(mainWindow,true,false);
}
else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTOSTART_LAST_SAVED_GAME])) == true) {
program->initSavedGame(mainWindow,false);
}
else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_PREVIEW_MAP])) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_PREVIEW_MAP]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_PREVIEW_MAP]),&foundParamIndIndex);
}
string mapName = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(mapName,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string autoloadMapName = paramPartTokens[1];
GameSettings *gameSettings = &startupGameSettings;
//int factionCount= 0;
gameSettings->setMap(autoloadMapName);
gameSettings->setTileset("forest");
gameSettings->setTech("megapack");
gameSettings->setDefaultUnits(false);
gameSettings->setDefaultResources(false);
gameSettings->setDefaultVictoryConditions(true);
gameSettings->setFogOfWar(false);
gameSettings->setAllowObservers(true);
gameSettings->setPathFinderType(pfBasic);
for(int i = 0; i < GameConstants::maxPlayers; ++i) {
ControlType ct= ctClosed;
gameSettings->setNetworkPlayerStatuses(i, 0);
gameSettings->setFactionControl(i, ct);
gameSettings->setStartLocationIndex(i, i);
gameSettings->setResourceMultiplierIndex(i, 10);
gameSettings->setNetworkPlayerName(i, "Closed");
}
ControlType ct= ctHuman;
gameSettings->setNetworkPlayerStatuses(0, 0);
gameSettings->setFactionControl(0, ct);
gameSettings->setFactionTypeName(0, formatString(GameConstants::OBSERVER_SLOTNAME));
gameSettings->setTeam(0, GameConstants::maxPlayers + fpt_Observer - 1);
gameSettings->setStartLocationIndex(0, 0);
gameSettings->setNetworkPlayerName(0, GameConstants::OBSERVER_SLOTNAME);
gameSettings->setFactionCount(1);
Config &config = Config::getInstance();
gameSettings->setEnableServerControlledAI(config.getBool("ServerControlledAI","true"));
gameSettings->setNetworkFramePeriod(config.getInt("NetworkSendFrameCount","20"));
program->initServer(mainWindow,gameSettings);
}
else {
printf("\nInvalid map name specified on commandline [%s] map [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
printParameterHelp(argv[0],foundInvalidArgs);
delete mainWindow;
return -1;
}
}
else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CLIENT])) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CLIENT]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CLIENT]),&foundParamIndIndex);
}
string serverToConnectTo = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(serverToConnectTo,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string autoConnectServer = paramPartTokens[1];
program->initClient(mainWindow, autoConnectServer);
}
else {
printf("\nInvalid host specified on commandline [%s] host [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
printParameterHelp(argv[0],foundInvalidArgs);
delete mainWindow;
return -1;
}
}
else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LOADSCENARIO])) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LOADSCENARIO]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LOADSCENARIO]),&foundParamIndIndex);
}
string scenarioName = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(scenarioName,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string autoloadScenarioName = paramPartTokens[1];
program->initScenario(mainWindow, autoloadScenarioName);
}
else {
printf("\nInvalid scenario name specified on commandline [%s] scenario [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
printParameterHelp(argv[0],foundInvalidArgs);
delete mainWindow;
return -1;
}
}
else {
program->initNormal(mainWindow);
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
// Initialize Renderer
//Renderer &renderer= Renderer::getInstance();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] OpenGL Info:\n%s\n",__FILE__,__FUNCTION__,__LINE__,renderer.getGlInfo().c_str());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled == true) {
renderer.setAllowRenderUnitTitles(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled);
SystemFlags::OutputDebug(SystemFlags::debugPathFinder,"In [%s::%s Line: %d] renderer.setAllowRenderUnitTitles = %d\n",__FILE__,__FUNCTION__,__LINE__,SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled);
}
renderer.setAllowRenderUnitTitles(true);
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_OPENGL_INFO]) == true) {
//Renderer &renderer= Renderer::getInstance();
printf("%s",renderer.getGlInfo().c_str());
printf("%s",renderer.getGlMoreInfo().c_str());
delete mainWindow;
return -1;
}
if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CONVERT_MODELS]) == true) {
int foundParamIndIndex = -1;
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CONVERT_MODELS]) + string("="),&foundParamIndIndex);
if(foundParamIndIndex < 0) {
hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CONVERT_MODELS]),&foundParamIndIndex);
}
string paramValue = argv[foundParamIndIndex];
vector<string> paramPartTokens;
Tokenize(paramValue,paramPartTokens,"=");
if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
string modelFile = paramPartTokens[1];
printf("About to convert model(s) [%s]\n",modelFile.c_str());
string textureFormat = "";
if(paramPartTokens.size() >= 3 && paramPartTokens[1].length() > 0) {
textureFormat = paramPartTokens[2];
printf("About to convert using texture format [%s]\n",textureFormat.c_str());
}
bool keepsmallest = false;
if(paramPartTokens.size() >= 4 && paramPartTokens[1].length() > 0) {
keepsmallest = (paramPartTokens[3] == "keepsmallest");
printf("About to convert using keepsmallest = %d\n",keepsmallest);
}
//CoreData::getInstance().load();
showCursor(true);
mainWindow->setUseDefaultCursorOnly(true);
const Metrics &metrics= Metrics::getInstance();
renderer.clearBuffers();
renderer.clearZBuffer();
renderer.reset2d();
if(CoreData::getInstance().getMenuFontBig3D() != NULL) {
renderer.renderText3D(
"Please wait, converting models...",
CoreData::getInstance().getMenuFontBig3D(),
Vec3f(1.f, 1.f, 0.f), (metrics.getScreenW() / 2) - 400,
(metrics.getScreenH() / 2), true);
}
else {
renderer.renderText(
"Please wait, converting models...",
CoreData::getInstance().getMenuFontBig(),
Vec3f(1.f, 1.f, 0.f), (metrics.getScreenW() / 2) - 400,
(metrics.getScreenH() / 2), true);
}
renderer.swapBuffers();
std::vector<string> models;
if(isdir(modelFile.c_str()) == true) {
models = getFolderTreeContentsListRecursively(modelFile, ".g3d");
}
else {
models.push_back(modelFile);
}
sleep(0);
Window::handleEvent();
SDL_PumpEvents();
char szTextBuf[1024]="";
for(unsigned int i =0; i < models.size(); ++i) {
string &file = models[i];
bool modelLoadedOk = false;
renderer.clearBuffers();
renderer.clearZBuffer();
renderer.reset2d();
sprintf(szTextBuf,"Please wait, converting models [%d of %lu] ...",i,(long int)models.size());
if(CoreData::getInstance().getMenuFontBig3D() != NULL) {
renderer.renderText3D(
szTextBuf,
CoreData::getInstance().getMenuFontBig3D(),
Vec3f(1.f, 1.f, 0.f), (metrics.getScreenW() / 2) - 400,
(metrics.getScreenH() / 2), true);
}
else {
renderer.renderText(
szTextBuf,
CoreData::getInstance().getMenuFontBig(),
Vec3f(1.f, 1.f, 0.f), (metrics.getScreenW() / 2) - 400,
(metrics.getScreenH() / 2), true);
}
renderer.swapBuffers();
sleep(0);
Window::handleEvent();
SDL_PumpEvents();
Model *model = renderer.newModel(rsGlobal);
try {
printf("About to load model [%s] [%d of %lu]\n",file.c_str(),i,(long int)models.size());
model->load(file);
modelLoadedOk = true;
}
catch(const exception &ex) {
printf("ERROR loading model [%s] message [%s]\n",file.c_str(),ex.what());
}
if(modelLoadedOk == true) {
printf("About to save converted model [%s]\n",file.c_str());
model->save(file,textureFormat,keepsmallest);
}
Renderer::getInstance().endModel(rsGlobal, model);
}
delete mainWindow;
return -1;
}
else {
printf("\nInvalid model specified on commandline [%s] texture [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
printParameterHelp(argv[0],foundInvalidArgs);
delete mainWindow;
return -1;
}
}
if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == true ||
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == true ||
hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == true) {
runTechValidationReport(argc, argv);
delete mainWindow;
return -1;
}
gameInitialized = true;
// Setup the screenshots folder
if(userData != "") {
endPathWithSlash(userData);
}
string screenShotsPath = userData + GameConstants::folder_path_screenshots;
if(isdir(screenShotsPath.c_str()) == false) {
createDirectoryPaths(screenShotsPath);
}
// Cache Player textures - START
string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
std::map<int,Texture2D *> &crcPlayerTextureCache = CacheManager::getCachedItem< std::map<int,Texture2D *> >(GameConstants::playerTextureCacheLookupKey);
for(int index = 0; index < GameConstants::maxPlayers; ++index) {
//string playerTexture = data_path + "data/core/faction_textures/faction" + intToStr(index) + ".tga";
string playerTexture = getGameCustomCoreDataPath(data_path, "data/core/faction_textures/faction" + intToStr(index) + ".tga");
if(fileExists(playerTexture) == true) {
Texture2D *texture = Renderer::getInstance().newTexture2D(rsGlobal);
if(texture) {
texture->load(playerTexture);
}
crcPlayerTextureCache[index] = texture;
}
else {
crcPlayerTextureCache[index] = NULL;
}
}
// Cache Player textures - END
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
CheckForDuplicateData();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//throw "BLAH!";
// START Test out SIGSEGV error handling
//int *foo = (int*)-1; // make a bad pointer
//printf("%d\n", *foo); // causes segfault
// END
bool startCRCPrecacheThread = config.getBool("PreCacheCRCThread","true");
//printf("### In [%s::%s Line: %d] precache thread enabled = %d SystemFlags::VERBOSE_MODE_ENABLED = %d\n",__FILE__,__FUNCTION__,__LINE__,startCRCPrecacheThread,SystemFlags::VERBOSE_MODE_ENABLED);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] precache thread enabled = %d\n",__FILE__,__FUNCTION__,__LINE__,startCRCPrecacheThread);
if(startCRCPrecacheThread == true) {
vector<string> techDataPaths = config.getPathListForType(ptTechs);
preCacheThread = new FileCRCPreCacheThread();
preCacheThread->setUniqueID(__FILE__);
preCacheThread->setTechDataPaths(techDataPaths);
//preCacheThread->setFileCRCPreCacheThreadCallbackInterface(&preCacheThreadGame);
preCacheThread->start();
}
// test
//Shared::Platform::MessageBox(NULL,"Mark's test.","Test",0);
//throw runtime_error("test!");
//ExceptionHandler::DisplayMessage("test!", false);
//Lang &lang= Lang::getInstance();
//string test = lang.get("ExitGameServer?");
//printf("[%s]",test.c_str());
//time_t lastTextureLoadEvent = time(NULL);
// Check for commands being input from stdin
string command="";
#ifndef WIN32
pollfd cinfd[1];
#else
HANDLE h = 0;
#endif
if(disableheadless_console == false) {
#ifndef WIN32
// Theoretically this should always be 0, but one fileno call isn't going to hurt, and if
// we try to run somewhere that stdin isn't fd 0 then it will still just work
cinfd[0].fd = fileno(stdin);
cinfd[0].events = POLLIN;
#else
h = GetStdHandle(STD_INPUT_HANDLE);
//DWORD dwMode;
//GetConsoleMode(h, &dwMode);
//SetConsoleMode(h, dwMode & ~ENABLE_MOUSE_INPUT);
FlushConsoleInputBuffer(h);
#endif
}
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
printf("Headless server is now running...\n");
}
//throw runtime_error("Test!");
//main loop
while(program->isShutdownApplicationEnabled() == false && Window::handleEvent()) {
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
if(disableheadless_console == false) {
#ifndef WIN32
int pollresult = poll(cinfd, 1, 0);
int pollerror = errno;
if(pollresult)
#else
// This is problematic because input on Windows is not line-buffered so this will return
// even if getline may block. I haven't found a good way to fix it, so for the moment
// I just strongly suggest only running the server from the Python frontend, which does
// line buffer input. This does work okay as long as the user doesn't enter characters
// without pressing enter, and then try to end the server another way (say a remote
// console command), in which case we'll still be waiting for the stdin EOL and hang.
DWORD saveMode;
GetConsoleMode(h, &saveMode);
DWORD dwMode = saveMode;
dwMode &= ~ENABLE_MOUSE_INPUT;
dwMode &= ~ENABLE_WINDOW_INPUT;
SetConsoleMode(h, dwMode);
bool gotData = (WaitForSingleObject(h, 0) == WAIT_OBJECT_0);
SetConsoleMode(h, saveMode);
if(gotData == true)
#endif
{
bool skip = true;
#ifdef WIN32
DWORD nNumberOfCharsToRead = 1024;
DWORD nRead = 0;
INPUT_RECORD irInRec[1025];
PeekConsoleInput(h,&irInRec[0],nNumberOfCharsToRead,&nRead);
for(int i = 0; i < nRead; ++i) {
INPUT_RECORD &inr = irInRec[i];
//printf("inr.EventType = %d\n",inr.EventType);
if(inr.EventType == KEY_EVENT) {
if(inr.Event.KeyEvent.bKeyDown) {
char cHoldKey = inr.Event.KeyEvent.uChar.AsciiChar;
if(cHoldKey == '\r') {
skip = false;
break;
}
}
}
}
#else
skip = false;
#endif
if(skip == false) {
getline(cin, command);
cin.clear();
printf("server command [%s]\n",command.c_str());
if(command == "quit") {
break;
}
#ifndef WIN32
if (cinfd[0].revents & POLLNVAL) {
printf("invalid file descriptor\n");
}
if (cinfd[0].revents & POLLERR) {
printf("error in file descriptor\n");
}
if (cinfd[0].revents & POLLHUP) {
printf("hang up in file descriptor\n");
}
if(pollresult < 0) {
printf("pollresult = %d errno = %d [%s]\n",pollresult,pollerror,strerror(pollerror));
cinfd[0].fd = fileno(stdin);
cinfd[0].events = POLLIN;
}
#endif
}
}
}
//printf("looping\n");
}
program->loop();
// Because OpenGL really doesn't do multi-threading well
// if(difftime(time(NULL),lastTextureLoadEvent) >= 3) {
// lastTextureLoadEvent = time(NULL);
// vector<Texture2D *> textureList = preCacheThread->getPendingTextureList(1);
// for(unsigned int i = 0; i < textureList.size(); ++i) {
// Texture2D * factionLogo = textureList[i];
// if(factionLogo != NULL) {
// printf("\n\n\n\n|||||||||||||||||||||||||| Load texture [%s]\n",factionLogo->getPath().c_str());
// //Renderer::findFactionLogoTexture(factionLogo);
// renderer.initTexture(rsGlobal,factionLogo);
// }
// }
// }
}
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
printf("\nHeadless server is about to quit...\n");
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] starting normal application shutdown\n",__FILE__,__FUNCTION__,__LINE__);
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
soundThreadManager = program->getSoundThreadManager(true);
if(soundThreadManager) {
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds);
chronoshutdownFadeSound.start();
}
}
cleanupCRCThread();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
showCursor(true);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
catch(const exception &e) {
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
soundThreadManager = (program != NULL ? program->getSoundThreadManager(true) : NULL);
if(soundThreadManager) {
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds);
chronoshutdownFadeSound.start();
}
}
ExceptionHandler::handleRuntimeError(e.what());
}
catch(const char *e) {
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
soundThreadManager = (program != NULL ? program->getSoundThreadManager(true) : NULL);
if(soundThreadManager) {
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds);
chronoshutdownFadeSound.start();
}
}
ExceptionHandler::handleRuntimeError(e);
}
catch(const string &ex) {
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
soundThreadManager = (program != NULL ? program->getSoundThreadManager(true) : NULL);
if(soundThreadManager) {
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds);
chronoshutdownFadeSound.start();
}
}
ExceptionHandler::handleRuntimeError(ex.c_str());
}
catch(...) {
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
soundThreadManager = (program != NULL ? program->getSoundThreadManager(true) : NULL);
if(soundThreadManager) {
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds);
chronoshutdownFadeSound.start();
}
}
ExceptionHandler::handleRuntimeError("Unknown error!");
}
cleanupCRCThread();
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
delete mainWindow;
mainWindow = NULL;
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//showCursor(true);
//restoreVideoMode(true);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
GraphicComponent::clearRegisteredComponents();
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(soundThreadManager) {
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
if( Config::getInstance().getString("FactorySound","") != "None" &&
soundRenderer.isVolumeTurnedOff() == false) {
//printf("chronoshutdownFadeSound.getMillis() = %llu\n",chronoshutdownFadeSound.getMillis());
for(;chronoshutdownFadeSound.getMillis() <= shutdownFadeSoundMilliseconds;) {
sleep(10);
}
}
BaseThread::shutdownAndWait(soundThreadManager);
delete soundThreadManager;
soundThreadManager = NULL;
}
return 0;
}
int glestMainWrapper(int argc, char** argv) {
//setlocale(LC_ALL, "zh_TW.UTF-8");
//setlocale(LC_ALL, "");
#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD)
//#ifdef DEBUG
//printf("MTRACE will be called...\n");
//mtrace ();
//#endif
#endif
#ifdef WIN32_STACK_TRACE
__try {
#endif
//application_binary= executable_path(argv[0],true);
//printf("\n\nargv0 [%s] application_binary [%s]\n\n",argv[0],application_binary.c_str());
#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD)
if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_DISABLE_SIGSEGV_HANDLER])) == false) {
signal(SIGSEGV, handleSIGSEGV);
}
// http://developerweb.net/viewtopic.php?id=3013
//signal(SIGPIPE, SIG_IGN);
#endif
initSpecialStrings();
int result = glestMain(argc, argv);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
cleanupProcessObjects();
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(sdl_quitCalled == false) {
sdl_quitCalled = true;
SDL_Quit();
}
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()), EXCEPTION_CONTINUE_SEARCH) { return 0; }
#endif
}
}}//end namespace
MAIN_FUNCTION(Glest::Game::glestMainWrapper)