initial commit
This commit is contained in:
@@ -0,0 +1,276 @@
|
||||
#include <c64/vic.h>
|
||||
#include <c64/rasterirq.h>
|
||||
#include <c64/sprites.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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 + 45 + 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 == 27)
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user