Chris Taylor / Mbed 2 deprecated RETRO-CaveDweller Featured

Dependencies:   mbed

Committer:
taylorza
Date:
Mon Feb 16 02:35:14 2015 +0000
Revision:
14:b4884a31069e
Parent:
9:34008d8b1cdf
Cleaned up some warnings and fixed memory issue related to incremental builds

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 }