Example #1
0
//-----------------------------------------------------------------
    int
main(int argc, char *argv[])
{
    try {
        Application app;

        try {
            app.init(argc, argv);
            app.run();
        }
        catch (HelpException &e) {
            printf("%s\n", e.what());
        }
        catch (BaseException &e) {
            LOG_ERROR(e.info());
        }
        app.shutdown();
        return 0;
    }
    catch (BaseException &e) {
        LOG_ERROR(e.info());
    }
    catch (std::exception &e) {
        LOG_ERROR(ExInfo("std::exception")
                .addInfo("what", e.what()));
    }
    catch (...) {
        LOG_ERROR(ExInfo("unknown exception"));
    }

    return 1;
}
Example #2
0
/**
 * Reinit the sound subsystem.
 */
    void
SDLSoundAgent::reinit()
{
    m_music = NULL;
    m_looper = NULL;
    m_soundVolume = MIX_MAX_VOLUME;
    m_musicVolume = MIX_MAX_VOLUME;
    if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
        throw SDLException(ExInfo("SDL_InitSubSystem"));
    }
    SDL_AudioSpec spec, have;
    spec.freq =48000;
    spec.format=AUDIO_S16SYS;
    spec.channels = 2;
    spec.samples=4096;
    spec.callback = 0;
    SDL_OpenAudio(&spec, &have);

    Mix_Init(MIX_INIT_FLAC | MIX_INIT_MOD | MIX_INIT_MP3 | MIX_INIT_OGG);

    int frequency =
       OptionAgent::agent()->getAsInt("sound_frequency", 44100);
    if(Mix_OpenAudio(frequency, MIX_DEFAULT_FORMAT, 2, 1024) < 0) {
        throw MixException(ExInfo("Mix_OpenAudio"));
    }
    Mix_AllocateChannels(16);

    SoundAgent::reinit();
}
/**
 * Break long string.
 * String is trimed at ' '
 * but not at " . " (single char surrounded with spaces).
 *
 * @param buffer buffer to change
 */
void
SubTitleAgent::trimRest(std::string &buffer)
{
    int i;
    for (i = buffer.size() - 1; i >= 0; --i) {
        if (buffer[i] == ' ' &&
                !(i - 2 >= 0 && buffer[i - 2] == ' '))
        {
            break;
        }
    }

    if (i <= 0) {
        LOG_WARNING(ExInfo("unbreakable string")
                .addInfo("string", buffer));
        if (buffer.size() > 4) {
            buffer.erase(buffer.size() - 4);
        }
        else {
            buffer = "";
        }
    }
    else {
        buffer.erase(i);
    }
}
Example #4
0
/**
 * Create one way output out of room.
 * @throws LogicException when output_DIR is not known
 */
Cube *
ModelFactory::createOutputItem(const std::string &kind, const V2 &loc,
        const std::string &shape)
{
    Dir::eDir outDir = Dir::DIR_NO;
    if ("output_left" == kind) {
        outDir = Dir::DIR_LEFT;
    }
    else if ("output_right" == kind) {
        outDir = Dir::DIR_RIGHT;
    }
    else if ("output_up" == kind) {
        outDir = Dir::DIR_UP;
    }
    else if ("output_down" == kind) {
        outDir = Dir::DIR_DOWN;
    }
    else {
        throw LogicException(ExInfo("unknown border dir")
                .addInfo("kind", kind));
    }

    Cube *model = new Cube(loc,
            Cube::FIXED, Cube::NONE, false, new Shape(shape));
    model->setOutDir(outDir);
    return model;
}
//-----------------------------------------------------------------
    void
GameState::noteFg()
{
    LOG_DEBUG(ExInfo("noteFg").addInfo("name", getName()));
    m_onBg = false;
    own_noteFg();
}
Example #6
0
/**
 * Play music.
 * @param file path to music file (i.e. *.ogg)
 * @param finished send this message when music is finished.
 * If finished is NULL, play music forever.
 */
