Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/exelotl/trick
Library for GBA/NDS image conversion, and more!
https://github.com/exelotl/trick
gameboy-advance gba nim
Last synced: 24 days ago
JSON representation
Library for GBA/NDS image conversion, and more!
- Host: GitHub
- URL: https://github.com/exelotl/trick
- Owner: exelotl
- License: zlib
- Created: 2020-04-21T00:11:47.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2024-05-24T14:00:25.000Z (6 months ago)
- Last Synced: 2024-08-04T03:07:35.808Z (3 months ago)
- Topics: gameboy-advance, gba, nim
- Language: Nim
- Homepage: https://exelotl.github.io/trick/trick.html
- Size: 175 KB
- Stars: 29
- Watchers: 3
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
Awesome Lists containing this project
- awesome-nim - trick - Library for GBA/NDS image conversion, and more! (User Interface / Design)
README
## Trick ;)
- [API Documentation](https://exelotl.github.io/trick/trick.html)
Trick is a library for GBA and NDS asset conversion in Nim.
It is used by the [Natu](https://github.com/exelotl/natu) project tool, providing an easy way to put images & maps into your GBA games.
It was also used for the [PP20th translation](https://www.romhacking.net/translations/4522/) project, thus is able to convert binary data back to PNG in some cases.
## Features
- Sprite Graphics
- Convert PNG images to raw GBA image data, and vice-versa
- Supported formats: 2 / 4 / 8 bpp paletted images using 15-bit BGR color, with bitmap or tile arrangement
- Backgrounds / Tilemaps
- Convert PNG images to a map + tileset + palette.
- Tileset reduction: identify & remove duplicate tiles, including flipped versions
- Rearrange maps into screenblocks
- Palette Reduction
- Given a list of palettes, attempt to merge them into the least number of 16-color palettes necessary. This doesn't produce optimal results, but may be good enough for some projects.
- Data Utils
- Facilities to reinterpret data as an array of some known type, without copying
- Convert raw bytes to C strings (a utility borrowed from the Nim compiler)
- Name helpers: filename to identifier, snake_case to camelCase## Overview
Trick is intended to allow you to make your own command-line tools to wrangle assets for your homebrew projects.
### Installation
```
$ nimble install trick
```## Examples
These examples use hardcoded settings and paths, but in practise you'll want to be looping over directories, reading from config files, etc.
### PNG to binary
Convert your sprite sheets into raw binary formats used by GBA/NDS games:
```nim
import trickvar conf = GfxInfo(
pal: @[clrEmpty], # initial palette
bpp: gfx4bpp, # bit depth
layout: gfxTiles, # arrange into 8x8 tiles
)# do the conversion
# `data` is now a string containing raw pixel data
# `conf.pal` will be populated with all the colors in the image
let data = pngToBin("mario.png", conf, buildPal=true)# output to files
writeFile("mario.img.bin", data)
writePal("mario.pal.bin", conf.pal)
```### Binary to PNG
The inverse of the above process. This may be useful for rom hacking, validation etc.
```nim
let conf = GfxInfo(
pal: readPal("mario.pal.bin"),
bpp: gfx4bpp, # bit depth
layout: gfxTiles, # unscramble from tile arrangement
)
let data = readFile("mario.img.bin")
let png = binToPng(data, conf)
writeFile("mario_out.png", png)
```### PNG to tileset + tilemap + palettes
The typical use case here is to take an image of your whole level and transform it into a tile map. Under the hood this involves both tileset reduction and palette reduction.
```nim
let bg4 = loadBg4("brinstar.png")
writeFile("brinstar.map.bin", toBytes(bg4.map))
writeFile("brinstar.img.bin", toBytes(bg4.img))
writeFile("brinstar.pal.bin", toBytes(joinPalettes(bg4.pals)))
```### Data to C
While the above examples use `.bin` files, the preferred way to embed read-only data in your Nim GBA games is by using extenal C files.
Example:
```nim
let data = readFile("mario.img.bin")# convert binary data to a C string literal
let imgStringLit = makeCString(data)# output C source code
writeFile("source/gfxdata.c", fmt"""
const char *marioImg = {imgStringLit};
""")# output Nim source code
writeFile("source/gfxdata.nim", fmt"""
{{.compile: "gfxdata.c".}}
var marioImg* {{.importc, extern:"marioImg", codegenDecl:"extern const $# $#".}}: array[{data.len}, uint8]
""")
```To explain the generated Nim code: the [`{.compile.}`][1] pragma ensures that `gfxdata.c` is compiled and linked into the final ROM. The [`{.importc.}`][2] and [`{.extern.}`][3] pragmas are used to make the C variable accessible to Nim. [`{.codegenDecl.}`][4] is just to help avoid compiler warnings.
It's worth mentioning that this Nim code *could* be written by hand, but I recommend this approach to maintain integrity between the assets and the game code. It will also save a lot of work once you modify your tool to support multiple images, by using a config file or by processing all images in a certain folder, etc.
[1]: https://nim-lang.org/docs/manual.html#implementation-specific-pragmas-compile-pragma
[2]: https://nim-lang.org/docs/manual.html#foreign-function-interface-importc-pragma
[3]: https://nim-lang.org/docs/manual.html#foreign-function-interface-extern-pragma
[4]: https://nim-lang.org/docs/manual.html#implementation-specific-pragmas-codegendecl-pragmaExample of using data in your game code:
```nim
import natu, gfxdata# copy the image data into VRAM
memcpy32(addr tileMemObj[0], addr marioImg, marioImg.len div sizeof(uint32))
```---
## Todo
- Fonts (currently the only way to produce [TTE](https://www.coranac.com/tonc/text/tte.htm) compatible fonts is [Usenti](http://www.coranac.com/projects/usenti/))
- ASM output?
- Ability to convert backgrounds/tilemaps back into PNG
- More graphic formats (in particular, NDS 3D texture formats with alpha bits have been implemented by [MyLegGuy](https://github.com/MyLegGuy) for PP20th, but I've yet to merge this code)
- Metatiles?