Retro Invaders a space invaders clone by Chris Favreau. Written for the RetroMbuino development board from outrageouscircuits.com for the game programming contest.

Dependencies:   mbed

This is a space invaders clone written for the Retro Mbuino from outrageous circuits.

Development board: http://www.outrageouscircuits.com/shop/product/15 ).

The game itself is basic space invaders. Shoot them before they get to the bottom of the screen. It has a UFO saucer which you can shoot for extra points. You get 4 shields and each shield can be hit up to 4 times before it is gone. Hmm... as each level increases the speed of the invaders shots goes up. The invaders only speed up when there is less of them. You complete the level when you shoot all the invaders. The game ends when a) you run out of lives (you start with 3) or the invaders get to the bottom.

The LEDs turned out to be a pretty cool addition to the game. I wrote a class that blinks them and turns them on for a specified amount of time. They add a nice extra to the game. I use them on the intro screen and when the UFO is present.

The sound turned out to be really difficult for a few reasons. The biggest was that I had never written a sound engine before. The interrupt service routine working off the timer was the easier part. I also had a lot of trouble because there is no filter to filter out the PWM frequency to the speaker... so I had to run the PWM frequency way up there 30 kHz.

The graphics turned out to be a bit of a bear too. Thanks to Chris Taylor for his really great LCD API. I picked up a couple of frames per second from that. I had modified the DisplayN18 class for blitting a single line buffer to the LCD panel however his is a little faster for some reason? I used a different approach to doing the graphics (as I have very little experience with anything other than double buffered displays). I have a tile map and a list of sprites. Each tile/sprite is 1 bit 8x8. They could be bigger. I ran out of time. That much is not special. What is different from what I can tell is that I use a 1 line buffer that is 160 shorts long. The render function first adds the tile map data into the line buffer first. Then the sprites are added over the existing data. You can have a great deal of different sprites and maps going to the screen and just have to rewrite the LCD memory once per frame. After each line is composited, the line is then drawn to the LCD. Kind of like an Atari 2600. Each sprite/tile has a foreground and background color and can be different from the other tiles/sprites. There is one color reserved for Transparency.

There are 16 colors to choose from. I chose a palette based on the Macintosh OS 4.1 palette I found on WikiPedia. It is a very nice mix of colors.

