mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-05-28 08:41:30 +00:00
c64: added sid music/sfx, updated memmap, examples
This commit is contained in:
parent
3beef5626c
commit
b0d4f8f1f5
BIN
presets/c64/badspacerobots-c64.multi.bin
Normal file
BIN
presets/c64/badspacerobots-c64.multi.bin
Normal file
Binary file not shown.
47
presets/c64/c64-sid.cfg
Normal file
47
presets/c64/c64-sid.cfg
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
FEATURES {
|
||||||
|
STARTADDRESS: default = $0801;
|
||||||
|
}
|
||||||
|
SYMBOLS {
|
||||||
|
__LOADADDR__: type = import;
|
||||||
|
__EXEHDR__: type = import;
|
||||||
|
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
||||||
|
__HIMEM__: type = weak, value = $D000;
|
||||||
|
}
|
||||||
|
MEMORY {
|
||||||
|
ZP: file = "", define = yes, start = $0002, size = $001A;
|
||||||
|
LOADADDR: file = %O, start = %S - 2, size = $0002;
|
||||||
|
HEADER: file = %O, define = yes, start = %S, size = $000D;
|
||||||
|
LOWMAIN: file = %O, define = yes, start = __HEADER_LAST__, size = $1000 - __HEADER_LAST__, fill = yes;
|
||||||
|
SIDFILE: file = %O, define = yes, start = $1000, size = $1000, fill = yes;
|
||||||
|
MAIN: file = %O, define = yes, start = $2000, size = __HIMEM__ - $2000;
|
||||||
|
BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__;
|
||||||
|
}
|
||||||
|
SEGMENTS {
|
||||||
|
ZEROPAGE: load = ZP, type = zp;
|
||||||
|
LOADADDR: load = LOADADDR, type = ro;
|
||||||
|
EXEHDR: load = HEADER, type = ro;
|
||||||
|
STARTUP: load = LOWMAIN, type = ro;
|
||||||
|
LOWCODE: load = LOWMAIN, type = ro, optional = yes;
|
||||||
|
SIDFILE: load = SIDFILE, type = ro, optional = yes;
|
||||||
|
CODE: load = MAIN, type = ro;
|
||||||
|
RODATA: load = MAIN, type = ro;
|
||||||
|
DATA: load = MAIN, type = rw;
|
||||||
|
INIT: load = MAIN, type = rw;
|
||||||
|
ONCE: load = MAIN, type = ro, define = yes;
|
||||||
|
BSS: load = BSS, type = bss, define = yes;
|
||||||
|
}
|
||||||
|
FEATURES {
|
||||||
|
CONDES: type = constructor,
|
||||||
|
label = __CONSTRUCTOR_TABLE__,
|
||||||
|
count = __CONSTRUCTOR_COUNT__,
|
||||||
|
segment = ONCE;
|
||||||
|
CONDES: type = destructor,
|
||||||
|
label = __DESTRUCTOR_TABLE__,
|
||||||
|
count = __DESTRUCTOR_COUNT__,
|
||||||
|
segment = RODATA;
|
||||||
|
CONDES: type = interruptor,
|
||||||
|
label = __INTERRUPTOR_TABLE__,
|
||||||
|
count = __INTERRUPTOR_COUNT__,
|
||||||
|
segment = RODATA,
|
||||||
|
import = __CALLIRQ__;
|
||||||
|
}
|
|
@ -17,8 +17,18 @@
|
||||||
#include "sprites.h"
|
#include "sprites.h"
|
||||||
//#link "sprites.c"
|
//#link "sprites.c"
|
||||||
|
|
||||||
// indices of sound effects (0..3)
|
//#resource "c64-sid.cfg"
|
||||||
typedef enum { SND_START, SND_HIT, SND_COIN, SND_JUMP } SFXIndex;
|
#define CFGFILE c64-sid.cfg
|
||||||
|
|
||||||
|
//#resource "sidmusic1.bin"
|
||||||
|
//#link "sidplaysfx.ca65"
|
||||||
|
#include "sidplaysfx.h"
|
||||||
|
|
||||||
|
// indices of sound effects
|
||||||
|
#define SND_JUMP 0
|
||||||
|
#define SND_HIT 2
|
||||||
|
#define SND_COIN 1
|
||||||
|
#define SND_FALL 3
|
||||||
|
|
||||||
///// DEFINES
|
///// DEFINES
|
||||||
|
|
||||||
|
@ -469,7 +479,7 @@ void draw_actor(byte i) {
|
||||||
void refresh_actors() {
|
void refresh_actors() {
|
||||||
byte i;
|
byte i;
|
||||||
yscroll = BOTTOM_Y + scroll_fine_y + (START_ORIGIN_Y - origin_y)*8;
|
yscroll = BOTTOM_Y + scroll_fine_y + (START_ORIGIN_Y - origin_y)*8;
|
||||||
sprite_clear();
|
sprshad.spr_ena = 0; // make all sprites invisible
|
||||||
for (i=0; i<MAX_ACTORS; i++)
|
for (i=0; i<MAX_ACTORS; i++)
|
||||||
draw_actor(i);
|
draw_actor(i);
|
||||||
animate_explosion();
|
animate_explosion();
|
||||||
|
@ -541,6 +551,7 @@ void move_actor(struct Actor* actor, byte joystick, bool scroll) {
|
||||||
actor->yvel = 15;
|
actor->yvel = 15;
|
||||||
if (joystick & JOY_LEFT_MASK) actor->xvel = -1;
|
if (joystick & JOY_LEFT_MASK) actor->xvel = -1;
|
||||||
if (joystick & JOY_RIGHT_MASK) actor->xvel = 1;
|
if (joystick & JOY_RIGHT_MASK) actor->xvel = 1;
|
||||||
|
if (scroll) sid_sfx(SND_JUMP);
|
||||||
} else if (joystick & JOY_LEFT_MASK) {
|
} else if (joystick & JOY_LEFT_MASK) {
|
||||||
actor->x--;
|
actor->x--;
|
||||||
actor->dir = 1;
|
actor->dir = 1;
|
||||||
|
@ -605,6 +616,7 @@ void move_actor(struct Actor* actor, byte joystick, bool scroll) {
|
||||||
if (actor->state == WALKING &&
|
if (actor->state == WALKING &&
|
||||||
is_in_gap(actor->x, floors[actor->level].gap)) {
|
is_in_gap(actor->x, floors[actor->level].gap)) {
|
||||||
fall_down(actor);
|
fall_down(actor);
|
||||||
|
if (scroll) sid_sfx(SND_FALL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -626,11 +638,11 @@ void pickup_object(Actor* actor) {
|
||||||
if (objtype == ITEM_MINE) {
|
if (objtype == ITEM_MINE) {
|
||||||
// we hit a mine, fall down
|
// we hit a mine, fall down
|
||||||
fall_down(actor);
|
fall_down(actor);
|
||||||
//sfx_play(SND_HIT,0);
|
sid_sfx(SND_HIT);
|
||||||
} else {
|
} else {
|
||||||
// we picked up an object, add to score
|
// we picked up an object, add to score
|
||||||
//score = bcd_add(score, 1);
|
//score = bcd_add(score, 1);
|
||||||
//sfx_play(SND_COIN,0);
|
sid_sfx(SND_COIN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -717,6 +729,9 @@ void play_scene() {
|
||||||
create_actors_on_floor(2);
|
create_actors_on_floor(2);
|
||||||
refresh_screen();
|
refresh_screen();
|
||||||
|
|
||||||
|
sid_init(1);
|
||||||
|
sid_start();
|
||||||
|
|
||||||
while (actors[0].level != MAX_FLOORS-1) {
|
while (actors[0].level != MAX_FLOORS-1) {
|
||||||
refresh_actors();
|
refresh_actors();
|
||||||
move_player();
|
move_player();
|
||||||
|
@ -728,6 +743,7 @@ void play_scene() {
|
||||||
if (VIC.spr_coll & 0x01) {
|
if (VIC.spr_coll & 0x01) {
|
||||||
if (actors[0].level > 0 && check_collision(&actors[0])) {
|
if (actors[0].level > 0 && check_collision(&actors[0])) {
|
||||||
fall_down(&actors[0]);
|
fall_down(&actors[0]);
|
||||||
|
sid_sfx(SND_HIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (swap_needed) sprite_update(hidbuf);
|
if (swap_needed) sprite_update(hidbuf);
|
||||||
|
|
|
@ -73,13 +73,16 @@ void main(void) {
|
||||||
|
|
||||||
// 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);
|
||||||
// animate sprite in shadow sprite ram
|
// animate sprite in shadow sprite ram
|
||||||
sprite_draw(0, n++, 70, 32);
|
sprite_draw(0, n++, 70, 32);
|
||||||
// wait for vblank
|
// wait for vblank
|
||||||
|
|
32
presets/c64/siddemo.c
Normal file
32
presets/c64/siddemo.c
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <c64.h>
|
||||||
|
#include <cbm_petscii_charmap.h>
|
||||||
|
#include <joystick.h>
|
||||||
|
|
||||||
|
//#resource "c64-sid.cfg"
|
||||||
|
#define CFGFILE c64-sid.cfg
|
||||||
|
|
||||||
|
//#resource "sidmusic1.bin"
|
||||||
|
//#link "sidplaysfx.ca65"
|
||||||
|
#include "sidplaysfx.h"
|
||||||
|
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
clrscr();
|
||||||
|
cursor(0);
|
||||||
|
joy_install(joy_static_stddrv);
|
||||||
|
sid_init(0);
|
||||||
|
sid_start();
|
||||||
|
printf("\r\nSID file loaded at $1000\r\n");
|
||||||
|
printf("\r\nMove joystick for SFX\r\n");
|
||||||
|
while (1) {
|
||||||
|
char joy = joy_read(0);
|
||||||
|
if (joy) {
|
||||||
|
sid_sfx(joy & 3);
|
||||||
|
}
|
||||||
|
waitvsync();
|
||||||
|
//sid_update();
|
||||||
|
}
|
||||||
|
}
|
BIN
presets/c64/sidmusic1.bin
Normal file
BIN
presets/c64/sidmusic1.bin
Normal file
Binary file not shown.
85
presets/c64/sidplaysfx.ca65
Normal file
85
presets/c64/sidplaysfx.ca65
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
|
||||||
|
; music and SFX from GoatTracker 2 sample files
|
||||||
|
; http://sourceforge.net/projects/goattracker2
|
||||||
|
|
||||||
|
.segment "SIDFILE"
|
||||||
|
|
||||||
|
.incbin "sidmusic1.bin"
|
||||||
|
|
||||||
|
.segment "LOWCODE"
|
||||||
|
|
||||||
|
.global _sid_init, _sid_update, _sid_sfx
|
||||||
|
.global _sid_start
|
||||||
|
|
||||||
|
_sid_init:
|
||||||
|
jmp $1000
|
||||||
|
|
||||||
|
_sid_update:
|
||||||
|
jmp $1003
|
||||||
|
|
||||||
|
_sid_sfx:
|
||||||
|
tax
|
||||||
|
lda sfxtbllo,x ;Address in A,Y
|
||||||
|
ldy sfxtblhi,x
|
||||||
|
ldx #$0e ;Channel index in X
|
||||||
|
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:
|
||||||
|
SEI ; set interrupt bit, make the CPU ignore interrupt requests
|
||||||
|
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 #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
|
||||||
|
.byte <arpeggio1
|
||||||
|
.byte <gunshot
|
||||||
|
.byte <explosion
|
||||||
|
|
||||||
|
sfxtblhi: .byte >arpeggio2
|
||||||
|
.byte >arpeggio1
|
||||||
|
.byte >gunshot
|
||||||
|
.byte >explosion
|
||||||
|
|
||||||
|
arpeggio2:
|
||||||
|
.byte $00,$89,$04,$A2,$41,$A2,$A2,$A6,$A6,$A6,$40,$A9,$A9,$A9,$A2,$A2
|
||||||
|
.byte $A2,$A6,$A6,$A6,$A9,$A9,$A9,$A2,$A2,$A2,$A6,$A6,$A6,$A9,$A9,$A9
|
||||||
|
.byte $A2,$A2,$A2,$A6,$A6,$A6,$A9,$A9,$A9,$00
|
||||||
|
|
||||||
|
arpeggio1:
|
||||||
|
.byte $0A,$00,$02,$A0,$41,$A0,$A0,$A4,$A4,$A4,$A7,$A7,$A7,$A0,$A0,$A0
|
||||||
|
.byte $A4,$A4,$A4,$A7,$A7,$A7,$A0,$A0,$A0,$A4,$A4,$A4,$A7,$A7,$A7,$A0
|
||||||
|
.byte $A0,$A0,$A4,$A4,$A4,$A7,$A7,$A7,$00
|
||||||
|
|
||||||
|
gunshot:
|
||||||
|
.byte $00,$F9,$08,$C4,$81,$A8,$41,$C0,$81,$BE,$BC,$80,$BA,$B8,$B6,$B4
|
||||||
|
.byte $B2,$B0,$AE,$AC,$AA,$A8,$A6,$A4,$A2,$A0,$9E,$9C,$9A,$98,$96,$94
|
||||||
|
.byte $92,$90,$00
|
||||||
|
|
||||||
|
explosion:
|
||||||
|
.byte $00,$FA,$08,$B8,$81,$A4,$41,$A0,$B4,$81,$98,$92,$9C,$90,$95,$9E
|
||||||
|
.byte $92,$80,$94,$8F,$8E,$8D,$8C,$8B,$8A,$89,$88,$87,$86,$84,$00
|
7
presets/c64/sidplaysfx.h
Normal file
7
presets/c64/sidplaysfx.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
extern void sid_init(char musicindex);
|
||||||
|
extern void sid_update(void);
|
||||||
|
extern void sid_sfx(char sfxindex);
|
||||||
|
|
||||||
|
extern void sid_start(void);
|
||||||
|
extern void sid_stop(void);
|
152
presets/c64/sprite_collision.c
Normal file
152
presets/c64/sprite_collision.c
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <c64.h>
|
||||||
|
#include <cbm_petscii_charmap.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
//#link "common.c"
|
||||||
|
|
||||||
|
#include "sprites.h"
|
||||||
|
//#link "sprites.c"
|
||||||
|
|
||||||
|
/*{w:12,h:21,bpp:2,brev:1}*/
|
||||||
|
const char SPRITEMC[3*21] = {
|
||||||
|
0x00,0xAA,0x80,0x02,0xAA,0xA0,0x0A,0xAA,0xA8,
|
||||||
|
0x0A,0xAE,0xA8,0x0A,0xBB,0xA8,0x0A,0xBA,0xA8,
|
||||||
|
0x0A,0xBB,0xA8,0x0A,0xAE,0xA8,0x0A,0xAA,0xA8,
|
||||||
|
0x09,0xAA,0x98,0x08,0x6A,0x48,0x08,0x1D,0x08,
|
||||||
|
0x02,0x0C,0x20,0x02,0x0C,0x20,0x02,0x0C,0x20,
|
||||||
|
0x00,0x8C,0x80,0x00,0x8C,0x80,0x00,0x55,0x40,
|
||||||
|
0x00,0x77,0x40,0x00,0x5D,0x40,0x00,0x15,0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
int xpos[8];
|
||||||
|
int ypos[8];
|
||||||
|
int xvel[8];
|
||||||
|
int yvel[8];
|
||||||
|
|
||||||
|
void init_sprites(void) {
|
||||||
|
byte i;
|
||||||
|
// setup sprite positions
|
||||||
|
for (i=0; i<8; i++) {
|
||||||
|
xpos[i] = ((i & 3) * 0x2000) - 0x1000;
|
||||||
|
ypos[i] = (i * 0x1000) - 0x3000;
|
||||||
|
sprshad.spr_color[i] = i | 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void move_sprites(void) {
|
||||||
|
byte i;
|
||||||
|
for (i=0; i<8; i++) {
|
||||||
|
//VIC.bordercolor = i;
|
||||||
|
sprite_draw(i, (xpos[i]>>7)+0x80, (ypos[i]>>8)+0x80, 32);
|
||||||
|
// update position
|
||||||
|
xpos[i] += xvel[i];
|
||||||
|
ypos[i] += yvel[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_sprites(void) {
|
||||||
|
byte i;
|
||||||
|
for (i=0; i<8; i++) {
|
||||||
|
// update velocity
|
||||||
|
xvel[i] -= xpos[i] >> 12;
|
||||||
|
yvel[i] -= ypos[i] >> 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void collide_sprites(byte spr_coll) {
|
||||||
|
byte i;
|
||||||
|
byte mask = 1;
|
||||||
|
// exit if no collisions
|
||||||
|
if (!spr_coll) return;
|
||||||
|
// iterate all sprites that have their flag set
|
||||||
|
for (i=0; i<8; i++, mask<<=1) {
|
||||||
|
//VIC.bordercolor = i;
|
||||||
|
if (spr_coll & mask) {
|
||||||
|
// find the first sprite that intersects
|
||||||
|
byte j = sprite_get_closest_collision(i, spr_coll);
|
||||||
|
// returns 0..7 if a sprite was found
|
||||||
|
if (j < 8) {
|
||||||
|
xvel[i] = (xpos[i] - xpos[j]) >> 4;
|
||||||
|
yvel[i] = (ypos[i] - ypos[j]) >> 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void iterategame1(void) {
|
||||||
|
byte spr_coll;
|
||||||
|
|
||||||
|
// wait for vblank
|
||||||
|
wait_vblank();
|
||||||
|
// grab and reset sprite-sprite collision flags
|
||||||
|
spr_coll = VIC.spr_coll;
|
||||||
|
// then update sprite registers from shadow RAM
|
||||||
|
sprite_update(DEFAULT_SCREEN);
|
||||||
|
// draw sprites into shadow ram
|
||||||
|
move_sprites();
|
||||||
|
// and update velocity and position
|
||||||
|
update_sprites();
|
||||||
|
// if any flags are set in the collision register,
|
||||||
|
// process sprite collisions
|
||||||
|
collide_sprites(spr_coll);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iterategame2(void) {
|
||||||
|
byte spr_coll;
|
||||||
|
|
||||||
|
// FIRST FRAME: move and update velocity
|
||||||
|
wait_vblank();
|
||||||
|
// grab and reset sprite-sprite collision flags
|
||||||
|
spr_coll = VIC.spr_coll;
|
||||||
|
// then update sprite registers from shadow RAM
|
||||||
|
sprite_update(DEFAULT_SCREEN);
|
||||||
|
// draw sprites into shadow ram
|
||||||
|
// and update posiitons
|
||||||
|
move_sprites();
|
||||||
|
// and update velocities
|
||||||
|
update_sprites();
|
||||||
|
|
||||||
|
// SECOND FRAME: move and process collisions
|
||||||
|
wait_vblank();
|
||||||
|
// grab and reset sprite-sprite collision flags
|
||||||
|
// combine with previous frame flags
|
||||||
|
spr_coll |= VIC.spr_coll;
|
||||||
|
// then update sprite registers from shadow RAM
|
||||||
|
sprite_update(DEFAULT_SCREEN);
|
||||||
|
// draw sprites into shadow ram
|
||||||
|
// and update posiitons
|
||||||
|
move_sprites();
|
||||||
|
// if any flags are set in the collision register,
|
||||||
|
// process sprite collisions
|
||||||
|
collide_sprites(spr_coll);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
|
||||||
|
clrscr();
|
||||||
|
VIC.bordercolor = 0;
|
||||||
|
|
||||||
|
// setup sprite library and copy sprite to VIC bank
|
||||||
|
sprite_clear();
|
||||||
|
sprite_shape((void*)0x400, 32/2, SPRITEMC);
|
||||||
|
|
||||||
|
// set colors
|
||||||
|
sprshad.spr_mcolor = 0xff;
|
||||||
|
sprshad.spr_mcolor0 = 4;
|
||||||
|
sprshad.spr_mcolor1 = 7;
|
||||||
|
|
||||||
|
// set sprite initial positions
|
||||||
|
init_sprites();
|
||||||
|
|
||||||
|
// game loop
|
||||||
|
while (1) {
|
||||||
|
iterategame2();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
|
|
||||||
SpriteShadow sprshad;
|
SpriteShadow sprshad;
|
||||||
|
|
||||||
|
void sprite_clear(void) {
|
||||||
|
memset(&sprshad, 0, sizeof(sprshad));
|
||||||
|
}
|
||||||
|
|
||||||
void sprite_update(char* vicbank) {
|
void sprite_update(char* vicbank) {
|
||||||
memcpy(vicbank + 0x3f8, sprshad.spr_shapes, 8);
|
memcpy(vicbank + 0x3f8, sprshad.spr_shapes, 8);
|
||||||
VIC.spr_ena = sprshad.spr_ena;
|
VIC.spr_ena = sprshad.spr_ena;
|
||||||
|
@ -38,7 +42,25 @@ void sprite_draw(byte i, word x, byte y, byte shape) {
|
||||||
sprshad.spr_shapes[i] = shape;
|
sprshad.spr_shapes[i] = shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprite_clear(void) {
|
byte sprite_get_closest_collision(byte i, byte spr_coll) {
|
||||||
sprshad.spr_ena = 0;
|
byte j;
|
||||||
|
byte jmask = 1;
|
||||||
|
byte dx,dy;
|
||||||
|
if (spr_coll & BITS[i]) {
|
||||||
|
spr_coll ^= BITS[i];
|
||||||
|
for (j=0; j<8; j++, jmask<<=1) {
|
||||||
|
if (spr_coll & jmask) {
|
||||||
|
// TODO?
|
||||||
|
dx = sprshad.spr_pos[i].x - sprshad.spr_pos[j].x + 24;
|
||||||
|
if (dx < 48) {
|
||||||
|
dy = sprshad.spr_pos[i].y - sprshad.spr_pos[j].y + 21;
|
||||||
|
if (dy < 42) {
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#define DEFAULT_SCREEN ((void*)0x400)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
byte spr_ena; /* Enable sprites */
|
byte spr_ena; /* Enable sprites */
|
||||||
byte spr_hi_x; /* High bits of X coordinate */
|
byte spr_hi_x; /* High bits of X coordinate */
|
||||||
|
@ -22,9 +24,10 @@ typedef struct {
|
||||||
|
|
||||||
extern SpriteShadow sprshad;
|
extern SpriteShadow sprshad;
|
||||||
|
|
||||||
|
void sprite_clear(void);
|
||||||
void sprite_update(char* screenram);
|
void sprite_update(char* screenram);
|
||||||
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);
|
||||||
void sprite_clear(void);
|
byte sprite_get_closest_collision(byte i, byte spr_coll);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
72
presets/c64/viewer-badspacerobots-c64.multi.asm
Normal file
72
presets/c64/viewer-badspacerobots-c64.multi.asm
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
|
||||||
|
processor 6502
|
||||||
|
include "basicheader.dasm"
|
||||||
|
|
||||||
|
Src equ $02
|
||||||
|
Dest equ $04
|
||||||
|
|
||||||
|
Start:
|
||||||
|
lda #$38 ; 25 rows, on, bitmap
|
||||||
|
sta $d011 ; VIC control #1
|
||||||
|
lda #$18 ; 40 column, multicolor
|
||||||
|
sta $d016 ; VIC control #2
|
||||||
|
lda #$02
|
||||||
|
sta $dd00 ; set VIC bank ($4000-$7FFF)
|
||||||
|
lda #$80
|
||||||
|
sta $d018 ; set VIC screen to $6000
|
||||||
|
lda XtraData+0
|
||||||
|
sta $d020 ; border
|
||||||
|
sta $d021 ; background
|
||||||
|
lda #0
|
||||||
|
sta Dest
|
||||||
|
; copy char memory
|
||||||
|
lda #<CharData
|
||||||
|
sta Src
|
||||||
|
lda #>CharData
|
||||||
|
sta Src+1
|
||||||
|
lda #$40
|
||||||
|
sta Dest+1
|
||||||
|
ldx #$20
|
||||||
|
jsr CopyMem
|
||||||
|
; copy screen memory
|
||||||
|
lda #<ScreenData
|
||||||
|
sta Src
|
||||||
|
lda #>ScreenData
|
||||||
|
sta Src+1
|
||||||
|
lda #$60
|
||||||
|
sta Dest+1
|
||||||
|
ldx #$04
|
||||||
|
jsr CopyMem
|
||||||
|
; copy color RAM
|
||||||
|
lda #<ColorData
|
||||||
|
sta Src
|
||||||
|
lda #>ColorData
|
||||||
|
sta Src+1
|
||||||
|
lda #$d8
|
||||||
|
sta Dest+1
|
||||||
|
ldx #4
|
||||||
|
jsr CopyMem
|
||||||
|
; infinite loop
|
||||||
|
jmp .
|
||||||
|
|
||||||
|
; copy data from Src to Dest
|
||||||
|
; X = number of bytes * 256
|
||||||
|
CopyMem
|
||||||
|
ldy #0
|
||||||
|
.Loop
|
||||||
|
lda (Src),y
|
||||||
|
sta (Dest),y
|
||||||
|
iny
|
||||||
|
bne .Loop
|
||||||
|
inc Src+1
|
||||||
|
inc Dest+1
|
||||||
|
dex
|
||||||
|
bne .Loop
|
||||||
|
rts
|
||||||
|
|
||||||
|
; bitmap data
|
||||||
|
CharData equ .
|
||||||
|
ScreenData equ CharData+8000
|
||||||
|
ColorData equ ScreenData+1000
|
||||||
|
XtraData equ ColorData+1000
|
||||||
|
incbin "badspacerobots-c64.multi.bin"
|
|
@ -122,7 +122,7 @@ export class C64_WASMMachine extends BaseWASMMachine implements Machine, Probeab
|
||||||
this.exports.machine_load_state(this.sys, this.stateptr);
|
this.exports.machine_load_state(this.sys, this.stateptr);
|
||||||
}
|
}
|
||||||
getVideoParams() {
|
getVideoParams() {
|
||||||
return {width:392, height:272, overscan:true, videoFrequency:50};
|
return {width:392, height:272, overscan:true, videoFrequency:50, aspect:392/272*0.9365};
|
||||||
}
|
}
|
||||||
setKeyInput(key: number, code: number, flags: number): void {
|
setKeyInput(key: number, code: number, flags: number): void {
|
||||||
// TODO: handle shifted keys
|
// TODO: handle shifted keys
|
||||||
|
|
|
@ -16,18 +16,23 @@ const C64_PRESETS = [
|
||||||
{id:'scroll3.c', name:'Scrolling 3 (C)'},
|
{id:'scroll3.c', name:'Scrolling 3 (C)'},
|
||||||
{id:'scroll4.c', name:'Scrolling 4 (C)'},
|
{id:'scroll4.c', name:'Scrolling 4 (C)'},
|
||||||
{id:'scroll5.c', name:'Scrolling 5 (C)'},
|
{id:'scroll5.c', name:'Scrolling 5 (C)'},
|
||||||
{id:'climber.c', name:'Climber Game (C)'},
|
{id:'sprite_collision.c', name:'Sprite Collision (C)'},
|
||||||
{id:'multilines.c', name:'Multicolor Lines+Flood Fill (C)'},
|
{id:'multilines.c', name:'Multicolor Lines+Flood Fill (C)'},
|
||||||
{id:'sidtune.dasm', name:'SID Tune (ASM)'},
|
|
||||||
{id:'musicplayer.c', name:'Music Player (C)'},
|
{id:'musicplayer.c', name:'Music Player (C)'},
|
||||||
|
{id:'sidtune.dasm', name:'Tiny SID Tune (ASM)'},
|
||||||
|
{id:'siddemo.c', name:'SID Demo (C)'},
|
||||||
|
{id:'climber.c', name:'Climber Game (C)'},
|
||||||
];
|
];
|
||||||
|
|
||||||
const C64_MEMORY_MAP = { main:[
|
const C64_MEMORY_MAP = { main:[
|
||||||
{name:'6510 Registers',start:0x0, size:0x2,type:'io'},
|
{name:'6510 Registers',start:0x0, size:0x2,type:'io'},
|
||||||
|
{name:'BIOS Reserved', start:0x200, size:0xa7},
|
||||||
|
{name:'Default Screen RAM', start:0x400, size:1024,type:'ram'},
|
||||||
//{name:'RAM', start:0x2, size:0x7ffe,type:'ram'},
|
//{name:'RAM', start:0x2, size:0x7ffe,type:'ram'},
|
||||||
{name:'Cartridge ROM',start:0x8000,size:0x2000,type:'rom'},
|
{name:'Cartridge ROM',start:0x8000,size:0x2000,type:'rom'},
|
||||||
{name:'BASIC ROM', start:0xa000,size:0x2000,type:'rom'},
|
{name:'BASIC ROM', start:0xa000,size:0x2000,type:'rom'},
|
||||||
{name:'RAM', start:0xc000,size:0x1000,type:'ram'},
|
{name:'Upper RAM', start:0xc000,size:0x1000,type:'ram'},
|
||||||
|
{name:'Character ROM',start:0xd000,size:0x1000,type:'rom'},
|
||||||
{name:'VIC-II I/O', start:0xd000,size:0x0400,type:'io'},
|
{name:'VIC-II I/O', start:0xd000,size:0x0400,type:'io'},
|
||||||
{name:'SID', start:0xd400,size:0x0400,type:'io'},
|
{name:'SID', start:0xd400,size:0x0400,type:'io'},
|
||||||
{name:'Color RAM', start:0xd800,size:0x0400,type:'io'},
|
{name:'Color RAM', start:0xd800,size:0x0400,type:'io'},
|
||||||
|
|
Loading…
Reference in New Issue
Block a user