PAL color video with Atmel controllers


November 13, 2007

Thinking about what game i should make, i been playing around with "custom" graphics, using a different character set. I worked out a way to still use 8 colors with just a minor change to the color DAC and changing my firmware to accept a 5bit character set, using the other 3 bits for color information. This gives me 32 usable characters, which is enough for a simple game: 10 characters for the digits 0..9 and 1 for space leaves me with 21 custom characters. I used the image of a well known game for my test:

  This doesn't mean i'm going to create a pacman game, it was just a sample of what the Mega88 can do.
The images on the left use only a half dot-clock (4 MHz). I can use 7 colors, with black always being the background color (there's actually an 8th color, but i guessed black pixels on a black background don't really count as a useable color combination).





November 17, 2007

I've been working on my color-DAC a bit, preparing the system to output the desired 4bit colors, instead of just the 3 bits i got working during last week. To that end, i've added the two external components i had planned to add: a 4bit selector (LS157 for example) and a 4bit D-Flip/flop (an LS174 will do for now). The logic components must be able to handle the 8MHz dot-clock i'm using, which is well in the range of the LS series (they are guaranteed to handle 30MHz at 5 Volts).

0 1 2 3 4 5 6 7
8 9 A B C D E F

Above is a sample of the colortable created by the DAC (see screenshot of actual color palette).
As described earlier, the DAC differs from a standard RGB-DAC in that it gives a 56% luminousity for the first 8 entries, and adds 44% when the I-signal is high. This gives the best approximation of the Commodore 64 palette, missing only 2 colors (orange and brown)
Click to enlarge
Original (24bit)
Click to enlarge
Mega-console
In addition, i have compaired my graphics system to the palettes featured on Wikipedia and decided to show what their parrot would look like using the 16 colors above (if it would fit in the Atmel's memory: it requies 8kB).

The result is quite amazing!

This "hi-resolution" image has the Atmel spit out ONLY 75 pixels each scanline, which i'm positive i can accomplish. However, it would require a totally different approach to output the pixel data and i may deal with it later.
Maybe using a Mega64 with 64kB of external RAM it might be possible to create "hi-res" images like the parrot. A full-screen 4bit image takes 16kB of memory; an 8bit image would be even easier to output and would take up 32kB of memory. But for now, i'll just stick to my 32x25 charachter screen. Using character combinations, it is possible to display a 64x50 pixel image, occupying only 1600 bytes.




November 18, 2007

To be able to use the Mega-Console as it was suppose to be (using my ATMega88) i need to rethink the screensize again. The Mega88 has only 1kB of SRAM at its disposal. Of that RAM i need to reserve some for system variables and of course some for stack space. I've come to a reasonable resolution of 24x20 characters, resulting in 480 bytes for character data and simular RAM space for color data. This leaves 64 bytes for variables and stack.

Considering the screen layout of the Tetris-game i wanted to make, the characters would have to be arranged as 24 rows of 20 characters each (Tetris requires a vertical game area). If i make the game area 12 characters wide, it leaves 8 characters for score keeping, which is more than enough.

The sample image on the left shows how it should look once it's complete. Although the current hardware supports a seperate user-defined background color for each character, this screen layout does not require it. The result is satisfying when the entire screen uses black as its background color.





November 20, 2007

I've written a few new subroutines handling block positioning & display. The images below are all screenshots of various steps within the process. Some of them are just testscreens, while others show the progress towards the "tetris" objective. All are static images.


New resolution:
something's wrong...

Tetris screen!

Block display test
Seems to work :)

Fill up the
game area

Let's create a
sample

Now, all i have to code is the gameplay itself.




November 23, 2007

Today i created the gameplay and scoring. Tomorrow i'll have to still add highscore saving (internal EEPROM).

Scoring is as follows:
1 line: 50
2 lines: 150
3 lines: 350
4 lines: 750

Calculation is simple: the first line is 50 points. Every next line within the same "turn" is double the score of the previous line. This way i get the scores as shown above: 50 for the first line, then add 2*50 for the second line, etc...

Since the last digit will always be a zero, it's displayed all the time and i don't need to include it in my scoring variable. I reserved a 16bit word for scores, meaning one can score upto a 655,350 points maximum. Any score above that value will simply wrap around, but it would require 874 four-line combos or over 13,000 single lines to reach it. I seriously doubt anyone would want to play that long!

The block color is randomly chosen, just like the block type and rotation: they're all part of a 16bit random word: the lower byte determines which block to use, while the upper byte defines the color.

The code for pseudo-random number generation i took from the Commodore 64 kernel. I translated it to AVR Assembler and optimized it a bit still: it is now only 18 instructions (including the return). It was added to the system kernel, so other projects can access it as well.

The game is first started by the user pressing the firebutton, and using the system timer (which counts number of ticks since system startup) as a random seed. Even when holding down fire during startup, it is unlikely the player will get the same blocks as the last time he started the system, because the "randomize" instruction is executed when the button is released.

I have not yet implemented levels, but the software does contain an internal SPEED variable, that i can change with each level. Level 1 starts at 40/50th of a second (40 PAL frames) for each step. I'm thinking about decreasing that steptime by 2/50 for every level, resulting in 20 possible levels (i tried it at 5/50, and it's damn hard to play at that speed). Assuming one can score 100 points for each line on average and i want to increase after every 20 lines, the level would change every 2000 points reaching level 20 at 40,000 points. Because i want the program to be as short and simple as possible, i'll just use the score high-byte for level checking: level 2 starts at 2560 points.




Sounds