mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-05-28 08:41:30 +00:00
c64: update presets
This commit is contained in:
parent
c4fcf51e55
commit
d99260c87e
|
@ -5,7 +5,7 @@ SYMBOLS {
|
||||||
__LOADADDR__: type = import;
|
__LOADADDR__: type = import;
|
||||||
__EXEHDR__: type = import;
|
__EXEHDR__: type = import;
|
||||||
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
||||||
__HIMEM__: type = weak, value = $D000;
|
__HIMEM__: type = weak, value = $8000;
|
||||||
}
|
}
|
||||||
MEMORY {
|
MEMORY {
|
||||||
ZP: file = "", define = yes, start = $0002, size = $001A;
|
ZP: file = "", define = yes, start = $0002, size = $001A;
|
||||||
|
@ -15,6 +15,7 @@ MEMORY {
|
||||||
SIDFILE: file = %O, define = yes, start = $1000, size = $1000, fill = yes;
|
SIDFILE: file = %O, define = yes, start = $1000, size = $1000, fill = yes;
|
||||||
MAIN: file = %O, define = yes, start = $2000, size = __HIMEM__ - $2000;
|
MAIN: file = %O, define = yes, start = $2000, size = __HIMEM__ - $2000;
|
||||||
BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__;
|
BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__;
|
||||||
|
VICBANK: file = %O, start = $8000, size = $4000;
|
||||||
}
|
}
|
||||||
SEGMENTS {
|
SEGMENTS {
|
||||||
ZEROPAGE: load = ZP, type = zp;
|
ZEROPAGE: load = ZP, type = zp;
|
||||||
|
@ -29,6 +30,7 @@ SEGMENTS {
|
||||||
INIT: load = MAIN, type = rw;
|
INIT: load = MAIN, type = rw;
|
||||||
ONCE: load = MAIN, type = ro, define = yes;
|
ONCE: load = MAIN, type = ro, define = yes;
|
||||||
BSS: load = BSS, type = bss, define = yes;
|
BSS: load = BSS, type = bss, define = yes;
|
||||||
|
VICBANK: load = MAIN, type = ro, optional = yes;
|
||||||
}
|
}
|
||||||
FEATURES {
|
FEATURES {
|
||||||
CONDES: type = constructor,
|
CONDES: type = constructor,
|
||||||
|
|
|
@ -5,6 +5,16 @@
|
||||||
#include <c64.h>
|
#include <c64.h>
|
||||||
#include <joystick.h>
|
#include <joystick.h>
|
||||||
|
|
||||||
|
//#resource "c64-sid.cfg"
|
||||||
|
#define CFGFILE c64-sid.cfg
|
||||||
|
|
||||||
|
//#resource "sidmusic1.bin"
|
||||||
|
//#link "sidplaysfx.ca65"
|
||||||
|
#include "sidplaysfx.h"
|
||||||
|
|
||||||
|
//#link "rasterirq.ca65"
|
||||||
|
#include "rasterirq.h"
|
||||||
|
|
||||||
#include "bcd.h"
|
#include "bcd.h"
|
||||||
//#link "bcd.c"
|
//#link "bcd.c"
|
||||||
|
|
||||||
|
@ -17,13 +27,6 @@
|
||||||
#include "sprites.h"
|
#include "sprites.h"
|
||||||
//#link "sprites.c"
|
//#link "sprites.c"
|
||||||
|
|
||||||
//#resource "c64-sid.cfg"
|
|
||||||
#define CFGFILE c64-sid.cfg
|
|
||||||
|
|
||||||
//#resource "sidmusic1.bin"
|
|
||||||
//#link "sidplaysfx.ca65"
|
|
||||||
#include "sidplaysfx.h"
|
|
||||||
|
|
||||||
// indices of sound effects
|
// indices of sound effects
|
||||||
#define SND_JUMP 0
|
#define SND_JUMP 0
|
||||||
#define SND_HIT 2
|
#define SND_HIT 2
|
||||||
|
@ -755,6 +758,16 @@ void play_scene() {
|
||||||
blimp_pickup_scene();
|
blimp_pickup_scene();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// main display list
|
||||||
|
void game_displaylist(void) {
|
||||||
|
VIC.bordercolor = 2;
|
||||||
|
sid_update();
|
||||||
|
VIC.bordercolor = 0;
|
||||||
|
// DLIST_NEXT(42);
|
||||||
|
// VIC.bordercolor = 3;
|
||||||
|
DLIST_RESTART(20);
|
||||||
|
}
|
||||||
|
|
||||||
// main program
|
// main program
|
||||||
void main() {
|
void main() {
|
||||||
byte i;
|
byte i;
|
||||||
|
@ -767,14 +780,16 @@ void main() {
|
||||||
sprite_shape(hidbuf, 32+i, SPRITE_DATA[i]);
|
sprite_shape(hidbuf, 32+i, SPRITE_DATA[i]);
|
||||||
}
|
}
|
||||||
sprshad.spr_mcolor = 0xff;
|
sprshad.spr_mcolor = 0xff;
|
||||||
sprshad.spr_mcolor0 = 0x0f;
|
VIC.spr_mcolor0 = 0x0f;
|
||||||
sprshad.spr_mcolor1 = 0x00;
|
VIC.spr_mcolor1 = 0x00;
|
||||||
// select character set 2
|
// select character set 2
|
||||||
VIC.addr = 0x15;
|
VIC.addr = 0x15;
|
||||||
// start scrolling @ bottom of level
|
// start scrolling @ bottom of level
|
||||||
origin_y = START_ORIGIN_Y;
|
origin_y = START_ORIGIN_Y;
|
||||||
// install joystick
|
// install joystick
|
||||||
joy_install (joy_static_stddrv);
|
joy_install (joy_static_stddrv);
|
||||||
|
// setup display list
|
||||||
|
DLIST_SETUP(game_displaylist);
|
||||||
// main game loop
|
// main game loop
|
||||||
while (1) {
|
while (1) {
|
||||||
make_floors();
|
make_floors();
|
||||||
|
|
|
@ -7,6 +7,7 @@ Start
|
||||||
sei ; turn off interrupts
|
sei ; turn off interrupts
|
||||||
ldy #0
|
ldy #0
|
||||||
sty $d020 ; reset border color
|
sty $d020 ; reset border color
|
||||||
|
|
||||||
Loop
|
Loop
|
||||||
lda Message,y ; load message byte
|
lda Message,y ; load message byte
|
||||||
beq EOM ; 0 = end of string
|
beq EOM ; 0 = end of string
|
||||||
|
|
86
presets/c64/rasterirq.ca65
Normal file
86
presets/c64/rasterirq.ca65
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
|
||||||
|
USE_INTERRUPTOR = 0
|
||||||
|
|
||||||
|
.segment "DATA"
|
||||||
|
|
||||||
|
StartDlist: .word NullDlist-1
|
||||||
|
NextDlist: .word NullDlist-1
|
||||||
|
|
||||||
|
.segment "CODE"
|
||||||
|
|
||||||
|
.global _dlist_setup
|
||||||
|
.global DLIST_IRQ_NEXT
|
||||||
|
.global DLIST_IRQ_RESTART
|
||||||
|
.if USE_INTERRUPTOR
|
||||||
|
.interruptor DLIST_IRQ
|
||||||
|
.endif
|
||||||
|
|
||||||
|
_dlist_setup:
|
||||||
|
SEI ; set interrupt bit, make the CPU ignore interrupt requests
|
||||||
|
|
||||||
|
sta StartDlist+0 ; save XA as pointer to start of dlist
|
||||||
|
stx StartDlist+1
|
||||||
|
|
||||||
|
LDA #%01111111 ; switch off interrupt signals from CIA-1
|
||||||
|
STA $DC0D
|
||||||
|
|
||||||
|
AND $D011 ; clear most significant bit of VIC's raster register
|
||||||
|
STA $D011
|
||||||
|
|
||||||
|
LDA $DC0D ; acknowledge pending interrupts from CIA-1
|
||||||
|
LDA $DD0D ; acknowledge pending interrupts from CIA-2
|
||||||
|
|
||||||
|
LDA #252 ; set rasterline where interrupt shall occur
|
||||||
|
STA $D012
|
||||||
|
|
||||||
|
.if !USE_INTERRUPTOR
|
||||||
|
LDA #<DLIST_IRQ ; set interrupt vectors, pointing to interrupt service routine below
|
||||||
|
STA $0314
|
||||||
|
LDA #>DLIST_IRQ
|
||||||
|
STA $0315
|
||||||
|
.endif
|
||||||
|
|
||||||
|
LDA #%00000001 ; enable raster interrupt signals from VIC
|
||||||
|
STA $D01A
|
||||||
|
cli
|
||||||
|
rts
|
||||||
|
|
||||||
|
DLIST_IRQ:
|
||||||
|
DLIST_CALL:
|
||||||
|
lda NextDlist+1
|
||||||
|
pha
|
||||||
|
lda NextDlist+0
|
||||||
|
pha
|
||||||
|
rts
|
||||||
|
|
||||||
|
DLIST_IRQ_RESTART:
|
||||||
|
sta $d012
|
||||||
|
lda StartDlist+0
|
||||||
|
sta NextDlist+0
|
||||||
|
lda StartDlist+1
|
||||||
|
sta NextDlist+1
|
||||||
|
bne DLIST_ACK
|
||||||
|
|
||||||
|
DLIST_IRQ_STOP:
|
||||||
|
lda #0 ; disable raster interrupt signals from VIC
|
||||||
|
sta $D01A
|
||||||
|
bne DLIST_ACK
|
||||||
|
|
||||||
|
DLIST_IRQ_NEXT:
|
||||||
|
sta $d012
|
||||||
|
pla
|
||||||
|
sta NextDlist+0
|
||||||
|
pla
|
||||||
|
sta NextDlist+1
|
||||||
|
DLIST_ACK:
|
||||||
|
ASL $D019 ; acknowledge the interrupt by clearing the VIC's interrupt flag
|
||||||
|
.if USE_INTERRUPTOR
|
||||||
|
clc
|
||||||
|
rts
|
||||||
|
.else
|
||||||
|
JMP $EA31 ; jump into KERNAL's standard interrupt service routine to handle keyboard scan, cursor display etc.
|
||||||
|
.endif
|
||||||
|
|
||||||
|
NullDlist:
|
||||||
|
lda #252
|
||||||
|
jmp DLIST_IRQ_RESTART
|
19
presets/c64/rasterirq.h
Normal file
19
presets/c64/rasterirq.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef _RASTERIRQ_H
|
||||||
|
#define _RASTERIRQ_H
|
||||||
|
|
||||||
|
|
||||||
|
void dlist_setup(void* ptr);
|
||||||
|
|
||||||
|
#define DLIST_SETUP(func) \
|
||||||
|
dlist_setup(((char*)func)-1)
|
||||||
|
|
||||||
|
#define DLIST_NEXT(line) \
|
||||||
|
__A__ = line; \
|
||||||
|
asm ("jsr DLIST_IRQ_NEXT");
|
||||||
|
|
||||||
|
#define DLIST_RESTART(line) \
|
||||||
|
__A__ = line; \
|
||||||
|
asm ("jmp DLIST_IRQ_RESTART");
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -8,183 +8,92 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <joystick.h>
|
#include <joystick.h>
|
||||||
|
|
||||||
typedef uint8_t byte;
|
#include "common.h"
|
||||||
typedef uint16_t word;
|
//#link "common.c"
|
||||||
typedef int8_t sbyte;
|
|
||||||
|
|
||||||
#define COLS 40
|
#include "scrolling.h"
|
||||||
#define ROWS 25
|
//#link "scrolling.c"
|
||||||
|
|
||||||
void raster_wait(unsigned char line) {
|
#include "sprites.h"
|
||||||
while (VIC.rasterline < line) ;
|
//#link "sprites.c"
|
||||||
}
|
|
||||||
|
|
||||||
void wait_vblank() {
|
static void draw_cell(word ofs, byte x, byte y) {
|
||||||
raster_wait(255); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
sbyte scroll_fine_x;
|
|
||||||
sbyte scroll_fine_y;
|
|
||||||
byte origin_x;
|
|
||||||
byte origin_y;
|
|
||||||
byte curbuf;
|
|
||||||
byte* scrnbuf[2]; // screen buffer(s)
|
|
||||||
byte tempbuf[COLS*ROWS];
|
|
||||||
|
|
||||||
void draw_cell(byte x, byte y) {
|
|
||||||
byte xx = x + origin_x;
|
byte xx = x + origin_x;
|
||||||
byte yy = y + origin_y;
|
byte yy = y + origin_y;
|
||||||
byte ch = xx ^ yy;
|
byte ch = xx ^ yy;
|
||||||
word ofs = x+y*COLS;
|
hidbuf[ofs] = ch; // character
|
||||||
scrnbuf[curbuf][ofs] = ch; // character
|
colorbuf[ofs] = ch; // color
|
||||||
tempbuf[ofs] = ch; // color
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll_draw_column(byte col) {
|
void scroll_draw_column(byte col) {
|
||||||
byte y;
|
byte y;
|
||||||
|
word ofs = col;
|
||||||
for (y=0; y<ROWS; y++) {
|
for (y=0; y<ROWS; y++) {
|
||||||
draw_cell(col, y);
|
draw_cell(ofs, col, y);
|
||||||
|
ofs += COLS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll_draw_row(byte row) {
|
void scroll_draw_row(byte row) {
|
||||||
byte x;
|
byte x;
|
||||||
|
word ofs = row * COLS;
|
||||||
for (x=0; x<COLS; x++) {
|
for (x=0; x<COLS; x++) {
|
||||||
draw_cell(x, row);
|
draw_cell(ofs, x, row);
|
||||||
|
++ofs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll_update_regs() {
|
/*{w:24,h:21,bpp:1,brev:1}*/
|
||||||
VIC.ctrl1 = (VIC.ctrl1 & 0xf8) | scroll_fine_y;
|
const char SPRITE1[3*21] = {
|
||||||
VIC.ctrl2 = (VIC.ctrl2 & 0xf8) | scroll_fine_x;
|
0x00,0x7F,0x00,0x01,0xFF,0xC0,0x03,0xFF,0xE0,
|
||||||
}
|
0x03,0xE7,0xE0,0x07,0xD9,0xF0,0x07,0xDF,0xF0,
|
||||||
|
0x07,0xD9,0xF0,0x03,0xE7,0xE0,0x03,0xFF,0xE0,
|
||||||
void scroll_swap() {
|
0x03,0xFF,0xE0,0x02,0xFF,0xA0,0x01,0x7F,0x40,
|
||||||
// swap hidden and visible buffers
|
0x01,0x3E,0x40,0x00,0x9C,0x80,0x00,0x9C,0x80,
|
||||||
curbuf ^= 1;
|
0x00,0x49,0x00,0x00,0x49,0x00,0x00,0x3E,0x00,
|
||||||
// wait for vblank and update registers
|
0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x1C,0x00
|
||||||
wait_vblank();
|
};
|
||||||
scroll_update_regs();
|
|
||||||
VIC.addr = (VIC.addr & 0xf) | (curbuf ? 0x00 : 0x10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void scroll_copy() {
|
|
||||||
// copy temp buf to color ram
|
|
||||||
memcpy(COLOR_RAM, tempbuf, COLS*ROWS);
|
|
||||||
// copy visible buffer to hidden buffer
|
|
||||||
memcpy(scrnbuf[curbuf], scrnbuf[curbuf^1], COLS*ROWS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: left and up can be faster, b/c we can copy color ram downward
|
|
||||||
|
|
||||||
void scroll_left() {
|
|
||||||
memcpy(scrnbuf[curbuf], scrnbuf[curbuf^1]+1, COLS*ROWS-1);
|
|
||||||
++origin_x;
|
|
||||||
memcpy(tempbuf, COLOR_RAM+1, COLS*ROWS-1);
|
|
||||||
scroll_draw_column(COLS-1);
|
|
||||||
scroll_swap();
|
|
||||||
scroll_copy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void scroll_up() {
|
|
||||||
memcpy(scrnbuf[curbuf], scrnbuf[curbuf^1]+COLS, COLS*(ROWS-1));
|
|
||||||
++origin_y;
|
|
||||||
memcpy(tempbuf, COLOR_RAM+COLS, COLS*(ROWS-1));
|
|
||||||
scroll_draw_row(ROWS-1);
|
|
||||||
scroll_swap();
|
|
||||||
scroll_copy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void scroll_right() {
|
|
||||||
memcpy(scrnbuf[curbuf]+1, scrnbuf[curbuf^1], COLS*ROWS-1);
|
|
||||||
--origin_x;
|
|
||||||
memcpy(tempbuf+1, COLOR_RAM, COLS*ROWS-1);
|
|
||||||
scroll_draw_column(0);
|
|
||||||
scroll_swap();
|
|
||||||
scroll_copy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void scroll_down() {
|
|
||||||
memcpy(scrnbuf[curbuf]+COLS, scrnbuf[curbuf^1], COLS*(ROWS-1));
|
|
||||||
--origin_y;
|
|
||||||
memcpy(tempbuf+COLS, COLOR_RAM, COLS*(ROWS-1));
|
|
||||||
scroll_draw_row(0);
|
|
||||||
scroll_swap();
|
|
||||||
scroll_copy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void scroll_horiz(sbyte delta_x) {
|
|
||||||
scroll_fine_x += delta_x;
|
|
||||||
while (scroll_fine_x < 0) {
|
|
||||||
scroll_fine_x += 8;
|
|
||||||
scroll_left();
|
|
||||||
}
|
|
||||||
while (scroll_fine_x >= 8) {
|
|
||||||
scroll_fine_x -= 8;
|
|
||||||
scroll_right();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void scroll_vert(sbyte delta_y) {
|
|
||||||
scroll_fine_y += delta_y;
|
|
||||||
while (scroll_fine_y < 0) {
|
|
||||||
scroll_fine_y += 8;
|
|
||||||
scroll_up();
|
|
||||||
}
|
|
||||||
while (scroll_fine_y >= 8) {
|
|
||||||
scroll_fine_y -= 8;
|
|
||||||
scroll_down();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void scroll_setup() {
|
|
||||||
scroll_fine_x = 0;
|
|
||||||
scroll_fine_y = 0;
|
|
||||||
origin_x = 0x80;
|
|
||||||
origin_y = 0x80;
|
|
||||||
curbuf = 0;
|
|
||||||
// get screen buffer addresses
|
|
||||||
scrnbuf[0] = (byte*) 0x8000;
|
|
||||||
scrnbuf[1] = (byte*) 0x8400;
|
|
||||||
// copy existing text to screen 0
|
|
||||||
memcpy(scrnbuf[0], (byte*)0x400, COLS*ROWS);
|
|
||||||
// copy screen 1 to screen 0
|
|
||||||
memcpy(scrnbuf[1], scrnbuf[0], COLS*ROWS);
|
|
||||||
|
|
||||||
// set VIC bank ($4000-$7FFF)
|
|
||||||
// https://www.c64-wiki.com/wiki/VIC_bank
|
|
||||||
CIA2.pra = 0x01;
|
|
||||||
|
|
||||||
VIC.ctrl1 = 0x10; // 24 lines
|
|
||||||
VIC.ctrl2 = 0x00; // 38 columns
|
|
||||||
}
|
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
sbyte n =0;
|
byte n = 0;
|
||||||
|
|
||||||
clrscr();
|
clrscr();
|
||||||
printf("\r\n\r\n\r\n Hello World!");
|
printf("\r\n\r\n\r\n Hello World!");
|
||||||
printf("\r\n\r\n\r\n This is how we scroll");
|
printf("\r\n\r\n\r\n This is how we scroll");
|
||||||
printf("\r\n\r\n\r\n But color RAM can't move");
|
printf("\r\n\r\n\r\n But color RAM can't move");
|
||||||
printf("\r\n\r\n\r\n So we have to use a temp buffer");
|
printf("\r\n\r\n\r\n So we have to use a temp buffer");
|
||||||
printf("\r\n\r\n\r\n And copy it just in time");
|
printf("\r\n\r\n\r\n And copy it just in time");
|
||||||
|
|
||||||
|
// setup scrolling library
|
||||||
scroll_setup();
|
scroll_setup();
|
||||||
|
|
||||||
|
// setup sprite library and copy sprite to VIC bank
|
||||||
|
sprite_clear();
|
||||||
|
sprite_shape(hidbuf, 32, SPRITE1);
|
||||||
|
|
||||||
// install the joystick driver
|
// install the joystick driver
|
||||||
joy_install (joy_static_stddrv);
|
joy_install (joy_static_stddrv);
|
||||||
|
|
||||||
// infinite loop
|
// infinite loop
|
||||||
while (1) {
|
while (1) {
|
||||||
|
static char speed = 1;
|
||||||
// get joystick bits
|
// get joystick bits
|
||||||
char joy = joy_read(0);
|
char joy = joy_read(0);
|
||||||
|
// speed up scrolling while button pressed
|
||||||
|
speed = JOY_BTN_1(joy) ? 2 : 1;
|
||||||
// move sprite based on arrow keys
|
// move sprite based on arrow keys
|
||||||
if (JOY_LEFT(joy)) scroll_horiz(-1);
|
if (JOY_LEFT(joy)) scroll_horiz(-speed);
|
||||||
if (JOY_UP(joy)) scroll_vert(-1);
|
if (JOY_UP(joy)) scroll_vert(-speed);
|
||||||
if (JOY_RIGHT(joy)) scroll_horiz(1);
|
if (JOY_RIGHT(joy)) scroll_horiz(speed);
|
||||||
if (JOY_DOWN(joy)) scroll_vert(1);
|
if (JOY_DOWN(joy)) scroll_vert(speed);
|
||||||
// update regs
|
// animate sprite in shadow sprite ram
|
||||||
|
sprite_draw(0, n++, 70, 32);
|
||||||
|
// wait for vblank
|
||||||
wait_vblank();
|
wait_vblank();
|
||||||
scroll_update_regs();
|
// update scroll registers
|
||||||
|
// and swap screens if we must
|
||||||
|
scroll_update();
|
||||||
|
// then update sprite registers
|
||||||
|
sprite_update(visbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,26 +17,29 @@
|
||||||
#include "sprites.h"
|
#include "sprites.h"
|
||||||
//#link "sprites.c"
|
//#link "sprites.c"
|
||||||
|
|
||||||
static void draw_cell(byte x, byte y) {
|
static void draw_cell(word ofs, byte x, byte y) {
|
||||||
byte xx = x + origin_x;
|
byte xx = x + origin_x;
|
||||||
byte yy = y + origin_y;
|
byte yy = y + origin_y;
|
||||||
byte ch = xx ^ yy;
|
byte ch = xx ^ yy;
|
||||||
word ofs = x+y*COLS;
|
|
||||||
hidbuf[ofs] = ch; // character
|
hidbuf[ofs] = ch; // character
|
||||||
colorbuf[ofs] = ch; // color
|
colorbuf[ofs] = ch; // color
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll_draw_column(byte col) {
|
void scroll_draw_column(byte col) {
|
||||||
byte y;
|
byte y;
|
||||||
|
word ofs = col;
|
||||||
for (y=0; y<ROWS; y++) {
|
for (y=0; y<ROWS; y++) {
|
||||||
draw_cell(col, y);
|
draw_cell(ofs, col, y);
|
||||||
|
ofs += COLS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll_draw_row(byte row) {
|
void scroll_draw_row(byte row) {
|
||||||
byte x;
|
byte x;
|
||||||
|
word ofs = row * COLS;
|
||||||
for (x=0; x<COLS; x++) {
|
for (x=0; x<COLS; x++) {
|
||||||
draw_cell(x, row);
|
draw_cell(ofs, x, row);
|
||||||
|
++ofs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,15 +54,42 @@ const char SPRITE1[3*21] = {
|
||||||
0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x1C,0x00
|
0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x1C,0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int playerx = 0;
|
||||||
|
int playery = 0;
|
||||||
|
int camerax = 0;
|
||||||
|
int cameray = 0;
|
||||||
|
|
||||||
|
void update_player() {
|
||||||
|
sprite_draw(0, playerx-camerax+160, playery-cameray+140, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
void camera_follow(byte moving) {
|
||||||
|
int dx, dy;
|
||||||
|
dx = camerax - playerx;
|
||||||
|
dy = cameray - playery;
|
||||||
|
if (moving && abs(dx) < 32 && abs(dy) < 32) return;
|
||||||
|
dx >>= 4;
|
||||||
|
dy >>= 4;
|
||||||
|
if (dx) {
|
||||||
|
if (dx > 8) dx = 8;
|
||||||
|
else if (dx < -8) dx = -8;
|
||||||
|
camerax -= dx;
|
||||||
|
scroll_horiz(dx);
|
||||||
|
}
|
||||||
|
if (dy) {
|
||||||
|
if (dy > 8) dy = 8;
|
||||||
|
else if (dy < -8) dy = -8;
|
||||||
|
cameray -= dy;
|
||||||
|
scroll_vert(dy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
byte n = 0;
|
|
||||||
|
|
||||||
clrscr();
|
clrscr();
|
||||||
printf("\r\n\r\n\r\n Hello World!");
|
printf("\r\n\r\n\r\n Hello World!");
|
||||||
printf("\r\n\r\n\r\n This is how we scroll");
|
printf("\r\n\r\n\r\n Use the joystick to move");
|
||||||
printf("\r\n\r\n\r\n But color RAM can't move");
|
printf("\r\n\r\n\r\n And the camera will follow");
|
||||||
printf("\r\n\r\n\r\n So we have to use a temp buffer");
|
|
||||||
printf("\r\n\r\n\r\n And copy it just in time");
|
|
||||||
|
|
||||||
// setup scrolling library
|
// setup scrolling library
|
||||||
scroll_setup();
|
scroll_setup();
|
||||||
|
@ -67,30 +97,39 @@ void main(void) {
|
||||||
// setup sprite library and copy sprite to VIC bank
|
// setup sprite library and copy sprite to VIC bank
|
||||||
sprite_clear();
|
sprite_clear();
|
||||||
sprite_shape(hidbuf, 32, SPRITE1);
|
sprite_shape(hidbuf, 32, SPRITE1);
|
||||||
|
sprshad.spr_color[0] = 13;
|
||||||
|
|
||||||
// install the joystick driver
|
// install the joystick driver
|
||||||
joy_install (joy_static_stddrv);
|
joy_install (joy_static_stddrv);
|
||||||
|
|
||||||
// infinite loop
|
// infinite loop
|
||||||
while (1) {
|
while (1) {
|
||||||
static char speed = 1;
|
static char speed;
|
||||||
|
static char joy;
|
||||||
|
static bool slowframe = false;
|
||||||
// get joystick bits
|
// get joystick bits
|
||||||
char joy = joy_read(0);
|
joy = joy_read(0);
|
||||||
// speed up scrolling while button pressed
|
// speed up scrolling while button pressed
|
||||||
speed = JOY_BTN_1(joy) ? 2 : 1;
|
speed = JOY_BTN_1(joy) ? 3 : 1;
|
||||||
|
// if we copied screen memory last frame,
|
||||||
|
// double speed of player for this frame
|
||||||
|
if (slowframe) speed *= 2;
|
||||||
// move sprite based on arrow keys
|
// move sprite based on arrow keys
|
||||||
if (JOY_LEFT(joy)) scroll_horiz(-speed);
|
if (JOY_LEFT(joy)) playerx -= speed;
|
||||||
if (JOY_UP(joy)) scroll_vert(-speed);
|
if (JOY_RIGHT(joy)) playerx += speed;
|
||||||
if (JOY_RIGHT(joy)) scroll_horiz(speed);
|
if (JOY_UP(joy)) playery -= speed;
|
||||||
if (JOY_DOWN(joy)) scroll_vert(speed);
|
if (JOY_DOWN(joy)) playery += speed;
|
||||||
|
// move the camera?
|
||||||
|
camera_follow(joy);
|
||||||
|
slowframe = swap_needed;
|
||||||
// animate sprite in shadow sprite ram
|
// animate sprite in shadow sprite ram
|
||||||
sprite_draw(0, n++, 70, 32);
|
update_player();
|
||||||
// wait for vblank
|
// wait for vblank
|
||||||
wait_vblank();
|
wait_vblank();
|
||||||
|
// then update sprite registers
|
||||||
|
sprite_update(visbuf);
|
||||||
// update scroll registers
|
// update scroll registers
|
||||||
// and swap screens if we must
|
// and swap screens if we must
|
||||||
scroll_update();
|
scroll_update();
|
||||||
// then update sprite registers
|
|
||||||
sprite_update(visbuf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,53 +11,124 @@ byte* hidbuf;
|
||||||
byte* visbuf;
|
byte* visbuf;
|
||||||
byte colorbuf[COLS*ROWS];
|
byte colorbuf[COLS*ROWS];
|
||||||
byte swap_needed;
|
byte swap_needed;
|
||||||
|
byte copy_needed;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
void scroll_swap(void) {
|
void scroll_swap(void) {
|
||||||
byte* tmp;
|
byte* tmp;
|
||||||
// set VIC bank address
|
|
||||||
VIC.addr = (VIC.addr & 0xf) | (((word)hidbuf >> 8) << 2);
|
|
||||||
// swap hidden and visible buffers
|
// swap hidden and visible buffers
|
||||||
tmp = hidbuf;
|
tmp = hidbuf;
|
||||||
hidbuf = visbuf;
|
hidbuf = visbuf;
|
||||||
visbuf = tmp;
|
visbuf = tmp;
|
||||||
|
// set VIC bank address
|
||||||
|
VIC.addr = (VIC.addr & 0xf) | (((word)visbuf >> 8) << 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll_copy(void) {
|
void copy_color_ram_slow() {
|
||||||
// copy temp buf to color ram
|
|
||||||
memcpy(COLOR_RAM, colorbuf, COLS*ROWS);
|
memcpy(COLOR_RAM, colorbuf, COLS*ROWS);
|
||||||
// copy visible buffer to hidden buffer
|
}
|
||||||
|
|
||||||
|
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);
|
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 copy_if_needed() {
|
||||||
|
if (copy_needed) {
|
||||||
|
copy_to_hidden_buffer_fast();
|
||||||
|
copy_needed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void scroll_update(void) {
|
void scroll_update(void) {
|
||||||
VIC.ctrl1 = (VIC.ctrl1 & 0xf8) | scroll_fine_y;
|
VIC.ctrl1 = (VIC.ctrl1 & 0xf8) | scroll_fine_y;
|
||||||
VIC.ctrl2 = (VIC.ctrl2 & 0xf8) | scroll_fine_x;
|
VIC.ctrl2 = (VIC.ctrl2 & 0xf8) | scroll_fine_x;
|
||||||
if (swap_needed) {
|
if (swap_needed) {
|
||||||
scroll_swap();
|
scroll_swap();
|
||||||
scroll_copy();
|
copy_color_ram_fast();
|
||||||
swap_needed = 0;
|
swap_needed = false;
|
||||||
|
copy_needed = true;
|
||||||
|
} else {
|
||||||
|
copy_if_needed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll_left(void) {
|
void scroll_left(void) {
|
||||||
memcpy(hidbuf, hidbuf+1, COLS*ROWS-1);
|
copy_if_needed();
|
||||||
memcpy(colorbuf, colorbuf+1, COLS*ROWS-1);
|
memmove(hidbuf, hidbuf+1, COLS*ROWS-1);
|
||||||
|
memmove(colorbuf, colorbuf+1, COLS*ROWS-1);
|
||||||
++origin_x;
|
++origin_x;
|
||||||
scroll_draw_column(COLS-1);
|
scroll_draw_column(COLS-1);
|
||||||
swap_needed = true;
|
swap_needed = true;
|
||||||
|
VIC.bordercolor = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll_up(void) {
|
void scroll_up(void) {
|
||||||
memcpy(hidbuf, hidbuf+COLS, COLS*(ROWS-1));
|
copy_if_needed();
|
||||||
memcpy(colorbuf, colorbuf+COLS, COLS*(ROWS-1));
|
memmove(hidbuf, hidbuf+COLS, COLS*(ROWS-1));
|
||||||
|
memmove(colorbuf, colorbuf+COLS, COLS*(ROWS-1));
|
||||||
++origin_y;
|
++origin_y;
|
||||||
scroll_draw_row(ROWS-1);
|
scroll_draw_row(ROWS-1);
|
||||||
swap_needed = true;
|
swap_needed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll_right(void) {
|
void scroll_right(void) {
|
||||||
|
copy_if_needed();
|
||||||
memmove(hidbuf+1, hidbuf, COLS*ROWS-1);
|
memmove(hidbuf+1, hidbuf, COLS*ROWS-1);
|
||||||
memmove(colorbuf+1, colorbuf, COLS*ROWS-1);
|
memmove(colorbuf+1, colorbuf, COLS*ROWS-1);
|
||||||
--origin_x;
|
--origin_x;
|
||||||
|
@ -66,6 +137,7 @@ void scroll_right(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll_down(void) {
|
void scroll_down(void) {
|
||||||
|
copy_if_needed();
|
||||||
memmove(hidbuf+COLS, hidbuf, COLS*(ROWS-1));
|
memmove(hidbuf+COLS, hidbuf, COLS*(ROWS-1));
|
||||||
memmove(colorbuf+COLS, colorbuf, COLS*(ROWS-1));
|
memmove(colorbuf+COLS, colorbuf, COLS*(ROWS-1));
|
||||||
--origin_y;
|
--origin_y;
|
||||||
|
@ -101,19 +173,22 @@ void scroll_setup(void) {
|
||||||
scroll_fine_x = scroll_fine_y = 0;
|
scroll_fine_x = scroll_fine_y = 0;
|
||||||
origin_x = origin_y = 0x80;
|
origin_x = origin_y = 0x80;
|
||||||
swap_needed = true;
|
swap_needed = true;
|
||||||
|
copy_needed = true;
|
||||||
|
|
||||||
// get screen buffer addresses
|
// setup screen buffer addresses
|
||||||
hidbuf = (byte*) 0x8000;
|
hidbuf = (byte*) 0x8000;
|
||||||
visbuf = (byte*) 0x8400;
|
visbuf = (byte*) 0x8400;
|
||||||
// copy existing text to screen 0
|
|
||||||
|
// copy existing screen contents to hidden buffer
|
||||||
memcpy(hidbuf, (byte*)0x400, COLS*ROWS);
|
memcpy(hidbuf, (byte*)0x400, COLS*ROWS);
|
||||||
// copy screen 1 to screen 0
|
// copy also to hidden buffer
|
||||||
memcpy(visbuf, hidbuf, COLS*ROWS);
|
memcpy(visbuf, hidbuf, COLS*ROWS);
|
||||||
|
|
||||||
// set VIC bank ($4000-$7FFF)
|
// set VIC bank ($8000-$BFFF)
|
||||||
// https://www.c64-wiki.com/wiki/VIC_bank
|
// https://www.c64-wiki.com/wiki/VIC_bank
|
||||||
CIA2.pra = 0x01;
|
CIA2.pra = 0x01;
|
||||||
|
|
||||||
|
// set up 24 line / 38 column mode to hide edges
|
||||||
VIC.ctrl1 &= ~0x08; // 24 lines
|
VIC.ctrl1 &= ~0x08; // 24 lines
|
||||||
VIC.ctrl2 &= ~0x08; // 38 columns
|
VIC.ctrl2 &= ~0x08; // 38 columns
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ void scroll_setup(void);
|
||||||
void scroll_horiz(sbyte delta_x);
|
void scroll_horiz(sbyte delta_x);
|
||||||
void scroll_vert(sbyte delta_y);
|
void scroll_vert(sbyte delta_y);
|
||||||
|
|
||||||
// call this after vblank
|
// call this right after vblank
|
||||||
void scroll_update(void);
|
void scroll_update(void);
|
||||||
|
|
||||||
// caller must implement these two
|
// caller must implement these two
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
//#link "sidplaysfx.ca65"
|
//#link "sidplaysfx.ca65"
|
||||||
#include "sidplaysfx.h"
|
#include "sidplaysfx.h"
|
||||||
|
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
clrscr();
|
clrscr();
|
||||||
cursor(0);
|
cursor(0);
|
||||||
|
@ -27,6 +26,6 @@ void main(void) {
|
||||||
sid_sfx(joy & 3);
|
sid_sfx(joy & 3);
|
||||||
}
|
}
|
||||||
waitvsync();
|
waitvsync();
|
||||||
//sid_update();
|
sid_update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
; music and SFX from GoatTracker 2 sample files
|
; music and SFX from GoatTracker 2 sample files
|
||||||
; http://sourceforge.net/projects/goattracker2
|
; http://sourceforge.net/projects/goattracker2
|
||||||
|
|
||||||
|
.segment "DATA"
|
||||||
|
|
||||||
|
_sid_playing: .byte $00
|
||||||
|
|
||||||
.segment "SIDFILE"
|
.segment "SIDFILE"
|
||||||
|
|
||||||
.incbin "sidmusic1.bin"
|
.incbin "sidmusic1.bin"
|
||||||
|
@ -9,13 +13,17 @@
|
||||||
.segment "LOWCODE"
|
.segment "LOWCODE"
|
||||||
|
|
||||||
.global _sid_init, _sid_update, _sid_sfx
|
.global _sid_init, _sid_update, _sid_sfx
|
||||||
.global _sid_start
|
.global _sid_start, _sid_stop, _sid_playing
|
||||||
|
|
||||||
_sid_init:
|
_sid_init:
|
||||||
jmp $1000
|
jmp $1000
|
||||||
|
|
||||||
_sid_update:
|
_sid_update:
|
||||||
|
bit _sid_playing
|
||||||
|
bpl @noplay
|
||||||
jmp $1003
|
jmp $1003
|
||||||
|
@noplay:
|
||||||
|
rts
|
||||||
|
|
||||||
_sid_sfx:
|
_sid_sfx:
|
||||||
tax
|
tax
|
||||||
|
@ -24,36 +32,14 @@ _sid_sfx:
|
||||||
ldx #$0e ;Channel index in X
|
ldx #$0e ;Channel index in X
|
||||||
jmp $1006 ;(0, 7 or 14)
|
jmp $1006 ;(0, 7 or 14)
|
||||||
|
|
||||||
SID_IRQ:
|
|
||||||
jsr $1003
|
|
||||||
ASL $D019 ; acknowledge the interrupt by clearing the VIC's interrupt flag
|
|
||||||
JMP $EA31 ; jump into KERNAL's standard interrupt service routine to handle keyboard scan, cursor display etc.
|
|
||||||
|
|
||||||
_sid_start:
|
_sid_start:
|
||||||
SEI ; set interrupt bit, make the CPU ignore interrupt requests
|
lda #$80
|
||||||
LDA #%01111111 ; switch off interrupt signals from CIA-1
|
bne skipstop
|
||||||
STA $DC0D
|
_sid_stop:
|
||||||
|
lda #$00
|
||||||
AND $D011 ; clear most significant bit of VIC's raster register
|
skipstop:
|
||||||
STA $D011
|
sta _sid_playing
|
||||||
|
rts
|
||||||
LDA $DC0D ; acknowledge pending interrupts from CIA-1
|
|
||||||
LDA $DD0D ; acknowledge pending interrupts from CIA-2
|
|
||||||
|
|
||||||
LDA #210 ; set rasterline where interrupt shall occur
|
|
||||||
STA $D012
|
|
||||||
|
|
||||||
LDA #<SID_IRQ ; set interrupt vectors, pointing to interrupt service routine below
|
|
||||||
STA $0314
|
|
||||||
LDA #>SID_IRQ
|
|
||||||
STA $0315
|
|
||||||
|
|
||||||
LDA #%00000001 ; enable raster interrupt signals from VIC
|
|
||||||
STA $D01A
|
|
||||||
|
|
||||||
CLI ; clear interrupt flag, allowing the CPU to respond to interrupt requests
|
|
||||||
RTS
|
|
||||||
|
|
||||||
|
|
||||||
sfxtbllo: .byte <arpeggio2
|
sfxtbllo: .byte <arpeggio2
|
||||||
.byte <arpeggio1
|
.byte <arpeggio1
|
||||||
|
|
|
@ -43,7 +43,7 @@ void move_sprites(void) {
|
||||||
byte i;
|
byte i;
|
||||||
for (i=0; i<8; i++) {
|
for (i=0; i<8; i++) {
|
||||||
//VIC.bordercolor = i;
|
//VIC.bordercolor = i;
|
||||||
sprite_draw(i, (xpos[i]>>7)+0x80, (ypos[i]>>8)+0x80, 32);
|
sprite_draw(i, (xpos[i]>>7)+0x80, (ypos[i]>>8)+0x80, 255);
|
||||||
// update position
|
// update position
|
||||||
xpos[i] += xvel[i];
|
xpos[i] += xvel[i];
|
||||||
ypos[i] += yvel[i];
|
ypos[i] += yvel[i];
|
||||||
|
@ -134,12 +134,12 @@ void main(void) {
|
||||||
|
|
||||||
// setup sprite library and copy sprite to VIC bank
|
// setup sprite library and copy sprite to VIC bank
|
||||||
sprite_clear();
|
sprite_clear();
|
||||||
sprite_shape((void*)0x400, 32/2, SPRITEMC);
|
sprite_shape((void*)0x0, 255, SPRITEMC);
|
||||||
|
|
||||||
// set colors
|
// set colors
|
||||||
sprshad.spr_mcolor = 0xff;
|
sprshad.spr_mcolor = 0xff;
|
||||||
sprshad.spr_mcolor0 = 4;
|
VIC.spr_mcolor0 = 4;
|
||||||
sprshad.spr_mcolor1 = 7;
|
VIC.spr_mcolor1 = 7;
|
||||||
|
|
||||||
// set sprite initial positions
|
// set sprite initial positions
|
||||||
init_sprites();
|
init_sprites();
|
||||||
|
|
|
@ -8,18 +8,16 @@ void sprite_clear(void) {
|
||||||
memset(&sprshad, 0, sizeof(sprshad));
|
memset(&sprshad, 0, sizeof(sprshad));
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprite_update(char* vicbank) {
|
void sprite_update(char* screenmem) {
|
||||||
memcpy(vicbank + 0x3f8, sprshad.spr_shapes, 8);
|
memcpy(screenmem + 0x3f8, sprshad.spr_shapes, 8);
|
||||||
VIC.spr_ena = sprshad.spr_ena;
|
|
||||||
VIC.spr_hi_x = sprshad.spr_hi_x;
|
|
||||||
memcpy(VIC.spr_pos, sprshad.spr_pos, 16);
|
memcpy(VIC.spr_pos, sprshad.spr_pos, 16);
|
||||||
memcpy(VIC.spr_color, sprshad.spr_color, 8);
|
memcpy(VIC.spr_color, sprshad.spr_color, 8);
|
||||||
|
VIC.spr_ena = sprshad.spr_ena;
|
||||||
|
VIC.spr_hi_x = sprshad.spr_hi_x;
|
||||||
VIC.spr_exp_x = sprshad.spr_exp_x;
|
VIC.spr_exp_x = sprshad.spr_exp_x;
|
||||||
VIC.spr_exp_y = sprshad.spr_exp_y;
|
VIC.spr_exp_y = sprshad.spr_exp_y;
|
||||||
VIC.spr_bg_prio = sprshad.spr_bg_prio;
|
VIC.spr_bg_prio = sprshad.spr_bg_prio;
|
||||||
VIC.spr_mcolor = sprshad.spr_mcolor;
|
VIC.spr_mcolor = sprshad.spr_mcolor;
|
||||||
VIC.spr_mcolor0 = sprshad.spr_mcolor0;
|
|
||||||
VIC.spr_mcolor1 = sprshad.spr_mcolor1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprite_shape(char* vicbank, byte index, const char* sprite_data) {
|
void sprite_shape(char* vicbank, byte index, const char* sprite_data) {
|
||||||
|
|
|
@ -6,26 +6,24 @@
|
||||||
#define DEFAULT_SCREEN ((void*)0x400)
|
#define DEFAULT_SCREEN ((void*)0x400)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
byte spr_ena; /* Enable sprites */
|
|
||||||
byte spr_hi_x; /* High bits of X coordinate */
|
|
||||||
byte spr_exp_x; /* Expand sprites in X dir */
|
|
||||||
byte spr_exp_y; /* Expand sprites in Y dir */
|
|
||||||
byte spr_bg_prio; /* Priority to background */
|
|
||||||
byte spr_mcolor; /* Sprite multicolor bits */
|
|
||||||
byte spr_mcolor0; /* Color 0 for multicolor sprites */
|
|
||||||
byte spr_mcolor1; /* Color 1 for multicolor sprites */
|
|
||||||
byte spr_color[8]; /* Colors for the sprites */
|
|
||||||
struct {
|
struct {
|
||||||
byte x; /* X coordinate */
|
byte x; /* X coordinate */
|
||||||
byte y; /* Y coordinate */
|
byte y; /* Y coordinate */
|
||||||
} spr_pos[8];
|
} spr_pos[8];
|
||||||
|
byte spr_hi_x; /* High bits of X coordinate */
|
||||||
|
byte spr_ena; /* Enable sprites */
|
||||||
|
byte spr_exp_y; /* Expand sprites in Y dir */
|
||||||
|
byte spr_bg_prio; /* Priority to background */
|
||||||
|
byte spr_mcolor; /* Sprite multicolor bits */
|
||||||
|
byte spr_exp_x; /* Expand sprites in X dir */
|
||||||
|
byte spr_color[8]; /* Colors for the sprites */
|
||||||
byte spr_shapes[8]; /* sprite shapes */
|
byte spr_shapes[8]; /* sprite shapes */
|
||||||
} SpriteShadow;
|
} SpriteShadow;
|
||||||
|
|
||||||
extern SpriteShadow sprshad;
|
extern SpriteShadow sprshad;
|
||||||
|
|
||||||
void sprite_clear(void);
|
void sprite_clear(void);
|
||||||
void sprite_update(char* screenram);
|
void sprite_update(char* screenmem);
|
||||||
void sprite_shape(char* vicbank, byte index, const char* sprite_data);
|
void sprite_shape(char* vicbank, byte index, const char* sprite_data);
|
||||||
void sprite_draw(byte i, word x, byte y, byte shape);
|
void sprite_draw(byte i, word x, byte y, byte shape);
|
||||||
byte sprite_get_closest_collision(byte i, byte spr_coll);
|
byte sprite_get_closest_collision(byte i, byte spr_coll);
|
||||||
|
|
69
presets/c64/spritesinborder.c
Normal file
69
presets/c64/spritesinborder.c
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <c64.h>
|
||||||
|
#include <cbm_petscii_charmap.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
//#link "rasterirq.ca65"
|
||||||
|
#include "rasterirq.h"
|
||||||
|
|
||||||
|
//#link "sprites.c"
|
||||||
|
#include "sprites.h"
|
||||||
|
|
||||||
|
/*{w:24,h:21,bpp:1,brev:1}*/
|
||||||
|
const char spriteshape[3*21] = {
|
||||||
|
0x00,0x7F,0x00,0x01,0xFF,0xC0,0x03,0xFF,0xE0,
|
||||||
|
0x03,0xE7,0xE0,0x07,0xD9,0xF0,0x07,0xDF,0xF0,
|
||||||
|
0x07,0xD9,0xF0,0x03,0xE7,0xE0,0x03,0xFF,0xE0,
|
||||||
|
0x03,0xFF,0xE0,0x02,0xFF,0xA0,0x01,0x7F,0x40,
|
||||||
|
0x01,0x3E,0x40,0x00,0x9C,0x80,0x00,0x9C,0x80,
|
||||||
|
0x00,0x49,0x00,0x00,0x49,0x00,0x00,0x3E,0x00,
|
||||||
|
0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x1C,0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
void dlist_example(void) {
|
||||||
|
static byte i = 0;
|
||||||
|
VIC.bordercolor = 6;
|
||||||
|
VIC.bordercolor = 5;
|
||||||
|
VIC.ctrl1 = 0x18;
|
||||||
|
DLIST_NEXT(150);
|
||||||
|
|
||||||
|
// VIC.ctrl1 = 5 | 0x18;
|
||||||
|
|
||||||
|
VIC.bordercolor = 2;
|
||||||
|
DLIST_NEXT(0xf9);
|
||||||
|
|
||||||
|
VIC.ctrl1 = 0x10;
|
||||||
|
VIC.bordercolor = 3;
|
||||||
|
DLIST_NEXT(0xfc);
|
||||||
|
|
||||||
|
VIC.ctrl1 = 0x18;
|
||||||
|
VIC.bordercolor = 4;
|
||||||
|
DLIST_RESTART(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
byte i;
|
||||||
|
|
||||||
|
clrscr();
|
||||||
|
|
||||||
|
sprite_clear();
|
||||||
|
sprite_shape((void*)0x400, 32/2, spriteshape);
|
||||||
|
|
||||||
|
// set colors
|
||||||
|
sprshad.spr_exp_x = 0xff;
|
||||||
|
for (i=0; i<8; i++) {
|
||||||
|
sprshad.spr_color[i] = i+3;
|
||||||
|
sprite_draw(i, i*38+24, 248, 32);
|
||||||
|
}
|
||||||
|
// TODO: can't do in IRQ
|
||||||
|
|
||||||
|
DLIST_SETUP(dlist_example);
|
||||||
|
while (1) {
|
||||||
|
sprshad.spr_pos[0].y += 1;
|
||||||
|
sprite_update(DEFAULT_SCREEN);
|
||||||
|
printf("Hello World! ");
|
||||||
|
}
|
||||||
|
}
|
|
@ -129,9 +129,9 @@ export function assembleCA65(step: BuildStep): BuildStepResult {
|
||||||
}
|
}
|
||||||
execMain(step, CA65, args);
|
execMain(step, CA65, args);
|
||||||
if (errors.length) {
|
if (errors.length) {
|
||||||
// TODO?
|
|
||||||
let listings : CodeListingMap = {};
|
let listings : CodeListingMap = {};
|
||||||
listings[step.path] = { lines:[], text:getWorkFileAsString(step.path) };
|
// TODO? change extension to .lst
|
||||||
|
//listings[step.path] = { lines:[], text:getWorkFileAsString(step.path) };
|
||||||
return { errors, listings };
|
return { errors, listings };
|
||||||
}
|
}
|
||||||
objout = FS.readFile(objpath, { encoding: 'binary' });
|
objout = FS.readFile(objpath, { encoding: 'binary' });
|
||||||
|
|
Loading…
Reference in New Issue
Block a user