void
SDLSoundAgent::playMusic(const Path &file,
        BaseMsg *finished)
{
    // The same music is not restarted when it is not needed.
    if (m_playingPath == file.getPosixName()
            && ms_finished == NULL && finished == NULL) {
        return;
    }

    stopMusic();
    m_playingPath = file.getPosixName();

    if (finished) {
        ms_finished = finished;
        m_music = Mix_LoadMUS(file.getNative().c_str());
        if (m_music && (0 == Mix_PlayMusic(m_music, 1))) {
            Mix_HookMusicFinished(musicFinished);
        }
        else {
            LOG_WARNING(ExInfo("cannot play music")
                    .addInfo("music", file.getNative())
                    .addInfo("Mix", Mix_GetError()));
        }
    }
    else {
        m_looper = new SDLMusicLooper(file);
        m_looper->setVolume(m_musicVolume);
        m_looper->start();
    }
}
/**
 * Load a few moves.
 * @throws LoadException for bad load
 */
    void
LevelLoading::nextLoadAction()
{
    if (m_paused) {
        return;
    }

    if (m_loadedMoves.empty()) {
        m_access->room()->beginFall(false);
        m_access->room()->finishRound(false);
    }
    else {
        for (int i = 0; i < m_loadSpeed
                && !m_loadedMoves.empty(); ++i)
        {
            try {
                char symbol = m_loadedMoves[0];
                m_loadedMoves.erase(0, 1);

                m_access->room()->loadMove(symbol);
            }
            catch (LoadException &e) {
                throw LoadException(ExInfo(e.info())
                        .addInfo("remain", m_loadedMoves));
            }
        }
    }
}
Example #8
0
/**
 * Bind keystroke.
 * @param stroke keystroke
 * @param msg message to raise, will be deleted
 * @throws LogicException when keystroke is occupied
 */
void
KeyBinder::addStroke(const KeyStroke &stroke, BaseMsg *msg)
{
    std::pair<t_strokes::iterator,bool> status =
        m_strokes.insert(
                std::pair<KeyStroke,BaseMsg*>(stroke, msg));
    if (!status.second) {
        throw LogicException(ExInfo("keystroke is occupied")
                .addInfo("keystroke", stroke.toString()));
    }
    else {
        LOG_DEBUG(ExInfo("binding keystroke")
                .addInfo("keystroke", stroke.toString())
                .addInfo("msg", msg->toString()));
    }
}
Example #9
0
/**
 * Handle incoming message.
 * Messages:
 * - quit ... application quit
 * - inc_loglevel ... inc loglevel by 1 (max LEVEL_DEBUG)
 * - dec_loglevel ... dec loglevel by 1 (min LEVEL_ERROR)
 */
    void
Application::receiveSimple(const SimpleMsg *msg)
{
    if (msg->equalsName("quit")) {
        m_quit = true;
    }
    else if (msg->equalsName("inc_loglevel")) {
        int level = Log::getLogLevel() + 1;
        if (level <= Log::LEVEL_DEBUG) {
            OptionAgent::agent()->setParam("loglevel", level);
        }
    }
    else if (msg->equalsName("dec_loglevel")) {
        int level = Log::getLogLevel() - 1;
        if (level >= Log::LEVEL_ERROR) {
            OptionAgent::agent()->setParam("loglevel", level);
        }
    }
    else if (msg->equalsName("flush_stdout")) {
        fflush(stdout);
    }
    else {
        LOG_WARNING(ExInfo("unknown msg")
                .addInfo("msg", msg->toString()));
    }
}
//-----------------------------------------------------------------
    void
BaseAgent::shutdown()
{
    LOG_DEBUG(ExInfo("shutdown").addInfo("name", getName()));
    own_shutdown();
    m_initialized = false;
}
/**
 * Install own video and input handler.
 */
    void
GameState::installHandlers()
{
    LOG_DEBUG(ExInfo("installHandlers").addInfo("state", getName()));
    InputAgent::agent()->installHandler(m_handler);
    VideoAgent::agent()->acceptDrawer(m_drawer);
}
//-----------------------------------------------------------------
    void
