> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/pret/pokeemerald/llms.txt
> Use this file to discover all available pages before exploring further.

# Graphics and Audio

> GBA graphics pipeline, sprites, tilesets, and M4A audio.

pokeemerald targets the GBA's 2D tile engine and the M4A (mp2k/Sappy) audio driver. Understanding how both pipelines work is essential when adding or modifying visual and sound assets.

## GBA graphics overview

The GBA renders graphics using 8×8 pixel tiles stored in VRAM. Each tile uses either 4 bits per pixel (16-color palette) or 8 bits per pixel (256-color palette). The hardware composites up to four background layers and 128 sprites per frame.

<Info>
  All source artwork must be indexed-color PNG files. The `tools/gbagfx` tool converts them to the packed tile formats the GBA hardware expects.
</Info>

## Sprite sheets

Sprite sheets live under `graphics/` as indexed PNG files. The Makefile converts them automatically using rules defined in `graphics_file_rules.mk` and `spritesheet_rules.mk`.

<Steps>
  <Step title="Create or edit the PNG">
    Export a power-of-two indexed PNG from your image editor. Ensure the color count matches the target palette depth (16 or 256 colors).
  </Step>

  <Step title="Check the conversion rule">
    Open `graphics_file_rules.mk` or `spritesheet_rules.mk` to verify the rule for your target file. Rules look like:

    ```bash theme={null}
    $(POKEEMERALD_GFX)/sprites/%.4bpp: $(POKEEMERALD_GRAPHICS)/sprites/%.png
        $(GBAGFX) $< $@
    ```
  </Step>

  <Step title="Run make">
    ```bash theme={null}
    make
    ```

    `tools/gbagfx` will convert the PNG to the appropriate 4bpp or 8bpp tile format.
  </Step>
</Steps>

## Tilesets

Each map uses two tilesets: a **primary** tileset shared across a region and a **secondary** tileset specific to an area. Tileset definitions are in `data/tilesets/`.

<AccordionGroup>
  <Accordion title="Primary tileset">
    Contains tiles common to an entire region (e.g. grass, water, paths). Loaded once when entering a region and shared by all maps using the same primary.
  </Accordion>

  <Accordion title="Secondary tileset">
    Contains tiles unique to a specific map or area. Loaded in addition to the primary tileset when a map is entered.
  </Accordion>
</AccordionGroup>

Map layout data is stored as JSON and processed by `tools/jsonproc` via rules in `json_data_rules.mk`. The resulting binary is assembled into the ROM.

## Build tools — graphics

<CardGroup cols={2}>
  <Card title="gbagfx" icon="image">
    Converts indexed PNG files to GBA 4bpp/8bpp tile format and back. The primary graphics conversion tool for all sprites and tilesets.
  </Card>

  <Card title="rsfont" icon="type">
    Processes font files used by the game's text engine. Converts font sheets to the internal format.
  </Card>

  <Card title="bin2c" icon="file-code">
    Converts arbitrary binary files into C byte arrays for embedding data directly in source.
  </Card>

  <Card title="jsonproc" icon="braces">
    Processes JSON map layout data (from porymap or hand-edited files) into binary data assembled into the ROM.
  </Card>
</CardGroup>

### gbagfx usage

```bash theme={null}
# PNG → 4bpp GBA tiles
tools/gbagfx input.png output.4bpp

# PNG → 8bpp GBA tiles
tools/gbagfx input.png output.8bpp

# Extract palette from PNG
tools/gbagfx input.png output.pal
```

## M4A audio engine

The M4A engine (also called mp2k or Sappy) is the standard GBA audio driver used in nearly all first-party GBA titles. pokeemerald's implementation lives in:

| File               | Role                                              |
| ------------------ | ------------------------------------------------- |
| `src/m4a.c`        | Main driver: mixer, channel management, sequencer |
| `src/m4a_tables.c` | Lookup tables (frequency, volume, envelope)       |
| `src/m4a_1.s`      | ARM assembly mixer core                           |
| `src/sound.c`      | Game-level sound API (`PlaySE`, `PlayBGM`, etc.)  |

## Song data pipeline

<Steps>
  <Step title="Write or obtain a MIDI file">
    MIDI source files live in `sound/songs/midi/`. Compose or edit using any standard MIDI sequencer. The M4A sequencer supports a subset of MIDI events.
  </Step>

  <Step title="Convert MIDI to AGB format">
    ```bash theme={null}
    tools/mid2agb input.mid output.s
    ```

    This produces an ARM assembly file with the song's event sequence.
  </Step>

  <Step title="Convert WAV samples">
    Instrument samples are stored as GBA-compatible PCM. Convert a WAV file with:

    ```bash theme={null}
    tools/wav2agb input.wav output.s
    ```
  </Step>

  <Step title="Register the song">
    Add the song constant to `include/constants/songs.h`:

    ```c theme={null}
    #define MUS_MY_NEW_SONG  (XXX)
    ```

    Then reference the assembled data in `data/sound_data.s`.
  </Step>
</Steps>

## Sound data assembly

`data/sound_data.s` is the central file that assembles all song and sample data into the ROM. It `#include`s the `.s` output files produced by `mid2agb` and `wav2agb`.

## Game-level sound API

`src/sound.c` exposes the functions used throughout the game:

| Function                          | Description                              |
| --------------------------------- | ---------------------------------------- |
| `PlayBGM(u16 songNum)`            | Start a background music track           |
| `PlaySE(u16 songNum)`             | Play a sound effect                      |
| `StopMapMusic(void)`              | Stop the current map BGM                 |
| `FadeOutBGM(u8 speed)`            | Fade out BGM over time                   |
| `FadeOutBGMTemporarily(u8 speed)` | Fade out BGM temporarily (resumes after) |

Song numbers are the constants defined in `include/constants/songs.h`.

<Warning>
  M4A uses a fixed number of mixing channels. Adding too many simultaneous sound effects will silently drop the lowest-priority channels. Keep SE channel counts in mind when composing.
</Warning>
