-
Notifications
You must be signed in to change notification settings - Fork 0
API Display and Graphics
Graphics and display functions. The display is 320×320 pixels with RGB565 color format.
Clears the entire framebuffer to the specified color.
-
Parameters:
-
color(number, optional): RGB565 color value. Defaults toBLACKif omitted.
-
- Returns: None
picocalc.display.clear(picocalc.display.BLACK)Sets a single pixel at the specified coordinates.
-
Parameters:
-
x(number): X coordinate (0-319) -
y(number): Y coordinate (0-319) -
color(number): RGB565 color value
-
- Returns: None
picocalc.display.setPixel(160, 160, picocalc.display.WHITE)Draws a filled rectangle.
-
Parameters:
-
x(number): Top-left X coordinate -
y(number): Top-left Y coordinate -
width(number): Rectangle width in pixels -
height(number): Rectangle height in pixels -
color(number): RGB565 color value
-
- Returns: None
picocalc.display.fillRect(10, 10, 50, 30, picocalc.display.RED)Draws a rectangle outline (1-pixel border).
-
Parameters:
-
x(number): Top-left X coordinate -
y(number): Top-left Y coordinate -
width(number): Rectangle width in pixels -
height(number): Rectangle height in pixels -
color(number): RGB565 color value
-
- Returns: None
picocalc.display.drawRect(10, 10, 100, 50, picocalc.display.BLUE)Draws a line between two points.
-
Parameters:
-
x0(number): Starting X coordinate -
y0(number): Starting Y coordinate -
x1(number): Ending X coordinate -
y1(number): Ending Y coordinate -
color(number): RGB565 color value
-
- Returns: None
picocalc.display.drawLine(0, 0, 319, 319, picocalc.display.GREEN)Draws text using the built-in 6×8 pixel bitmap font (ASCII 0x20–0x7E).
-
Parameters:
-
x(number): Top-left X coordinate -
y(number): Top-left Y coordinate -
text(string): Text to draw -
fg_color(number): Foreground RGB565 color -
bg_color(number or false, optional): Background RGB565 color. Defaults toBLACK. Passfalsefor a transparent background (glyph pixels only).
-
- Returns: (number) Pixel width of the drawn text
local width = picocalc.display.drawText(10, 10, "Hello!", picocalc.display.WHITE)
picocalc.display.drawText(10, 20, "Overlay", picocalc.display.WHITE, false) -- transparent bgCalculates the pixel width of text without drawing it.
-
Parameters:
-
text(string): Text to measure
-
- Returns: (number) Width in pixels
local width = picocalc.display.textWidth("Hello World")Flushes the internal framebuffer to the LCD via DMA. Call once per frame after all drawing is complete.
- Parameters: None
- Returns: None
picocalc.display.flush()Pushes rows y0–y1 (inclusive) of the current draw buffer to the LCD via non-blocking DMA, without swapping buffers. Rows are clamped to 0–319; the band always spans the full screen width.
Because there is no swap, subsequent drawing continues into the same buffer — ideal for repeatedly updating a small horizontal band (status bar, HUD, terminal line) while the rest of the screen keeps its last presented contents. Mixing flushRows with the normal double-buffered flush() cycle is the job of flushRegion() instead.
-
Parameters:
-
y0(number): First row (inclusive) -
y1(number): Last row (inclusive)
-
- Returns: None
-- Redraw just a score bar without touching the play field
picocalc.display.fillRect(0, 0, 320, 16, picocalc.display.BLACK)
picocalc.display.drawText(4, 4, "SCORE " .. score, picocalc.display.WHITE, false)
picocalc.display.flushRows(0, 15)Like flush(), but transfers only rows y0–y1 (inclusive): the front/back buffers are swapped, and the flushed band is then copied back into the new back buffer so both buffers stay in sync for that region. Rows are clamped to 0–319.
Use this when your app follows the normal draw-then-flush double-buffered cycle but only a horizontal band changed — cheaper than a full-screen transfer, and later full flush() calls will not flicker. Costs one extra band-sized copy compared to flushRows().
-
Parameters:
-
y0(number): First row (inclusive) -
y1(number): Last row (inclusive)
-
- Returns: None
-- Only the animation strip in the middle changed this frame
picocalc.display.flushRegion(120, 200)Returns the display width in pixels.
- Parameters: None
- Returns: (number) 320
Returns the display height in pixels.
- Parameters: None
- Returns: (number) 320
Sets the display backlight brightness.
-
Parameters:
-
level(number): Brightness value (0-255, where 255 is full brightness)
-
- Returns: None
picocalc.display.setBrightness(128) -- 50% brightnessConverts 8-bit RGB components to a 16-bit RGB565 color value.
-
Parameters:
-
r(number): Red component (0-255) -
g(number): Green component (0-255) -
b(number): Blue component (0-255)
-
- Returns: (number) RGB565 color value
local purple = picocalc.display.rgb(128, 0, 128)
picocalc.display.clear(purple)Draw a circle outline.
-
Parameters:
-
cx(number): Center X coordinate -
cy(number): Center Y coordinate -
radius(number): Circle radius in pixels -
color(number): RGB565 color value
-
- Returns: None
picocalc.display.drawCircle(160, 160, 50, picocalc.display.WHITE)Draw a filled circle.
-
Parameters:
-
cx(number): Center X coordinate -
cy(number): Center Y coordinate -
radius(number): Circle radius in pixels -
color(number): RGB565 color value
-
- Returns: None
picocalc.display.fillCircle(160, 160, 50, picocalc.display.RED)Draw an optimized vertical line.
-
Parameters:
-
x(number): X coordinate -
y0(number): Top Y coordinate -
y1(number): Bottom Y coordinate -
color(number): RGB565 color value
-
- Returns: None
picocalc.display.fillVLine(100, 10, 300, picocalc.display.GREEN)Draw an optimized horizontal line.
-
Parameters:
-
y(number): Y coordinate -
x0(number): Left X coordinate -
x1(number): Right X coordinate -
color(number): RGB565 color value
-
- Returns: None
picocalc.display.fillHLine(50, 10, 300, picocalc.display.GREEN)Draw a filled triangle.
-
Parameters:
-
x0,y0(number): First vertex -
x1,y1(number): Second vertex -
x2,y2(number): Third vertex -
color(number): RGB565 color value
-
- Returns: None
picocalc.display.fillTriangle(160, 40, 60, 280, 260, 280, picocalc.display.RED)Draw a vertical line with gradient between two colors.
-
Parameters:
-
x(number): X coordinate -
y0(number): Top Y coordinate -
y1(number): Bottom Y coordinate -
colorTop(number): RGB565 color at the top -
colorBottom(number): RGB565 color at the bottom
-
- Returns: None
picocalc.display.fillVLineGradient(160, 0, 319, picocalc.display.BLUE, picocalc.display.BLACK)Draw a vertical column of pixels sampled from a texture image. Useful for raycasting renderers.
-
Parameters:
-
x(number): Screen X coordinate -
y0(number): Screen top Y coordinate -
y1(number): Screen bottom Y coordinate -
image(userdata): Image object frompicocalc.graphics.image.load()or.new() -
texX(number): Texture X coordinate to sample from -
texY0(number): Texture top Y coordinate -
texY1(number): Texture bottom Y coordinate
-
- Returns: None
-- Draw a column from a wall texture (raycasting)
picocalc.display.drawTexturedColumn(x, wallTop, wallBottom, wallTexture, texCol, 0, 63)Restrict all drawing primitives to a rectangle. Useful for split-screen, UI panels, and partial redraws. clear() and the framebuffer effects are NOT clipped (they are whole-buffer by design). The rectangle is clamped to the 320×320 screen. The clip rect is reset to full screen automatically at app launch and exit, so apps always start (and leave the launcher) unclipped.
-
Parameters:
-
x(number): Clip rect left -
y(number): Clip rect top -
w(number): Clip rect width -
h(number): Clip rect height
-
- Returns: None
picocalc.display.setClipRect(0, 0, 160, 320) -- left half only
-- ... draw player 1 view ...
picocalc.display.clearClipRect() -- back to full screenReturn the current clip rectangle.
-
Returns: (number, number, number, number)
x, y, w, h
Restore the clip rectangle to the full screen.
- Returns: None
Render a Mode 7-style perspective ground plane (SNES F-Zero / Mario Kart floor). The camera sits at (camX, camY) in texture space, camZ units above the plane, facing angle radians (0 = toward +Y in texture space). Rows below horizonY are filled. Power-of-two texture dimensions (64/128/256) wrap seamlessly; other sizes clamp at the edges. Respects the clip rect.
-
Parameters:
-
image(userdata): Ground texture image -
camX(number): Camera X in texture space -
camY(number): Camera Y in texture space -
camZ(number): Camera height above the plane -
angle(number, optional): Facing in radians (default 0) -
horizonY(number, optional): Horizon scanline (default 120) -
scale(number, optional): FOV/zoom tuning, larger = further view (default 1.0)
-
- Returns: None
local floor = picocalc.graphics.image.load(APP_DIR .. "/track.png") -- 256x256
while true do
picocalc.display.clear(picocalc.display.rgb(64, 64, 128)) -- sky
picocalc.display.drawPlane(floor, x, y, 20.0, angle, 120, 40.0)
picocalc.display.flush()
endSet the active bitmap font for drawText and textWidth.
-
Parameters:
-
fontId(number): One of theFONT_*constants
-
- Returns: None
picocalc.display.setFont(picocalc.display.FONT_8X12)
picocalc.display.drawText(10, 10, "Larger text", picocalc.display.WHITE)Get the current font ID.
- Parameters: None
- Returns: (number) Font ID constant
local currentFont = picocalc.display.getFont()Get the character width in pixels of the current font.
- Parameters: None
- Returns: (number) Width in pixels
local charWidth = picocalc.display.getFontWidth()Get the character height in pixels of the current font.
- Parameters: None
- Returns: (number) Height in pixels
local charHeight = picocalc.display.getFontHeight()Configure the LCD's hardware vertical scroll area (ST7365P VSCRDEF).
The controller's frame memory is 480 lines; the visible panel shows lines
0..319. The three values must sum to 480. The standard configuration is
setScrollArea(0, 320, 160), which turns the whole visible panel into a
mod-320 ring: with an offset set, screen row L displays frame-memory row
(offset + L) % 320.
-
Parameters:
-
top(number): Fixed rows at the top of frame memory -
height(number): Scrolling area height in rows -
bottom(number): Fixed rows at the bottom of frame memory
-
- Returns: None
-- Ring the whole visible panel over its 320 frame-memory rows
picocalc.display.setScrollArea(0, 320, 160)Set the hardware vertical scroll offset (ST7365P VSCRSADD): the frame-memory
row displayed at the top of the scroll area. The remap is instant and moves
no pixel data — combined with flushRows for the newly revealed strip, this
scrolls full-screen content for the cost of a few rows per frame
(panels.lua does exactly this for rigid scroll sequences).
0 restores the identity mapping. The setter waits out any in-flight flush
DMA before touching the register, so it is safe immediately after
flush/flushRows.
-
Parameters:
-
offset(number): Frame-memory row shown at the top of the scroll area
-
- Returns: None
picocalc.display.setScrollOffset(scrollPos % 320)Return the last offset written with setScrollOffset, plus a write counter
(the LCD register itself is write-only).
The OS resets the offset to 0 whenever it takes over the screen (system menu, app switch) and does not restore it. An app driving hardware scroll must poll this each frame and repaint when either value changes unexpectedly — the counter catches a foreign write even when the value matches what the app last set.
-
Returns:
-
offset(number): Last written scroll offset -
writeCount(number): Total register writes since boot
-
local off, gen = picocalc.display.getScrollOffset()
if off ~= myOffset or gen ~= myGen then
-- someone else (system menu) touched the register: repaint
end| Constant | Value | Description |
|---|---|---|
picocalc.display.FONT_6X8 |
0 | Built-in 6x8 pixel bitmap font (default) |
picocalc.display.FONT_8X12 |
1 | Larger 8x12 pixel bitmap font |
picocalc.display.FONT_SCIENTIFICA |
2 | Scientifica proportional font |
picocalc.display.FONT_SCIENTIFICA_BOLD |
3 | Scientifica bold proportional font |
Predefined RGB565 color values:
| Constant | Color |
|---|---|
picocalc.display.BLACK |
Black (0, 0, 0) |
picocalc.display.WHITE |
White (255, 255, 255) |
picocalc.display.RED |
Red (255, 0, 0) |
picocalc.display.GREEN |
Green (0, 255, 0) |
picocalc.display.BLUE |
Blue (0, 0, 255) |
picocalc.display.YELLOW |
Yellow (255, 255, 0) |
picocalc.display.CYAN |
Cyan (0, 255, 255) |
picocalc.display.GRAY |
Gray (128, 128, 128) |
Post-processing effects applied to the entire framebuffer. Draw your scene first, apply effects, then call flush(). Effects use the RP2350's hardware interpolators for fast per-pixel blending where applicable.
All effects operate on the back buffer and do not block DMA — they can overlap with the previous frame's transfer for maximum throughput.
Bitwise-inverts all pixels. The fastest effect (~0.3ms).
picocalc.display.applyEffect("invert")Darkens the framebuffer by blending each pixel toward black.
-
Parameters:
-
factor(number, optional): 0 = fully black, 255 = no change. Default: 128.
-
picocalc.display.applyEffect("darken", 200) -- slight darken
picocalc.display.applyEffect("darken", 64) -- heavy darkenBrightens the framebuffer by blending each pixel toward white.
-
Parameters:
-
factor(number, optional): 0 = no change, 255 = fully white. Default: 128.
-
picocalc.display.applyEffect("brighten", 80)Blends the framebuffer toward a tint color. Uses hardware interpolator BLEND mode.
-
Parameters:
-
r,g,b(number): Tint color components (0-255) -
strength(number, optional): Blend strength (0 = no tint, 255 = solid color). Default: 128.
-
-- Red tint overlay
picocalc.display.applyEffect("tint", 255, 0, 0, 100)
-- Sepia tone
picocalc.display.applyEffect("tint", 180, 140, 100, 80)Fades the framebuffer toward a target color. Alias for "tint" — identical behavior.
-
Parameters:
-
r,g,b(number): Target color components (0-255) -
factor(number, optional): Fade amount (0 = no change, 255 = solid color). Default: 128.
-
-- Fade to black (transition effect)
picocalc.display.applyEffect("fade", 0, 0, 0, 200)
-- Fade to white (flash effect)
picocalc.display.applyEffect("fade", 255, 255, 255, 128)Desaturates the framebuffer using ITU-R BT.601 luma weights (0.299R + 0.587G + 0.114B).
picocalc.display.applyEffect("grayscale")Alpha-blends an image onto the framebuffer. The image is drawn at (0, 0) and clipped to the screen.
-
Parameters:
-
image(userdata): Image object frompicocalc.graphics.image.load()or.new() -
alpha(number, optional): Opacity (0 = fully transparent, 255 = fully opaque). Default: 128.
-
local overlay = picocalc.graphics.image.load(APP_DIR .. "/overlay.png")
picocalc.display.applyEffect("blend", overlay, 100)Remaps all framebuffer colors through a lookup table. Each pixel's RGB channels are quantized to an 8-bit index (3 bits red, 3 bits green, 2 bits blue) and replaced with the corresponding LUT entry.
-
Parameters:
-
lut(table): Array of 1-256 RGB565 color values
-
-- Create a 256-entry grayscale palette
local lut = {}
for i = 1, 256 do
local v = math.floor((i - 1) * 255 / 255)
lut[i] = picocalc.display.rgb(v, v, v)
end
picocalc.display.applyEffect("palette", lut)Applies ordered Bayer 4x4 dithering, quantizing colors to a reduced number of levels per channel.
-
Parameters:
-
levels(number, optional): Quantization levels per channel (2-32). Default: 4.
-
picocalc.display.applyEffect("dither", 4) -- retro 4-level dither
picocalc.display.applyEffect("dither", 2) -- extreme 1-bit style ditherDarkens every other row to create a CRT scanline effect. Uses fast bit-shift operations (no per-pixel channel extraction).
-
Parameters:
-
intensity(number, optional): 1-127 = light scanlines (50% brightness), 128-254 = heavy (25%), 255 = black lines. Default: 128.
-
picocalc.display.applyEffect("scanline", 100) -- subtle CRT effect
picocalc.display.applyEffect("scanline", 255) -- full black scanlinesReduces color depth by quantizing each channel to a fixed number of levels.
-
Parameters:
-
levels(number, optional): Levels per channel (2-32). Default: 4.
-
picocalc.display.applyEffect("posterize", 4) -- poster-art style
picocalc.display.applyEffect("posterize", 8) -- subtle reductionEffects can be chained. Each modifies the framebuffer in sequence.
while true do
picocalc.display.clear(picocalc.display.BLACK)
-- Draw your scene...
picocalc.display.fillRect(50, 50, 220, 220, picocalc.display.CYAN)
picocalc.display.drawText(80, 160, "Effects!", picocalc.display.WHITE)
-- Apply effects (order matters)
picocalc.display.applyEffect("tint", 255, 100, 0, 60) -- warm tint
picocalc.display.applyEffect("scanline", 100) -- CRT lines
picocalc.display.applyEffect("dither", 8) -- subtle dither
picocalc.display.flush()
endNative ELF apps access effects through the picocalc_display_t vtable:
void picos_main(PicoCalcAPI *api) {
const picocalc_display_t *d = api->display;
d->clear(RGB565(0, 0, 0));
d->drawText(10, 10, "Hello", RGB565(255, 255, 255), RGB565(0, 0, 0));
// Apply effects
d->effectTint(255, 0, 0, 128); // red tint
d->effectScanline(100); // CRT scanlines
d->flush();
}| Function | Signature |
|---|---|
effectInvert |
void (*)(void) |
effectDarken |
void (*)(uint8_t factor) |
effectBrighten |
void (*)(uint8_t factor) |
effectTint |
void (*)(uint8_t r, uint8_t g, uint8_t b, uint8_t strength) |
effectGrayscale |
void (*)(void) |
effectBlend |
void (*)(const uint16_t *src, int w, int h, uint8_t alpha) |
effectPalette |
void (*)(const uint16_t *lut, int lut_size) |
effectDither |
void (*)(uint8_t levels) |
effectScanline |
void (*)(uint8_t intensity) |
effectPosterize |
void (*)(uint8_t levels) |
API version 4 (api->version >= 4) adds the clip rect, mode-7 plane, and the previously Lua-only primitives to the same vtable:
| Function | Signature |
|---|---|
setClipRect |
void (*)(int x, int y, int w, int h) |
getClipRect |
void (*)(int *x, int *y, int *w, int *h) |
clearClipRect |
void (*)(void) |
fillHLine |
void (*)(int y, int x0, int x1, uint16_t color) |
fillTriangle |
void (*)(int x0, int y0, int x1, int y1, int x2, int y2, uint16_t color) |
setScrollArea |
void (*)(int top_fixed, int scroll_height, int bottom_fixed) |
setScrollOffset |
void (*)(int offset) |
drawPlane |
void (*)(const uint16_t *tex, int tex_w, int tex_h, float cam_x, float cam_y, float cam_z, float angle, int horizon_y, float scale) |
Image loading, drawing, and state management. Images are stored in PSRAM and support BMP, JPEG, PNG, and GIF formats.
Sets the current drawing color for graphics operations.
-
Parameters:
-
color(number): RGB565 color value
-
- Returns: None
Sets the background color for graphics operations.
-
Parameters:
-
color(number): RGB565 color value
-
- Returns: None
Sets the global transparent color for image and sprite drawing. Pixels matching this color will not be drawn.
-
Parameters:
-
color(number or nil): RGB565 color value, ornilto disable transparency.
-
- Returns: None
Returns the current global transparent color.
-
Returns: (number or nil) RGB565 color value, or
nilif transparency is disabled.
Sets a global 8-byte stencil pattern applied to subsequent drawing.
-
Parameters:
-
pattern(table or nil): Array of 8 bytes (one per row of the 8×8 pattern), ornilto clear the stencil
-
- Returns: None
picocalc.graphics.setStencilPattern({0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55})
picocalc.graphics.setStencilPattern(nil) -- clearClears the screen using the background color (or a specified color).
-
Parameters:
-
color(number, optional): RGB565 color value. Defaults to the current background color.
-
- Returns: None
picocalc.graphics.setBackgroundColor(picocalc.display.BLACK)
picocalc.graphics.clear()Draws a grid of cols×rows outlined cells in a single C call.
-
Parameters:
-
x,y(number): Top-left corner of the grid -
cell_w,cell_h(number): Width and height of each cell in pixels -
cols,rows(number): Number of columns and rows -
color(number): RGB565 border color
-
- Returns: None
picocalc.graphics.drawGrid(10, 10, 14, 14, 10, 20, picocalc.display.GRAY)Fills a rectangle then draws a 1-pixel border over it in a single C call.
-
Parameters:
-
x,y(number): Top-left corner -
w,h(number): Width and height in pixels -
fill_color(number): RGB565 fill color -
border_color(number): RGB565 border color
-
- Returns: None
picocalc.graphics.fillBorderedRect(10, 10, 50, 50, picocalc.display.BLUE, picocalc.display.WHITE)Draws a 2D block grid in a single C call — ideal for falling-block games. playfield[row][col] holds an RGB565 color, or 0 for an empty cell. Blocks are filled; the grid lines are drawn in grid_color.
-
Parameters:
-
playfield(table): 2D array indexedplayfield[row][col](1-based); RGB565 color or0= empty -
ox,oy(number): Top-left corner of the playfield in pixels -
block_size(number): Width and height of each block in pixels -
cols,rows(number): Playfield dimensions in blocks -
grid_color(number): RGB565 grid line color
-
- Returns: None
local playfield = {}
for r = 1, 20 do
playfield[r] = {}
for c = 1, 10 do playfield[r][c] = 0 end
end
playfield[20][5] = picocalc.display.RED
picocalc.graphics.drawPlayfield(playfield, 85, 10, 15, 10, 20, picocalc.display.GRAY)Updates, draws, and compacts a flat particle array in a single C call. The array holds 6 values per particle: x, y, vx, vy, life_ms, color.
-
Parameters:
-
flat_array(table): Flat sequence with 6 values per particle -
delta_s(number): Elapsed time in seconds since last call
-
- Returns: (number) Count of live particles remaining
-- particles = {x, y, vx, vy, life_ms, color, ...}
local live = picocalc.graphics.updateDrawParticles(particles, delta / 1000)picocalc.graphics.draw3DWireframe(verts, edges, aX, aY, aZ, scx, scy, fov, edgeColor [, vertColor [, vertSize]])
Rotates, projects, and draws a 3D wireframe model in a single C call. All trigonometry and matrix math runs in C — suitable for real-time use in game loops.
-
Parameters:
-
verts(table): Flat sequence{x1, y1, z1, x2, y2, z2, ...}—n/3vertices -
edges(table): Flat sequence{a1, b1, a2, b2, ...}— 1-based vertex index pairs -
aX,aY,aZ(number): Rotation angles in radians, applied in X→Y→Z order -
scx,scy(number): Screen-space center point (projection origin) -
fov(number): Field-of-view scale factor (larger = more perspective, try 200–400) -
edgeColor(number): RGB565 color for edges -
vertColor(number, optional): RGB565 color for vertex dots. Defaults toedgeColor. -
vertSize(number, optional): Dot size in pixels for vertex dots. Defaults to 3.
-
- Returns: None
local verts = {
-1,-1,-1, 1,-1,-1, 1,1,-1, -1,1,-1, -- back face
-1,-1, 1, 1,-1, 1, 1,1, 1, -1,1, 1, -- front face
}
local edges = {
1,2, 2,3, 3,4, 4,1, -- back
5,6, 6,7, 7,8, 8,5, -- front
1,5, 2,6, 3,7, 4,8, -- sides
}
local angle = 0
while true do
angle = angle + 0.02
picocalc.display.clear(picocalc.display.BLACK)
picocalc.graphics.draw3DWireframe(verts, edges, angle, angle*0.7, 0,
160, 160, 300, picocalc.display.WHITE)
picocalc.display.flush()
enddraw3DWireframeEx(verts, edges, angleX, angleY, angleZ, scx, scy, fov, edgeColor [, fillColor [, fillMode [, vertSize [, faces]]]])
Enhanced 3D wireframe with optional filled triangles. Note: this is a global function, not under picocalc.*.
-
Parameters:
-
verts(table): Flat sequence{x1, y1, z1, x2, y2, z2, ...}—n/3vertices -
edges(table): Flat sequence{a1, b1, a2, b2, ...}— 1-based vertex index pairs -
angleX,angleY,angleZ(number): Rotation angles in radians -
scx,scy(number): Screen-space center point -
fov(number): Field-of-view scale factor -
edgeColor(number): RGB565 color for edges -
fillColor(number, optional): RGB565 fill color. Defaults to0(black). -
fillMode(number, optional): 0 = wireframe only, 1 = fill only, 2 = both. Defaults to0. -
vertSize(number, optional): Vertex dot size in pixels. Defaults to3. -
faces(table, optional): Flat sequence of vertex-index triples{v1, v2, v3, ...}defining the triangles to fill
-
- Returns: None
local faces = {1,2,3, 1,3,4, 5,6,7, 5,7,8} -- two quads as triangles
draw3DWireframeEx(verts, edges, angle, angle*0.7, 0,
160, 160, 300, picocalc.display.WHITE, picocalc.display.BLUE, 2, 3, faces)Draws text using the current graphics color and background color. Optionally specify a font object.
-
Parameters:
-
text(string): Text to draw -
x(number): X coordinate -
y(number): Y coordinate -
font(userdata, optional): Font object fromgraphics.font.new()
-
- Returns: (number) Pixel width of rendered text
local width = picocalc.graphics.drawText("Hello!", 10, 10)Draws text with alignment. For center/right, text is positioned relative to x.
-
Parameters:
-
text(string): Text to draw -
x(number): X coordinate -
y(number): Y coordinate -
alignment(number): 0 = left, 1 = center, 2 = right -
font(userdata, optional): Font object fromgraphics.font.new()
-
- Returns: None
-- Draw centered text
picocalc.graphics.drawTextAligned("Centered", 160, 10, 1)Draws word-wrapped text within a bounding rectangle. Line breaks at word boundaries for monospace fonts.
-
Parameters:
-
text(string): Text to draw -
x(number): Left edge of bounding rectangle -
y(number): Top edge of bounding rectangle -
w(number): Width of bounding rectangle -
h(number): Height of bounding rectangle -
alignment(number, optional): 0 = left (default), 1 = center, 2 = right -
font(userdata, optional): Font object fromgraphics.font.new()
-
- Returns: None
-- Draw a paragraph of word-wrapped text in a box
picocalc.graphics.setColor(picocalc.display.WHITE)
picocalc.graphics.setBackgroundColor(picocalc.display.BLACK)
picocalc.graphics.drawTextInRect(
"This is a long string that will be word-wrapped to fit within the rectangle.",
10, 10, 200, 100
)Returns pixel dimensions for a single line of text.
-
Parameters:
-
text(string): Text to measure -
font(userdata, optional): Font object fromgraphics.font.new()
-
-
Returns: (number, number)
width, height
local w, h = picocalc.graphics.getTextSize("Hello!")Returns pixel dimensions of word-wrapped text within maxWidth.
-
Parameters:
-
text(string): Text to measure -
maxWidth(number): Maximum width in pixels for word wrapping -
font(userdata, optional): Font object fromgraphics.font.new()
-
-
Returns: (number, number)
width, height
local w, h = picocalc.graphics.getTextSizeForMaxWidth("A long string to measure.", 200)Renders word-wrapped text into a new image in PSRAM. Uses the current graphics color for the text foreground.
-
Parameters:
-
text(string): Text to render -
maxWidth(number): Maximum image width in pixels -
maxHeight(number): Maximum image height in pixels -
bgColor(number, optional): Background RGB565 color -
font(userdata, optional): Font object fromgraphics.font.new()
-
-
Returns: (userdata) Image object, or
nil, errstron failure
picocalc.graphics.setColor(picocalc.display.WHITE)
local img = picocalc.graphics.imageWithText("Hello World", 200, 100, picocalc.display.BLACK)
if img then
img:draw(10, 10)
endCreates a new blank image in PSRAM, initialized to all zeros (black).
-
Parameters:
-
width(number): Image width in pixels -
height(number): Image height in pixels
-
- Returns: (userdata) Image object
- Errors: If dimensions are invalid or memory allocation fails
local canvas = picocalc.graphics.image.new(64, 64)Loads an image from the SD card. Supports BMP, JPEG, PNG, and GIF (first frame only) formats.
-
Parameters:
-
path(string): Absolute file path
-
- Returns: (userdata) Image object
- Errors: If file not found, format unsupported, or memory allocation fails
local img = picocalc.graphics.image.load("/apps/myapp/sprite.bmp")Decodes an image from an in-memory buffer. The format is auto-detected from the magic bytes — BMP, JPEG, PNG, and GIF are all supported.
-
Parameters:
-
data(string or userdata): Image file data
-
- Returns: (userdata) Image object
- Errors: If format unsupported or decoding fails
local raw = picocalc.fs.readFile("/apps/myapp/photo.jpg")
local img = picocalc.graphics.image.loadFromBuffer(raw)Reads an image's dimensions from its header only — no full decode.
-
Parameters:
-
path(string): Absolute file path
-
-
Returns: (table)
{width=number, height=number, format=string} - Errors: If the file is not a recognized image
local info = picocalc.graphics.image.getInfo("/apps/myapp/photo.jpg")
print(info.width, info.height, info.format)Loads an image and keeps only the given sub-rectangle. The region is clamped to the image bounds.
-
Parameters:
-
path(string): Absolute file path -
x,y(number): Top-left of the region -
w,h(number): Region dimensions in pixels
-
- Returns: (userdata) Image object
- Errors: If the file fails to load or the region lies outside the image
-- Load just the top-left 64x64 corner of a large image
local corner = picocalc.graphics.image.loadRegion("/apps/myapp/big.png", 0, 0, 64, 64)Loads an image and resamples it to w×h (bilinear). Faster and lighter than loading full-size then scaling at draw time.
-
Parameters:
-
path(string): Absolute file path -
w,h(number): Target dimensions in pixels
-
- Returns: (userdata) Image object
- Errors: If the file fails to load
local thumb = picocalc.graphics.image.loadScaled("/apps/myapp/photo.jpg", 64, 64)Starts an asynchronous decode of an image on Core 1. Only one preload can be in flight at a time. Poll for completion with pollPreload().
-
Parameters:
-
path(string): Absolute file path
-
-
Returns: (boolean)
trueif the preload was started
picocalc.graphics.image.preload("/apps/myapp/level2.png")Checks the state of the pending preload.
-
Returns: (userdata or nil, boolean)
image, ready—readyistrueonce the preload has finished (successfully or not);imageis the decoded image, ornilwhile still decoding or on failure
while true do
local img, ready = picocalc.graphics.image.pollPreload()
if ready then
if img then levelArt = img end
break
end
picocalc.sys.sleep(10)
endCancels the pending preload.
- Returns: None
Returns a table of supported image format names.
-
Returns: (table) Array of format strings (e.g.,
{"BMP", "JPEG", "PNG", "GIF"})
All methods are called on image objects with colon syntax.
Returns the image dimensions.
-
Returns: (number, number)
width, height
local w, h = img:getSize()Returns image metadata without touching pixel data.
-
Returns: (table)
{width=number, height=number, transparentColor=number?, storage=string}—transparentColoris only present if one is set;storageis"psram"
local meta = img:getMetadata()
print(meta.width, meta.height, meta.storage)Draws the image (or a sub-rectangle of it) to the framebuffer.
-
Parameters:
-
x(number): Destination X coordinate -
y(number): Destination Y coordinate -
flipOpts(boolean or table, optional): Iftrue, flips horizontally. If table:{flipX=bool, flipY=bool} -
srcRect(table, optional): Source sub-rectangle{x=int, y=int, w=int, h=int}
-
- Returns: None
-- Draw full image
img:draw(10, 20)
-- Draw horizontally flipped
img:draw(10, 20, true)
-- Draw with flip options
img:draw(10, 20, {flipX = true, flipY = false})
-- Draw a sub-region
img:draw(10, 20, false, {x = 0, y = 0, w = 32, h = 32})Draws the image positioned relative to an anchor point.
-
Parameters:
-
x(number): Anchor X coordinate -
y(number): Anchor Y coordinate -
anchorX(number): Horizontal anchor (0.0 = left, 0.5 = center, 1.0 = right) -
anchorY(number): Vertical anchor (0.0 = top, 0.5 = center, 1.0 = bottom)
-
- Returns: None
-- Draw centered on screen
img:drawAnchored(160, 160, 0.5, 0.5)Tiles the image to fill a rectangular area.
-
Parameters:
-
x(number): Top-left X coordinate -
y(number): Top-left Y coordinate -
width(number): Fill area width -
height(number): Fill area height
-
- Returns: None
-- Tile a pattern across a 200x100 area
img:drawTiled(0, 30, 200, 100)Draws the image scaled and optionally rotated.
-
Parameters:
-
x(number): Destination X coordinate -
y(number): Destination Y coordinate -
scale(number): Scale factor (1.0 = original size, 2.0 = double) -
angle(number, optional): Rotation angle in radians. Defaults to 0.
-
- Returns: None
img:drawScaled(160, 160, 2.0) -- 2x zoom
img:drawScaled(160, 160, 1.0, 0.785) -- Rotate 45°Draws the image scaled using nearest-neighbor interpolation. Faster and sharper for integer scaling (pixel art).
-
Parameters:
-
x(number): Destination X coordinate -
y(number): Destination Y coordinate -
scale(number): Integer scale factor (e.g., 2 for 2x size)
-
- Returns: None
img:drawScaledNN(10, 10, 3) -- 3x zoom (pixel art style)Creates a deep copy of the image.
- Returns: (userdata) New image object with identical pixel data
local backup = img:copy()Sprite system for game and graphics applications. Sprites are 2D objects that can be positioned, scaled, rotated, and managed through a global sprite manager.
Creates a new sprite, optionally with an image.
-
Parameters:
-
image(userdata, optional): Image object fromgraphics.image.new()orgraphics.image.load()
-
- Returns: (userdata) Sprite object
local sprite = picocalc.graphics.sprite.new(myImage)
local emptySprite = picocalc.graphics.sprite.new()Updates and draws all sprites in the manager. Call once per frame.
- Returns: None
while true do
-- Update sprite positions
sprite1:moveBy(1, 0)
picocalc.graphics.sprite.update()
endReturns the number of sprites in the manager.
- Returns: (number) Count of sprites
local count = picocalc.graphics.sprite.spriteCount()Returns a table containing all sprites in the manager.
- Returns: (table) Array of sprite objects
local all = picocalc.graphics.sprite.getAllSprites()
for i, s in ipairs(all) do
print(i, s.x, s.y)
endRemoves all sprites from the manager.
- Returns: None
picocalc.graphics.sprite.removeAll()Removes multiple sprites from the manager.
-
Parameters:
-
spriteArray(table): Array of sprite objects to remove
-
- Returns: None
picocalc.graphics.sprite.removeSprites({sprite1, sprite2, sprite3})Calls a function on each sprite in the manager.
-
Parameters:
-
callback(function): Function to call with each sprite as argument
-
- Returns: None
picocalc.graphics.sprite.performOnAllSprites(function(s)
s:setVisible(false)
end)Queries all sprites at a specific point.
-
Parameters:
-
x,y(number): Coordinates, OR -
point(table):{x=number, y=number}
-
- Returns: (table) Array of sprites at that point
local hits = picocalc.graphics.sprite.querySpritesAtPoint(160, 100)Queries all sprites within a rectangular area.
-
Parameters:
-
x,y,w,h(number), OR -
rect(table):{x=number, y=number, w=number, h=number}
-
- Returns: (table) Array of sprites in the rect
local hits = picocalc.graphics.sprite.querySpritesInRect(0, 0, 100, 100)Queries all sprites that intersect a line segment.
-
Parameters:
-
x1,y1(number): Start point -
x2,y2(number): End point
-
- Returns: (table) Array of sprite objects
local hits = picocalc.graphics.sprite.querySpritesAlongLine(0, 0, 320, 320)Queries all sprites that intersect a line segment, returning detailed intersection info.
-
Parameters:
-
x1,y1(number): Start point -
x2,y2(number): End point
-
-
Returns: (table) Array of intersection info tables:
{sprite, x, y}
All methods are called on sprite objects with colon syntax.
Adds the sprite to the global sprite manager.
- Returns: None
mySprite:add()Removes the sprite from the global sprite manager.
- Returns: None
mySprite:remove()Draws the sprite to the framebuffer immediately (not via the manager).
-
Parameters:
-
x,y(number, optional): Position to draw. Defaults to sprite's stored position.
-
- Returns: None
mySprite:draw() -- Draw at sprite.x, sprite.y
mySprite:draw(50, 100) -- Draw at custom positionUpdates and draws a single sprite (alternative to using the manager).
- Returns: None
mySprite:update()Sets the sprite's image.
-
Parameters:
-
image(userdata): Image object -
flip(boolean, optional): Enable horizontal flip -
scale(number, optional): Scale factor -
yscale(number, optional): Y scale factor (defaults to scale)
-
- Returns: None
sprite:setImage(myImage, false, 1.5)Gets the sprite's image.
- Returns: (userdata or nil) Image object
Moves the sprite to absolute coordinates.
-
Parameters:
-
x,y(number): New position
-
- Returns: None
sprite:moveTo(100, 50)Moves the sprite by a relative offset.
-
Parameters:
-
dx,dy(number): Offset to add to current position
-
- Returns: None
sprite:moveBy(5, -3)Gets the sprite's position.
-
Returns: (number, number)
x, y
local x, y = sprite:getPosition()Sets the sprite's Z-index for draw ordering.
-
Parameters:
-
z(number): Z-order value
-
- Returns: None
sprite:setZIndex(10)Gets the sprite's Z-index.
- Returns: (number) Z-index
Shows or hides the sprite.
-
Parameters:
-
flag(boolean):trueto show,falseto hide
-
- Returns: None
sprite:setVisible(false)Checks if the sprite is visible.
- Returns: (boolean)
Sets the sprite's rotation/scale center point.
-
Parameters:
-
x,y(number): Center point relative to sprite origin
-
- Returns: None
sprite:setCenter(16, 16) -- Center of a 32x32 spriteGets the sprite's center point.
-
Returns: (number, number)
centerX, centerY
Gets the sprite's center point as a table.
-
Returns: (table)
{x, y}
Sets the sprite's dimensions.
-
Parameters:
-
width,height(number): New dimensions
-
- Returns: None
sprite:setSize(64, 64)Gets the sprite's dimensions.
-
Returns: (number, number)
width, height
Sets the sprite's scale factor(s).
-
Parameters:
-
scale(number): Scale factor -
yScale(number, optional): Y scale (defaults to scale)
-
- Returns: None
sprite:setScale(2.0) -- Uniform 2x
sprite:setScale(2.0, 1.5) -- Non-uniformGets the sprite's scale factors.
-
Returns: (number, number)
scaleX, scaleY
Sets an integer scale factor using nearest-neighbor interpolation. Sharp for pixel art.
-
Parameters:
-
scale(number): Positive integer scale (1, 2, 3...)
-
- Returns: None
Sets a per-sprite transparent color, overriding the global transparent color.
-
Parameters:
-
color(number or nil): RGB565 color value, ornilto use the global setting.
-
- Returns: None
Sets the sprite's rotation angle in radians.
-
Parameters:
-
angle(number): Rotation in radians -
scale(number, optional): Scale X -
yScale(number, optional): Scale Y
-
- Returns: None
sprite:setRotation(math.pi / 4) -- 45 degreesGets the sprite's rotation angle.
- Returns: (number) Rotation in radians
Creates a copy of the sprite.
- Returns: (userdata) New sprite object
local clone = sprite:copy()Extracts a sub-region of the sprite's image as its new frame. Subsequent draw() or update() calls will only render this region. This effectively creates an internal copy of the frame data.
-
Parameters:
-
x,y(number): Top-left coordinate in source image -
w,h(number): Dimensions of the frame to extract
-
- Returns: None
-- Select a 32x32 frame from a larger sheet
sprite:setSourceRect(32, 0, 32, 32)Resets the sprite to use its full source image.
- Returns: None
Enables or disables automatic updates when using graphics.sprite.update().
-
Parameters:
-
flag(boolean): Enable/disable updates
-
- Returns: None
Checks if updates are enabled.
- Returns: (boolean)
Enables or disables forced redraw for this sprite every frame, even if it hasn't moved.
-
Parameters:
-
flag(boolean)
-
- Returns: None
- Returns: (boolean)
Explicitly marks the sprite as needing to be redrawn in the next update.
- Returns: None
Adds a dirty rectangle for partial redrawing. (Stub implementation)
Sets whether the sprite automatically redraws when its image is changed.
-
Parameters:
-
flag(boolean)
-
- Returns: None
Sets a user-defined tag value.
-
Parameters:
-
tag(number): Tag value
-
- Returns: None
sprite:setTag(123)Gets the sprite's tag.
- Returns: (number) Tag value
Sets horizontal flip.
-
Parameters:
-
flip(boolean): Flip enabled
-
- Returns: None
Gets horizontal flip state.
- Returns: (boolean)
Sets whether the sprite ignores global draw offsets.
-
Parameters:
-
flag(boolean): Ignore offset
-
- Returns: None
Sets the sprite's bounding box for culling.
-
Parameters:
-
x,y,w,h(number), OR -
rect(table):{x, y, w, h}
-
- Returns: None
Gets the sprite's bounding box.
-
Returns: (number, number, number, number)
x, y, w, h
Gets the sprite's bounding box as a table.
-
Returns: (table)
{x, y, w, h}
Sets whether the sprite is opaque (affects collision detection).
-
Parameters:
-
flag(boolean): Opaque state
-
- Returns: None
Gets the sprite's opaque state.
- Returns: (boolean)
Enables collision detection for this sprite.
-
Parameters:
-
flag(boolean): Enable collisions
-
- Returns: None
Checks if collisions are enabled.
- Returns: (boolean)
Sets the sprite's collision rectangle.
-
Parameters:
-
x,y,w,h(number), OR -
rect(table):{x, y, w, h}
-
- Returns: None
Gets the sprite's collision rectangle.
-
Returns: (number, number, number, number)
x, y, w, h
Gets the absolute collision bounds (sprite position + collide rect).
-
Returns: (number, number, number, number)
x, y, w, h
Resets the collision rectangle to the full sprite size.
- Returns: None
Sets a clipping rectangle for the sprite, relative to the screen.
-
Parameters:
-
x,y,w,h(number), OR -
rect(table):{x, y, w, h}
-
- Returns: None
Clears the clipping rectangle.
- Returns: None
Gets all sprites that overlap with this sprite.
- Returns: (table) Array of overlapping sprites
local hits = mySprite:overlappingSprites()Gets all sprite pairs that overlap each other.
-
Returns: (table) Array of
{sprite1, sprite2}pairs
Sets collision group membership.
-
Parameters:
-
groups(number): Bitmask of groups
-
- Returns: None
Sets which collision groups this sprite collides with.
-
Parameters:
-
groups(number): Bitmask
-
- Returns: None
Sets/gets the group mask.
Sets/gets the collision-with-groups mask.
Resets the group masks to 0.
Checks if a point collides with the sprite's collision rect.
-
Parameters:
-
x,y(number), OR -
point(table):{x, y}
-
- Returns: (boolean) True if collision
Moves the sprite toward a goal position, sliding along the collision rects of other sprites. Requires collisions to be enabled (setCollisionsEnabled(true)).
-
Parameters:
-
goalX,goalY(number): Desired position
-
-
Returns: (number, number, table)
actualX, actualY, collisions— the position reached, plus a table of collision records{sprite, other, type, x, y, normal = {x, y}, touch}
sprite:setCollisionsEnabled(true)
local x, y, hits = sprite:moveWithCollisions(goalX, goalY)
for i, c in ipairs(hits) do
print("bumped", c.type, c.normal.x, c.normal.y)
endReturns the sprite's collision response type.
-
Returns: (string) Response type (default
"slide")
Sets a stencil image for the sprite.
-
Parameters:
-
image(userdata): Image object to use as the stencil
-
- Returns: None
Assigns a tilemap to this sprite. When set, the sprite renders the tilemap instead of a single image. The sprite's position acts as the tilemap scroll offset. Pass nil to clear.
-
Parameters:
-
tilemap(userdata or nil): Tilemap object, ornilto clear
-
- Returns: None
local tm = picocalc.graphics.tilemap.new(tilesetImage, 16, 16)
tm:setSize(20, 20)
local bgSprite = picocalc.graphics.sprite.new()
bgSprite:setTilemap(tm)
bgSprite:moveTo(0, 0)
bgSprite:add()Creates invisible collision sprites for each tile whose index appears in the wallIDs table. Useful for tile-based collision detection with the sprite system.
-
Parameters:
-
tilemap(userdata): Tilemap object -
wallIDs(table): Array of tile indices that are solid/collidable -
xOffset(number, optional): X offset applied to all wall sprite positions -
yOffset(number, optional): Y offset applied to all wall sprite positions
-
- Returns: (number) Count of wall sprites created
-- Create wall collision sprites for tile indices 1, 2, and 5
local wallCount = picocalc.graphics.sprite.addWallSprites(tilemap, {1, 2, 5})
print("Created " .. wallCount .. " wall sprites")Creates a sprite with text rendered into it. Uses the current graphics color for the text foreground.
-
Parameters:
-
text(string): Text to render -
maxWidth(number): Maximum image width in pixels -
maxHeight(number): Maximum image height in pixels -
bgColor(number, optional): Background RGB565 color -
font(userdata, optional): Font object fromgraphics.font.new()
-
- Returns: (userdata) Sprite object with text image
picocalc.graphics.setColor(picocalc.display.WHITE)
local label = picocalc.graphics.sprite.spriteWithText("Score: 0", 120, 16, picocalc.display.BLACK)
label:moveTo(10, 10)
label:add()Sprites support direct property access via Lua:
sprite.x = 100 -- Set X position
sprite.y = 50 -- Set Y position
sprite.width = 64 -- Set width
sprite.height = 64 -- Set height
sprite.z = 10 -- Set Z-index
sprite.visible = true -- Show/hide
sprite.scale = 2.0 -- Set uniform scale
sprite.scale_nn = 1 -- Get/set integer NN scale
sprite.rotation = 0.5 -- Set rotation (radians)
sprite.tag = 123 -- Set tag
sprite.image -- Get image (userdata or nil)Spritesheet support for sprite animations. A spritesheet is a single image containing multiple animation frames.
Creates a new spritesheet, optionally with a base image.
-
Parameters:
-
image(userdata, optional): Image object containing the spritesheet
-
- Returns: (userdata) Spritesheet object
local ss = picocalc.graphics.spritesheet.new(myImage)Creates a spritesheet from a grid layout. Automatically calculates frame positions.
-
Parameters:
-
image(userdata): Image object containing the spritesheet -
cols(number): Number of columns -
rows(number): Number of rows -
frameWidth(number): Width of each frame in pixels -
frameHeight(number): Height of each frame in pixels
-
- Returns: (userdata) Spritesheet object
-- 4x4 grid of 32x32 pixel frames
local ss = picocalc.graphics.spritesheet.newGrid(spritesheetImg, 4, 4, 32, 32)Manually adds a frame to the spritesheet.
-
Parameters:
-
x,y(number): Top-left position of frame in the image -
width,height(number): Dimensions of the frame
-
- Returns: (number) Frame index (0-based)
ss:addFrame(0, 0, 32, 32) -- Frame 0
ss:addFrame(32, 0, 32, 32) -- Frame 1Returns the total number of frames.
- Returns: (number) Frame count
local count = ss:getFrameCount()Returns the bounds of a specific frame.
-
Parameters:
-
index(number): Frame index (0-based)
-
-
Returns: (table)
{x, y, w, h}or nil if invalid
local frame = ss:getFrame(0)
print(frame.x, frame.y, frame.w, frame.h)Returns the base image.
- Returns: (userdata or nil) Image object
Draws a specific frame to the screen.
-
Parameters:
-
frameIndex(number): Which frame to draw -
x,y(number): Screen position -
flip(boolean, optional): Horizontal flip
-
- Returns: None
ss:drawFrame(0, 100, 100) -- Draw frame 0 at (100,100)
ss:drawFrame(1, 100, 100, true) -- Flippedlocal spritesheet = picocalc.graphics.image.load("/apps/myapp/character.png")
local ss = picocalc.graphics.spritesheet.newGrid(spritesheet, 4, 4, 32, 32)
local frame = 0
local timer = 0
while true do
picocalc.display.clear(picocalc.display.BLACK)
timer = timer + 1
if timer > 5 then -- Change frame every 5 frames
frame = (frame + 1) % ss:getFrameCount()
timer = 0
end
ss:drawFrame(frame, 144, 144)
picocalc.display.flush()
endCustom font loading and text rendering. Font objects can be passed to text rendering functions throughout the graphics API.
Creates a new font object from a built-in font ID.
-
Parameters:
-
fontId(number): One of theFONT_*constants (e.g.,picocalc.display.FONT_6X8)
-
- Returns: (userdata) Font object
local font = picocalc.graphics.font.new(picocalc.display.FONT_8X12)Draws text at the specified position using this font.
-
Parameters:
-
x(number): X coordinate -
y(number): Y coordinate -
text(string): Text to draw -
fg(number): Foreground RGB565 color -
bg(number, optional): Background RGB565 color
-
- Returns: None
font:drawText(10, 10, "Hello!", picocalc.display.WHITE)Draws text with alignment using this font.
-
Parameters:
-
x(number): X coordinate -
y(number): Y coordinate -
text(string): Text to draw -
alignment(number): 0 = left, 1 = center, 2 = right -
fg(number): Foreground RGB565 color -
bg(number, optional): Background RGB565 color
-
- Returns: None
font:drawTextAligned(160, 10, "Centered", 1, picocalc.display.WHITE)Draws word-wrapped text within a bounding rectangle using this font. Monospace fonts only.
-
Parameters:
-
x(number): Left edge of bounding rectangle -
y(number): Top edge of bounding rectangle -
w(number): Width of bounding rectangle -
h(number): Height of bounding rectangle -
text(string): Text to draw -
alignment(number, optional): 0 = left (default), 1 = center, 2 = right -
fg(number, optional): Foreground RGB565 color -
bg(number, optional): Background RGB565 color
-
- Returns: None
local font = picocalc.graphics.font.new(picocalc.display.FONT_SCIENTIFICA)
font:drawTextInRect(10, 10, 200, 100, "This text will wrap within the rectangle.", 0,
picocalc.display.WHITE, picocalc.display.BLACK)Returns the font's character height in pixels.
- Returns: (number) Height in pixels
Returns the font's character width in pixels.
- Returns: (number) Width in pixels
Returns the pixel width of text rendered in this font.
-
Parameters:
-
text(string): Text to measure
-
- Returns: (number) Width in pixels
local w = font:getTextWidth("Hello")Returns the name of the font.
- Returns: (string) Font name
Tilemap system for tile-based game worlds. Tilemaps use an image atlas as a tileset and render visible tiles to the screen with scroll offset support.
Creates a new tilemap using an image atlas as the tileset. Tiles are indexed 1-based (0 = empty/transparent). Tiles are extracted from the tileset image left-to-right, top-to-bottom.
-
Parameters:
-
image(userdata): Tileset image (image atlas containing all tile graphics) -
tileWidth(number): Width of each tile in pixels -
tileHeight(number): Height of each tile in pixels
-
- Returns: (userdata) Tilemap object
local tileset = picocalc.graphics.image.load(APP_DIR .. "/tileset.png")
local tilemap = picocalc.graphics.tilemap.new(tileset, 16, 16)Allocates the tile grid. Maximum 128x128 tiles. Tile data is stored in PSRAM.
-
Parameters:
-
width(number): Grid width in tiles -
height(number): Grid height in tiles
-
- Returns: None
tilemap:setSize(40, 30)Sets the tile at a grid position. Tile index is 1-based; 0 = empty/transparent.
-
Parameters:
-
x(number): Grid X position -
y(number): Grid Y position -
tileIndex(number): Tile index (1-based, 0 = empty)
-
- Returns: None
tilemap:setTileAtPosition(5, 3, 1) -- Place tile 1 at grid (5,3)
tilemap:setTileAtPosition(5, 4, 0) -- Clear tile at grid (5,4)Returns the tile index at a grid position. Returns 0 for empty or out-of-bounds positions.
-
Parameters:
-
x(number): Grid X position -
y(number): Grid Y position
-
- Returns: (number) Tile index (0 = empty)
local tile = tilemap:getTileAtPosition(5, 3)Returns the tilemap dimensions in tiles.
-
Returns: (number, number)
width, height
local w, h = tilemap:getSize()Returns the tile dimensions in pixels.
-
Returns: (number, number)
tileWidth, tileHeight
local tw, th = tilemap:getTileSize()Returns the total tilemap dimensions in pixels.
-
Returns: (number, number)
pixelWidth, pixelHeight
local pw, ph = tilemap:getPixelSize()Draws visible tiles to the framebuffer with scroll offset. Only draws tiles visible on the 320x320 screen.
-
Parameters:
-
scrollX(number): Horizontal scroll offset in pixels -
scrollY(number): Vertical scroll offset in pixels
-
- Returns: None
tilemap:draw(cameraX, cameraY)-- Load tileset and create tilemap
local tileset = picocalc.graphics.image.load(APP_DIR .. "/tileset.png")
local tilemap = picocalc.graphics.tilemap.new(tileset, 16, 16)
tilemap:setSize(40, 30)
-- Fill with grass (tile 1), add some walls (tile 2)
for y = 0, 29 do
for x = 0, 39 do
tilemap:setTileAtPosition(x, y, 1) -- grass
end
end
-- Add border walls
for x = 0, 39 do
tilemap:setTileAtPosition(x, 0, 2) -- top wall
tilemap:setTileAtPosition(x, 29, 2) -- bottom wall
end
-- Create wall collision sprites for tile index 2
local wallCount = picocalc.graphics.sprite.addWallSprites(tilemap, {2})
-- Scroll camera
local scrollX, scrollY = 0, 0
while true do
picocalc.display.clear(picocalc.display.BLACK)
tilemap:draw(scrollX, scrollY)
picocalc.graphics.sprite.update()
picocalc.display.flush()
endBuilding a game? These pages cover APIs that pair well with the graphics functions above:
- API Game — camera, scene management, and save helpers
- API TCP — raw TCP/TLS sockets
- API Zip — ZIP archive extraction
- API JSON — JSON encoding/decoding