GameState::noteBg()
{
    LOG_DEBUG(ExInfo("noteBg").addInfo("name", getName()));
    own_noteBg();
    m_onBg = true;
}
/**
 * Forward message to her destination.
 * @param msg message, will be deleted
 * @throws NameException when listener cannot be found
 */
void
MessagerAgent::forwardNewMsg(BaseMsg *msg)
{
    std::auto_ptr<BaseMsg> sure_delete(msg);

    const std::string &listenerName = msg->getListenerName();
    LOG_DEBUG(ExInfo("received new message")
            .addInfo("msg", msg->toString()));

    t_listeners::iterator it = m_listeners.find(listenerName);
    if (m_listeners.end() == it) {
        throw NameException(ExInfo("cannot find listener")
                .addInfo("name", listenerName));
    }

    msg->sendActual(it->second);
}
//-----------------------------------------------------------------
    void
BaseAgent::init()
{
    LOG_DEBUG(ExInfo("init").addInfo("name", getName()));
    //NOTE: agent can call oneself in init()
    m_initialized = true;
    own_init();
}
/**
 * Clean state after run.
 * @throws LogicException when state is not active
 */
    void
GameState::cleanState()
{
    LOG_DEBUG(ExInfo("cleanState").addInfo("name", getName()));
    if (!m_active) {
        throw LogicException(ExInfo("clean - state is not active")
                .addInfo("name", getName()));
    }
    own_cleanState();
    unHandlers();

    m_active = false;
    m_onBg = false;
    m_manager = NULL;
    removeWatchers();
    MessagerAgent::agent()->removeListener(getName());
}
Example #16
0
/**
 * Callback called when music is finished.
 * NOTE: no one exception can be passed to "C" SDL_mixer code
 */
    void
SDLSoundAgent::musicFinished()
{
    try {
        if (ms_finished) {
            ms_finished->sendClone();
        }
        else {
            LOG_WARNING(ExInfo("NULL == ms_finished"));
        }
    }
    catch (std::exception &e) {
        LOG_WARNING(ExInfo("musicFinished error")
                .addInfo("what", e.what()));
    }
    catch (...) {
        LOG_ERROR(ExInfo("musicFinished error - unknown exception"));
    }
}
/**
 * @throws LogicException when agent is not initialized.
 */
    void
BaseAgent::update()
{
    if (!m_initialized) {
        throw LogicException(ExInfo("agent is not ready")
            .addInfo("name", getName()));
    }

    own_update();
}
/**
 * Read dots postions and level descriptions.
 * @throws LogicException when cannot parse data file
 */
    void
WorldMap::initMap(const Path &mapfile)
{
    WorldBranch parser(NULL);
    m_startNode = parser.parseMap(mapfile, &m_ending, m_descPack);
    if (NULL == m_startNode) {
        throw LogicException(ExInfo("cannot create world map")
                .addInfo("file", mapfile.getNative()));
    }
}
/**
 * Reactivate state after pause.
 * @throws LogicException when state is already active
 */
    void
GameState::resumeState()
{
    if (m_active) {
        throw LogicException(ExInfo("resume - state is already active")
                .addInfo("name", getName()));
    }
    m_active = true;
    own_resumeState();
}
/**
 * @throws LogicException when state is not active
 */
    void
GameState::updateState()
{
    if (!m_active) {
        throw LogicException(ExInfo("update - state is not active")
                .addInfo("name", getName()));
    }

    own_updateState();
}
/**
 * Return new cloned surface.
 * @return new surface, free it after use
 * @throws SDLException when function fails
 */
SDL_Surface *
SurfaceTool::createClone(SDL_Surface *surface)
{
    SDL_Surface *clone = SDL_ConvertSurface(surface,
                                            surface->format, surface->flags);
    if (NULL == clone) {
        throw SDLException(ExInfo("ConvertSurface"));
    }
    return clone;
}
//-----------------------------------------------------------------
    void
GameState::initState(StateManager *manager)
{
    LOG_DEBUG(ExInfo("initState").addInfo("name", getName()));
    MessagerAgent::agent()->addListener(this);
    m_manager = manager;
    m_active = true;
    m_onBg = false;
    own_initState();
}
/**
 * Supported options are '-h', '-v'.
 * @throws HelpException when only help is need
 * @throws LogicException when used option is unknown
 */
    void
