00001
00002
00003
00004
00005
00006
00007
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
00058
00059 void
00060 Pedometer::prepareBg()
00061 {
00062
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
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
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
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
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
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
00188
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
00231
00232
00233
00234
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 }