I found a sprite editor called SpriteX ( https://code.google.com/p/spritesx-ed/ )... it works nicely except that the 16x16 sprites are in a weird format. Time limited me to 8x8 sprites. Oh well.

I used nokring to make the music. It makes RTTTL formatted ring tones which my sound api can play. Here is a useful site that has lots of arcade/video game ring tones with a link to nokring in the utilities page. http://arcadetones.emuunlim.com/files.htm

Other than all that stuff I used state machines to do most of the game logic. Please excuse the horrible coding as I tried to comment a lot of it however it is not very nice to look at. Lots of long functions...

Committer:
cfavreau
Date:
Tue Mar 03 04:26:01 2015 +0000
Revision:
0:c79e1f29f029
Retro Invaders by Chris Favreau for the RetroMbuino Platform - outrageouscircuits.com game programming contest.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cfavreau 0:c79e1f29f029 1 #include "DisplayN18.h"
cfavreau 0:c79e1f29f029 2
cfavreau 0:c79e1f29f029 3 DisplayN18::DisplayN18() : resetPin(P0_20), backlightPin(P0_19), rsPin(P0_7), csPin(P0_2), spi(P0_21, P0_22, P1_15) {
cfavreau 0:c79e1f29f029 4
cfavreau 0:c79e1f29f029 5 //buffer = new unsigned char[512];
cfavreau 0:c79e1f29f029 6 //memset(buffer, 0, 512);
cfavreau 0:c79e1f29f029 7 buffer = new unsigned char[320];
cfavreau 0:c79e1f29f029 8 memset(buffer, 0, 320);
cfavreau 0:c79e1f29f029 9
cfavreau 0:c79e1f29f029 10 this->resetPin.write(false);
cfavreau 0:c79e1f29f029 11 this->backlightPin.write(true);
cfavreau 0:c79e1f29f029 12 this->rsPin.write(false);
cfavreau 0:c79e1f29f029 13
cfavreau 0:c79e1f29f029 14 this->spi.format(8, 3);
cfavreau 0:c79e1f29f029 15 this->spi.frequency(15000000);
cfavreau 0:c79e1f29f029 16
cfavreau 0:c79e1f29f029 17 this->initialize();
cfavreau 0:c79e1f29f029 18 }
cfavreau 0:c79e1f29f029 19
cfavreau 0:c79e1f29f029 20 void DisplayN18::writeCommand(unsigned char command) {
cfavreau 0:c79e1f29f029 21 this->rsPin.write(false);
cfavreau 0:c79e1f29f029 22
cfavreau 0:c79e1f29f029 23 this->csPin.write(false);
cfavreau 0:c79e1f29f029 24
cfavreau 0:c79e1f29f029 25 this->spi.write(command);
cfavreau 0:c79e1f29f029 26
cfavreau 0:c79e1f29f029 27 this->csPin.write(true);
cfavreau 0:c79e1f29f029 28 }
cfavreau 0:c79e1f29f029 29
cfavreau 0:c79e1f29f029 30 void DisplayN18::writeData(unsigned char data) {
cfavreau 0:c79e1f29f029 31 this->writeData(&data, 1);
cfavreau 0:c79e1f29f029 32 }
cfavreau 0:c79e1f29f029 33
cfavreau 0:c79e1f29f029 34 void DisplayN18::writeData(const unsigned char* data, unsigned int length) {
cfavreau 0:c79e1f29f029 35 this->rsPin.write(true);
cfavreau 0:c79e1f29f029 36
cfavreau 0:c79e1f29f029 37 this->csPin.write(false);
cfavreau 0:c79e1f29f029 38
cfavreau 0:c79e1f29f029 39 for (unsigned int i = 0; i < length; i++)
cfavreau 0:c79e1f29f029 40 // Turbo Time! Use the Burst SPI FastWrite! (from Erik Olieman -> http://developer.mbed.org/users/Sissors/code/BurstSPI/)
cfavreau 0:c79e1f29f029 41 this->spi.fastWrite(data[i]);
cfavreau 0:c79e1f29f029 42 // this->spi.write(data[i]);
cfavreau 0:c79e1f29f029 43
cfavreau 0:c79e1f29f029 44 spi.clearRX();
cfavreau 0:c79e1f29f029 45
cfavreau 0:c79e1f29f029 46 this->csPin.write(true);
cfavreau 0:c79e1f29f029 47 }
cfavreau 0:c79e1f29f029 48
cfavreau 0:c79e1f29f029 49 void DisplayN18::reset() {
cfavreau 0:c79e1f29f029 50 this->resetPin.write(false);
cfavreau 0:c79e1f29f029 51 wait_ms(300);
cfavreau 0:c79e1f29f029 52
cfavreau 0:c79e1f29f029 53 this->resetPin.write(true);
cfavreau 0:c79e1f29f029 54 wait_ms(500);
cfavreau 0:c79e1f29f029 55 }
cfavreau 0:c79e1f29f029 56
cfavreau 0:c79e1f29f029 57 void DisplayN18::initialize() {
cfavreau 0:c79e1f29f029 58 this->reset();
cfavreau 0:c79e1f29f029 59
cfavreau 0:c79e1f29f029 60 // Sleep Out - Turn sleep mode off
cfavreau 0:c79e1f29f029 61 this->writeCommand(0x11);
cfavreau 0:c79e1f29f029 62
cfavreau 0:c79e1f29f029 63 wait_ms(120);
cfavreau 0:c79e1f29f029 64
cfavreau 0:c79e1f29f029 65 // SETPOWER
cfavreau 0:c79e1f29f029 66 this->writeCommand(0xB1);
cfavreau 0:c79e1f29f029 67 this->writeData(0x01); this->writeData(0x2C); this->writeData(0x2D);
cfavreau 0:c79e1f29f029 68 // SETDISP
cfavreau 0:c79e1f29f029 69 this->writeCommand(0xB2);
cfavreau 0:c79e1f29f029 70 this->writeData(0x01); this->writeData(0x2C); this->writeData(0x2D);
cfavreau 0:c79e1f29f029 71 // SETLUT
cfavreau 0:c79e1f29f029 72 this->writeCommand(0xB3);
cfavreau 0:c79e1f29f029 73 this->writeData(0x01); this->writeData(0x2C); this->writeData(0x2D);
cfavreau 0:c79e1f29f029 74 this->writeData(0x01); this->writeData(0x2C); this->writeData(0x2D);
cfavreau 0:c79e1f29f029 75
cfavreau 0:c79e1f29f029 76 // SETCYC
cfavreau 0:c79e1f29f029 77 this->writeCommand(0xB4);
cfavreau 0:c79e1f29f029 78 this->writeData(0x07);
cfavreau 0:c79e1f29f029 79
cfavreau 0:c79e1f29f029 80 // SETSTBA
cfavreau 0:c79e1f29f029 81 this->writeCommand(0xC0);
cfavreau 0:c79e1f29f029 82 this->writeData(0xA2); this->writeData(0x02); this->writeData(0x84);
cfavreau 0:c79e1f29f029 83 // SETPFUSE
cfavreau 0:c79e1f29f029 84 this->writeCommand(0xC1); this->writeData(0xC5);
cfavreau 0:c79e1f29f029 85 // What does this do?
cfavreau 0:c79e1f29f029 86 this->writeCommand(0xC2);
cfavreau 0:c79e1f29f029 87 this->writeData(0x0A); this->writeData(0x00);
cfavreau 0:c79e1f29f029 88 // What does this do?
cfavreau 0:c79e1f29f029 89 this->writeCommand(0xC3);
cfavreau 0:c79e1f29f029 90 this->writeData(0x8A); this->writeData(0x2A);
cfavreau 0:c79e1f29f029 91 // SetID
cfavreau 0:c79e1f29f029 92 this->writeCommand(0xC4);
cfavreau 0:c79e1f29f029 93 this->writeData(0x8A); this->writeData(0xEE);
cfavreau 0:c79e1f29f029 94 // What does this do?
cfavreau 0:c79e1f29f029 95 this->writeCommand(0xC5);
cfavreau 0:c79e1f29f029 96 this->writeData(0x0E);
cfavreau 0:c79e1f29f029 97
cfavreau 0:c79e1f29f029 98 // Set Memory Access Control
cfavreau 0:c79e1f29f029 99 this->writeCommand(0x36);
cfavreau 0:c79e1f29f029 100 this->writeData(0xA8);
cfavreau 0:c79e1f29f029 101
cfavreau 0:c79e1f29f029 102 // Read Internal Oscillator
cfavreau 0:c79e1f29f029 103 this->writeCommand(0xe0);
cfavreau 0:c79e1f29f029 104 this->writeData(0x0f); this->writeData(0x1a);
cfavreau 0:c79e1f29f029 105 this->writeData(0x0f); this->writeData(0x18);
cfavreau 0:c79e1f29f029 106 this->writeData(0x2f); this->writeData(0x28);
cfavreau 0:c79e1f29f029 107 this->writeData(0x20); this->writeData(0x22);
cfavreau 0:c79e1f29f029 108 this->writeData(0x1f); this->writeData(0x1b);
cfavreau 0:c79e1f29f029 109 this->writeData(0x23); this->writeData(0x37); this->writeData(0x00);
cfavreau 0:c79e1f29f029 110 this->writeData(0x07);
cfavreau 0:c79e1f29f029 111 this->writeData(0x02); this->writeData(0x10);
cfavreau 0:c79e1f29f029 112
cfavreau 0:c79e1f29f029 113 // Read Power
cfavreau 0:c79e1f29f029 114 this->writeCommand(0xe1);
cfavreau 0:c79e1f29f029 115 this->writeData(0x0f); this->writeData(0x1b);
cfavreau 0:c79e1f29f029 116 this->writeData(0x0f); this->writeData(0x17);
cfavreau 0:c79e1f29f029 117 this->writeData(0x33); this->writeData(0x2c);
cfavreau 0:c79e1f29f029 118 this->writeData(0x29); this->writeData(0x2e);
cfavreau 0:c79e1f29f029 119 this->writeData(0x30); this->writeData(0x30);
cfavreau 0:c79e1f29f029 120 this->writeData(0x39); this->writeData(0x3f);
cfavreau 0:c79e1f29f029 121 this->writeData(0x00); this->writeData(0x07);
cfavreau 0:c79e1f29f029 122 this->writeData(0x03); this->writeData(0x10);
cfavreau 0:c79e1f29f029 123
cfavreau 0:c79e1f29f029 124 // Set the initial column and page address sets (clipping area)
cfavreau 0:c79e1f29f029 125 this->writeCommand(0x2a);
cfavreau 0:c79e1f29f029 126 this->writeData(0x00); this->writeData(0x00);
cfavreau 0:c79e1f29f029 127 this->writeData(0x00); this->writeData(0x7f);
cfavreau 0:c79e1f29f029 128 this->writeCommand(0x2b);
cfavreau 0:c79e1f29f029 129 this->writeData(0x00); this->writeData(0x00);
cfavreau 0:c79e1f29f029 130 this->writeData(0x00); this->writeData(0x9f);
cfavreau 0:c79e1f29f029 131
cfavreau 0:c79e1f29f029 132 // Read Source Option
cfavreau 0:c79e1f29f029 133 this->writeCommand(0xF0);
cfavreau 0:c79e1f29f029 134 this->writeData(0x01);
cfavreau 0:c79e1f29f029 135 this->writeCommand(0xF6);
cfavreau 0:c79e1f29f029 136 this->writeData(0x00);
cfavreau 0:c79e1f29f029 137
cfavreau 0:c79e1f29f029 138 // Set the pixel format (16 bits per pixel)
cfavreau 0:c79e1f29f029 139 this->writeCommand(0x3A);
cfavreau 0:c79e1f29f029 140 this->writeData(0x05);
cfavreau 0:c79e1f29f029 141
cfavreau 0:c79e1f29f029 142 // Turn on the display
cfavreau 0:c79e1f29f029 143 this->writeCommand(0x29);
cfavreau 0:c79e1f29f029 144
cfavreau 0:c79e1f29f029 145 this->clear();
cfavreau 0:c79e1f29f029 146 }
cfavreau 0:c79e1f29f029 147
cfavreau 0:c79e1f29f029 148 unsigned short *DisplayN18::getLineBuffer()
cfavreau 0:c79e1f29f029 149 {
cfavreau 0:c79e1f29f029 150 // *** Tried buffering up all the commands however I think we need to toggle the CS pin or something
cfavreau 0:c79e1f29f029 151 // in order to execute the command... so we cannot just buffer and send everything at once...
cfavreau 0:c79e1f29f029 152 // Anyhoo.. ran out of time so we have to try this some other time...
cfavreau 0:c79e1f29f029 153 // Have to return a pointer on a 4 byte boundary I think!
cfavreau 0:c79e1f29f029 154 //return (unsigned short *)&buffer[12];
cfavreau 0:c79e1f29f029 155 // Just return the base buffer for now
cfavreau 0:c79e1f29f029 156 return (unsigned short *)buffer;
cfavreau 0:c79e1f29f029 157 }
cfavreau 0:c79e1f29f029 158
cfavreau 0:c79e1f29f029 159 void DisplayN18::blitLine(unsigned char line)
cfavreau 0:c79e1f29f029 160 {
cfavreau 0:c79e1f29f029 161 this->setClippingArea(0, line, 159, 0);
cfavreau 0:c79e1f29f029 162 this->writeCommand(0x2C);
cfavreau 0:c79e1f29f029 163 this->writeData(buffer, 160 * 1 * 2);
cfavreau 0:c79e1f29f029 164
cfavreau 0:c79e1f29f029 165 // *** Tried buffering up all the commands however I think we need to toggle the CS pin or something
cfavreau 0:c79e1f29f029 166 // in order to execute the command... so we cannot just buffer and send everything at once...
cfavreau 0:c79e1f29f029 167 // Anyhoo.. ran out of time so we have to try this some other time...
cfavreau 0:c79e1f29f029 168 /*
cfavreau 0:c79e1f29f029 169 // Setup column address set
cfavreau 0:c79e1f29f029 170 buffer[0] = 0;
cfavreau 0:c79e1f29f029 171 buffer[1] = 0x2A;
cfavreau 0:c79e1f29f029 172 buffer[2] = 0;
cfavreau 0:c79e1f29f029 173 buffer[3] = 0; // x
cfavreau 0:c79e1f29f029 174 buffer[4] = 0;
cfavreau 0:c79e1f29f029 175 buffer[5] = 159; // x + (width - 1)
cfavreau 0:c79e1f29f029 176 buffer[6] = 0x2B;
cfavreau 0:c79e1f29f029 177 buffer[7] = 0;
cfavreau 0:c79e1f29f029 178 buffer[8] = line; // y
cfavreau 0:c79e1f29f029 179 buffer[9] = 0;
cfavreau 0:c79e1f29f029 180 buffer[10] = line; // y + (height - 1)
cfavreau 0:c79e1f29f029 181 // Write Command
cfavreau 0:c79e1f29f029 182 buffer[11] = 0x2C;
cfavreau 0:c79e1f29f029 183
cfavreau 0:c79e1f29f029 184 //buffer[0] = 0;
cfavreau 0:c79e1f29f029 185 //buffer[1] = 0x2C;
cfavreau 0:c79e1f29f029 186 // Everything else is a buffer of 160 unsigned shorts
cfavreau 0:c79e1f29f029 187 // Already should be filled out....
cfavreau 0:c79e1f29f029 188
cfavreau 0:c79e1f29f029 189 // Write the buffer to the display
cfavreau 0:c79e1f29f029 190 writeData(&buffer[1], 11 + (160 * 2));
cfavreau 0:c79e1f29f029 191 */
cfavreau 0:c79e1f29f029 192 }
cfavreau 0:c79e1f29f029 193
cfavreau 0:c79e1f29f029 194 void DisplayN18::setClippingArea(unsigned char x, unsigned char y, unsigned char width, unsigned char height) {
cfavreau 0:c79e1f29f029 195 unsigned char data[4] = { 0x00, 0x00, 0x00, 0x00 };
cfavreau 0:c79e1f29f029 196
cfavreau 0:c79e1f29f029 197 // Set the Column Address Set
cfavreau 0:c79e1f29f029 198 data[1] = x;
cfavreau 0:c79e1f29f029 199 data[3] = x + width;
cfavreau 0:c79e1f29f029 200 this->writeCommand(0x2A);
cfavreau 0:c79e1f29f029 201 this->writeData(data, 4);
cfavreau 0:c79e1f29f029 202
cfavreau 0:c79e1f29f029 203 // Set the Page Address Set
cfavreau 0:c79e1f29f029 204 data[1] = y;
cfavreau 0:c79e1f29f029 205 data[3] = y + height;
cfavreau 0:c79e1f29f029 206 this->writeCommand(0x2B);
cfavreau 0:c79e1f29f029 207 this->writeData(data, 4);
cfavreau 0:c79e1f29f029 208 }
cfavreau 0:c79e1f29f029 209
cfavreau 0:c79e1f29f029 210 unsigned short DisplayN18::rgbToShort(unsigned char r, unsigned char g, unsigned char b) {
cfavreau 0:c79e1f29f029 211 unsigned short red = r;
cfavreau 0:c79e1f29f029 212 unsigned short green = g;
cfavreau 0:c79e1f29f029 213 unsigned short blue = b;
cfavreau 0:c79e1f29f029 214
cfavreau 0:c79e1f29f029 215 red /= 8;
cfavreau 0:c79e1f29f029 216 green /= 4;
cfavreau 0:c79e1f29f029 217 blue /= 8;
cfavreau 0:c79e1f29f029 218
cfavreau 0:c79e1f29f029 219 red &= 0x1F;
cfavreau 0:c79e1f29f029 220 green &= 0x3F;
cfavreau 0:c79e1f29f029 221 blue &= 0x1F;
cfavreau 0:c79e1f29f029 222
cfavreau 0:c79e1f29f029 223 red <<= 8;//3;
cfavreau 0:c79e1f29f029 224 blue <<= 3;//8;
cfavreau 0:c79e1f29f029 225 green = ((green & 0x7) << 13) + ((green & 0x38) >> 3);
cfavreau 0:c79e1f29f029 226
cfavreau 0:c79e1f29f029 227 return red | green | blue;
cfavreau 0:c79e1f29f029 228 }
cfavreau 0:c79e1f29f029 229
cfavreau 0:c79e1f29f029 230 void DisplayN18::clear(unsigned short backColor) {
cfavreau 0:c79e1f29f029 231 for (unsigned int i = 0; i < LCD_WIDTH; i += 10)
cfavreau 0:c79e1f29f029 232 for (unsigned int j = 0; j < LCD_HEIGHT; j += 8)
cfavreau 0:c79e1f29f029 233 this->fillRect(i, j, 10, 8, backColor);
cfavreau 0:c79e1f29f029 234 }
cfavreau 0:c79e1f29f029 235
cfavreau 0:c79e1f29f029 236 void DisplayN18::draw(const unsigned short* data, int x, int y, int width, int height) {
cfavreau 0:c79e1f29f029 237 this->setClippingArea(x, y, width - 1, height - 1);
cfavreau 0:c79e1f29f029 238 this->writeCommand(0x2C);
cfavreau 0:c79e1f29f029 239 this->writeData(reinterpret_cast<const unsigned char*>(data), width * height * 2);
cfavreau 0:c79e1f29f029 240 }
cfavreau 0:c79e1f29f029 241
cfavreau 0:c79e1f29f029 242 void DisplayN18::setPixel(int x, int y, unsigned short foreColor) {
cfavreau 0:c79e1f29f029 243 this->draw(&foreColor, x, y, 1, 1);
cfavreau 0:c79e1f29f029 244 }
cfavreau 0:c79e1f29f029 245
cfavreau 0:c79e1f29f029 246 void DisplayN18::fillRect(int x, int y, int width, int height, unsigned short foreColor) {
cfavreau 0:c79e1f29f029 247 this->setClippingArea(static_cast<unsigned char>(x), static_cast<unsigned char>(y), static_cast<unsigned char>(width - 1), static_cast<unsigned char>(height));
cfavreau 0:c79e1f29f029 248
cfavreau 0:c79e1f29f029 249 this->writeCommand(0x2C);
cfavreau 0:c79e1f29f029 250
cfavreau 0:c79e1f29f029 251 unsigned short buffer[50];
cfavreau 0:c79e1f29f029 252 for (int j = 0; j < sizeof(buffer) / 2; j++)
cfavreau 0:c79e1f29f029 253 buffer[j] = foreColor;
cfavreau 0:c79e1f29f029 254
cfavreau 0:c79e1f29f029 255 this->rsPin.write(true);
cfavreau 0:c79e1f29f029 256
cfavreau 0:c79e1f29f029 257 int i;
cfavreau 0:c79e1f29f029 258 for (i = sizeof(buffer); i < height * width * 2; i += sizeof(buffer))
cfavreau 0:c79e1f29f029 259 this->writeData(reinterpret_cast<unsigned char*>(buffer), sizeof(buffer));
cfavreau 0:c79e1f29f029 260
cfavreau 0:c79e1f29f029 261 i -= sizeof(buffer);
cfavreau 0:c79e1f29f029 262 if (i != height * width * 2)
cfavreau 0:c79e1f29f029 263 this->writeData(reinterpret_cast<unsigned char*>(buffer), height * width * 2 - i);
cfavreau 0:c79e1f29f029 264 }
cfavreau 0:c79e1f29f029 265
cfavreau 0:c79e1f29f029 266 void DisplayN18::drawRect(int x, int y, int width, int height, unsigned short foreColor) {
cfavreau 0:c79e1f29f029 267 this->drawLine(x, y, x + width, y, foreColor);
cfavreau 0:c79e1f29f029 268 this->drawLine(x, y + height, x + width, y + height, foreColor);
cfavreau 0:c79e1f29f029 269 this->drawLine(x, y, x, y + height, foreColor);
cfavreau 0:c79e1f29f029 270 this->drawLine(x + width, y, x + width, y + height, foreColor);
cfavreau 0:c79e1f29f029 271 }
cfavreau 0:c79e1f29f029 272
cfavreau 0:c79e1f29f029 273 void DisplayN18::fillCircle(int x, int y, int radius, unsigned short foreColor) {
cfavreau 0:c79e1f29f029 274 int f = 1 - radius;
cfavreau 0:c79e1f29f029 275 int dd_f_x = 1;
cfavreau 0:c79e1f29f029 276 int dd_f_y = -2 * radius;
cfavreau 0:c79e1f29f029 277 int x1 = 0;
cfavreau 0:c79e1f29f029 278 int y1 = radius;
cfavreau 0:c79e1f29f029 279
cfavreau 0:c79e1f29f029 280 for (int i = y - radius; i <= y + radius; i++)
cfavreau 0:c79e1f29f029 281 this->setPixel(x, i, foreColor);
cfavreau 0:c79e1f29f029 282
cfavreau 0:c79e1f29f029 283 while (x1 < y1) {
cfavreau 0:c79e1f29f029 284 if (f >= 0) {
cfavreau 0:c79e1f29f029 285 y1--;
cfavreau 0:c79e1f29f029 286 dd_f_y += 2;
cfavreau 0:c79e1f29f029 287 f += dd_f_y;
cfavreau 0:c79e1f29f029 288 }
cfavreau 0:c79e1f29f029 289
cfavreau 0:c79e1f29f029 290 x1++;
cfavreau 0:c79e1f29f029 291 dd_f_x += 2;
cfavreau 0:c79e1f29f029 292 f += dd_f_x;
cfavreau 0:c79e1f29f029 293
cfavreau 0:c79e1f29f029 294 for (int i = y - y1; i <= y + y1; i++) {
cfavreau 0:c79e1f29f029 295 this->setPixel(x + x1, i, foreColor);
cfavreau 0:c79e1f29f029 296 this->setPixel(x - x1, i, foreColor);
cfavreau 0:c79e1f29f029 297 }
cfavreau 0:c79e1f29f029 298
cfavreau 0:c79e1f29f029 299 for (int i = y - x1; i <= y + x1; i++) {
cfavreau 0:c79e1f29f029 300 this->setPixel(x + y1, i, foreColor);
cfavreau 0:c79e1f29f029 301 this->setPixel(x - y1, i, foreColor);
cfavreau 0:c79e1f29f029 302 }
cfavreau 0:c79e1f29f029 303 }
cfavreau 0:c79e1f29f029 304 }
cfavreau 0:c79e1f29f029 305
cfavreau 0:c79e1f29f029 306 void DisplayN18::drawCircle(int x, int y, int radius, unsigned short foreColor) {
cfavreau 0:c79e1f29f029 307 int f = 1 - radius;
cfavreau 0:c79e1f29f029 308 int dd_f_x = 1;
cfavreau 0:c79e1f29f029 309 int dd_f_y = -2 * radius;
cfavreau 0:c79e1f29f029 310 int x1 = 0;
cfavreau 0:c79e1f29f029 311 int y1 = radius;
cfavreau 0:c79e1f29f029 312
cfavreau 0:c79e1f29f029 313 this->setPixel(x, y + radius, foreColor);
cfavreau 0:c79e1f29f029 314 this->setPixel(x, y - radius, foreColor);
cfavreau 0:c79e1f29f029 315 this->setPixel(x + radius, y, foreColor);
cfavreau 0:c79e1f29f029 316 this->setPixel(x - radius, y, foreColor);
cfavreau 0:c79e1f29f029 317
cfavreau 0:c79e1f29f029 318 while (x1 < y1) {
cfavreau 0:c79e1f29f029 319 if (f >= 0) {
cfavreau 0:c79e1f29f029 320 y1--;
cfavreau 0:c79e1f29f029 321 dd_f_y += 2;
cfavreau 0:c79e1f29f029 322 f += dd_f_y;
cfavreau 0:c79e1f29f029 323 }
cfavreau 0:c79e1f29f029 324
cfavreau 0:c79e1f29f029 325 x1++;
cfavreau 0:c79e1f29f029 326 dd_f_x += 2;
cfavreau 0:c79e1f29f029 327 f += dd_f_x;
cfavreau 0:c79e1f29f029 328
cfavreau 0:c79e1f29f029 329 this->setPixel(x + x1, y + y1, foreColor);
cfavreau 0:c79e1f29f029 330 this->setPixel(x - x1, y + y1, foreColor);
cfavreau 0:c79e1f29f029 331 this->setPixel(x + x1, y - y1, foreColor);
cfavreau 0:c79e1f29f029 332 this->setPixel(x - x1, y - y1, foreColor);
cfavreau 0:c79e1f29f029 333
cfavreau 0:c79e1f29f029 334 this->setPixel(x + y1, y + x1, foreColor);
cfavreau 0:c79e1f29f029 335 this->setPixel(x - y1, y + x1, foreColor);
cfavreau 0:c79e1f29f029 336 this->setPixel(x + y1, y - x1, foreColor);
cfavreau 0:c79e1f29f029 337 this->setPixel(x - y1, y - x1, foreColor);
cfavreau 0:c79e1f29f029 338 }
cfavreau 0:c79e1f29f029 339 }
cfavreau 0:c79e1f29f029 340
cfavreau 0:c79e1f29f029 341 void DisplayN18::drawLine(int x0, int y0, int x1, int y1, unsigned short foreColor) {
cfavreau 0:c79e1f29f029 342 if (x0 == x1) {
cfavreau 0:c79e1f29f029 343 if (y1 < y0) {
cfavreau 0:c79e1f29f029 344 int temp = y0;
cfavreau 0:c79e1f29f029 345 y0 = y1;
cfavreau 0:c79e1f29f029 346 y1 = temp;
cfavreau 0:c79e1f29f029 347 }
cfavreau 0:c79e1f29f029 348
cfavreau 0:c79e1f29f029 349 this->setClippingArea(static_cast<unsigned char>(x0), static_cast<unsigned char>(y0), 0, static_cast<unsigned char>(y1 - y0 - 1));
cfavreau 0:c79e1f29f029 350 this->writeCommand(0x2C);
cfavreau 0:c79e1f29f029 351
cfavreau 0:c79e1f29f029 352 unsigned short data[DisplayN18::STEP];
cfavreau 0:c79e1f29f029 353 for (int i = 0; i < DisplayN18::STEP; i++)
cfavreau 0:c79e1f29f029 354 data[i] = foreColor;
cfavreau 0:c79e1f29f029 355
cfavreau 0:c79e1f29f029 356 for (unsigned char thisY = y0; thisY < y1; thisY += DisplayN18::STEP)
cfavreau 0:c79e1f29f029 357 this->writeData(reinterpret_cast<unsigned char*>(data), (thisY + DisplayN18::STEP <= y1 ? DisplayN18::STEP : y1 - thisY) * 2);
cfavreau 0:c79e1f29f029 358
cfavreau 0:c79e1f29f029 359 return;
cfavreau 0:c79e1f29f029 360 }
cfavreau 0:c79e1f29f029 361
cfavreau 0:c79e1f29f029 362 if (y0 == y1) {
cfavreau 0:c79e1f29f029 363 if (x1 < x0) {
cfavreau 0:c79e1f29f029 364 int temp = x0;
cfavreau 0:c79e1f29f029 365 x0 = x1;
cfavreau 0:c79e1f29f029 366 x1 = temp;
cfavreau 0:c79e1f29f029 367 }
cfavreau 0:c79e1f29f029 368
cfavreau 0:c79e1f29f029 369 this->setClippingArea(static_cast<unsigned char>(x0), static_cast<unsigned char>(y0), static_cast<unsigned char>(x1 - x0 - 1), 0);
cfavreau 0:c79e1f29f029 370 this->writeCommand(0x2C);
cfavreau 0:c79e1f29f029 371
cfavreau 0:c79e1f29f029 372 unsigned short data[DisplayN18::STEP];
cfavreau 0:c79e1f29f029 373 for (int i = 0; i < DisplayN18::STEP; i++)
cfavreau 0:c79e1f29f029 374 data[i] = foreColor;
cfavreau 0:c79e1f29f029 375
cfavreau 0:c79e1f29f029 376 for (unsigned char thisX = x0; thisX < x1; thisX += DisplayN18::STEP)
cfavreau 0:c79e1f29f029 377 this->writeData(reinterpret_cast<unsigned char*>(data), (thisX + DisplayN18::STEP <= x1 ? DisplayN18::STEP : x1 - thisX) * 2);
cfavreau 0:c79e1f29f029 378
cfavreau 0:c79e1f29f029 379 return;
cfavreau 0:c79e1f29f029 380 }
cfavreau 0:c79e1f29f029 381
cfavreau 0:c79e1f29f029 382 int t;
cfavreau 0:c79e1f29f029 383 bool steep = ((y1 - y0) < 0 ? -(y1 - y0) : (y1 - y0)) > ((x1 - x0) < 0 ? -(x1 - x0) : (x1 - x0));
cfavreau 0:c79e1f29f029 384
cfavreau 0:c79e1f29f029 385 if (steep) {
cfavreau 0:c79e1f29f029 386 t = x0;
cfavreau 0:c79e1f29f029 387 x0 = y0;
cfavreau 0:c79e1f29f029 388 y0 = t;
cfavreau 0:c79e1f29f029 389 t = x1;
cfavreau 0:c79e1f29f029 390 x1 = y1;
cfavreau 0:c79e1f29f029 391 y1 = t;
cfavreau 0:c79e1f29f029 392 }
cfavreau 0:c79e1f29f029 393
cfavreau 0:c79e1f29f029 394 if (x0 > x1) {
cfavreau 0:c79e1f29f029 395 t = x0;
cfavreau 0:c79e1f29f029 396 x0 = x1;
cfavreau 0:c79e1f29f029 397 x1 = t;
cfavreau 0:c79e1f29f029 398
cfavreau 0:c79e1f29f029 399 t = y0;
cfavreau 0:c79e1f29f029 400 y0 = y1;
cfavreau 0:c79e1f29f029 401 y1 = t;
cfavreau 0:c79e1f29f029 402 }
cfavreau 0:c79e1f29f029 403
cfavreau 0:c79e1f29f029 404 int dx, dy;
cfavreau 0:c79e1f29f029 405 dx = x1 - x0;
cfavreau 0:c79e1f29f029 406 dy = (y1 - y0) < 0 ? -(y1 - y0) : (y1 - y0);
cfavreau 0:c79e1f29f029 407
cfavreau 0:c79e1f29f029 408 int err = (dx / 2);
cfavreau 0:c79e1f29f029 409 int ystep;
cfavreau 0:c79e1f29f029 410
cfavreau 0:c79e1f29f029 411 ystep = y0 < y1 ? 1 : -1;
cfavreau 0:c79e1f29f029 412
cfavreau 0:c79e1f29f029 413 for (; x0 < x1; x0++) {
cfavreau 0:c79e1f29f029 414 if (steep)
cfavreau 0:c79e1f29f029 415 this->setPixel(y0, x0, foreColor);
cfavreau 0:c79e1f29f029 416 else
cfavreau 0:c79e1f29f029 417 this->setPixel(x0, y0, foreColor);
cfavreau 0:c79e1f29f029 418
cfavreau 0:c79e1f29f029 419 err -= dy;
cfavreau 0:c79e1f29f029 420
cfavreau 0:c79e1f29f029 421 if (err < 0) {
cfavreau 0:c79e1f29f029 422 y0 += (char)ystep;
cfavreau 0:c79e1f29f029 423 err += dx;
cfavreau 0:c79e1f29f029 424 }
cfavreau 0:c79e1f29f029 425 }
cfavreau 0:c79e1f29f029 426 }
cfavreau 0:c79e1f29f029 427
cfavreau 0:c79e1f29f029 428 void DisplayN18::drawBitmap(int x, int y, int w, int h, unsigned char *bitmap, unsigned short foreColor, unsigned short backColor)
cfavreau 0:c79e1f29f029 429 {
cfavreau 0:c79e1f29f029 430 this->setClippingArea(x, y, w - 1, h);
cfavreau 0:c79e1f29f029 431 this->writeCommand(0x2C);
cfavreau 0:c79e1f29f029 432
cfavreau 0:c79e1f29f029 433 this->rsPin.write(true);
cfavreau 0:c79e1f29f029 434 this->csPin.write(false);
cfavreau 0:c79e1f29f029 435
cfavreau 0:c79e1f29f029 436 int length = ((h * w) / 8);
cfavreau 0:c79e1f29f029 437
cfavreau 0:c79e1f29f029 438 for (unsigned int i = 0; i < length; i++)
cfavreau 0:c79e1f29f029 439 {
cfavreau 0:c79e1f29f029 440 unsigned short color = 0;
cfavreau 0:c79e1f29f029 441 unsigned char data = bitmap[i];
cfavreau 0:c79e1f29f029 442 for (unsigned int bit = 0; bit < 8; bit++)
cfavreau 0:c79e1f29f029 443 {
cfavreau 0:c79e1f29f029 444 color = (data & (1 << bit)) ? foreColor : backColor;
cfavreau 0:c79e1f29f029 445 this->spi.write((unsigned char)(color >> 8));
cfavreau 0:c79e1f29f029 446 this->spi.write((unsigned char)(color & 0x00FF));
cfavreau 0:c79e1f29f029 447 }
cfavreau 0:c79e1f29f029 448 }
cfavreau 0:c79e1f29f029 449
cfavreau 0:c79e1f29f029 450 this->csPin.write(true);
cfavreau 0:c79e1f29f029 451 }
cfavreau 0:c79e1f29f029 452 /*
cfavreau 0:c79e1f29f029 453 void DisplayN18::drawCharacter(int x, int y, const char character, unsigned short foreColor, unsigned short backColor, unsigned char fontSize)
cfavreau 0:c79e1f29f029 454 {
cfavreau 0:c79e1f29f029 455 if (character > 126 || character < 32) return;
cfavreau 0:c79e1f29f029 456 drawBitmap(x, y, CHAR_WIDTH, CHAR_HEIGHT, &font8x8_basic[(character - 32) * 8], foreColor, backColor);
cfavreau 0:c79e1f29f029 457 }
cfavreau 0:c79e1f29f029 458
cfavreau 0:c79e1f29f029 459 void DisplayN18::drawString(int x, int y, const char* str, unsigned short foreColor, unsigned short backColor, unsigned char fontSize) {
cfavreau 0:c79e1f29f029 460 if (*str == '\0')
cfavreau 0:c79e1f29f029 461 return;
cfavreau 0:c79e1f29f029 462
cfavreau 0:c79e1f29f029 463 do {
cfavreau 0:c79e1f29f029 464 this->drawCharacter(x, y, *str, foreColor, backColor, fontSize);
cfavreau 0:c79e1f29f029 465
cfavreau 0:c79e1f29f029 466 x += (CHAR_WIDTH + CHAR_SPACING) * fontSize;
cfavreau 0:c79e1f29f029 467 } while (*(++str) != '\0');
cfavreau 0:c79e1f29f029 468 }
cfavreau 0:c79e1f29f029 469
cfavreau 0:c79e1f29f029 470 unsigned char *DisplayN18::getCharBuffer()
cfavreau 0:c79e1f29f029 471 {
cfavreau 0:c79e1f29f029 472 return font8x8_basic;
cfavreau 0:c79e1f29f029 473 }
cfavreau 0:c79e1f29f029 474
cfavreau 0:c79e1f29f029 475 */