WIN320 — windowed UI
WIN320.DLL is a lightweight windowed UI library for Sprinter in mode #81
(320×256, 256 colours). It is not a framework: the library provides a set of
ready-made building blocks — panels, buttons, edit fields, listboxes,
scrollbars, progress bars, icons, checkboxes and radio buttons — from which
an application in assembly, C (SDCC) or Turbo Pascal assembles an interface
in the GFX Viewer / Flex Navigator style. Everything is drawn by the Sprinter
hardware accelerator, but that is an implementation detail, not part of the
interface.
The shared DLL loading rules are in the libraries overview.
Two ways of working
Section titled “Two ways of working”- Declarative — controls are described by structures, references to them
are collected into a
WinItem[]array, the array into aWinWindow. The window is drawn with a singlewin_drawcall and then updated selectively: the application changes a control’s state, sets theWIN_IT_DIRTYflag and callswin_update— only the changed items are redrawn. - Imperative — the same structures are passed directly to
win_button,win_panel,win_labeland so on, without a window or arrays.
The structures are identical on both paths: a button descriptor from a window list works unchanged in a direct call.
Quick start (assembly)
Section titled “Quick start (assembly)” include "win320.inc"
ld bc,#0050 ; DSS SETVMOD ld a,#81 ; the application enables mode 320x256x256 rst #10
ld hl,dll_name ; "WIN320.DLL",0 ld a,3 ; DLL — into window WIN3 call LIBMAN.l_load jp c,load_error ld (dll_handle),hl ; the font is already loaded from the DLL tail
; GUI palette + clear the screen with the desktop colour ld e,WIN_STYLE_PALETTE|WIN_STYLE_CLEAR ld d,#FF ; #FF = desktop colour from the theme ld b,WIN_STYLE call api jr nz,win_error ...api: ld hl,(dll_handle) call LIBMAN.l_call ; arguments: A, DE, IX, IY ret c ; CF — libman dispatcher error or a ; ZF from the WIN320 status retWalkthrough: the application enables the mode itself, loads the DLL into WIN3
(code, data and stack are best kept in WIN0–WIN2) and calls win_style first
of all — it installs the GUI palette and fills the screen. Without the
palette every colour comes out black, so this call is mandatory. The api
helper is a typical idiom: the two error levels (the dispatcher’s CF and the
status in A; 0 — success, #20..#28 — WIN_ERR_* codes) are checked in
one place.
Coordinates and the theme
Section titled “Coordinates and the theme”Every drawable structure starts with the same header: x, y, width,
height. Coordinates are measured from the origin — the screen corner by
default, or the window corner while a window is being drawn. A dialog is
therefore moved by editing the two WinWindow.x/y fields, with no control
coordinates to recalculate.
Colours are almost never given explicitly: the value #FF in any colour
field means “take it from the theme”. The theme is 18 colour roles (light and
shadow of the 3D bevels, panel face, desktop background, text, edit field,
selection, window title…) set with a single win_set_theme call — and the
whole interface is recoloured.
A declarative window
Section titled “A declarative window”window: dw 32,20,256,216 ; x, y, width, height db #FF ; body colour — from the theme db 0 ; window flags db 7 ; number of items db 2 ; index of the focused item dw items ; WinItem[] array dw title ; title (0 — no title bar) db #FF ; title colour — from the theme db 0 ; internal field
items: ; 8 bytes per entry: type, flags, id, pointer, user_data db WIN_T_BUTTON, WIN_IT_HIT|WIN_IT_FOCUSABLE|WIN_IT_PRESS db ID_OK dw ok_button ; -> WinButton structure dw 0 ...win_draw renders the whole window; win_update redraws only entries
carrying the WIN_IT_DIRTY flag (and clears it). The typical loop: handle an
event → change the control’s state → set dirty → win_update.
A window may have a title bar with a close button (WinWindow.title plus the
WIN_WND_CLOSE flag) — the strip is drawn automatically, and a full click on
the close button arrives as the WIN_EV_CLOSE event.
Modal dialogs
Section titled “Modal dialogs”win_open saves the background under the window into memory pages allocated
by the application (win_set_backstore) and draws the window; win_close
restores the background. The stack holds up to four nested windows, strictly
last-opened-first-closed. On an error in the item list win_open rolls back
atomically — no half-drawn dialog is left on screen.
Events
Section titled “Events”Two polling styles, both through a WinTrack structure owned by the
application:
win_poll— one non-blocking iteration: no event meansWIN_EV_NONE, and the application can do background work;win_track— blocks until an event (with theWIN_TRK_HALTflag it waits economically viaHALT).
Events: left/right clicks, auto-repeat, hover/leave, hotkeys from a
WinKey[] table, arbitrary keys, focus changes, checkbox/radio changes, a
click outside all objects, and the window close button. Along with the event
come the item index and id, the sub-area (e.g. a scrollbar arrow or a listbox
row) and the mouse coordinates.
Keyboard focus is handled by the library: Tab/Shift+Tab cycle through items
with the WIN_IT_FOCUSABLE flag, Enter presses the focused button, Space
toggles a checkbox, arrows move within a radio group.
The mouse driver is initialised by the application (BIOS RST #30, C=0) —
the library only reads it and manages the cursor.
Controls
Section titled “Controls”- Edit field (
win_edit) — modal editing directly in the application’s buffer: caret, Backspace/Delete, Home/End, word jumps with Ctrl+←/→, Esc rollback, click-to-position, password mode. - Listbox — rows either as an array of pointers or in memory pages (up to 5461 entries); redrawing is differential, a one-row shift uses fast hardware scrolling.
- Scrollbar — recomputes its thumb from
first/visible/totalitself; the arrows are serviced by the control, hit-testing reports the sub-area. - Progress bar — the unit is a percent; only the difference is redrawn.
- Icons — 8×8 and 16×16 from the application’s memory pages, with
#FFhardware transparency; thewiniconpack.pypacker builds them from PNG/BMP. - Checkbox and radio buttons — state, group exclusivity, mouse and
keyboard reactions all live inside the library; the application receives a
ready-made
WIN_EV_CHANGE.
Example (C, SDCC)
Section titled “Example (C, SDCC)”static win_button_t ok = {40, 154, 72, 20, 0xff, 0, 0}; /* x,y,w,h,attr,flags,text */static win_item_t items[7];static win_window_t window = {32, 20, 256, 216, 0xff, 0, 7, 2, 0, 0xff, 0};static win_track_t track;
win320_bind(handle); /* attach wrappers to the DLL */win320_set_text_format(WIN_TXT_ASCIIZ);win320_draw(&window); /* render the whole window */for (;;) { if (win320_poll(&track)) break; /* ABI error */ if (track.event == WIN_EV_NONE) continue;/* background work here */ if (track.id == ID_CANCEL) break; items[STATUS_INDEX].flags |= WIN_IT_DIRTY; win320_update(&window, &drawn); /* redraw only dirty items */}The package implements the same dialog three times — dialog.asm, dialog.c
and DIALOG.PAS — convenient for comparing the languages. Turbo Pascal gets
records and LibCall helpers, and the string format can be switched to
“length byte” with win_set_text_format, so edit fields work directly with
string[n].
Limitations
Section titled “Limitations”- The application enables mode
#81and switches the visible screen itself; the library can draw into either of the two buffers (win_set_screen). - Call data must not live in the DLL’s window: during a call the library
itself is mapped there. Mutable structures (the window, the edit buffer,
WinTrack) belong in writable RAM; in C they must not beconst. - The library is not reentrant: do not call it from interrupt handlers.
- Do not print through the DSS console while the graphics mode is active (see the overview).
Package contents
Section titled “Package contents”| File | Purpose |
|---|---|
WIN320.DLL |
the library; the font is embedded in the file tail |
win320.inc |
constants and field offsets for sjasmplus |
bind/win320.h, bind/win320.lib |
header and wrappers for C (SDCC) |
bind/WIN320.INC |
records and helpers for Turbo Pascal |
examples/dialog.asm, dialog.c, DIALOG.PAS |
one dialog in three languages |
tools/winiconpack.py |
icon packer for PNG/BMP |
WIN320.EXE |
visual test; applications do not need it |