agb Rust Library

repository·master·Indexed 19 days ago

https://github.com/agbrs/agb

A Rust library for Game Boy Advance development (version 0.25.0) providing high-level abstractions for graphics, audio, and asset management. It includes features for sprite and tiled background handling, a high-performance audio mixer with .xm tracker support, and a global allocator for core and alloc crates. The ecosystem includes complementary tools such as embassy-agb for Async Rust, agb-fixnum for fixed-point math, and agb-debug for mapping binary dumps back to source code using DWARF debug information.

Tokens
86.9K
Snippets
328
Records
410
Agent score
66%

What's inside agb

  1. Overview of the agb library

    master

    What is agb?

    agb is a Rust library designed for writing games for the Game Boy Advance (GBA). It provides an abstracted interface to the GBA hardware, allowing developers to leverage hardware capabilities without managing low-level implementation details directly.

    Key Features

    • Simplified Build Process: Minimal dependencies for easier setup.
    • Asset Management: Built-in support for importing sprites, backgrounds, music, and sound effects.
    • High Performance Audio: Includes a high-performance audio mixer.
    • Graphics API: Easy-to-use interfaces for sprites and tiled backgrounds.
    • Memory Management: Provides a global allocator that enables the use of both core and alloc crates.
  2. Overview of AGB features

    master

    AGB is a Rust library designed for Game Boy Advance development. It provides high-level abstractions to leverage GBA hardware without requiring deep low-level knowledge.

    Key features include:

    • Simple build process with minimal dependencies.
    • Built-in asset importing for sprites, backgrounds, music, and sound effects.
    • High-performance audio via an audio mixer and an optional tracker supporting .xm files.
    • Graphics abstractions for easy use of sprites and tiled backgrounds.
    • Memory management via a global allocator that supports both core and alloc crates.
  3. How backgrounds work on GBA

    master

    Backgrounds are layers made of 8x8 tiles. The GBA supports up to 4 different background layers, which can be stacked to create parallax effects or HUDs (Heads Up Displays).

    There are two main types of backgrounds:

    1. Regular backgrounds: These use fixed tile modes.
    2. Affine backgrounds: These support transformations (scrolling/scaling).

    Regular backgrounds support two color modes:

    • 16-colour mode (4 bits per pixel): Each tile uses a single 16-colour palette. This uses half the video RAM and cartridge space compared to 256-colour mode. Most games use this for efficiency.
    • 256-colour mode (8 bits per pixel): Each tile can use any one of the 256 colours in the palette.
  4. How bit-packing works for level maps

    master

    To save space, boolean properties (like colliding or win) are packed into bit-arrays where 8 tiles are represented by a single u8.

    In the implementation, this is achieved by iterating through chunks of 8 tiles and using a fold operation. For each bit, the existing bits are shifted right by one position (a >> 1) and the new bit is placed in the most significant position (b << 7).

    As a result:

    • Bit 0 of the byte corresponds to the first tile in the chunk.
    • Bit 1 corresponds to the second tile, and so on.
    • Bit 7 corresponds to the eighth tile.
  5. How DMA effects work in AGB

    master

    DMA (Direct Memory Access) effects exploit the Game Boy Advance's rendering process, which draws the screen one row at a time. During the brief period between rows (known as HBlank), DMA can be used to change hardware values (like scroll positions or palette colors) just before the next line is rendered.

    In agb, you can apply a single DMA effect per frame. To identify which properties can be controlled via DMA, look for methods that return a DmaControllable type.

    Warning: DMA replaces the value stored in the target location with its own value. Any values you set manually during the frame for that specific property will be overwritten by the DMA effect.

  6. How blending works in AGB

    master

    Blending allows you to apply post-process effects like transparency or screen fading. There are two critical constraints to remember:

    1. Global Property: Blending is a single global property. You can only apply one blending style at a time; calling a new .blend().<style>() method overwrites the previous one. All objects/backgrounds using that effect will share the same level of intensity.
    2. Layer-based: Blending occurs between layers. For objects to participate in blending, their GraphicsMode must be set to AlphaBlending.

    Changes to blending are only applied to the screen when frame.commit() is called.

  7. How sprites and vblank work in AGB

    master

    The Game Boy Advance uses hardware sprites to draw objects on the screen efficiently. Unlike backgrounds, which are tile-based, sprites can be various sizes (e.g., 8x8 to 8x32).

    To prevent visual artifacts like 'tearing' (where an object is drawn while the screen is mid-refresh), agb utilizes the vertical blanking interval (vblank). The frame.commit() method automatically waits for this vblank period before rendering. This synchronization ensures that sprite position updates are atomic relative to the screen refresh and also allows the CPU to enter a low-power state automatically, replacing the need for manual agb::halt() calls.

  8. Explore AGB ecosystem and related libraries

    master

    Several libraries are designed to work alongside agb to extend its functionality:

    • embassy-agb: Enables the use of Async Rust on the Game Boy Advance.
    • gba_rumble: Provides support for the rumble feature of the Game Boy Player.
    • agb-fixnum: Provides fixed-point number storage for performant decimal math (since the GBA lacks an FPU).
    • agb-image-converter: Converts standard image formats into GBA-compatible formats.
    • agb-sound-converter: Converts .wav files into GBA-compatible formats.
  9. Understand the Game Boy Advance hardware capabilities

    master

    The Game Boy Advance (GBA) is a 32-bit handheld system powered by a 16.8MHz ARM CPU. It is fundamentally a 2D system with a Pixel Processing Unit (PPU) optimized for hardware-accelerated 2D graphics.

    Key hardware capabilities include:

    • Sprites: Up to 256 hardware sprites, ranging in size from 8x8 to 64x64 pixels.
    • Backgrounds: Up to 4 background layers (enabled/disabled based on graphics mode).
    • Tiles: Background layers use 8x8 pixel tiles when in tile mode.
    • Audio: 8-bit sound support, allowing for raw 8-bit audio data to be sent to speakers (optionally in stereo).

    While agb abstracts much of this hardware to simplify development, you can interact with these features directly for low-level control.

  10. Understand Game Boy Advance affine transformations

    master

    The Game Boy Advance supports affine transformations, which preserve lines and parallelism. These allow for effects like translation, scaling, rotation, and shearing.

    CRITICAL: Inverted Matrices Transformation matrices in the GBA are inverted. Instead of mapping object locations to screen locations, the GBA uses matrices to map screen locations to object locations.

    If you want to double the size of an object, you must use a matrix with 0.5 on the diagonal. If you use 2.0, the object will actually shrink to half its size. agb does not automatically invert matrices to avoid precision loss during fixed-point division, so you must account for this in your math.

  11. Choose a mixer frequency

    master

    The agb software mixer operates at a fixed frequency chosen when the mixer is initialized. You cannot change the frequency without dropping the mixer. Higher frequencies improve audio quality but increase CPU usage.

    FrequencyAudio qualityApprox. CPU usage (4 channels)
    Frequency::Hz10512Poor~5% per frame
    Frequency::Hz18157Low~10% per frame
    Frequency::Hz32768Medium~20% per frame

    Note: Ensure your .wav files are resampled to your chosen frequency before loading, as agb does not resample them automatically.

    use agb::sound::mixer::Frequency;
    
    let mut mixer = gba.mixer.mixer(Frequency::Hz18157);
  12. Understand the `agb-save` file format structure

    master

    The agb-save format is a block-based storage system designed for corruption resistance and multiple save slots. Data is organized into dynamic-sized blocks. Each block starts with a standard header, followed by a payload that varies based on the block type.

    Block Header Layout:

    OffsetSizeField
    02CRC16 covering bytes 2..end of block
    22Block type
    42Next block index (0 = end / none)
    62Reserved (zeros)
    8block_size - 8payload

    Block Types:

    • 0: Free / unused
    • 1: Global header
    • 2: Slot header
    • 3: Data block