bool LogFatal(const char *szMessage) { if (!szMessage) szMessage = "(null)"; // add to fatal error message stack - if not already in there (avoid duplication) if (!SSearch(sFatalError.getData(), szMessage)) { if (!sFatalError.isNull()) sFatalError.AppendChar('|'); sFatalError.Append(szMessage); } // write to log - note that Log might overwrite a static buffer also used in szMessage return !!Log(FormatString(LoadResStr("IDS_ERR_FATAL"), szMessage).getData()); }
bool C4Startup::DoStartup() { assert(!fInStartup); assert(Game.pGUI); // now in startup! fInStartup = true; fLastDlgWasBack = false; // first run: Splash video #ifndef USE_CONSOLE if (!fFirstRun) { fFirstRun = true; if (!Config.Startup.NoSplash && !Application.NoSplash) { Game.VideoPlayer.PlayVideo(C4CFN_Splash); } } #endif // make sure loader is drawn after splash Game.GraphicsSystem.EnableLoaderDrawing(); // Play some music! if (Config.Sound.FEMusic) Application.MusicSystem.Play(); // clear any previous if (pLastDlg) { delete pLastDlg; pLastDlg = NULL; } if (pCurrDlg) { delete pCurrDlg; pCurrDlg = NULL; } // start with the last dlg that was shown - at first startup main dialog if (!SwitchDialog(eLastDlgID)) return false; // show error dlg if restart if (Game.fQuitWithError || GetFatalError()) { Game.fQuitWithError = false; // preferred: Show fatal error const char *szErr = GetFatalError(); if (szErr) { Game.pGUI->ShowMessage(szErr, LoadResStr("IDS_DLG_LOG"), C4GUI::Ico_Error); } else { // fallback to showing complete log StdStrBuf sLastLog; if (GetLogSection(Game.StartupLogPos, Game.QuitLogPos - Game.StartupLogPos, sLastLog)) if (!sLastLog.isNull()) Game.pGUI->ShowRemoveDlg(new C4GUI::InfoDialog(LoadResStr("IDS_DLG_LOG"), 10, sLastLog)); } ResetFatalError(); } // while state startup: keep looping while(fInStartup && Game.pGUI && !pCurrDlg->IsAborted()) if (Application.HandleMessage() == HR_Failure) return false; // check whether startup was aborted; first checking Game.pGUI // (because an external call to Game.Clear() would invalidate dialogs) if (!Game.pGUI) return false; if (pLastDlg) { delete pLastDlg; pLastDlg = NULL; } if (pCurrDlg) { // deinit last shown dlg if (pCurrDlg->IsAborted()) { // force abort flag if dlg abort done by user fAborted = true; } else if (pCurrDlg->IsShown()) { pCurrDlg->Close(true); } delete pCurrDlg; pCurrDlg = NULL; } // now no more in startup! fInStartup = false; // after startup: cleanup if (Game.pGUI) Game.pGUI->CloseAllDialogs(true); // reinit keyboard to reflect any config changes that might have been done // this is a good time to do it, because no GUI dialogs are opened if (Game.pGUI) if (!Game.InitKeyboard()) LogFatal(LoadResStr("IDS_ERR_NOKEYBOARD")); // all okay; return whether startup finished with a game start selection return !fAborted; }