Added comments to source samples
This commit is contained in:
parent
b9a1689dc6
commit
2d0f20cadc
|
@ -320,6 +320,7 @@ void rirq_sort(void)
|
|||
rasterIRQNext[i] = rasterIRQRows[rasterIRQIndex[i]];
|
||||
|
||||
npos++;
|
||||
vic.raster = rasterIRQNext[nextIRQ] - 1;
|
||||
}
|
||||
|
||||
void rirq_start(void)
|
||||
|
|
|
@ -3,29 +3,38 @@
|
|||
#include <c64/memmap.h>
|
||||
#include <conio.h>
|
||||
|
||||
// Address of hires buffer and color buffer
|
||||
#define Screen ((char *)0xe000)
|
||||
#define Color ((char *)0xc800)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Install the IRQ trampoline
|
||||
mmap_trampoline();
|
||||
|
||||
// Turn of the kernal ROM
|
||||
mmap_set(MMAP_NO_ROM);
|
||||
|
||||
// Switch VIC into hires mode
|
||||
vic_setmode(VICM_HIRES, Color, Screen);
|
||||
|
||||
// Clear the screen
|
||||
memset(Screen, 0, 8000);
|
||||
memset(Color, 0x10, 1000);
|
||||
|
||||
// Loop over all pixels
|
||||
int py, px;
|
||||
|
||||
for(py=0; py<200; py++)
|
||||
{
|
||||
for(px=0; px<320; px++)
|
||||
{
|
||||
// Value in the complex plane
|
||||
|
||||
float xz = (float)px * (3.5 / 320.0)- 2.5;
|
||||
float yz = (float)py * (2.0 / 200.0) - 1.0;
|
||||
|
||||
// Iterate up to 32 times
|
||||
float x = 0.0, y = 0.0;
|
||||
int i;
|
||||
for(i=0; i<32; i++)
|
||||
|
@ -37,15 +46,19 @@ int main(void)
|
|||
x = xt;
|
||||
}
|
||||
|
||||
// Set a pixel if exceeds bound in less than 32 iterations
|
||||
if (i < 32)
|
||||
Screen[320 * (py >> 3) + (py & 7) + (px & ~7)] |= 0x80 >> (px & 7);
|
||||
}
|
||||
}
|
||||
|
||||
// Re-enable the kernal
|
||||
mmap_set(MMAP_NO_BASIC);
|
||||
|
||||
// Wait for key press
|
||||
getch();
|
||||
|
||||
// Restore VIC state
|
||||
vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -3,10 +3,12 @@
|
|||
#include <c64/memmap.h>
|
||||
#include <conio.h>
|
||||
|
||||
// Address of hires buffer and color buffers
|
||||
#define Screen ((char *)0xe000)
|
||||
#define Color ((char *)0xc800)
|
||||
#define Color2 ((char *)0xd800)
|
||||
|
||||
// Bit patters for eight different color pairs
|
||||
char colors[] = {
|
||||
0xff, 0xff,
|
||||
0xee, 0xbb,
|
||||
|
@ -21,27 +23,35 @@ char colors[] = {
|
|||
|
||||
int main(void)
|
||||
{
|
||||
// Install the IRQ trampoline
|
||||
mmap_trampoline();
|
||||
|
||||
// Turn of the kernal ROM
|
||||
mmap_set(MMAP_NO_ROM);
|
||||
|
||||
// Switch VIC into multicolor bitmap mode
|
||||
vic_setmode(VICM_HIRES_MC, Color, Screen);
|
||||
|
||||
// Clear the screen and set the colors
|
||||
vic.color_back = 0x00;
|
||||
|
||||
memset(Screen, 0, 8000);
|
||||
memset(Color, 0x27, 1000);
|
||||
memset(Color2, 0x03, 1000);
|
||||
|
||||
// Loop over all pixels
|
||||
int py, px;
|
||||
|
||||
for(py=0; py<100; py++)
|
||||
{
|
||||
for(px=0; px<160; px++)
|
||||
{
|
||||
// Value in the complex plane
|
||||
|
||||
float xz = (float)px * (3.5 / 160.0)- 2.5;
|
||||
float yz = (float)py * (2.4 / 100.0) - 1.2;
|
||||
|
||||
// Iterate up to 32 times
|
||||
float x = 0.0, y = 0.0;
|
||||
int i;
|
||||
for(i=0; i<32; i++)
|
||||
|
@ -55,20 +65,29 @@ int main(void)
|
|||
|
||||
if (i < 32)
|
||||
{
|
||||
// Position on screen
|
||||
char * dp = Screen + 320 * (py >> 2) + 2 * (py & 3) + 2 * (px & ~3);
|
||||
|
||||
// Mask of pixels to change
|
||||
char mask = 0xc0 >> (2 * (px & 3));
|
||||
|
||||
// Get the two color patterns for upper and lower half
|
||||
char c0 = colors[2 * (i & 7)], c1 = colors[2 * (i & 7) + 1];
|
||||
|
||||
// Put the pixels into the image
|
||||
dp[0] |= c0 & mask;
|
||||
dp[1] |= c1 & mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Re-enable the kernal
|
||||
mmap_set(MMAP_NO_BASIC);
|
||||
|
||||
// Wait for key press
|
||||
getch();
|
||||
|
||||
// Restore VIC state
|
||||
vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
#include <conio.h>
|
||||
#include <math.h>
|
||||
|
||||
// Address of hires buffer and color buffers
|
||||
#define Screen ((char *)0xe000)
|
||||
#define Color1 ((char *)0xc800)
|
||||
#define Color2 ((char *)0xd800)
|
||||
|
||||
// Bit patters for two different color pairs and eight shades
|
||||
byte colors[2][17] =
|
||||
{
|
||||
{0x00,
|
||||
|
@ -20,27 +22,37 @@ byte colors[2][17] =
|
|||
}
|
||||
};
|
||||
|
||||
// Fill a vertical line x from py to ty with color c
|
||||
void VLine(int x, int py, int ty, char c)
|
||||
{
|
||||
// Clip boundaries
|
||||
if (py < 0)
|
||||
py = 0;
|
||||
if (ty > 100)
|
||||
ty = 100;
|
||||
|
||||
// Check if there are pixel to draw
|
||||
if (py < ty)
|
||||
{
|
||||
// Calculate top address and mask
|
||||
char mask = 0xc0 >> (2 * (x & 3));
|
||||
char * dp = Screen + 320 * (py >> 2) + 2 * (py & 3) + 2 * (x & ~3);
|
||||
|
||||
|
||||
// Get the two color patterns
|
||||
char c0 = colors[0][c] & mask, c1 = colors[1][c] & mask;
|
||||
|
||||
// Invert mask to cover the unchanged portion
|
||||
mask = ~mask;
|
||||
|
||||
// Loop over all pixels
|
||||
char h = ty - py;
|
||||
while (h)
|
||||
{
|
||||
// Apply color to memory
|
||||
dp[0] = (dp[0] & mask) | c0;
|
||||
dp[1] = (dp[1] & mask) | c1;
|
||||
|
||||
// Two pixel lines down
|
||||
dp += 2;
|
||||
if (!((int)dp & 7))
|
||||
dp += 312;
|
||||
|
@ -50,6 +62,7 @@ void VLine(int x, int py, int ty, char c)
|
|||
}
|
||||
}
|
||||
|
||||
// Iterate up to 32 iterations and return a smoothed height
|
||||
float iter(float xz, float yz)
|
||||
{
|
||||
float x = 0.0, y = 0.0, r;
|
||||
|
@ -71,6 +84,7 @@ float iter(float xz, float yz)
|
|||
return i - log(log(r)/log(64.0))/log(2.0)
|
||||
}
|
||||
|
||||
// Calculate light with given new and old heights
|
||||
int light(float hl, float hu, float h)
|
||||
{
|
||||
float dx = h - hl, dz = h - hu, dy = 0.1;
|
||||
|
@ -84,12 +98,16 @@ int light(float hl, float hu, float h)
|
|||
|
||||
int main(void)
|
||||
{
|
||||
// Install the IRQ trampoline
|
||||
mmap_trampoline();
|
||||
|
||||
// Turn of the kernal ROM
|
||||
mmap_set(MMAP_NO_ROM);
|
||||
|
||||
// Switch VIC into multicolor bitmap mode
|
||||
vic_setmode(VICM_HIRES_MC, Color1, Screen);
|
||||
|
||||
// Clear the screen and set the colors
|
||||
vic.color_back = 0x00;
|
||||
vic.color_border = 0x00;
|
||||
|
||||
|
@ -97,22 +115,28 @@ int main(void)
|
|||
memset(Color1, 0x26, 1000);
|
||||
memset(Color2, 0x0f, 1000);
|
||||
|
||||
// Height of previous row, needed for lighting
|
||||
float hl[200];
|
||||
|
||||
// Rotation of complex plane
|
||||
float w = -0.7;
|
||||
float co = cos(w), si = sin(w);
|
||||
|
||||
// Loop from left to right
|
||||
for(int x=-1; x<160; x+= 1)
|
||||
{
|
||||
// Loop from far to nead
|
||||
int py = 20;
|
||||
float hu = 0;
|
||||
for(int y=1; y<200; y+= 1)
|
||||
{
|
||||
// Inverse 3D projection
|
||||
float fz = 2.0 / (float)y;
|
||||
float fx = (float)(x - 80) * fz / 100.0;
|
||||
|
||||
float mz = fz * 100.0 - 3.0, mx = fx * 100.0;
|
||||
|
||||
// Rotation of the plane
|
||||
float rx = mx * co - mz * si, rz = mx * si + mz * co;
|
||||
float dp = iter(rx, rz);
|
||||
float v = 2 * dp;
|
||||
|
@ -120,20 +144,25 @@ int main(void)
|
|||
|
||||
float fy = 5.0 * pow(2.0, - v * 0.4);
|
||||
|
||||
// Calculate light
|
||||
int ni = light(hl[y], hu, fy);
|
||||
|
||||
// Update left column
|
||||
hl[y] = fy;
|
||||
hu = fy;
|
||||
|
||||
// Forward 3D projection
|
||||
int ty = 20 + y / 2 + (int)(floor(fy / fz));
|
||||
|
||||
int c;
|
||||
|
||||
// color of pixel
|
||||
int c;
|
||||
if (dp != 32)
|
||||
c = 1 + ni + 8 * ((int)floor(dp) & 1);
|
||||
else
|
||||
c = 0;
|
||||
|
||||
// Draw line if not dummy left row
|
||||
if (x >= 0)
|
||||
VLine(x, py, ty, c);
|
||||
|
||||
|
@ -141,10 +170,13 @@ int main(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Re-enable the kernal
|
||||
mmap_set(MMAP_NO_BASIC);
|
||||
|
||||
// Wait for key press
|
||||
getch();
|
||||
|
||||
// Restore VIC state
|
||||
vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -3,18 +3,24 @@
|
|||
|
||||
int main(void)
|
||||
{
|
||||
// Set name for file and open it on drive 9
|
||||
krnio_setnam("@0:CHARS,P,R");
|
||||
if (krnio_open(2, 9, 2))
|
||||
{
|
||||
// Read bytes until failure
|
||||
int ch, k = 0;
|
||||
while ((ch = krnio_getch(2)) >= 0)
|
||||
{
|
||||
// Print the value of the byte
|
||||
printf("%d : %d\n", k, ch)
|
||||
k++;
|
||||
|
||||
// Exit the loop if this was the last byte of the file
|
||||
if (ch & 0x100)
|
||||
break;
|
||||
}
|
||||
|
||||
// Close the file
|
||||
krnio_close(2);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,12 +3,18 @@
|
|||
|
||||
int main(void)
|
||||
{
|
||||
// Set name for file and open it with replace on drive 9
|
||||
krnio_setnam("@0:CHARS,P,W");
|
||||
if (krnio_open(2, 9, 2))
|
||||
{
|
||||
// Write 128 bytes to the file, it would be more efficient
|
||||
// to set the output channel with krnio_chkout() for the file and
|
||||
// write the bytes using krnio_chrout()
|
||||
|
||||
for(char i=0; i<128; i++)
|
||||
krnio_putch(2, i);
|
||||
|
||||
// Close the file again
|
||||
krnio_close(2);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,14 +11,18 @@ Score score[4];
|
|||
|
||||
int main(void)
|
||||
{
|
||||
// Set name for file and open it on drive 9
|
||||
krnio_setnam("HIGHSCORE,P,R");
|
||||
if (krnio_open(2, 9, 2))
|
||||
{
|
||||
// Read the content of the file into the score arrayx
|
||||
krnio_read(2, (char*)score, sizeof(score));
|
||||
|
||||
// Close the file
|
||||
krnio_close(2);
|
||||
}
|
||||
|
||||
// Print the result to stdout
|
||||
for(int i=0; i<4; i++)
|
||||
{
|
||||
printf("%s : %u\n", score[i].name, score[i].score);
|
||||
|
|
|
@ -16,11 +16,14 @@ Score score[] = {
|
|||
|
||||
int main(void)
|
||||
{
|
||||
// Set name for file and open it with replace on drive 9
|
||||
krnio_setnam("@0:HIGHSCORE,P,W");
|
||||
if (krnio_open(2, 9, 2))
|
||||
{
|
||||
// Fill the file with the score array
|
||||
krnio_write(2, (char*)score, sizeof(score));
|
||||
|
||||
// Close the file
|
||||
krnio_close(2);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,27 +12,40 @@ Bitmap Screen;
|
|||
|
||||
int main(void)
|
||||
{
|
||||
// Install the IRQ trampoline
|
||||
mmap_trampoline();
|
||||
|
||||
// Initialize the display bitmap
|
||||
bm_init(&Screen, ScreenMem, 40, 25);
|
||||
|
||||
// Clear the color memory with ROM and IO disabled
|
||||
mmap_set(MMAP_RAM);
|
||||
memset(ScreenMem, 0, 8000);
|
||||
memset(ColorMem, 0x70, 1000);
|
||||
mmap_set(MMAP_NO_ROM);
|
||||
|
||||
// Switch VIC to hires mode
|
||||
vic_setmode(VICM_HIRES, ColorMem, ScreenMem);
|
||||
|
||||
// Reenable the kernal rom
|
||||
mmap_set(MMAP_ROM);
|
||||
|
||||
|
||||
// Set name for file and open it with replace on drive 9
|
||||
krnio_setnam("TESTIMAGE,P,R");
|
||||
if (krnio_open(2, 9, 2))
|
||||
{
|
||||
// Read the bitmap image in one go
|
||||
krnio_read(2, ScreenMem, 8000);
|
||||
|
||||
// Close the file
|
||||
krnio_close(2);
|
||||
}
|
||||
|
||||
// Wait for a character
|
||||
getchar();
|
||||
|
||||
// Restore VIC
|
||||
vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -13,27 +13,34 @@ char Buffer[200];
|
|||
|
||||
int main(void)
|
||||
{
|
||||
// Install the IRQ trampoline
|
||||
mmap_trampoline();
|
||||
|
||||
// Initialize the display bitmap and a brush
|
||||
bm_init(&Screen, ScreenMem, 40, 25);
|
||||
bm_alloc(&Brush, 2, 2);
|
||||
|
||||
// Clear the color memory with ROM and IO disabled
|
||||
mmap_set(MMAP_RAM);
|
||||
memset(ScreenMem, 0, 8000);
|
||||
memset(ColorMem, 0x70, 1000);
|
||||
mmap_set(MMAP_NO_ROM);
|
||||
|
||||
// Switch VIC to hires mode
|
||||
vic_setmode(VICM_HIRES, ColorMem, ScreenMem);
|
||||
|
||||
// Draw the brush
|
||||
ClipRect crb = {0, 0, 16, 16};
|
||||
bm_fill(&Brush, 0);
|
||||
bm_circle_fill(&Brush, &crb, 7, 7, 6, NineShadesOfGrey[8]);
|
||||
|
||||
// Draw the main image
|
||||
ClipRect crr = {0, 0, 320, 200};
|
||||
bm_circle_fill(&Screen, &crr, 160, 100, 90, NineShadesOfGrey[8]);
|
||||
bm_circle_fill(&Screen, &crr, 120, 80, 20, NineShadesOfGrey[0]);
|
||||
bm_circle_fill(&Screen, &crr, 200, 80, 20, NineShadesOfGrey[0]);
|
||||
|
||||
// And a smile
|
||||
for(int x=-40; x<=40; x+=4)
|
||||
{
|
||||
int y = bm_usqrt(50 * 50 - x * x);
|
||||
|
@ -41,22 +48,32 @@ int main(void)
|
|||
}
|
||||
|
||||
|
||||
// Reenable the kernal rom
|
||||
mmap_set(MMAP_ROM);
|
||||
|
||||
// Set name for file and open it with replace on drive 9
|
||||
krnio_setnam("@0:TESTIMAGE,P,W");
|
||||
if (krnio_open(2, 9, 2))
|
||||
{
|
||||
// Loop in chunks of 200 bytes
|
||||
for(int i=0; i<8000; i+=200)
|
||||
{
|
||||
// Disable ROM
|
||||
mmap_set(MMAP_NO_ROM);
|
||||
// Copy chunk into buffer
|
||||
memcpy(Buffer, ScreenMem + i, 200);
|
||||
// Reeable the ROM
|
||||
mmap_set(MMAP_ROM);
|
||||
|
||||
// Write the chunk to disk
|
||||
krnio_write(2, Buffer, 200);
|
||||
}
|
||||
|
||||
// Close the file
|
||||
krnio_close(2);
|
||||
}
|
||||
|
||||
// Restore the VIC
|
||||
vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -2,25 +2,31 @@
|
|||
#include <c64/rasterirq.h>
|
||||
#include <conio.h>
|
||||
|
||||
|
||||
// Prepare small 14 color bars and one IRQ for back to normal
|
||||
RIRQCode bars[15];
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// initialize raster IRQ
|
||||
rirq_init(true);
|
||||
|
||||
for(int i=0; i<15; i++)
|
||||
{
|
||||
// Build color change raster IRQ
|
||||
rirq_build(bars + i, 2);
|
||||
// Change border color
|
||||
rirq_write(bars + i, 0, &vic.color_border, i);
|
||||
// Change background color
|
||||
rirq_write(bars + i, 1, &vic.color_back, i);
|
||||
// Place it on screen
|
||||
rirq_set(i, 80 + 8 * i, bars + i);
|
||||
}
|
||||
|
||||
// Sort all raster IRQs
|
||||
rirq_sort();
|
||||
|
||||
// Start raster IRQs
|
||||
rirq_start();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <math.h>
|
||||
#include <conio.h>
|
||||
|
||||
// Five raster IRQs for top and bottom of the two chasing bars, and the bottom
|
||||
// of the screen
|
||||
RIRQCode ftop, fbottom, btop, bbottom, final ;
|
||||
|
||||
char sintab[256];
|
||||
|
|
|
@ -8,26 +8,36 @@ char spdata[] = {
|
|||
#embed "../resources/friendlybear.bin"
|
||||
};
|
||||
|
||||
// Raster IRQs for last line of screen and below
|
||||
RIRQCode open, bottom;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// initialize raster IRQ
|
||||
rirq_init(true);
|
||||
|
||||
// Build open border raster IRQ
|
||||
rirq_build(&open, 1);
|
||||
// Reduce vertical screen size to fool VIC counter
|
||||
rirq_write(&open, 0, &vic.ctrl1, VIC_CTRL1_DEN | 3);
|
||||
// Place it into the last line of the screen
|
||||
rirq_set(0, 50 + 200 - 3, &open);
|
||||
|
||||
// Build switch to normal raster IRQ
|
||||
rirq_build(&bottom, 1);
|
||||
rirq_write(&bottom, 0, &vic.ctrl1, VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3 );
|
||||
rirq_set(1, 50, &bottom);
|
||||
|
||||
// sort the raster IRQs
|
||||
rirq_sort();
|
||||
|
||||
// start raster IRQ processing
|
||||
rirq_start();
|
||||
|
||||
// Copy the sprite data
|
||||
memcpy((char *)0x0380, spdata, 128);
|
||||
|
||||
// Initialize sprites
|
||||
*(char *)(0x7f8) = 0x03c0 / 64;
|
||||
*(char *)(0x7f9) = 0x0380 / 64;
|
||||
*(char *)(0x7fa) = 0x03c0 / 64;
|
||||
|
@ -52,6 +62,7 @@ int main(void)
|
|||
|
||||
for(;;)
|
||||
{
|
||||
// Move sprites through all vertical positions
|
||||
for(int i=0; i<255; i++)
|
||||
{
|
||||
vic_sprxy(0, 100, 1 * i); vic_sprxy(1, 100, 1 * i);
|
||||
|
|
|
@ -10,29 +10,44 @@ const char * Text =
|
|||
S"CORPORIS, EOS? UNDE VERO ISTE QUIA? EAQUE EAQUE. IN. AUT ID "
|
||||
S"EXPEDITA ILLUM MOLESTIAS, ";
|
||||
|
||||
// Raster interrupt command structure for change to scrolled and back
|
||||
|
||||
RIRQCode scroll, bottom;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// initialize raster IRQ
|
||||
rirq_init(true);
|
||||
|
||||
// Build switch to scroll line IRQ
|
||||
rirq_build(&scroll, 1);
|
||||
// Change control register two with this IRQ
|
||||
rirq_write(&scroll, 0, &vic.ctrl2, 0);
|
||||
// Put it onto the scroll line
|
||||
rirq_set(0, 50 + 24 * 8, &scroll);
|
||||
|
||||
// Build the switch to normal IRQ
|
||||
rirq_build(&bottom, 1);
|
||||
// re-enable left and right column and reset horizontal scroll
|
||||
rirq_write(&bottom, 0, &vic.ctrl2, VIC_CTRL2_CSEL);
|
||||
// place this at the bottom
|
||||
rirq_set(1, 250, &bottom);
|
||||
|
||||
// sort the raster IRQs
|
||||
rirq_sort();
|
||||
|
||||
// start raster IRQ processing
|
||||
rirq_start();
|
||||
|
||||
// Loop through text
|
||||
int x = 0;
|
||||
for(;;)
|
||||
{
|
||||
// wait for raster reaching bottom of screen
|
||||
rirq_wait();
|
||||
// Update raster IRQ for scroll line with new horizontal scroll offset
|
||||
rirq_data(&scroll, 0, 7 - (x & 7));
|
||||
// Copy scrolled version of text when switching over char border
|
||||
if ((x & 7) == 0)
|
||||
memcpy((char *)0x0400 + 40 * 24, Text + ((x >> 3) & 255), 40);
|
||||
x++;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
byte font[2048];
|
||||
|
||||
// Copy the system font into local RAM for easy access
|
||||
void copyFont(void)
|
||||
{
|
||||
mmap_set(MMAP_CHAR_ROM);
|
||||
|
@ -13,15 +14,23 @@ void copyFont(void)
|
|||
mmap_set(MMAP_ROM);
|
||||
}
|
||||
|
||||
// Screen and color space
|
||||
#define screen ((byte *)0x0400)
|
||||
#define color ((byte *)0xd800)
|
||||
|
||||
// Macro for easy access to screen space
|
||||
#define sline(x, y) (screen + 40 * (y) + (x))
|
||||
|
||||
// Start row for text
|
||||
#define srow 5
|
||||
|
||||
// Move the screen one character to the left
|
||||
void scrollLeft(void)
|
||||
{
|
||||
// Loop horizontaly
|
||||
for(char x=0; x<39; x++)
|
||||
{
|
||||
// Unroll vetical loop 16 times
|
||||
#assign y 0
|
||||
#repeat
|
||||
sline(0, srow + y)[x] = sline(1, srow + y)[x];
|
||||
|
@ -30,10 +39,13 @@ void scrollLeft(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Expand one column of a glyph to the right most screen column
|
||||
void expand(char c, byte f)
|
||||
{
|
||||
// Address of glyph data
|
||||
byte * fp = font + 8 * c;
|
||||
|
||||
// Unroll eight times for each byte in glyph data
|
||||
#assign y 0
|
||||
#repeat
|
||||
sline(39, srow + 2 * y + 0)[0] =
|
||||
|
@ -54,28 +66,36 @@ const char * text =
|
|||
|
||||
int main(void)
|
||||
{
|
||||
// Install the IRQ trampoline
|
||||
mmap_trampoline();
|
||||
|
||||
// Copy the font data
|
||||
copyFont();
|
||||
|
||||
// Cleat the screen
|
||||
memset(screen, 0x20, 1000);
|
||||
|
||||
// Color bars
|
||||
for(int i=0; i<16; i++)
|
||||
memset(color + 40 * (srow + i), i + 1, 40);
|
||||
|
||||
vic.color_back = VCOL_BLACK;
|
||||
vic.color_border = VCOL_BLACK;
|
||||
|
||||
// Hide left and right column
|
||||
vic.ctrl2 = 0;
|
||||
|
||||
// Loop over text
|
||||
int ci = 0;
|
||||
for(;;)
|
||||
{
|
||||
// Loop over glyph from left to right
|
||||
byte cf = 0x80;
|
||||
while (cf)
|
||||
{
|
||||
for(char i=0; i<2; i++)
|
||||
{
|
||||
// Pixel level scrolling
|
||||
vic_waitBottom();
|
||||
vic.ctrl2 = 4;
|
||||
vic_waitTop();
|
||||
|
@ -91,12 +111,16 @@ int main(void)
|
|||
vic_waitBottom();
|
||||
vic.ctrl2 = 6;
|
||||
|
||||
// Crossing character border, now scroll and show new column
|
||||
scrollLeft();
|
||||
expand(text[ci], cf);
|
||||
}
|
||||
|
||||
// Next glyph column
|
||||
cf >>= 1;
|
||||
}
|
||||
|
||||
// Next character
|
||||
ci++;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,11 +4,15 @@
|
|||
#include <c64/joystick.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Screen and color space
|
||||
#define Screen ((byte *)0x0400)
|
||||
#define Color ((byte *)0xd800)
|
||||
|
||||
// Macro for easy access to screen and color space
|
||||
#define sline(x, y) (Screen + 40 * (y) + (x))
|
||||
#define cline(x, y) (Color + 40 * (y) + (x))
|
||||
|
||||
// Tile data, each column has four rows of four tiles
|
||||
static const char quad[4][4 * 4] =
|
||||
{
|
||||
{
|
||||
|
@ -40,6 +44,7 @@ static const char quad[4][4 * 4] =
|
|||
|
||||
#pragma align(quad, 256)
|
||||
|
||||
// Expand a single row into an offscreen buffer
|
||||
void expandrow(char * dp, char * cp, const char * grid, char ly, char lx)
|
||||
{
|
||||
char hx = 0;
|
||||
|
@ -56,6 +61,7 @@ void expandrow(char * dp, char * cp, const char * grid, char ly, char lx)
|
|||
}
|
||||
}
|
||||
|
||||
// Expand a single column into an offscreen buffer
|
||||
void expandcol(char * dp, char * cp, const char * grid, char ly, char lx)
|
||||
{
|
||||
for(char y=0; y<25; y++)
|
||||
|
@ -71,25 +77,39 @@ void expandcol(char * dp, char * cp, const char * grid, char ly, char lx)
|
|||
}
|
||||
}
|
||||
|
||||
// Two split scroll for left, right and up
|
||||
#define VSPLIT 12
|
||||
|
||||
// Three split scroll for down. Downscrolling is more tricky because
|
||||
// we have to copy towards the raster
|
||||
#define VSPLIT 12
|
||||
#define VSPLIT2 20
|
||||
|
||||
// New line/column of screen and color data
|
||||
char news[40], newc[40];
|
||||
|
||||
// All scroll routines start with a pixel offset of 4, 4
|
||||
|
||||
// Scroll one character left in two pixel increments
|
||||
void scroll_left(void)
|
||||
{
|
||||
// Wait for one frame
|
||||
vic_waitTop();
|
||||
vic_waitBottom();
|
||||
|
||||
// Switch to offset 2, 4
|
||||
vic.ctrl2 = 0x02;
|
||||
vic_waitTop();
|
||||
vic_waitBottom();
|
||||
|
||||
// Switch to offset 0, 4
|
||||
vic.ctrl2 = 0x00;
|
||||
|
||||
// Wait until bottom of section
|
||||
vic_waitLine(50 + 8 * VSPLIT);
|
||||
|
||||
// Scroll upper section
|
||||
|
||||
for(char x=0; x<39; x++)
|
||||
{
|
||||
#assign ty 0
|
||||
|
@ -100,6 +120,7 @@ void scroll_left(void)
|
|||
#until ty == VSPLIT
|
||||
}
|
||||
|
||||
// Update column
|
||||
#assign ty 0
|
||||
#repeat
|
||||
sline(0, ty)[39] = news[ty];
|
||||
|
@ -107,9 +128,13 @@ void scroll_left(void)
|
|||
#assign ty ty + 1
|
||||
#until ty == VSPLIT
|
||||
|
||||
// Wait for bottom of visible screen
|
||||
vic_waitBottom();
|
||||
|
||||
// Switch to offset 6, 4
|
||||
vic.ctrl2 = 0x06;
|
||||
|
||||
// Scroll lower part of the screen, while top is redrawn
|
||||
for(char x=0; x<39; x++)
|
||||
{
|
||||
#assign ty VSPLIT
|
||||
|
@ -120,6 +145,7 @@ void scroll_left(void)
|
|||
#until ty == 25
|
||||
}
|
||||
|
||||
// Update new column
|
||||
#assign ty VSPLIT
|
||||
#repeat
|
||||
sline(0, ty)[39] = news[ty];
|
||||
|
@ -127,11 +153,16 @@ void scroll_left(void)
|
|||
#assign ty ty + 1
|
||||
#until ty == 25
|
||||
|
||||
// Wait for bottom
|
||||
vic_waitBottom();
|
||||
|
||||
// Now back to 4, 4
|
||||
vic.ctrl2 = 0x04
|
||||
|
||||
}
|
||||
|
||||
// Scroll one character right in two pixel increments
|
||||
|
||||
void scroll_right(void)
|
||||
{
|
||||
vic_waitTop();
|
||||
|
@ -185,6 +216,8 @@ void scroll_right(void)
|
|||
vic.ctrl2 = 0x04;
|
||||
}
|
||||
|
||||
// Scroll one character up in two pixel increments
|
||||
|
||||
void scroll_up(void)
|
||||
{
|
||||
vic_waitTop();
|
||||
|
@ -229,20 +262,36 @@ void scroll_up(void)
|
|||
|
||||
char tmp0[40], tmp1[40], tmp2[40], tmp3[40];
|
||||
|
||||
// Scroll one character down in two pixel increments. This is more tricky than
|
||||
// the other three cases, because we have to work towards the beam because
|
||||
// we have to copy backwards in memory.
|
||||
//
|
||||
// The scroll is split into three sections, the seam rows are saved into
|
||||
// intermediate arrays, so we can copy the top section first and the bottom
|
||||
// section last, and stay ahead of the beam.
|
||||
|
||||
void scroll_down(void)
|
||||
{
|
||||
// Wait one frame
|
||||
vic_waitTop();
|
||||
vic_waitBottom();
|
||||
|
||||
// Save seam lines
|
||||
for(char x=0; x<40; x++)
|
||||
{
|
||||
tmp0[x] = sline(0, VSPLIT)[x];
|
||||
tmp1[x] = cline(0, VSPLIT)[x];
|
||||
tmp2[x] = sline(0, VSPLIT2)[x];
|
||||
tmp3[x] = cline(0, VSPLIT2)[x];
|
||||
}
|
||||
|
||||
// Now switch to 4, 6
|
||||
vic.ctrl1 = 0x06 | VIC_CTRL1_DEN;
|
||||
|
||||
// Wait for bottom of top section
|
||||
vic_waitLine(58 + 8 * VSPLIT);
|
||||
|
||||
// Scroll top section down and copy new column
|
||||
for(char x=0; x<40; x++)
|
||||
{
|
||||
#assign ty VSPLIT
|
||||
|
@ -257,12 +306,12 @@ void scroll_down(void)
|
|||
}
|
||||
|
||||
// vic_waitBottom();
|
||||
// We have already reached the bottom, switch to 4, 0
|
||||
vic.ctrl1 = 0x00 | VIC_CTRL1_DEN;
|
||||
|
||||
// Copy the second section, update the seam line from the buffer
|
||||
for(char x=0; x<40; x++)
|
||||
{
|
||||
tmp2[x] = sline(0, VSPLIT2)[x];
|
||||
tmp3[x] = cline(0, VSPLIT2)[x];
|
||||
|
||||
#assign ty VSPLIT2
|
||||
#repeat
|
||||
|
@ -275,6 +324,7 @@ void scroll_down(void)
|
|||
cline(0, ty)[x] = tmp1[x];
|
||||
}
|
||||
|
||||
// Copy the third section, update the seam line from the buffer
|
||||
for(char x=0; x<40; x++)
|
||||
{
|
||||
#assign ty 24
|
||||
|
@ -288,9 +338,11 @@ void scroll_down(void)
|
|||
cline(0, ty)[x] = tmp3[x];
|
||||
}
|
||||
|
||||
// Switch to 4, 2
|
||||
vic_waitBottom();
|
||||
vic.ctrl1 = 0x02 | VIC_CTRL1_DEN;
|
||||
|
||||
// Switch to 4, 4
|
||||
vic_waitTop();
|
||||
vic_waitBottom();
|
||||
vic.ctrl1 = 0x04 | VIC_CTRL1_DEN;
|
||||
|
@ -302,11 +354,13 @@ char grid[16][16];
|
|||
|
||||
int main(void)
|
||||
{
|
||||
// We need some more accurate timing for this, so kill the kernal IRQ
|
||||
__asm
|
||||
{
|
||||
sei
|
||||
}
|
||||
|
||||
// Init the grid
|
||||
for(char y=0; y<16; y++)
|
||||
{
|
||||
for(char x=0; x<16; x++)
|
||||
|
@ -317,6 +371,7 @@ int main(void)
|
|||
|
||||
char gridX = 0, gridY = 0;
|
||||
|
||||
// Inital drwaing of the screen
|
||||
char * dp = Screen, * cp = Color;
|
||||
for(char y=0; y<25; y++)
|
||||
{
|
||||
|
@ -325,11 +380,18 @@ int main(void)
|
|||
cp += 40;
|
||||
}
|
||||
|
||||
// setup initial scroll offset
|
||||
|
||||
vic.ctrl1 = 0x04 | VIC_CTRL1_DEN;
|
||||
vic.ctrl2 = 0x04
|
||||
|
||||
for(;;)
|
||||
{
|
||||
// Check the joystick
|
||||
joy_poll(1);
|
||||
if (joyx[1] == 1)
|
||||
{
|
||||
// Move to the right
|
||||
if (gridX < 24)
|
||||
{
|
||||
gridX++;
|
||||
|
@ -339,6 +401,7 @@ int main(void)
|
|||
}
|
||||
else if (joyx[1] == -1)
|
||||
{
|
||||
// Move to the left
|
||||
if (gridX > 0)
|
||||
{
|
||||
gridX--;
|
||||
|
@ -348,6 +411,7 @@ int main(void)
|
|||
}
|
||||
else if (joyy[1] == 1)
|
||||
{
|
||||
// Move down
|
||||
if (gridY < 39)
|
||||
{
|
||||
gridY++;
|
||||
|
@ -357,6 +421,7 @@ int main(void)
|
|||
}
|
||||
else if (joyy[1] == -1)
|
||||
{
|
||||
// Move up
|
||||
if (gridY > 0)
|
||||
{
|
||||
gridY--;
|
||||
|
|
|
@ -3,16 +3,22 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Screen and color space
|
||||
#define screen ((byte *)0x0400)
|
||||
#define color ((byte *)0xd800)
|
||||
|
||||
// Macro for easy access to screen and color space
|
||||
#define sline(x, y) (screen + 40 * (y) + (x))
|
||||
#define cline(x, y) (color + 40 * (y) + (x))
|
||||
|
||||
// Column buffer for one prepared column of screen and color data
|
||||
char rbuff[25], cbuff[25];
|
||||
|
||||
// Split into three scrolling sections to race the beam
|
||||
#define SPLIT1 8
|
||||
#define SPLIT2 16
|
||||
|
||||
// Scroll top section
|
||||
void scrollLeft0(void)
|
||||
{
|
||||
for(char x=0; x<39; x++)
|
||||
|
@ -32,6 +38,7 @@ void scrollLeft0(void)
|
|||
#until y == SPLIT1
|
||||
}
|
||||
|
||||
// Scroll bottom two sections
|
||||
void scrollLeft1(void)
|
||||
{
|
||||
for(char x=0; x<39; x++)
|
||||
|
@ -67,7 +74,7 @@ void scrollLeft1(void)
|
|||
}
|
||||
|
||||
|
||||
|
||||
// Prepare a new column with random data
|
||||
void prepcol(void)
|
||||
{
|
||||
for(char i=0; i<25; i++)
|
||||
|
@ -80,6 +87,7 @@ void prepcol(void)
|
|||
|
||||
int main(void)
|
||||
{
|
||||
// Clear the screen
|
||||
memset(screen, 0x20, 1000);
|
||||
memset(color, 7, 1000);
|
||||
|
||||
|
@ -90,24 +98,33 @@ int main(void)
|
|||
|
||||
for(;;)
|
||||
{
|
||||
// Advance one pixel
|
||||
|
||||
x = (x + 1) & 7;
|
||||
|
||||
// If we will cross the character boundary, scroll the top section
|
||||
if (x == 0)
|
||||
{
|
||||
// Wait for raster reaching bottom of first section
|
||||
vic_waitLine(50 + 8 * SPLIT1);
|
||||
// Scroll first section
|
||||
scrollLeft0();
|
||||
}
|
||||
|
||||
// Wait for bottom of screen
|
||||
vic_waitBottom();
|
||||
|
||||
// Update the pixel offset
|
||||
vic.ctrl2 = (7 - x) & 7;
|
||||
|
||||
if (x == 0)
|
||||
{
|
||||
// Scroll the bottom section if needed
|
||||
scrollLeft1();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update the new column somewhere in the middle of the character
|
||||
if (x == 4)
|
||||
prepcol();
|
||||
vic_waitTop();
|
||||
|
|
|
@ -4,10 +4,14 @@
|
|||
#include <stdlib.h>
|
||||
#include <c64/rasterirq.h>
|
||||
|
||||
// Screen and color space
|
||||
#define screen ((byte *)0x0400)
|
||||
#define color ((byte *)0xd800)
|
||||
|
||||
// Macro for easy access to screen space
|
||||
#define sline(x, y) (screen + 40 * (y) + (x))
|
||||
|
||||
// Tile data, each column has four rows of four tiles
|
||||
static const char quad[4][4 * 4] =
|
||||
{
|
||||
{
|
||||
|
@ -38,9 +42,11 @@ static const char quad[4][4 * 4] =
|
|||
|
||||
#pragma align(quad, 256)
|
||||
|
||||
// expand one row with column offset 0 into the grid
|
||||
void expandrow0(char * dp, const char * grid, char ly)
|
||||
{
|
||||
char gi;
|
||||
// unroll for each char in the row
|
||||
#assign gx 0
|
||||
#repeat
|
||||
gi = grid[gx] | ly;
|
||||
|
@ -52,6 +58,8 @@ void expandrow0(char * dp, const char * grid, char ly)
|
|||
#until gx == 10
|
||||
}
|
||||
|
||||
// expand one row with column offset 1 into the grid, so three
|
||||
// chars from the first tile and one char from the last
|
||||
void expandrow1(char * dp, const char * grid, char ly)
|
||||
{
|
||||
char gi;
|
||||
|
@ -72,6 +80,8 @@ void expandrow1(char * dp, const char * grid, char ly)
|
|||
dp[39] = quad[0][gi];
|
||||
}
|
||||
|
||||
// expand one row with column offset 2 into the grid, so two
|
||||
// chars from the first tile and two chars from the last
|
||||
void expandrow2(char * dp, const char * grid, char ly)
|
||||
{
|
||||
char gi;
|
||||
|
@ -92,6 +102,8 @@ void expandrow2(char * dp, const char * grid, char ly)
|
|||
dp[39] = quad[1][gi];
|
||||
}
|
||||
|
||||
// expand one row with column offset 3 into the grid, so one
|
||||
// char from the first tile and trhee chars from the last
|
||||
void expandrow3(char * dp, const char * grid, char ly)
|
||||
{
|
||||
char gi;
|
||||
|
@ -112,16 +124,24 @@ void expandrow3(char * dp, const char * grid, char ly)
|
|||
dp[39] = quad[2][gi];
|
||||
}
|
||||
|
||||
// expand the visibile portion of the screen at the
|
||||
// given char offset into the tiles
|
||||
void expand(char * dp, const char * grid, char px, char py)
|
||||
{
|
||||
// remainder of position, offset into the tile
|
||||
char ry = 4 * (py & 3);
|
||||
char rx = px & 3;
|
||||
|
||||
// target screen position
|
||||
char * cdp = dp;
|
||||
const char * cgrid = grid + (px >> 2) + 16 * (py >> 2);
|
||||
|
||||
// pointer to grid offset for top lest tile visible
|
||||
const char * cgrid = grid + (px >> 2) + 32 * (py >> 2);
|
||||
|
||||
// Loop over all visible screen rows
|
||||
for(char gy=0; gy<20; gy++)
|
||||
{
|
||||
// Update based on row (could be unrolled for inner groups of full tiles)
|
||||
switch (rx)
|
||||
{
|
||||
case 0:
|
||||
|
@ -137,28 +157,35 @@ void expand(char * dp, const char * grid, char px, char py)
|
|||
expandrow3(cdp, cgrid, ry);
|
||||
break;
|
||||
}
|
||||
|
||||
// Next row
|
||||
cdp += 40;
|
||||
ry += 4;
|
||||
|
||||
// Next tile
|
||||
if (ry == 16)
|
||||
{
|
||||
ry = 0;
|
||||
cgrid += 16;
|
||||
cgrid += 32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char grid[16][16];
|
||||
char grid[32][32];
|
||||
|
||||
#pragma align(grid, 256)
|
||||
|
||||
// Raster IRQs for split screen
|
||||
|
||||
RIRQCode blank, scroll, bottom;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
for(char y=0; y<16; y++)
|
||||
// Init grid with random data
|
||||
for(char y=0; y<32; y++)
|
||||
{
|
||||
for(char x=0; x<16; x++)
|
||||
for(char x=0; x<32; x++)
|
||||
{
|
||||
grid[y][x] = rand() & 3;
|
||||
}
|
||||
|
@ -166,18 +193,22 @@ int main(void)
|
|||
|
||||
vic.color_border = 0;
|
||||
|
||||
// Setup split screen
|
||||
rirq_init(true);
|
||||
|
||||
// Blank display after top section
|
||||
rirq_build(&blank, 1);
|
||||
rirq_write(&blank, 0, &vic.ctrl1, 0);
|
||||
rirq_set(0, 46 + 5 * 8, &blank);
|
||||
|
||||
// Setup scrolling area
|
||||
rirq_build(&scroll, 3);
|
||||
rirq_delay(&scroll, 10);
|
||||
rirq_write(&scroll, 1, &vic.ctrl1, VIC_CTRL1_DEN);
|
||||
rirq_write(&scroll, 2, &vic.ctrl2, 0);
|
||||
rirq_set(1, 54 + 5 * 8, &scroll);
|
||||
|
||||
// Wait for bottom of screen
|
||||
rirq_build(&bottom, 2);
|
||||
rirq_write(&bottom, 0, &vic.ctrl1, VIC_CTRL1_DEN | VIC_CTRL1_RSEL);
|
||||
rirq_write(&bottom, 1, &vic.ctrl2, VIC_CTRL2_CSEL);
|
||||
|
@ -187,46 +218,59 @@ int main(void)
|
|||
|
||||
rirq_start();
|
||||
|
||||
// Movement data
|
||||
int py = 40 * 32, px = 40 * 32, dy = 0, dx = 0, ax = 0, ay = 0;
|
||||
for(;;)
|
||||
{
|
||||
// Grid position using 13.5 fractions
|
||||
int rx = px >> 5, ry = py >> 5;
|
||||
|
||||
// Wait for next raster
|
||||
vic.color_border++;
|
||||
rirq_wait();
|
||||
vic.color_border--;
|
||||
|
||||
// Update vertical scroll position
|
||||
rirq_data(&blank, 0, ((7 - ry) & 7) | VIC_CTRL1_DEN | VIC_CTRL1_BMM | VIC_CTRL1_ECM);
|
||||
|
||||
// Dynamic wait based on vertical scroll position to counter bad lines
|
||||
if ((ry & 7) == 0)
|
||||
rirq_data(&scroll, 0, 4);
|
||||
else
|
||||
rirq_data(&scroll, 0, 10);
|
||||
|
||||
// Update vertical and horizontal scroll position
|
||||
rirq_data(&scroll, 1, ((7 - ry) & 7) | VIC_CTRL1_DEN);
|
||||
rirq_data(&scroll, 2, (7 - rx) & 7);
|
||||
|
||||
// Expand grid at current location
|
||||
expand(screen + 200, &(grid[0][0]), rx >> 3, ry >> 3);
|
||||
|
||||
// Update screen velocity using differential equation
|
||||
dx += ax;
|
||||
dy += ay;
|
||||
|
||||
// New force
|
||||
if ((rand() & 127) == 0)
|
||||
{
|
||||
ax = (rand() & 63) - 32;
|
||||
ay = (rand() & 63) - 32;
|
||||
}
|
||||
|
||||
// Some friction
|
||||
dx -= (dx + 8) >> 4;
|
||||
dy -= (dy + 8) >> 4;
|
||||
|
||||
// Update position reflect at borders
|
||||
py += dy;
|
||||
if (py < 0 || py > 10 * 8 * 4 * 32)
|
||||
if (py < 0 || py > 26 * 8 * 4 * 32)
|
||||
{
|
||||
dy = -dy;
|
||||
py += dy;
|
||||
}
|
||||
|
||||
px += dx;
|
||||
if (px < 0 || px > 6 * 8 * 4 * 32)
|
||||
if (px < 0 || px > 22 * 8 * 4 * 32)
|
||||
{
|
||||
dx = -dx;
|
||||
px += dx;
|
||||
|
|
|
@ -3,14 +3,20 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Screen and color space
|
||||
#define screen ((byte *)0x0400)
|
||||
#define color ((byte *)0xd800)
|
||||
|
||||
// Macro for easy access to screen space
|
||||
#define sline(x, y) (screen + 40 * (y) + (x))
|
||||
|
||||
// Column buffer for one prepared column of tunnel
|
||||
char rbuff[25];
|
||||
|
||||
// Copy the prepared tunnel column to screen
|
||||
void expand(char x)
|
||||
{
|
||||
// Unroll for each row
|
||||
#assign y 0
|
||||
#repeat
|
||||
sline(0, y)[x] = rbuff[y];
|
||||
|
@ -18,8 +24,13 @@ void expand(char x)
|
|||
#until y == 25
|
||||
}
|
||||
|
||||
// Scrolling left, copying new column. This is split into two
|
||||
// unrolled sections so the update of the new column can race the
|
||||
// beam
|
||||
|
||||
void scrollLeft(void)
|
||||
{
|
||||
// First 12 rows scroll left and copy new column
|
||||
for(char x=0; x<39; x++)
|
||||
{
|
||||
#assign y 0
|
||||
|
@ -34,6 +45,7 @@ void scrollLeft(void)
|
|||
#assign y y + 1
|
||||
#until y == 12
|
||||
|
||||
// Final 13 rows scroll left and copy new column
|
||||
for(char x=0; x<39; x++)
|
||||
{
|
||||
#assign y 12
|
||||
|
@ -49,6 +61,10 @@ void scrollLeft(void)
|
|||
#until y == 25
|
||||
}
|
||||
|
||||
// Scrolling right, copying new column. This is split into two
|
||||
// unrolled sections so the update of the new column can race the
|
||||
// beam
|
||||
|
||||
void scrollRight(void)
|
||||
{
|
||||
for(char x=39; x>0; x--)
|
||||
|
@ -80,19 +96,26 @@ void scrollRight(void)
|
|||
#until y == 25
|
||||
}
|
||||
|
||||
// Top and bottom row of the tunnel
|
||||
|
||||
char ytop[256], ybottom[256];
|
||||
|
||||
// Prepare one column of the tunnel
|
||||
|
||||
void prepcol(char xi)
|
||||
{
|
||||
char yt, yb;
|
||||
signed char dyt, dyb;
|
||||
|
||||
// Current height of top and bottom
|
||||
yt = ytop[(char)(xi + 0)];
|
||||
yb = ybottom[(char)(xi + 0)];
|
||||
|
||||
// Height of column to the left for diagonal
|
||||
dyt = yt - ytop[(char)(xi - 1)];
|
||||
dyb = yb - ybottom[(char)(xi - 1)];
|
||||
|
||||
// Fill top, center and bottom range
|
||||
for(char i=0; i<yt; i++)
|
||||
rbuff[i] = 160;
|
||||
for(char i=yt; i<yb; i++)
|
||||
|
@ -100,6 +123,7 @@ void prepcol(char xi)
|
|||
for(char i=yb; i<25; i++)
|
||||
rbuff[i] = 160;
|
||||
|
||||
// Select transitional characters based on slope
|
||||
if (dyt < 0)
|
||||
rbuff[yt] = 105;
|
||||
else if (dyt > 0)
|
||||
|
@ -112,6 +136,7 @@ void prepcol(char xi)
|
|||
|
||||
}
|
||||
|
||||
// Initialize tunnel with "random" data
|
||||
void buildTunnel(void)
|
||||
{
|
||||
signed char yt = 1, yb = 24, dyt = 1, dyb = -1;
|
||||
|
@ -152,49 +177,64 @@ void buildTunnel(void)
|
|||
|
||||
int main(void)
|
||||
{
|
||||
// Clear the screen
|
||||
|
||||
memset(screen, 0x20, 1000);
|
||||
memset(color, 7, 1000);
|
||||
|
||||
vic.color_back = VCOL_BLACK;
|
||||
vic.color_border = VCOL_BLACK;
|
||||
|
||||
// Build tunnel
|
||||
|
||||
buildTunnel();
|
||||
|
||||
// Initial fill of screen
|
||||
|
||||
for(char i=0; i<40; i++)
|
||||
{
|
||||
prepcol(i);
|
||||
expand(i);
|
||||
}
|
||||
|
||||
// Now start moving
|
||||
int xpos = 0, dx = 0, ax = 1;
|
||||
int xi = 0, pxi = 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
// Random change of direction
|
||||
unsigned r = rand();
|
||||
if ((r & 127) == 0)
|
||||
ax = -ax;
|
||||
|
||||
// Acceleration
|
||||
dx += ax;
|
||||
if (dx > 32)
|
||||
dx = 32;
|
||||
else if (dx < -32)
|
||||
dx = -32;
|
||||
|
||||
// Movement
|
||||
xpos += dx;
|
||||
pxi = xi;
|
||||
xi = xpos >> 5;
|
||||
|
||||
// Check if we cross a character boundary, and if so prepare
|
||||
// the new column
|
||||
if (pxi < xi)
|
||||
prepcol(xi + 39);
|
||||
else if (pxi > xi)
|
||||
prepcol(xi + 0);
|
||||
|
||||
// Wait one frame
|
||||
vic_waitTop();
|
||||
vic_waitBottom();
|
||||
|
||||
// Update pixel level scrolling
|
||||
vic.ctrl2 = (7 - (xpos >> 2)) & 7;
|
||||
|
||||
// Character level scrolling if needed
|
||||
if (pxi < xi)
|
||||
scrollLeft();
|
||||
else if (pxi > xi)
|
||||
|
|
|
@ -12,29 +12,38 @@ int spx, spy;
|
|||
|
||||
int main(void)
|
||||
{
|
||||
// Copy the sprite data
|
||||
memcpy(SpriteData, spdata, 128);
|
||||
|
||||
// Initalize 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(1);
|
||||
|
||||
// Change position according to joystick
|
||||
spx += joyx[1];
|
||||
spy += joyy[1];
|
||||
|
||||
// Move sprites on screen
|
||||
spr_move(0, spx, spy);
|
||||
spr_move(1, spx, spy);
|
||||
|
||||
// Wait for one frame iteration
|
||||
vic_waitFrame();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue