Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

Application.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004 Ivo Danihelka (ivo@danihelka.net)
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  */
00009 #include "Application.h"
00010 
00011 #include "Log.h"
00012 #include "Path.h"
00013 #include "Random.h"
00014 #include "AgentPack.h"
00015 #include "MessagerAgent.h"
00016 #include "VideoAgent.h"
00017 #include "InputAgent.h"
00018 #include "TimerAgent.h"
00019 #include "GameAgent.h"
00020 #include "SoundAgent.h"
00021 #include "SDLSoundAgent.h"
00022 #include "DummySoundAgent.h"
00023 #include "ScriptAgent.h"
00024 #include "OptionAgent.h"
00025 #include "SubTitleAgent.h"
00026 #include "ResourceException.h"
00027 #include "OptionParams.h"
00028 #include "Font.h"
00029 
00030 #include "SimpleMsg.h"
00031 #include "StringMsg.h"
00032 
00033 #include "SDL.h"
00034 
00035 //-----------------------------------------------------------------
00036 Application::Application()
00037 {
00038     m_quit = false;
00039     Random::init();
00040     Font::init();
00041 
00042     m_agents = new AgentPack();
00043     //NOTE: MessagerAgent is added by AgentPack
00044     //NOTE: creating order is not significant, names are significant,
00045     // like rc.d scripts
00046     m_agents->addAgent(new ScriptAgent());
00047     m_agents->addAgent(new OptionAgent());
00048     m_agents->addAgent(new VideoAgent());
00049 
00050     m_agents->addAgent(new InputAgent());
00051 
00052     m_agents->addAgent(new SubTitleAgent());
00053     m_agents->addAgent(new GameAgent());
00054 
00055     m_agents->addAgent(new TimerAgent());
00056 }
00057 //-----------------------------------------------------------------
00058 Application::~Application()
00059 {
00060     delete m_agents;
00061     Font::shutdown();
00062 }
00063 //-----------------------------------------------------------------
00064     void
00065 Application::init(int argc, char *argv[])
00066 {
00067     MessagerAgent::agent()->addListener(this);
00068     m_agents->init(Name::VIDEO_NAME);
00069     prepareLogLevel();
00070     prepareOptions(argc, argv);
00071     customizeGame();
00072 
00073     m_agents->init(Name::INPUT_NAME);
00074     addSoundAgent();
00075 
00076     m_agents->init();
00077 }
00078 //-----------------------------------------------------------------
00079     void
00080 Application::run()
00081 {
00082     while (!m_quit) {
00083         m_agents->update();
00084     }
00085 }
00086 //-----------------------------------------------------------------
00087     void
00088 Application::shutdown()
00089 {
00090     m_agents->shutdown();
00091 }
00092 //-----------------------------------------------------------------
00093 /**
00094  * Set loglevel according option.
00095  * Prepare to change.
00096  */
00097     void
00098 Application::prepareLogLevel()
00099 {
00100     OptionAgent *options = OptionAgent::agent();
00101     StringMsg *event = new StringMsg(this, "param_changed", "loglevel");
00102     options->addWatcher("loglevel", event);
00103     options->setDefault("loglevel", Log::getLogLevel());
00104 }
00105 //-----------------------------------------------------------------
00106     void
00107 Application::prepareOptions(int argc, char *argv[])
00108 {
00109     OptionParams params;
00110     params.addParam("loglevel", OptionParams::TYPE_NUMBER,
00111             "Loglevel uses same numbers as syslog");
00112     params.addParam("systemdir", OptionParams::TYPE_PATH,
00113             "Path to game data");
00114     params.addParam("userdir", OptionParams::TYPE_PATH,
00115             "Path to game data");
00116     params.addParam("lang", OptionParams::TYPE_STRING,
00117             "2-letter code (en, cs, fr, de)");
00118     params.addParam("speech", OptionParams::TYPE_STRING,
00119             "Lang for speech");
00120     params.addParam("subtitles", OptionParams::TYPE_BOOLEAN,
00121             "Enable subtitles");
00122     params.addParam("fullscreen", OptionParams::TYPE_BOOLEAN,
00123             "Turn fullscreen on/off");
00124     params.addParam("show_steps", OptionParams::TYPE_BOOLEAN,
00125             "Show step counter in level");
00126     params.addParam("sound", OptionParams::TYPE_BOOLEAN,
00127             "Turn sound on/off");
00128     params.addParam("volume_sound", OptionParams::TYPE_NUMBER,
00129             "Sound volume in percentage");
00130     params.addParam("volume_music", OptionParams::TYPE_NUMBER,
00131             "Music volume in percentage");
00132     params.addParam("worldmap", OptionParams::TYPE_STRING,
00133             "Path to worldmap file");
00134     OptionAgent::agent()->parseCmdOpt(argc, argv, params);
00135 }
00136 //-----------------------------------------------------------------
00137 /**
00138  * Run init script.
00139  * @throws ResourceException when data are not available
00140  */
00141     void
00142 Application::customizeGame()
00143 {
00144     Path initfile = Path::dataReadPath("script/init.lua");
00145     if (initfile.exists()) {
00146         ScriptAgent::agent()->doFile(initfile);
00147     }
00148     else {
00149         throw ResourceException(ExInfo("init file not found")
00150                 .addInfo("path", initfile.getNative())
00151                 .addInfo("systemdir",
00152                     OptionAgent::agent()->getParam("systemdir"))
00153                 .addInfo("userdir",
00154                     OptionAgent::agent()->getParam("userdir"))
00155                 .addInfo("hint",
00156                     "try command line option \"systemdir=path/to/data\""));
00157     }
00158 }
00159 //-----------------------------------------------------------------
00160 /**
00161  * Choose SDL or Dummy sound agent.
00162  * Reads 'sound' config option.
00163  */
00164     void
00165 Application::addSoundAgent()
00166 {
00167     //TODO: better setting sound on/off
00168     //TODO: move to the SoundAgent
00169     SoundAgent *soundAgent = NULL;
00170     if (OptionAgent::agent()->getAsBool("sound", true)) {
00171         soundAgent = new SDLSoundAgent();
00172         try {
00173             soundAgent->init();
00174         }
00175         catch (BaseException &e) {
00176             LOG_WARNING(e.info());
00177             delete soundAgent;
00178             soundAgent = new DummySoundAgent();
00179         }
00180     }
00181     else {
00182         soundAgent = new DummySoundAgent();
00183     }
00184     m_agents->addAgent(soundAgent);
00185 }
00186 
00187 //-----------------------------------------------------------------
00188 /**
00189  * Handle incoming message.
00190  * Messages:
00191  * - quit ... application quit
00192  * - inc_loglevel ... inc loglevel by 1 (max LEVEL_DEBUG)
00193  * - dec_loglevel ... dec loglevel by 1 (min LEVEL_ERROR)
00194  */
00195     void
00196 Application::receiveSimple(const SimpleMsg *msg)
00197 {
00198     if (msg->equalsName("quit")) {
00199         m_quit = true;
00200     }
00201     else if (msg->equalsName("inc_loglevel")) {
00202         int level = Log::getLogLevel() + 1;
00203         if (level <= Log::LEVEL_DEBUG) {
00204             OptionAgent::agent()->setParam("loglevel", level);
00205         }
00206     }
00207     else if (msg->equalsName("dec_loglevel")) {
00208         int level = Log::getLogLevel() - 1;
00209         if (level >= Log::LEVEL_ERROR) {
00210             OptionAgent::agent()->setParam("loglevel", level);
00211         }
00212     }
00213     else {
00214         LOG_WARNING(ExInfo("unknown msg")
00215                 .addInfo("msg", msg->toString()));
00216     }
00217 }
00218 //-----------------------------------------------------------------
00219 /**
00220  * Handle incoming message.
00221  * Messages:
00222  * - param_changed(loglevel) ... set loglevel
00223  */
00224     void
00225 Application::receiveString(const StringMsg *msg)
00226 {
00227     if (msg->equalsName("param_changed")) {
00228         std::string param = msg->getValue();
00229         if ("loglevel" == param) {
00230             Log::setLogLevel(OptionAgent::agent()->getAsInt("loglevel"));
00231         }
00232     }
00233     else {
00234         LOG_WARNING(ExInfo("unknown msg")
00235                 .addInfo("msg", msg->toString()));
00236     }
00237 }
00238 

Generated on Wed Jun 1 09:54:30 2005 for Fish Fillets - Next Generation by  doxygen 1.4.2