nes: fixed presets, added to platforms menu

This commit is contained in:
Steven Hugg 2019-03-04 09:35:33 -05:00
parent 733846af16
commit f17a3488ed
12 changed files with 53 additions and 47 deletions

View File

@ -96,6 +96,7 @@ TODO:
- open ROM from URL?
- NES: disassembly not aligned on PC
- NES: vrambuf.c for Solarian
- game starts even if switched away before first load
WEB WORKER FORMAT

View File

@ -109,6 +109,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
<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.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>
</li>
<li class="dropdown dropdown-submenu">

View File

@ -78,10 +78,6 @@ byte rndint(byte a, byte b) {
return (rand() % (b-a)) + a;
}
///// OAM buffer (for sprites)
#define OAMBUF ((unsigned char*) 0x200)
// return nametable address for tile (x,y)
// assuming vertical scrolling (horiz. mirroring)
word getntaddr(byte x, byte y) {
@ -397,6 +393,7 @@ void create_actors_on_floor(byte floor_index) {
if (floor_index == MAX_FLOORS-1) {
a->name = ACTOR_RESCUE;
a->state = PACING;
a->x = 0;
}
}
}
@ -439,14 +436,15 @@ byte draw_actor(byte oam_id, byte i) {
x = a->x;
y = screen_y;
oam_id = oam_meta_spr(x, y, oam_id, meta);
// actor 0 is player sprite
// is this actor 0? (player sprite)
if (i == 0) {
player_screen_y = y; // last screen Y position
// set special palette for player sprites
OAMBUF[0+2] |= 3;
OAMBUF[4+2] |= 3;
OAMBUF[8+2] |= 3;
OAMBUF[12+2] |= 3;
// set special palette for the player's sprites
// directly in OAM buffer
OAMBUF[0].attr |= 3;
OAMBUF[1].attr |= 3;
OAMBUF[2].attr |= 3;
OAMBUF[3].attr |= 3;
}
a->onscreen = 1;
return oam_id;

View File

@ -38,7 +38,7 @@ Start:
; fill video RAM with "Hello World" msg
HelloVRAM: subroutine
; set PPU address to name table A (row 1, col 1)
PPU_SETADDR $2021
PPU_SETADDR $2021
ldy #0 ; set Y counter to 0
.loop:
lda HelloMsg,y ; get next character
@ -57,7 +57,8 @@ HelloMsg:
; set palette colors
SetPalette: subroutine
; set PPU address to palette start
PPU_SETADDR $3f00
PPU_SETADDR $3f00
ldy #0
.loop:
lda Palette,y ; lookup byte in ROM
sta PPU_DATA ; store byte to PPU data

View File

@ -10,7 +10,7 @@ ScrollPos word ; used during NMI
;;;;; 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
@ -54,6 +54,7 @@ FillVRAM: subroutine
; set palette colors
SetPalette: subroutine
PPU_SETADDR $3f00
ldy #0
.loop:
lda Palette,y ; lookup byte in ROM
sta PPU_DATA ; store byte to PPU data

View File

@ -45,6 +45,7 @@ Start:
FillVRAM: subroutine
PPU_SETADDR $2000
ldy #$10
ldx #0
.loop:
stx PPU_DATA ; X -> PPU data port
inx ; X = X + 1
@ -83,6 +84,7 @@ MoveSprites: subroutine
; set palette colors
SetPalette: subroutine
PPU_SETADDR $3f00
ldy #0
.loop:
lda Palette,y ; lookup byte in ROM
sta PPU_DATA ; store byte to PPU data

View File

@ -38,8 +38,9 @@ Start:
; fill video RAM
FillVRAM: subroutine
PPU_SETADDR $2000
PPU_SETADDR $2000
ldy #$10
ldx #0
.loop:
stx PPU_DATA
inx
@ -49,17 +50,16 @@ FillVRAM: subroutine
rts
; set palette colors
SetPalette: subroutine
PPU_SETADDR $3f00
ldx #32
PPU_SETADDR $3f00
ldy #0
.loop:
lda Palette,y
sta PPU_DATA
iny
dex
bne .loop
rts
lda Palette,y ; lookup byte in ROM
sta PPU_DATA ; store byte to PPU data
iny ; Y = Y + 1
cpy #32 ; is Y equal to 32?
bne .loop ; not yet, loop
rts ; return to caller
;;;;; COMMON SUBROUTINES

View File

@ -92,9 +92,6 @@ char actor_y[NUM_ACTORS];
char actor_dx[NUM_ACTORS];
char actor_dy[NUM_ACTORS];
// OAM buffer pointer, in case we want to manipulate directly
#define OAMBUF ((unsigned char*) 0x200)
// main program
void main() {
char i;

View File

@ -92,9 +92,6 @@ char actor_y[NUM_ACTORS];
char actor_dx[NUM_ACTORS];
char actor_dy[NUM_ACTORS];
// OAM buffer pointer, in case we want to manipulate directly
#define OAMBUF ((unsigned char*) 0x200)
// main program
void main() {
char i;
@ -138,6 +135,11 @@ void main() {
actor_x[i] += actor_dx[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
// if we haven't wrapped oam_id around to 0
if (oam_id!=0) oam_hide_rest(oam_id);

View File

@ -42,7 +42,6 @@ typedef unsigned short word; // 16-bit signed
typedef enum { false, true } bool; // boolean
// set bg and spr palettes, data is 32 bytes array
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 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 */

View File

@ -692,25 +692,19 @@ void set_sounds() {
APU_ENABLE(enable);
}
static char starx[32]; // array of star X coords
static byte starofs; // Y offset of all stars
void init_stars() {
byte oamid = 0; // 32 slots = 128 bytes
byte i;
for (i=0; i<sizeof(starx); i++) {
starx[i] = rand();
for (i=0; i<32; i++) {
oamid = oam_spr(rand(), i*8, 103+(i&3), 0, oamid);
}
}
void draw_stars() {
byte i;
byte oamid = 0; // 32 slots = 128 bytes
byte yofs = starofs;
for (i=0; i<32; i++) {
oamid = oam_spr(starx[i], yofs, 102+(i&3), 0, oamid);
yofs += 8; // 32*8 = 256, wraps around
++OAMBUF[i].y;
}
starofs++;
}
void play_round() {
@ -812,13 +806,13 @@ void setup_graphics() {
void main() {
setup_graphics();
apu_init();
init_stars();
player_score = 0;
while (1) {
pal_all(PALETTE);
oam_clear();
oam_size(1); // 8x16 sprites
clrscr();
init_stars();
play_round();
}
}

View File

@ -2,15 +2,9 @@
#include "neslib.h"
#include "vrambuf.h"
#pragma bss-name(push,"ZEROPAGE")
#pragma data-name(push,"ZEROPAGE")
// index to end of buffer
byte updptr = 0;
#pragma bss-name(pop)
#pragma data-name(pop)
// add EOF marker to buffer
void cendbuf(void) {
updbuf[updptr] = NT_UPD_EOF;
@ -35,13 +29,18 @@ void cflushnow(void) {
// add multiple characters to update buffer
// using horizontal increment
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();
// add vram address
updbuf[updptr] = (addr >> 8) ^ NT_UPD_HORZ;
updbuf[++updptr] = addr & 0xff;
// add length
updbuf[++updptr] = len;
// add bytes
while (len--) {
updbuf[++updptr] = *str++;
}
++updptr;
// add EOF mark
cendbuf();
}