#include #include #include #include #define Screen ((char *)0x400) // make space until 0x2000 for code and data #pragma region( lower, 0x0a00, 0x2000, , , {code, data} ) // then space for our sprite data #pragma section( spriteset, 0) #pragma region( spriteset, 0x2000, 0x2c00, , , {spriteset} ) // everything beyond will be code, data, bss and heap to the end #pragma region( main, 0x2c00, 0xa000, , , {code, data, bss, heap, stack} ) // spriteset at fixed location #pragma data(spriteset) char spriteset[64 * 48] = {0}; #pragma data(data) char charset[32 * 8] = { #embed "../resources/scifiglyph.bin" }; const char * scrolltext[] = { "This sample uses", "six sprites", "multiplexed six", "times to provide", "twelve lines of", "text with eighteen", "characters each", "", "each character is", "extracted from a", "custom font into a", "new sprite and the", "sprites are then", "moved up the", "screen", "", "interrupts are", "used to switch the", "sprite vertical", "position and", "graphics", "data every two", "character lines" "", "", "", "", }; RIRQCode * spmux[6], final; // Expand a line of source text into buffer centered void readline(char * dp, char n) { const char * sp = scrolltext[n]; // Count number of characters char s = 0; while (sp[s]) s++; // Left padding char l = (18 - s) >> 1; char i = 0; while (i < l) dp[i++] = ' '; // Text in center s = 0; while (sp[s]) dp[i++] = sp[s++]; // Right padding while (i < 18) dp[i++] = ' '; } // Expand six characters into sprite void expandline(const char * line, char sppos, char ty) { // Target position for first character char * dp = spriteset + 64 * sppos + 3 * ty; char xl = 0; for(char x=0; x<6; x++) { // Source character data const char * sp = charset + 8 * (line[x] & 0x1f); // Copy eight rows dp[ 0] = sp[0]; dp[ 3] = sp[1]; dp[ 6] = sp[2]; dp[ 9] = sp[3]; dp[12] = sp[4]; dp[15] = sp[5]; dp[18] = sp[6]; dp[21] = sp[7]; // Next character dp++; xl++; // Advance to next sprite if (xl == 3) { dp += 61; xl = 0; } } } int main(void) { rirq_init(true); spr_init(Screen); // Vertical pixel offset sbyte oy = 0; // Index of top left sprite char sy = 128; // Loop over five rows of virtual sprites for(char i=0; i<5; i++) { // Allocate large rirq command with 12 writes RIRQCode * sp = rirq_alloc(12); spmux[i] = sp; // Six sprites per row for(char x=0; x<6; x++) { // Vertical sprite position rirq_write(sp, 2 * x + 0, &vic.spr_pos[x].y, 48 * (i + 1) + oy); // Sprite graphic rirq_write(sp, 2 * x + 1, Screen + 0x3f8 + x, sy + 1 + i); } // Place in list rirq_set(i, 48 * i + 46 + oy, spmux[i]); } // Final irq at bottom of screen rirq_build(&final, 0); rirq_set(5, 250, &final); // Placing top sprites for(int x=0; x<6; x++) spr_set(x, true, 40 + 48 * x, oy, 128, 1, false, true, true); // Initial sort and start of processing rirq_sort(); rirq_start(); // Buffer for single line char line[20]; // Index into text to scroll char lpos = 0; for(;;) { // Wait for end of irq list rirq_wait(); // Advance one pixel line oy--; if (oy < 0) { // Advance one row of sprites oy += 48; sy += 6; if (sy == 128 + 36) sy = 128; } // Update interrupt position for(char i=0; i<5; i++) { int ty = 48 * i + 46 + oy; // No interrupts below screen bottom if (ty < 250) rirq_move(i, ty); else rirq_clear(i); } // Sort list rirq_sort(); // Reset row of top level sprites char sty = sy; for(int x=0; x<6; x++) { spr_move(x, 40 + 48 * x, oy); spr_image(x, sty); sty ++; } // Update write data in interrupt list for(char i=0; i<5; i++) { RIRQCode * sp = spmux[i]; // Check sprite rotation if (sty == 128 + 36) sty = 128; // Update vertical position and sprite data char py = 48 * (i + 1) + oy; for(char x=0; x<6; x++) { rirq_data(sp, 2 * x + 0, py); rirq_data(sp, 2 * x + 1, sty); sty ++; } } // Expand next line of text into bottom row of // sprites while invisible switch (oy) { case 46: case 42: readline(line, lpos); lpos++; if (lpos == 28) lpos = 0; break; case 45: expandline(line + 0, sty - 6 - 128, 0); break; case 44: expandline(line + 6, sty - 4 - 128, 0); break; case 43: expandline(line + 12, sty - 2 - 128, 0); break; case 41: expandline(line + 0, sty - 6 - 128, 12); break; case 40: expandline(line + 6, sty - 4 - 128, 12); break; case 39: expandline(line + 12, sty - 2 - 128, 12); break; } } return 0; }