oscar64/samples/scrolling/cgrid8way.c

371 lines
5.9 KiB
C

#include <c64/vic.h>
#include <c64/memmap.h>
#include <string.h>
#include <c64/joystick.h>
#include <stdlib.h>
#define Screen ((byte *)0x0400)
#define Color ((byte *)0xd800)
#define sline(x, y) (Screen + 40 * (y) + (x))
#define cline(x, y) (Color + 40 * (y) + (x))
static const char quad[4][4 * 4] =
{
{
0x20, 0x55, 0x6c, 0x4e,
0x20, 0x5d, 0xe1, 0x65,
0x20, 0x5d, 0xe1, 0x65,
0x20, 0x4a, 0x7c, 0x4d,
},
{
0x20, 0x40, 0x62, 0x77,
0x20, 0x20, 0xa0, 0x20,
0x20, 0x20, 0xa0, 0x20,
0x20, 0x40, 0xe2, 0x6f,
},
{
0x20, 0x40, 0x62, 0x77,
0x20, 0x20, 0xa0, 0x20,
0x20, 0x20, 0xa0, 0x20,
0x20, 0x40, 0xe2, 0x6f,
},
{
0x20, 0x49, 0x7b, 0x4d,
0x20, 0x5d, 0x61, 0x6a,
0x20, 0x5d, 0x61, 0x6a,
0x20, 0x4b, 0x7e, 0x4e,
}
};
#pragma align(quad, 256)
void expandrow(char * dp, char * cp, const char * grid, char ly, char lx)
{
char hx = 0;
for(char x=0; x<40; x++)
{
dp[x] = quad[lx][ly + grid[hx]];
cp[x] = grid[hx];
lx++;
if (lx == 4)
{
lx = 0;
hx++;
}
}
}
void expandcol(char * dp, char * cp, const char * grid, char ly, char lx)
{
for(char y=0; y<25; y++)
{
dp[y] = quad[lx][ly + grid[0]];
cp[y] = grid[0];
ly += 4;
if (ly == 16)
{
grid += 16;
ly = 0;
}
}
}
#define VSPLIT 12
#define VSPLIT 12
#define VSPLIT2 20
char news[40], newc[40];
void scroll_left(void)
{
vic_waitTop();
vic_waitBottom();
vic.ctrl2 = 0x02;
vic_waitTop();
vic_waitBottom();
vic.ctrl2 = 0x00;
vic_waitLine(50 + 8 * VSPLIT);
for(char x=0; x<39; x++)
{
#assign ty 0
#repeat
sline(0, ty)[x] = sline(1, ty)[x];
cline(0, ty)[x] = cline(1, ty)[x];
#assign ty ty + 1
#until ty == VSPLIT
}
#assign ty 0
#repeat
sline(0, ty)[39] = news[ty];
cline(0, ty)[39] = newc[ty];
#assign ty ty + 1
#until ty == VSPLIT
vic_waitBottom();
vic.ctrl2 = 0x06;
for(char x=0; x<39; x++)
{
#assign ty VSPLIT
#repeat
sline(0, ty)[x] = sline(1, ty)[x];
cline(0, ty)[x] = cline(1, ty)[x];
#assign ty ty + 1
#until ty == 25
}
#assign ty VSPLIT
#repeat
sline(0, ty)[39] = news[ty];
cline(0, ty)[39] = newc[ty];
#assign ty ty + 1
#until ty == 25
vic_waitBottom();
vic.ctrl2 = 0x04
}
void scroll_right(void)
{
vic_waitTop();
vic_waitBottom();
vic.ctrl2 = 0x06;
vic_waitLine(50 + 8 * VSPLIT);
for(char x=39; x>0; x--)
{
#assign ty 0
#repeat
sline(0, ty)[x] = sline(-1, ty)[x];
cline(0, ty)[x] = cline(-1, ty)[x];
#assign ty ty + 1
#until ty == VSPLIT
}
#assign ty 0
#repeat
sline(0, ty)[0] = news[ty];
cline(0, ty)[0] = newc[ty];
#assign ty ty + 1
#until ty == VSPLIT
vic_waitBottom();
vic.ctrl2 = 0x00;
for(char x=39; x>0; x--)
{
#assign ty VSPLIT
#repeat
sline(0, ty)[x] = sline(-1, ty)[x];
cline(0, ty)[x] = cline(-1, ty)[x];
#assign ty ty + 1
#until ty == 25
}
#assign ty VSPLIT
#repeat
sline(0, ty)[0] = news[ty];
cline(0, ty)[0] = newc[ty];
#assign ty ty + 1
#until ty == 25
vic_waitBottom();
vic.ctrl2 = 0x02
vic_waitTop();
vic_waitBottom();
vic.ctrl2 = 0x04;
}
void scroll_up(void)
{
vic_waitTop();
vic_waitBottom();
vic.ctrl1 = 0x02 | VIC_CTRL1_DEN;
vic_waitTop();
vic_waitBottom();
vic.ctrl1 = 0x00 | VIC_CTRL1_DEN;
vic_waitLine(50 + 8 * VSPLIT);
for(char x=0; x<40; x++)
{
#assign ty 0
#repeat
sline(0, ty)[x] = sline(0, ty + 1)[x];
cline(0, ty)[x] = cline(0, ty + 1)[x];
#assign ty ty + 1
#until ty == VSPLIT
}
vic_waitBottom();
vic.ctrl1 = 0x06 | VIC_CTRL1_DEN;
for(char x=0; x<40; x++)
{
#assign ty VSPLIT
#repeat
sline(0, ty)[x] = sline(0, ty + 1)[x];
cline(0, ty)[x] = cline(0, ty + 1)[x];
#assign ty ty + 1
#until ty == 24
sline(0, ty)[x] = news[x];
cline(0, ty)[x] = newc[x];
}
vic_waitBottom();
vic.ctrl1 = 0x04 | VIC_CTRL1_DEN;
}
char tmp0[40], tmp1[40], tmp2[40], tmp3[40];
void scroll_down(void)
{
vic_waitTop();
vic_waitBottom();
for(char x=0; x<40; x++)
{
tmp0[x] = sline(0, VSPLIT)[x];
tmp1[x] = cline(0, VSPLIT)[x];
}
vic.ctrl1 = 0x06 | VIC_CTRL1_DEN;
vic_waitLine(58 + 8 * VSPLIT);
for(char x=0; x<40; x++)
{
#assign ty VSPLIT
#repeat
sline(0, ty)[x] = sline(0, ty - 1)[x];
cline(0, ty)[x] = cline(0, ty - 1)[x];
#assign ty ty - 1
#until ty == 0
sline(0, ty)[x] = news[x];
cline(0, ty)[x] = newc[x];
}
// vic_waitBottom();
vic.ctrl1 = 0x00 | VIC_CTRL1_DEN;
for(char x=0; x<40; x++)
{
tmp2[x] = sline(0, VSPLIT2)[x];
tmp3[x] = cline(0, VSPLIT2)[x];
#assign ty VSPLIT2
#repeat
sline(0, ty)[x] = sline(0, ty - 1)[x];
cline(0, ty)[x] = cline(0, ty - 1)[x];
#assign ty ty - 1
#until ty == VSPLIT + 1
sline(0, ty)[x] = tmp0[x];
cline(0, ty)[x] = tmp1[x];
}
for(char x=0; x<40; x++)
{
#assign ty 24
#repeat
sline(0, ty)[x] = sline(0, ty - 1)[x];
cline(0, ty)[x] = cline(0, ty - 1)[x];
#assign ty ty - 1
#until ty == VSPLIT2 + 1
sline(0, ty)[x] = tmp2[x];
cline(0, ty)[x] = tmp3[x];
}
vic_waitBottom();
vic.ctrl1 = 0x02 | VIC_CTRL1_DEN;
vic_waitTop();
vic_waitBottom();
vic.ctrl1 = 0x04 | VIC_CTRL1_DEN;
}
char grid[16][16];
#pragma align(grid, 256)
int main(void)
{
__asm
{
sei
}
for(char y=0; y<16; y++)
{
for(char x=0; x<16; x++)
{
grid[y][x] = rand() & 3;
}
}
char gridX = 0, gridY = 0;
char * dp = Screen, * cp = Color;
for(char y=0; y<25; y++)
{
expandrow(dp, cp, &(grid[y >> 2][0]), 4 * (y & 3), 0);
dp += 40;
cp += 40;
}
for(;;)
{
joy_poll(1);
if (joyx[1] == 1)
{
if (gridX < 24)
{
gridX++;
expandcol(news, newc, &(grid[gridY >> 2][(gridX + 39) >> 2]), 4 * (gridY & 3), (gridX + 39) & 3);
scroll_left();
}
}
else if (joyx[1] == -1)
{
if (gridX > 0)
{
gridX--;
expandcol(news, newc, &(grid[gridY >> 2][gridX >> 2]), 4 * (gridY & 3), gridX & 3);
scroll_right();
}
}
else if (joyy[1] == 1)
{
if (gridY < 39)
{
gridY++;
expandrow(news, newc, &(grid[(gridY + 24) >> 2][gridX >> 2]), 4 * ((gridY + 24) & 3), gridX & 3);
scroll_up();
}
}
else if (joyy[1] == -1)
{
if (gridY > 0)
{
gridY--;
expandrow(news, newc, &(grid[gridY >> 2][gridX >> 2]), 4 * (gridY & 3), gridX & 3);
scroll_down();
}
}
}
return 0;
}