1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-12-02 04:49:44 +00:00
8bitworkshop/presets/c64/scrolling_text.c

163 lines
34 KiB
C
Raw Normal View History

2022-08-25 20:52:04 +00:00
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <peekpoke.h>
#include <string.h>
#include <c64.h>
#include <cbm_screen_charmap.h>
#include "common.h"
//#link "common.c"
#include "rasterirq.h"
//#link "rasterirq.ca65"
// generated from https://8bitworkshop.com/bitmapfontgenerator/
// 16 x 32 MSB first y offset 6 Terminus
#define LOCHAR 32
#define HICHAR 127
#define FONT_BWIDTH 2
#define FONT_HEIGHT 32
#define FONT_ROWS (FONT_HEIGHT/8)
const char FONT[HICHAR-LOCHAR+1][FONT_HEIGHT*FONT_BWIDTH] = {
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x3F,0xFC,0x3F,0xFC,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x3F,0xFC,0x3F,0xFC,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x0F,0xF0,0x1F,0xF8,0x39,0x9C,0x31,0x8C,0x31,0x80,0x31,0x80,0x31,0x80,0x39,0x80,0x1F,0xF0,0x0F,0xF8,0x01,0x9C,0x01,0x8C,0x01,0x8C,0x01,0x8C,0x31,0x8C,0x39,0x9C,0x1F,0xF8,0x0F,0xF0,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x18,0x3F,0x18,0x33,0x30,0x33,0x30,0x3F,0x60,0x1E,0x60,0x00,0xC0,0x00,0xC0,0x01,0x80,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0xF0,0x0D,0xF8,0x19,0x98,0x19,0x98,0x31,0xF8,0x30,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x1F,0xC0,0x38,0xE0,0x30,0x60,0x30,0x60,0x30,0x60,0x38,0xE0,0x1D,0xC0,0x0F,0x80,0x0F,0x00,0x1F,0x8C,0x39,0xDC,0x70,0xF8,0x60,0x70,0x60,0x30,0x60,0x30,0x60,0x70,0x70,0xF8,0x3F,0xDC,0x1F,0x8C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0xE0,0x01,0xC0,0x03,0x80,0x03,0x00,0x07,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x07,0x00,0x03,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xC0,0x00,0xE0,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xE0,0x00,0xC0,0x01,0xC0,0x03,0x80,0x07,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38,0x1C,0x70,0x0E,0xE0,0x07,0xC0,0x03,0x80,0x7F,0xFC,0x7F,0xFC,0x03,0x80,0x07,0xC0,0x0E,0xE0,0x1C,0x70,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x3F,0xFC,0x3F,0xFC,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
#define SCREEN 0x400
#define BITMAP 0x3000
#define SCROLL_TOP 10
#define SCROLL_ROWS FONT_ROWS
#define TOP_Y (SCROLL_TOP*8+50)
#define BOTTOM_Y (TOP_Y+SCROLL_ROWS*8)
byte scroll_x = 0;
byte msg_x = 0;
byte msg_index = 0;
byte fonttile_index = 1;
const byte* get_font_ptr(char ch) {
return FONT[ch - LOCHAR];
}
word get_charbitmap_addr(char code) {
return BITMAP + code*8;
}
const char *MSG =
" HELLO WORLD! THIS IS SOME *BIG*"
" TEXT SCROLLING! THE BITMAP FONT IS"
" 16 X 32 PIXELS."
" EACH TIME WE SCROLL 8 PIXELS,"
" WE DRAW INTO 4 CHARACTER TILES,"
" DISPLAYING 160 AT ANY GIVEN TIME."
" THE RAINBOW EFFECT IS JUST FROM"
" SETTING CHARACTER COLORS IN COLOR RAM."
" MESSAGE REPEATS .........."
;
char get_next_char() {
char ch = MSG[msg_index];
if (ch == 0 || ch == 128) {
msg_index = 0;
ch = MSG[0];
}
return ch;
}
byte get_char_for_row(byte row) {
byte x = msg_x;
byte x1 = x % FONT_BWIDTH;
char code = fonttile_index + row;
word bmp = get_charbitmap_addr(code);
char nextchar = get_next_char();
const char* fptr = get_font_ptr(nextchar)
+ row*8*FONT_BWIDTH
+ x1;
byte i;
for (i=0; i<8; i++) {
POKE(bmp+i, fptr[i*FONT_BWIDTH]);
}
return code;
}
void next_msg_column() {
// increment variables
fonttile_index += FONT_ROWS;
if (fonttile_index >= 1+40*FONT_ROWS) {
fonttile_index = 1;
}
if ((++msg_x % FONT_BWIDTH) == 0) {
msg_index++;
}
}
void draw_right_column() {
// get the top-right corner address of scroll area
word addr = SCRNADR(SCREEN, 39, SCROLL_TOP);
byte row;
// draw one character per row
for (row=0; row<SCROLL_ROWS; row++) {
POKE(addr, get_char_for_row(row));
addr += 40;
}
}
void scroll_one_column_left() {
// copy several rows of screen memory
// backwards one byte
const word start = SCRNADR(SCREEN, 0, SCROLL_TOP);
const word nbytes = SCROLL_ROWS*40-1;
memcpy((byte*)start, (byte*)start+1, nbytes);
// draw the right column of characters
draw_right_column();
// increment variables
next_msg_column();
}
void scroll_one_pixel_left() {
// scroll left one pixel
scroll_x--;
// set scroll register with lower three bits
VIC.ctrl2 = (VIC.ctrl2 & ~7) | (scroll_x & 7);
// move screen memory if the scroll register
// has just gone past 0 and wrapped to 7
if ((scroll_x & 7) == 7) {
scroll_one_column_left();
}
// double-speed! (can comment this out)
scroll_x--;
}
void display_list() {
VIC.bgcolor[0] = COLOR_BLACK;
DLIST_NEXT(BOTTOM_Y);
VIC.bgcolor[0] = COLOR_GRAY1;
DLIST_RESTART(TOP_Y);
}
void set_row_color(byte line, byte color) {
memset((byte*)COLOR_RAM+line*40, color, 40);
}
void main(void) {
// clear the screen to 0 (not ' ' space)
memset((byte*)SCREEN, 0, 0x400);
// set color RAM for each row of chars
set_row_color(SCROLL_TOP+0, COLOR_CYAN);
set_row_color(SCROLL_TOP+1, COLOR_GREEN);
set_row_color(SCROLL_TOP+2, COLOR_YELLOW);
set_row_color(SCROLL_TOP+3, COLOR_LIGHTRED);
// set new address for character bitmaps
SET_VIC_BITMAP(BITMAP);
// set 38 column mode (for X scrolling)
VIC.ctrl2 = 0b00000000;
// setup IRQs to change colors
DLIST_SETUP(display_list);
// infinite loop
while (1) {
waitvsync();
scroll_one_pixel_left();
}
}