瀏覽代碼

- basic loading screen, no progress bar
- startGame() call will run in separate thread if loading screen is used (looks OK so far)

Ivan Savenko 13 年之前
父節點
當前提交
62e99a1ae5
共有 5 個文件被更改,包括 65 次插入27 次删除
  1. 0 2
      client/CMT.cpp
  2. 2 1
      client/CPlayerInterface.cpp
  3. 47 23
      client/CPreGame.cpp
  4. 13 1
      client/CPreGame.h
  5. 3 0
      config/mainmenu.json

+ 0 - 2
client/CMT.cpp

@@ -861,8 +861,6 @@ static void listenForEvents()
 
 void startGame(StartInfo * options, CConnection *serv/* = NULL*/)
 {
-	GH.curInt =NULL;
-	SDL_FillRect(screen, 0, 0);
 	if(gOnlyAI)
 	{
 		for(auto it = options->playerInfos.begin(); it != options->playerInfos.end(); ++it)

+ 2 - 1
client/CPlayerInterface.cpp

@@ -2420,8 +2420,9 @@ void CPlayerInterface::artifactDisassembled(const ArtifactLocation &al)
 void CPlayerInterface::playerStartsTurn(ui8 player)
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
-	if(!GH.listInt.size())
+	if (GH.listInt.empty() || GH.listInt.front() != adventureInt)
 	{
+		GH.popInts(GH.listInt.size());
 		GH.pushInt(adventureInt);
 	}
 	if(howManyPeople == 1)

+ 47 - 23
client/CPreGame.cpp

@@ -502,8 +502,8 @@ void CGPreGame::update()
 	GH.updateTime();
 	GH.handleEvents();
 
-	if (GH.curInt == NULL) // no redraw, when a new game was created
-		return;
+	//if (GH.curInt == NULL) // no redraw, when a new game was created
+		//return;
 
 	GH.topInt()->show(screen);
 
@@ -638,7 +638,7 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMulti
 				};
 			}
 
-			start  = new CAdventureMapButton(CGI->generaltexth->zelp[103], bind(&CSelectionScreen::startGame, this), 411, 535, "SCNRBEG.DEF", SDLK_b);
+			start  = new CAdventureMapButton(CGI->generaltexth->zelp[103], bind(&CSelectionScreen::startScenario, this), 411, 535, "SCNRBEG.DEF", SDLK_b);
 
 			if(network)
 			{
@@ -659,11 +659,11 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMulti
 		break;
 	case CMenuScreen::loadGame:
 		sel->recActions = 255;
-		start  = new CAdventureMapButton(CGI->generaltexth->zelp[103], bind(&CSelectionScreen::startGame, this), 411, 535, "SCNRLOD.DEF", SDLK_l);
+		start  = new CAdventureMapButton(CGI->generaltexth->zelp[103], bind(&CSelectionScreen::startScenario, this), 411, 535, "SCNRLOD.DEF", SDLK_l);
 		break;
 	case CMenuScreen::saveGame:
 		sel->recActions = 255;
-		start  = new CAdventureMapButton("", CGI->generaltexth->zelp[103].second, bind(&CSelectionScreen::startGame, this), 411, 535, "SCNRSAV.DEF");
+		start  = new CAdventureMapButton("", CGI->generaltexth->zelp[103].second, bind(&CSelectionScreen::startScenario, this), 411, 535, "SCNRSAV.DEF");
 		break;
 	case CMenuScreen::campaignList:
 		sel->recActions = 255;
@@ -836,7 +836,7 @@ void CSelectionScreen::startCampaign()
 	}
 }
 
-void CSelectionScreen::startGame()
+void CSelectionScreen::startScenario()
 {
 	if(screenType == CMenuScreen::newGame)
 	{
@@ -880,7 +880,7 @@ void CSelectionScreen::startGame()
 
 		StartInfo * si = new StartInfo(sInfo);
 		CGP->removeFromGui();
-		::startGame(si);
+		CGP->showLoadingScreen(boost::bind(&startGame, si, (CConnection *)nullptr));
 	}
 	else
 	{
@@ -3564,11 +3564,19 @@ void CBonusSelection::startMap()
 	{
 		GH.popInts(1);
 	}
-	else
+	const CCampaignScenario & scenario = ourCampaign->camp->scenarios[ourCampaign->currentMap];
+
+	tlog1 << "Starting scenario " << int(ourCampaign->currentMap) << "\n";
+
+	if (scenario.prolog.hasPrologEpilog)
 	{
-		CGP->removeFromGui();
+		tlog1 << "Video: " << scenario.prolog.prologVideo <<"\n";
+		tlog1 << "Audio: " << scenario.prolog.prologMusic <<"\n";
+		tlog1 << "Text:  " << scenario.prolog.prologText <<"\n";
 	}
-	::startGame(si);
+	else
+		tlog1 << "Without prolog\n";
+	CGP->showLoadingScreen(boost::bind(&startGame, si, (CConnection *)nullptr));
 }
 
 void CBonusSelection::selectBonus( int id )
@@ -3583,7 +3591,6 @@ void CBonusSelection::selectBonus( int id )
 		updateStartButtonState(id);
 	}
 
