A lightweight media file viewer for the Tandy/Memorex Video Information System (VIS) — a 1992 multimedia console running Microsoft Modular Windows 3.1 on an Intel 80286 @ 12 MHz, with a Yamaha YMF262 (OPL3) FM synth + R-2R DAC and a Mitsumi 1× CD-ROM.
It is a single Win16 NE executable, bundlable as the shell of any VIS CD/ISO. On boot it enumerates the media files on the disc and presents a hand-controller-navigable browser. Selecting a file plays/shows it using the VIS's native Modular Windows facilities — no persistence (the VIS is CD-only: no hard disk, no save).
| Media | Format | How it's rendered |
|---|---|---|
| 📷 Photo | .BMP / .DIB (8-bit, ≤ 320×200) |
GDI StretchDIBits + realized 256-color palette |
| 🔊 Audio | .WAV (PCM→DAC), .MID / .RMI (→ OPL3 FM) |
MCI waveaudio / sequencer |
| 🎬 Video | .FLC / .FLI (Autodesk FLIC) |
DISPDIB DVA, decoded straight into video RAM (A000) |
VIS edutainment titles are full of full-motion video — but inspecting the retail discs
(Atlas of U.S. Presidents, Bible Lands, Fitness Partner) shows not a single AVI
file: their video is Autodesk FLC/FLIC animation and RLE/DIB sequences blitted via
DisplayDib. The ROM's mciavi.drv is vestigial — opening an AVI through MCI returns
MMSYSERR_NODRIVER (err 6). So this viewer implements a from-scratch FLC player, which is
how VIS video actually worked.
- MCI wiring — audio needs the
[mci]+[drivers] wave/midi=vwavmidi.drvsections inSYSTEM.INI, ormciSendString openreturns err 306 (MCIERR_DEVICE_NOT_INSTALLED). - MIDI base-level mode — the VIS synth boots responding only to channels 13–16; play a
General MIDI file by embedding the GM-System-On SysEx (
F0 7E 7F 09 01 F7) as the first event (see tools/prep_midi.py). - Video performance — three independent ceilings, all addressed for full-frame video:
GDI is too slow (
DIB_RGB_COLORS≈ 1 fps,DIB_PAL_COLORS≈ 5 fps) → use DISPDIB DVA with direct A000 writes;GetTickCount/WM_TIMERare quantized to ~55 ms → pace frames off the PIT directly (~596 kHz on MAME-VIS); per-pixel decode is the real limit → decode in place to A000 and fill RLE runs withrep stos/movs(_fmemset/_fmemcpy). - 256-color rendering —
[tvvga](lowercase)resolution=320x200x8;StretchDIBits, notSetDIBitsToDevice; bottom-up DIBs; palette realization for the free 236 colors. - Hand controller —
IMPORT hcGetCursorPos HC.HCGETCURSORPOSis mandatory forWM_KEYDOWNrouting; poll it from a timer; suppress the native cursor.
src/ viewer.c (the app) + build_viewer.bat + link_viewer.lnk + mkiso_viewer.py
tools/ prep_image.py (any image → VIS 8-bit BMP), prep_midi.py (SMF → VIS MID)
reverse/ flc_encode.py (test-FLC generator), inspect_real_disc.py (disc recon)
cd_root/ VIS-bootable CD staging: AUTOEXEC, SYSTEM.INI, CONTROL.TAT + test media
Requires Open Watcom V2 (Win16 target),
Python with pycdlib (+ Pillow for the tools), and MAME with
the vis driver and a VIS BIOS dump (vis.zip, not included — provide your own).
# 1. compile the Win16 NE and stage it into cd_root
cmd /c src\build_viewer.bat # override WATCOM to point at your Open Watcom
# 2. master the VIS-bootable ISO
python src\mkiso_viewer.py # cd_root/* -> build/viewer.iso
# 3. run in MAME (BIOS vis.zip on the rompath)
mame -rompath . vis -cdrom build/viewer.iso -window -nomax -skip_gameinfopython tools/prep_image.py path/to/photo.jpg NAME # -> cd_root/NAME.BMP (8-bit, ≤320×200)
python tools/prep_midi.py path/to/song.mid NAME # -> cd_root/NAME.MID (GM-On injected)
# then re-run mkiso_viewer.py8.3 uppercase filenames; BMPs must stay under ~65 KB (≈ 320×200 at 8-bit).
Built on the VIS reverse-engineering groundwork from the sibling vis-wolf3d project
(toolchain, CONTROL.TAT, DISPDIB/__A000H, PIT timing, palette/rendering gotchas). The VIS
BIOS and Modular Windows are property of their respective owners and are not redistributed
here.
MIT © 2026 Samuele Voltan — see LICENSE.