DVX_GUI/src/apps/kpunch
2026-10-14 17:37:03 -05:00
..
basdemo VESA 1.2 supported! 2026-10-14 17:37:03 -05:00
clock Major font work, terminal enhancements. 2026-10-14 12:30:57 -05:00
cpanel VESA 1.2 supported! 2026-10-14 17:37:03 -05:00
dvxbasic VESA 1.2 supported! 2026-10-14 17:37:03 -05:00
dvxdemo VESA 1.2 supported! 2026-10-14 17:37:03 -05:00
dvxhelp VESA 1.2 supported! 2026-10-14 17:37:03 -05:00
fileMgr Major font work, terminal enhancements. 2026-10-14 12:30:57 -05:00
iconed VESA 1.2 supported! 2026-10-14 17:37:03 -05:00
imgview Major font work, terminal enhancements. 2026-10-14 12:30:57 -05:00
notepad Major font work, terminal enhancements. 2026-10-14 12:30:57 -05:00
progman VESA 1.2 supported! 2026-10-14 17:37:03 -05:00
resedit Major font work, terminal enhancements. 2026-10-14 12:30:57 -05:00
terminal VESA 1.2 supported! 2026-10-14 17:37:03 -05:00
welcome Major font work, terminal enhancements. 2026-10-14 12:30:57 -05:00
widshow New toolchain installer. Serious number of bugs fixed. New Program Manager and File Manager. TCP/IP and printing added. SQLite upgraded. Safe video mode startup added. File associations. Terminal program. First run welcome. New docs. Whew. 2026-09-28 15:31:13 -05:00
Makefile Major font work, terminal enhancements. 2026-10-14 12:30:57 -05:00
README.md VESA 1.2 supported! 2026-10-14 17:37:03 -05:00

DVX Shell Applications

Every DVX application is a DXE3 module packaged as a .app file, installed under bin/apps/kpunch/<name>/<name>.app. The Program Manager scans this directory at startup and displays each discovered app as a launchable icon on the desktop.

This directory holds the source for the bundled applications plus the BASIC-based sample apps. Two flavours of app live side by side:

  • C apps -- written directly against the DVX SDK headers, compiled to a DXE3 by dxe3gen. See progman/, dvxdemo/, cpanel/, dvxhelp/.
  • BASIC apps -- .dbp projects compiled to .app files by the host-side bascomp. The compiler links the BASIC bytecode into a copy of basstub.app, which acts as the runtime host. See iconed/, notepad/, imgview/, basdemo/, resedit/, widshow/, dvxhelp/helpedit/, clock/, welcome/, fileMgr/, terminal/.

The rest of this document covers writing a C app against the SDK. For BASIC apps, see dvxbasic/README.md. A new app outside this tree starts from the SDK templates (bin/sdk/newProject.sh app|basic NAME, sources in src/sdk/).

DXE App Contract

Every .app binary exports two required symbols and one optional symbol:

AppDescriptorT appDescriptor;                    // required (SHELL_APP_DESCRIPTOR)
int32_t        appMain(DxeAppContextT *ctx);     // required
void           appShutdown(void);                // optional

appDescriptor

A statically-initialised struct read by the shell at load time to decide how to launch the app. Declare it with SHELL_APP_DESCRIPTOR, which names the global and records the DVX_ABI_VERSION the app was built with; the shell refuses an app whose abiVersion differs ("This program was built for a different version of DVX and cannot run.").

typedef struct {
    uint32_t abiVersion;                 // set by SHELL_APP_DESCRIPTOR; first
    char    name[SHELL_APP_NAME_MAX];    // display name (<= 64 chars)
    bool    hasMainLoop;                 // see below
    bool    multiInstance;               // may have multiple copies open
    int32_t stackSize;                   // SHELL_STACK_DEFAULT or byte count
    int32_t priority;                    // TS_PRIORITY_* for main-loop apps
} AppDescriptorT;

