OpenSNES
Modern Open-Source SNES Development SDK
Loading...
Searching...
No Matches
console.h File Reference

SNES Console Initialization and Core Functions. More...

#include <snes/types.h>
#include <snes/registers.h>

Go to the source code of this file.

Functions

void consoleInit (void)
 Initialize SNES hardware.
void fadeIn (u8 speed)
 Fade the screen from black (0) up to full brightness (15).
void fadeOut (u8 speed)
 Fade the screen from full brightness (15) down to black (0).
u8 getBrightness (void)
 Get current brightness.
u16 getFrameCount (void)
 Get frame counter.
u8 isInVBlank (void)
 Check if currently in VBlank.
u8 isPAL (void)
 Check if PAL system.
void resetFrameCount (void)
 Reset frame counter.
u16 rngNext (void)
 Next pseudo-random 16-bit number.
void rngSeed (u16 seed)
 Seed the generator (the srand() of 0.x, removed 2026-10-05).
void setBrightness (u8 brightness)
 Set screen brightness.
void setScreenOff (void)
 Disable screen display (blank).
void setScreenOn (void)
 Enable screen display.
void WaitForVBlank (void)
 Wait for next VBlank period.

Detailed Description

SNES Console Initialization and Core Functions.

Provides functions for initializing SNES hardware and core functionality like VBlank synchronization.

Basic Usage

#include <snes.h>
int main(void) {
// Initialize hardware
// Set up your game...
// Main game loop
while (1) {
// Wait for VBlank (required for stable graphics)
// Update game logic
// Handle input
// Update sprites/backgrounds
}
}
int main(void)
Definition main.c:66
void consoleInit(void)
Initialize SNES hardware.
void WaitForVBlank(void)
Wait for next VBlank period.
OpenSNES common-case master header.

Attribution

