bool PGE_OSXApplication::event(QEvent *event) { if(event->type() == QEvent::FileOpen) { QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event); if(openEvent) { if(m_connected) { QString file = openEvent->file(); std::string file_s = file.toStdString(); pLogDebug("Opened file %s (signal)", file_s.c_str()); emit openFileRequested(file); } else { QString file = openEvent->file(); std::string file_s = file.toStdString(); pLogDebug("Opened file %s (queue)", file_s.c_str()); m_openFileRequests.enqueue(file); } } else pLogWarning("Failed to process openEvent: pointer is null!"); } return QApplication::event(event); }
void CreditsScene::init() { /*****************************Load built-in stuff*******************************/ bgcolor.r = ConfigManager::setup_CreditsScreen.backgroundColor.Red(); bgcolor.g = ConfigManager::setup_CreditsScreen.backgroundColor.Green(); bgcolor.b = ConfigManager::setup_CreditsScreen.backgroundColor.Blue(); if(!ConfigManager::setup_CreditsScreen.backgroundImg.empty()) GlRenderer::loadTextureP(background, ConfigManager::setup_CreditsScreen.backgroundImg); else GlRenderer::loadTextureP(background, ":cat_splash.png"); imgs.clear(); for(size_t i = 0; i < ConfigManager::setup_CreditsScreen.AdditionalImages.size(); i++) { if(ConfigManager::setup_CreditsScreen.AdditionalImages[i].imgFile.empty()) continue; CreditsScene_misc_img img; GlRenderer::loadTextureP(img.t, ConfigManager::setup_CreditsScreen.AdditionalImages[i].imgFile); img.x = ConfigManager::setup_CreditsScreen.AdditionalImages[i].x; img.y = ConfigManager::setup_CreditsScreen.AdditionalImages[i].y; img.a.construct(ConfigManager::setup_CreditsScreen.AdditionalImages[i].animated, ConfigManager::setup_CreditsScreen.AdditionalImages[i].frames, ConfigManager::setup_CreditsScreen.updateDelay); img.frmH = (img.t.h / ConfigManager::setup_CreditsScreen.AdditionalImages[i].frames); imgs.push_back(img); } /*****************************Load built-in stuff*end***************************/ /*****************************Load LUA stuff*******************************/ // onLoad() <- Gives ability to load/init custom stuff luaEngine.setLuaScriptPath(ConfigManager::PathScript()); luaEngine.setCoreFile(":/script/maincore_credits.lua"); luaEngine.setUserFile(ConfigManager::setup_CreditsScreen.luaFile); luaEngine.setErrorReporterFunc([this](const std::string & errorMessage, const std::string &stacktrace) { pLogWarning("Lua-Error: "); pLogWarning("Error Message: %s", errorMessage.c_str()); pLogWarning("Stacktrace:\n%s", stacktrace.c_str()); // Do not show error message box in credits }); luaEngine.init(); /*****************************Load LUA stuff*******************************/ }
int TitleScene::findEpisodes(void *) { m_filefind_found_files.clear(); DirMan worlddir(m_filefind_folder); std::vector<std::string> files; std::vector<std::string> folders; worlddir.getListOfFolders(folders); for(std::string &folder : folders) { std::string path = m_filefind_folder + folder; DirMan episodedir(path); std::vector<std::string> worlds; episodedir.getListOfFiles(worlds, {".wld", ".wldx"}); for(std::string &world : worlds) files.push_back(m_filefind_folder + folder + "/" + world); } bool has_files_added = false; if(!files.empty()) { WorldData world; for(std::string &filename : files) { if(FileFormats::OpenWorldFileHeader(filename, world)) { std::string title = world.EpisodeTitle; std::pair<std::string, std::string > file; file.first = filename; file.second = (title.empty() ? Files::basename(filename) : title); m_filefind_found_files.push_back(file); has_files_added = true; } else { pLogWarning("Failed to parse world map header %s while listing available levels with error [%s] at line %d with line data [%s]", filename.c_str(), world.meta.ERROR_info.c_str(), world.meta.ERROR_linenum, world.meta.ERROR_linedata.c_str()); } } } if(!has_files_added) { std::pair<std::string, std::string > file; file.first = "noworlds"; //% "<episodes not found>" file.second = qtTrId("MSG_EPISODES_NOT_FOUND"); m_filefind_found_files.push_back(file); } m_filefind_finished = true; return 0; }
bool Render_OpenGL31::init() { LogDebug("Create OpenGL context..."); //Creating of the OpenGL Context PGE_Window::glcontext = SDL_GL_CreateContext(PGE_Window::window); if(!PGE_Window::glcontext) { pLogWarning("GL 3.1: Failed to create context! %s", SDL_GetError()); return false; } if(PGE_Window::isSdlError()) { pLogWarning("GL 3.1: Failed to init context! %s", SDL_GetError()); return false; } SDL_GL_MakeCurrent(PGE_Window::window, PGE_Window::glcontext); if(PGE_Window::isSdlError()) { pLogWarning("GL 3.1: Failed to set context as current! %s", SDL_GetError()); return false; } glViewport(0.f, 0.f, PGE_Window::Width, PGE_Window::Height); GLERRORCHECK(); //Initialize clear color glClearColor(0.f, 0.f, 0.f, 1.f); GLERRORCHECK(); glDisable(GL_DEPTH_TEST); GLERRORCHECK(); glDepthFunc(GL_NEVER); GLERRORCHECK(); //Ignore depth values (Z) to cause drawing bottom to top glEnable(GL_BLEND); GLERRORCHECK(); glEnable(GL_TEXTURE_2D); GLERRORCHECK(); return true; }
int TitleScene::findLevels(void *) { //Build list of casual levels DirMan leveldir(m_filefind_folder); std::vector<std::string> files; leveldir.getListOfFiles(files, {".lvl", ".lvlx"}); m_filefind_found_files.clear();//Clean up old stuff bool has_files_added = false; if(!files.empty()) { m_filefind_folder.push_back('/'); LevelData level; for(std::string &file : files) { if(FileFormats::OpenLevelFileHeader(m_filefind_folder + file, level)) { std::string title = level.LevelName; std::pair<std::string, std::string > filex; filex.first = m_filefind_folder + file; filex.second = (title.empty() ? file : title); m_filefind_found_files.push_back(filex); has_files_added = true; } else { pLogWarning("Failed to parse level header %s%s while listing available levels with error [%s] at line %d with line data [%s]", m_filefind_folder.c_str(), file.c_str(), level.meta.ERROR_info.c_str(), level.meta.ERROR_linenum, level.meta.ERROR_linedata.c_str()); } } } if(!has_files_added) { std::pair<std::string, std::string > file; file.first = "noworlds"; //% "<levels not found>" file.second = qtTrId("MSG_LEVELS_NOT_FOUND"); m_filefind_found_files.push_back(file); } m_filefind_finished = true; return 0; }
void RasterFont::loadFont(QString font_ini) { QFileInfo fm_ini(font_ini); if(!fm_ini.exists()) { pLogWarning("Can't load font %s: file not exist", font_ini.toStdString().c_str()); return; } QString root = fm_ini.absoluteDir().absolutePath() + "/"; QSettings font(font_ini, QSettings::IniFormat); font.setIniCodec("UTF-8"); int tables = 0; font.beginGroup("font"); tables = font.value("tables", 0).toInt(); fontName = font.value("name", fontName).toString(); ttf_borders = font.value("ttf-borders", false).toBool(); space_width = font.value("space-width", 0).toInt(); interletter_space = font.value("interletter-space", 0).toInt(); newline_offset = font.value("newline-offset", 0).toInt(); font.endGroup(); QStringList tables_list; font.beginGroup("tables"); for(int i = 1; i <= tables; i++) { QString table = font.value(QString("table%1").arg(i), "").toString(); if(!table.isEmpty()) tables_list.append(table); } font.endGroup(); for(QString &tbl : tables_list) loadFontMap(root + tbl); }
/** * @brief Receive an opened file from the Finder (Must be created at least one window!) */ static void macosReceiveOpenFile() { if(g_fileToOpen.empty()) { pLogDebug("Attempt to take Finder args..."); SDL_EventState(SDL_DROPFILE, SDL_ENABLE); SDL_Event event; while(SDL_PollEvent(&event)) { if(event.type == SDL_DROPFILE) { std::string file(event.drop.file); if(Files::fileExists(file)) { g_fileToOpen = file; pLogDebug("Got file path: [%s]", file.c_str()); } else pLogWarning("Invalid file path, sent by Mac OS X Finder event: [%s]", file.c_str()); } } SDL_EventState(SDL_DROPFILE, SDL_DISABLE); } }
int main(int argc, char *argv[]) { std::vector<std::string> args; for(int i = 0; i < argc; i++) args.emplace_back(argv[i]); #ifdef __EMSCRIPTEN__ args.emplace_back(PGE_RUN_SINGLE_LEVEL); #endif // Parse --version or --install low args if(!PGEEngineApp::parseLowArgs(args)) return 0; // RAII for loaded/initialized libraries and modules PGEEngineApp app; //Initialize Qt's subsystem AppPathManager::initAppPath(); //Load settings app.loadSettings(); //Init log writer app.loadLogger(); //Initialize translation sub-system app.loadTr(); // Parse high arguments app.parseHighArgs(args); // Initializing SDL if(app.initSDL()) { //% "Unable to init SDL!" PGE_Window::printSDLError(qtTrId("SDL_INIT_ERROR")); pLogDebug("<Application closed with failure>"); return 1; } if(g_flags.audioEnabled && app.initAudio(g_flags.audioEnabled)) { std::string msg = "Unable to load audio sub-system!\n"; msg += app.errorAudio(); msg += "\n\nContinuing without sound..."; pLogWarning(msg.c_str()); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "Audio subsystem Error", msg.c_str(), nullptr); g_flags.audioEnabled = false; } if(app.initWindow(INITIAL_WINDOW_TITLE, g_flags.rendererType)) { pLogDebug("<Application closed with failure>"); return 1; } app.loadJoysticks(); SDL_PumpEvents(); if(g_AppSettings.fullScreen) pLogDebug("Toggle fullscreen..."); #ifdef __APPLE__ macosReceiveOpenFile(); #endif PGE_Window::setFullScreen(g_AppSettings.fullScreen); GlRenderer::resetViewport(); //Init font manager app.initFontBasics(); pLogDebug("Showing window..."); SDL_ShowWindow(PGE_Window::window); pLogDebug("Clear screen..."); GlRenderer::clearScreen(); GlRenderer::flush(); GlRenderer::repaint(); SDL_PumpEvents(); /************************************************ * Check & ask for configuration pack * ************************************************/ //Process config manager screen { // Create configs folder if not exists app.createConfigsDir(); // Initialize config selection screen ConfigSelectScene GOScene; // Are any config packs exists? if(!GOScene.hasConfigPacks()) { pLogCritical("Config packs not found"); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, //% "Config packs not found" qtTrId("ERROR_NO_CONFIG_PACKS_TTL").c_str(), /*% "Can't start game, because available\n" "configuration packages are not found!" */ qtTrId("ERROR_NO_CONFIG_PACKS_TEXT").c_str(), PGE_Window::window); return 2; } std::string configPath_manager = GOScene.isPreLoaded(); if(!g_fileToOpen.empty()) { //% "Choose a game to test:" GOScene.setLabel(qtTrId("CONFIG_SELECT_TEST")); } //If application have ran a first time or target configuration is not exist if(configPath_manager.empty() && g_configPackPath.empty()) { //Ask for configuration if(GOScene.exec() == 1) g_configPackPath = GOScene.currentConfigPath; else return 2; } else if(!configPath_manager.empty() && g_configPackPath.empty()) g_configPackPath = GOScene.currentConfigPath; pLogDebug("Opening of the configuration package..."); ConfigManager::setConfigPath(g_configPackPath); pLogDebug("Initialization of basic properties..."); if(!ConfigManager::loadBasics()) { pLogDebug("<Application closed with failure>"); return 1; } app.enableConfigManager(); if(!ConfigManager::config_name.empty()) PGE_Window::setWindowTitle(ConfigManager::config_name); pLogDebug("Current scene resolution: %d x %d", PGE_Window::Width, PGE_Window::Height); pLogDebug("Config pack scene resolution: %d x %d", ConfigManager::viewport_width, ConfigManager::viewport_height); if(ConfigManager::viewport_width != static_cast<unsigned int>(PGE_Window::Width) || ConfigManager::viewport_height != static_cast<unsigned int>(PGE_Window::Height)) { PGE_Window::changeViewportResolution(ConfigManager::viewport_width, ConfigManager::viewport_height); pLogDebug("Using scene resolution: %d x %d", ConfigManager::viewport_width, ConfigManager::viewport_height); } pLogDebug("Configuration package successfully loaded!"); if(g_flags.audioEnabled) { PGE_MusPlayer::setVolume(g_AppSettings.volume_music); pLogDebug("Build SFX index cache..."); ConfigManager::buildSoundIndex(); //Load all sound effects into memory } //Init font manager app.initFontFull(); } if(!g_fileToOpen.empty()) { g_GameState.reset(); //Apply custom game parameters from command line g_flags.applyTestSettings(g_GameState); if(Files::hasSuffix(g_fileToOpen, ".lvl") || Files::hasSuffix(g_fileToOpen, ".lvlx")) { g_GameState.LevelFile = g_fileToOpen; g_GameState.isEpisode = false; g_GameState.isTestingModeL = true; g_GameState.isTestingModeW = false; g_flags.testLevel = true; g_flags.testWorld = false; goto PlayLevel; } else if(Files::hasSuffix(g_fileToOpen, ".wld") || Files::hasSuffix(g_fileToOpen, ".wldx")) { g_Episode.character = 1; g_Episode.savefile = "save1.savx"; g_Episode.worldfile = g_fileToOpen; g_GameState._episodePath = DirMan(Files::dirname(g_fileToOpen)).absolutePath() + "/"; g_GameState.saveFileName = g_Episode.savefile; g_GameState.isEpisode = true; g_GameState.WorldFile = g_fileToOpen; g_GameState.isTestingModeL = false; g_GameState.isTestingModeW = true; g_flags.testLevel = false; g_flags.testWorld = true; goto PlayWorldMap; } } if(g_AppSettings.interprocessing) { //Apply custom game parameters from command line g_flags.applyTestSettings(g_GameState); goto PlayLevel; } LoadingScreen: { LoadingScene ttl; ttl.setWaitTime(15000); ttl.init(); ttl.m_fader.setFade(10, 0.0, 0.01); int ret = ttl.exec(); if(ttl.doShutDown()) ret = -1; if(ret == -1) goto ExitFromApplication; goto MainMenu; } CreditsScreen: { CreditsScene ttl; ttl.setWaitTime(30000); ttl.init(); ttl.m_fader.setFade(10, 0.0, 0.01); int ret = ttl.exec(); if(ttl.doShutDown()) ret = -1; if(ret == -1) goto ExitFromApplication; if(g_flags.testWorld) goto ExitFromApplication; goto MainMenu; } GameOverScreen: { GameOverScene GOScene; int result = GOScene.exec(); if(result == GameOverSceneResult::CONTINUE) { if(g_GameState.isHubLevel) goto PlayLevel; else goto PlayWorldMap; } if(g_flags.testWorld) goto ExitFromApplication; goto MainMenu; } MainMenu: { g_GameState.reset(); std::shared_ptr<TitleScene> iScene(new TitleScene()); iScene->init(); iScene->m_fader.setFade(10, 0.0, 0.02); int answer = iScene->exec(); PlayLevelResult res_level = iScene->m_result_level; PlayEpisodeResult res_episode = iScene->m_result_episode; if(iScene->doShutDown()) answer = TitleScene::ANSWER_EXIT; switch(answer) { case TitleScene::ANSWER_EXIT: goto ExitFromApplication; case TitleScene::ANSWER_CREDITS: goto CreditsScreen; case TitleScene::ANSWER_LOADING: goto LoadingScreen; case TitleScene::ANSWER_GAMEOVER: goto GameOverScreen; case TitleScene::ANSWER_PLAYLEVEL: { g_jumpOnLevelEndTo = RETURN_TO_MAIN_MENU; g_GameState.isEpisode = false; g_GameState.numOfPlayers = 1; g_GameState.LevelFile = res_level.levelfile; g_GameState._episodePath.clear(); g_GameState.saveFileName.clear(); g_GameState.isTestingModeL = true; goto PlayLevel; } case TitleScene::ANSWER_PLAYEPISODE: case TitleScene::ANSWER_PLAYEPISODE_2P: { g_jumpOnLevelEndTo = RETURN_TO_WORLDMAP; g_GameState.numOfPlayers = (answer == TitleScene::ANSWER_PLAYEPISODE_2P) ? 2 : 1; PlayerState plr; plr._chsetup = FileFormats::CreateSavCharacterState(); plr.characterID = 1; plr.stateID = 1; plr._chsetup.id = 1; plr._chsetup.state = 1; g_GameState.setPlayerState(1, plr); plr.characterID = 2; plr.stateID = 1; plr._chsetup.id = 2; plr._chsetup.state = 1; g_GameState.setPlayerState(2, plr); g_GameState.isEpisode = true; g_Episode = res_episode; g_GameState._episodePath = DirMan(Files::dirname(g_Episode.worldfile)).absolutePath() + "/"; g_GameState.saveFileName = g_Episode.savefile; g_GameState.load(); goto PlayWorldMap; } default: goto PlayWorldMap; } //goto PlayLevel; } PlayWorldMap: { WldExit::ExitWorldCodes wldExitCode = WldExit::EXIT_close; std::shared_ptr<WorldScene> wScene; wScene.reset(new WorldScene()); bool sceneResult = true; if(g_Episode.worldfile.empty()) { sceneResult = false; //% "No opened files" PGE_MsgBox::warn(qtTrId("ERROR_NO_OPEN_FILES_MSG")); if(g_AppSettings.debugMode || g_flags.testWorld) goto ExitFromApplication; else goto MainMenu; } else { sceneResult = wScene->loadFile(g_Episode.worldfile); wScene->setGameState(&g_GameState); //Load game state to the world map if(!sceneResult) { //% "ERROR:\nFail to start world map\n\n%1" PGE_MsgBox::error( fmt::qformat(qtTrId("ERROR_FAIL_START_WLD"), wScene->getLastError()) ); wldExitCode = WldExit::EXIT_error; } } if(sceneResult) sceneResult = wScene->init(); if(sceneResult) wScene->m_fader.setFade(10, 0.0, 0.02); if(sceneResult) wldExitCode = (WldExit::ExitWorldCodes)wScene->exec(); if(!sceneResult) { wldExitCode = WldExit::EXIT_error; //% "World map was closed with error.\n%1" PGE_MsgBox::error( fmt::qformat(qtTrId("WLD_ERROR_LVLCLOSED"), wScene->errorString()) ); } g_GameState._recent_ExitCode_world = (int)wldExitCode; if(wScene->doShutDown()) { wScene.reset(); goto ExitFromApplication; } if(g_AppSettings.debugMode) { if(wldExitCode == WldExit::EXIT_beginLevel) { std::string msg; //% "Start level\n%1" msg += fmt::qformat(qtTrId("MSG_START_LEVEL"), g_GameState.LevelFile) + "\n\n"; //% "Type an exit code (signed integer)" msg += qtTrId("MSG_WLDTEST_EXIT_CODE"); PGE_TextInputBox text(nullptr, msg, PGE_BoxBase::msg_info_light, PGE_Point(-1, -1), ConfigManager::setup_message_box.box_padding, ConfigManager::setup_message_box.sprite); text.exec(); g_GameState._recent_ExitCode_level = LvlExit::EXIT_Neutral; if(PGEFile::IsIntS(text.inputText())) g_GameState._recent_ExitCode_level = SDL_atoi(text.inputText().c_str()); if(g_GameState.isHubLevel) goto ExitFromApplication; goto PlayWorldMap; } else goto ExitFromApplication; } switch(wldExitCode) { case WldExit::EXIT_beginLevel: goto PlayLevel; case WldExit::EXIT_close: break; case WldExit::EXIT_error: break; case WldExit::EXIT_exitNoSave: break; case WldExit::EXIT_exitWithSave: break; default: break; } if(g_flags.testWorld) goto ExitFromApplication; goto MainMenu; } PlayLevel: { bool playAgain = true; unsigned long entranceID = 0; std::shared_ptr<LevelScene> lScene(nullptr); while(playAgain) { entranceID = g_GameState.LevelTargetWarp; if(g_GameState.LevelFile_hub == g_GameState.LevelFile) { g_GameState.isHubLevel = true; entranceID = g_GameState.game_state.last_hub_warp; } int levelExitCode = 0; lScene.reset(new LevelScene()); if(g_AppSettings.interprocessing) g_GameState.isTestingModeL = true; lScene->setGameState(&g_GameState); bool sceneResult = true; if(g_GameState.LevelFile.empty()) { if(g_AppSettings.interprocessing && IntProc::isEnabled()) { sceneResult = lScene->loadFileIP(); if((!sceneResult) && (!lScene->isExiting())) { //SDL_Delay(50); levelExitCode = LvlExit::EXIT_Error; PGE_MsgBox msgBox(nullptr, fmt::format_ne("ERROR:\nFail to start level\n\n{0}", lScene->getLastError()), PGE_MsgBox::msg_error); msgBox.exec(); } } else { sceneResult = false; levelExitCode = LvlExit::EXIT_Error; //% "No opened files" PGE_MsgBox::warn(qtTrId("ERROR_NO_OPEN_FILES_MSG")); } } else { sceneResult = lScene->loadFile(g_GameState.LevelFile); if(!sceneResult) { SDL_Delay(50); PGE_MsgBox msgBox(nullptr, fmt::format_ne("ERROR:\nFail to start level\n\n" "{0}", lScene->getLastError()), PGE_MsgBox::msg_error); msgBox.exec(); } } if(sceneResult) sceneResult = lScene->setEntrance(entranceID); if(sceneResult) sceneResult = lScene->init(); if(sceneResult) { lScene->m_fader.setFade(10, 0.0, 0.02); levelExitCode = lScene->exec(); g_GameState._recent_ExitCode_level = levelExitCode; } if(!sceneResult) levelExitCode = LvlExit::EXIT_Error; switch(levelExitCode) { case LvlExit::EXIT_Warp: { if(lScene->m_warpToWorld) { g_GameState.game_state.worldPosX = lScene->toWorldXY().x(); g_GameState.game_state.worldPosY = lScene->toWorldXY().y(); g_GameState.LevelFile.clear(); entranceID = 0; g_jumpOnLevelEndTo = g_GameState.isEpisode ? RETURN_TO_WORLDMAP : RETURN_TO_MAIN_MENU; } else { g_GameState.LevelFile = lScene->toAnotherLevel(); g_GameState.LevelTargetWarp = lScene->toAnotherEntrance(); entranceID = g_GameState.LevelTargetWarp; if(g_GameState.isHubLevel) { g_GameState.isHubLevel = false; g_GameState.game_state.last_hub_warp = lScene->m_lastWarpID; } } if(g_GameState.LevelFile.empty()) playAgain = false; if(g_AppSettings.debugMode) { std::string target; if(lScene->m_warpToWorld) { target = fmt::format_ne("X={0}, Y={1}", g_GameState.game_state.worldPosX, g_GameState.game_state.worldPosY); } else target = g_GameState.LevelFile; if(!target.empty()) { //% "Warp exit\n\nExit into:\n%1\n\nEntrance point: %2" PGE_MsgBox::warn( fmt::qformat(qtTrId("LVL_EXIT_WARP_INFO"), target, entranceID) ); } playAgain = false; } } break; case LvlExit::EXIT_Closed: { g_jumpOnLevelEndTo = RETURN_TO_EXIT; playAgain = false; } break; case LvlExit::EXIT_ReplayRequest: { playAgain = true; } break; case LvlExit::EXIT_MenuExit: { g_jumpOnLevelEndTo = g_GameState.isEpisode ? RETURN_TO_WORLDMAP : RETURN_TO_MAIN_MENU; if(g_GameState.isHubLevel) g_jumpOnLevelEndTo = g_flags.testLevel ? RETURN_TO_EXIT : RETURN_TO_MAIN_MENU; playAgain = false; } break; case LvlExit::EXIT_PlayerDeath: { playAgain = g_GameState.isEpisode ? g_GameState.replay_on_fail : true; g_jumpOnLevelEndTo = g_GameState.isEpisode ? RETURN_TO_WORLDMAP : RETURN_TO_MAIN_MENU; //check the number of player lives here and decided to return worldmap or gameover if(g_GameState.isEpisode) { g_GameState.game_state.lives--; if(g_GameState.game_state.lives < 0) { playAgain = false; g_GameState.game_state.coins = 0; g_GameState.game_state.points = 0; g_GameState.game_state.lives = 3; g_jumpOnLevelEndTo = RETURN_TO_GAMEOVER_SCREEN; } } } break; case LvlExit::EXIT_Error: { g_jumpOnLevelEndTo = (g_GameState.isEpisode) ? RETURN_TO_WORLDMAP : RETURN_TO_MAIN_MENU; playAgain = false; //% "Level was closed with error.\n%1" PGE_MsgBox::error( fmt::qformat(qtTrId("LVL_ERROR_LVLCLOSED"), lScene->errorString()) ); } break; default: g_jumpOnLevelEndTo = g_GameState.isEpisode ? RETURN_TO_WORLDMAP : RETURN_TO_MAIN_MENU; playAgain = false; } if(g_flags.testLevel || g_AppSettings.debugMode) g_jumpOnLevelEndTo = RETURN_TO_EXIT; ConfigManager::unloadLevelConfigs(); lScene.reset(); } if(g_AppSettings.interprocessing) goto ExitFromApplication; switch(g_jumpOnLevelEndTo) { case RETURN_TO_WORLDMAP: goto PlayWorldMap; case RETURN_TO_MAIN_MENU: goto MainMenu; case RETURN_TO_EXIT: goto ExitFromApplication; case RETURN_TO_GAMEOVER_SCREEN: goto GameOverScreen; case RETURN_TO_CREDITS_SCREEN: goto CreditsScreen; } } ExitFromApplication: return 0; }
static void handle_signal(int signal, siginfo_t *siginfo, void * /*context*/) { #ifdef _WIN32 //Unsupported signals by Windows (void)siginfo; #endif // Find out which signal we're handling switch(signal) { #ifndef _WIN32 //Unsupported signals by Windows case SIGHUP: pLogWarning("Terminal was closed"); abortEngine(signal); case SIGQUIT: pLogWarning("<Quit command>"); abortEngine(signal); case SIGKILL: pLogFatal("<killed>"); abortEngine(signal); case SIGALRM: { pLogFatal("<alarm() time out!>"); msgBox( //% "Time out!" qtTrId("CRASH_TIMEOUT_TITLE"), //% "Engine has abourted because alarm() time out!" qtTrId("CRASH_TIMEOUT_MSG")); abortEngine(signal); } case SIGBUS: { std::string stack = getStacktrace(); if(siginfo) { switch(siginfo->si_code) { case BUS_ADRALN: pLogFatal("<Physical memory address error: wrong address alignment>\n" STACK_FORMAT, stack.c_str(), g_messageToUser); break; case BUS_ADRERR: pLogFatal("<Physical memory address error: physical address is not exists>\n" STACK_FORMAT, stack.c_str(), g_messageToUser); break; case BUS_OBJERR: pLogFatal("<Physical memory address error: object specific hardware error>\n" STACK_FORMAT, stack.c_str(), g_messageToUser); break; default: pLogFatal("<Physical memory address error>\n" STACK_FORMAT, stack.c_str(), g_messageToUser); } } else { pLogFatal("<Physical memory address error>\n" STACK_FORMAT, stack.c_str(), g_messageToUser); } msgBox( //% "Physical memory address error!" qtTrId("CRASH_BUS_TITLE"), //% "Engine has crashed because a physical memory address error" qtTrId("CRASH_BUS_MSG")); abortEngine(signal); } case SIGURG: case SIGUSR1: case SIGUSR2: break; case SIGILL: { std::string stack = getStacktrace(); pLogFatal("<Wrong CPU Instruction>\n" STACK_FORMAT, stack.c_str(), g_messageToUser); msgBox( //% "Wrong CPU Instruction!" qtTrId("CRASH_ILL_TITLE"), //% "Engine has crashed because a wrong CPU instruction" qtTrId("CRASH_ILL_MSG")); abortEngine(signal); } #endif case SIGFPE: { std::string stack = getStacktrace(); #ifndef _WIN32 //Unsupported signals by Windows if(siginfo) { switch(siginfo->si_code) { case FPE_INTDIV: pLogFatal("<wrong arithmetical operation: division of integer number by zero>\n" STACK_FORMAT, stack.c_str(), g_messageToUser); break; case FPE_FLTDIV: pLogFatal("<wrong arithmetical operation: division of floating point number by zero>\n" STACK_FORMAT, stack.c_str(), g_messageToUser); break; case FPE_INTOVF: pLogFatal("<wrong arithmetical operation: integer number max bits size overflot>\n" STACK_FORMAT, stack.c_str(), g_messageToUser); break; case FPE_FLTOVF: pLogFatal("<wrong arithmetical operation: floating point number max bits size overflot>\n" STACK_FORMAT, stack.c_str(), g_messageToUser); break; default: pLogFatal("<wrong arithmetical operation>\n" STACK_FORMAT, stack.c_str(), g_messageToUser); } } else #endif { pLogFatal("<wrong arithmetical operation>\n" STACK_FORMAT, stack.c_str(), g_messageToUser); } msgBox( //% "Wrong arithmetical operation" qtTrId("CRASH_FPE_TITLE"), //% "Engine has crashed because of a wrong arithmetical operation!" qtTrId("CRASH_FPE_MSG")); abortEngine(signal); } case SIGABRT: { std::string stack = getStacktrace(); pLogFatal("<Aborted!>\n" STACK_FORMAT, stack.c_str(), g_messageToUser); msgBox( //% "Aborted" qtTrId("CRASH_ABORT_TITLE"), //% "Engine has been aborted because critical error was occouped." qtTrId("CRASH_ABORT_TITLE.")); abortEngine(signal); } case SIGSEGV: { D_pLogDebug("\n===========================================================\n" "Attempt to take a backtrace..." "(if log ends before \"DONE\" will be shown, seems also trouble in the backtracing function too...)"); std::string stack = getStacktrace(); #ifndef _WIN32 //Unsupported signals by Windows if(siginfo) { switch(siginfo->si_code) { case SEGV_MAPERR: pLogFatal("<Segmentation fault crash!: Address is not pointing to object!!!>\n" STACK_FORMAT, stack.c_str(), g_messageToUser); break; case SEGV_ACCERR: pLogFatal("<Segmentation fault crash!: Wrong access rights for address!!!>\n" STACK_FORMAT, stack.c_str(), g_messageToUser); break; default: pLogFatal("<Segmentation fault crash!>\n" STACK_FORMAT, stack.c_str(), g_messageToUser); break; } } else #endif { pLogFatal("<Segmentation fault crash!>\n" STACK_FORMAT, stack.c_str(), g_messageToUser); } msgBox( //% "Segmentation fault" qtTrId("CRASH_SIGSEGV_TITLE"), /*% "Engine has crashed because of a Segmentation fault.\n" "Run debugging with a built in debug mode application\n" "and retry your recent actions to get more detailed information." */ qtTrId("CRASH_SIGSEGV_MSG.")); abortEngine(signal); } case SIGINT: { pLogFatal("<Interrupted!>"); msgBox( //% "Interrupt" qtTrId("CRASH_INT_TITLE"), //% "Engine has been interrupted" qtTrId("CRASH_INT_MSG")); abortEngine(signal); } default: return; } }
void RasterFont::loadFontMap(QString fontmap_ini) { QFileInfo fm_ini(fontmap_ini); QString root = fm_ini.absoluteDir().absolutePath() + "/"; if(!fm_ini.exists()) { pLogWarning("Can't load font map %s: file not exist", fontmap_ini.toStdString().c_str()); return; } QSettings font(fontmap_ini, QSettings::IniFormat); font.setIniCodec("UTF-8"); QString texFile; int w = letter_width, h = letter_height; font.beginGroup("font-map"); texFile = font.value("texture", "").toString(); w = font.value("width", 0).toInt(); h = font.value("height", 0).toInt(); matrix_width = w; matrix_height = h; if((w <= 0) || (h <= 0)) { pLogWarning("Wrong width and height values! %d x %d", w, h); return; } if(!QFileInfo(root + texFile).exists()) { pLogWarning("Failed to load font texture! file not exists: %s", (root + texFile).toStdString().c_str()); return; } PGE_Texture fontTexture; GlRenderer::loadTextureP(fontTexture, root + texFile); if(!fontTexture.inited) pLogWarning("Failed to load font texture! Invalid image!"); textures.push_back(fontTexture); PGE_Texture *loadedTexture = &textures.last(); if((letter_width == 0) || (letter_height == 0)) { letter_width = fontTexture.w / w; letter_height = fontTexture.h / h; if(space_width == 0) space_width = letter_width; if(newline_offset == 0) newline_offset = letter_height; } font.endGroup(); font.beginGroup("entries"); QStringList entries = font.allKeys(); //qDebug()<<entries; for(QString &x : entries) { bool okX = false; bool okY = false; x = x.trimmed(); QString charPosX = "0", charPosY = "0"; QStringList tmp = x.split('-'); if(tmp.isEmpty()) continue; charPosX = tmp[0]; charPosX.toInt(&okX); if(!okX) { pLogDebug("=invalid-X=%d=", x.toStdString().c_str()); continue; } if(matrix_width > 1) { if(tmp.size() < 2) continue; charPosY = tmp[1]; charPosY.toInt(&okY); if(!okY) { pLogDebug("=invalid-Y=%d=", x.toStdString().c_str()); continue; } } QString charX = font.value(x, "").toString(); /*Format of entry: X23 * X - UTF-8 Symbol * 2 - padding left [for non-mono fonts] * 3 - padding right [for non-mono fonts] */ if(charX.isEmpty()) continue; QChar ch = charX[0]; //qDebug()<<"=char=" << ch << "=id="<<charPosX.toInt()<<charPosY.toInt()<<"="; RasChar rch; rch.valid = true; rch.tx = loadedTexture; rch.l = charPosY.toFloat(&okY) / matrix_width; rch.r = (charPosY.toFloat(&okY) + 1.0f) / matrix_width; rch.padding_left = (charX.size() > 1) ? char2int(charX[1]) : 0; rch.padding_right = (charX.size() > 2) ? char2int(charX[2]) : 0; rch.t = charPosX.toFloat(&okX) / matrix_height; rch.b = (charPosX.toFloat(&okX) + 1.0f) / matrix_height; fontMap[ch] = rch; } font.endGroup(); if(!fontMap.isEmpty()) isReady = true; }
void ConfigManager::buildSoundIndex() { int need_to_reserve = 0; int total_channels = 32; bool newBuild = main_sfx_index.empty(); #ifdef DEBUG_BUILD ElapsedTimer loadingTime; loadingTime.start(); #endif if(newBuild) { //build array table main_sfx_index.resize(static_cast<size_t>(main_sound.size()) - 1); for(unsigned long i = 1; i < main_sound.size(); i++) { obj_sound_index sound; if(main_sound.contains(i)) { obj_sound &snd = main_sound[i]; #if defined(__unix__) || defined(__APPLE__) || defined(_WIN32) FileMapper fileMap; if(fileMap.open_file(snd.absPath.c_str())) { sound.chunk = Mix_LoadWAV_RW(SDL_RWFromMem(fileMap.data(), static_cast<int>(fileMap.size())), 1); fileMap.close_file(); } #else sound.chunk = Mix_LoadWAV(snd.absPath.toUtf8().data()); #endif sound.path = snd.absPath; if(!sound.chunk) pLogWarning("Fail to load sound-%d: %s", i, Mix_GetError()); else need_to_reserve += (snd.channel >= 0 ? 1 : 0); sound.channel = snd.channel; } main_sfx_index[static_cast<size_t>(i) - 1] = sound; } } else { for(unsigned long i = 1; (i < main_sound.size()) && (i <= static_cast<unsigned long>(main_sfx_index.size())); i++) { if(main_sound.contains(i)) { obj_sound_index &sound = main_sfx_index[static_cast<size_t>(i) - 1]; obj_sound &snd = main_sound[i]; sound.setPath(snd.absPath); if(sound.need_reload) { #if defined(__unix__) || defined(__APPLE__) || defined(_WIN32) FileMapper fileMap; if(fileMap.open_file(snd.absPath.c_str())) { sound.chunk = Mix_LoadWAV_RW(SDL_RWFromMem(fileMap.data(), static_cast<int>(fileMap.size())), static_cast<int>(fileMap.size())); fileMap.close_file(); } #else sound.chunk = Mix_LoadWAV(snd.absPath.toUtf8().data()); #endif } if(!sound.chunk) pLogWarning("Fail to load sound-%d: %s", i, Mix_GetError()); else need_to_reserve += (snd.channel >= 0 ? 1 : 0); sound.channel = snd.channel; } } } if(need_to_reserve > 0) { total_channels = (total_channels + need_to_reserve + 32); total_channels = Mix_AllocateChannels(total_channels); } //Final channel definition (use reserved channels at end of channels set) //int set_channel = (total_channels-1); //for(int i=0; i < main_sfx_index.size(); i++) //{ // obj_sound_index &sound = main_sfx_index[i]; // if(sound.channel>=0) // { // sound.channel = set_channel--; // } //} if(need_to_reserve == total_channels) need_to_reserve = 0; //else // need_to_reserve=set_channel; #ifndef DEBUG_BUILD Mix_ReserveChannels(need_to_reserve) #endif #define RESERVE_CHANS_COMMAND Mix_ReserveChannels(need_to_reserve) D_pLogDebug("Loading of sounds passed in %d milliseconds", static_cast<int>(loadingTime.elapsed())); D_pLogDebug("Reserved audio channels: %d", RESERVE_CHANS_COMMAND); D_pLogDebug("SFX Index entries: %d", main_sfx_index.size()); #undef RESERVE_CHANS_COMMAND SDL_ClearError(); }