graphics ******** This module allows working with "graphic" assets, which are spritesheets converted to the GBA's pixel format with an accompanying palette and metadata, stored in ROM. ----------------------------- Tutorial ======== To add a new graphic asset to your game: 1. Export a spritesheet as a *vertical strip*. For example, this is a spritesheet for a 32x32 graphic with 8 frames: .. image:: media/dog.png Save it to `graphics/dog.png`. 2. Add a line to your project's `graphics.nims` file: .. code-block:: nim # ... graphic "dog.png", s32x32 # A handle called gfxDog will be created 3. Import `natu/graphics` in your game and start using the asset: .. code-block:: nim import natu/[video, graphics] # Init # ---- var dog = initObj( pos = vec2i(100, 50), tileId = allocObjTiles(gfxDog), # Allocate tiles for a single frame of animation. palId = acquireObjPal(gfxDog), # Obtain palette. size = gfxDog.size, # Set to correct size. ) # During vblank # ------------- # Copy a frame of animation into VRAM. copyFrame(addr objTileMem[dog.tileId], gfxDog, frame = 0) # Copy the object into OAM. objMem[0] = dog # Clean up # -------- freeObjTiles(obj.tileId) releaseObjPal(gfxDog) ----------------------------- Configuration ============= The `graphics.nims` config file is used to add new graphics to your project. This is a `nimscript `_ file executed in a local scope in your project's `config.nims` before compiling the game. The following operations are available: .. nim:proc:: graphic(name: string, size: ObjSize, bpp = 4, strictPal = false) Specify an image to be added to the graphics list, converted and embedded in the ROM. If the image is an *indexed* PNG then the palette will be preserved exactly, except duplicate colours will be removed (use `strictPal=true` to avoid this behaviour). Otherwise, if the image is a *true-color* PNG then the palette will be derived from the image in the order the colours appear. :name: Path to a .png file, relative to the current working directory. :size: Specifies the dimensions that sprites using this graphic should have. .. note:: The provided spritesheet must be a vertical strip. i.e. its width equal to the given width, and its height a *multiple* of the given height. :bpp: The desired bits-per-pixel that the graphic should be converted to. Possible values are: .. container:: * `2` -- The image can have up to 4 colours (including transparent). This may be handy if you're tight on ROM space, but note that the GBA hardware doesn't actually support 2bpp graphics. You could use :xref:`BitUnPack` to load the data into VRAM. * `4` (default) -- The image can have up to 16 colours (including transparent). * `8` -- The image can have up to 256 colors (including transparent). :strictPal: For use with indexed PNGs. Any duplicate colours in the palette will *not* be reduced into a single index. If the graphic is part of a `sharePal` block, then any colours which already exist in the shared palette at this point *must* appear in the same order in this image. .. nim:template:: sharePal(body: untyped) This can be used to define a group of graphics which all share the same palette data. **Example:** .. code-block:: nim cd "graphics" sharePal: # These two graphics use the same palette: graphic "dog.png", s32x32 graphic "hamster.png", s16x16 # But this one has its own palette. graphic "cat.png", s32x32 ----------------------------- Types ===== .. .. autonim:: graphics.GraphicData .. nim:type:: Graphic = enum Enum type representing spritesheets in ROM. This type is generated based on the contents of your project's *graphics.nims* file. Each image gets a corresponding enum value based on its filename, for example, `dog.png` becomes `gfxDog`. For each item, the following read-only properties are available: .. autonim:: graphics.width .. autonim:: graphics.height .. autonim:: graphics.size .. autonim:: graphics.bpp .. autonim:: graphics.frameTiles .. autonim:: graphics.allTiles .. autonim:: graphics.numFrames .. tip:: Since most `Graphic` metadata is known at compile-time and accessed via templates, it's slightly more efficient to work with constant graphics rather than variables. For example, this: .. code-block:: nim const g = gfxDog acquireObjPal(g) is preferable to: .. code-block:: nim var g = gfxDog acquireObjPal(g) The latter is of course necessary if you want to change graphics at runtime, or make a general-purpose type which can display any graphic. Loading Data Directly ===================== .. autonim:: graphics.copyPal .. autonim:: graphics.copyPal_2 .. autonim:: graphics.copyFrame .. autonim:: graphics.copyAllFrames Utilities ========= .. autonim:: graphics.onscreen .. autonim:: graphics.onscreen_2 Palette Management ================== .. autonim:: graphics.acquireObjPal .. autonim:: graphics.releaseObjPal .. autonim:: graphics.getPalId .. autonim:: graphics.loadPal Obj PAL RAM Allocator --------------------- These procedures let you allocate & free palettes for sprites. .. note:: If you are trying to load a palette from a :xref:`Graphic` you should use :xref:`acquireObjPal` and :xref:`releaseObjPal` instead of these. .. autonim:: kit.pal_manager.allocObjPal .. autonim:: kit.pal_manager.freeObjPal Palette Buffers --------------- These are targeted by gfx and bg operations such as `acquireObjPal` and `bg.loadPal`, or you can write directly to them. Be sure to call `flushPals` during VBlank to update the real palettes. Or you can use :xref:`clrFadeFast` from the `video` module to blend in a certain colour while copying. .. autonim:: kit.pal_manager.bgPalBuf .. autonim:: kit.pal_manager.objPalBuf .. autonim:: kit.pal_manager.bgColorBuf .. autonim:: kit.pal_manager.objColorBuf .. autonim:: kit.pal_manager.flushPals Tile Management =============== .. autonim:: graphics.allocObjTiles .. autonim:: kit.obj_tile_manager.allocObjTiles .. autonim:: kit.obj_tile_manager.freeObjTiles