Programming: Arduino
Check out my other articles:
- Galaga: Failed Attempt at writing a Game
- Sudoku
- Blockade / Snake
- Farkle
- Minesweeper
- Blackjack
- ADC Graph
- Analogue Clock
- Tetris
Galaga: Failed Attempt at writing a Game
I bought the 480 x 320 pixel version of the TFT LCD SmartGPU2 screen from Vizic with the intention of building a simple Space Invaders or Galaga game. My initial tests were disappointing - I wrote a simple app that would paint an enemy space ship on the screen, reset the region to black and move the ship a pixel to the next position on its path. Although the performance was reasonable, the screen flicker was distracting. I modified the code to repaint the ship over the top of the existing one (albeit moved by a pixel) and simply blacked out the remnants of the previous image using a black line but this did not seem to improve the flickering. It was also obvious that the performance of the board would not be sufficient to render an entire army of invaders.
Another option was to render the attackers from images stored on the SD card. A quick test confirmed that this was never going to work as the read performance is simply slow. To be honest, I think I knew this before I even wrote the code. This approach would be to use the memory read and write APIs to retrieve an image from the screen and repaint it at the new location. This presents a couple of problems ..
- the memory read function returns 3 byte colour code (RGB888) whereas the write API uses 2 byte colour codes (RGB565). This is a practical reality of using these TFT screens which only support 262,000 colours rather than the 16 million possible (though not necessarily distinguishable) with a full 3 byte RGB colour scheme. Vizic supports RGB88 for memory read operations and all SD card operations as this is the de facto standard. What I am yet to understand is whether each RGB888 code can simply be divided by 8 (the ratio between 2^8 / 2^5) to get a result .. I assume it can but is this an accurate rendering?
- a typical image is takes a lot of memory on a device that has only 1K of RAM. The images I am using for the enemy spaceships are 13 x 10 pixels in size. This equals 130 pixels and at 3 bytes per pixel to store colour information comes to a whopping 390 bytes or a third of the available memory. Although manageable for one enemy, I want a number of different enemies each of which will have two stances - arms up and arms down. As I cannot cache all of the required images within the available 1K of memory, I would need to read the image from screen memory, convert from RGB888 to RGB565 and render the new image on every change of image. This would mean that I would need to ensure that the image is on-screen all of the time.
I have played with the device a little more and now realise there is something I haven't tested yet- the SmartGPU2 comes with 16Kb of non-volatile EEPROM or flash memory segmented into eight 2kb pages. As the game starts up, I could render the RGB565 images into flash memory and render these to the screen as required. Though all in memory, the images would need to be copied from the SmartGPU2s' flash memory to the Arduino's onboard RAM and then back to the SmartGPU2's video RAM. By storing the rendered image in RGB565 format, no conversion would need to occur prior to rendering. However, I am not sure how the flash memory will perform when copying data back and forth.
I will definitely come back to this game to see if I can get it to work with the flash memory approach.