diff --git a/presets/coleco/climber.c b/presets/coleco/climber.c index 06d6365c..0a96bbd4 100644 --- a/presets/coleco/climber.c +++ b/presets/coleco/climber.c @@ -1,4 +1,9 @@ +/* +Demonstration game. +For more information, see "Making Games for the NES". +*/ + #include #include #include diff --git a/presets/coleco/cursorsmooth.c b/presets/coleco/cursorsmooth.c index 41d36d3d..9753d2dc 100644 --- a/presets/coleco/cursorsmooth.c +++ b/presets/coleco/cursorsmooth.c @@ -1,4 +1,9 @@ +/* +This demo animates two 16 x 16 sprites. +It also uses the collision detection bit. +*/ + #include #include #include @@ -48,6 +53,10 @@ void move_cursor(struct cvu_sprite *s, int controller) { if (cs.joystick & CV_DOWN) y++; if (cs.joystick & CV_UP) y--; + // M; + + // M; + // Make sure cursor doesn't leave the screen. if(x < 0) x = 0; if(x > 239) x = 239; diff --git a/presets/coleco/hello.c b/presets/coleco/hello.c index 8e89fa17..cde05cf1 100644 --- a/presets/coleco/hello.c +++ b/presets/coleco/hello.c @@ -1,25 +1,33 @@ +/* +This is a demonstration of integrating the C +standard I/O (stdio) functions with the display, +so that standard functions like printf() can be used. +*/ + #include #include #include #include #include +// overrides value in common.h #define COLS 40 #include "common.h" //#link "common.c" void setup_40_column_font() { - cv_set_image_table(IMAGE); - copy_default_character_set(); - cv_set_character_pattern_t(PATTERN); cv_set_screen_mode(CV_SCREENMODE_TEXT); + cv_set_image_table(IMAGE); + cv_set_character_pattern_t(PATTERN); + copy_default_character_set(); } -char cursor_x; -char cursor_y; +char cursor_x; // current cursor column +char cursor_y; // current cursor row +// clear the screen to ' ' (blank spaces) void clrscr() { cvu_vmemset(IMAGE, ' ', COLS*ROWS); } @@ -30,6 +38,8 @@ void setup_stdio() { clrscr(); } +// scroll the screen upward, by copying each row +// of VRAM to its previous row. void scrollup() { char buf[COLS]; char y; @@ -40,6 +50,7 @@ void scrollup() { cvu_vmemset(IMAGE + COLS*(ROWS-1), ' ', COLS); } +// move cursor to next line, scrolling when it hits the bottom. void newline() { if (cursor_y >= ROWS-1) { scrollup(); @@ -48,15 +59,18 @@ void newline() { } } +// write a character to the screen. int putchar(int ch) { switch (ch) { case '\n': - newline(); // TODO: scrolling + newline(); // move cursor to next line case '\r': - cursor_x = 0; + cursor_x = 0; // move cursor to start of line return 0; } + // output character to VRAM at cursor position cvu_voutb(ch, IMAGE + COLS*cursor_y + cursor_x); + // move cursor to right, going to next line if neccessary cursor_x++; if (cursor_x >= COLS) { newline(); @@ -64,6 +78,9 @@ int putchar(int ch) { } } +#ifdef __MAIN__ + +// test program void main() { unsigned char byteval = 123; signed char charval = 123; @@ -79,3 +96,5 @@ void main() { charval++, byteval++, shortval++); } } + +#endif diff --git a/presets/coleco/lines.c b/presets/coleco/lines.c index f5e8950a..0a8b2bd4 100644 --- a/presets/coleco/lines.c +++ b/presets/coleco/lines.c @@ -1,4 +1,10 @@ +/* +This demo draws pixels and lines in Mode 2. +Note that when lines of two different colors overlap, +they create "clashing" effects. +*/ + #include #include #include @@ -54,6 +60,8 @@ void draw_line(int x0, int y0, int x1, int y1, byte color) { } } +#ifdef _MAIN_ + void main() { setup_mode2(); cv_set_screen_active(true); @@ -61,3 +69,5 @@ void main() { draw_line(rand()&0xff, rand()&0xbf, rand()&0xff, rand()&0xbf, rand()&15); } } + +#endif diff --git a/presets/coleco/mode2bitmap.c b/presets/coleco/mode2bitmap.c index 18a5aa3b..4a00e1ce 100644 --- a/presets/coleco/mode2bitmap.c +++ b/presets/coleco/mode2bitmap.c @@ -1,4 +1,19 @@ +/* +Displays a bitmap using the TMS9928A's Mode 2. + +In Mode 2, the screen is horizontally divided into three +256×64 pixel areas, each of which gets its own character +set. By sequentially printing the characters 0 through 255 +in all three areas, the program can simulate a graphics mode +where each pixel can be set individually. + +The limitation is that every horizontal run of 8 pixels +can only have two colors (a foreground and background color.) + +The included Mode 2 bitmap was converted with a web utility: +http://msx.jannone.org/conv/ +*/ #include diff --git a/presets/coleco/mode2compressed.c b/presets/coleco/mode2compressed.c index 32e2c249..83cf825d 100644 --- a/presets/coleco/mode2compressed.c +++ b/presets/coleco/mode2compressed.c @@ -1,4 +1,9 @@ +/* +This demo uncompresses the Mode 2 bitmap from a +compressed LZG stream in ROM. This takes several times +longer than just copying it from ROM. +*/ #include diff --git a/presets/coleco/multicolor.c b/presets/coleco/multicolor.c index 8bf6a176..c76e08b8 100644 --- a/presets/coleco/multicolor.c +++ b/presets/coleco/multicolor.c @@ -1,5 +1,8 @@ /* -64x48 multicolor mode +Demonstrates the 64x48 multicolor mode. +This mode is a little tricky to implement, +but each pixel can have its own color with no +clashing effects. */ #include @@ -58,7 +61,9 @@ void draw_line(int x0, int y0, int x1, int y1, byte color) { if (e2 < dy) { err += dx; y0 += sy; } } } - + +#ifdef _MAIN_ + void main() { setup_multicolor(); cv_set_screen_active(true); @@ -67,3 +72,5 @@ void main() { } while (1); } + +#endif diff --git a/presets/coleco/musicplayer.c b/presets/coleco/musicplayer.c index 03a5980d..817c430a 100644 --- a/presets/coleco/musicplayer.c +++ b/presets/coleco/musicplayer.c @@ -1,4 +1,11 @@ +/* +Demonstrates playing multi-voice music on the SN76489A PSG +using the CVLib functions. + +Similar to the music example in "Making Arcade Games in C". +*/ + #include #include #include diff --git a/presets/coleco/shoot.c b/presets/coleco/shoot.c index 1ab3fa10..34939f4b 100644 --- a/presets/coleco/shoot.c +++ b/presets/coleco/shoot.c @@ -1,4 +1,9 @@ +/* +Demonstration game. +For more information, see "Making Arcade Games in C". +*/ + #include #include #include diff --git a/presets/coleco/siegegame.c b/presets/coleco/siegegame.c index 7c615e91..ef0b30ea 100644 --- a/presets/coleco/siegegame.c +++ b/presets/coleco/siegegame.c @@ -1,4 +1,9 @@ +/* +Demonstration game. +For more information, see "Making Arcade Games in C". +*/ + #include #include #include diff --git a/presets/coleco/simplemusic.c b/presets/coleco/simplemusic.c index 13c97eda..f2ef81ae 100644 --- a/presets/coleco/simplemusic.c +++ b/presets/coleco/simplemusic.c @@ -1,4 +1,12 @@ +/* +This demonstrates the cvu_play_music() function. +Command-line tools generate the music file from ABC source files. + +For more information, see: +http://www.colecovision.eu/ColecoVision/development/tutorial2.shtml +*/ + #include const uint16_t notes[] = { 12846, 12334, 11086, 10062, 10062, 9806, 10062, 10574, 11086, 10062, 11086, 12430, 11042, 12334, 12878, 14158, 14158, 12878, 13390, 13646, 10574, 9806, 10574, 12430, 12846, 12334, 11086, 10062, 10062, 9806, 10062, 10574, 11086, 10062, 11086, 12430, 11054, 12334, 12878, 14158, 14158, 12878, 13390, 13646, 10574, 10062, 10062, 10126, 11054, 12334, 12878, 14158, 13902, 14158, 14670, 14158, 13646, 12878, 13390, 13646, 3918, 12878, 14158, 13902, 12878, 12366, 12878, 12366, 12878, 11086, 10062, 9870, 12334, 11054, 11086, 10062, 10062, 9806, 10062, 10574, 11086, 10062, 11086, 12430, 11054, 12334, 12878, 14158, 14158, 12878, 13390, 13646, 10574, 10062, 10062, 10126, 0xffff }; @@ -8,18 +16,20 @@ const uint16_t notes[] = { 12846, 12334, 11086, 10062, 10062, 9806, 10062, 10574 struct cvu_music music; +// change screen colors to show how long the music +// routine takes to run after screen interrupt void play(void) { - cv_set_colors(CV_COLOR_BLACK, CV_COLOR_BLUE); - cvu_play_music(&music); - cv_set_colors(CV_COLOR_BLACK, CV_COLOR_BLACK); + cv_set_colors(CV_COLOR_BLACK, CV_COLOR_BLUE); + cvu_play_music(&music); + cv_set_colors(CV_COLOR_BLACK, CV_COLOR_BLACK); } void main(void) { - cvu_init_music(&music); - music.notes = notes; - cv_set_vint_handler(&play); - cv_set_screen_active(true); - for(;;); + cvu_init_music(&music); + music.notes = notes; + cv_set_vint_handler(&play); + cv_set_screen_active(true); + for(;;); } diff --git a/presets/coleco/stars.c b/presets/coleco/stars.c index 23662d40..5afefcf2 100644 --- a/presets/coleco/stars.c +++ b/presets/coleco/stars.c @@ -1,11 +1,35 @@ +/* +This is a demo of an animated starfield. +The TMS9918 has no scrolling registers, so scrolling +requires rewriting the pattern table on each frame. + +There is actually only one star in the pattern table, +just a single pixel. We move it vertically between 16 +different character tiles (8 * 16 = 128 pixels high). +We then draw vertical stripes of 8 repeating consecutive +characters into the image table. + +By randomly offsetting where we begin each stripe, we +create what appears to be a random starfield. +(If you look closely, you'll see there's exactly two +stars for every 8-pixel-wide vertical column.) + +This demo uses an interrupt handler to increment a +counter 60 times per second. We use this counter to +determine the new position of the star pixel when we animate. +*/ + #include #include +//#link "common.c" #include "common.h" +// the starting character index in the pattern table char starfield_base_char = 240; +// a random offset for every vertical column const char star_yoffsets[32] = { 31, 11, 25, 10, 21, 1, 9, 6, 22, 3, 7, 14, 15, 18, 0, 29, @@ -13,39 +37,48 @@ const char star_yoffsets[32] = { 13, 8, 26, 19, 23, 27, 2, 4 }; +// returns the tile index for every (x,y) position byte starfield_get_tile_xy(byte x, byte y) { return ((star_yoffsets[x] + y) & 15) + starfield_base_char; } +// set up starfield image and pattern table void starfield_setup() { // clear star patterns cvu_vmemset(PATTERN+starfield_base_char*8, 0, 16*8); + // write starfield image table for (byte x=0; x<32; x++) { for (byte y=0; y<28; y++) { putcharxy(x, y, starfield_get_tile_xy(x, y)); } + // set value in color table for each character cvu_voutb(COLOR_FG(CV_COLOR_WHITE), COLOR+((starfield_base_char+x)>>3)); } } +// call each frame to animate starfield void starfield_update() { static byte oldcounter; const byte mask = 0x7f; // 128 star bytes + // interrupt counter increments every frame + // use this value to determine new star position byte counter = vint_counter; + // base address in pattern table word base = PATTERN + starfield_base_char * 8; // erase old star, create new star in pattern table cvu_voutb(0, base + (oldcounter & mask)); cvu_voutb(8, base + (counter & mask)); + // make sure we remember counter value to erase + // in case we skip a frame oldcounter = counter; } #ifdef __MAIN__ -//#link "common.c" - void main() { vdp_setup(); + // set up default interrupt handler cv_set_vint_handler(&vint_handler); starfield_setup(); cv_set_screen_active(true); diff --git a/presets/coleco/text.c b/presets/coleco/text.c index 1c24aec4..af631a36 100644 --- a/presets/coleco/text.c +++ b/presets/coleco/text.c @@ -1,4 +1,9 @@ +/* +This is a demonstration of the TMS9928A's +40 x 24 monochrome text mode. +*/ + #include #include @@ -6,22 +11,31 @@ //#link "common.c" void setup_text_mode() { + // set screen mode to text cv_set_screen_mode(CV_SCREENMODE_TEXT); + // set image table address, which defines grid of characters cv_set_image_table(IMAGE); + // set pattern table address, which defines character graphics cv_set_character_pattern_t(PATTERN); + // clear VRAM to all zeroes cvu_vmemset(0, 0, 0x4000); + // copy default character set from ROM to VRAM copy_default_character_set(); } void show_text() { + // set background and foreground colors cv_set_colors(CV_COLOR_LIGHT_GREEN, CV_COLOR_BLACK); + // fill image table with '.' characters cvu_vmemset(IMAGE, '.', 40*24); - cvu_memtovmemcpy(IMAGE + 1, "Hello Professor Falken", 22); + // draw message at row 0, column 1 + cvu_memtovmemcpy(IMAGE + 1, "Greetings Professor Falken", 26); + // turn on display cv_set_screen_active(true); } void main() { setup_text_mode(); show_text(); - while (1); + while (1); // infinite loop } diff --git a/presets/coleco/text32.c b/presets/coleco/text32.c index 85a79cf7..4bf2370c 100644 --- a/presets/coleco/text32.c +++ b/presets/coleco/text32.c @@ -1,4 +1,14 @@ +/* +Demonstration of "standard" mode, which is 32 x 24 +characters. Each cell can have its own background and +foreground color, determined by the character in its +place. The color table contains 32 bytes, each byte +controlling the colors of a range of 8 characters. +For example, the first byte determines colors for +characters 0-7, the second byte for 8-15, etc. +*/ + #include #include @@ -20,7 +30,7 @@ void setup_32_column_font() { void show_text() { cvu_vmemset(IMAGE, '.', 32*24); - cvu_memtovmemcpy(IMAGE + 1, "Hello Professor Falken", 22); + cvu_memtovmemcpy(IMAGE + 1, "Greetings Professor Falken", 26); cv_set_screen_active(true); } @@ -29,6 +39,8 @@ void main() { setup_32_column_font(); show_text(); while (1) { - cvu_vmemset(COLOR+8, i++, 4); // set color for chars 64-95 + /* + cvu_vmemset(COLOR+8, i++, 4); // animate color for chars 64-95 + */ } }