mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-10-31 23:09:49 +00:00
c64: fixed presets
This commit is contained in:
parent
63d3b88a7a
commit
a5a8b94991
281
presets/c64/scrolling2.c
Normal file
281
presets/c64/scrolling2.c
Normal file
@ -0,0 +1,281 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "scrolling.h"
|
||||
|
||||
#define VICBANK 0x8000
|
||||
#define BUFFER_A (byte*) 0x8000
|
||||
#define BUFFER_B (byte*) 0x8400
|
||||
|
||||
sbyte scroll_fine_x;
|
||||
sbyte scroll_fine_y;
|
||||
byte origin_x;
|
||||
byte origin_y;
|
||||
byte* hidbuf;
|
||||
byte* visbuf;
|
||||
byte colorbuf[COLS*ROWS];
|
||||
int pixofs_x;
|
||||
int pixofs_y;
|
||||
sbyte fine_correct_x;
|
||||
sbyte fine_correct_y;
|
||||
|
||||
byte scroll_dir;
|
||||
byte scroll_seq;
|
||||
|
||||
//
|
||||
|
||||
static void wait_offscreen(void) {
|
||||
while (VIC.rasterline < 250 && VIC.rasterline > 40) ;
|
||||
}
|
||||
|
||||
void scroll_swap(void) {
|
||||
byte* tmp;
|
||||
// swap hidden and visible buffers
|
||||
tmp = hidbuf;
|
||||
hidbuf = visbuf;
|
||||
visbuf = tmp;
|
||||
// set VIC bank address
|
||||
wait_offscreen();
|
||||
VIC.addr = (VIC.addr & 0xf) | (((word)visbuf >> 8) << 2);
|
||||
}
|
||||
|
||||
void copy_color_ram_slow() {
|
||||
memcpy(COLOR_RAM, colorbuf, COLS*ROWS);
|
||||
}
|
||||
|
||||
void copy_color_ram_fast() {
|
||||
// fast copy loop for upper 1/2 of color ram
|
||||
asm("ldy #0");
|
||||
asm("@loop:");
|
||||
asm("lda %v,y", colorbuf);
|
||||
asm("sta $d800,y");
|
||||
asm("lda %v + $100,y", colorbuf);
|
||||
asm("sta $d900,y");
|
||||
asm("iny");
|
||||
asm("bne @loop");
|
||||
// second loop for lower 1/2 of color ram
|
||||
asm("@loop2:");
|
||||
asm("lda %v + $200,y", colorbuf);
|
||||
asm("sta $da00,y");
|
||||
asm("lda %v + $300,y", colorbuf);
|
||||
asm("sta $db00,y");
|
||||
asm("@skip: iny");
|
||||
asm("bne @loop2");
|
||||
}
|
||||
|
||||
void copy_to_hidden_buffer_slow() {
|
||||
memcpy(hidbuf, visbuf, COLS*ROWS);
|
||||
}
|
||||
|
||||
void copy_to_hidden_buffer_fast() {
|
||||
// self-modifying code
|
||||
asm("ldy %v+1", visbuf);
|
||||
asm("sty @loop+2+6*0");
|
||||
asm("iny");
|
||||
asm("sty @loop+2+6*1");
|
||||
asm("iny");
|
||||
asm("sty @loop+2+6*2");
|
||||
asm("iny");
|
||||
asm("sty @skip-1-3");
|
||||
asm("ldy %v+1", hidbuf);
|
||||
asm("sty @loop+5+6*0");
|
||||
asm("iny");
|
||||
asm("sty @loop+5+6*1");
|
||||
asm("iny");
|
||||
asm("sty @loop+5+6*2");
|
||||
asm("iny");
|
||||
asm("sty @skip-1");
|
||||
// fast copy loop
|
||||
asm("ldy #0");
|
||||
asm("@loop:");
|
||||
asm("lda $8000,y");
|
||||
asm("sta $8000,y");
|
||||
asm("lda $8100,y");
|
||||
asm("sta $8100,y");
|
||||
asm("lda $8200,y");
|
||||
asm("sta $8200,y");
|
||||
asm("cpy #$e8");
|
||||
asm("bcs @skip");
|
||||
asm("lda $8300,y");
|
||||
asm("sta $8300,y");
|
||||
asm("@skip: iny");
|
||||
asm("bne @loop");
|
||||
}
|
||||
|
||||
void scroll_start(byte dir) {
|
||||
if (scroll_seq == 0 && dir) {
|
||||
scroll_dir = dir;
|
||||
scroll_seq = 8;
|
||||
// correct sprites b/c our fine offset is one pixel
|
||||
// off depending on last scroll direction
|
||||
if (dir & SCROLL_LEFT) fine_correct_x = 1;
|
||||
else if (dir & SCROLL_RIGHT) fine_correct_x = 0;
|
||||
if (dir & SCROLL_UP) fine_correct_y = 1;
|
||||
else if (dir & SCROLL_DOWN) fine_correct_y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_step_move_buffer(char* src, char* dst) {
|
||||
word size = COLS*ROWS;
|
||||
if (scroll_dir & SCROLL_LEFT) {
|
||||
++src;
|
||||
--size;
|
||||
}
|
||||
if (scroll_dir & SCROLL_RIGHT) {
|
||||
++dst;
|
||||
--size;
|
||||
}
|
||||
if (scroll_dir & SCROLL_UP) {
|
||||
src += COLS;
|
||||
size -= COLS;
|
||||
}
|
||||
if (scroll_dir & SCROLL_DOWN) {
|
||||
dst += COLS;
|
||||
size -= COLS;
|
||||
}
|
||||
memmove(dst, src, size);
|
||||
}
|
||||
|
||||
void scroll_step_draw_cells() {
|
||||
if (scroll_dir & SCROLL_UP) ++origin_y;
|
||||
if (scroll_dir & SCROLL_DOWN) --origin_y;
|
||||
if (scroll_dir & SCROLL_LEFT) {
|
||||
++origin_x;
|
||||
scroll_draw_column(COLS-1);
|
||||
}
|
||||
if (scroll_dir & SCROLL_RIGHT) {
|
||||
--origin_x;
|
||||
scroll_draw_column(0);
|
||||
}
|
||||
if (scroll_dir & SCROLL_UP) {
|
||||
scroll_draw_row(ROWS-1);
|
||||
}
|
||||
if (scroll_dir & SCROLL_DOWN) {
|
||||
scroll_draw_row(0);
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_step_move_sprites() {
|
||||
// copy sprites from visible to hidden buffer
|
||||
memcpy(hidbuf + 0x3f8, visbuf + 0x3f8, 8);
|
||||
}
|
||||
|
||||
void scroll_update_pixofs() {
|
||||
// fine scroll starts at 8-5 = 32107 or 12-8 = 45670
|
||||
if (scroll_dir & SCROLL_LEFT) {
|
||||
pixofs_x -= 1;
|
||||
scroll_fine_x = (scroll_seq - 5) & 7;
|
||||
}
|
||||
if (scroll_dir & SCROLL_RIGHT) {
|
||||
pixofs_x += 1;
|
||||
scroll_fine_x = (12 - scroll_seq) & 7;
|
||||
}
|
||||
if (scroll_dir & SCROLL_UP) {
|
||||
pixofs_y -= 1;
|
||||
scroll_fine_y = (scroll_seq - 5) & 7;
|
||||
}
|
||||
if (scroll_dir & SCROLL_DOWN) {
|
||||
pixofs_y += 1;
|
||||
scroll_fine_y = (12 - scroll_seq) & 7;
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_offset_sprites(byte delta) {
|
||||
byte dx = 0;
|
||||
byte dy = 0;
|
||||
// fine scroll starts at 8-5 = 32107 or 12-8 = 45670
|
||||
if (scroll_dir & SCROLL_LEFT) {
|
||||
dx = -delta;
|
||||
}
|
||||
if (scroll_dir & SCROLL_RIGHT) {
|
||||
dx = delta;
|
||||
}
|
||||
if (scroll_dir & SCROLL_UP) {
|
||||
dy = -delta;
|
||||
}
|
||||
if (scroll_dir & SCROLL_DOWN) {
|
||||
dy = delta;
|
||||
}
|
||||
VIC.spr_pos[0].x += dx;
|
||||
VIC.spr_pos[1].x += dx;
|
||||
VIC.spr_pos[0].y += dy;
|
||||
VIC.spr_pos[1].y += dy;
|
||||
}
|
||||
|
||||
void scroll_update_scroll_regs() {
|
||||
wait_offscreen();
|
||||
VIC.ctrl1 = (VIC.ctrl1 & 0xf8) | scroll_fine_y;
|
||||
VIC.ctrl2 = (VIC.ctrl2 & 0xf8) | scroll_fine_x;
|
||||
}
|
||||
|
||||
void scroll_next_step(void) {
|
||||
switch (--scroll_seq) {
|
||||
case 7:
|
||||
scroll_step_move_buffer(visbuf, hidbuf);
|
||||
break;
|
||||
case 6:
|
||||
scroll_step_move_buffer(colorbuf, colorbuf);
|
||||
break;
|
||||
case 5:
|
||||
scroll_step_draw_cells();
|
||||
break;
|
||||
case 4:
|
||||
scroll_step_move_sprites();
|
||||
break;
|
||||
case 3:
|
||||
scroll_swap();
|
||||
copy_color_ram_fast();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_update(void) {
|
||||
if (scroll_seq) {
|
||||
scroll_update_pixofs();
|
||||
scroll_update_scroll_regs();
|
||||
scroll_offset_sprites(1);
|
||||
scroll_next_step();
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_finish(void) {
|
||||
while (scroll_seq) {
|
||||
scroll_update_pixofs();
|
||||
if (scroll_seq == 4) { scroll_offset_sprites(8); }
|
||||
scroll_next_step();
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_setup(void) {
|
||||
origin_x = origin_y = 0;
|
||||
pixofs_x = pixofs_y = 0;
|
||||
scroll_fine_x = scroll_fine_y = 3;
|
||||
scroll_dir = 0;
|
||||
scroll_seq = 0;
|
||||
|
||||
// setup screen buffer addresses
|
||||
hidbuf = BUFFER_A;
|
||||
visbuf = BUFFER_B;
|
||||
|
||||
memset(BUFFER_A, 0, 0x800);
|
||||
memset(colorbuf, 0, sizeof(colorbuf));
|
||||
|
||||
SET_VIC_BANK(VICBANK);
|
||||
|
||||
// set up 24 line / 38 column mode to hide edges
|
||||
VIC.ctrl1 &= ~0x08; // 24 lines
|
||||
VIC.ctrl2 &= ~0x08; // 38 columns
|
||||
}
|
||||
|
||||
void scroll_refresh(void) {
|
||||
byte i;
|
||||
for (i=0; i<25; i++) {
|
||||
scroll_draw_row(i);
|
||||
}
|
||||
scroll_swap();
|
||||
copy_color_ram_fast();
|
||||
copy_to_hidden_buffer_fast();
|
||||
scroll_dir = 0;
|
||||
scroll_seq = 0;
|
||||
scroll_fine_x = scroll_fine_y = 3;
|
||||
}
|
Loading…
Reference in New Issue
Block a user