"Lost treasure of mBedungu" 100 level puzzle game for RETRO

Dependencies:   LCD_ST7735 RetroPlatform mbed

Into Level 0 Menu Level 99

Committer:
Architect
Date:
Sun Mar 01 05:32:06 2015 +0000
Revision:
1:dcea5500a32d
Parent:
0:f5f961973d01
Initial checkin

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Architect 1:dcea5500a32d 1 /*
Architect 1:dcea5500a32d 2 * (C) Copyright 2015 Valentin Ivanov. All rights reserved.
Architect 1:dcea5500a32d 3 *
Architect 1:dcea5500a32d 4 * This file is part of the "Lost treasure of mBedungu" game application for Retro
Architect 1:dcea5500a32d 5 *
Architect 1:dcea5500a32d 6 * The "Lost treasure of mBedungu" application is free software: you can redistribute it and/or modify
Architect 1:dcea5500a32d 7 * it under the terms of the GNU Lesser General Public License as published by
Architect 1:dcea5500a32d 8 * the Free Software Foundation, either version 3 of the License, or
Architect 1:dcea5500a32d 9 * (at your option) any later version.
Architect 1:dcea5500a32d 10 *
Architect 1:dcea5500a32d 11 * This program is distributed in the hope that it will be useful,
Architect 1:dcea5500a32d 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Architect 1:dcea5500a32d 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Architect 1:dcea5500a32d 14 * GNU Lesser General Public License for more details.
Architect 1:dcea5500a32d 15 *
Architect 1:dcea5500a32d 16 * You should have received a copy of the GNU Lesser General Public License
Architect 1:dcea5500a32d 17 * along with this program. If not, see <http://www.gnu.org/licenses/>
Architect 1:dcea5500a32d 18 *
Architect 1:dcea5500a32d 19 */
Architect 1:dcea5500a32d 20
Architect 0:f5f961973d01 21 #include "GameScreen.h"
Architect 0:f5f961973d01 22 #include "Retro.h"
Architect 0:f5f961973d01 23 #include "Sprites.h"
Architect 0:f5f961973d01 24 #include "Levels.h"
Architect 0:f5f961973d01 25
Architect 1:dcea5500a32d 26 #include "Utils.h"
Architect 1:dcea5500a32d 27
Architect 0:f5f961973d01 28 extern Retro retro;
Architect 0:f5f961973d01 29
Architect 1:dcea5500a32d 30
Architect 1:dcea5500a32d 31 const int soundfx[][8] = {
Architect 1:dcea5500a32d 32 {0,24,1,1,1,4,4,9}, // gameover
Architect 1:dcea5500a32d 33 {0,27,53,1,1,1,4,5}, // pickup
Architect 1:dcea5500a32d 34 {0,23,60,1,1,1,4,5} // drop
Architect 1:dcea5500a32d 35 };
Architect 1:dcea5500a32d 36
Architect 1:dcea5500a32d 37 void sfx(int fxno, int channel)
Architect 1:dcea5500a32d 38 {
Architect 1:dcea5500a32d 39 sfx(soundfx[fxno], channel);
Architect 1:dcea5500a32d 40 };
Architect 1:dcea5500a32d 41
Architect 1:dcea5500a32d 42 void sfx( const int * effect, int channel)
Architect 1:dcea5500a32d 43 {
Architect 1:dcea5500a32d 44 retro.sound.command(0, effect[6], 0, channel); // set volume
Architect 1:dcea5500a32d 45 retro.sound.command(1, effect[0], 0, channel); // set waveform
Architect 1:dcea5500a32d 46 retro.sound.command(2, effect[5], -effect[4], channel); // set volume slide
Architect 1:dcea5500a32d 47 retro.sound.command(3, effect[3], effect[2] - 58, channel); // set pitch slide
Architect 1:dcea5500a32d 48 retro.sound.playNote(effect[1], effect[7], channel); // play note
Architect 1:dcea5500a32d 49
Architect 1:dcea5500a32d 50 }
Architect 1:dcea5500a32d 51
Architect 1:dcea5500a32d 52 Image sprites[] = {
Architect 1:dcea5500a32d 53 {false, false, NULL},
Architect 1:dcea5500a32d 54 {false, false, wall},
Architect 1:dcea5500a32d 55 {false, false, barrel},
Architect 1:dcea5500a32d 56 {false, false, ladder},
Architect 1:dcea5500a32d 57 {false, false, key},
Architect 1:dcea5500a32d 58 {false, false, door},
Architect 1:dcea5500a32d 59 {false, false, left},
Architect 1:dcea5500a32d 60 {true, false, left},
Architect 1:dcea5500a32d 61 {false, false, crate},
Architect 1:dcea5500a32d 62 {false, false, totem},
Architect 1:dcea5500a32d 63 {false, true, rick},
Architect 1:dcea5500a32d 64 {false, false, rick_top},
Architect 1:dcea5500a32d 65 {false, false, rick_happy}
Architect 0:f5f961973d01 66 };
Architect 0:f5f961973d01 67
Architect 0:f5f961973d01 68 GameScreen::GameScreen()
Architect 0:f5f961973d01 69 {
Architect 0:f5f961973d01 70 _level = 0;
Architect 0:f5f961973d01 71 _state = 0;
Architect 0:f5f961973d01 72 _pocket[0] = 0;
Architect 0:f5f961973d01 73 _pocket[1] = 0;
Architect 0:f5f961973d01 74 _rickDirection = 0;
Architect 1:dcea5500a32d 75 _gameOver = false;
Architect 1:dcea5500a32d 76
Architect 1:dcea5500a32d 77 //for some reason writing to eeprom sometime hangs the program
Architect 1:dcea5500a32d 78 // _gameData[0] = 0;
Architect 1:dcea5500a32d 79 // _gameData[1] = 0;
Architect 1:dcea5500a32d 80 // _gameData[2] = 0;
Architect 1:dcea5500a32d 81 // _gameData[3] = 0;
Architect 1:dcea5500a32d 82 // _gameData[4] = 0;
Architect 1:dcea5500a32d 83 // _gameData[5] = 0;
Architect 1:dcea5500a32d 84 //
Architect 1:dcea5500a32d 85 // read_eeprom((char *)64, _gameData, 8);
Architect 1:dcea5500a32d 86 // if( _gameData[0]=='R' && _gameData[1]=='I' && _gameData[2]=='C' && _gameData[3]=='K' )
Architect 1:dcea5500a32d 87 // {
Architect 1:dcea5500a32d 88 // _level = _gameData[4];
Architect 1:dcea5500a32d 89 // _gameComplete = _gameData[5];
Architect 1:dcea5500a32d 90 // }
Architect 1:dcea5500a32d 91 //
Architect 1:dcea5500a32d 92 // _gameData[0]='R';
Architect 1:dcea5500a32d 93 // _gameData[1]='I';
Architect 1:dcea5500a32d 94 // _gameData[2]='C';
Architect 1:dcea5500a32d 95 // _gameData[3]='K';
Architect 1:dcea5500a32d 96
Architect 0:f5f961973d01 97 }
Architect 0:f5f961973d01 98
Architect 0:f5f961973d01 99 bool GameScreen::isPocketFull()
Architect 0:f5f961973d01 100 {
Architect 0:f5f961973d01 101 return (_pocket[0] != 0 && _pocket[1] != 0);
Architect 0:f5f961973d01 102 }
Architect 0:f5f961973d01 103
Architect 0:f5f961973d01 104 bool GameScreen::isPocketEmpty()
Architect 0:f5f961973d01 105 {
Architect 0:f5f961973d01 106 return (_pocket[0] == 0 && _pocket[1] == 0);
Architect 0:f5f961973d01 107 }
Architect 0:f5f961973d01 108
Architect 0:f5f961973d01 109 bool GameScreen::putInPocket( int item )
Architect 0:f5f961973d01 110 {
Architect 0:f5f961973d01 111 if( item != CELL_BARREL && item != CELL_KEY )
Architect 0:f5f961973d01 112 return false;
Architect 0:f5f961973d01 113
Architect 0:f5f961973d01 114 bool bRet = true;
Architect 0:f5f961973d01 115
Architect 0:f5f961973d01 116 if( _pocket[0] == 0 )
Architect 0:f5f961973d01 117 _pocket[0] = item;
Architect 0:f5f961973d01 118 else if( _pocket[1] == 0 )
Architect 0:f5f961973d01 119 _pocket[1] = item;
Architect 0:f5f961973d01 120 else
Architect 0:f5f961973d01 121 bRet = false;
Architect 0:f5f961973d01 122
Architect 0:f5f961973d01 123 return bRet;
Architect 0:f5f961973d01 124 }
Architect 0:f5f961973d01 125
Architect 0:f5f961973d01 126 bool GameScreen::getKeyFromPocket()
Architect 0:f5f961973d01 127 {
Architect 0:f5f961973d01 128 bool bRet = true;
Architect 0:f5f961973d01 129
Architect 0:f5f961973d01 130 if( _pocket[0] == CELL_KEY )
Architect 0:f5f961973d01 131 _pocket[0] = 0;
Architect 0:f5f961973d01 132 else if( _pocket[1] == CELL_KEY )
Architect 0:f5f961973d01 133 _pocket[1] = 0;
Architect 0:f5f961973d01 134 else
Architect 0:f5f961973d01 135 bRet = false;
Architect 0:f5f961973d01 136
Architect 0:f5f961973d01 137 return bRet;
Architect 0:f5f961973d01 138 }
Architect 0:f5f961973d01 139
Architect 0:f5f961973d01 140 bool GameScreen::getBarrelFromPocket()
Architect 0:f5f961973d01 141 {
Architect 0:f5f961973d01 142 bool bRet = true;
Architect 0:f5f961973d01 143
Architect 0:f5f961973d01 144 if( _pocket[0] == CELL_BARREL )
Architect 0:f5f961973d01 145 _pocket[0] = 0;
Architect 0:f5f961973d01 146 else if( _pocket[1] == CELL_BARREL )
Architect 0:f5f961973d01 147 _pocket[1] = 0;
Architect 0:f5f961973d01 148 else
Architect 0:f5f961973d01 149 bRet = false;
Architect 0:f5f961973d01 150
Architect 0:f5f961973d01 151 return bRet;
Architect 0:f5f961973d01 152 }
Architect 0:f5f961973d01 153
Architect 0:f5f961973d01 154 void GameScreen::moveleft()
Architect 0:f5f961973d01 155 {
Architect 1:dcea5500a32d 156 if( _rickDirection == 0 ) {
Architect 0:f5f961973d01 157 _rickDirection = 1;
Architect 1:dcea5500a32d 158 sprites[CELL_RICK].Mirrored = true;//(_rickDirection == 1);
Architect 1:dcea5500a32d 159 drawSprite(_rickX,_rickY, CELL_RICK);
Architect 0:f5f961973d01 160 }
Architect 1:dcea5500a32d 161
Architect 0:f5f961973d01 162 if( _rickX == 0 )
Architect 0:f5f961973d01 163 return;
Architect 0:f5f961973d01 164
Architect 0:f5f961973d01 165 uint8_t cell = _maze[(_rickY<<3)+_rickX-1];
Architect 0:f5f961973d01 166
Architect 0:f5f961973d01 167
Architect 0:f5f961973d01 168 if( cell == CELL_KEY || cell == CELL_BARREL ) {
Architect 0:f5f961973d01 169 if( putInPocket(cell) ) {
Architect 1:dcea5500a32d 170 sfx(1,0);
Architect 0:f5f961973d01 171 _maze[(_rickY<<3)+_rickX-1] = CELL_EMPTY;
Architect 0:f5f961973d01 172 drawSprite((_rickX-1),_rickY, CELL_EMPTY);
Architect 0:f5f961973d01 173 drawPocket();
Architect 1:dcea5500a32d 174
Architect 1:dcea5500a32d 175 //Fall any crates on top of that key or barrel
Architect 1:dcea5500a32d 176 int y = _rickY;
Architect 1:dcea5500a32d 177 while( y >= 0 ) {
Architect 1:dcea5500a32d 178 fall(_rickX-1,y--);
Architect 1:dcea5500a32d 179 }
Architect 1:dcea5500a32d 180
Architect 0:f5f961973d01 181 }
Architect 0:f5f961973d01 182 return;
Architect 0:f5f961973d01 183 }
Architect 0:f5f961973d01 184
Architect 1:dcea5500a32d 185 if( (cell == CELL_CRATE) && ((_rickX-1)>0) ) {
Architect 1:dcea5500a32d 186 if( moveto(_rickX-1,_rickY, _rickX-2,_rickY) ) {
Architect 0:f5f961973d01 187 fall(_rickX-2,_rickY);
Architect 1:dcea5500a32d 188
Architect 1:dcea5500a32d 189 int y = _rickY;
Architect 1:dcea5500a32d 190 while( y >= 0 ) {
Architect 1:dcea5500a32d 191 fall(_rickX-1,y--);
Architect 1:dcea5500a32d 192 }
Architect 1:dcea5500a32d 193
Architect 1:dcea5500a32d 194 }
Architect 1:dcea5500a32d 195
Architect 0:f5f961973d01 196 return;
Architect 0:f5f961973d01 197 }
Architect 0:f5f961973d01 198
Architect 0:f5f961973d01 199
Architect 0:f5f961973d01 200 if( moveto(_rickX,_rickY,_rickX-1,_rickY) )
Architect 0:f5f961973d01 201 fall(_rickX,_rickY);
Architect 0:f5f961973d01 202
Architect 0:f5f961973d01 203 }
Architect 0:f5f961973d01 204
Architect 0:f5f961973d01 205 void GameScreen::moveright()
Architect 0:f5f961973d01 206 {
Architect 1:dcea5500a32d 207 if( _rickDirection == 1 ) {
Architect 0:f5f961973d01 208 _rickDirection = 0;
Architect 1:dcea5500a32d 209 sprites[CELL_RICK].Mirrored = false;
Architect 1:dcea5500a32d 210 drawSprite(_rickX,_rickY, CELL_RICK);
Architect 0:f5f961973d01 211 }
Architect 1:dcea5500a32d 212
Architect 0:f5f961973d01 213 if( _rickX == 7 )
Architect 0:f5f961973d01 214 return;
Architect 0:f5f961973d01 215
Architect 0:f5f961973d01 216 uint8_t cell = _maze[(_rickY<<3)+_rickX+1];
Architect 0:f5f961973d01 217
Architect 0:f5f961973d01 218 if( cell == CELL_KEY || cell == CELL_BARREL ) {
Architect 0:f5f961973d01 219 if( putInPocket(cell) ) {
Architect 1:dcea5500a32d 220 sfx(1,0);
Architect 0:f5f961973d01 221 _maze[(_rickY<<3)+_rickX+1] = CELL_EMPTY;
Architect 0:f5f961973d01 222 drawSprite((_rickX+1),_rickY, CELL_EMPTY);
Architect 0:f5f961973d01 223 drawPocket();
Architect 1:dcea5500a32d 224
Architect 1:dcea5500a32d 225 //Fall any crates on top of that key or barrel
Architect 1:dcea5500a32d 226 int y = _rickY;
Architect 1:dcea5500a32d 227 while( y >= 0 ) {
Architect 1:dcea5500a32d 228 fall(_rickX+1,y--);
Architect 1:dcea5500a32d 229 }
Architect 0:f5f961973d01 230 }
Architect 0:f5f961973d01 231 return;
Architect 0:f5f961973d01 232 }
Architect 1:dcea5500a32d 233
Architect 1:dcea5500a32d 234 if( (cell == CELL_CRATE) && ((_rickX+1)<7) ) {
Architect 1:dcea5500a32d 235 if( moveto(_rickX+1,_rickY, _rickX+2,_rickY) ) {
Architect 0:f5f961973d01 236 fall(_rickX+2,_rickY);
Architect 1:dcea5500a32d 237
Architect 1:dcea5500a32d 238 int y = _rickY;
Architect 1:dcea5500a32d 239 while( y >= 0 ) {
Architect 1:dcea5500a32d 240 fall(_rickX+1,y--);
Architect 1:dcea5500a32d 241 }
Architect 1:dcea5500a32d 242 }
Architect 0:f5f961973d01 243 return;
Architect 0:f5f961973d01 244 }
Architect 0:f5f961973d01 245
Architect 0:f5f961973d01 246 if( moveto(_rickX,_rickY,_rickX+1,_rickY) )
Architect 0:f5f961973d01 247 fall(_rickX,_rickY);
Architect 0:f5f961973d01 248
Architect 0:f5f961973d01 249 }
Architect 0:f5f961973d01 250
Architect 0:f5f961973d01 251 void GameScreen::moveup()
Architect 0:f5f961973d01 252 {
Architect 0:f5f961973d01 253 if( _rickY == 0 )
Architect 0:f5f961973d01 254 return;
Architect 0:f5f961973d01 255
Architect 0:f5f961973d01 256 uint8_t currentCell = _maze[((_rickY)<<3)+_rickX];
Architect 0:f5f961973d01 257 uint8_t aboveCell = _maze[((_rickY-1)<<3)+_rickX];
Architect 0:f5f961973d01 258
Architect 0:f5f961973d01 259 //if already on ladder
Architect 0:f5f961973d01 260 if( currentCell == CELL_LADDER )
Architect 0:f5f961973d01 261 moveto(_rickX,_rickY,_rickX,_rickY-1);
Architect 0:f5f961973d01 262 else if( currentCell == CELL_EMPTY && !isPocketEmpty()) {
Architect 0:f5f961973d01 263 uint8_t x = _rickX;
Architect 0:f5f961973d01 264 uint8_t y = _rickY;
Architect 0:f5f961973d01 265 if( moveto(_rickX,_rickY,_rickX,_rickY-1) ) {
Architect 0:f5f961973d01 266 if( getBarrelFromPocket() ) {
Architect 1:dcea5500a32d 267 sfx(2,0);
Architect 0:f5f961973d01 268 _maze[(y<<3)+x] = CELL_BARREL;
Architect 0:f5f961973d01 269 drawSprite(x,y,CELL_BARREL);
Architect 0:f5f961973d01 270 } else if( getKeyFromPocket() ) {
Architect 1:dcea5500a32d 271 sfx(2,0);
Architect 0:f5f961973d01 272 _maze[(y<<3)+x] = CELL_KEY;
Architect 0:f5f961973d01 273 drawSprite(x,y,CELL_KEY);
Architect 0:f5f961973d01 274 }
Architect 0:f5f961973d01 275 drawPocket();
Architect 0:f5f961973d01 276 }
Architect 0:f5f961973d01 277 }
Architect 0:f5f961973d01 278 }
Architect 0:f5f961973d01 279
Architect 0:f5f961973d01 280 void GameScreen::movedown()
Architect 0:f5f961973d01 281 {
Architect 1:dcea5500a32d 282 if( _rickY == 7 )
Architect 0:f5f961973d01 283 return;
Architect 0:f5f961973d01 284
Architect 0:f5f961973d01 285
Architect 1:dcea5500a32d 286 if( moveto(_rickX,_rickY,_rickX,_rickY+1) ) {
Architect 1:dcea5500a32d 287 fall(_rickX,_rickY);
Architect 0:f5f961973d01 288 }
Architect 1:dcea5500a32d 289
Architect 0:f5f961973d01 290 }
Architect 0:f5f961973d01 291
Architect 0:f5f961973d01 292
Architect 0:f5f961973d01 293 bool GameScreen::moveto(uint8_t fromX, uint8_t fromY, uint8_t toX, uint8_t toY)
Architect 0:f5f961973d01 294 {
Architect 1:dcea5500a32d 295
Architect 0:f5f961973d01 296 bool isRick = false;
Architect 0:f5f961973d01 297
Architect 0:f5f961973d01 298 if( fromX == _rickX && fromY == _rickY )
Architect 0:f5f961973d01 299 isRick = true;
Architect 0:f5f961973d01 300
Architect 0:f5f961973d01 301 uint8_t fromCell = _maze[((fromY)<<3)+fromX];
Architect 0:f5f961973d01 302 uint8_t toCell = _maze[((toY)<<3)+toX];
Architect 0:f5f961973d01 303
Architect 0:f5f961973d01 304 if( isRick ) {
Architect 1:dcea5500a32d 305 if( toCell == CELL_EMPTY || toCell == CELL_LADDER ) {
Architect 0:f5f961973d01 306 drawSprite(fromX,fromY, fromCell);
Architect 0:f5f961973d01 307 _rickX = toX;
Architect 0:f5f961973d01 308 _rickY = toY;
Architect 1:dcea5500a32d 309 drawSprite(_rickX,_rickY, CELL_RICK);
Architect 1:dcea5500a32d 310 return true;
Architect 1:dcea5500a32d 311 }
Architect 1:dcea5500a32d 312 if( toCell == CELL_TOTEM )
Architect 1:dcea5500a32d 313 {
Architect 1:dcea5500a32d 314 sfx(0,0);
Architect 1:dcea5500a32d 315 _gameOver = true;
Architect 1:dcea5500a32d 316 drawSprite(fromX,fromY, fromCell);
Architect 1:dcea5500a32d 317 _rickX = toX;
Architect 1:dcea5500a32d 318 _rickY = toY;
Architect 1:dcea5500a32d 319 drawSprite(_rickX,_rickY, CELL_RICK);
Architect 0:f5f961973d01 320 return true;
Architect 0:f5f961973d01 321 }
Architect 0:f5f961973d01 322 if( toCell == CELL_DOOR ) {
Architect 0:f5f961973d01 323 if( getKeyFromPocket() ) {
Architect 0:f5f961973d01 324 drawSprite(fromX,fromY, fromCell);
Architect 0:f5f961973d01 325 _maze[((toY)<<3)+toX] = CELL_EMPTY;
Architect 0:f5f961973d01 326 _rickX = toX;
Architect 0:f5f961973d01 327 _rickY = toY;
Architect 1:dcea5500a32d 328 drawSprite(_rickX,_rickY, CELL_RICK);
Architect 0:f5f961973d01 329 drawPocket();
Architect 0:f5f961973d01 330 return true;
Architect 0:f5f961973d01 331 }
Architect 0:f5f961973d01 332 }
Architect 1:dcea5500a32d 333 if( (toCell == CELL_RIGHT && fromX < toX) || (toCell == CELL_LEFT && fromX > toX)) {
Architect 1:dcea5500a32d 334 drawSprite(fromX,fromY, fromCell);
Architect 1:dcea5500a32d 335 _rickX = toX;
Architect 1:dcea5500a32d 336 _rickY = toY;
Architect 1:dcea5500a32d 337 drawSprite(_rickX,_rickY, CELL_RICK);
Architect 1:dcea5500a32d 338 return true;
Architect 1:dcea5500a32d 339 }
Architect 1:dcea5500a32d 340 } else if( fromCell == CELL_CRATE && toCell == CELL_EMPTY ) {
Architect 0:f5f961973d01 341 _maze[((toY)<<3)+toX] = CELL_CRATE;
Architect 0:f5f961973d01 342 _maze[((fromY)<<3)+fromX] = CELL_EMPTY;
Architect 1:dcea5500a32d 343
Architect 0:f5f961973d01 344 drawSprite(fromX,fromY, toCell);
Architect 0:f5f961973d01 345 drawSprite(toX,toY, fromCell);
Architect 0:f5f961973d01 346 return true;
Architect 0:f5f961973d01 347 }
Architect 0:f5f961973d01 348
Architect 0:f5f961973d01 349 return false;
Architect 0:f5f961973d01 350 }
Architect 0:f5f961973d01 351
Architect 0:f5f961973d01 352 bool GameScreen::fall(uint8_t fromX, uint8_t fromY)
Architect 0:f5f961973d01 353 {
Architect 0:f5f961973d01 354 if( fromY == 7 )
Architect 0:f5f961973d01 355 return false;
Architect 0:f5f961973d01 356
Architect 0:f5f961973d01 357 uint8_t curCell = _maze[(fromY<<3)+fromX];
Architect 0:f5f961973d01 358
Architect 0:f5f961973d01 359 if( curCell == CELL_LADDER )
Architect 0:f5f961973d01 360 return false;
Architect 0:f5f961973d01 361
Architect 0:f5f961973d01 362 uint8_t cell = _maze[((fromY+1)<<3)+fromX];
Architect 0:f5f961973d01 363
Architect 0:f5f961973d01 364
Architect 0:f5f961973d01 365
Architect 0:f5f961973d01 366 while( cell == CELL_EMPTY || cell == CELL_TOTEM ) {
Architect 0:f5f961973d01 367 if( moveto(fromX,fromY,fromX,fromY+1) ) {
Architect 0:f5f961973d01 368 fromY++;
Architect 0:f5f961973d01 369
Architect 0:f5f961973d01 370 if( fromY == 7 )
Architect 0:f5f961973d01 371 break;
Architect 0:f5f961973d01 372
Architect 0:f5f961973d01 373 cell = _maze[((fromY+1)<<3)+fromX];
Architect 0:f5f961973d01 374 } else {
Architect 0:f5f961973d01 375 break;
Architect 0:f5f961973d01 376 }
Architect 0:f5f961973d01 377 }
Architect 0:f5f961973d01 378
Architect 0:f5f961973d01 379 return true;
Architect 0:f5f961973d01 380 }
Architect 0:f5f961973d01 381
Architect 0:f5f961973d01 382
Architect 0:f5f961973d01 383
Architect 0:f5f961973d01 384
Architect 0:f5f961973d01 385 void GameScreen::unpackLevel( int level )
Architect 0:f5f961973d01 386 {
Architect 0:f5f961973d01 387 if( level < 0 || level > 99 )
Architect 0:f5f961973d01 388 level = 0;
Architect 0:f5f961973d01 389
Architect 0:f5f961973d01 390 _level = level;
Architect 0:f5f961973d01 391
Architect 0:f5f961973d01 392 const uint32_t * pLevel = &levels[level*8];
Architect 0:f5f961973d01 393
Architect 0:f5f961973d01 394 for( int y = 0; y < 8; y++ )
Architect 0:f5f961973d01 395 for( int x = 0; x < 8; x++ ) {
Architect 0:f5f961973d01 396 _maze[(y<<3) + x] = (pLevel[y]>>(28-(x<<2))) & 0x0F;
Architect 0:f5f961973d01 397
Architect 0:f5f961973d01 398 switch( _maze[(y<<3) + x] ) {
Architect 0:f5f961973d01 399 case CELL_RICK:
Architect 0:f5f961973d01 400 //The level data has specialy marked cell for Rick
Architect 0:f5f961973d01 401 //During the game Rick position is tracked separately
Architect 0:f5f961973d01 402 //This allows us to put Rick on none EMPTY cells
Architect 0:f5f961973d01 403 _maze[(y<<3) + x] = CELL_EMPTY;
Architect 0:f5f961973d01 404 _rickX = x;
Architect 0:f5f961973d01 405 _rickY = y;
Architect 0:f5f961973d01 406 break;
Architect 0:f5f961973d01 407 case CELL_TOTEM:
Architect 0:f5f961973d01 408 _totemX = x;
Architect 0:f5f961973d01 409 _totemY = y;
Architect 0:f5f961973d01 410 break;
Architect 0:f5f961973d01 411 default:
Architect 0:f5f961973d01 412 break;
Architect 0:f5f961973d01 413 }
Architect 0:f5f961973d01 414 }
Architect 1:dcea5500a32d 415
Architect 1:dcea5500a32d 416 _state = 0;
Architect 1:dcea5500a32d 417 _pocket[0] = 0;
Architect 1:dcea5500a32d 418 _pocket[1] = 0;
Architect 1:dcea5500a32d 419 _rickDirection = 0;
Architect 1:dcea5500a32d 420 _gameOver = false;
Architect 1:dcea5500a32d 421
Architect 1:dcea5500a32d 422 sprites[CELL_RICK].Mirrored = false;
Architect 1:dcea5500a32d 423
Architect 1:dcea5500a32d 424 frame = 0;
Architect 0:f5f961973d01 425 }
Architect 0:f5f961973d01 426
Architect 0:f5f961973d01 427 void GameScreen::resetLevel()
Architect 0:f5f961973d01 428 {
Architect 0:f5f961973d01 429 unpackLevel(_level);
Architect 0:f5f961973d01 430 }
Architect 0:f5f961973d01 431
Architect 0:f5f961973d01 432 void GameScreen::drawPocket()
Architect 0:f5f961973d01 433 {
Architect 0:f5f961973d01 434 if( _pocket[0] == 0 )
Architect 0:f5f961973d01 435 retro.display.fillRect(136,80,151,95,0);
Architect 0:f5f961973d01 436 else
Architect 1:dcea5500a32d 437 retro.display.drawBitmapIndexed(136,80, 16,16,sprites[_pocket[0]].Sprite, palette);
Architect 0:f5f961973d01 438
Architect 0:f5f961973d01 439 if( _pocket[1] == 0 )
Architect 0:f5f961973d01 440 retro.display.fillRect(136,96,151,111,0);
Architect 0:f5f961973d01 441 else
Architect 1:dcea5500a32d 442 retro.display.drawBitmapIndexed(136,96, 16,16,sprites[_pocket[1]].Sprite, palette);
Architect 0:f5f961973d01 443 }
Architect 0:f5f961973d01 444
Architect 0:f5f961973d01 445
Architect 0:f5f961973d01 446 void GameScreen::drawLevel()
Architect 0:f5f961973d01 447 {
Architect 0:f5f961973d01 448 //Draw the maze
Architect 0:f5f961973d01 449 for( int y = 0; y < 8; y++ )
Architect 0:f5f961973d01 450 for( int x = 0; x < 8; x++ ) {
Architect 0:f5f961973d01 451 drawSprite(x, y, _maze[(y<<3)+x]);
Architect 0:f5f961973d01 452 }
Architect 0:f5f961973d01 453
Architect 0:f5f961973d01 454 //Put Rick on the map
Architect 1:dcea5500a32d 455 drawSprite(_rickX, _rickY, CELL_RICK);
Architect 0:f5f961973d01 456
Architect 0:f5f961973d01 457 //Draw the statistics and "pocket" area
Architect 0:f5f961973d01 458 for( int y = 0; y < 8; y++ ) {
Architect 0:f5f961973d01 459 retro.display.drawBitmapIndexed(128,y<<4, 16,16,wall, palette);
Architect 0:f5f961973d01 460 retro.display.drawBitmapIndexed(144,y<<4, 16,16, wall, palette);
Architect 0:f5f961973d01 461 }
Architect 0:f5f961973d01 462 retro.display.drawBitmapIndexed(136,16, 16,16,totem,palette);
Architect 0:f5f961973d01 463 retro.display.fillRect(132,32,155,39,0);
Architect 0:f5f961973d01 464
Architect 1:dcea5500a32d 465 drawLevelNumber(136,32,_level);
Architect 0:f5f961973d01 466
Architect 0:f5f961973d01 467 drawPocket();
Architect 0:f5f961973d01 468 }
Architect 0:f5f961973d01 469
Architect 0:f5f961973d01 470
Architect 1:dcea5500a32d 471
Architect 0:f5f961973d01 472 Screen GameScreen::Update()
Architect 0:f5f961973d01 473 {
Architect 1:dcea5500a32d 474 frame++;
Architect 1:dcea5500a32d 475
Architect 0:f5f961973d01 476 if( _state == 0 ) {
Architect 0:f5f961973d01 477 drawLevel();
Architect 0:f5f961973d01 478 _state = 1;
Architect 0:f5f961973d01 479 }
Architect 1:dcea5500a32d 480
Architect 1:dcea5500a32d 481 if( _gameOver )
Architect 1:dcea5500a32d 482 {
Architect 1:dcea5500a32d 483 if( (frame % 3) == 0 )
Architect 1:dcea5500a32d 484 {
Architect 1:dcea5500a32d 485 sprites[12].Mirrored = !sprites[12].Mirrored;
Architect 1:dcea5500a32d 486 drawSprite(_rickX,_rickY,12);
Architect 1:dcea5500a32d 487 }
Architect 1:dcea5500a32d 488 }
Architect 0:f5f961973d01 489
Architect 1:dcea5500a32d 490 if(retro.pressed(BTN_LEFT)) {
Architect 1:dcea5500a32d 491 //sfx(0,0);
Architect 1:dcea5500a32d 492 if( !_gameOver )
Architect 1:dcea5500a32d 493 moveleft();
Architect 0:f5f961973d01 494 }
Architect 1:dcea5500a32d 495 if(retro.pressed(BTN_RIGHT)) {
Architect 1:dcea5500a32d 496 //sfx(1,0);
Architect 1:dcea5500a32d 497 if( !_gameOver )
Architect 0:f5f961973d01 498 moveright();
Architect 0:f5f961973d01 499 }
Architect 1:dcea5500a32d 500 if(retro.pressed(BTN_UP)) {
Architect 1:dcea5500a32d 501 //sfx(2,0);
Architect 1:dcea5500a32d 502 if( !_gameOver )
Architect 1:dcea5500a32d 503 moveup();
Architect 0:f5f961973d01 504 }
Architect 1:dcea5500a32d 505 if(retro.pressed(BTN_DOWN)) {
Architect 1:dcea5500a32d 506 //sfx(3,0);
Architect 1:dcea5500a32d 507 if( !_gameOver )
Architect 0:f5f961973d01 508 movedown();
Architect 0:f5f961973d01 509 }
Architect 1:dcea5500a32d 510 if(retro.pressed(BTN_ROBOT)) {
Architect 0:f5f961973d01 511 _state = 0;
Architect 0:f5f961973d01 512 return Menu;
Architect 0:f5f961973d01 513 }
Architect 1:dcea5500a32d 514
Architect 1:dcea5500a32d 515 if(retro.pressed(BTN_SHIP)) {
Architect 1:dcea5500a32d 516 if( _gameOver )
Architect 1:dcea5500a32d 517 {
Architect 1:dcea5500a32d 518 if( _level < 99 )
Architect 1:dcea5500a32d 519 {
Architect 1:dcea5500a32d 520 _level++;
Architect 1:dcea5500a32d 521 resetLevel();
Architect 1:dcea5500a32d 522
Architect 1:dcea5500a32d 523 //for some reason writing to eeprom sometime hangs the program
Architect 1:dcea5500a32d 524 // _gameData[4]= _level;
Architect 1:dcea5500a32d 525 // _gameData[5] = _gameComplete;
Architect 1:dcea5500a32d 526 //
Architect 1:dcea5500a32d 527 // write_eeprom(_gameData, (char *)64, 8 );
Architect 1:dcea5500a32d 528 }
Architect 1:dcea5500a32d 529 }
Architect 1:dcea5500a32d 530 }
Architect 0:f5f961973d01 531
Architect 0:f5f961973d01 532 return Game;
Architect 1:dcea5500a32d 533 }
Architect 1:dcea5500a32d 534
Architect 1:dcea5500a32d 535
Architect 1:dcea5500a32d 536 void drawSprite(int x, int y, int sprite)
Architect 1:dcea5500a32d 537 {
Architect 1:dcea5500a32d 538 int screenx = x<<4;
Architect 1:dcea5500a32d 539 int screeny = y<<4;
Architect 1:dcea5500a32d 540 if( sprite == 0 )
Architect 1:dcea5500a32d 541 retro.display.fillRect(screenx,screeny, screenx+15,screeny+15,0);
Architect 1:dcea5500a32d 542 else {
Architect 1:dcea5500a32d 543 retro.display.drawBitmapIndexed(screenx,screeny, 16,16,sprites[sprite].Sprite, palette, sprites[sprite].Mirrored);
Architect 1:dcea5500a32d 544 }
Architect 1:dcea5500a32d 545 }
Architect 1:dcea5500a32d 546
Architect 1:dcea5500a32d 547 void drawLevelNumber(int x, int y, int level)
Architect 1:dcea5500a32d 548 {
Architect 1:dcea5500a32d 549 char buf[3];
Architect 1:dcea5500a32d 550 if( (level/10) > 0 )
Architect 1:dcea5500a32d 551 sprintf(buf,"%d",level);
Architect 1:dcea5500a32d 552 else
Architect 1:dcea5500a32d 553 sprintf(buf,"@%d",level);
Architect 1:dcea5500a32d 554 drawString(x,y,buf, palette_orange);
Architect 0:f5f961973d01 555 }