new mods upon mods by devhammer: - Added paddle control using tilting of the console - Finished mute function - Reduced flickering See game.cpp for full info.

Dependencies:   mbed

Fork of RETRO_Pong_Mod by G. Andrew Duthie

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DisplayN18.cpp Source File

DisplayN18.cpp

00001 #include "DisplayN18.h"
00002 
00003 DisplayN18::DisplayN18() : resetPin(P0_20), backlightPin(P0_19), rsPin(P0_7), csPin(P0_2), spi(P0_21, P0_22, P1_15) {
00004     this->resetPin.write(false);
00005     this->backlightPin.write(true);
00006     this->rsPin.write(false);
00007     
00008     this->spi.format(8, 3);
00009     this->spi.frequency(15000000);
00010     
00011     this->initialize();
00012 }
00013 
00014 void DisplayN18::writeCommand(unsigned char command) {
00015     this->rsPin.write(false);
00016     
00017     this->csPin.write(false);
00018     
00019     this->spi.write(command);
00020     
00021     this->csPin.write(true);
00022 }
00023 
00024 void DisplayN18::writeData(unsigned char data) {
00025     this->writeData(&data, 1);
00026 }
00027 
00028 void DisplayN18::writeData(const unsigned char* data, unsigned int length) {
00029     this->rsPin.write(true);
00030     
00031     this->csPin.write(false);
00032     
00033     for (unsigned int i = 0; i < length; i++)
00034         this->spi.write(data[i]);
00035     
00036     this->csPin.write(true);
00037 }
00038 
00039 void DisplayN18::reset() {
00040     this->resetPin.write(false);
00041     wait_ms(300);
00042     
00043     this->resetPin.write(true);
00044     wait_ms(500);
00045 }
00046 
00047 void DisplayN18::initialize() {
00048     this->reset();
00049 
00050     this->writeCommand(0x11);
00051     
00052     wait_ms(120);
00053 
00054     this->writeCommand(0xB1);
00055     this->writeData(0x01); this->writeData(0x2C); this->writeData(0x2D);
00056     this->writeCommand(0xB2);
00057     this->writeData(0x01); this->writeData(0x2C); this->writeData(0x2D);
00058     this->writeCommand(0xB3);
00059     this->writeData(0x01); this->writeData(0x2C); this->writeData(0x2D);
00060     this->writeData(0x01); this->writeData(0x2C); this->writeData(0x2D);
00061 
00062     this->writeCommand(0xB4);
00063     this->writeData(0x07);
00064 
00065     this->writeCommand(0xC0);
00066     this->writeData(0xA2); this->writeData(0x02); this->writeData(0x84);
00067     this->writeCommand(0xC1); this->writeData(0xC5);
00068     this->writeCommand(0xC2);
00069     this->writeData(0x0A); this->writeData(0x00);
00070     this->writeCommand(0xC3);
00071     this->writeData(0x8A); this->writeData(0x2A);
00072     this->writeCommand(0xC4);
00073     this->writeData(0x8A); this->writeData(0xEE);
00074 
00075     this->writeCommand(0xC5);
00076     this->writeData(0x0E);
00077 
00078     this->writeCommand(0x36);
00079     this->writeData(0xA8);
00080 
00081     this->writeCommand(0xe0);
00082     this->writeData(0x0f); this->writeData(0x1a);
00083     this->writeData(0x0f); this->writeData(0x18);
00084     this->writeData(0x2f); this->writeData(0x28);
00085     this->writeData(0x20); this->writeData(0x22);
00086     this->writeData(0x1f); this->writeData(0x1b);
00087     this->writeData(0x23); this->writeData(0x37); this->writeData(0x00);
00088     this->writeData(0x07);
00089     this->writeData(0x02); this->writeData(0x10);
00090 
00091     this->writeCommand(0xe1);
00092     this->writeData(0x0f); this->writeData(0x1b);
00093     this->writeData(0x0f); this->writeData(0x17);
00094     this->writeData(0x33); this->writeData(0x2c);
00095     this->writeData(0x29); this->writeData(0x2e);
00096     this->writeData(0x30); this->writeData(0x30);
00097     this->writeData(0x39); this->writeData(0x3f);
00098     this->writeData(0x00); this->writeData(0x07);
00099     this->writeData(0x03); this->writeData(0x10);
00100 
00101     this->writeCommand(0x2a);
00102     this->writeData(0x00); this->writeData(0x00);
00103     this->writeData(0x00); this->writeData(0x7f);
00104     this->writeCommand(0x2b);
00105     this->writeData(0x00); this->writeData(0x00);
00106     this->writeData(0x00); this->writeData(0x9f);
00107 
00108     this->writeCommand(0xF0);
00109     this->writeData(0x01);
00110     this->writeCommand(0xF6);
00111     this->writeData(0x00);
00112 
00113     this->writeCommand(0x3A);
00114     this->writeData(0x05);
00115 
00116     this->writeCommand(0x29);
00117 
00118     this->clear();
00119 }
00120 
00121 void DisplayN18::setClippingArea(unsigned char x, unsigned char y, unsigned char width, unsigned char height) {
00122     unsigned char data[4] = { 0x00, 0x00, 0x00, 0x00 };
00123 
00124     data[1] = x;
00125     data[3] = x + width;
00126     this->writeCommand(0x2A);
00127     this->writeData(data, 4);
00128 
00129     data[1] = y;
00130     data[3] = y + height;
00131     this->writeCommand(0x2B);
00132     this->writeData(data, 4);
00133 }
00134 
00135 unsigned short DisplayN18::rgbToShort(unsigned char r, unsigned char g, unsigned char b) {
00136     unsigned short red = r;
00137     unsigned short green = g;
00138     unsigned short blue = b;
00139 
00140     red /= 8;
00141     green /= 4;
00142     blue /= 8;
00143 
00144     red &= 0x1F;
00145     green &= 0x3F;
00146     blue &= 0x1F;
00147 
00148     red <<= 3;
00149     blue <<= 8;
00150     green = ((green & 0x7) << 13) + ((green & 0x38) >> 3);
00151 
00152     return red | green | blue;
00153 }
00154 
00155 void DisplayN18::clear(unsigned short backColor) {
00156     for (unsigned int i = 0; i < DisplayN18::WIDTH; i += 10)
00157         for (unsigned int j = 0; j < DisplayN18::HEIGHT; j += 8)
00158             this->fillRect(i, j, 10, 8, backColor);
00159 }
00160 
00161 void DisplayN18::draw(const unsigned short* data, int x, int y, int width, int height) {
00162     this->setClippingArea(x, y, width - 1, height - 1);
00163     this->writeCommand(0x2C);
00164     this->writeData(reinterpret_cast<const unsigned char*>(data), width * height * 2);
00165 }
00166 
00167 void DisplayN18::setPixel(int x, int y, unsigned short foreColor) {
00168     this->draw(&foreColor, x, y, 1, 1);
00169 }
00170 
00171 void DisplayN18::fillRect(int x, int y, int width, int height, unsigned short foreColor) {
00172     this->setClippingArea(static_cast<unsigned char>(x), static_cast<unsigned char>(y), static_cast<unsigned char>(width - 1), static_cast<unsigned char>(height));
00173     
00174     this->writeCommand(0x2C);
00175     
00176     unsigned short buffer[50];
00177     for (int j = 0; j < sizeof(buffer) / 2; j++)
00178         buffer[j] = foreColor;
00179 
00180     this->rsPin.write(true);
00181 
00182     int i;
00183     for (i = sizeof(buffer); i < height * width * 2; i += sizeof(buffer))
00184         this->writeData(reinterpret_cast<unsigned char*>(buffer), sizeof(buffer));
00185     
00186     i -= sizeof(buffer);
00187     if (i != height * width * 2)
00188         this->writeData(reinterpret_cast<unsigned char*>(buffer), height * width * 2 - i);
00189 }
00190 
00191 void DisplayN18::drawRect(int x, int y, int width, int height, unsigned short foreColor) {
00192     this->drawLine(x, y, x + width, y, foreColor);
00193     this->drawLine(x, y + height, x + width, y + height, foreColor);
00194     this->drawLine(x, y, x, y + height, foreColor);
00195     this->drawLine(x + width, y, x + width, y + height, foreColor);
00196 }
00197 
00198 void DisplayN18::fillCircle(int x, int y, int radius, unsigned short foreColor) {
00199     int f = 1 - radius;
00200     int dd_f_x = 1;
00201     int dd_f_y = -2 * radius;
00202     int x1 = 0;
00203     int y1 = radius;
00204 
00205     for (int i = y - radius; i <= y + radius; i++)
00206         this->setPixel(x, i, foreColor);
00207 
00208     while (x1 < y1) {
00209         if (f >= 0) {
00210             y1--;
00211             dd_f_y += 2;
00212             f += dd_f_y;
00213         }
00214 
00215         x1++;
00216         dd_f_x += 2;
00217         f += dd_f_x;
00218 
00219         for (int i = y - y1; i <= y + y1; i++) {
00220             this->setPixel(x + x1, i, foreColor);
00221             this->setPixel(x - x1, i, foreColor);
00222         }
00223 
00224         for (int i = y - x1; i <= y + x1; i++) {
00225             this->setPixel(x + y1, i, foreColor);
00226             this->setPixel(x - y1, i, foreColor);
00227         }
00228     }
00229 }
00230 
00231 void DisplayN18::drawCircle(int x, int y, int radius, unsigned short foreColor) {
00232     int f = 1 - radius;
00233     int dd_f_x = 1;
00234     int dd_f_y = -2 * radius;
00235     int x1 = 0;
00236     int y1 = radius;
00237 
00238     this->setPixel(x, y + radius, foreColor);
00239     this->setPixel(x, y - radius, foreColor);
00240     this->setPixel(x + radius, y, foreColor);
00241     this->setPixel(x - radius, y, foreColor);
00242 
00243     while (x1 < y1) {
00244         if (f >= 0) {
00245             y1--;
00246             dd_f_y += 2;
00247             f += dd_f_y;
00248         }
00249 
00250         x1++;
00251         dd_f_x += 2;
00252         f += dd_f_x;
00253 
00254         this->setPixel(x + x1, y + y1, foreColor);
00255         this->setPixel(x - x1, y + y1, foreColor);
00256         this->setPixel(x + x1, y - y1, foreColor);
00257         this->setPixel(x - x1, y - y1, foreColor);
00258 
00259         this->setPixel(x + y1, y + x1, foreColor);
00260         this->setPixel(x - y1, y + x1, foreColor);
00261         this->setPixel(x + y1, y - x1, foreColor);
00262         this->setPixel(x - y1, y - x1, foreColor);
00263     }
00264 }
00265 
00266 void DisplayN18::drawLine(int x0, int y0, int x1, int y1, unsigned short foreColor) {
00267     if (x0 == x1) {
00268         if (y1 < y0) {
00269             int temp = y0;
00270             y0 = y1;
00271             y1 = temp;
00272         }
00273 
00274         this->setClippingArea(static_cast<unsigned char>(x0), static_cast<unsigned char>(y0), 0, static_cast<unsigned char>(y1 - y0 - 1));
00275         this->writeCommand(0x2C);
00276 
00277         unsigned short data[DisplayN18::STEP];
00278         for (int i = 0; i < DisplayN18::STEP; i++)
00279             data[i] = foreColor;
00280 
00281         for (unsigned char thisY = y0; thisY < y1; thisY += DisplayN18::STEP)
00282             this->writeData(reinterpret_cast<unsigned char*>(data), (thisY + DisplayN18::STEP <= y1 ? DisplayN18::STEP : y1 - thisY) * 2);
00283 
00284         return;
00285     }
00286 
00287     if (y0 == y1) {
00288         if (x1 < x0) {
00289             int temp = x0;
00290             x0 = x1;
00291             x1 = temp;
00292         }
00293 
00294         this->setClippingArea(static_cast<unsigned char>(x0), static_cast<unsigned char>(y0), static_cast<unsigned char>(x1 - x0 - 1), 0);
00295         this->writeCommand(0x2C);
00296 
00297         unsigned short data[DisplayN18::STEP];
00298         for (int i = 0; i < DisplayN18::STEP; i++)
00299             data[i] = foreColor;
00300 
00301         for (unsigned char thisX = x0; thisX < x1; thisX += DisplayN18::STEP)
00302             this->writeData(reinterpret_cast<unsigned char*>(data), (thisX + DisplayN18::STEP <= x1 ? DisplayN18::STEP : x1 - thisX) * 2);
00303 
00304         return;
00305     }
00306 
00307     int t;
00308     bool steep = ((y1 - y0) < 0 ? -(y1 - y0) : (y1 - y0)) > ((x1 - x0) < 0 ? -(x1 - x0) : (x1 - x0));
00309 
00310     if (steep) {
00311         t = x0;
00312         x0 = y0;
00313         y0 = t;
00314         t = x1;
00315         x1 = y1;
00316         y1 = t;
00317     }
00318 
00319     if (x0 > x1) {
00320         t = x0;
00321         x0 = x1;
00322         x1 = t;
00323 
00324         t = y0;
00325         y0 = y1;
00326         y1 = t;
00327     }
00328 
00329     int dx, dy;
00330     dx = x1 - x0;
00331     dy = (y1 - y0) < 0 ? -(y1 - y0) : (y1 - y0);
00332 
00333     int err = (dx / 2);
00334     int ystep;
00335 
00336     ystep = y0 < y1 ? 1 : -1;
00337 
00338     for (; x0 < x1; x0++) {
00339         if (steep)
00340             this->setPixel(y0, x0, foreColor);
00341         else
00342             this->setPixel(x0, y0, foreColor);
00343 
00344         err -= dy;
00345 
00346         if (err < 0) {
00347             y0 += (char)ystep;
00348             err += dx;
00349         }
00350     }
00351 }
00352 
00353 unsigned char characters[95 * 5] = {
00354     0x00, 0x00, 0x00, 0x00, 0x00, /* Space  0x20 */
00355     0x00, 0x00, 0x4f, 0x00, 0x00, /* ! */
00356     0x00, 0x07, 0x00, 0x07, 0x00, /* " */
00357     0x14, 0x7f, 0x14, 0x7f, 0x14, /* # */
00358     0x24, 0x2a, 0x7f, 0x2a, 0x12, /* $ */
00359     0x23, 0x13, 0x08, 0x64, 0x62, /* % */
00360     0x36, 0x49, 0x55, 0x22, 0x20, /* & */
00361     0x00, 0x05, 0x03, 0x00, 0x00, /* ' */
00362     0x00, 0x1c, 0x22, 0x41, 0x00, /* ( */
00363     0x00, 0x41, 0x22, 0x1c, 0x00, /* ) */
00364     0x14, 0x08, 0x3e, 0x08, 0x14, /* // */
00365     0x08, 0x08, 0x3e, 0x08, 0x08, /* + */
00366     0x50, 0x30, 0x00, 0x00, 0x00, /* , */
00367     0x08, 0x08, 0x08, 0x08, 0x08, /* - */
00368     0x00, 0x60, 0x60, 0x00, 0x00, /* . */
00369     0x20, 0x10, 0x08, 0x04, 0x02, /* / */
00370     0x3e, 0x51, 0x49, 0x45, 0x3e, /* 0      0x30 */
00371     0x00, 0x42, 0x7f, 0x40, 0x00, /* 1 */
00372     0x42, 0x61, 0x51, 0x49, 0x46, /* 2 */
00373     0x21, 0x41, 0x45, 0x4b, 0x31, /* 3 */
00374     0x18, 0x14, 0x12, 0x7f, 0x10, /* 4 */
00375     0x27, 0x45, 0x45, 0x45, 0x39, /* 5 */
00376     0x3c, 0x4a, 0x49, 0x49, 0x30, /* 6 */
00377     0x01, 0x71, 0x09, 0x05, 0x03, /* 7 */
00378     0x36, 0x49, 0x49, 0x49, 0x36, /* 8 */
00379     0x06, 0x49, 0x49, 0x29, 0x1e, /* 9 */
00380     0x00, 0x36, 0x36, 0x00, 0x00, /* : */
00381     0x00, 0x56, 0x36, 0x00, 0x00, /* ; */
00382     0x08, 0x14, 0x22, 0x41, 0x00, /* < */
00383     0x14, 0x14, 0x14, 0x14, 0x14, /* = */
00384     0x00, 0x41, 0x22, 0x14, 0x08, /* > */
00385     0x02, 0x01, 0x51, 0x09, 0x06, /* ? */
00386     0x3e, 0x41, 0x5d, 0x55, 0x1e, /* @      0x40 */
00387     0x7e, 0x11, 0x11, 0x11, 0x7e, /* A */
00388     0x7f, 0x49, 0x49, 0x49, 0x36, /* B */
00389     0x3e, 0x41, 0x41, 0x41, 0x22, /* C */
00390     0x7f, 0x41, 0x41, 0x22, 0x1c, /* D */
00391     0x7f, 0x49, 0x49, 0x49, 0x41, /* E */
00392     0x7f, 0x09, 0x09, 0x09, 0x01, /* F */
00393     0x3e, 0x41, 0x49, 0x49, 0x7a, /* G */
00394     0x7f, 0x08, 0x08, 0x08, 0x7f, /* H */
00395     0x00, 0x41, 0x7f, 0x41, 0x00, /* I */
00396     0x20, 0x40, 0x41, 0x3f, 0x01, /* J */
00397     0x7f, 0x08, 0x14, 0x22, 0x41, /* K */
00398     0x7f, 0x40, 0x40, 0x40, 0x40, /* L */
00399     0x7f, 0x02, 0x0c, 0x02, 0x7f, /* M */
00400     0x7f, 0x04, 0x08, 0x10, 0x7f, /* N */
00401     0x3e, 0x41, 0x41, 0x41, 0x3e, /* O */
00402     0x7f, 0x09, 0x09, 0x09, 0x06, /* P      0x50 */
00403     0x3e, 0x41, 0x51, 0x21, 0x5e, /* Q */
00404     0x7f, 0x09, 0x19, 0x29, 0x46, /* R */
00405     0x26, 0x49, 0x49, 0x49, 0x32, /* S */
00406     0x01, 0x01, 0x7f, 0x01, 0x01, /* T */
00407     0x3f, 0x40, 0x40, 0x40, 0x3f, /* U */
00408     0x1f, 0x20, 0x40, 0x20, 0x1f, /* V */
00409     0x3f, 0x40, 0x38, 0x40, 0x3f, /* W */
00410     0x63, 0x14, 0x08, 0x14, 0x63, /* X */
00411     0x07, 0x08, 0x70, 0x08, 0x07, /* Y */
00412     0x61, 0x51, 0x49, 0x45, 0x43, /* Z */
00413     0x00, 0x7f, 0x41, 0x41, 0x00, /* [ */
00414     0x02, 0x04, 0x08, 0x10, 0x20, /* \ */
00415     0x00, 0x41, 0x41, 0x7f, 0x00, /* ] */
00416     0x04, 0x02, 0x01, 0x02, 0x04, /* ^ */
00417     0x40, 0x40, 0x40, 0x40, 0x40, /* _ */
00418     0x00, 0x00, 0x03, 0x05, 0x00, /* `      0x60 */
00419     0x20, 0x54, 0x54, 0x54, 0x78, /* a */
00420     0x7F, 0x44, 0x44, 0x44, 0x38, /* b */
00421     0x38, 0x44, 0x44, 0x44, 0x44, /* c */
00422     0x38, 0x44, 0x44, 0x44, 0x7f, /* d */
00423     0x38, 0x54, 0x54, 0x54, 0x18, /* e */
00424     0x04, 0x04, 0x7e, 0x05, 0x05, /* f */
00425     0x08, 0x54, 0x54, 0x54, 0x3c, /* g */
00426     0x7f, 0x08, 0x04, 0x04, 0x78, /* h */
00427     0x00, 0x44, 0x7d, 0x40, 0x00, /* i */
00428     0x20, 0x40, 0x44, 0x3d, 0x00, /* j */
00429     0x7f, 0x10, 0x28, 0x44, 0x00, /* k */
00430     0x00, 0x41, 0x7f, 0x40, 0x00, /* l */
00431     0x7c, 0x04, 0x7c, 0x04, 0x78, /* m */
00432     0x7c, 0x08, 0x04, 0x04, 0x78, /* n */
00433     0x38, 0x44, 0x44, 0x44, 0x38, /* o */
00434     0x7c, 0x14, 0x14, 0x14, 0x08, /* p      0x70 */
00435     0x08, 0x14, 0x14, 0x14, 0x7c, /* q */
00436     0x7c, 0x08, 0x04, 0x04, 0x00, /* r */
00437     0x48, 0x54, 0x54, 0x54, 0x24, /* s */
00438     0x04, 0x04, 0x3f, 0x44, 0x44, /* t */
00439     0x3c, 0x40, 0x40, 0x20, 0x7c, /* u */
00440     0x1c, 0x20, 0x40, 0x20, 0x1c, /* v */
00441     0x3c, 0x40, 0x30, 0x40, 0x3c, /* w */
00442     0x44, 0x28, 0x10, 0x28, 0x44, /* x */
00443     0x0c, 0x50, 0x50, 0x50, 0x3c, /* y */
00444     0x44, 0x64, 0x54, 0x4c, 0x44, /* z */
00445     0x08, 0x36, 0x41, 0x41, 0x00, /* { */
00446     0x00, 0x00, 0x77, 0x00, 0x00, /* | */
00447     0x00, 0x41, 0x41, 0x36, 0x08, /* } */
00448     0x08, 0x08, 0x2a, 0x1c, 0x08  /* ~ */
00449 };
00450 
00451 void DisplayN18::drawCharacter(int x, int y, const char character, unsigned short foreColor, unsigned short backColor, unsigned char fontSize) {
00452     if (character > 126 || character < 32)
00453         return;
00454 
00455     unsigned short* horizontal = new unsigned short[DisplayN18::CHAR_HEIGHT * fontSize];
00456     for (int i = 0; i < DisplayN18::CHAR_WIDTH; i++) {
00457         for (int j = 0; j < DisplayN18::CHAR_HEIGHT; j++)
00458             for (int k = 0; k < fontSize; k++)
00459                 horizontal[j * fontSize + k] = characters[(character - 32) * 5 + i] & (1 << j) ? foreColor : backColor;
00460 
00461         for (int k = 0; k < fontSize; k++)
00462             this->draw(horizontal, x + i * fontSize + k, y, 1, DisplayN18::CHAR_HEIGHT * fontSize);
00463     }
00464 
00465     for (int i = 0; i < DisplayN18::CHAR_HEIGHT; i++)
00466         for (int k = 0; k < fontSize; k++)
00467             horizontal[i * fontSize + k] = backColor;
00468 
00469     for (int k = 0; k < fontSize; k++)
00470         this->draw(horizontal, x + DisplayN18::CHAR_WIDTH * fontSize + k, y, 1, DisplayN18::CHAR_HEIGHT * fontSize);
00471 
00472     delete[] horizontal;
00473 }
00474 
00475 void DisplayN18::drawString(int x, int y, const char* str, unsigned short foreColor, unsigned short backColor, unsigned char fontSize) {
00476     if (*str == '\0')
00477         return;
00478 
00479     do {
00480         this->drawCharacter(x, y, *str, foreColor, backColor, fontSize);
00481         
00482         x += (DisplayN18::CHAR_WIDTH + DisplayN18::CHAR_SPACING) * fontSize;
00483     } while (*(++str) != '\0');
00484 }