Originally from: PVSnesLib (https://github.com/alekmaul/pvsneslib) Author: Alekmaul License: zlib (compatible with MIT) Modifications:

  • Renamed functions for clarity
  • Added comprehensive documentation
Author
OpenSNES Team

Function Documentation

◆ consoleInit()

void consoleInit ( void )

Initialize SNES hardware.

Must be called at the start of your program. What it does, exactly:

  • forces blank, brightness shadow = 15
  • detects PAL / NTSC
  • seeds rngNext() from the H/V counters
  • BG mode 1, BG1 tilemap at VRAM $0400 (32x32), BG1 tiles at $0000
  • mosaic off, all 256 CGRAM entries cleared to black
  • enables NMI + auto-joypad, and DROPS any armed H/V timer IRQ bits

It does not clear work RAM or set up the CPU (crt0 did that before main), and it loads no palette — this list claimed all three until 2026-09-20.

After calling, screen is blanked (black). Call setScreenOn() to enable display after you've set up your graphics.

int main(void) {
// Load graphics...
// Set up sprites...
setScreenOn(); // Now show the screen
while (1) {
}
}
void setScreenOn(void)
Enable screen display.

◆ fadeIn()

void fadeIn ( u8 speed)

Fade the screen from black (0) up to full brightness (15).

Symmetric counterpart to fadeOut. Steps INIDISP brightness from 0 → 15, waiting speed VBlank frames between each step.

Parameters
speedVBlank frames to wait between steps (see fadeOut for the wall-clock cost at common values).

◆ fadeOut()

void fadeOut ( u8 speed)

Fade the screen from full brightness (15) down to black (0).

Steps INIDISP brightness from 15 → 0, waiting speed VBlank frames between each step. Final state: setBrightness(0) (visually black, screen still rendering). Combine with setScreenOff() afterwards if you want to also enter force-blank for safe VRAM updates.

At 60 fps (NTSC):

  • speed=1 → 16 frames (~0.27 s, fast/snappy)
  • speed=3 → 48 frames (~0.80 s, cinematic)
  • speed=6 → 96 frames (~1.60 s, dramatic)
Parameters
speedVBlank frames to wait between each brightness step. speed=0 waits for nothing: all 16 steps are written in one burst, i.e. an instant cut, not a fade.
Note
Under forced blank the brightness writes are skipped (the shadow still moves), so a fade does nothing visible until setScreenOn().
fadeOut(3); // ~0.8 s cinematic fade
setScreenOff(); // force-blank for VRAM swap
dmaCopyVram(new_tiles, 0, ...);
fadeIn(3);
void setScreenOff(void)
Disable screen display (blank).
void fadeIn(u8 speed)
Fade the screen from black (0) up to full brightness (15).
void fadeOut(u8 speed)
Fade the screen from full brightness (15) down to black (0).
void dmaCopyVram(const u8 *source, u16 vramAddr, u16 size)
Copy data to VRAM (PVSnesLib compatible).

◆ getBrightness()

u8 getBrightness ( void )

Get current brightness.

Returns
Current brightness level (0-15)

◆ getFrameCount()

u16 getFrameCount ( void )
inline

Get frame counter.

Returns the number of VBlanks since initialization. Wraps at 65535.

Inlined for zero-call-overhead access (just a 16-bit load).

Returns
Frame count
// Simple animation timing
u8 anim_frame = (getFrameCount() / 8) % 4;
u16 getFrameCount(void)
Get frame counter.
Definition console.h:269
unsigned char u8
8-bit unsigned integer (0 to 255)
Definition types.h:47

◆ isInVBlank()

u8 isInVBlank ( void )

Check if currently in VBlank.

Returns
1 if in VBlank, 0 in active display (0xFF for "yes" until 2026-09-22)

◆ isPAL()

u8 isPAL ( void )

Check if PAL system.

Returns
1 if PAL (50Hz), 0 if NTSC (60Hz) (it returned 0xFF for PAL before 2026-09-22)
if (isPAL()) {
// Adjust game speed for 50Hz
}
u8 isPAL(void)
Check if PAL system.

◆ resetFrameCount()

void resetFrameCount ( void )

Reset frame counter.

Sets frame counter to 0. Useful for timing game events.

◆ rngNext()

u16 rngNext ( void )

Next pseudo-random 16-bit number.

A 16-bit linear feedback shift register (x^16 + x^14 + x^13 + x^11 + 1). Named rand() until 2026-09-22 (that name was removed on 2026-10-05) — a libc name for a function that is not the libc one (no RAND_MAX, 1-65535, a u16), which collides the day any C library code is linked.

Returns
Random value 1-65535 — a 16-bit LFSR never yields 0 (and a zero seed is replaced, see rngSeed())
u16 enemy_x = rngNext() % 256;
static s16 enemy_x[4]
X positions of the four static enemy sprites.
Definition main.c:63
u16 rngNext(void)
Next pseudo-random 16-bit number.
unsigned short u16
16-bit unsigned integer (0 to 65535)
Definition types.h:53

◆ rngSeed()

void rngSeed ( u16 seed)

Seed the generator (the srand() of 0.x, removed 2026-10-05).

consoleInit() seeds it from the H/V counters; reseed from a player action (rngSeed(getFrameCount()) on START) for a different game each run.

Parameters
seedInitial seed value; 0 is replaced by a fixed non-zero state

◆ setBrightness()

void setBrightness ( u8 brightness)

Set screen brightness.

Parameters
brightnessBrightness level (0-15, 0=black, 15=full)
Warning
setBrightness(0) is NOT forced blank. It makes the screen black, but the PPU keeps fetching, so VRAM and CGRAM writes are still rejected. Only setScreenOff() (INIDISP bit 7) opens the write window outside VBlank.

The mistake survives testing: a small transfer written this way lands inside VBlank and is correct every time, while a multi-KB one has its tail dropped during active display. Use setScreenOff() / setScreenOn() around any upload that is not comfortably inside the VBlank budget — see dmaCopyVram().

// Fade in effect
for (u8 i = 0; i <= 15; i++) {
}
void setBrightness(u8 brightness)
Set screen brightness.
static u8 i
Definition main.c:155

◆ setScreenOff()

void setScreenOff ( void )

Disable screen display (blank).

Turns off the display. Use during major VRAM updates that can't complete during VBlank.

// ... massive VRAM update ...

◆ setScreenOn()

void setScreenOn ( void )

Enable screen display.

Turns on the display after initialization or a screen blank, at the LAST brightness set (15 after consoleInit). After fadeOut() that level is 0, so the screen stays black until fadeIn() or setBrightness() — which is what the fade example below relies on. (Documented as "full brightness" until 2026-09-20.)

// ... load graphics ...
setScreenOn(); // Display is now visible

◆ WaitForVBlank()

void WaitForVBlank ( void )

Wait for next VBlank period.

Blocks until the PPU enters Vertical Blank. This is essential for:

  • Stable graphics (prevents tearing)
  • Safe VRAM/OAM/CGRAM updates
  • Consistent game timing

Call once per frame in your main loop.

The capital W is deliberate: the name is PVSnesLib's, kept so a port needs no edit. It is the only function of the library not in camelCase.

while (1) {
// Update game logic (can happen during active display)
updatePlayer();
checkCollisions();
// Wait for VBlank
// Now safe to update graphics
updateOAM();
scrollBackground();
}
Note
VBlank occurs ~60 times/second (NTSC) or ~50 times/second (PAL)
On return the NMI handler has ALREADY run: the OAM upload, the text tilemap flush, the scroll sync, your nmiSet() callback and the auto-joypad wait have used part of VBlank. What is left is safe for VRAM / CGRAM writes, but it is not the whole VBlank.
Warning
Hangs forever if NMI is disabled (NMITIMEN bit 7 clear): it sleeps until the NMI handler clears the handshake flag.