initial commit
This commit is contained in:
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
../../bin/oscar64 joycontrol.c
|
||||
../../bin/oscar64 multiplexer.c -n
|
||||
../../bin/oscar64 creditroll.c -n
|
||||
../../bin/oscar64 -n sprmux32.c -O2 -dVSPRITES_MAX=32 -dNUM_IRQS=28
|
||||
../../bin/oscar64 -n sprmux64.c
|
||||
@@ -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;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
@@ -0,0 +1,52 @@
|
||||
#include <c64/sprites.h>
|
||||
#include <c64/joystick.h>
|
||||
#include <string.h>
|
||||
|
||||
char spdata[] = {
|
||||
#embed "../resources/friendlybear.bin"
|
||||
};
|
||||
|
||||
int spx, spy;
|
||||
|
||||
#define SpriteData ((char *)0x0380)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Copy the sprite data
|
||||
memcpy(SpriteData, spdata, 128);
|
||||
|
||||
// Initialize the sprite system
|
||||
spr_init((char*)0x0400);
|
||||
|
||||
// Center screen position
|
||||
spx = 160;
|
||||
spy = 100;
|
||||
|
||||
// Two sprites, one black in front hires and one multicolor in back
|
||||
spr_set(0, true, spx, spy, 0x03c0 / 64, VCOL_BLACK, false, false, false);
|
||||
spr_set(1, true, spx, spy, 0x0380 / 64, VCOL_ORANGE, true, false, false);
|
||||
|
||||
// Multicolor sprite colors
|
||||
vic.spr_mcolor0 = VCOL_BROWN;
|
||||
vic.spr_mcolor1 = VCOL_WHITE;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
// Poll joytick
|
||||
joy_poll(0);
|
||||
|
||||
// Change position according to joystick
|
||||
spx += joyx[0];
|
||||
spy += joyy[0];
|
||||
|
||||
// Move sprites on screen
|
||||
spr_move(0, spx, spy);
|
||||
spr_move(1, spx, spy);
|
||||
|
||||
// Wait for one frame iteration
|
||||
vic_waitFrame();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
call ..\..\bin\oscar64 joycontrol.c
|
||||
call ..\..\bin\oscar64 multiplexer.c -n
|
||||
call ..\..\bin\oscar64 creditroll.c -n
|
||||
call ..\..\bin\oscar64 -n sprmux32.c -O2 -dVSPRITES_MAX=32 -dNUM_IRQS=28
|
||||
call ..\..\bin\oscar64 -n sprmux64.c
|
||||
@@ -0,0 +1,14 @@
|
||||
%.prg: %.c
|
||||
@echo "Compiling sample file" $<
|
||||
@$(OSCAR64_CC) $(OSCAR64_CFLAGS) $<
|
||||
|
||||
all: joycontrol.prg multiplexer.prg creditroll.prg sprmux32.prg sprmux64.prg
|
||||
|
||||
joycontrol.prg: joycontrol.c
|
||||
@$(OSCAR64_CC) $<
|
||||
|
||||
sprmux32.prg: sprmux32.c
|
||||
@$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< -O2 -dVSPRITES_MAX=32 -dNUM_IRQS=28
|
||||
|
||||
clean:
|
||||
@$(RM) *.asm *.int *.lbl *.map *.prg *.bcs
|
||||
@@ -0,0 +1,90 @@
|
||||
#include <c64/vic.h>
|
||||
#include <c64/rasterirq.h>
|
||||
#include <c64/sprites.h>
|
||||
#include <math.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, 0x2800, , , {spriteset} )
|
||||
|
||||
// everything beyond will be code, data, bss and heap to the end
|
||||
|
||||
#pragma region( main, 0x2800, 0xa000, , , {code, data, bss, heap, stack} )
|
||||
|
||||
|
||||
// spriteset at fixed location
|
||||
|
||||
#pragma data(spriteset)
|
||||
|
||||
char spriteset[2048] = {
|
||||
#embed "../resources/digitsprites.bin"
|
||||
};
|
||||
|
||||
#pragma data(data)
|
||||
|
||||
// sinus table for circular movement
|
||||
|
||||
int sintab[128];
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// calculate sine table
|
||||
for(int i=0; i<128; i++)
|
||||
sintab[i] = (int)(70 * sin(i * PI / 64));
|
||||
|
||||
// enable raster interrupt via kernal path
|
||||
rirq_init(true);
|
||||
|
||||
// initialize sprite multiplexer
|
||||
vspr_init(Screen);
|
||||
|
||||
// initialize sprites
|
||||
for(int i=0; i<16; i++)
|
||||
{
|
||||
vspr_set(i, 30 + 16 * i, 220 - 8 * i, (unsigned)&(spriteset[0]) / 64 + i, (i & 7) + 8);
|
||||
}
|
||||
|
||||
// initial sort and update
|
||||
vspr_sort();
|
||||
vspr_update();
|
||||
rirq_sort();
|
||||
|
||||
// start raster IRQ processing
|
||||
rirq_start();
|
||||
|
||||
// animation loop
|
||||
unsigned j = 0;
|
||||
for(;;)
|
||||
{
|
||||
// move sprites around
|
||||
char k = j >> 4;
|
||||
for(char i=0; i<16; i++)
|
||||
{
|
||||
vspr_move(i, 200 + sintab[(j + 8 * i) & 127] + sintab[k & 127], 150 + sintab[(j + 8 * i + 32) & 127] + sintab[(k + 32) & 127]);
|
||||
}
|
||||
j++;
|
||||
|
||||
// sort virtual sprites by y position
|
||||
vspr_sort();
|
||||
|
||||
// wait for raster IRQ to reach and of frame
|
||||
rirq_wait();
|
||||
|
||||
// update sprites back to normal and set up raster IRQ for second set
|
||||
vspr_update();
|
||||
|
||||
// sort raster IRQs
|
||||
rirq_sort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
@@ -0,0 +1,126 @@
|
||||
#include <c64/vic.h>
|
||||
#include <c64/sprites.h>
|
||||
#include <c64/rasterirq.h>
|
||||
#include <c64/memmap.h>
|
||||
#include <c64/cia.h>
|
||||
|
||||
static const sbyte sintab[256] = {
|
||||
0, 2, 4, 7, 9, 11, 13, 15, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 55, 57, 59, 60,
|
||||
62, 64, 65, 67, 68, 70, 71, 72, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 85, 86, 87, 87, 88, 88, 89, 89, 89, 90, 90, 90, 90,
|
||||
90, 90, 90, 90, 90, 89, 89, 89, 88, 88, 87, 87, 86, 85, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 72, 71, 70, 68, 67, 65, 64,
|
||||
62, 60, 59, 57, 55, 54, 52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 28, 26, 24, 22, 20, 18, 15, 13, 11, 9, 7, 4, 2,
|
||||
0, -2, -4, -7, -9, -11, -13, -15, -18, -20, -22, -24, -26, -28, -30, -32, -34, -36, -38, -40, -42, -44, -46, -48, -50, -52, -54, -55, -57, -59, -60,
|
||||
-62, -64, -65, -67, -68, -70, -71, -72, -74, -75, -76, -77, -78, -79, -80, -81, -82, -83, -84, -85, -85, -86, -87, -87, -88, -88, -89, -89, -89, -90, -90, -90, -90,
|
||||
-90, -90, -90, -90, -90, -89, -89, -89, -88, -88, -87, -87, -86, -85, -85, -84, -83, -82, -81, -80, -79, -78, -77, -76, -75, -74, -72, -71, -70, -68, -67, -65, -64,
|
||||
-62, -60, -59, -57, -55, -54, -52, -50, -48, -46, -44, -42, -40, -38, -36, -34, -32, -30, -28, -26, -24, -22, -20, -18, -15, -13, -11, -9, -7, -4, -2
|
||||
};
|
||||
|
||||
static const sbyte costab[256] = {
|
||||
120, 120, 120, 120, 119, 119, 119, 118, 118, 117, 116, 116, 115, 114, 113, 112, 111, 110, 108, 107, 106, 104, 103, 101, 100, 98, 96, 95, 93, 91, 89, 87,
|
||||
85, 83, 81, 78, 76, 74, 71, 69, 67, 64, 62, 59, 57, 54, 51, 49, 46, 43, 40, 38, 35, 32, 29, 26, 23, 21, 18, 15, 12, 9, 6, 3,
|
||||
0, -3, -6, -9, -12, -15, -18, -21, -23, -26, -29, -32, -35, -38, -40, -43, -46, -49, -51, -54, -57, -59, -62, -64, -67, -69, -71, -74, -76, -78, -81, -83,
|
||||
-85, -87, -89, -91, -93, -95, -96, -98, -100, -101, -103, -104, -106, -107, -108, -110, -111, -112, -113, -114, -115, -116, -116, -117, -118, -118, -119, -119, -119, -120, -120, -120,
|
||||
-120, -120, -120, -120, -119, -119, -119, -118, -118, -117, -116, -116, -115, -114, -113, -112, -111, -110, -108, -107, -106, -104, -103, -101, -100, -98, -96, -95, -93, -91, -89, -87,
|
||||
-85, -83, -81, -78, -76, -74, -71, -69, -67, -64, -62, -59, -57, -54, -51, -49, -46, -43, -40, -38, -35, -32, -29, -26, -23, -21, -18, -15, -12, -9, -6, -3,
|
||||
0, 3, 6, 9, 12, 15, 18, 21, 23, 26, 29, 32, 35, 38, 40, 43, 46, 49, 51, 54, 57, 59, 62, 64, 67, 69, 71, 74, 76, 78, 81, 83,
|
||||
85, 87, 89, 91, 93, 95, 96, 98, 100, 101, 103, 104, 106, 107, 108, 110, 111, 112, 113, 114, 115, 116, 116, 117, 118, 118, 119, 119, 119, 120, 120, 120
|
||||
};
|
||||
|
||||
#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, 0x2800, , , {spriteset} )
|
||||
|
||||
// everything beyond will be code, data, bss and heap to the end
|
||||
|
||||
#pragma region( main, 0x2800, 0xa000, , , {code, data, bss, heap, stack} )
|
||||
|
||||
|
||||
// spriteset at fixed location
|
||||
|
||||
#pragma data(spriteset)
|
||||
|
||||
static const char spriteset[2048] = {
|
||||
#embed "../resources/digitsprites.bin"
|
||||
};
|
||||
|
||||
#pragma data(data)
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Disable interrupts while setting up
|
||||
__asm { sei };
|
||||
|
||||
// Kill CIA interrupts
|
||||
cia_init();
|
||||
|
||||
mmap_set(MMAP_NO_ROM);
|
||||
|
||||
// enable raster interrupt via direct path
|
||||
rirq_init(false);
|
||||
|
||||
// initialize sprite multiplexer
|
||||
vspr_init(Screen);
|
||||
|
||||
// initialize sprites
|
||||
for(char i=0; i<32; i++)
|
||||
{
|
||||
vspr_set(i, 30 + 8 * i, 220 - 4 * i, (unsigned)&(spriteset[0]) / 64 + (i & 15), (i & 7) + 8);
|
||||
}
|
||||
|
||||
// initial sort and update
|
||||
vspr_sort();
|
||||
vspr_update();
|
||||
rirq_sort();
|
||||
|
||||
// start raster IRQ processing
|
||||
rirq_start();
|
||||
|
||||
// Black screen
|
||||
vic.color_border = 0;
|
||||
vic.color_back = 0;
|
||||
|
||||
// animation loop
|
||||
unsigned j = 0, t = 0;
|
||||
unsigned k = 91;
|
||||
for(;;)
|
||||
{
|
||||
// Use MSB as start position
|
||||
j = t << 8;
|
||||
|
||||
// Unroll movement loop for performance
|
||||
#pragma unroll(full)
|
||||
for(char i=0; i<32; i++)
|
||||
{
|
||||
vspr_move(i, 170 + costab[((j >> 8) + 8 * i) & 255], 140 + sintab[(t + 8 * i) & 255]);
|
||||
j += k;
|
||||
}
|
||||
|
||||
// Advance animation
|
||||
t+=3;
|
||||
k++;
|
||||
|
||||
// sort virtual sprites by y position
|
||||
vspr_sort();
|
||||
|
||||
// wait for raster IRQ to reach and of frame
|
||||
rirq_wait();
|
||||
|
||||
// update sprites back to normal and set up raster IRQ for sprites 8 to 31
|
||||
vspr_update();
|
||||
|
||||
// sort raster IRQs
|
||||
rirq_sort();
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.8 KiB |
@@ -0,0 +1,185 @@
|
||||
#include <c64/vic.h>
|
||||
#include <c64/rasterirq.h>
|
||||
#include <c64/memmap.h>
|
||||
#include <c64/cia.h>
|
||||
|
||||
static const sbyte costab[256] = {
|
||||
30, 30, 30, 30, 30, 30, 30, 30, 29, 29, 29, 29, 29, 28, 28, 28, 28, 27, 27, 27, 26, 26, 26, 25, 25, 25, 24, 24, 23, 23, 22, 22,
|
||||
21, 21, 20, 20, 19, 18, 18, 17, 17, 16, 15, 15, 14, 13, 13, 12, 11, 11, 10, 9, 9, 8, 7, 7, 6, 5, 4, 4, 3, 2, 1, 1,
|
||||
0, -1, -1, -2, -3, -4, -4, -5, -6, -7, -7, -8, -9, -9, -10, -11, -11, -12, -13, -13, -14, -15, -15, -16, -17, -17, -18, -18, -19, -20, -20,
|
||||
-21, -21, -22, -22, -23, -23, -24, -24, -25, -25, -25, -26, -26, -26, -27, -27, -27, -28, -28, -28, -28, -29, -29, -29, -29, -29, -30, -30, -30, -30, -30, -30, -30,
|
||||
-30, -30, -30, -30, -30, -30, -30, -30, -29, -29, -29, -29, -29, -28, -28, -28, -28, -27, -27, -27, -26, -26, -26, -25, -25, -25, -24, -24, -23, -23, -22, -22,
|
||||
-21, -21, -20, -20, -19, -18, -18, -17, -17, -16, -15, -15, -14, -13, -13, -12, -11, -11, -10, -9, -9, -8, -7, -7, -6, -5, -4, -4, -3, -2, -1, -1,
|
||||
0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17, 17, 18, 18, 19, 20, 20,
|
||||
21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30
|
||||
};
|
||||
|
||||
#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, 0x2040, , , {spriteset} )
|
||||
|
||||
// everything beyond will be code, data, bss and heap to the end
|
||||
|
||||
#pragma region( main, 0x2800, 0xa000, , , {code, data, bss, heap, stack} )
|
||||
|
||||
|
||||
// spriteset at fixed location
|
||||
|
||||
#pragma data(spriteset)
|
||||
|
||||
__export const char spriteset[64] = {
|
||||
#embed "../resources/ballsprite.bin"
|
||||
};
|
||||
|
||||
#pragma data(data)
|
||||
|
||||
// Control variables for the interrupt
|
||||
|
||||
char pphase; // global phase
|
||||
char poffset; // phase offset for this row of sprites
|
||||
char yoffset; // vertical offset for this row of sprites
|
||||
|
||||
// Interrupt routine switching to next row of sprites, invokes some lines after
|
||||
// start of previous row
|
||||
|
||||
__interrupt void setspr(void)
|
||||
{
|
||||
// Switch vertical position first, will not take effect
|
||||
// until after the current row of sprites is complete, so it
|
||||
// is done first
|
||||
#pragma unroll(full)
|
||||
for(char i=0; i<8; i++)
|
||||
vic.spr_pos[i].y = yoffset;
|
||||
|
||||
char phase = pphase + poffset; // Effective rotation phase for this row
|
||||
int step = costab[phase]; // 30 * Cosine of phase for x step
|
||||
int xpos0 = 172 - (step >> 1); // Half a step to the left
|
||||
int xpos1 = 172 + (step >> 1); // Half a step to the right
|
||||
|
||||
// Table for xpositions
|
||||
static unsigned xp[8];
|
||||
|
||||
// Calculate xpositions, four to the left and four to the right
|
||||
#pragma unroll(full)
|
||||
for(char i=0; i<4; i++)
|
||||
{
|
||||
xp[3 - i] = xpos0;
|
||||
xp[i + 4] = xpos1;
|
||||
|
||||
// Stepping left and right
|
||||
xpos0 -= step;
|
||||
xpos1 += step;
|
||||
}
|
||||
|
||||
// build highbyte for sprite pos
|
||||
char xymask = 0;
|
||||
if (phase & 0x80)
|
||||
{
|
||||
// put MSB into xymask bit
|
||||
#pragma unroll(full)
|
||||
for(char i=0; i<8; i++)
|
||||
xymask = ((unsigned)xymask | (xp[i] & 0xff00)) >> 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// put MSB into xymask bit
|
||||
#pragma unroll(full)
|
||||
for(char i=0; i<8; i++)
|
||||
xymask = ((unsigned)xymask | (xp[7 - i] & 0xff00)) >> 1;
|
||||
}
|
||||
|
||||
|
||||
// Wait for end of current sprite, xpos will take effect
|
||||
// at start of line, so we need to patch it after the last
|
||||
// pixel line has started
|
||||
vic_waitLine(yoffset - 3);
|
||||
|
||||
// Left to right or right to left to get a matching z order
|
||||
if (phase & 0x80)
|
||||
{
|
||||
// Update all sprite x LSB and color
|
||||
#pragma unroll(full)
|
||||
for(char i=0; i<8; i++)
|
||||
{
|
||||
vic.spr_pos[i].x = xp[i];
|
||||
vic.spr_color[i] = VCOL_ORANGE + i;
|
||||
}
|
||||
|
||||
// Update MSB
|
||||
vic.spr_msbx = xymask;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update all sprite x LSB and color
|
||||
#pragma unroll(full)
|
||||
for(char i=0; i<8; i++)
|
||||
{
|
||||
vic.spr_pos[i].x = xp[7 - i];
|
||||
vic.spr_color[i] = VCOL_ORANGE + (7 - i);
|
||||
}
|
||||
}
|
||||
// Update MSB
|
||||
vic.spr_msbx = xymask;
|
||||
}
|
||||
|
||||
// Eight raster interrupts
|
||||
RIRQCode spmux[8];
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Keep kernal alive
|
||||
rirq_init(true);
|
||||
|
||||
// Setup sprite images
|
||||
for(char i=0; i<8; i++)
|
||||
Screen[0x03f8 + i] = 128;
|
||||
|
||||
// Remaining sprite registers
|
||||
vic.spr_enable = 0xff;
|
||||
vic.spr_multi = 0xff;
|
||||
vic.spr_expand_x = 0x00;
|
||||
vic.spr_expand_y = 0x00;
|
||||
vic.spr_mcolor0 = VCOL_BLACK;
|
||||
vic.spr_mcolor1 = VCOL_WHITE;
|
||||
|
||||
// Setup raster interrupts
|
||||
for(char i=0; i<8; i++)
|
||||
{
|
||||
// Three operations per interrupt
|
||||
rirq_build(spmux + i, 3);
|
||||
// Store phase offset
|
||||
rirq_write(spmux + i, 0, &poffset, 11 * i);
|
||||
// Store vertical position
|
||||
rirq_write(spmux + i, 1, &yoffset, 52 + 25 * i);
|
||||
// Call sprite update function
|
||||
rirq_call(spmux + i, 2, setspr);
|
||||
|
||||
// Place raster interrupt 16 lines before sprite start to
|
||||
// give it enough time for processing
|
||||
rirq_set(i, 36 + 25 * i, spmux + i);
|
||||
}
|
||||
|
||||
// Sort interrupts and start processing
|
||||
rirq_sort();
|
||||
rirq_start();
|
||||
|
||||
// Forever
|
||||
for(;;)
|
||||
{
|
||||
// Advance phase
|
||||
pphase += 5;
|
||||
|
||||
// Wait for next frame
|
||||
vic_waitFrame();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 7.2 KiB |
Reference in New Issue
Block a user