DVI Module
The DVI module provides a low-level API for controlling DVI output and drawing on screen.
Harucom has two display modes: text mode and graphics mode. In graphics mode, you can draw at the pixel level, including shapes and text.
For easier drawing, use the P5 Drawing Library, which wraps DVI::Graphics.
Table of Contents
- Basic Usage
- DVI Module Methods
- DVI::Text (Text Mode)
- DVI::Graphics (Graphics Mode)
- Color Format
- Font List
Basic Usage
Text Mode
DVI.set_mode(DVI::TEXT_MODE)
# Clear screen (black background, white text)
attr = (DVI::Text::WHITE << 4) | DVI::Text::BLACK
DVI::Text.clear(attr)
# Display a string
DVI::Text.put_string(0, 0, "Hello, world!", attr)
DVI::Text.commit
Graphics Mode
DVI.set_mode(DVI::GRAPHICS_MODE)
G = DVI::Graphics
# Fill the screen with black
G.fill(0x00)
# Draw a red circle
G.fill_circle(160, 120, 50, 0xE0)
# Draw text
G.draw_text(10, 10, "Hello!", 0xFF, G::FONT_MPLUS_12)
G.commit
DVI Module Methods
DVI.set_mode(mode)
DVI.set_mode(DVI::TEXT_MODE)
DVI.set_mode(DVI::GRAPHICS_MODE)
Switches the display mode. The switch takes effect at the next VBlank.
| Constant | Mode |
|---|---|
DVI::TEXT_MODE |
Text mode (106 columns x 37 rows) |
DVI::GRAPHICS_MODE |
Graphics mode (640x480 or 320x240) |
DVI.wait_vsync
DVI.wait_vsync
Waits until the next VBlank (vertical blanking interval).
DVI.frame_count
DVI.frame_count #=> Integer
Returns the number of frames since DVI output started. Increases at approximately 60 frames per second.
DVI::Text (Text Mode)
In text mode, you can place characters on a 106-column x 37-row screen. Each cell has a character code and an attribute (foreground and background color).
Screen Size
| Constant | Value |
|---|---|
DVI::Text::COLS |
106 (columns) |
DVI::Text::ROWS |
37 (rows) |
Color Constants
The following constants can be used for foreground and background colors in attributes.
| Constant | Color |
|---|---|
DVI::Text::BLACK |
Black |
DVI::Text::BLUE |
Blue |
DVI::Text::GREEN |
Green |
DVI::Text::CYAN |
Cyan |
DVI::Text::RED |
Red |
DVI::Text::MAGENTA |
Magenta |
DVI::Text::BROWN |
Brown |
DVI::Text::LIGHT_GRAY |
Light gray |
DVI::Text::DARK_GRAY |
Dark gray |
DVI::Text::LIGHT_BLUE |
Light blue |
DVI::Text::LIGHT_GREEN |
Light green |
DVI::Text::LIGHT_CYAN |
Light cyan |
DVI::Text::LIGHT_RED |
Light red |
DVI::Text::LIGHT_MAGENTA |
Light magenta |
DVI::Text::YELLOW |
Yellow |
DVI::Text::WHITE |
White |
Building Attributes
An attribute is a 1-byte value where the upper 4 bits are the foreground color and the lower 4 bits are the background color.
# White text, black background
attr = (DVI::Text::WHITE << 4) | DVI::Text::BLACK
# Yellow text, blue background
attr = (DVI::Text::YELLOW << 4) | DVI::Text::BLUE
Displaying Characters
DVI::Text.put_char(col, row, ch, attr)
DVI::Text.put_char(0, 0, 65, attr) # Display 'A'
Places the character code ch at position (col, row) with attribute attr.
DVI::Text.put_string(col, row, str, attr)
DVI::Text.put_string(0, 0, "Hello!", attr)
Displays a UTF-8 string starting at position (col, row) with attribute attr. Full-width characters (such as Japanese) are also supported.
Clearing the Screen
DVI::Text.clear(attr)
DVI::Text.clear(attr)
Clears the entire screen with the specified attribute.
DVI::Text.clear_line(row, attr)
DVI::Text.clear_line(5, attr)
Clears the specified row with attribute attr.
DVI::Text.clear_range(col, row, width, attr)
DVI::Text.clear_range(10, 5, 20, attr)
Clears width cells starting at position (col, row) with attribute attr.
Scrolling
DVI::Text.scroll_up(lines, attr)
DVI::Text.scroll_up(1, attr)
Scrolls the screen up by the specified number of lines. Empty lines at the bottom are filled with attribute attr.
DVI::Text.scroll_down(lines, attr)
DVI::Text.scroll_down(1, attr)
Scrolls the screen down by the specified number of lines. Empty lines at the top are filled with attribute attr.
Attribute Operations
DVI::Text.get_attr(col, row)
a = DVI::Text.get_attr(0, 0)
Returns the attribute of the cell at position (col, row).
DVI::Text.set_attr(col, row, attr)
DVI::Text.set_attr(0, 0, attr)
Changes the attribute of the cell at position (col, row).
Line Reading and Writing
DVI::Text.read_line(row)
line = DVI::Text.read_line(0)
Reads the contents of the specified row as a DVI::Text::Line object.
Can be used for scroll-back buffers, etc.
DVI::Text.write_line(row, line)
DVI::Text.write_line(5, line)
Writes a DVI::Text::Line object (read by read_line) to the specified row.
Flushing to Display
DVI::Text.commit
DVI::Text.commit
Copies the back buffer to the front buffer for display. Waits for VBlank before copying, so no screen flickering occurs.
DVI::Graphics (Graphics Mode)
In graphics mode, you can draw on screen at the pixel level. Colors are specified in RGB332 format (1 byte).
Screen Control
DVI::Graphics.width
DVI::Graphics.width #=> 640 or 320
Returns the framebuffer width in pixels.
DVI::Graphics.height
DVI::Graphics.height #=> 480 or 240
Returns the framebuffer height in pixels.
DVI::Graphics.set_resolution(width, height)
DVI::Graphics.set_resolution(320, 240) # Switch to 320x240
DVI::Graphics.set_resolution(640, 480) # Switch back to 640x480
Switches the screen resolution. The two available options are 640x480 (default) and 320x240.
DVI::Graphics.fill(color)
DVI::Graphics.fill(0x00) # Fill the screen with black
Fills the entire screen with the specified RGB332 color.
DVI::Graphics.commit
DVI::Graphics.commit
Waits for VBlank, then copies the back buffer to the front buffer for display. Call this after all drawing for one frame is complete.
Pixel Operations
DVI::Graphics.set_pixel(x, y, color)
DVI::Graphics.set_pixel(100, 50, 0xFF)
Sets the pixel at (x, y) to the specified RGB332 color.
DVI::Graphics.get_pixel(x, y)
c = DVI::Graphics.get_pixel(100, 50)
Returns the RGB332 color value of the pixel at (x, y). Returns 0 if the coordinates are out of bounds.
Drawing Shapes
Shape drawing methods come in two types: filled (prefixed with fill_) and outline-only (prefixed with draw_).
DVI::Graphics.fill_rect(x, y, w, h, color)
DVI::Graphics.fill_rect(10, 10, 100, 50, 0xE0)
Draws a filled rectangle with (x, y) as the top-left corner, width w, and height h.
DVI::Graphics.draw_rect(x, y, w, h, color)
DVI::Graphics.draw_rect(10, 10, 100, 50, 0xFF)
Draws a rectangle outline with (x, y) as the top-left corner, width w, and height h.
DVI::Graphics.fill_circle(cx, cy, r, color)
DVI::Graphics.fill_circle(160, 120, 50, 0xE0)
Draws a filled circle centered at (cx, cy) with radius r.
DVI::Graphics.draw_circle(cx, cy, r, color)
DVI::Graphics.draw_circle(160, 120, 50, 0xFF)
Draws a circle outline centered at (cx, cy) with radius r.
DVI::Graphics.fill_ellipse(cx, cy, rx, ry, color)
DVI::Graphics.fill_ellipse(160, 120, 80, 40, 0xE0)
Draws a filled ellipse centered at (cx, cy) with horizontal radius rx and vertical radius ry.
DVI::Graphics.draw_ellipse(cx, cy, rx, ry, color)
DVI::Graphics.draw_ellipse(160, 120, 80, 40, 0xFF)
Draws an ellipse outline centered at (cx, cy).
DVI::Graphics.fill_triangle(x0, y0, x1, y1, x2, y2, color)
DVI::Graphics.fill_triangle(100, 10, 50, 90, 150, 90, 0x1C)
Draws a filled triangle connecting three vertices.
DVI::Graphics.fill_arc(cx, cy, r, start_angle, stop_angle, color)
DVI::Graphics.fill_arc(160, 120, 50, 0, Math::PI / 2, 0xE0)
Draws a filled arc sector. Angles are in radians (0 is right, PI/2 is down).
DVI::Graphics.draw_arc(cx, cy, r, start_angle, stop_angle, color)
DVI::Graphics.draw_arc(160, 120, 50, 0, Math::PI / 2, 0xFF)
Draws an arc sector outline.
Drawing Lines
DVI::Graphics.draw_line(x0, y0, x1, y1, color)
DVI::Graphics.draw_line(0, 0, 100, 100, 0xFF)
Draws a line from (x0, y0) to (x1, y1).
DVI::Graphics.draw_thick_line(x0, y0, x1, y1, thickness, color)
DVI::Graphics.draw_thick_line(0, 0, 100, 100, 3, 0xFF)
Draws a line with the specified thickness in pixels.
Drawing Text
DVI::Graphics.draw_text(x, y, text, color, font = FONT_8X8, wide_font = nil)
# Basic usage
DVI::Graphics.draw_text(10, 10, "Hello!", 0xFF)
# Specify a font
DVI::Graphics.draw_text(10, 10, "Hello!", 0xFF, DVI::Graphics::FONT_MPLUS_12)
# Also specify a Japanese font
DVI::Graphics.draw_text(10, 10, "こんにちは", 0xFF,
DVI::Graphics::FONT_MPLUS_12, DVI::Graphics::FONT_MPLUS_J12)
Draws a UTF-8 string at position (x, y). The 5th argument specifies the font, and the 6th argument specifies a wide font for full-width characters.
DVI::Graphics.text_width(text, font = FONT_8X8, wide_font = nil)
w = DVI::Graphics.text_width("Hello!", DVI::Graphics::FONT_MPLUS_12)
Returns the width in pixels that the string would occupy when drawn (without actually drawing it).
DVI::Graphics.font_height(font)
h = DVI::Graphics.font_height(DVI::Graphics::FONT_MPLUS_12)
Returns the glyph height of the specified font in pixels.
Drawing Images
DVI::Graphics.draw_image(data, x, y, w, h)
DVI::Graphics.draw_image(pixel_data, 10, 10, 32, 32)
Draws RGB332 image data (byte array) at position (x, y). The data length must be at least w * h bytes.
DVI::Graphics.draw_image_masked(data, mask, x, y, w, h)
DVI::Graphics.draw_image_masked(pixel_data, mask_data, 10, 10, 32, 32)
Draws an image with a transparency mask. The mask is 1bpp (1 bit per pixel), where 1 bits are opaque and 0 bits are transparent. The mask length must be at least (w * h + 7) / 8 bytes.
Blend Modes
DVI::Graphics.set_blend_mode(mode)
DVI::Graphics.set_blend_mode(DVI::Graphics::BLEND_ADD)
Changes the pixel compositing method.
| Constant | Behavior |
|---|---|
DVI::Graphics::BLEND_REPLACE |
Overwrite (default) |
DVI::Graphics::BLEND_ADD |
Per-channel addition (saturating) |
DVI::Graphics::BLEND_SUBTRACT |
Per-channel subtraction (saturating) |
DVI::Graphics::BLEND_MULTIPLY |
Per-channel multiply |
DVI::Graphics::BLEND_SCREEN |
Per-channel screen compositing |
DVI::Graphics::BLEND_ALPHA |
Alpha blending (set opacity with set_alpha) |
DVI::Graphics.set_alpha(alpha)
DVI::Graphics.set_alpha(128) # Semi-transparent
Sets the opacity (0-255) for BLEND_ALPHA mode.
0 is fully transparent, 255 is fully opaque.
Color Format
In graphics mode, colors are specified in RGB332 format (1 byte).
Bits 7-5: Red (0-7)
Bits 4-2: Green (0-7)
Bits 1-0: Blue (0-3)
Common color examples:
| Value | Color |
|---|---|
0x00 |
Black |
0xFF |
White |
0xE0 |
Red |
0x1C |
Green |
0x03 |
Blue |
0xFC |
Yellow |
You can use the color(r, g, b) method from the P5 Drawing Library to convert standard RGB values (0-255) to RGB332.
Font List
Font constants available in DVI::Graphics.
| Constant | Description |
|---|---|
FONT_8X8 |
8x8 monospace font |
FONT_MPLUS_12 |
M+ 12px proportional font |
FONT_FIXED_4X6 |
Misc-Fixed 4x6 monospace font |
FONT_FIXED_5X7 |
Misc-Fixed 5x7 monospace font |
FONT_FIXED_6X13 |
Misc-Fixed 6x13 monospace font |
FONT_SPLEEN_5X8 |
Spleen 5x8 monospace font |
FONT_SPLEEN_8X16 |
Spleen 8x16 monospace font |
FONT_SPLEEN_12X24 |
Spleen 12x24 monospace font |
FONT_DENKICHIP |
DenkiChip 12px font (ASCII) |
FONT_MPLUS_J12 |
M+ 12px Japanese font (JIS X 0208) |
FONT_DENKICHIP_J |
DenkiChip 12px Japanese font (JIS X 0208) |
To display full-width characters such as Japanese, specify FONT_MPLUS_J12 or FONT_DENKICHIP_J
as the wide_font argument of draw_text.