96 lines
4 KiB
C
96 lines
4 KiB
C
// Tiles: 8x8 pixel blocks aligned on the 8-pixel grid of any surface.
|
|
//
|
|
// A "tile" in JoeyLib isn't a separate object -- it's just the 8x8
|
|
// region of a SurfaceT at block coordinates (bx, by), where bx is in
|
|
// [0, 39] and by is in [0, 24] (40x25 blocks per 320x200 surface).
|
|
// The tile API is a small set of operations that move 32-byte chunks
|
|
// between surfaces or fill them with a solid color.
|
|
//
|
|
// Why this shape: anything you can do with a regular surface --
|
|
// drawPixel, drawLine, fillRect, blits -- also works on tile-aligned
|
|
// regions, so authors can paint, edit, and procedurally generate tile
|
|
// content using the same primitives they use for everything else.
|
|
// "Fonts," "terrain tilesets," and "spritesheets" are just surfaces
|
|
// you treat as tile sources at draw time.
|
|
//
|
|
// Snap / paste use a small TileT value type so callers don't need a
|
|
// 32 KB scratch surface for save-under-style work.
|
|
//
|
|
// Block coords map to pixels by multiplying by 8 -- byte-aligned in
|
|
// 4bpp packed (8 px = 4 bytes per row), so all the operations are
|
|
// byte-shoveling memcpys with no shifting.
|
|
|
|
#ifndef JOEYLIB_TILE_H
|
|
#define JOEYLIB_TILE_H
|
|
|
|
#include "platform.h"
|
|
#include "surface.h"
|
|
#include "types.h"
|
|
|
|
// ----- Constants -----
|
|
|
|
#define TILE_PIXELS_PER_SIDE 8
|
|
#define TILE_BYTES_PER_ROW 4
|
|
#define TILE_BYTES (TILE_BYTES_PER_ROW * TILE_PIXELS_PER_SIDE)
|
|
#define TILE_BLOCKS_PER_ROW (SURFACE_WIDTH / TILE_PIXELS_PER_SIDE)
|
|
#define TILE_BLOCKS_PER_COL (SURFACE_HEIGHT / TILE_PIXELS_PER_SIDE)
|
|
|
|
// Sentinel for asciiMap entries that should not draw. drawText
|
|
// advances the cursor past TILE_NO_GLYPH chars without writing.
|
|
#define TILE_NO_GLYPH ((uint16_t)0xFFFFu)
|
|
|
|
// ----- Types -----
|
|
|
|
// Stack-allocated 32-byte snapshot buffer for tileSnap / tilePaste.
|
|
typedef struct TileT {
|
|
uint8_t pixels[TILE_BYTES];
|
|
} TileT;
|
|
|
|
// ----- API -----
|
|
|
|
// Copy the 8x8 block at (srcBx, srcBy) on src to (dstBx, dstBy) on
|
|
// dst, opaque. Out-of-range block coordinates on either side are
|
|
// silent no-ops; src and dst can be the same surface.
|
|
void tileCopy(SurfaceT *dst, uint8_t dstBx, uint8_t dstBy,
|
|
const SurfaceT *src, uint8_t srcBx, uint8_t srcBy);
|
|
|
|
// Like tileCopy but pixels equal to transparentIndex are skipped --
|
|
// the destination pixel keeps its original value. Use this for fonts
|
|
// (transparentIndex = 0 leaves the page background showing through
|
|
// glyph backgrounds) and for any tileset where some pixels are meant
|
|
// to be see-through.
|
|
void tileCopyMasked(SurfaceT *dst, uint8_t dstBx, uint8_t dstBy,
|
|
const SurfaceT *src, uint8_t srcBx, uint8_t srcBy,
|
|
uint8_t transparentIndex);
|
|
|
|
// Fill the 8x8 block at (bx, by) with a solid color. Equivalent to
|
|
// fillRect(s, bx*8, by*8, 8, 8, colorIndex) but skips the rect
|
|
// clipping math since tile coords are already known to be in range.
|
|
void tileFill(SurfaceT *s, uint8_t bx, uint8_t by, uint8_t colorIndex);
|
|
|
|
// Capture the 8x8 block at (bx, by) into the caller's TileT. Used
|
|
// for save-under style work where allocating a scratch surface would
|
|
// be overkill.
|
|
void tileSnap(const SurfaceT *src, uint8_t bx, uint8_t by, TileT *out);
|
|
|
|
// Paste a TileT back onto a surface at block (bx, by). Always
|
|
// opaque; use tileCopyMasked if you need transparency.
|
|
void tilePaste(SurfaceT *dst, uint8_t bx, uint8_t by, const TileT *in);
|
|
|
|
// Draw a NUL-terminated ASCII string at block (bx, by) using glyphs
|
|
// pulled from fontSurface.
|
|
//
|
|
// asciiMap is a 256-entry table mapping ASCII code to glyph location
|
|
// on fontSurface, encoded as a packed uint16_t: low byte = source
|
|
// blockX, high byte = source blockY. asciiMap[c] == TILE_NO_GLYPH
|
|
// causes that character to be skipped (cursor advances, nothing
|
|
// drawn). Glyph color 0 is treated as transparent so the underlying
|
|
// surface shows through glyph backgrounds.
|
|
//
|
|
// The cursor wraps to the next row at the right edge and truncates
|
|
// at the bottom edge.
|
|
void drawText(SurfaceT *dst, uint8_t bx, uint8_t by,
|
|
const SurfaceT *fontSurface, const uint16_t *asciiMap,
|
|
const char *str);
|
|
|
|
#endif
|