231 lines
5.9 KiB
Text
231 lines
5.9 KiB
Text
== Drawing Primitives
|
|
|
|
Declared in `<joey/draw.h>`.
|
|
|
|
All primitives clip to the surface rectangle. Out-of-bounds draws are silent
|
|
no-ops, never errors, and there are no unclipped variants in the public API --
|
|
you cannot corrupt memory by drawing off the edge. Every primitive marks the
|
|
rows it touched, so `jlStagePresent` knows what to copy.
|
|
|
|
Primitives work in color indices, and use only the low 4 bits of one.
|
|
Per-scanline palette resolution happens only at display time, so drawing does
|
|
not care which palette a line uses.
|
|
|
|
=== jlSurfaceClear
|
|
|
|
[source,c]
|
|
----
|
|
void jlSurfaceClear(jlSurfaceT *s, uint8_t colorIndex);
|
|
----
|
|
|
|
Fills the whole surface with one color index. Clearing to color 0 is a
|
|
legitimate clear-to-black, not a skipped no-op.
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`s` |`jlSurfaceT *` |Target surface.
|
|
|`colorIndex` |`uint8_t` |Color index 0..15.
|
|
|===
|
|
|
|
*Returns:* nothing.
|
|
|
|
=== jlDrawPixel
|
|
|
|
[source,c]
|
|
----
|
|
void jlDrawPixel(jlSurfaceT *s, int16_t x, int16_t y, uint8_t colorIndex);
|
|
----
|
|
|
|
Plots one pixel. Off-surface coordinates are no-ops.
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`s` |`jlSurfaceT *` |Target surface.
|
|
|`x`, `y` |`int16_t` |Position. Valid range is 0..319 and 0..199.
|
|
|`colorIndex` |`uint8_t` |Color index 0..15.
|
|
|===
|
|
|
|
*Returns:* nothing.
|
|
|
|
=== jlSamplePixel
|
|
|
|
[source,c]
|
|
----
|
|
uint8_t jlSamplePixel(const jlSurfaceT *s, int16_t x, int16_t y);
|
|
----
|
|
|
|
Reads one pixel.
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`s` |`const jlSurfaceT *` |Source surface.
|
|
|`x`, `y` |`int16_t` |Position.
|
|
|===
|
|
|
|
*Returns:* the color index at that position, or 0 for an off-surface read.
|
|
|
|
=== jlDrawLine
|
|
|
|
[source,c]
|
|
----
|
|
void jlDrawLine(jlSurfaceT *s, int16_t x0, int16_t y0,
|
|
int16_t x1, int16_t y1, uint8_t colorIndex);
|
|
----
|
|
|
|
Draws a Bresenham line. Both endpoints are inclusive. Off-surface pixels are
|
|
skipped individually, so a line that crosses the edge draws its visible part; a
|
|
line entirely off-surface draws nothing. Horizontal and vertical runs take fast
|
|
paths.
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`s` |`jlSurfaceT *` |Target surface.
|
|
|`x0`, `y0` |`int16_t` |Start point, inclusive.
|
|
|`x1`, `y1` |`int16_t` |End point, inclusive.
|
|
|`colorIndex` |`uint8_t` |Color index 0..15.
|
|
|===
|
|
|
|
*Returns:* nothing.
|
|
|
|
=== jlDrawRect
|
|
|
|
[source,c]
|
|
----
|
|
void jlDrawRect(jlSurfaceT *s, int16_t x, int16_t y,
|
|
uint16_t w, uint16_t h, uint8_t colorIndex);
|
|
----
|
|
|
|
Draws a one-pixel-wide rectangle outline. A 1xN or Nx1 rectangle degenerates to
|
|
a line, and 1x1 to a single pixel. Zero dimensions are no-ops.
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`s` |`jlSurfaceT *` |Target surface.
|
|
|`x`, `y` |`int16_t` |Top-left corner.
|
|
|`w`, `h` |`uint16_t` |Size in pixels. Zero is a no-op.
|
|
|`colorIndex` |`uint8_t` |Color index 0..15.
|
|
|===
|
|
|
|
*Returns:* nothing.
|
|
|
|
=== jlFillRect
|
|
|
|
[source,c]
|
|
----
|
|
void jlFillRect(jlSurfaceT *s, int16_t x, int16_t y,
|
|
uint16_t w, uint16_t h, uint8_t colorIndex);
|
|
----
|
|
|
|
Fills a solid rectangle. Zero dimensions are no-ops.
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`s` |`jlSurfaceT *` |Target surface.
|
|
|`x`, `y` |`int16_t` |Top-left corner.
|
|
|`w`, `h` |`uint16_t` |Size in pixels.
|
|
|`colorIndex` |`uint8_t` |Color index 0..15.
|
|
|===
|
|
|
|
*Returns:* nothing.
|
|
|
|
=== jlDrawCircle
|
|
|
|
[source,c]
|
|
----
|
|
void jlDrawCircle(jlSurfaceT *s, int16_t cx, int16_t cy,
|
|
uint16_t r, uint8_t colorIndex);
|
|
----
|
|
|
|
Draws a circle outline using the Bresenham midpoint algorithm. A radius of 0
|
|
plots a single pixel.
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`s` |`jlSurfaceT *` |Target surface.
|
|
|`cx`, `cy` |`int16_t` |Center.
|
|
|`r` |`uint16_t` |Radius in pixels.
|
|
|`colorIndex` |`uint8_t` |Color index 0..15.
|
|
|===
|
|
|
|
*Returns:* nothing.
|
|
|
|
=== jlFillCircle
|
|
|
|
[source,c]
|
|
----
|
|
void jlFillCircle(jlSurfaceT *s, int16_t cx, int16_t cy,
|
|
uint16_t r, uint8_t colorIndex);
|
|
----
|
|
|
|
Fills a disk, emitting one span per scanline using midpoint symmetry. A radius
|
|
of 0 plots a single pixel.
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`s` |`jlSurfaceT *` |Target surface.
|
|
|`cx`, `cy` |`int16_t` |Center.
|
|
|`r` |`uint16_t` |Radius in pixels.
|
|
|`colorIndex` |`uint8_t` |Color index 0..15.
|
|
|===
|
|
|
|
*Returns:* nothing.
|
|
|
|
=== jlFloodFill
|
|
|
|
[source,c]
|
|
----
|
|
void jlFloodFill(jlSurfaceT *s, int16_t x, int16_t y, uint8_t newColor);
|
|
----
|
|
|
|
Flood-fills a 4-connected region, replacing every pixel of the original color
|
|
reachable by north, south, east, and west steps. A no-op if the start point is
|
|
off-surface or already `newColor`. The fill keeps a 512-entry stack of spans
|
|
still to visit, and a region complex enough to need more is left partly
|
|
filled, the same way on every port.
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`s` |`jlSurfaceT *` |Target surface.
|
|
|`x`, `y` |`int16_t` |Seed point.
|
|
|`newColor` |`uint8_t` |Replacement color index.
|
|
|===
|
|
|
|
*Returns:* nothing.
|
|
|
|
=== jlFloodFillBounded
|
|
|
|
[source,c]
|
|
----
|
|
void jlFloodFillBounded(jlSurfaceT *s, int16_t x, int16_t y,
|
|
uint8_t newColor, uint8_t boundaryColor);
|
|
----
|
|
|
|
Flood-fills a 4-connected region, stopping at pixels of `boundaryColor` rather
|
|
than at pixels differing from the seed color. Every reachable pixel that is
|
|
not the boundary color becomes `newColor`. Pixels that are `newColor` already
|
|
stop the fill too, so a region behind them is not reached, and a start on
|
|
either color does nothing. The 512-entry span stack of `jlFloodFill` applies.
|
|
|
|
This is the primitive for vector-art playback, such as Sierra-style picture
|
|
drawing: outline a closed region with `jlDrawLine` in the boundary color, then
|
|
fill it with this.
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`s` |`jlSurfaceT *` |Target surface.
|
|
|`x`, `y` |`int16_t` |Seed point.
|
|
|`newColor` |`uint8_t` |Replacement color index.
|
|
|`boundaryColor` |`uint8_t` |Color that stops the fill.
|
|
|===
|
|
|
|
*Returns:* nothing.
|