initial commit
This commit is contained in:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user