1
0
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:
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? - 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

View File

@ -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">

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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 */

View File

@ -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();
} }
} }

View File

@ -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();
} }