PVSneslib Documentation
repository·master·Indexed 22 days ago
https://github.com/alekmaul/pvsneslibA development kit for coding Nintendo SNES games in C or assembly. It features the 816-tcc compiler/linker toolchain and a hardware abstraction library covering backgrounds, sprites, input, sound (SPC700), and memory support (HiROM/FastROM). Includes specialized tools such as 816-opt for assembly optimization, bin2txt for binary-to-text conversion, and fnt4snes for variable font width conversion.
What's inside PVSneslib
- DevkitSnes is a toolset designed to compile C source files and graphics files into homebrew applications for the Super Nintendo Entertainment System (SNES). It is part of the PVSnesLib distribution.
Overview of PVSnesLib Features
masterPVSnesLib is a development kit for coding Nintendo SNES games in C or assembly. It includes a compiler/linker toolchain (816-tcc) and a library for hardware abstraction.
Key capabilities include:
- Backgrounds: Tile and map loading, support for multiple BG modes.
- Sprites: OAM management helpers for animation.
- Input: Reading controller/pad and mouse/superscope input.
- Sound & Music: Integration with the SPC700 audio driver.
- Memory Support: HiROM and FastROM support.
- Flexibility: Write in C, use assembly for performance-critical sections, or use assembly exclusively.
Optimize BRR encoding quality and size
masterWhen using
snesbrr, follow these best practices to improve audio quality and file size:- Minimize File Size: Ensure both the loop start point and the loop size are multiples of 16. If they are not, the tool will automatically repeat samples until they reach a multiple of 16, which can increase file size.
- Improve Audio Quality: Use a higher sampling rate than strictly necessary for the source. Gaussian filtering (used during SNES decoding) reduces high-frequency volume. Increasing the sampling rate offsets this effect.
- Example: A 4000 Hz square wave requires 8000 Hz minimum. At 8000 Hz, the decoded volume is only ~27%. At 16000 Hz, it reaches ~89%. At 32000 Hz, it reaches ~99%.
- Manual Encoding: For simple waves (Square, Triangle, Sawtooth), you can manually provide BRR block data for maximum quality and smallest size.
How 816-opt optimizations work
master816-opt performs several types of optimizations through iterative passes. It continues scanning the assembly source until no further changes can be made. Key optimization patterns include:
- Prologue/epilogue simplification: Collapses stack-frame sequences and removes
.define <name>_locals 0markers for functions without local variables. - Redundant store elimination: Removes stores to registers that are immediately overwritten, unused before a function call, or only used as a pointer.
- Pseudo-register (preg) optimizations: Simplifies
store/push/loadsequences for virtual 16/32-bit registers (e.g., converting a store+push into a single push). - Increment/decrement folding: Converts pseudo-register stores followed by
inc/decinto direct hardware register operations. - Shift/rotate folding: Merges pseudo-register stores followed by shifts (like
asl) into a single shift on the accumulator. - 32-bit value reordering: Reorders 32-bit value copies to enable further optimizations.
- Comparison optimizations: Simplifies common compare/branch sequences.
- Branch distance optimization: Converts long branch instructions to short forms when the target is close.
- Dead code and local name cleanup: Removes unused local variable names and bookkeeping metadata.
- Prologue/epilogue simplification: Collapses stack-frame sequences and removes
Update VRAM using the 'Slow' method
masterIf frame timing is not a priority, you can update the entire screen to VRAM by setting the
mapdirtyflag to1. This is the simplest way to ensure changes made tomapbuffer[]in RAM are reflected on screen, but it updates the entire screen at once.mapbuffer[123] = 0x0001; mapdirty = 1;Quickstart with PVSnesLib
masterTo get a project compiling quickly, follow these steps:
- Download the appropriate release for your operating system from the latest release page and unzip the archive.
- Set the environment variable
PVSNESLIB_HOMEto point to the directory where you unzipped the library. This is required for the toolchain to function. - Write a Hello World program to verify your setup. For a detailed guide on the Hello World example, refer to the Compiling helloworld-example tutorial.
For advanced details regarding Makefile setup, folder layouts, and flashing to real SNES hardware, consult the Project Wiki.
export PVSNESLIB_HOME="/path/to/pvsneslib"Build the Transparent HDMA Window demo with Visual Studio Code
masterTo build this specific demo using Visual Studio Code, ensure you have the editor installed and the project root directory open. You can trigger the build process using the integrated build task shortcut.
# Build shortcut Ctrl + Shift + BLoad maps into the mapbuffer[]
masterTo initialize the extension, you must first load your map data into WRAM using
mapbuffersLoad, and then point the standard map engine to themapbufferinstead of the original map data usingmapLoad.#include "mapbufferextension.h" // 1. Load map data into WRAM mapbuffersLoad((u8 *)&mapmario, (&mapmario_end - &mapmario)); // 2. Point the map engine to the buffer instead of the original map mapLoad((u8 *)&mapbuffer, (u8 *)&tilesetdef, (u8 *)&tilesetatt);#include "mapbufferextension.h" ... //load map into wram mapbuffersLoad((u8 *)&mapmario, (&mapmario_end- &mapmario)); //map engine gets the buffer instead mapLoad((u8 *)&mapbuffer, (u8 *)&tilesetdef, (u8 *)&tilesetatt);Build the Capcom Logo demo using Visual Studio Code
masterTo build the Capcom logo demo, ensure you have Visual Studio Code installed. Open the root directory of the project in VS Code and use the integrated build task to compile the source code.
- Open the project root directory in Visual Studio Code.
- Press
Ctrl + Shift + Bto trigger the build process. - Once the build completes, open the resulting
logo.sfcfile using a Super Nintendo (SNES) emulator to view the demo.
# Build command via VS Code shortcut Ctrl + Shift + BUse bin2txt to convert binary files
masterThe
bin2txtutility is a binary file converter designed for Super Nintendo development. It converts binary files into text-based formats (C or Assembly) so they can be easily included in your source code as data arrays.bin2txt [options] filenameBuild and Clean PVSneslib projects in VS Code
masterOnce configured, you can manage your project using VS Code tasks:
- Open your project folder in VS Code (
File -> Open Folder...). - Press
Ctrl + Shift + Bto trigger the build tasks. - Select from the following tasks:
PVSneslib - Build: Compiles the project.PVSneslib - Clean: Removes all object files and temporary files.
Alternatively, you can run build commands manually via the integrated terminal after navigating to your project directory.
- Open your project folder in VS Code (
Update VRAM using the 'Fast' method (Dynamic Tile Buffer)
masterFor high-performance tile manipulation (e.g., event-driven or time-based changes), use the Dynamic Tile Buffer (
__dtb__) and Dynamic Tile Queue (__dtq__) workflow. This method avoids full-screen updates by queuing only necessary tiles to be updated during V-Blank.Workflow Steps:
- Prepare Metadata: Call
__mapGetMetaTilesInfo__to pre-store variables required for the dynamic buffer. - Setup/Update Buffer: Call
__GetDynamicTileID__to setup or update the__dtb__. This returns an index used for subsequent calls. - Manipulate Tiles: Use one of the following to modify tiles using the index from step 2:
__mapChangeTileByID__: Changes a tile by ID and attributes.__ManipulateDynamicTile__: Example of event-driven manipulation (e.g., reacting to a player collision).__DynamicTileAutoUpdate__: Example of time-based manipulation (call once before queuing).
- Queue Tiles: Call
__maptileQueueUpdate__once beforeWaitForVBlankto push tiles currently on screen from the__dtb__into the__dtq__. - Flush to VRAM: Call
__maptileVRAMUpdate__once afterWaitForVBlankto update the queued tiles in VRAM and flush the queue. VRAM access is only permitted during V-Blank.
- Prepare Metadata: Call