Platform game written for the GHI/OutrageousCircuits RETRO game device. Navigate the caves collecting all the pickups and avoiding the creatures and haunted mine carts that patrol the caves. Oh and remember to watch out for the poisonous plants... This game demonstrates the ability to have multiple animated sprites where the sprites can overlap the background environment. See how the player moves past the fence and climbs the wall in the 3rd screen.

Dependencies:   mbed

Committer:
taylorza
Date:
Mon Feb 16 03:46:57 2015 +0000
Revision:
16:f9227904afc4
Parent:
14:b4884a31069e
Added a 4th game screen

Who changed what in which revision?

UserRevisionLine numberNew contents of line
taylorza 9:34008d8b1cdf 1 #include "GameEngine.h"
taylorza 9:34008d8b1cdf 2
taylorza 9:34008d8b1cdf 3 Bitmap4bpp Scene::BitmapBuffer(24, 24);
taylorza 9:34008d8b1cdf 4
taylorza 9:34008d8b1cdf 5 Scene::Scene() :
taylorza 9:34008d8b1cdf 6 _map(NULL),
taylorza 9:34008d8b1cdf 7 _x(0),
taylorza 9:34008d8b1cdf 8 _y(0),
taylorza 9:34008d8b1cdf 9 _objectsHeld(0)
taylorza 9:34008d8b1cdf 10 {
taylorza 9:34008d8b1cdf 11 Game::Surface.setOrientation(LCD_ST7735::Rotate270, false);
taylorza 9:34008d8b1cdf 12 Game::Surface.clearScreen();
taylorza 9:34008d8b1cdf 13
taylorza 9:34008d8b1cdf 14 for (int i = 0; i < MAX_GAMEOBJECTS; ++i)
taylorza 9:34008d8b1cdf 15 {
taylorza 9:34008d8b1cdf 16 _gameObjects[i] = NULL;
taylorza 9:34008d8b1cdf 17 }
taylorza 9:34008d8b1cdf 18 }
taylorza 9:34008d8b1cdf 19
taylorza 9:34008d8b1cdf 20 Scene::~Scene()
taylorza 9:34008d8b1cdf 21 {
taylorza 14:b4884a31069e 22
taylorza 9:34008d8b1cdf 23 }
taylorza 9:34008d8b1cdf 24
taylorza 9:34008d8b1cdf 25 void Scene::restartScreen()
taylorza 9:34008d8b1cdf 26 {
taylorza 9:34008d8b1cdf 27 _objectsHeld = 0;
taylorza 9:34008d8b1cdf 28 Game::Surface.clearScreen();
taylorza 9:34008d8b1cdf 29 drawMap();
taylorza 9:34008d8b1cdf 30 }
taylorza 9:34008d8b1cdf 31
taylorza 9:34008d8b1cdf 32 void Scene::update()
taylorza 9:34008d8b1cdf 33 {
taylorza 9:34008d8b1cdf 34 for (int i = 0; i < MAX_GAMEOBJECTS; ++i)
taylorza 9:34008d8b1cdf 35 {
taylorza 9:34008d8b1cdf 36 GameObject *o = _gameObjects[i];
taylorza 9:34008d8b1cdf 37 if (o != NULL) o->update();
taylorza 9:34008d8b1cdf 38 }
taylorza 9:34008d8b1cdf 39 }
taylorza 9:34008d8b1cdf 40
taylorza 9:34008d8b1cdf 41 void Scene::draw()
taylorza 9:34008d8b1cdf 42 {
taylorza 9:34008d8b1cdf 43 for (int i = 0; i < MAX_GAMEOBJECTS; ++i)
taylorza 9:34008d8b1cdf 44 {
taylorza 9:34008d8b1cdf 45 GameObject *o = _gameObjects[i];
taylorza 9:34008d8b1cdf 46 if (o != NULL) o->draw();
taylorza 9:34008d8b1cdf 47 }
taylorza 9:34008d8b1cdf 48 }
taylorza 9:34008d8b1cdf 49
taylorza 9:34008d8b1cdf 50 void Scene::setPosition(uint8_t x, uint8_t y)
taylorza 9:34008d8b1cdf 51 {
taylorza 9:34008d8b1cdf 52 if (x != _x || y != _y)
taylorza 9:34008d8b1cdf 53 {
taylorza 9:34008d8b1cdf 54 _x = x;
taylorza 9:34008d8b1cdf 55 _y = y;
taylorza 9:34008d8b1cdf 56 drawMap();
taylorza 9:34008d8b1cdf 57 }
taylorza 9:34008d8b1cdf 58 }
taylorza 9:34008d8b1cdf 59
taylorza 9:34008d8b1cdf 60 void Scene::setMap(const uint8_t *map, uint8_t xCells, uint8_t yCells, const Block *blocks, Sprite *sprites)
taylorza 9:34008d8b1cdf 61 {
taylorza 9:34008d8b1cdf 62 _map = map;
taylorza 9:34008d8b1cdf 63 _xCells = xCells;
taylorza 9:34008d8b1cdf 64 _yCells = yCells;
taylorza 9:34008d8b1cdf 65 _blocks = blocks;
taylorza 9:34008d8b1cdf 66 _sprites = sprites;
taylorza 9:34008d8b1cdf 67 }
taylorza 9:34008d8b1cdf 68
taylorza 9:34008d8b1cdf 69 void Scene::addGameObject(GameObject *gameObject)
taylorza 9:34008d8b1cdf 70 {
taylorza 9:34008d8b1cdf 71 for (int i = 0; i < MAX_GAMEOBJECTS; ++i)
taylorza 9:34008d8b1cdf 72 {
taylorza 9:34008d8b1cdf 73 if (_gameObjects[i] == NULL)
taylorza 9:34008d8b1cdf 74 {
taylorza 9:34008d8b1cdf 75 _gameObjects[i] = gameObject;
taylorza 9:34008d8b1cdf 76 gameObject->setScene(this);
taylorza 9:34008d8b1cdf 77 break;
taylorza 9:34008d8b1cdf 78 }
taylorza 9:34008d8b1cdf 79 }
taylorza 9:34008d8b1cdf 80 }
taylorza 9:34008d8b1cdf 81
taylorza 9:34008d8b1cdf 82 void Scene::removeGameObject(GameObject *gameObject)
taylorza 9:34008d8b1cdf 83 {
taylorza 9:34008d8b1cdf 84 for (int i = 0; i < MAX_GAMEOBJECTS; ++i)
taylorza 9:34008d8b1cdf 85 {
taylorza 9:34008d8b1cdf 86 if (_gameObjects[i] == gameObject)
taylorza 9:34008d8b1cdf 87 {
taylorza 9:34008d8b1cdf 88 gameObject->setScene(NULL);
taylorza 9:34008d8b1cdf 89 _gameObjects[i] = NULL;
taylorza 9:34008d8b1cdf 90 break;
taylorza 9:34008d8b1cdf 91 }
taylorza 9:34008d8b1cdf 92 }
taylorza 9:34008d8b1cdf 93 }
taylorza 9:34008d8b1cdf 94
taylorza 9:34008d8b1cdf 95 const GameObject* Scene::detectCollision(GameObject *primary)
taylorza 9:34008d8b1cdf 96 {
taylorza 9:34008d8b1cdf 97 for (int i = 0; i < MAX_GAMEOBJECTS; ++i)
taylorza 9:34008d8b1cdf 98 {
taylorza 9:34008d8b1cdf 99 GameObject *other = _gameObjects[i];
taylorza 9:34008d8b1cdf 100 if (other != NULL && other != primary)
taylorza 9:34008d8b1cdf 101 {
taylorza 9:34008d8b1cdf 102 if (detectCollision(primary, other))
taylorza 9:34008d8b1cdf 103 {
taylorza 9:34008d8b1cdf 104 return other;
taylorza 9:34008d8b1cdf 105 }
taylorza 9:34008d8b1cdf 106 }
taylorza 9:34008d8b1cdf 107 }
taylorza 9:34008d8b1cdf 108 return NULL;
taylorza 9:34008d8b1cdf 109 }
taylorza 9:34008d8b1cdf 110
taylorza 9:34008d8b1cdf 111 const Block* Scene::detectBlock(GameObject *primary)
taylorza 9:34008d8b1cdf 112 {
taylorza 9:34008d8b1cdf 113 Point &position = primary->getPosition();
taylorza 9:34008d8b1cdf 114 uint8_t cellX = position.X / 8;
taylorza 9:34008d8b1cdf 115 uint8_t cellY = position.Y / 8;
taylorza 9:34008d8b1cdf 116
taylorza 9:34008d8b1cdf 117 int my = cellY < _yCells ? 2 : 1;
taylorza 9:34008d8b1cdf 118 int mx = cellX < _xCells ? 2 : 1;
taylorza 9:34008d8b1cdf 119
taylorza 9:34008d8b1cdf 120 int offset = (cellY * _xCells) + cellX;
taylorza 9:34008d8b1cdf 121 for (int y = 0; y < my; ++y, ++cellY)
taylorza 9:34008d8b1cdf 122 {
taylorza 9:34008d8b1cdf 123 for (int x = 0; x < mx; ++x, ++cellX)
taylorza 9:34008d8b1cdf 124 {
taylorza 9:34008d8b1cdf 125 uint8_t blockId = _map[offset++];
taylorza 9:34008d8b1cdf 126 const Block &block = _blocks[blockId];
taylorza 9:34008d8b1cdf 127 switch(block.getType())
taylorza 9:34008d8b1cdf 128 {
taylorza 9:34008d8b1cdf 129 case Block::Deadly : return &block;
taylorza 9:34008d8b1cdf 130 case Block::Pickup : return !isHeld(cellX, cellY) ? &block : NULL;
taylorza 9:34008d8b1cdf 131 }
taylorza 9:34008d8b1cdf 132 }
taylorza 9:34008d8b1cdf 133 offset += _xCells - mx;
taylorza 9:34008d8b1cdf 134 }
taylorza 9:34008d8b1cdf 135 return NULL;
taylorza 9:34008d8b1cdf 136 }
taylorza 9:34008d8b1cdf 137
taylorza 9:34008d8b1cdf 138 #pragma push
taylorza 9:34008d8b1cdf 139 //#pragma diag_suppress 4017
taylorza 9:34008d8b1cdf 140 bool Scene::detectCollision(GameObject *o1, GameObject *o2)
taylorza 9:34008d8b1cdf 141 {
taylorza 9:34008d8b1cdf 142 Rect r1 = o1->getCollisionRect();
taylorza 9:34008d8b1cdf 143 Rect r2 = o2->getCollisionRect();
taylorza 9:34008d8b1cdf 144
taylorza 9:34008d8b1cdf 145 return r1.left < r2.right &&
taylorza 9:34008d8b1cdf 146 r2.left < r1.right &&
taylorza 9:34008d8b1cdf 147 r1.top < r2.bottom &&
taylorza 9:34008d8b1cdf 148 r2.top < r1.bottom;
taylorza 9:34008d8b1cdf 149 }
taylorza 9:34008d8b1cdf 150 #pragma pop
taylorza 9:34008d8b1cdf 151
taylorza 9:34008d8b1cdf 152
taylorza 9:34008d8b1cdf 153 void Scene::drawMap()
taylorza 9:34008d8b1cdf 154 {
taylorza 9:34008d8b1cdf 155 if (_map == NULL) return;
taylorza 9:34008d8b1cdf 156
taylorza 9:34008d8b1cdf 157 int yOffset = 0;
taylorza 9:34008d8b1cdf 158
taylorza 9:34008d8b1cdf 159 for(int y = 0; y < _yCells; ++y, yOffset += _xCells)
taylorza 9:34008d8b1cdf 160 {
taylorza 9:34008d8b1cdf 161 for (int x = 0; x < _xCells; ++x)
taylorza 9:34008d8b1cdf 162 {
taylorza 9:34008d8b1cdf 163 uint8_t blockId = _map[yOffset + x];
taylorza 9:34008d8b1cdf 164 if (blockId != 0)
taylorza 9:34008d8b1cdf 165 {
taylorza 9:34008d8b1cdf 166 drawBlock(blockId, x * 8, y * 8);
taylorza 9:34008d8b1cdf 167 }
taylorza 9:34008d8b1cdf 168 }
taylorza 9:34008d8b1cdf 169 }
taylorza 9:34008d8b1cdf 170 }
taylorza 9:34008d8b1cdf 171
taylorza 9:34008d8b1cdf 172 bool Scene::canEnter(uint16_t x, uint16_t y)
taylorza 9:34008d8b1cdf 173 {
taylorza 9:34008d8b1cdf 174 uint8_t cellX = x / 8;
taylorza 9:34008d8b1cdf 175 uint8_t cellY = y / 8;
taylorza 9:34008d8b1cdf 176 uint8_t blockId = _map[(cellY * _xCells) + cellX];
taylorza 9:34008d8b1cdf 177 const Block &block = _blocks[blockId];
taylorza 9:34008d8b1cdf 178 Block::Type type = block.getType();
taylorza 9:34008d8b1cdf 179
taylorza 9:34008d8b1cdf 180 switch(type)
taylorza 9:34008d8b1cdf 181 {
taylorza 9:34008d8b1cdf 182 case Block::Background : return true;
taylorza 9:34008d8b1cdf 183 case Block::Platform : return true;
taylorza 9:34008d8b1cdf 184 case Block::Solid : return false;
taylorza 9:34008d8b1cdf 185 case Block::Ladder : return true;
taylorza 9:34008d8b1cdf 186 }
taylorza 9:34008d8b1cdf 187
taylorza 9:34008d8b1cdf 188 return true;
taylorza 9:34008d8b1cdf 189 }
taylorza 9:34008d8b1cdf 190
taylorza 9:34008d8b1cdf 191 bool Scene::canEnterFromTop(uint16_t x, uint16_t y)
taylorza 9:34008d8b1cdf 192 {
taylorza 9:34008d8b1cdf 193 uint8_t cellX = x / 8;
taylorza 9:34008d8b1cdf 194 uint8_t cellY = y / 8;
taylorza 9:34008d8b1cdf 195 uint8_t blockId = _map[(cellY * _xCells) + cellX];
taylorza 9:34008d8b1cdf 196 const Block &block = _blocks[blockId];
taylorza 9:34008d8b1cdf 197 Block::Type type = block.getType();
taylorza 9:34008d8b1cdf 198
taylorza 9:34008d8b1cdf 199 switch(type)
taylorza 9:34008d8b1cdf 200 {
taylorza 9:34008d8b1cdf 201 case Block::Background : return true;
taylorza 9:34008d8b1cdf 202 case Block::Platform : return false;
taylorza 9:34008d8b1cdf 203 case Block::Solid : return false;
taylorza 9:34008d8b1cdf 204 case Block::Ladder : return true;
taylorza 9:34008d8b1cdf 205 }
taylorza 9:34008d8b1cdf 206
taylorza 9:34008d8b1cdf 207 return true;
taylorza 9:34008d8b1cdf 208 }
taylorza 9:34008d8b1cdf 209
taylorza 9:34008d8b1cdf 210 const Block& Scene::getBlock(uint16_t x, uint16_t y)
taylorza 9:34008d8b1cdf 211 {
taylorza 9:34008d8b1cdf 212 uint8_t cellX = x / 8;
taylorza 9:34008d8b1cdf 213 uint8_t cellY = y / 8;
taylorza 9:34008d8b1cdf 214 uint8_t blockId = _map[(cellY * _xCells) + cellX];
taylorza 9:34008d8b1cdf 215 return _blocks[blockId];
taylorza 9:34008d8b1cdf 216 }
taylorza 9:34008d8b1cdf 217
taylorza 9:34008d8b1cdf 218 void Scene::animate(uint8_t spriteId)
taylorza 9:34008d8b1cdf 219 {
taylorza 9:34008d8b1cdf 220 Sprite &sprite = _sprites[spriteId];
taylorza 9:34008d8b1cdf 221 sprite.animate();
taylorza 9:34008d8b1cdf 222 }
taylorza 9:34008d8b1cdf 223
taylorza 9:34008d8b1cdf 224 bool Scene::pickupObject(uint8_t cellX, uint8_t cellY)
taylorza 9:34008d8b1cdf 225 {
taylorza 9:34008d8b1cdf 226 if (_objectsHeld == MAX_PICKUPS) return false;
taylorza 9:34008d8b1cdf 227 if (getBlock(cellX * 8, cellY * 8).getType() != Block::Pickup) return false;
taylorza 9:34008d8b1cdf 228
taylorza 9:34008d8b1cdf 229 if (isHeld(cellX, cellY)) return false;
taylorza 9:34008d8b1cdf 230
taylorza 9:34008d8b1cdf 231 _pickups[_objectsHeld].X = cellX;
taylorza 9:34008d8b1cdf 232 _pickups[_objectsHeld].Y = cellY;
taylorza 9:34008d8b1cdf 233 ++_objectsHeld;
taylorza 9:34008d8b1cdf 234 drawBlock(0, cellX * 8, cellY * 8);
taylorza 9:34008d8b1cdf 235 return true;
taylorza 9:34008d8b1cdf 236 }
taylorza 9:34008d8b1cdf 237
taylorza 9:34008d8b1cdf 238 bool Scene::isHeld(uint8_t cellX, uint8_t cellY)
taylorza 9:34008d8b1cdf 239 {
taylorza 14:b4884a31069e 240 Point pt(cellX, cellY);
taylorza 9:34008d8b1cdf 241 for (int i = 0; i < _objectsHeld; ++i)
taylorza 9:34008d8b1cdf 242 {
taylorza 9:34008d8b1cdf 243 if (pt == _pickups[i]) return true;
taylorza 9:34008d8b1cdf 244 }
taylorza 9:34008d8b1cdf 245 return false;
taylorza 9:34008d8b1cdf 246 }
taylorza 9:34008d8b1cdf 247
taylorza 9:34008d8b1cdf 248 void Scene::compose(const Block &block, uint8_t x, uint8_t y)
taylorza 9:34008d8b1cdf 249 {
taylorza 9:34008d8b1cdf 250 uint8_t fc = block.getForegroundColor();
taylorza 9:34008d8b1cdf 251 uint8_t fch = (fc << 4) & 0xf0;
taylorza 9:34008d8b1cdf 252 uint8_t fcl = fc & 0x0f;
taylorza 9:34008d8b1cdf 253
taylorza 9:34008d8b1cdf 254 uint8_t bc = block.getBackgroundColor();
taylorza 9:34008d8b1cdf 255 uint8_t bch = (bc << 4) & 0xf0;
taylorza 9:34008d8b1cdf 256 uint8_t bcl = bc & 0x0f;
taylorza 9:34008d8b1cdf 257
taylorza 9:34008d8b1cdf 258 uint8_t *bitmap = Scene::BitmapBuffer.getBitmapData();
taylorza 9:34008d8b1cdf 259 int offsetRow = (y * Scene::BitmapBuffer.getStride()) + (x >> 1);
taylorza 9:34008d8b1cdf 260
taylorza 9:34008d8b1cdf 261 for (int iy = 0; iy < 8; ++iy, offsetRow += Scene::BitmapBuffer.getStride())
taylorza 9:34008d8b1cdf 262 {
taylorza 9:34008d8b1cdf 263 int offset = offsetRow;
taylorza 9:34008d8b1cdf 264 uint8_t b = *block.getBits(iy);
taylorza 9:34008d8b1cdf 265 bool highNibble = ((x & 0x01) == 0);
taylorza 9:34008d8b1cdf 266 for(int c = 0; c < 8; ++c, b <<= 1)
taylorza 9:34008d8b1cdf 267 {
taylorza 9:34008d8b1cdf 268 if (b & 0x80)
taylorza 9:34008d8b1cdf 269 {
taylorza 9:34008d8b1cdf 270 if (highNibble) bitmap[offset] = ((bitmap[offset] & 0x0f) | fch);
taylorza 9:34008d8b1cdf 271 else
taylorza 9:34008d8b1cdf 272 {
taylorza 9:34008d8b1cdf 273 bitmap[offset] = ((bitmap[offset] & 0xf0) | fcl);
taylorza 9:34008d8b1cdf 274 ++offset;
taylorza 9:34008d8b1cdf 275 }
taylorza 9:34008d8b1cdf 276 }
taylorza 9:34008d8b1cdf 277 else if (block.getType() == Block::Foreground)
taylorza 9:34008d8b1cdf 278 {
taylorza 9:34008d8b1cdf 279 if (!highNibble) ++offset;
taylorza 9:34008d8b1cdf 280 }
taylorza 9:34008d8b1cdf 281 else
taylorza 9:34008d8b1cdf 282 {
taylorza 9:34008d8b1cdf 283 if (highNibble) bitmap[offset] = ((bitmap[offset] & 0x0f) | bch);
taylorza 9:34008d8b1cdf 284 else
taylorza 9:34008d8b1cdf 285 {
taylorza 9:34008d8b1cdf 286 bitmap[offset] = ((bitmap[offset] & 0xf0) | bcl);
taylorza 9:34008d8b1cdf 287 ++offset;
taylorza 9:34008d8b1cdf 288 }
taylorza 9:34008d8b1cdf 289 }
taylorza 9:34008d8b1cdf 290 highNibble = !highNibble;
taylorza 9:34008d8b1cdf 291 }
taylorza 9:34008d8b1cdf 292 }
taylorza 9:34008d8b1cdf 293 }
taylorza 9:34008d8b1cdf 294
taylorza 9:34008d8b1cdf 295 void Scene::compose(const Sprite &sprite, uint8_t x, uint8_t y, bool flip)
taylorza 9:34008d8b1cdf 296 {
taylorza 9:34008d8b1cdf 297 uint8_t fc = sprite.getForegroundColor();
taylorza 9:34008d8b1cdf 298 uint8_t fch = (fc << 4) & 0xf0;
taylorza 9:34008d8b1cdf 299 uint8_t fcl = fc & 0x0f;
taylorza 9:34008d8b1cdf 300
taylorza 9:34008d8b1cdf 301 uint8_t *bitmap = Scene::BitmapBuffer.getBitmapData();
taylorza 9:34008d8b1cdf 302 int offsetRow = (y * Scene::BitmapBuffer.getStride()) + (x >> 1);
taylorza 9:34008d8b1cdf 303
taylorza 9:34008d8b1cdf 304 if (!flip)
taylorza 9:34008d8b1cdf 305 {
taylorza 9:34008d8b1cdf 306 for (int iy = 0; iy < 16; ++iy, offsetRow += Scene::BitmapBuffer.getStride())
taylorza 9:34008d8b1cdf 307 {
taylorza 9:34008d8b1cdf 308 int offset = offsetRow;
taylorza 9:34008d8b1cdf 309 uint8_t *p = sprite.getBits(iy);
taylorza 9:34008d8b1cdf 310 bool highNibble = ((x & 0x01) == 0);
taylorza 9:34008d8b1cdf 311 for (int ix = 0; ix < 2; ++ix)
taylorza 9:34008d8b1cdf 312 {
taylorza 9:34008d8b1cdf 313 uint8_t b = *p++;
taylorza 9:34008d8b1cdf 314 for(int c = 0; c < 8; ++c, b <<= 1)
taylorza 9:34008d8b1cdf 315 {
taylorza 9:34008d8b1cdf 316 if (b & 0x80)
taylorza 9:34008d8b1cdf 317 {
taylorza 9:34008d8b1cdf 318 if (highNibble) bitmap[offset] = ((bitmap[offset] & 0x0f) | fch);
taylorza 9:34008d8b1cdf 319 else
taylorza 9:34008d8b1cdf 320 {
taylorza 9:34008d8b1cdf 321 bitmap[offset] = ((bitmap[offset] & 0xf0) | fcl);
taylorza 9:34008d8b1cdf 322 offset++;
taylorza 9:34008d8b1cdf 323 }
taylorza 9:34008d8b1cdf 324 }
taylorza 9:34008d8b1cdf 325 else if (!highNibble)
taylorza 9:34008d8b1cdf 326 {
taylorza 9:34008d8b1cdf 327 offset++;
taylorza 9:34008d8b1cdf 328 }
taylorza 9:34008d8b1cdf 329 highNibble = !highNibble;
taylorza 9:34008d8b1cdf 330 }
taylorza 9:34008d8b1cdf 331 }
taylorza 9:34008d8b1cdf 332 }
taylorza 9:34008d8b1cdf 333 }
taylorza 9:34008d8b1cdf 334 else
taylorza 9:34008d8b1cdf 335 {
taylorza 9:34008d8b1cdf 336 for (int iy = 0; iy < 16; ++iy, offsetRow += Scene::BitmapBuffer.getStride())
taylorza 9:34008d8b1cdf 337 {
taylorza 9:34008d8b1cdf 338 int offset = offsetRow;
taylorza 9:34008d8b1cdf 339 uint8_t *p = sprite.getBits(iy) + 1;
taylorza 9:34008d8b1cdf 340 bool highNibble = ((x & 0x01) == 0);
taylorza 9:34008d8b1cdf 341 for (int ix = 0; ix < 2; ++ix)
taylorza 9:34008d8b1cdf 342 {
taylorza 9:34008d8b1cdf 343 uint8_t b = *p--;
taylorza 9:34008d8b1cdf 344 for(int c = 0; c < 8; ++c, b >>= 1)
taylorza 9:34008d8b1cdf 345 {
taylorza 9:34008d8b1cdf 346 if (b & 0x01)
taylorza 9:34008d8b1cdf 347 {
taylorza 9:34008d8b1cdf 348 if (highNibble) bitmap[offset] = ((bitmap[offset] & 0x0f) | fch);
taylorza 9:34008d8b1cdf 349 else
taylorza 9:34008d8b1cdf 350 {
taylorza 9:34008d8b1cdf 351 bitmap[offset] = ((bitmap[offset] & 0xf0) | fcl);
taylorza 9:34008d8b1cdf 352 offset++;
taylorza 9:34008d8b1cdf 353 }
taylorza 9:34008d8b1cdf 354 }
taylorza 9:34008d8b1cdf 355 else if (!highNibble)
taylorza 9:34008d8b1cdf 356 {
taylorza 9:34008d8b1cdf 357 offset++;
taylorza 9:34008d8b1cdf 358 }
taylorza 9:34008d8b1cdf 359 highNibble = !highNibble;
taylorza 9:34008d8b1cdf 360 }
taylorza 9:34008d8b1cdf 361 }
taylorza 9:34008d8b1cdf 362 }
taylorza 9:34008d8b1cdf 363 }
taylorza 9:34008d8b1cdf 364 }
taylorza 9:34008d8b1cdf 365
taylorza 9:34008d8b1cdf 366 void Scene::drawBlock(uint8_t blockId, int16_t x, int16_t y)
taylorza 9:34008d8b1cdf 367 {
taylorza 9:34008d8b1cdf 368 const Block &block = _blocks[blockId];
taylorza 9:34008d8b1cdf 369 uint8_t fc = block.getForegroundColor();
taylorza 9:34008d8b1cdf 370 uint8_t fch = (fc << 4) & 0xf0;
taylorza 9:34008d8b1cdf 371 uint8_t fcl = fc & 0x0f;
taylorza 9:34008d8b1cdf 372
taylorza 9:34008d8b1cdf 373 uint8_t bc = block.getBackgroundColor();
taylorza 9:34008d8b1cdf 374 uint8_t bch = (bc << 4) & 0xf0;
taylorza 9:34008d8b1cdf 375 uint8_t bcl = bc & 0x0f;
taylorza 9:34008d8b1cdf 376
taylorza 9:34008d8b1cdf 377 uint8_t *bitmap = Scene::BitmapBuffer.getBitmapData();
taylorza 9:34008d8b1cdf 378
taylorza 9:34008d8b1cdf 379 int offset = 0;
taylorza 9:34008d8b1cdf 380 for (int iy = 0; iy < 8; ++iy)
taylorza 9:34008d8b1cdf 381 {
taylorza 9:34008d8b1cdf 382 uint8_t b = *block.getBits(iy);
taylorza 9:34008d8b1cdf 383
taylorza 9:34008d8b1cdf 384 bitmap[offset] = b & 0x80 ? ((bitmap[offset] & 0x0f) | fch) : ((bitmap[offset] & 0x0f) | bch);
taylorza 9:34008d8b1cdf 385 bitmap[offset] = b & 0x40 ? ((bitmap[offset] & 0xf0) | fcl) : ((bitmap[offset] & 0xf0) | bcl);
taylorza 9:34008d8b1cdf 386 ++offset;
taylorza 9:34008d8b1cdf 387
taylorza 9:34008d8b1cdf 388 bitmap[offset] = b & 0x20 ? ((bitmap[offset] & 0x0f) | fch) : ((bitmap[offset] & 0x0f) | bch);
taylorza 9:34008d8b1cdf 389 bitmap[offset] = b & 0x10 ? ((bitmap[offset] & 0xf0) | fcl) : ((bitmap[offset] & 0xf0) | bcl);
taylorza 9:34008d8b1cdf 390 ++offset;
taylorza 9:34008d8b1cdf 391
taylorza 9:34008d8b1cdf 392 bitmap[offset] = b & 0x08 ? ((bitmap[offset] & 0x0f) | fch) : ((bitmap[offset] & 0x0f) | bch);
taylorza 9:34008d8b1cdf 393 bitmap[offset] = b & 0x04 ? ((bitmap[offset] & 0xf0) | fcl) : ((bitmap[offset] & 0xf0) | bcl);
taylorza 9:34008d8b1cdf 394 ++offset;
taylorza 9:34008d8b1cdf 395
taylorza 9:34008d8b1cdf 396 bitmap[offset] = b & 0x02 ? ((bitmap[offset] & 0x0f) | fch) : ((bitmap[offset] & 0x0f) | bch);
taylorza 9:34008d8b1cdf 397 bitmap[offset] = b & 0x01 ? ((bitmap[offset] & 0xf0) | fcl) : ((bitmap[offset] & 0xf0) | bcl);
taylorza 9:34008d8b1cdf 398 //++offset;
taylorza 9:34008d8b1cdf 399 offset += Scene::BitmapBuffer.getStride() - 3;
taylorza 9:34008d8b1cdf 400 }
taylorza 9:34008d8b1cdf 401
taylorza 9:34008d8b1cdf 402 Game::Surface.drawBitmap(_x + x, _y + y, Scene::BitmapBuffer, 0, 0, 8, 8);
taylorza 9:34008d8b1cdf 403 }
taylorza 9:34008d8b1cdf 404
taylorza 9:34008d8b1cdf 405 void Scene::drawSprite(uint8_t spriteId, int16_t x, int16_t y, int16_t dx, int16_t dy, bool flip)
taylorza 9:34008d8b1cdf 406 {
taylorza 9:34008d8b1cdf 407 uint8_t cellX = x / 8;
taylorza 9:34008d8b1cdf 408 uint8_t cellY = y / 8;
taylorza 9:34008d8b1cdf 409 uint8_t rx = x % 8;
taylorza 9:34008d8b1cdf 410 uint8_t ry = y % 8;
taylorza 9:34008d8b1cdf 411
taylorza 9:34008d8b1cdf 412 if (rx == 0 && dx > 0 && cellX > 0) { --cellX; rx += 8; }
taylorza 9:34008d8b1cdf 413 if (ry == 0 && dy > 0 && cellY > 0) { --cellY; ry += 8; }
taylorza 9:34008d8b1cdf 414
taylorza 9:34008d8b1cdf 415 Scene::BitmapBuffer.clear();
taylorza 9:34008d8b1cdf 416
taylorza 9:34008d8b1cdf 417 // Compose blocks, except foreground blocks
taylorza 9:34008d8b1cdf 418 for (int cy = 0; cy < 3; ++cy)
taylorza 9:34008d8b1cdf 419 {
taylorza 9:34008d8b1cdf 420 int yOffset = (cellY + cy) * _xCells;
taylorza 9:34008d8b1cdf 421 for (int cx = 0; cx < 3; ++cx)
taylorza 9:34008d8b1cdf 422 {
taylorza 9:34008d8b1cdf 423 uint8_t blockId = _map[yOffset + cellX + cx];
taylorza 9:34008d8b1cdf 424 const Block &block = _blocks[blockId];
taylorza 9:34008d8b1cdf 425
taylorza 9:34008d8b1cdf 426 if (blockId != 0 && block.getType() != Block::Foreground)
taylorza 9:34008d8b1cdf 427 {
taylorza 9:34008d8b1cdf 428 if (!(block.getType() == Block::Pickup && isHeld(cellX + cx, cellY + cy)))
taylorza 9:34008d8b1cdf 429 {
taylorza 9:34008d8b1cdf 430 compose(block, cx * 8, cy * 8);
taylorza 9:34008d8b1cdf 431 }
taylorza 9:34008d8b1cdf 432 }
taylorza 9:34008d8b1cdf 433 }
taylorza 9:34008d8b1cdf 434 }
taylorza 9:34008d8b1cdf 435
taylorza 9:34008d8b1cdf 436 // Compose sprite
taylorza 9:34008d8b1cdf 437 const Sprite &sprite = _sprites[spriteId];
taylorza 9:34008d8b1cdf 438 compose(sprite, rx, ry, flip);
taylorza 9:34008d8b1cdf 439
taylorza 9:34008d8b1cdf 440 // Compose foreground blocks
taylorza 9:34008d8b1cdf 441 for (int cy = 0; cy < 3; ++cy)
taylorza 9:34008d8b1cdf 442 {
taylorza 9:34008d8b1cdf 443 int yOffset = (cellY + cy) * _xCells;
taylorza 9:34008d8b1cdf 444 for (int cx = 0; cx < 3; ++cx)
taylorza 9:34008d8b1cdf 445 {
taylorza 9:34008d8b1cdf 446 uint8_t blockId = _map[yOffset + cellX + cx];
taylorza 9:34008d8b1cdf 447 const Block &block = _blocks[blockId];
taylorza 9:34008d8b1cdf 448 if (blockId != 0 && block.getType() == Block::Foreground)
taylorza 9:34008d8b1cdf 449 {
taylorza 9:34008d8b1cdf 450 compose(block, cx * 8, cy * 8);
taylorza 9:34008d8b1cdf 451 }
taylorza 9:34008d8b1cdf 452 }
taylorza 9:34008d8b1cdf 453 }
taylorza 9:34008d8b1cdf 454
taylorza 9:34008d8b1cdf 455 // Render the composed image
taylorza 9:34008d8b1cdf 456 //Screen.drawBitmap(cellX * 8, cellY * 8, Scene::BitmapBuffer, 0, 0, 24, 24);
taylorza 9:34008d8b1cdf 457
taylorza 9:34008d8b1cdf 458 Game::Surface.drawBitmap(
taylorza 9:34008d8b1cdf 459 _x + (dx > 0 ? x - dx : x),
taylorza 9:34008d8b1cdf 460 _y + (dy > 0 ? y - dy : y),
taylorza 9:34008d8b1cdf 461 Scene::BitmapBuffer,
taylorza 9:34008d8b1cdf 462 dx > 0 ? rx - dx : rx,
taylorza 9:34008d8b1cdf 463 dy > 0 ? ry - dy : ry,
taylorza 9:34008d8b1cdf 464 16 + abs(dx), 16 + abs(dy));
taylorza 9:34008d8b1cdf 465
taylorza 9:34008d8b1cdf 466 }