-
 	const CCampaignScenario &scenario = ourCampaign->camp->scenarios[sInfo.campState->currentMap];
 	const std::vector<CScenarioTravel::STravelBonus> & bonDescs = scenario.travelOptions.bonusesToChoose;
 	if (bonDescs[id].type == CScenarioTravel::STravelBonus::HERO)
@@ -3902,9 +3909,7 @@ void StartWithCurrentSettings::apply(CSelectionScreen *selScreen)
 	vstd::clear_pointer(selScreen->serverHandlingThread); //detach us
 	saveGameName.clear();
 
-	CGP->removeFromGui();
-
-	::startGame(startingInfo.sInfo, startingInfo.serv);
+	CGP->showLoadingScreen(boost::bind(&startGame, startingInfo.sInfo, startingInfo.serv));
 	throw 666; //EVIL, EVIL, EVIL workaround to kill thread (does "goto catch" outside listening loop)
 }
 
@@ -3918,15 +3923,6 @@ CCampaignScreen::CCampaignButton::CCampaignButton(const JsonNode &config )
 	campFile = config["file"].String();
 	video = config["video"].String();
 
-//On linux we can only play *.mjpg videos from LOKI release
-#ifdef _WIN32
-	std::transform(video.begin(), video.end(), video.begin(), toupper);
-	video += ".BIK";
-#else
-	std::transform(video.begin(), video.end(), video.begin(), tolower);
-	video += ".mjpg";
-#endif
-
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 
 	status = config["open"].Bool() ? CCampaignScreen::ENABLED : CCampaignScreen::DISABLED;
@@ -4030,3 +4026,31 @@ void CCampaignScreen::showAll(SDL_Surface *to)
 		CMessage::drawBorder(1, to, pos.w+28, pos.h+30, pos.x-14, pos.y-15);
 }
 
+void CGPreGame::showLoadingScreen(boost::function<void()> loader)
+{
+	if (GH.listInt.front() == CGP) //pregame active
+		CGP->removeFromGui();
+	GH.pushInt(new CLoadingScreen(loader));
+}
+
+std::string CLoadingScreen::getBackground()
+{
+	const JsonVector & conf = (*CGP->pregameConfig)["loading"].Vector();
+
+	if (conf.empty())
+		return "loadbar";
+	return conf[ rand() % conf.size() ].String();
+}
+
+CLoadingScreen::CLoadingScreen(boost::function<void ()> loader):
+    CWindowObject(BORDERED, getBackground()),
+    loadingThread(loader)
+{}
+
+void CLoadingScreen::showAll(SDL_Surface *to)
+{
+	Rect rect(0,0,to->w, to->h);
+	SDL_FillRect(to, &rect, 0);
+
+	CWindowObject::showAll(to);
+}

+ 13 - 1
client/CPreGame.h

@@ -470,7 +470,7 @@ public:
 	void toggleTab(CIntObject *tab);
 	void changeSelection(const CMapInfo *to);
 	void startCampaign();
-	void startGame();
+	void startScenario();
 	void difficultyChange(int to);
 
 	void handleConnection();
@@ -683,6 +683,18 @@ public:
 
 	static CGPreGame * create();
 	void removeFromGui();
+	static void showLoadingScreen(boost::function<void()> loader);
+};
+
+class CLoadingScreen : public CWindowObject
+{
+	boost::thread loadingThread;
+
+	std::string getBackground();
+public:
+	CLoadingScreen(boost::function<void()> loader);
+
+	void showAll(SDL_Surface *to);
 };
 
 extern ISelectionScreenInfo *SEL;

+ 3 - 0
config/mainmenu.json

@@ -1,6 +1,9 @@
 {
 	//images used in game selection screen
 	"game-select" : ["ZPIC1000", "ZPIC1001"],
+
+	"loading" : ["ZPIC106", "LoadBar"],
+
 	//Main menu window, consists of several sub-menus aka items
 	"window":
 	{