84 lines
3.2 KiB
C
84 lines
3.2 KiB
C
// nooncraft.render: Grid-like text rendering
|
|
//
|
|
// Owing to the CPC constraint, the entire rendering system for this game is
|
|
// just text with a single font. We make two adjustments on the grid model:
|
|
//
|
|
// 1. We group rows and columns by pairs, so that the row/column spacing
|
|
// alternates between 1 and 3. This allows blocks to be represented by
|
|
// "clusters" of 4 characters.
|
|
// 2. To keep text natural, we provide a text function which forces column
|
|
// spacing to 2, offsetting every other character by 1 pixel. Rows remain
|
|
// irregularly spaced.
|
|
//---
|
|
|
|
#pragma once
|
|
|
|
using Glyph = char;
|
|
|
|
/* Non-ASCII glyphs */
|
|
enum {
|
|
GLYPH_FOUR_DOT = 1, /* U+2058 FOUR DOT PUNCTUATION */
|
|
GLYPH_MIDDLE_DOT = 2, /* U+00B7 MIDDLE DOT */
|
|
GLYPH_PARALLEL_TO = 3, /* U+2225 PARALLEL TO */
|
|
GLYPH_CURRENCY_SIGN = 4, /* U+00A4 CURRENCY SIGN */
|
|
GLYPH_NORTH_EAST_ARROW = 5, /* U+2197 NORTH EAST ARROW */
|
|
GLYPH_RIGHT_GUILLEMET = 6, /* U+00BB RIGHT GUILLEMET */
|
|
GLYPH_DOWN_ARROW = 7, /* U+2193 DOWNARDS ARROW */
|
|
GLYPH_I_CIRCUMFLEX = 8, /* U+00EE SMALL LATIN I WITH CIRCUMFLEX */
|
|
GLYPH_INTEGRAL = 9, /* U+222B INTEGRAL */
|
|
GLYPH_SMALL_SQUARE = 10, /* U+25AB WHITE SMALL SQUARE */
|
|
GLYPH_STAR = 11, /* U+2605 BLACK STAR */
|
|
GLYPH_CIRCLE = 12, /* U+25CF BLACK CIRCLE */
|
|
GLYPH_UP_ARROW_BAR = 13, /* U+21A5 UPWARDS ARROW FROM BAR */
|
|
GLYPH_CAPITAL_LAMBDA = 14, /* U+039B GREEK CAPITAL LETTER LAMBDA */
|
|
GLYPH_DEGREE_UNDERLINE = 15, /* U+00B0 U+0331 */
|
|
GLYPH_OPLUS = 16, /* U+2295 CIRCLED PLUS */
|
|
};
|
|
|
|
/* A cluster of 4 glyphs. Can be conversion-constructed from a multi-byte
|
|
character literal like 'AXE '. */
|
|
struct GlyphCluster
|
|
{
|
|
GlyphCluster(): glyphs {0,0,0,0} {}
|
|
|
|
GlyphCluster(Glyph g1, Glyph g2, Glyph g3, Glyph g4):
|
|
glyphs {g1, g2, g3, g4} {}
|
|
|
|
GlyphCluster(int mbliteral) {
|
|
this->glyphs[0] = mbliteral >> 24;
|
|
this->glyphs[1] = (mbliteral >> 16) & 0xff;
|
|
this->glyphs[2] = (mbliteral >> 8) & 0xff;
|
|
this->glyphs[3] = mbliteral & 0xff;
|
|
}
|
|
|
|
GlyphCluster applyOver(GlyphCluster const &other) {
|
|
return GlyphCluster(
|
|
this->glyphs[0] ? this->glyphs[0] : other.glyphs[0],
|
|
this->glyphs[1] ? this->glyphs[1] : other.glyphs[1],
|
|
this->glyphs[2] ? this->glyphs[2] : other.glyphs[2],
|
|
this->glyphs[3] ? this->glyphs[3] : other.glyphs[3]);
|
|
}
|
|
|
|
Glyph glyphs[4];
|
|
};
|
|
|
|
/* Enable or disable night mode (black-on-white). */
|
|
void renderSetNight(bool night);
|
|
/* Clear the screen. */
|
|
void renderClear(void);
|
|
/* Update the screen. */
|
|
void renderUpdate(void);
|
|
|
|
/* Render a single character with text alignment (2-pixel column spacing).
|
|
The position (x,y) is counted in characters units with (0,0) top-left. */
|
|
void renderGlyph(int x, int y, Glyph g);
|
|
|
|
/* Render a 2x2 cluster of 4 characters. The position (x,y) should be even on
|
|
both axes. */
|
|
void renderCluster(int x, int y, GlyphCluster c);
|
|
|
|
/* Render a string with text alignment. */
|
|
void renderText(int x, int y, char const *text);
|
|
/* Same with printf() formatting. */
|
|
void renderFormat(int x, int y, char const *fmt, ...);
|