"Lost treasure of mBedungu" 100 level puzzle game for RETRO
Dependencies: LCD_ST7735 RetroPlatform mbed
Game/GameScreen.cpp@1:dcea5500a32d, 2015-03-01 (annotated)
- 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?
User | Revision | Line number | New 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 | } |