mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-26 10:49:17 +00:00
nes: fixed presets, added to platforms menu
This commit is contained in:
parent
733846af16
commit
f17a3488ed
@ -96,6 +96,7 @@ TODO:
|
|||||||
- open ROM from URL?
|
- open ROM from URL?
|
||||||
- NES: disassembly not aligned on PC
|
- NES: disassembly not aligned on PC
|
||||||
- NES: vrambuf.c for Solarian
|
- NES: vrambuf.c for Solarian
|
||||||
|
- game starts even if switched away before first load
|
||||||
|
|
||||||
|
|
||||||
WEB WORKER FORMAT
|
WEB WORKER FORMAT
|
||||||
|
@ -109,6 +109,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a class="dropdown-item" href="?platform=vcs" id="item_platform_vcs">Atari 2600/VCS</a></li>
|
<li><a class="dropdown-item" href="?platform=vcs" id="item_platform_vcs">Atari 2600/VCS</a></li>
|
||||||
<li><a class="dropdown-item" href="?platform=vcs.mame" id="item_platform_vcs">Atari 2600/VCS (MAME)</a></li>
|
<li><a class="dropdown-item" href="?platform=vcs.mame" id="item_platform_vcs">Atari 2600/VCS (MAME)</a></li>
|
||||||
|
<li><a class="dropdown-item" href="?platform=nes" id="item_platform_nes">NES</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown dropdown-submenu">
|
<li class="dropdown dropdown-submenu">
|
||||||
|
@ -78,10 +78,6 @@ byte rndint(byte a, byte b) {
|
|||||||
return (rand() % (b-a)) + a;
|
return (rand() % (b-a)) + a;
|
||||||
}
|
}
|
||||||
|
|
||||||
///// OAM buffer (for sprites)
|
|
||||||
|
|
||||||
#define OAMBUF ((unsigned char*) 0x200)
|
|
||||||
|
|
||||||
// return nametable address for tile (x,y)
|
// return nametable address for tile (x,y)
|
||||||
// assuming vertical scrolling (horiz. mirroring)
|
// assuming vertical scrolling (horiz. mirroring)
|
||||||
word getntaddr(byte x, byte y) {
|
word getntaddr(byte x, byte y) {
|
||||||
@ -397,6 +393,7 @@ void create_actors_on_floor(byte floor_index) {
|
|||||||
if (floor_index == MAX_FLOORS-1) {
|
if (floor_index == MAX_FLOORS-1) {
|
||||||
a->name = ACTOR_RESCUE;
|
a->name = ACTOR_RESCUE;
|
||||||
a->state = PACING;
|
a->state = PACING;
|
||||||
|
a->x = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -439,14 +436,15 @@ byte draw_actor(byte oam_id, byte i) {
|
|||||||
x = a->x;
|
x = a->x;
|
||||||
y = screen_y;
|
y = screen_y;
|
||||||
oam_id = oam_meta_spr(x, y, oam_id, meta);
|
oam_id = oam_meta_spr(x, y, oam_id, meta);
|
||||||
// actor 0 is player sprite
|
// is this actor 0? (player sprite)
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
player_screen_y = y; // last screen Y position
|
player_screen_y = y; // last screen Y position
|
||||||
// set special palette for player sprites
|
// set special palette for the player's sprites
|
||||||
OAMBUF[0+2] |= 3;
|
// directly in OAM buffer
|
||||||
OAMBUF[4+2] |= 3;
|
OAMBUF[0].attr |= 3;
|
||||||
OAMBUF[8+2] |= 3;
|
OAMBUF[1].attr |= 3;
|
||||||
OAMBUF[12+2] |= 3;
|
OAMBUF[2].attr |= 3;
|
||||||
|
OAMBUF[3].attr |= 3;
|
||||||
}
|
}
|
||||||
a->onscreen = 1;
|
a->onscreen = 1;
|
||||||
return oam_id;
|
return oam_id;
|
||||||
|
@ -58,6 +58,7 @@ HelloMsg:
|
|||||||
SetPalette: subroutine
|
SetPalette: subroutine
|
||||||
; set PPU address to palette start
|
; set PPU address to palette start
|
||||||
PPU_SETADDR $3f00
|
PPU_SETADDR $3f00
|
||||||
|
ldy #0
|
||||||
.loop:
|
.loop:
|
||||||
lda Palette,y ; lookup byte in ROM
|
lda Palette,y ; lookup byte in ROM
|
||||||
sta PPU_DATA ; store byte to PPU data
|
sta PPU_DATA ; store byte to PPU data
|
||||||
|
@ -10,7 +10,7 @@ ScrollPos word ; used during NMI
|
|||||||
|
|
||||||
;;;;; NES CARTRIDGE HEADER
|
;;;;; NES CARTRIDGE HEADER
|
||||||
|
|
||||||
NES_HEADER 0,2,1,1 ; mapper 0, 2 PRGs, 1 CHR, horiz. mirror
|
NES_HEADER 0,2,1,1 ; mapper 0, 2 PRGs, 1 CHR, vert. mirror
|
||||||
|
|
||||||
;;;;; START OF CODE
|
;;;;; START OF CODE
|
||||||
|
|
||||||
@ -54,6 +54,7 @@ FillVRAM: subroutine
|
|||||||
; set palette colors
|
; set palette colors
|
||||||
SetPalette: subroutine
|
SetPalette: subroutine
|
||||||
PPU_SETADDR $3f00
|
PPU_SETADDR $3f00
|
||||||
|
ldy #0
|
||||||
.loop:
|
.loop:
|
||||||
lda Palette,y ; lookup byte in ROM
|
lda Palette,y ; lookup byte in ROM
|
||||||
sta PPU_DATA ; store byte to PPU data
|
sta PPU_DATA ; store byte to PPU data
|
||||||
|
@ -45,6 +45,7 @@ Start:
|
|||||||
FillVRAM: subroutine
|
FillVRAM: subroutine
|
||||||
PPU_SETADDR $2000
|
PPU_SETADDR $2000
|
||||||
ldy #$10
|
ldy #$10
|
||||||
|
ldx #0
|
||||||
.loop:
|
.loop:
|
||||||
stx PPU_DATA ; X -> PPU data port
|
stx PPU_DATA ; X -> PPU data port
|
||||||
inx ; X = X + 1
|
inx ; X = X + 1
|
||||||
@ -83,6 +84,7 @@ MoveSprites: subroutine
|
|||||||
; set palette colors
|
; set palette colors
|
||||||
SetPalette: subroutine
|
SetPalette: subroutine
|
||||||
PPU_SETADDR $3f00
|
PPU_SETADDR $3f00
|
||||||
|
ldy #0
|
||||||
.loop:
|
.loop:
|
||||||
lda Palette,y ; lookup byte in ROM
|
lda Palette,y ; lookup byte in ROM
|
||||||
sta PPU_DATA ; store byte to PPU data
|
sta PPU_DATA ; store byte to PPU data
|
||||||
|
@ -40,6 +40,7 @@ Start:
|
|||||||
FillVRAM: subroutine
|
FillVRAM: subroutine
|
||||||
PPU_SETADDR $2000
|
PPU_SETADDR $2000
|
||||||
ldy #$10
|
ldy #$10
|
||||||
|
ldx #0
|
||||||
.loop:
|
.loop:
|
||||||
stx PPU_DATA
|
stx PPU_DATA
|
||||||
inx
|
inx
|
||||||
@ -49,17 +50,16 @@ FillVRAM: subroutine
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
; set palette colors
|
; set palette colors
|
||||||
|
|
||||||
SetPalette: subroutine
|
SetPalette: subroutine
|
||||||
PPU_SETADDR $3f00
|
PPU_SETADDR $3f00
|
||||||
ldx #32
|
ldy #0
|
||||||
.loop:
|
.loop:
|
||||||
lda Palette,y
|
lda Palette,y ; lookup byte in ROM
|
||||||
sta PPU_DATA
|
sta PPU_DATA ; store byte to PPU data
|
||||||
iny
|
iny ; Y = Y + 1
|
||||||
dex
|
cpy #32 ; is Y equal to 32?
|
||||||
bne .loop
|
bne .loop ; not yet, loop
|
||||||
rts
|
rts ; return to caller
|
||||||
|
|
||||||
|
|
||||||
;;;;; COMMON SUBROUTINES
|
;;;;; COMMON SUBROUTINES
|
||||||
|
@ -92,9 +92,6 @@ char actor_y[NUM_ACTORS];
|
|||||||
char actor_dx[NUM_ACTORS];
|
char actor_dx[NUM_ACTORS];
|
||||||
char actor_dy[NUM_ACTORS];
|
char actor_dy[NUM_ACTORS];
|
||||||
|
|
||||||
// OAM buffer pointer, in case we want to manipulate directly
|
|
||||||
#define OAMBUF ((unsigned char*) 0x200)
|
|
||||||
|
|
||||||
// main program
|
// main program
|
||||||
void main() {
|
void main() {
|
||||||
char i;
|
char i;
|
||||||
|
@ -92,9 +92,6 @@ char actor_y[NUM_ACTORS];
|
|||||||
char actor_dx[NUM_ACTORS];
|
char actor_dx[NUM_ACTORS];
|
||||||
char actor_dy[NUM_ACTORS];
|
char actor_dy[NUM_ACTORS];
|
||||||
|
|
||||||
// OAM buffer pointer, in case we want to manipulate directly
|
|
||||||
#define OAMBUF ((unsigned char*) 0x200)
|
|
||||||
|
|
||||||
// main program
|
// main program
|
||||||
void main() {
|
void main() {
|
||||||
char i;
|
char i;
|
||||||
@ -138,6 +135,11 @@ void main() {
|
|||||||
actor_x[i] += actor_dx[i];
|
actor_x[i] += actor_dx[i];
|
||||||
actor_y[i] += actor_dy[i];
|
actor_y[i] += actor_dy[i];
|
||||||
}
|
}
|
||||||
|
// set sprites 0-3 palette directly in OAM buffer
|
||||||
|
OAMBUF[0].attr |= 3;
|
||||||
|
OAMBUF[1].attr |= 3;
|
||||||
|
OAMBUF[2].attr |= 3;
|
||||||
|
OAMBUF[3].attr |= 3;
|
||||||
// hide rest of sprites
|
// hide rest of sprites
|
||||||
// if we haven't wrapped oam_id around to 0
|
// if we haven't wrapped oam_id around to 0
|
||||||
if (oam_id!=0) oam_hide_rest(oam_id);
|
if (oam_id!=0) oam_hide_rest(oam_id);
|
||||||
|
@ -42,7 +42,6 @@ typedef unsigned short word; // 16-bit signed
|
|||||||
typedef enum { false, true } bool; // boolean
|
typedef enum { false, true } bool; // boolean
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// set bg and spr palettes, data is 32 bytes array
|
// set bg and spr palettes, data is 32 bytes array
|
||||||
void __fastcall__ pal_all(const char *data);
|
void __fastcall__ pal_all(const char *data);
|
||||||
|
|
||||||
@ -309,5 +308,16 @@ void __fastcall__ nmi_set_callback(void (*callback)(void));
|
|||||||
#define MSB(x) (((x)>>8))
|
#define MSB(x) (((x)>>8))
|
||||||
#define LSB(x) (((x)&0xff))
|
#define LSB(x) (((x)&0xff))
|
||||||
|
|
||||||
|
// OAM buffer @ $200-$2FF
|
||||||
|
|
||||||
|
typedef struct OAMSprite {
|
||||||
|
byte y; // Y coordinate
|
||||||
|
byte name; // tile index in name table
|
||||||
|
byte attr; // attribute flags
|
||||||
|
byte x; // X coordinate
|
||||||
|
} OAMSprite;
|
||||||
|
|
||||||
|
#define OAMBUF ((OAMSprite*) 0x200)
|
||||||
|
|
||||||
#endif /* neslib.h */
|
#endif /* neslib.h */
|
||||||
|
|
||||||
|
@ -692,25 +692,19 @@ void set_sounds() {
|
|||||||
APU_ENABLE(enable);
|
APU_ENABLE(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char starx[32]; // array of star X coords
|
|
||||||
static byte starofs; // Y offset of all stars
|
|
||||||
|
|
||||||
void init_stars() {
|
void init_stars() {
|
||||||
|
byte oamid = 0; // 32 slots = 128 bytes
|
||||||
byte i;
|
byte i;
|
||||||
for (i=0; i<sizeof(starx); i++) {
|
for (i=0; i<32; i++) {
|
||||||
starx[i] = rand();
|
oamid = oam_spr(rand(), i*8, 103+(i&3), 0, oamid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_stars() {
|
void draw_stars() {
|
||||||
byte i;
|
byte i;
|
||||||
byte oamid = 0; // 32 slots = 128 bytes
|
|
||||||
byte yofs = starofs;
|
|
||||||
for (i=0; i<32; i++) {
|
for (i=0; i<32; i++) {
|
||||||
oamid = oam_spr(starx[i], yofs, 102+(i&3), 0, oamid);
|
++OAMBUF[i].y;
|
||||||
yofs += 8; // 32*8 = 256, wraps around
|
|
||||||
}
|
}
|
||||||
starofs++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void play_round() {
|
void play_round() {
|
||||||
@ -812,13 +806,13 @@ void setup_graphics() {
|
|||||||
void main() {
|
void main() {
|
||||||
setup_graphics();
|
setup_graphics();
|
||||||
apu_init();
|
apu_init();
|
||||||
init_stars();
|
|
||||||
player_score = 0;
|
player_score = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
pal_all(PALETTE);
|
pal_all(PALETTE);
|
||||||
oam_clear();
|
oam_clear();
|
||||||
oam_size(1); // 8x16 sprites
|
oam_size(1); // 8x16 sprites
|
||||||
clrscr();
|
clrscr();
|
||||||
|
init_stars();
|
||||||
play_round();
|
play_round();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,9 @@
|
|||||||
#include "neslib.h"
|
#include "neslib.h"
|
||||||
#include "vrambuf.h"
|
#include "vrambuf.h"
|
||||||
|
|
||||||
#pragma bss-name(push,"ZEROPAGE")
|
|
||||||
#pragma data-name(push,"ZEROPAGE")
|
|
||||||
|
|
||||||
// index to end of buffer
|
// index to end of buffer
|
||||||
byte updptr = 0;
|
byte updptr = 0;
|
||||||
|
|
||||||
#pragma bss-name(pop)
|
|
||||||
#pragma data-name(pop)
|
|
||||||
|
|
||||||
// add EOF marker to buffer
|
// add EOF marker to buffer
|
||||||
void cendbuf(void) {
|
void cendbuf(void) {
|
||||||
updbuf[updptr] = NT_UPD_EOF;
|
updbuf[updptr] = NT_UPD_EOF;
|
||||||
@ -35,13 +29,18 @@ void cflushnow(void) {
|
|||||||
// add multiple characters to update buffer
|
// add multiple characters to update buffer
|
||||||
// using horizontal increment
|
// using horizontal increment
|
||||||
void putbytes(word addr, const char* str, byte len) {
|
void putbytes(word addr, const char* str, byte len) {
|
||||||
|
// if bytes won't fit, wait for vsync and flush buffer
|
||||||
if (updptr >= VBUFSIZE-4-len) cflushnow();
|
if (updptr >= VBUFSIZE-4-len) cflushnow();
|
||||||
|
// add vram address
|
||||||
updbuf[updptr] = (addr >> 8) ^ NT_UPD_HORZ;
|
updbuf[updptr] = (addr >> 8) ^ NT_UPD_HORZ;
|
||||||
updbuf[++updptr] = addr & 0xff;
|
updbuf[++updptr] = addr & 0xff;
|
||||||
|
// add length
|
||||||
updbuf[++updptr] = len;
|
updbuf[++updptr] = len;
|
||||||
|
// add bytes
|
||||||
while (len--) {
|
while (len--) {
|
||||||
updbuf[++updptr] = *str++;
|
updbuf[++updptr] = *str++;
|
||||||
}
|
}
|
||||||
++updptr;
|
++updptr;
|
||||||
|
// add EOF mark
|
||||||
cendbuf();
|
cendbuf();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user