diff --git a/presets/nes/aputest.c b/presets/nes/aputest.c index 9e5527f8..c24edff9 100644 --- a/presets/nes/aputest.c +++ b/presets/nes/aputest.c @@ -1,4 +1,10 @@ +/* +Generates random sounds in the APU, printing the parameters +to the screen. Also shows an asterisk while each channel is +playing, i.e. while its length counter is active. +*/ + #include #include #include diff --git a/presets/nes/attributes.c b/presets/nes/attributes.c index c185a303..360e5799 100644 --- a/presets/nes/attributes.c +++ b/presets/nes/attributes.c @@ -1,4 +1,9 @@ +/* +Setting the attribute table, which controls palette selection +for the nametable. We copy it from an array in ROM to video RAM. +*/ + #include "neslib.h" #include #include diff --git a/presets/nes/bankswitch.c b/presets/nes/bankswitch.c index 69f88821..19155b31 100644 --- a/presets/nes/bankswitch.c +++ b/presets/nes/bankswitch.c @@ -1,4 +1,13 @@ +/* +Bank-switching using the MMC3 mapper. +We use a special linker config that sets up +64 KB of PRG ROM and 64 KB of CHR ROM. +Macros are used to set MMC3 registers and switch banks. +CC65 #pragma directives are used to put things in various +PRG ROM segments (CODE0-CODE6, CODE). +*/ + // bank-switching configuration #define NES_MAPPER 4 // Mapper 4 (MMC3) #define NES_PRG_BANKS 4 // # of 16KB PRG banks diff --git a/presets/nes/climber.c b/presets/nes/climber.c index c8461bcc..20075cd7 100644 --- a/presets/nes/climber.c +++ b/presets/nes/climber.c @@ -1,4 +1,14 @@ +/* +A platform game with a randomly generated stage. +Uses the Famitone2 library for sound and music. +It scrolls vertically (horizontal mirroring) and nametable +updates are performed offscreen one row at a time with the +draw_floor_line() function. +The enemies use the same movement logic as the player, just +with random inputs. +*/ + #include #include diff --git a/presets/nes/fami.c b/presets/nes/fami.c index 96de1caf..cdf9b7f5 100644 --- a/presets/nes/fami.c +++ b/presets/nes/fami.c @@ -1,4 +1,9 @@ +/* +Demonstrates the Famitone2 library for sound and music. +Press controller buttons to hear sound effects. +*/ + #include "neslib.h" // link the pattern table into CHR ROM diff --git a/presets/nes/flicker.c b/presets/nes/flicker.c index 92818f98..0d68376b 100644 --- a/presets/nes/flicker.c +++ b/presets/nes/flicker.c @@ -1,4 +1,11 @@ +/* +If you have more objects than will fit into the 64 hardware +sprites, you can omit some of the sprites each frame. +We also use oam_meta_spr_pal() to change the color of each +metasprite. +*/ + #include #include diff --git a/presets/nes/hello.c b/presets/nes/hello.c index e7054e8d..a8cc3b49 100644 --- a/presets/nes/hello.c +++ b/presets/nes/hello.c @@ -1,4 +1,11 @@ +/* +A simple "hello world" example. +Set the screen background color and palette colors. +Then write a message to the nametable. +Finally, turn on the PPU to display video. +*/ + #include "neslib.h" // link the pattern table into CHR ROM diff --git a/presets/nes/horizmask.c b/presets/nes/horizmask.c index be16c708..eb58337b 100644 --- a/presets/nes/horizmask.c +++ b/presets/nes/horizmask.c @@ -1,4 +1,15 @@ +/* +We demonstrate horizontal scrolling of two nametables. +Vertical mirroring is set, so nametables A and B are +to the left and right of each other. + +New playfield data is randomly generated and updated +offscreen using the vrambuf module. +Every 32 pixels, we also update the attribute table. +We also use the split() function to create a status bar. +*/ + #include "neslib.h" #include @@ -29,11 +40,13 @@ byte bldg_attr; // attribute table value #define PLAYROWS 24 +// convert from nametable address to attribute table address word nt2attraddr(word a) { return (a & 0x2c00) | 0x3c0 | ((a >> 4) & 0x38) | ((a >> 2) & 0x07); } +// generate new random building data void new_building() { bldg_height = (rand8() & 7) + 2; bldg_width = (rand8() & 3) * 4 + 4; @@ -41,6 +54,8 @@ void new_building() { bldg_attr = rand8(); } +// update the nametable offscreen +// called every 8 horizontal pixels void update_nametable() { register word addr; // a buffer drawn to the nametable vertically diff --git a/presets/nes/irq.c b/presets/nes/irq.c index 5b1534df..2e327183 100644 --- a/presets/nes/irq.c +++ b/presets/nes/irq.c @@ -1,4 +1,12 @@ +/* +Multiple screen splits with the MMC3 mapper using IRQs. +The main loop updates the scroll counters continuously. +When a IRQ fires, we change the X scroll register, setting +it immediately via the PPU struct. +The NMI and IRQ use the same callback function. +*/ + // bank-switching configuration #define NES_MAPPER 4 // Mapper 4 (MMC3) #define NES_PRG_BANKS 4 // # of 16KB PRG banks diff --git a/presets/nes/metacursor.c b/presets/nes/metacursor.c index 8fc80a21..5890fa7e 100644 --- a/presets/nes/metacursor.c +++ b/presets/nes/metacursor.c @@ -1,4 +1,10 @@ +/* +Read from controllers with pad_poll(). +We also demonstrate sprite animation by cycling among +several different metasprites, which are defined using macros. +*/ + #include #include diff --git a/presets/nes/metasprites.c b/presets/nes/metasprites.c index 5cf55e49..5bd3f8d6 100644 --- a/presets/nes/metasprites.c +++ b/presets/nes/metasprites.c @@ -1,4 +1,10 @@ +/* +Metasprites combine several hardware sprites to make a larger +sprite. Our demo uses 4 hardware sprites in a 2x2 pattern, +forming 16x16 pixel sprites. +*/ + #include #include diff --git a/presets/nes/monobitmap.c b/presets/nes/monobitmap.c index 4f54ac74..a25c7d9a 100644 --- a/presets/nes/monobitmap.c +++ b/presets/nes/monobitmap.c @@ -1,4 +1,12 @@ +/* +Creates a monochrome frame buffer in video RAM. +We map the pattern tables to CHR RAM, using the UxROM (2) mapper. +By cleverly setting up palettes, and using a split-screen +CHR bank switch, we split the screen into four different regions +that display their own pixels. +*/ + #include "neslib.h" #include "nes.h" #include diff --git a/presets/nes/music.c b/presets/nes/music.c index 5b758ad5..c1f817e7 100644 --- a/presets/nes/music.c +++ b/presets/nes/music.c @@ -1,4 +1,8 @@ +/* +A simple music player. +*/ + #include #include diff --git a/presets/nes/rletitle.c b/presets/nes/rletitle.c index e10787aa..98c0c334 100644 --- a/presets/nes/rletitle.c +++ b/presets/nes/rletitle.c @@ -1,6 +1,8 @@ -// this example code unpacks a RLE'd nametable into the VRAM -// you can create the source data using NES Screen Tool +/* +Unpacks a RLE-compressed nametable+attribute table into VRAM. +Also uses the pal_bright() function to fade in the palette. +*/ #include "neslib.h" diff --git a/presets/nes/scroll.c b/presets/nes/scroll.c index 06e1b824..cdf336d7 100644 --- a/presets/nes/scroll.c +++ b/presets/nes/scroll.c @@ -1,4 +1,12 @@ +/* +Scrolling demo. +We've selected horizontal mirroring as the default, so +nametables A and C are stacked on top of each other. +The vertical scroll area is 480 pixels high; note how +the nametables wrap around. +*/ + #include "neslib.h" #include diff --git a/presets/nes/shoot2.c b/presets/nes/shoot2.c index d106bdc1..fc55472c 100644 --- a/presets/nes/shoot2.c +++ b/presets/nes/shoot2.c @@ -1,4 +1,11 @@ +/* +A shoot-em-up game. +Uses CHR RAM to draw attacker tiles at 8 different pixels, +then animates them in the nametable. +Sprites are used for the player, missiles, attackers, and stars. +*/ + #include #include #include diff --git a/presets/nes/siegegame.c b/presets/nes/siegegame.c index a4690371..185d7308 100644 --- a/presets/nes/siegegame.c +++ b/presets/nes/siegegame.c @@ -1,4 +1,10 @@ +/* +A character-based surround-the-opponent game. +Reads from nametable RAM to determine collisions, and also +to help the AI avoid walls. +*/ + #include #include #include diff --git a/presets/nes/sprites.c b/presets/nes/sprites.c index 322309e4..8d0e42ac 100644 --- a/presets/nes/sprites.c +++ b/presets/nes/sprites.c @@ -1,4 +1,9 @@ +/* +Sprite demo. +Animate all 64 hardware sprites. +*/ + #include #include diff --git a/presets/nes/statusbar.c b/presets/nes/statusbar.c index c827f83d..39c5c6a0 100644 --- a/presets/nes/statusbar.c +++ b/presets/nes/statusbar.c @@ -1,4 +1,12 @@ +/* +Demo of split screen effect. +We position sprite 0 at the desired scanline, and when it +collides with the background, a flag in the PPU is set. +The split() function waits for this flag, then changes the +X scroll register in the PPU. +*/ + #include "neslib.h" #include diff --git a/presets/nes/tint.c b/presets/nes/tint.c index 9811e1d1..248bab99 100644 --- a/presets/nes/tint.c +++ b/presets/nes/tint.c @@ -1,4 +1,9 @@ +/* +Demonstrates the PPU's tint and monochrome bits. +Use the controller to see different combinations. +*/ + #include #include diff --git a/presets/nes/vrambuffer.c b/presets/nes/vrambuffer.c index e60a8ae6..16e61bce 100644 --- a/presets/nes/vrambuffer.c +++ b/presets/nes/vrambuffer.c @@ -1,4 +1,11 @@ +/* +On the NES, you can't write to video RAM while the PPU +is active, so you have to do it during the vertical blank. +We have a module (vrambuf) which fills up a buffer with video +data, then NESLib writes it to VRAM during the NMI interrupt. +*/ + #include "neslib.h" #include #include diff --git a/src/platform/nes.ts b/src/platform/nes.ts index 6147f9c4..8d5d4db9 100644 --- a/src/platform/nes.ts +++ b/src/platform/nes.ts @@ -24,10 +24,10 @@ const JSNES_PRESETS = [ {id:'monobitmap.c', name:'Monochrome Bitmap'}, {id:'aputest.c', name:'Sound Tester'}, {id:'music.c', name:'Music Player'}, + {id:'fami.c', name:'Famitone Demo'}, {id:'siegegame.c', name:'Siege Game'}, {id:'shoot2.c', name:'Solarian Game'}, {id:'climber.c', name:'Platform Game'}, - {id:'fami.c', name:'Famitone Demo'}, {id:'bankswitch.c', name:'Bank Switching'}, {id:'irq.c', name:'IRQ Scanline Counter'}, {id:'ex0.dasm', name:'Initialization (ASM)'},