Loading...
Searching...
No Matches
main.c File Reference

Interactive showcase of all four HDMA library helper effects. More...

#include <snes.h>
#include <snes/console.h>
#include <snes/input.h>
#include <snes/hdma.h>

Classes

struct  EffectState
 Tracks which HDMA effect is currently active and its parameters. More...
 

Functions

int main (void)
 Entry point – interactive showcase of four HDMA helper effects.
 
static void stopCurrentEffect (void)
 Stop whichever HDMA effect is currently running and restore defaults.
 

Variables

EffectState fx = {0, 80, 0, 6}
 Global effect state instance with default values.
 
u8 hdma_table_a []
 Scratch HDMA table used for channel 6 null-terminator setup.
 
u8 hdma_wave_amplitude
 Current wave amplitude for the water ripple effect (library variable).
 
u8 palette []
 15-bit BGR palette for the background (up to 16 colors).
 
u8 palette_end []
 
u8 tilemap []
 Tilemap data (32x32 tile grid) for the background.
 
u8 tilemap_end []
 
u8 tiles []
 4bpp tile data for the background image.
 
u8 tiles_end []
 

Detailed Description

Interactive showcase of all four HDMA library helper effects.

Demonstrates the four high-level HDMA helper functions provided by the OpenSNES library: brightness gradient, color gradient, iris wipe, and water ripple. Each effect uses one or two HDMA channels to modify PPU registers per-scanline without CPU intervention. The brightness gradient writes INIDISP ($2100), the color gradient rewrites CGRAM color 0 via CGADD/CGDATA, the iris wipe programs window registers (WH0/WH1) with TMW masking, and the water ripple offsets BG1HOFS per scanline using a sine-based displacement table. Effects can be toggled and their parameters adjusted in real time using the controller.

SNES Concepts
  • HDMA brightness gradient (INIDISP per-scanline dimming)
  • HDMA color gradient (CGRAM color 0 rewrite per scanline group)
  • HDMA iris wipe (window registers WH0/WH1 + TMW masking)
  • HDMA water ripple (BG1HOFS sine displacement per scanline)
  • Safe HDMA channel management (stop previous before starting new)
What to Observe
  • Press A: brightness gradient (screen fades to black at bottom)
  • Press B: color gradient (backdrop shifts from deep blue to orange)
  • Press X: iris wipe (circular window reveals the background)
  • Press Y: water ripple (sinusoidal horizontal distortion animates)
  • D-pad UP/DOWN: adjust the active effect's parameter (radius, amplitude, etc.)
  • START: stop the current effect and restore normal display
Modules Used
console, sprite, dma, input, background, hdma
See also
hdma.h, input.h, background.h, video.h

Function Documentation

◆ main()

int main ( void  )

Entry point – interactive showcase of four HDMA helper effects.

Loads a background image and enters an interactive loop where each button activates a different HDMA effect:

  • A: brightness gradient (INIDISP per-scanline dimming)
  • B: color gradient (CGRAM color 0 rewrite per scanline group)
  • X: iris wipe (window registers WH0/WH1 with TMW masking)
  • Y: water ripple (BG1HOFS sine displacement per scanline)
  • D-pad UP/DOWN: adjust the active effect's parameter
  • START: stop the current effect and restore normal display

Before activating a new effect, the previous one is always stopped first to avoid HDMA channel conflicts and stale PPU register values.

Returns
Does not return (infinite loop).

< Newly pressed buttons this frame (edge-detected)

◆ stopCurrentEffect()

static void stopCurrentEffect ( void  )
static

Stop whichever HDMA effect is currently running and restore defaults.

This function performs a complete cleanup:

  1. Stops ALL HDMA helper channels (ch6 and ch7) unconditionally, because different effects use different channels and a previous effect's channel may still be running when switching.
  2. Re-enables ch6 with a null (terminator-only) table. This is critical because the SNES HDMA controller initializes table pointers (A1T -> A2A) only for channels that are enabled at VBlank. If ch6 is disabled and then enabled mid-frame, the first frame reads stale A2A data, causing a visible one-frame glitch (horizontal lines).
  3. Reloads the original palette from ROM, because the color gradient effect modifies CGRAM per-scanline and those values persist after HDMA stops. CGRAM DMA must happen during VBlank to avoid visual artifacts.

Variable Documentation

◆ fx

EffectState fx = {0, 80, 0, 6}

Global effect state instance with default values.

◆ hdma_table_a

u8 hdma_table_a[]
extern

Scratch HDMA table used for channel 6 null-terminator setup.

Defined in the HDMA library module. When an effect is stopped, this table is loaded with a single 0x00 terminator and assigned to channel 6 to keep the channel "alive" for proper HDMA initialization at each VBlank.

◆ hdma_wave_amplitude

u8 hdma_wave_amplitude
extern

Current wave amplitude for the water ripple effect (library variable).

This variable is defined in the HDMA library module. Writing to it adjusts the horizontal displacement amplitude of the sine-wave distortion applied per-scanline to BG1HOFS. Valid range: 2-24 pixels. The library reads this value each frame in hdmaWaveUpdate() to scale the sine table entries.

◆ palette

u8 palette[]
extern

15-bit BGR palette for the background (up to 16 colors).

◆ palette_end

u8 palette_end[]

◆ tilemap

u8 tilemap[]
extern

Tilemap data (32x32 tile grid) for the background.

◆ tilemap_end

u8 tilemap_end[]

◆ tiles

u8 tiles[]
extern

4bpp tile data for the background image.

◆ tiles_end

u8 tiles_end[]