1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

remove separate GUI thread

+ this fixes OGL
- has some issues(f.e. hero movement)
This commit is contained in:
AlexVinS 2014-06-01 19:31:37 +04:00
parent 0bf7d2b84c
commit 41a0319985
5 changed files with 138 additions and 128 deletions

View File

@ -74,14 +74,13 @@ int preferredDriverIndex = -1;
SDL_Window * mainWindow = nullptr;
SDL_Renderer * mainRenderer = nullptr;
SDL_Texture * screenTexture = nullptr;
#endif // VCMI_SDL1
SDL_Surface *screen = nullptr, //main screen surface
*screen2 = nullptr,//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
static boost::thread *mainGUIThread;
std::queue<SDL_Event> events;
boost::mutex eventsM;
@ -95,7 +94,7 @@ void processCommand(const std::string &message);
static void setScreenRes(int w, int h, int bpp, bool fullscreen, bool resetVideo=true);
void dispose();
void playIntro();
static void listenForEvents();
static void mainLoop();
//void requestChangingResolution();
void startGame(StartInfo * options, CConnection *serv = nullptr);
void endGame();
@ -458,8 +457,7 @@ int main(int argc, char** argv)
if(!gNoGUI)
{
mainGUIThread = new boost::thread(&CGuiHandler::run, &GH);
listenForEvents();
mainLoop();
}
else
{
@ -822,7 +820,7 @@ static bool checkVideoMode(int monitorIndex, int w, int h, int& bpp, bool fullsc
#ifndef VCMI_SDL1
static bool recreateWindow(int w, int h, int bpp, bool fullscreen)
{
// VCMI will only work with 2, 3 or 4 bytes per pixel
// VCMI will only work with 2 or 4 bytes per pixel
vstd::amax(bpp, 16);
vstd::amin(bpp, 32);
if(bpp>16)
@ -905,6 +903,8 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen)
logGlobal->infoStream() << "Created renderer " << info.name;
SDL_RenderSetLogicalSize(mainRenderer, w, h);
SDL_RenderSetViewport(mainRenderer, nullptr);
@ -1082,83 +1082,97 @@ static void fullScreenChanged()
GH.totalRedraw();
}
static void listenForEvents()
static void handleEvent(SDL_Event & ev)
{
if((ev.type==SDL_QUIT) ||(ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4 && (ev.key.keysym.mod & KMOD_ALT)))
{
handleQuit();
return;
}
#ifdef VCMI_SDL1
//FIXME: this should work even in pregame
else if(LOCPLINT && ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4)
#else
else if(ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4)
#endif // VCMI_SDL1
{
Settings full = settings.write["video"]["fullscreen"];
full->Bool() = !full->Bool();
return;
}
else if(ev.type == SDL_USEREVENT)
{
switch(ev.user.code)
{
case RETURN_TO_MAIN_MENU:
{
endGame();
GH.curInt = CGPreGame::create();;
GH.defActionsDef = 63;
}
break;
case STOP_CLIENT:
client->endGame(false);
break;
case RESTART_GAME:
{
StartInfo si = *client->getStartInfo(true);
endGame();
startGame(&si);
}
break;
case PREPARE_RESTART_CAMPAIGN:
{
auto si = reinterpret_cast<StartInfo *>(ev.user.data1);
endGame();
startGame(si);
}
break;
case RETURN_TO_MENU_LOAD:
endGame();
CGPreGame::create();
GH.defActionsDef = 63;
CGP->update();
CGP->menu->switchToTab(vstd::find_pos(CGP->menu->menuNameToEntry, "load"));
GH.curInt = CGP;
break;
case FULLSCREEN_TOGGLED:
fullScreenChanged();
break;
default:
logGlobal->errorStream() << "Error: unknown user event. Code " << ev.user.code;
break;
}
return;
}
{
boost::unique_lock<boost::mutex> lock(eventsM);
events.push(ev);
}
}
static void mainLoop()
{
SettingsListener resChanged = settings.listen["video"]["fullscreen"];
resChanged([](const JsonNode &newState){ CGuiHandler::pushSDLEvent(SDL_USEREVENT, FULLSCREEN_TOGGLED); });
GH.mainFPSmng->init();
while(1) //main SDL events loop
{
SDL_Event ev;
int ret = SDL_WaitEvent(&ev);
if (ret == 0 || (ev.type==SDL_QUIT) ||
(ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4 && (ev.key.keysym.mod & KMOD_ALT)))
while(1 == SDL_PollEvent(&ev))
{
handleQuit();
continue;
handleEvent(ev);
}
#ifdef VCMI_SDL1
//FIXME: this should work even in pregame
else if(LOCPLINT && ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4)
#else
else if(ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4)
#endif // VCMI_SDL1
{
Settings full = settings.write["video"]["fullscreen"];
full->Bool() = !full->Bool();
continue;
}
else if(ev.type == SDL_USEREVENT)
{
switch(ev.user.code)
{
case RETURN_TO_MAIN_MENU:
{
endGame();
GH.curInt = CGPreGame::create();;
GH.defActionsDef = 63;
}
break;
case STOP_CLIENT:
client->endGame(false);
break;
case RESTART_GAME:
{
StartInfo si = *client->getStartInfo(true);
endGame();
startGame(&si);
}
break;
case PREPARE_RESTART_CAMPAIGN:
{
auto si = reinterpret_cast<StartInfo *>(ev.user.data1);
endGame();
startGame(si);
}
break;
case RETURN_TO_MENU_LOAD:
endGame();
CGPreGame::create();
GH.defActionsDef = 63;
CGP->update();
CGP->menu->switchToTab(vstd::find_pos(CGP->menu->menuNameToEntry, "load"));
GH.curInt = CGP;
break;
case FULLSCREEN_TOGGLED:
fullScreenChanged();
break;
default:
logGlobal->errorStream() << "Error: unknown user event. Code " << ev.user.code;
assert(0);
}
GH.renderFrame();
continue;
}
{
boost::unique_lock<boost::mutex> lock(eventsM);
events.push(ev);
}
}
}
@ -1208,15 +1222,16 @@ void handleQuit()
{
auto quitApplication = []()
{
if(client) client->endGame();
if(client)
endGame();
if(mainGUIThread)
{
GH.terminate = true;
if(mainGUIThread->get_id() != boost::this_thread::get_id()) mainGUIThread->join();
delete mainGUIThread;
mainGUIThread = nullptr;
}
// if(mainGUIThread)
// {
// GH.terminate = true;
// if(mainGUIThread->get_id() != boost::this_thread::get_id()) mainGUIThread->join();
// delete mainGUIThread;
// mainGUIThread = nullptr;
// }
delete console;
console = nullptr;
boost::this_thread::sleep(boost::posix_time::milliseconds(750));

View File

@ -410,43 +410,25 @@ void CGuiHandler::fakeMouseMove()
handleMouseMotion(&evnt);
}
void CGuiHandler::run()
void CGuiHandler::renderFrame()
{
setThreadName("CGuiHandler::run");
inGuiThread.reset(new bool(true));
try
{
if(settings["video"]["fullscreen"].Bool())
CCS->curh->centerCursor();
mainFPSmng->init(); // resets internal clock, needed for FPS manager
while(!terminate)
{
{
//boost::unique_lock<boost::recursive_mutex> lock(*CPlayerInterface::pim);
if(curInt)
curInt->update(); // calls a update and drawing process of the loaded game interface object at the moment
if(!terminate)
{
if(curInt)
curInt->update(); // calls a update and drawing process of the loaded game interface object at the moment
#ifndef VCMI_SDL1
if(0 != SDL_RenderCopy(mainRenderer, screenTexture, nullptr, nullptr))
logGlobal->errorStream() << __FUNCTION__ << " SDL_RenderCopy " << SDL_GetError();
SDL_SetRenderDrawColor(mainRenderer, 0, 0, 0, 0);
SDL_RenderClear(mainRenderer);
SDL_RenderCopy(mainRenderer, screenTexture, NULL, NULL);
SDL_RenderPresent(mainRenderer);
SDL_RenderPresent(mainRenderer);
#endif
}
mainFPSmng->framerateDelay(); // holds a constant FPS
}
}
catch(const std::exception & e)
{
logGlobal->errorStream() << "Error: " << e.what();
exit(EXIT_FAILURE);
}
mainFPSmng->framerateDelay(); // holds a constant FPS
}
}
CGuiHandler::CGuiHandler()
:lastClick(-500, -500)
{

View File

@ -80,7 +80,8 @@ public:
CGuiHandler();
~CGuiHandler();
void run(); // holds the main loop for the whole program after initialization and manages the update/rendering system
void renderFrame();
void totalRedraw(); //forces total redraw (using showAll), sets a flag, method gets called at the end of the rendering
void simpleRedraw(); //update only top interface and draw background from buffer, sets a flag, method gets called at the end of the rendering

View File

@ -14,6 +14,21 @@ const SDL_Color Colors::WHITE = { 255, 243, 222, 0 };
const SDL_Color Colors::METALLIC_GOLD = { 173, 142, 66, 0 };
const SDL_Color Colors::GREEN = { 0, 255, 0, 0 };
#if (SDL_MAJOR_VERSION == 2)
void SDL_UpdateRect(SDL_Surface *surface, int x, int y, int w, int h)
{
Rect rect(x,y,w,h);
if(0 !=SDL_UpdateTexture(screenTexture, &rect, surface->pixels, surface->pitch))
logGlobal->errorStream() << __FUNCTION__ << "SDL_UpdateTexture " << SDL_GetError();
SDL_RenderClear(mainRenderer);
if(0 != SDL_RenderCopy(mainRenderer, screenTexture, NULL, NULL))
logGlobal->errorStream() << __FUNCTION__ << "SDL_RenderCopy " << SDL_GetError();
SDL_RenderPresent(mainRenderer);
}
#endif // VCMI_SDL1
SDL_Surface * CSDL_Ext::newSurface(int w, int h, SDL_Surface * mod) //creates new surface, with flags/format same as in surface given
{
SDL_Surface * ret = SDL_CreateRGBSurface(mod->flags,w,h,mod->format->BitsPerPixel,mod->format->Rmask,mod->format->Gmask,mod->format->Bmask,mod->format->Amask);
@ -490,12 +505,19 @@ Uint32 CSDL_Ext::colorToUint32(const SDL_Color * color)
void CSDL_Ext::update(SDL_Surface * what)
{
// #ifdef VCMI_SDL1
// if(what)
SDL_UpdateRect(what, 0, 0, what->w, what->h);
// #else
// SDL_UpdateTexture(screenTexture, NULL, what->pixels, what->pitch);
// #endif
#ifdef VCMI_SDL1
if(what)
SDL_UpdateRect(what, 0, 0, what->w, what->h);
#else
Rect rect(0,0,what->w,what->h);
if(!what)
return;
if(0 !=SDL_UpdateTexture(screenTexture, &rect, what->pixels, what->pitch))
logGlobal->errorStream() << __FUNCTION__ << "SDL_UpdateTexture " << SDL_GetError();
#endif // VCMI_SDL1
}
void CSDL_Ext::drawBorder(SDL_Surface * sur, int x, int y, int w, int h, const int3 &color)
{

View File

@ -52,17 +52,7 @@ inline void SDL_WarpMouse(int x, int y)
SDL_WarpMouseInWindow(mainWindow,x,y);
}
inline void SDL_UpdateRect(SDL_Surface *surface, int x, int y, int w, int h)
{
Rect rect(x,y,w,h);
SDL_UpdateTexture(screenTexture, &rect, surface->pixels, surface->pitch);
SDL_RenderClear(mainRenderer);
SDL_RenderCopy(mainRenderer, screenTexture, NULL, NULL);
SDL_RenderPresent(mainRenderer);
}
void SDL_UpdateRect(SDL_Surface *surface, int x, int y, int w, int h);
#endif
inline bool isCtrlKeyDown()