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

Pedometer.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 "Pedometer.h"
00010 
00011 #include "LevelStatus.h"
00012 #include "Level.h"
00013 #include "PedoInput.h"
00014 #include "LayeredPicture.h"
00015 
00016 #include "ResImagePack.h"
00017 #include "StateManager.h"
00018 #include "NodeDrawer.h"
00019 #include "SolverDrawer.h"
00020 #include "Level.h"
00021 #include "minmax.h"
00022 #include "StringMsg.h"
00023 #include "UnknownMsgException.h"
00024 
00025 //-----------------------------------------------------------------
00026 Pedometer::Pedometer(LevelStatus *status, Level *new_level)
00027 {
00028     m_level = new_level;
00029     m_status = status;
00030     m_solution = m_status->readSolvedMoves();
00031     m_meterPhase = 0;
00032     m_bg = NULL;
00033 
00034     prepareBg();
00035     prepareRack();
00036 
00037     m_numbers = ResImagePack::loadImage(
00038             Path::dataReadPath("images/menu/numbers.png"));
00039 
00040     takeHandler(new PedoInput(this));
00041     registerDrawable(m_bg);
00042     registerDrawable(m_rack);
00043     registerDrawable(this);
00044 }
00045 //-----------------------------------------------------------------
00046 Pedometer::~Pedometer()
00047 {
00048     if (m_level) {
00049         delete m_level;
00050     }
00051     SDL_FreeSurface(m_numbers);
00052     delete m_rack;
00053     delete m_bg;
00054 }
00055 //-----------------------------------------------------------------
00056 /**
00057  * Draw level name on background.
00058  */
00059     void
00060 Pedometer::prepareBg()
00061 {
00062     //TODO: allow to set differect images
00063     SDL_Surface *bgSurface = ResImagePack::loadImage(
00064             Path::dataReadPath("images/menu/map.png"));
00065     NodeDrawer drawer;
00066     drawer.setScreen(bgSurface);
00067     drawer.drawSelected(m_level->getLevelName());
00068 
00069     SolverDrawer solver(m_status);
00070     solver.setShift(V2((bgSurface->w - solver.getW()) / 2,
00071                 bgSurface->h - 150));
00072     solver.drawOn(bgSurface);
00073 
00074     if (m_bg) {
00075         m_bg->changePicture(bgSurface);
00076     }
00077     else {
00078         m_bg = new Picture(bgSurface, V2(0, 0));
00079     }
00080 }
00081 //-----------------------------------------------------------------
00082     void
00083 Pedometer::prepareRack()
00084 {
00085     static const int POS_X = 193;
00086     static const int POS_Y = 141;
00087 
00088     //TODO: allow to set differect images
00089     m_rack = new LayeredPicture(
00090             Path::dataReadPath("images/menu/pedometer.png"),
00091             V2(POS_X, POS_Y),
00092             Path::dataReadPath("images/menu/pedometer_lower.png"),
00093             Path::dataReadPath("images/menu/pedometer_mask.png"));
00094 
00095     //TODO: don't use numeric constants for coordinates
00096     m_maskRun = m_rack->getMaskAt(V2(86, 100));
00097     m_maskReplay = m_rack->getMaskAt(V2(128, 100));
00098     m_maskCancel = m_rack->getMaskAt(V2(170, 100));
00099     m_activeMask = m_rack->getNoMask();
00100 }
00101 
00102 //-----------------------------------------------------------------
00103 /**
00104  * Display menu and play menu music.
00105  */
00106     void
00107 Pedometer::own_initState()
00108 {
00109     registerWatcher("lang");
00110     own_resumeState();
00111 }
00112 //-----------------------------------------------------------------
00113     void
00114 Pedometer::own_updateState()
00115 {
00116     watchCursor();
00117 }
00118 
00119 //-----------------------------------------------------------------
00120 /**
00121  * Mark pixel under cursor as ative mask.
00122  */
00123     void
00124 Pedometer::watchCursor()
00125 {
00126     V2 mouseLoc = getInput()->getMouseLoc();
00127     m_activeMask = m_rack->getMaskAtWorld(mouseLoc);
00128     if (m_activeMask == m_maskRun
00129             || m_activeMask == m_maskReplay
00130             || m_activeMask == m_maskCancel)
00131     {
00132         m_rack->setActiveMask(m_activeMask);
00133     }
00134     else {
00135         m_rack->setNoActive();
00136     }
00137 }
00138 //-----------------------------------------------------------------
00139 /**
00140  * Start selected button.
00141  */
00142     void
00143 Pedometer::runSelected()
00144 {
00145     if (m_activeMask == m_maskRun) {
00146         runLevel();
00147     }
00148     else if (m_activeMask == m_maskReplay) {
00149         runReplay();
00150     }
00151     else {
00152         quitState();
00153     }
00154 }
00155 //-----------------------------------------------------------------
00156     void
00157 Pedometer::runLevel()
00158 {
00159     Level *levelState = m_level;
00160     m_level = NULL;
00161     GameState *poster = m_status->createPoster();
00162     if (poster) {
00163         poster->setNextState(levelState);
00164         changeState(poster);
00165     }
00166     else {
00167         changeState(levelState);
00168     }
00169 }
00170 //-----------------------------------------------------------------
00171     void
00172 Pedometer::runReplay()
00173 {
00174     Level *levelState = m_level;
00175     m_level = NULL;
00176     changeState(levelState);
00177     levelState->loadReplay(m_solution);
00178 }
00179 //-----------------------------------------------------------------
00180     void
00181 Pedometer::drawOn(SDL_Surface *screen)
00182 {
00183     drawNumbers(screen, m_solution.size());
00184 }
00185 //-----------------------------------------------------------------
00186 /**
00187  * Draw number of steps.
00188  * Draw nice rotating numbers.
00189  */
00190     void
00191 Pedometer::drawNumbers(SDL_Surface *screen, int value)
00192 {
00193     static const int CIPHERS = 5;
00194     static const int POS_X = 275;
00195     static const int POS_Y = 177;
00196     static const int SHIFT_SPEED = 8;
00197 
00198     int numberWidth = m_numbers->w;
00199     int numberHeight = m_numbers->h / 10;
00200 
00201     for (int i = CIPHERS - 1; i >= 0; --i) {
00202         int cipher = value % 10;
00203         value /= 10;
00204         int x = POS_X + numberWidth * i;
00205         int shiftY = max(numberHeight * (9 - cipher),
00206                 numberHeight * 9 - SHIFT_SPEED * m_meterPhase);
00207         m_meterPhase++;
00208 
00209         drawNumber(screen, x, POS_Y, shiftY);
00210     }
00211 }
00212 //-----------------------------------------------------------------
00213 void
00214 Pedometer::drawNumber(SDL_Surface *screen, int x, int y, int shiftY)
00215 {
00216     SDL_Rect dest_rect;
00217     dest_rect.x = x;
00218     dest_rect.y = y;
00219 
00220     SDL_Rect src_rect;
00221     src_rect.x = 0;
00222     src_rect.y = shiftY;
00223     src_rect.w = m_numbers->w;
00224     src_rect.h = m_numbers->h / 10;
00225 
00226     SDL_BlitSurface(m_numbers, &src_rect, screen, &dest_rect);
00227 }
00228 //-----------------------------------------------------------------
00229 /**
00230  * Handle incoming message.
00231  * Messages:
00232  * - param_changed(lang) ... refresh bg
00233  *
00234  * @throws UnknownMsgException
00235  */
00236     void
00237 Pedometer::receiveString(const StringMsg *msg)
00238 {
00239     if (msg->equalsName("param_changed")) {
00240         std::string param = msg->getValue();
00241         if ("lang" == param) {
00242             prepareBg();
00243         }
00244         else {
00245             throw UnknownMsgException(msg);
00246         }
00247     }
00248     else {
00249         throw UnknownMsgException(msg);
00250     }
00251 }

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