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

VideoAgent.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 "VideoAgent.h"
00010 
00011 #include "Log.h"
00012 #include "Path.h"
00013 #include "ImgException.h"
00014 #include "SDLException.h"
00015 #include "LogicException.h"
00016 #include "AgentPack.h"
00017 #include "SimpleMsg.h"
00018 #include "StringMsg.h"
00019 #include "UnknownMsgException.h"
00020 #include "OptionAgent.h"
00021 #include "SysVideo.h"
00022 
00023 #include "SDL_image.h"
00024 #include <stdlib.h> // atexit()
00025 
00026 //-----------------------------------------------------------------
00027 /**
00028  * Init SDL and grafic window.
00029  * Register watcher for "fullscren" and "screen_*" options.
00030  * @throws SDLException if there is no usuable video mode
00031  */
00032     void
00033 VideoAgent::own_init()
00034 {
00035     m_screen = NULL;
00036     m_fullscreen = false;
00037     if (SDL_Init(SDL_INIT_VIDEO) < 0) {
00038         throw SDLException(ExInfo("Init"));
00039     }
00040     atexit(SDL_Quit);
00041 
00042     setIcon(Path::dataReadPath("images/icon.png"));
00043 
00044     registerWatcher("fullscreen");
00045     initVideoMode();
00046 }
00047 //-----------------------------------------------------------------
00048 /**
00049  * Draw all drawer from list.
00050  * First will be drawed first.
00051  */
00052     void
00053 VideoAgent::own_update()
00054 {
00055     drawOn(m_screen);
00056     SDL_Flip(m_screen);
00057 }
00058 //-----------------------------------------------------------------
00059 /**
00060  * Shutdown SDL.
00061  */
00062     void
00063 VideoAgent::own_shutdown()
00064 {
00065     SDL_Quit();
00066 }
00067 
00068 //-----------------------------------------------------------------
00069 /**
00070  * Load and set icon.
00071  * @throws ImgException
00072  */
00073     void
00074 VideoAgent::setIcon(const Path &file)
00075 {
00076     SDL_Surface *icon = IMG_Load(file.getNative().c_str());
00077     if (NULL == icon) {
00078         throw ImgException(ExInfo("Load")
00079                 .addInfo("file", file.getNative()));
00080     }
00081 
00082     SDL_WM_SetIcon(icon, NULL);
00083     SDL_FreeSurface(icon);
00084 }
00085 
00086 //-----------------------------------------------------------------
00087 /**
00088  * Init video mode along options.
00089  * Change window only when necessary.
00090  *
00091  * @throws SDLException when video mode cannot be made,
00092  * the old video mode remain usable
00093  */
00094     void
00095 VideoAgent::initVideoMode()
00096 {
00097     OptionAgent *options = OptionAgent::agent();
00098     int screen_width = options->getAsInt("screen_width", 640);
00099     int screen_height = options->getAsInt("screen_height", 480);
00100 
00101     SysVideo::setCaption(options->getParam("caption", "A game"));
00102     if (NULL == m_screen
00103             || m_screen->w != screen_width
00104             || m_screen->h != screen_height)
00105     {
00106         changeVideoMode(screen_width, screen_height);
00107     }
00108 }
00109 //-----------------------------------------------------------------
00110 /**
00111  * Init new video mode.
00112  * NOTE: m_screen pointer will change
00113  */
00114     void
00115 VideoAgent::changeVideoMode(int screen_width, int screen_height)
00116 {
00117     OptionAgent *options = OptionAgent::agent();
00118     int screen_bpp = options->getAsInt("screen_bpp", 32);
00119     int videoFlags = getVideoFlags();
00120     m_fullscreen = options->getAsBool("fullscreen", false);
00121     if (m_fullscreen) {
00122         videoFlags |= SDL_FULLSCREEN;
00123     }
00124 
00125     //TODO: check VideoModeOK and available ListModes
00126     SDL_Surface *newScreen =
00127         SDL_SetVideoMode(screen_width, screen_height, screen_bpp, videoFlags);
00128     if (newScreen) {
00129         m_screen = newScreen;
00130         //NOTE: must be two times to change MouseState
00131         SDL_WarpMouse(screen_width / 2, screen_height / 2);
00132         SDL_WarpMouse(screen_width / 2, screen_height / 2);
00133     }
00134     else {
00135         throw SDLException(ExInfo("SetVideoMode")
00136                 .addInfo("width", screen_width)
00137                 .addInfo("height", screen_height)
00138                 .addInfo("bpp", screen_bpp));
00139     }
00140 }
00141 //-----------------------------------------------------------------
00142 /**
00143  * Obtain video information about best video mode.
00144  * @return best video flags
00145  */
00146     int
00147 VideoAgent::getVideoFlags()
00148 {
00149     int videoFlags  = 0;
00150     videoFlags |= SDL_HWPALETTE;
00151     videoFlags |= SDL_ANYFORMAT;
00152     videoFlags |= SDL_SWSURFACE;
00153 
00154     return videoFlags;
00155 }
00156 //-----------------------------------------------------------------
00157 /**
00158  *  Toggle fullscreen.
00159  */
00160     void
00161 VideoAgent::toggleFullScreen()
00162 {
00163     int success = SDL_WM_ToggleFullScreen(m_screen);
00164     if (success) {
00165         m_fullscreen = !m_fullscreen;
00166     }
00167     else {
00168         //NOTE: some platforms need reinit video
00169         changeVideoMode(m_screen->w, m_screen->h);
00170     }
00171 }
00172 //-----------------------------------------------------------------
00173 /**
00174  * Handle incoming message.
00175  * Messages:
00176  * - fullscreen ... toggle fullscreen
00177  *
00178  * @throws UnknownMsgException
00179  */
00180     void
00181 VideoAgent::receiveSimple(const SimpleMsg *msg)
00182 {
00183     if (msg->equalsName("fullscreen")) {
00184         OptionAgent *options = OptionAgent::agent();
00185         bool toggle = !(options->getAsBool("fullscreen"));
00186         options->setPersistent("fullscreen", toggle);
00187     }
00188     else {
00189         throw UnknownMsgException(msg);
00190     }
00191 }
00192 //-----------------------------------------------------------------
00193 /**
00194  * Handle incoming message.
00195  * Messages:
00196  * - param_changed(fullscreen) ... handle fullscreen
00197  *
00198  * @throws UnknownMsgException
00199  */
00200     void
00201 VideoAgent::receiveString(const StringMsg *msg)
00202 {
00203     if (msg->equalsName("param_changed")) {
00204         std::string param = msg->getValue();
00205         if ("fullscreen" == param) {
00206             bool fs = OptionAgent::agent()->getAsBool("fullscreen");
00207             if (fs != m_fullscreen) {
00208                 toggleFullScreen();
00209             }
00210         }
00211         else {
00212             throw UnknownMsgException(msg);
00213         }
00214     }
00215     else {
00216         throw UnknownMsgException(msg);
00217     }
00218 }
00219 

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