OptionAgent::parseDashOpt(const std::string &arg,
        const OptionParams &params)
{
    if ("-h" == arg || "--help" == arg) {
        throw HelpException(ExInfo(getHelpInfo(params)));
    }
    else if ("-v" == arg || "--version" == arg) {
        throw HelpException(ExInfo(getVersionInfo()));
    }
    else if ("-c" == arg || "--config" == arg) {
        throw HelpException(ExInfo(params.getConfig(m_environ)));
    }
    else {
        throw LogicException(ExInfo("unknown option")
                .addInfo("arg", arg)
                .addInfo("use",
                    getParam("program") + " --help"));
    }
}
/**
 * Handle incoming message.
 * Messages:
 * - quit ... quit state
 */
    void
GameState::receiveSimple(const SimpleMsg *msg)
{
    if (msg->equalsName("quit")) {
        quitState();
    }
    else {
        LOG_WARNING(ExInfo("unknown msg")
                .addInfo("msg", msg->toString()));
    }
}
/**
 * @throws LogicException when state is not active
 */
    void
GameState::pauseState()
{
    if (!m_active) {
        throw LogicException(ExInfo("pause - state is not active")
                .addInfo("name", getName()));
    }

    own_pauseState();
    m_active = false;
    m_onBg = false;
}
Example #26
0
//-----------------------------------------------------------------
void
KeyBinder::removeStroke(const KeyStroke &stroke)
{
    t_strokes::iterator it = m_strokes.find(stroke);
    if (m_strokes.end() != it) {
        delete it->second;
        m_strokes.erase(it);
    }
    else {
        LOG_WARNING(ExInfo("keystroke does not exist")
                .addInfo("keystroke", stroke.toString()));
    }
}
Example #27
0
/**
 * Handle incoming message.
 * Messages:
 * - param_changed(loglevel) ... set loglevel
 */
    void
Application::receiveString(const StringMsg *msg)
{
    if (msg->equalsName("param_changed")) {
        std::string param = msg->getValue();
        if ("loglevel" == param) {
            Log::setLogLevel(OptionAgent::agent()->getAsInt("loglevel"));
        }
    }
    else {
        LOG_WARNING(ExInfo("unknown msg")
                .addInfo("msg", msg->toString()));
    }
}
Example #28
0
/**
 * Define controls symbols for extra fish.
 * Format: "fish_extra-UDLR"
 * @throws LogicException when symbols are not specified
 */
ControlSym
ModelFactory::parseExtraControlSym(const std::string &kind)
{
    static const std::string PREFIX = "fish_extra-";
    if (kind.size() != PREFIX.size() + 4) {
        throw LogicException(ExInfo("you must specify control symbols")
                .addInfo("kind", kind));
    }

    char up = kind[PREFIX.size()];
    char down = kind[PREFIX.size() + 1];
    char left = kind[PREFIX.size() + 2];
    char right = kind[PREFIX.size() + 3];
    return ControlSym(up, down, left, right);
}
//-----------------------------------------------------------------
    void
WorldMap::runIntro()
{
#ifdef HAVE_SMPEG
    Path movieFile = Path::dataReadPath("images/menu/intro.mpg");
    if (movieFile.exists()) {
        pushState(new MovieState(movieFile));
        return;
    }

    LOG_WARNING(ExInfo("cannot find intro")
            .addInfo("file", movieFile.getNative()));
#endif

    pushState(new DemoMode(Path::dataReadPath("script/share/demo_intro.lua")));
}
//-----------------------------------------------------------------
    void
OptionAgent::parseParamOpt(const std::string &arg,
                const OptionParams &params)
{
    std::string name;
    std::string value;
    if (splitOpt(arg, &name, &value)) {
        params.checkValidity(name, value);
        setParam(name, value);
    }
    else {
        throw LogicException(ExInfo("unknown option")
                .addInfo("arg", arg)
                .addInfo("use",
                    getParam("program") + " --help"));
    }
}