Add text rendering support via the Windows 3.x ExtTextOut DDI function. Builds a .FNT v3 font structure from the VGA BIOS 8x16 ROM font (INT 10h AH=11h), with v3 char table (6-byte entries, absolute offsets) required by VBESVGA.DRV's BigFontFlags in protected mode. Provides a full-screen clip rect since STRBLT.ASM unconditionally dereferences lpClipRect. Tested with both VBESVGA.DRV and S3TRIO.DRV. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
196 lines
8.1 KiB
C
196 lines
8.1 KiB
C
#ifndef WINDRV_H
|
|
#define WINDRV_H
|
|
|
|
// ============================================================================
|
|
// windrv.h - Public API for using Windows 3.x display drivers from DOS
|
|
//
|
|
// This library loads Windows 3.x accelerated display drivers (16-bit NE
|
|
// format DLLs) and provides a clean 32-bit C API for DOS programs compiled
|
|
// with DJGPP to use their hardware-accelerated drawing functions.
|
|
//
|
|
// The library handles:
|
|
// - NE executable loading with segment relocation
|
|
// - 32-bit to 16-bit protected mode thunking via DPMI
|
|
// - Windows API stub functions that drivers import
|
|
// - DDI (Device Driver Interface) function wrappers
|
|
//
|
|
// Usage:
|
|
// 1. Call wdrvInit() to initialize the library
|
|
// 2. Call wdrvLoadDriver() with path to a .DRV file
|
|
// 3. Call wdrvEnable() to set a video mode
|
|
// 4. Use drawing functions (wdrvBitBlt, wdrvLine, etc.)
|
|
// 5. Call wdrvDisable() to restore text mode
|
|
// 6. Call wdrvUnloadDriver() and wdrvShutdown() to clean up
|
|
// ============================================================================
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include "wintypes.h"
|
|
|
|
// ============================================================================
|
|
// Error codes
|
|
// ============================================================================
|
|
|
|
#define WDRV_OK 0
|
|
#define WDRV_ERR_INIT -1 // Initialization failed
|
|
#define WDRV_ERR_NO_DPMI -2 // DPMI not available or insufficient
|
|
#define WDRV_ERR_FILE_NOT_FOUND -3 // Driver file not found
|
|
#define WDRV_ERR_BAD_FORMAT -4 // Not a valid NE executable
|
|
#define WDRV_ERR_LOAD_FAILED -5 // Failed to load driver segments
|
|
#define WDRV_ERR_NO_MEMORY -6 // Out of memory (conventional or extended)
|
|
#define WDRV_ERR_RELOC_FAILED -7 // Relocation processing failed
|
|
#define WDRV_ERR_NO_ENTRY -8 // Required DDI entry point not found
|
|
#define WDRV_ERR_ENABLE_FAILED -9 // Driver Enable() call failed
|
|
#define WDRV_ERR_THUNK_FAILED -10 // Thunk setup failed
|
|
#define WDRV_ERR_NOT_LOADED -11 // No driver loaded
|
|
#define WDRV_ERR_NOT_ENABLED -12 // Driver not enabled
|
|
#define WDRV_ERR_UNSUPPORTED -13 // Operation not supported by driver
|
|
|
|
// ============================================================================
|
|
// Opaque driver handle
|
|
// ============================================================================
|
|
|
|
typedef struct WdrvDriverS *WdrvHandleT;
|
|
|
|
// ============================================================================
|
|
// Driver information (returned by wdrvGetInfo)
|
|
// ============================================================================
|
|
|
|
typedef struct {
|
|
char driverName[64]; // Module name from NE header
|
|
uint16_t driverVersion; // Driver version number
|
|
int32_t maxWidth; // Maximum supported width
|
|
int32_t maxHeight; // Maximum supported height
|
|
int32_t maxBpp; // Maximum bits per pixel
|
|
int32_t numColors; // Number of colors
|
|
uint32_t rasterCaps; // Raster capability bits (RC_*)
|
|
bool hasBitBlt; // Driver exports BitBlt
|
|
bool hasOutput; // Driver exports Output (lines, shapes)
|
|
bool hasPixel; // Driver exports Pixel
|
|
bool hasStretchBlt; // Driver exports StretchBlt
|
|
bool hasExtTextOut; // Driver exports ExtTextOut
|
|
bool hasSetPalette; // Driver exports SetPalette
|
|
bool hasSetCursor; // Driver exports SetCursor
|
|
} WdrvInfoT;
|
|
|
|
// ============================================================================
|
|
// BitBlt parameters
|
|
// ============================================================================
|
|
|
|
typedef struct {
|
|
int16_t dstX;
|
|
int16_t dstY;
|
|
int16_t srcX;
|
|
int16_t srcY;
|
|
int16_t width;
|
|
int16_t height;
|
|
uint32_t rop3; // Raster operation (SRCCOPY, PATCOPY, etc.)
|
|
} WdrvBitBltParamsT;
|
|
|
|
// ============================================================================
|
|
// Library initialization / shutdown
|
|
// ============================================================================
|
|
|
|
// Initialize the library. Must be called before any other functions.
|
|
// Sets up DPMI descriptors, thunk infrastructure, and API stubs.
|
|
int32_t wdrvInit(void);
|
|
|
|
// Shut down the library and free all resources.
|
|
void wdrvShutdown(void);
|
|
|
|
// ============================================================================
|
|
// Driver loading
|
|
// ============================================================================
|
|
|
|
// Load a Windows 3.x display driver (.DRV file).
|
|
// Returns a driver handle on success, NULL on failure.
|
|
// Call wdrvGetLastError() for details on failure.
|
|
WdrvHandleT wdrvLoadDriver(const char *driverPath);
|
|
|
|
// Unload a previously loaded driver.
|
|
void wdrvUnloadDriver(WdrvHandleT handle);
|
|
|
|
// Get information about a loaded driver.
|
|
// The driver must be loaded but need not be enabled.
|
|
int32_t wdrvGetInfo(WdrvHandleT handle, WdrvInfoT *info);
|
|
|
|
// ============================================================================
|
|
// Mode setting
|
|
// ============================================================================
|
|
|
|
// Enable the driver (set video mode and initialize hardware).
|
|
// width/height/bpp are the requested mode; the driver may adjust.
|
|
// Pass 0 for defaults (driver's preferred resolution).
|
|
int32_t wdrvEnable(WdrvHandleT handle, int32_t width, int32_t height, int32_t bpp);
|
|
|
|
// Disable the driver (restore text mode, release hardware).
|
|
int32_t wdrvDisable(WdrvHandleT handle);
|
|
|
|
// ============================================================================
|
|
// Drawing operations
|
|
// ============================================================================
|
|
|
|
// Block transfer (hardware-accelerated if supported).
|
|
int32_t wdrvBitBlt(WdrvHandleT handle, WdrvBitBltParamsT *params);
|
|
|
|
// Solid rectangle fill using PatBlt with a solid brush.
|
|
int32_t wdrvFillRect(WdrvHandleT handle, int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color);
|
|
|
|
// Set a single pixel.
|
|
int32_t wdrvSetPixel(WdrvHandleT handle, int16_t x, int16_t y, uint32_t color);
|
|
|
|
// Get a single pixel's color.
|
|
uint32_t wdrvGetPixel(WdrvHandleT handle, int16_t x, int16_t y);
|
|
|
|
// Draw a polyline using the Output DDI function.
|
|
int32_t wdrvPolyline(WdrvHandleT handle, Point16T *points, int16_t count, uint32_t color);
|
|
|
|
// Draw a rectangle outline.
|
|
int32_t wdrvRectangle(WdrvHandleT handle, int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color);
|
|
|
|
// Draw text using the ExtTextOut DDI function.
|
|
// Uses a built-in 8x16 VGA bitmap font.
|
|
int32_t wdrvExtTextOut(WdrvHandleT handle, int16_t x, int16_t y,
|
|
const char *text, int16_t length,
|
|
uint32_t fgColor, uint32_t bgColor,
|
|
bool opaque);
|
|
|
|
// ============================================================================
|
|
// Palette operations (for 8bpp modes)
|
|
// ============================================================================
|
|
|
|
// Set palette entries. colors is an array of RGBQUAD (R,G,B,flags).
|
|
int32_t wdrvSetPalette(WdrvHandleT handle, int32_t startIndex, int32_t count, const uint8_t *colors);
|
|
|
|
// ============================================================================
|
|
// Direct framebuffer access
|
|
// ============================================================================
|
|
|
|
// Get a near pointer to the linear framebuffer (if available).
|
|
// Returns NULL if the driver doesn't provide linear access.
|
|
void *wdrvGetFramebuffer(WdrvHandleT handle);
|
|
|
|
// Get the framebuffer pitch (bytes per scanline).
|
|
int32_t wdrvGetPitch(WdrvHandleT handle);
|
|
|
|
// ============================================================================
|
|
// Error reporting
|
|
// ============================================================================
|
|
|
|
// Get the last error code.
|
|
int32_t wdrvGetLastError(void);
|
|
|
|
// Get a human-readable description of the last error.
|
|
const char *wdrvGetLastErrorString(void);
|
|
|
|
// ============================================================================
|
|
// Debugging
|
|
// ============================================================================
|
|
|
|
// Enable/disable verbose debug output to stderr.
|
|
void wdrvSetDebug(bool enable);
|
|
|
|
// Dump all segment base addresses for debugging.
|
|
void wdrvDumpSegmentBases(WdrvHandleT handle);
|
|
|
|
#endif // WINDRV_H
|