Beispiel #1
0
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);
}
Beispiel #2
0
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*******************************/
}
Beispiel #3
0
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;
}
Beispiel #4
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;
}
Beispiel #5
0
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;
}
Beispiel #6
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;
}
Beispiel #9
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;
    }
}
Beispiel #10
0
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;
}
Beispiel #11
0
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();
}