Example (from the SDK's game template, src/sdk/templates/game/tplName.c):

SHELL_APP_DESCRIPTOR(
    .name          = TPLNAME_TITLE,
    .hasMainLoop   = true,
    .multiInstance = false,
    .stackSize     = SHELL_STACK_DEFAULT,
    .priority      = TS_PRIORITY_NORMAL
);

appMain

Entry point. The shell calls it with a DxeAppContextT that exposes the shell's GUI context, the app's ID, its install directory, its writable folder in the user folder (userDir: shellEnsureUserDir, shellUserPath; shipped files are in DATA/ beside the .app: shellDataPath), launch arguments, and a help-topic query callback for F1.

Returning from appMain signals that the app has finished; the shell unloads the DXE, frees per-app memory, and reclaims the app slot.

appShutdown

Called by the shell when the app is force-killed (by the Task Manager) or when the shell is shutting down with this app still running. Main-loop apps use it to set a flag that their main loop observes, so the loop exits cleanly and appMain can return.

App Types

Callback-only apps (hasMainLoop = false)

appMain creates windows, registers callbacks, and returns 0. The shell drives all further work by invoking those callbacks in response to user input and timers. No dedicated task is allocated; no per-app stack is consumed. The app's lifetime ends when the last window closes (or when every callback has released all references).

Use this pattern for event-driven UI: Notepad, Program Manager, DVX Demo, Control Panel, Image Viewer.

Main-loop apps (hasMainLoop = true)

The shell creates a cooperative task for the app and calls appMain from inside it. appMain runs a loop that calls tsYield() periodically to share the CPU. Exit by breaking out of the loop and returning.

Use this pattern when the app needs continuous background work that does not map cleanly onto event callbacks: terminal emulators, games, and every compiled BASIC program (the BASIC stub runs the program and its event loop in the app's task).

Resource Conventions

Apps attach resources to their .app binary using dvxres build (see src/tools/README.md). The standard resource names are:

Name Type Meaning
icon32 icon 32x32 BMP shown in Program Manager and the Task Manager.
name text Human-readable display name (overrides appDescriptor.name for UI where available).
author text Author / maintainer name.
publisher text Publisher or studio.
copyright text Copyright notice.
version text Version string, free-form.
description text One-sentence description, shown in Program Manager's status bar and List view.
helpfile text BASIC apps: name of the app's .hlp file, relative to the app's directory (the project's Help File); the BASIC stub sets F1 help from it. Not needed when the file is <app>.hlp, which the shell uses by default.

Additional application-specific resources may be attached with any unique name. The runtime reads them via dvxResOpen(appPath) / dvxResRead(handle, name, &size) / dvxResClose(handle).

Typical .res manifest:

# dvxdemo.res
icon32      icon  icon32.bmp
name        text  "DVX Demo"
author      text  "Scott Duensing"
copyright   text  "Copyright 2026 Scott Duensing"
publisher   text  "Kangaroo Punch Studios"
description text  "Widget toolkit demonstration"

Help

Every app has its own help file; the system help (the user guide plus the developer reference, opened from Program Manager) holds only material that applies to every app, and never lists or describes individual apps.

  • Write the help source as <app>.dhs next to <app>.c or <app>.dbp, where <app> is the name of the .app file.
  • The top-level compile-help target runs src/tools/helpFiles.sh, which finds every such file by name, compiles it to <app>.hlp next to <app>.app, deploys the source as <APP>.DHS, and writes an <APP>.HCF so the loader's boot-time help rebuild produces it too. No list needs editing when an app is added.
  • F1 needs no code: before appMain the shell sets ctx->helpFile to <app>.hlp beside <app>.app when that file exists.
  • C apps open it from Help > Contents with shellOpenHelp(ctx->shellCtx, ctx->helpFile).
  • BASIC apps call HelpView "<app>.hlp" (from src/include/basic/help.bas) from Help > Contents. F1 opens the focused control's or form's HelpTopic.
  • Every app's Help menu has Contents and About.

See claudeDocs/perAppHelp.md for the full rules.

Bundled Applications

Program Manager (progman)

File apps/kpunch/progman/progman.app
Type Callback-only
Multi-instance No

The desktop: program groups in a list on the left, the selected group's items as large icons, small icons, or a list on the right, a search box that filters every group, and a status bar. The automatic "Installed Programs" group is rebuilt from shellProgramScan() at start, on View > Refresh, and when the window comes to the front with programs added or removed; items in the "Startup" group run once DVX is up. Groups, items (name, program, arguments, working folder, icon, shortcut key, run minimized, grid cell), view, options, and Run history are saved in USER/APPS/KPUNCH/PROGMAN/PROGMAN.INI after every change (crash-safe rewrite). Running, the Run dialog, program discovery, and file associations are shell library services (shellRun.h, shellProg.h, shellAssoc.h) shared with other programs. Closing it exits DVX through shellRequestExit(); shellRegisterDesktopUpdate() keeps the running count current. Design notes: claudeDocs/programManager.md.

Sources: progman.c (window, menus, commands), pmModel.c (groups, items, PROGMAN.INI; no widgets, host-tested), pmView.c (the icon view, a private widget class), pmProps.c (item Properties dialog). Its own help is progman.dhs (progman.hlp). The directory also owns the system help: dvxhelp.hcf (on-target rebuild recipe) and userHelp.dhs, the end-user guide that is compiled first so its user.welcome page is the help file's default topic.

Notepad (notepad, BASIC)

File apps/kpunch/notepad/notepad.app
Type BASIC (main-loop via basstub)
Multi-instance No

Plain-text editor with File menu (New, Open, Save, Save As) and Edit menu (Cut, Copy, Paste, Select All). Built from a BASIC project (notepad.dbp + notepad.frm); demonstrates the form designer, TextInput widget, and common dialog integration.

Clock (clock, BASIC)

File apps/kpunch/clock/clock.app
Type BASIC (main-loop via basstub)
Multi-instance Yes

Digital clock showing the time and date, updated by a Timer. Each new copy opens a little lower and to the right of the previous one (ShellInstanceCount, shell.bas). Built from clock.dbp + clock.frm; its help is clock.dhs.

Welcome (welcome, BASIC)

File apps/kpunch/welcome/welcome.app
Type BASIC (main-loop via basstub)
Multi-instance No

The window DVX shows after the desktop when it starts for the first time (DVX.INI [shell] welcome, written by Setup). "Don't show this again" removes the key when the window closes; unticked, it writes the program's path back (ShellSetWelcome, shell.bas). "Open the User Guide" opens the system help. Built from welcome.dbp + welcome.frm; its help is welcome.dhs.

File Manager (fileMgr, BASIC)

File apps/kpunch/fileMgr/fileMgr.app
Type BASIC (main-loop via basstub)
Multi-instance Yes

Drive buttons, a path box, a folder tree, and a sortable file list with open / run, copy, move, cut / copy / paste between windows, rename, delete, new folder, properties (attributes), selection, and filter commands. Copy, move, and delete run as jobs with their own progress windows, driven by a Timer, so the program stays usable. Built from fileMgr.dbp: fileMgr.frm (the window), fmProps.frm (Properties), fileMgr.bas (the job engine), fmJob.cls, with the fileops.bas, shell.bas, commdlg.bas, and help.bas libraries; its help is fileMgr.dhs.

Terminal (terminal, BASIC)

File apps/kpunch/terminal/terminal.app
Type BASIC (main-loop via basstub)
Multi-instance Yes (one per COM port, for example)

A BBS / serial terminal: serial port, modem (dialing, redial, carrier loss), the secure link to the DVX host proxy (with or without a passphrase), and Telnet; a phone book of sessions (TERMINAL.INI in its settings folder); the ANSI terminal with scrollback, colors, local echo, answerback, capture to file, and break; XMODEM, XMODEM-1K, YMODEM, and ZMODEM uploads and downloads (ZMODEM downloads start by themselves) with a progress window that asks about existing files. The connection, the terminal feed, and the transfers run in the conn and xfer libraries (conn.bas, xfer.bas); a 10 ms Timer moves them along. Started with telnet://host[:port] it connects to that host. Built from terminal.dbp: terminal.frm (the window), termBook.frm (Phone Book), termSess.frm (Session Settings), termXfer.frm (Transfer Options), termPass.frm (passphrase), termProg.frm (File Transfer), terminal.bas (the phone book and shared state), termMain.bas (the start), with the conn.bas, xfer.bas, prefs.bas, fileops.bas, shell.bas, commdlg.bas, and help.bas libraries; its help is terminal.dhs.

DVX Demo (dvxdemo)

File apps/kpunch/dvxdemo/dvxdemo.app
Type Callback-only
Multi-instance No

Widget toolkit showcase. Opens multiple windows demonstrating virtually every widget type:

  • Main window -- raw paint callbacks (gradients, patterns, text)
  • Widget demo -- form widgets (TextInput, Checkbox, Radio, ListBox)
  • Controls window -- tabbed advanced widgets (Dropdown, ProgressBar, Slider, Spinner, TreeView, ListView, ScrollPane, Toolbar, Canvas, Splitter, Image)
  • Terminal window -- AnsiTerm widget

Resources include logo.bmp, new.bmp, open.bmp, sample.bmp, save.bmp. Reference implementation for widget-based UIs.

Control Panel (cpanel)

File apps/kpunch/cpanel/cpanel.app
Type Callback-only
Multi-instance No

System configuration with five tabs:

  • Mouse -- scroll direction, wheel speed, double-click speed, acceleration, cursor speed
  • Colors -- every system colour with live preview; theme load and save
  • Desktop -- wallpaper image and display mode
  • Video -- resolution and colour depth switching
  • File Types -- file associations (cpTypes.c): add, change, and remove which program opens each extension

Changes preview live. OK writes to USER/DVX.INI and the file types to USER/ASSOC.INI (the user's changes to SYSTEM/ASSOC.INI, through shellAssocSet/shellAssocRemove); themes it saves go to USER/THEMES, and its lists show SHARED's and the user's together; Cancel reverts to the snapshot taken when the panel opened.

Image Viewer (imgview, BASIC)

File apps/kpunch/imgview/imgview.app
Type BASIC (main-loop via basstub)
Multi-instance No

Displays BMP, PNG, JPEG, and GIF images scaled to fit the window with aspect ratio preserved. Resize to zoom. Open via the File menu or via launch arguments. Built from a BASIC project using the Canvas widget.

DVX BASIC (dvxbasic)

File apps/kpunch/dvxbasic/dvxbasic.app
Type Callback-only
Multi-instance No

Visual Basic 3 compatible IDE: form designer, per-procedure code editor, project manager, compiler, and runtime VM. See dvxbasic/README.md for a detailed architecture description.

dvxbasic/ also builds:

  • bin/libs/kpunch/basrt/basrt.lib -- the BASIC runtime (VM + values) as a separately loadable library, so compiled BASIC apps do not carry their own copy of the runtime.
  • bin/apps/kpunch/dvxbasic/basstub.app -- the stub used as the template for every compiled BASIC app.

DVX Help Viewer (dvxhelp)

File apps/kpunch/dvxhelp/dvxhelp.app
Type Callback-only
Multi-instance Yes

Renders compiled .hlp files produced by dvxhlpc. Supports table of contents, keyword index, full-text search (trigram), hyperlinks, and inline images. The file is read with the hlpfile library (src/libs/kpunch/hlpfile) and topics are drawn by the HelpView widget (src/widgets/kpunch/helpView, BASIC type HelpPane), the same code a BASIC program uses through hlpfile.bas and HelpPane.

Icon Editor (iconed, BASIC)

File apps/kpunch/iconed/iconed.app
Type BASIC (main-loop via basstub)
Multi-instance No

Dot-by-dot editor for 16x16, 24x24, and 32x32 icons. Pencil / eraser / colour picker tools, 32-colour palette, BMP or PNG open, PNG (or BMP by extension) save.

Help Editor (helpedit, BASIC)

File apps/kpunch/dvxhelp/helpedit.app
Type BASIC (main-loop via basstub)
Multi-instance No

Editor for .dhs help source files with syntax highlighting. Build > Compile writes <name>.hlp next to the source; Build > Preview compiles and opens the result in the help viewer. Its own help is helpedit.hlp; Help > Help File Format opens the format reference in the viewer's dvxhelp.hlp.

Resource Editor (resedit, BASIC)

File apps/kpunch/resedit/resedit.app
Type BASIC (main-loop via basstub)
Multi-instance No

GUI wrapper around dvxres: open a .app / .wgt / .lib, browse its resources, add, replace, extract, or remove them.

BASIC Demo (basdemo, BASIC)

File apps/kpunch/basdemo/basdemo.app
Type BASIC (main-loop via basstub)
Multi-instance No

Gallery of short BASIC programs demonstrating the language and the form designer. Intended as sample source for reading.

Widget Showcase (widshow, BASIC)

File apps/kpunch/widshow/widshow.app
Type BASIC (main-loop via basstub)
Multi-instance No

One tabbed window exercising the standard BASIC controls, with tooltips and a status bar reporting each event. Shipped in the SDK as a sample project, with basdemo.

Build

make              # build every app (C apps + BASIC apps)
make <appname>    # build a single app
make clean        # remove all app build artifacts

The apps/kpunch/Makefile orchestrates both C and BASIC builds:

  • C apps are discovered: every directory <app>/ that holds <app>/<app>.c is one. All .c files in the directory are compiled and linked with dxe3gen -U into <app>.app, then resources are attached with dvxres build if <app>/<app>.res exists. No list needs editing.
  • BASIC apps run bascomp <app>.dbp -o <app>.app -release, which handles project-file parsing, compilation, resource attachment, and linking into basstub.app.

Build output goes to bin/apps/kpunch/<app>/<app>.app.

Writing a New C App

Minimal skeleton:

#include "dvxApp.h"
#include "dvxWgt.h"
#include "shellApp.h"

#include <stdint.h>
#include <stdbool.h>

// Prototypes
static int32_t appMainImpl(DxeAppContextT *ctx);
static void    onClose(WindowT *win);

// Required descriptor
SHELL_APP_DESCRIPTOR(
    .name          = "My App",
    .hasMainLoop   = false,
    .multiInstance = false,
    .stackSize     = SHELL_STACK_DEFAULT,
    .priority      = 0
);


static void onClose(WindowT *win) {
    (void)win;
    // Callback-only apps: nothing to do; the shell reaps us when
    // the last window closes.
}


int32_t appMain(DxeAppContextT *ctx) {
    return appMainImpl(ctx);
}


static int32_t appMainImpl(DxeAppContextT *ctx) {
    AppContextT *ac = ctx->shellCtx;

    WindowT *win = dvxCreateWindow(ac, appDescriptor.name, 100, 100, 320, 240, true);

    if (!win) {
        return -1;
    }

    win->onClose = onClose;
    return 0;
}

Put the source in apps/kpunch/<app>/<app>.c (more .c files in the same directory are linked in too), drop a .res manifest next to the source, and provide a 32x32 icon32.bmp. The Makefile finds the app by itself; make <app> then produces bin/apps/kpunch/<app>/<app>.app.

Files a program reads at run time (pictures, data) are installed beside it by one Makefile rule, for C and BASIC programs alike: list them in APP_DATA_<app> (relative to the program's source directory, <app> being the last part of that directory), as APP_DATA_dvxdemo does. make <app> copies them into the program's folder and make clean removes them; the program finds them through its own folder (App.Path in BASIC, the app context's appDir in C).

Testing Locally

After make, the app is deployed in-tree under bin/apps/kpunch/. Launch the full system (bin/dvx.exe) and the Program Manager picks up the new app automatically on the next boot.

To iterate quickly: rebuild the single app, restart DVX, and launch it. The log at bin/USER/DVX.LOG records load errors, missing dependencies, and per-app crash diagnostics.

Files

Each app's own help source <app>.dhs sits beside its .c or .dbp (see Help above). progman/, dvxbasic/, and dvxhelp/ also hold help configured by hand in the top-level Makefile and their .hcf files: the system help (progman/userHelp.dhs), the BASIC help, and the viewer's help.

apps/kpunch/
  Makefile               top-level app build
  README.md              this file

  # C apps
  progman/
    progman.c            Program Manager window, menus, commands
    pmModel.c/.h         groups, items, PROGMAN.INI
    pmView.c/.h          icon view widget class
    pmProps.c/.h         item Properties dialog
    progman.dhs          Program Manager's own help
    dvxhelp.hcf          help-compiler config (system reference)
    userHelp.dhs         end-user guide (first part of the system help)
  dvxdemo/
    dvxdemo.c            widget showcase
    dvxdemo.res
    icon32.bmp
    logo.bmp / new.bmp / open.bmp / sample.bmp / save.bmp
  cpanel/
    cpanel.c             Control Panel
    cpTypes.c/.h         File Types page
    cpanel.res
    icon32.bmp
  dvxhelp/
    dvxhelp.c            help viewer (reads .hlp files with the hlpfile
                         library, shows topics in the HelpView widget)
    dvxhelp.res
    help.dhs             source for the dvxhelp app's own help
    sample.dhs           small sample source
    icon32.bmp
    helpedit/            BASIC project: help editor
      helpedit.dbp
      helpedit.frm
      ICON32.BMP

  # BASIC apps
  iconed/
    iconed.dbp
    iconed.frm
    ICON32.BMP
  notepad/
    notepad.dbp
    notepad.frm
    ICON32.BMP
  imgview/
    imgview.dbp
    imgview.frm
    ICON32.BMP
  basdemo/
    basdemo.dbp
    basdemo.frm
    ICON32.BMP
  resedit/
    resedit.dbp
    resedit.frm
    ICON32.BMP
  widshow/
    widshow.dbp
    widshow.frm
    ICON32.BMP
  clock/
    clock.dbp
    clock.frm
    clock.dhs
    ICON32.BMP
  welcome/
    welcome.dbp
    welcome.frm
    welcome.dhs
    ICON32.BMP
  fileMgr/
    fileMgr.dbp
    fileMgr.frm          the window
    fmProps.frm          Properties dialog
    fileMgr.bas          job engine (copy / move / delete windows)
    fmJob.cls            one job
    fileMgr.dhs
    ICON32.BMP
  terminal/
    terminal.dbp
    terminal.frm         the window
    termBook.frm         Phone Book
    termSess.frm         Session Settings
    termXfer.frm         Transfer Options
    termPass.frm         secure link passphrase
    termProg.frm         File Transfer (progress)
    terminal.bas         phone book (TERMINAL.INI), shared state
    termMain.bas         start
    terminal.dhs
    ICON32.BMP

  dvxbasic/              see dvxbasic/README.md
    compiler/            lexer, parser, codegen, strip, obfuscate
    runtime/             VM + value system
    formrt/              form runtime (BASIC <-> DVX widgets)
    ide/                 IDE front end
    stub/                bascomp + basstub
    ...