1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

Fixed several crashes when exiting.

This commit is contained in:
Frank Zago
2009-10-26 05:39:30 +00:00
parent 95808db933
commit 7471372074
5 changed files with 53 additions and 18 deletions

View File

@@ -209,20 +209,23 @@ CConsoleHandler::CConsoleHandler()
} }
CConsoleHandler::~CConsoleHandler() CConsoleHandler::~CConsoleHandler()
{ {
tlog3 << "Killing console... ";
end();
delete cb; delete cb;
delete thread; tlog3 << "done!\n";
} }
void CConsoleHandler::end() void CConsoleHandler::end()
{ {
tlog3 << "Killing console... "; if (thread) {
ThreadHandle th = (ThreadHandle)thread->native_handle(); ThreadHandle th = (ThreadHandle)thread->native_handle();
_kill_thread(th); int ret = _kill_thread(th);
delete thread; thread->join();
thread = NULL; delete thread;
tlog3 << "done!\n"; thread = NULL;
}
} }
void CConsoleHandler::start() void CConsoleHandler::start()
{ {
thread = new boost::thread(boost::bind(&CConsoleHandler::run,console)); thread = new boost::thread(boost::bind(&CConsoleHandler::run,console));
} }

View File

@@ -65,6 +65,7 @@ CClient *client = NULL;
SDL_Surface *screen = NULL, //main screen surface SDL_Surface *screen = NULL, //main screen surface
*screen2 = NULL,//and hlp surface (used to store not-active interfaces layer) *screen2 = NULL,//and hlp surface (used to store not-active interfaces layer)
*screenBuf = screen; //points to screen (if only advmapint is present) or screen2 (else) - should be used when updating controls which are not regularly redrawed *screenBuf = screen; //points to screen (if only advmapint is present) or screen2 (else) - should be used when updating controls which are not regularly redrawed
static boost::thread *hhh;
SystemOptions GDefaultOptions; SystemOptions GDefaultOptions;
VCMIDirs GVCMIDirs; VCMIDirs GVCMIDirs;
@@ -184,13 +185,13 @@ int main(int argc, char** argv)
srand ( time(NULL) ); srand ( time(NULL) );
//CPG=NULL; //CPG=NULL;
atexit(SDL_Quit);
CGI = new CGameInfo; //contains all global informations about game (texts, lodHandlers, map handler itp.) CGI = new CGameInfo; //contains all global informations about game (texts, lodHandlers, map handler itp.)
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO)) if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO))
{ {
tlog1<<"Something was wrong: "<< SDL_GetError() << std::endl; tlog1<<"Something was wrong: "<< SDL_GetError() << std::endl;
exit(-1); exit(-1);
} }
atexit(SDL_Quit);
setScreenRes(800,600,conf.cc.bpp,conf.cc.fullscreen); setScreenRes(800,600,conf.cc.bpp,conf.cc.fullscreen);
tlog0 <<"\tInitializing screen: "<<pomtime.getDif() << std::endl; tlog0 <<"\tInitializing screen: "<<pomtime.getDif() << std::endl;
@@ -210,8 +211,10 @@ int main(int argc, char** argv)
new CGPreGame; //will set CGP pointer to itself new CGPreGame; //will set CGP pointer to itself
CGI->musich->playMusic(musicBase::mainMenu, -1); CGI->musich->playMusic(musicBase::mainMenu, -1);
boost::thread hhh(&CGPreGame::run, CGP); hhh = new boost::thread(&CGPreGame::run, CGP);
listenForEvents(); listenForEvents();
return 0;
} }
void processCommand(const std::string &message) void processCommand(const std::string &message)
@@ -379,7 +382,8 @@ void playIntro()
void dispose() void dispose()
{ {
delete logfile; delete logfile;
delete console; if (console)
delete console;
} }
static void setScreenRes(int w, int h, int bpp, bool fullscreen) static void setScreenRes(int w, int h, int bpp, bool fullscreen)
@@ -429,7 +433,7 @@ static void setScreenRes(int w, int h, int bpp, bool fullscreen)
screenBuf = bufOnScreen ? screen : screen2; screenBuf = bufOnScreen ? screen : screen2;
} }
void listenForEvents() void listenForEvents()
{ {
SDL_Event *ev = NULL; SDL_Event *ev = NULL;
while(1) //main SDL events loop while(1) //main SDL events loop
@@ -439,15 +443,26 @@ void listenForEvents()
//tlog0 << "Waiting... "; //tlog0 << "Waiting... ";
int ret = SDL_WaitEvent(ev); int ret = SDL_WaitEvent(ev);
//tlog0 << "got " << (int)ev->type; //tlog0 << "got " << (int)ev->type;
if(/*ret == 0 || */(ev->type==SDL_QUIT) || (ev->type == SDL_KEYDOWN && ev->key.keysym.sym==SDLK_F4 && (ev->key.keysym.mod & KMOD_ALT))) if(ret == 0 || (ev->type==SDL_QUIT) || (ev->type == SDL_KEYDOWN && ev->key.keysym.sym==SDLK_F4 && (ev->key.keysym.mod & KMOD_ALT)))
{ {
if(LOCPLINT) if(LOCPLINT)
LOCPLINT->pim->lock(); LOCPLINT->pim->lock();
client->close(); if (client)
client->close();
if (hhh) {
CGP->terminate = true;
hhh->join();
delete hhh;
hhh = NULL;
}
console->end(); console->end();
delete console;
console = NULL;
SDL_Delay(750); SDL_Delay(750);
SDL_Quit();
tlog0 << "Ending...\n"; tlog0 << "Ending...\n";
exit(EXIT_SUCCESS);
break;
} }
else if(LOCPLINT && ev->type == SDL_KEYDOWN && ev->key.keysym.sym==SDLK_F4) else if(LOCPLINT && ev->type == SDL_KEYDOWN && ev->key.keysym.sym==SDLK_F4)
{ {

View File

@@ -50,6 +50,13 @@ static int playerColor, playerSerial;
static std::string selectedName; //set when game is started/loaded static std::string selectedName; //set when game is started/loaded
static void do_quit()
{
SDL_Event event;
event.quit.type = SDL_QUIT;
SDL_PushEvent(&event);
}
CMenuScreen::CMenuScreen( EState which ) CMenuScreen::CMenuScreen( EState which )
{ {
OBJ_CONSTRUCTION; OBJ_CONSTRUCTION;
@@ -63,7 +70,7 @@ CMenuScreen::CMenuScreen( EState which )
buttons[1] = new AdventureMapButton("", CGI->generaltexth->zelp[4].second, bind(&CMenuScreen::moveTo, this, ref(CGP->scrs[loadGame])), 532, 132, "ZMENULG.DEF", SDLK_l); buttons[1] = new AdventureMapButton("", CGI->generaltexth->zelp[4].second, bind(&CMenuScreen::moveTo, this, ref(CGP->scrs[loadGame])), 532, 132, "ZMENULG.DEF", SDLK_l);
buttons[2] = new AdventureMapButton("", CGI->generaltexth->zelp[5].second, 0 /*cb*/, 524, 251, "ZMENUHS.DEF", SDLK_h); buttons[2] = new AdventureMapButton("", CGI->generaltexth->zelp[5].second, 0 /*cb*/, 524, 251, "ZMENUHS.DEF", SDLK_h);
buttons[3] = new AdventureMapButton("", CGI->generaltexth->zelp[6].second, 0 /*cb*/, 557, 359, "ZMENUCR.DEF", SDLK_c); buttons[3] = new AdventureMapButton("", CGI->generaltexth->zelp[6].second, 0 /*cb*/, 557, 359, "ZMENUCR.DEF", SDLK_c);
buttons[4] = new AdventureMapButton("", CGI->generaltexth->zelp[7].second, bind(std::exit, 0), 586, 468, "ZMENUQT.DEF", SDLK_ESCAPE); buttons[4] = new AdventureMapButton("", CGI->generaltexth->zelp[7].second, bind(do_quit), 586, 468, "ZMENUQT.DEF", SDLK_ESCAPE);
} }
break; break;
case newGame: case newGame:
@@ -126,7 +133,7 @@ void CGPreGame::run()
GH.pushInt(scrs[mainMenu]); GH.pushInt(scrs[mainMenu]);
while(1) while(!terminate)
{ {
CGI->curh->draw1(); CGI->curh->draw1();
SDL_Flip(screen); SDL_Flip(screen);
@@ -144,6 +151,7 @@ CGPreGame::CGPreGame()
GH.defActionsDef = 63; GH.defActionsDef = 63;
CGP = this; CGP = this;
mainbg = BitmapHandler::loadBitmap("ZPIC1005.bmp"); mainbg = BitmapHandler::loadBitmap("ZPIC1005.bmp");
terminate = false;
for(int i = 0; i < ARRAY_COUNT(scrs); i++) for(int i = 0; i < ARRAY_COUNT(scrs); i++)
scrs[i] = new CMenuScreen((EState)i); scrs[i] = new CMenuScreen((EState)i);

View File

@@ -222,6 +222,8 @@ public:
CDefHandler *bonuses; CDefHandler *bonuses;
CDefHandler *victory, *loss; CDefHandler *victory, *loss;
bool terminate;
CGPreGame(); CGPreGame();
~CGPreGame(); ~CGPreGame();
void run(); void run();

View File

@@ -2884,9 +2884,16 @@ CSystemOptionsWindow::~CSystemOptionsWindow()
delete effectsVolume; delete effectsVolume;
} }
static void do_quit()
{
SDL_Event event;
event.quit.type = SDL_QUIT;
SDL_PushEvent(&event);
}
void CSystemOptionsWindow::bquitf() void CSystemOptionsWindow::bquitf()
{ {
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[578], std::vector<SComponent*>(), boost::bind(exit, 0), 0, false); LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[578], std::vector<SComponent*>(), boost::bind(do_quit), 0, false);
} }
void CSystemOptionsWindow::breturnf() void CSystemOptionsWindow::breturnf()