Race around the city collecting the flags while avoiding those that stand in the way of your mission. Make no mistake you will need to be quick to outwit your opponents, they are smart and will try to box you in. I wrote this game to prove that writing a game with scrolling scenery is possible even with the limited 6kB of RAM available. I had to compromise sound effects for features, I wanted multiple opponents, I wanted to be able to drop smoke bombs to trap the opponents but all this required memory so the sound effects had to take a back seat.

Dependencies:   mbed

LCD_ST7735/Bitmap2bpp.cpp

Committer:
taylorza
Date:
2015-02-01
Revision:
1:1b8125937f28
Parent:
0:d85c449aca6d

File content as of revision 1:1b8125937f28:

#include "mbed.h"
#include "Bitmap2bpp.h"
#include "Base.h"

Bitmap2bpp::Bitmap2bpp(const uint8_t *bitmap) :
    _width(*(bitmap + 1) << 8 | *bitmap),
    _height(*(bitmap + 3) << 8 | *(bitmap + 2)),
    _stride((_width >> 2) + ((_width & 0x03) > 0 ? 1 : 0)),
    _pBitmapData((uint8_t*)(bitmap + 4))
{
}

Bitmap2bpp::Bitmap2bpp(uint16_t width, uint16_t height) :
    _width(width), 
    _height(height),
    _stride((width >> 2) + ((width & 0x03) > 0 ? 1 : 0)),
    _pBitmapData(new uint8_t[_stride * height])    
{
 
}

Bitmap2bpp::~Bitmap2bpp()
{
    if (_pBitmapData != NULL)
    {
        delete []_pBitmapData;
        _pBitmapData = NULL;
    }
}

void Bitmap2bpp::clear()
{
    memset(_pBitmapData, 0, _stride * _height);
}

void Bitmap2bpp::setPixel(int16_t x, int16_t y, uint16_t color)
{
    if (x < 0 || x >= _width || y < 0 || y >= _height) return;
    
    int shift = 6 - ((x % 4) << 1);
    uint8_t mask = ~(0x03 << shift);
    uint8_t pixelColor = (color  & 0x03) << shift;
    uint8_t *p = _pBitmapData + ((y * _stride) + (x / 4));
    
    *p &= mask; 
    *p |= pixelColor;
}

void Bitmap2bpp::fastHLine(int16_t x1, int16_t x2, int16_t y, uint16_t color)
{
    for (int x = x1; x <= x2; ++x)
    {
        setPixel(x, y, color);
    }
}

void Bitmap2bpp::fastVLine(int16_t y1, int16_t y2, int16_t x, uint16_t color)
{
    for (int y = y1; y <= y2; ++y)
    {
        setPixel(x, y, color);
    }
}
void Bitmap2bpp::drawBitmap(int16_t x, int16_t y, Bitmap2bpp &bmp, uint16_t srcX, uint16_t srcY, uint16_t srcWidth, uint16_t srcHeight, bool transparent)
{
    // Clip if out of bitmap    
    if ((x >= _width) || (x + srcWidth < 0) || 
        (y >= _height) || (y + srcHeight < 0))
    {
        return;
    }
    
    // Clip X
    if (x < 0) { srcX += -x; srcWidth += x; x = 0; }
    if (x + srcWidth >= _width) { srcWidth += _width - (x + srcWidth); }
    
    // Clip Y
    if (y  < 0) {srcY += -y; srcHeight += y; y = 0; }  
    if (y + srcHeight >= _height) { srcHeight += _height - (y + srcHeight); }
    
    int srcStartShift = 6 - ((srcX % 4) << 1);
    int dstStartShift = 6 - ((x % 4) << 1);
    
    int srcOffset = ((srcY * bmp.getStride()) + (srcX / 4));
    int dstOffset = ((y * getStride()) + (x / 4));
    for (int r = 0; r < srcHeight; ++r)
    {        
        uint8_t *src = bmp.getBitmapData() + srcOffset;
        uint8_t *dst = getBitmapData() + dstOffset;
        
        uint8_t sb = *src;
        for (int c = 0, srcShift = srcStartShift, dstShift = dstStartShift; c < srcWidth; ++c, srcShift -= 2, dstShift -= 2)
        {
            if (srcShift < 0) 
            {
                srcShift = 6;
                sb = *++src;
            }
            
            if (dstShift < 0) 
            {
                dstShift = 6;
                ++dst;
            }
            
            uint8_t srcPixel = (sb >> srcShift) &0x3;
            if (transparent && srcPixel == 0) continue;
            
            uint8_t mask = ~(0x03 << dstShift);
            uint8_t pixelColor = srcPixel << dstShift;
            
            *dst &= mask; 
            *dst |= pixelColor;
        }
        
        srcOffset += bmp.getStride();
        dstOffset += getStride();
    }
}