Start of DJGPP backend. Buggy.

This commit is contained in:
Scott Duensing 2022-05-29 19:49:23 -05:00
parent 2ea3cfe57b
commit ef63b14c2f
17 changed files with 8751 additions and 115 deletions

51
LICENSE
View file

@ -24,3 +24,54 @@ ZLIB
----
https://www.zlib.net/
"As-Is"
MemWatch
--------
http://www.linkdata.se/sourcecode/memwatch/
GPL2
SDL2
----
https://www.libsdl.org/
BSD 3-Clause
SDL2_image
----------
https://www.libsdl.org/
BSD 3-Clause
stb_ds.h
--------
https://github.com/nothings/stb
Public Domain
stb_image.h
-----------
https://github.com/nothings/stb
Public Domain
tiny-AES-c
----------
https://github.com/kokke/tiny-AES-c
Unlicense
tiny-AES128-C
-------------
https://github.com/bonybrown/tiny-AES128-C
Unlicense
DOS Serial Library
------------------
https://github.com/kstenerud/DOS-Serial-Library
Attribution
ENet
----
https://github.com/zpl-c/enet
MIT
ini
---
https://github.com/rxi/ini
MIT

View file

@ -21,7 +21,7 @@ CC = gcc
LD = gcc
RM = rm -f
RMDIR = rm -rf
INSTALL = install
INSTALL = install
DEBUG = -g
## CHANGE THIS ##
@ -32,14 +32,19 @@ BINDIR = bin
## CHANGE THIS ##
# CFLAGS, LDFLAGS, CPPFLAGS, PREFIX can be overriden on CLI
CFLAGS := $(DEBUG)
CFLAGS += -I$(SRCDIR)/shared -I$(SRCDIR)/installed/dos/include -I$(SRCDIR)/client/src
CPPFLAGS :=
LDFLAGS := -L$(SRCDIR)/installed/dos/lib
LDLIBS := -lgrx20 -ljpeg -lpng -lz
CFLAGS := $(DEBUG) -DBACKEND_DJGPP
CFLAGS += -I$(SRCDIR)/shared -I$(SRCDIR)/client/src
CPPFLAGS :=
LDFLAGS :=
LDLIBS :=
PREFIX :=
TARGET_ARCH :=
# GRX
#CFLAGS += -I$(SRCDIR)/installed/dos/include
#LDFLAGS := -L$(SRCDIR)/installed/dos/lib
#LDLIBS := -lgrx20 -ljpeg -lpng -lz
# Compiler Flags
ALL_CFLAGS := $(CFLAGS)

View file

@ -22,8 +22,11 @@
#
# See: https://github.com/andrewwutw/build-djgpp
[[ -d obj ]] && rm -rf obj
mkdir -p \
obj/shared/thirdparty/memwatch \
obj/client/src/platform \
obj/client/src/gui
source /opt/cross/djgpp/setenv

View file

@ -5,8 +5,8 @@ CONFIG += console
CONFIG += c99
#CONFIG += BACKEND_GRX
CONFIG += BACKEND_SDL2
#CONFIG += BACKEND_DJGPP
#CONFIG += BACKEND_SDL2
CONFIG += BACKEND_DJGPP
SHARED = $$PWD/../shared
@ -23,15 +23,16 @@ HEADERS += \
$$SHARED/stddclmr.h \
$$SHARED/thirdparty/memwatch/memwatch.h \
$$SHARED/thirdparty/stb_ds.h \
src/gui/color.h \
src/gui/font.h \
src/gui/gui.h \
src/gui/image.h \
src/gui/wmwindow.h \
src/os.h \
src/platform/djgpp.h \
src/platform/grx.h \
src/platform/platform.h \
src/platform/sdl2.h
src/platform/sdl2.h \
src/thirdparty/stb_image.h
SOURCES += \
$$SHARED/array.c \
@ -39,12 +40,16 @@ SOURCES += \
$$SHARED/thirdparty/memwatch/memwatch.c \
src/gui/font.c \
src/gui/gui.c \
src/gui/image.c \
src/gui/wmwindow.c \
src/main.c \
src/platform/djgpp.c \
src/platform/grx.c \
src/platform/sdl2.c
OTHER_FILES += \
$$PWD/../LICENSE
BACKEND_GRX {
LINUX = $$PWD/../installed/linux
DEFINES += BACKEND_GRX
@ -61,11 +66,15 @@ BACKEND_GRX {
BACKEND_SDL2 {
DEFINES += BACKEND_SDL2
LIBS += \
-lSDL2 \
-lSDL2_image
-lSDL2
}
BACKEND_DJGPP {
DEFINES += BACKEND_DJGPP
OTHER_FILES += \
$$PWD/../build.sh \
$$PWD/../Makefile.djgpp \
$$PWD/../test.sh \
$$PWD/../test.conf
}

View file

@ -1,14 +0,0 @@
#ifndef COLOR_H
#define COLOR_H
#include <stdint.h>
typedef uint32_t ColorT;
#define COLOR(r,g,b) (((r) << 24) | ((g) << 16) | ((b) << 8) | 255)
#endif // COLOR_H

View file

@ -87,6 +87,8 @@ void fontRender(FontT *font, char *string, ColorT foreground, ColorT background,
cx = character % font->span;
cy = character / font->span;
yp = y;
// Half byte or full byte font?
if (font->width == 4) {
// Half Byte.
@ -123,7 +125,6 @@ void fontRender(FontT *font, char *string, ColorT foreground, ColorT background,
offset = cy * font->span * font->height + cx;
// Draw out 8 lines.
yp = y;
for (yl=0; yl<font->height; yl++) {
// We do 8 pixels unrolled hoping it's fast.
data = font->bits[offset];

View file

@ -3,7 +3,7 @@
#include "os.h"
#include "color.h"
#include "../platform/platform.h"
typedef struct FontS {

View file

@ -1,6 +1,7 @@
#include "gui.h"
#include "font.h"
#include "wmwindow.h"
#include "image.h"
#include "array.h"

42
client/src/gui/image.c Normal file
View file

@ -0,0 +1,42 @@
#define STB_IMAGE_IMPLEMENTATION
#define STBI_ONLY_PNG
#include "thirdparty/stb_image.h"
#include "../platform/platform.h"
#include "image.h"
#define PIXEL_COMPONENTS 3
SurfaceT *imageLoad(char *filename) {
int w; // These unspecified ints are intentional.
int h;
int n;
int32_t r;
int32_t x;
int32_t y;
SurfaceT *i = NULL;
SurfaceT *t = videoSurfaceGet();
unsigned char *raw = NULL;
r = stbi_info(filename, &w, &h, &n);
if (r) {
raw = stbi_load(filename, &w, &h, &n, PIXEL_COMPONENTS);
if (raw) {
i = videoSurfaceCreate(w, h);
videoSurfaceSet(i);
n = 0;
for (y=0; y<h; y++) {
for (x=0; x<w; x++) {
videoSurfacePixelSet(x, y, videoColorMake(raw[n], raw[n + 1], raw[n + 2]));
n += PIXEL_COMPONENTS;
}
}
videoSurfaceSet(t);
stbi_image_free(raw);
}
}
return i;
}

12
client/src/gui/image.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef IMAGE_H
#define IMAGE_H
#include "os.h"
#include "../platform/platform.h"
SurfaceT *imageLoad(char *filename);
#endif // IMAGE_H

View file

@ -1,22 +1,150 @@
#ifdef BACKEND_DJGPP
#include <dos.h>
#include <dpmi.h>
#include <go32.h>
#include <bios.h>
#include <conio.h>
#include <sys/farptr.h>
#include <sys/nearptr.h>
#include <string.h>
#include "djgpp.h"
FontT *__font8x14 = NULL;
#define DIVISIBLE_BY_EIGHT(x) ((((x) >> 3) << 3) == (x))
void fontWrite(char *message, int16_t x, int16_t y, FontT *font, ColorT foreground, ColorT background) {
}
// These are all we support
#define VBE_MM_PACKED 4
#define VBE_MM_DCOLOR 6
SurfaceT *imageLoad(char *filename) {
SurfaceT *image = NULL;
typedef struct VBEInfoS {
char vbeSignature[4]; // 'VESA' 4 byte signature
int16_t vbeVersion; // VBE version number
char *oemStringPtr; // Pointer to OEM string
uint32_t capabilities; // Capabilities of video card
uint16_t *videoModePtr; // Pointer to supported modes
uint16_t totalMemory; // Number of 64kb memory blocks
// added for VBE 2.0
uint16_t oemSoftwareRev; // OEM Software revision number
char *oemVendorNamePtr; // Pointer to Vendor Name string
char *oemProductNamePtr; // Pointer to Product Name string
char *oemProductRevPtr; // Pointer to Product Revision str
char reserved[222]; // Pad to 256 byte block size
char oemData[256]; // Scratch pad for OEM data
} __attribute__ ((packed)) VBEInfoT;
return image;
}
typedef struct VBEModeInfoS {
// Mandatory information for all VBE revisions:
uint16_t modeAttributes; // mode attributes
uint8_t winAAttributes; // window A attributes
uint8_t winBAttributes; // window B attributes
uint16_t winGranularity; // window granularity
uint16_t winSize; // window size
uint16_t winASegment; // window A start segment
uint16_t winBSegment; // window B start segment
uint32_t winFuncPtr; // pointer to window function
uint16_t bytesPerScanLine; // bytes per scan line
// Mandatory information for VBE 1.2 and above:
uint16_t xResolution; // horizontal resolution in pixels or chars
uint16_t yResolution; // vertical resolution in pixels or chars
uint8_t xCharSize; // character cell width in pixels
uint8_t yCharSize; // character cell height in pixels
uint8_t numberOfPlanes; // number of memory planes
uint8_t bitsPerPixel; // bits per pixel
uint8_t numberOfBanks; // number of banks
uint8_t memoryModel; // memory model type
uint8_t bankSize; // bank size in KB
uint8_t numberOfImagePages; // number of images
uint8_t reserved; // reserved for page function
// Direct Color fields (required for direct/6 and YUV/7 memory models)
uint8_t redMaskSize; // size of direct color red mask in bits
uint8_t redFieldPosition; // bit position of lsb of red mask
uint8_t greenMaskSize; // size of direct color green mask in bits
uint8_t greenFieldPosition; // bit position of lsb of green mask
uint8_t blueMaskSize; // size of direct color blue mask in bits
uint8_t blueFieldPosition; // bit position of lsb of blue mask
uint8_t rsvdMaskSize; // size of direct color reserved mask in bits
uint8_t rsvdFieldPosition; // bit position of lsb of reserved mask
uint8_t directColorModeInfo; // direct color mode attributes
// Mandatory information for VBE 2.0 and above:
uint32_t physBasePtr; // physical address for flat frame buffer
uint32_t offScreenMemOffset; // pointer to start of off screen memory
uint16_t offScreenMemSize; // amount of off screen memory in 1k units
char reservedBuf[206];
} __attribute__ ((packed)) VBEModeInfoT;
typedef struct PModeInterfaceS {
int16_t setWindow;
int16_t setDisplayStart;
int16_t setPalette;
int16_t ioInfo;
} __attribute__ ((packed)) PModeInterfaceT;
typedef struct VBESurfaceS {
uint32_t lfbLinearAddress;
uint16_t lfbSelector;
void *lfbNearPtr;
uint32_t lfbMemSize;
uint16_t xResolution;
uint16_t yResolution;
uint32_t bitsPerPixel;
uint16_t virtualXResolution;
uint32_t bytesPerPixel;
uint32_t screenBytes;
uint32_t screenDWords;
uint32_t centerX;
uint32_t centerY;
uint16_t numberOfOffscreens;
uint8_t vbeBoolean;
uint8_t vbeInitBoolean;
int32_t ioSegment;
uint32_t ioLinear;
uint32_t rMask;
uint32_t gMask;
uint32_t bMask;
uint32_t aMask;
uint8_t rShift;
uint8_t gShift;
uint8_t bShift;
uint8_t aShift;
uint8_t rPos;
uint8_t gPos;
uint8_t bPos;
uint8_t aPos;
} VBESurfaceT;
static VBESurfaceT _vbeSurface;
static VBEInfoT _vbeInfo;
static VBEModeInfoT _vbeModeInfo;
static PModeInterfaceT *_pmodeInterfacePtr;
static uint32_t *_yTable;
static SurfaceT *_activeSurface = NULL;
static void vbeCreatePalette(void);
static VBEInfoT *vbeGetInfo(void);
static VBEModeInfoT *vbeGetModeInfo(uint16_t vbeModeNumber);
static void *vbeGetPmodeInterface(void);
static uint8_t vbeIsDesiredMode(void);
static uint16_t vbeSelectModeNumber(uint16_t xRes, uint16_t yRes, uint8_t bpp);
static VBESurfaceT *vbeSetMode(uint16_t vbeModeNumber);
static uint16_t vbeSetScanlineLength(uint16_t pixelLength);
static void videoSurfacePixelSet8(uint16_t x, uint16_t y, ColorT color);
static void videoSurfacePixelSet16(uint16_t x, uint16_t y, ColorT color);
static void videoSurfacePixelSet32(uint16_t x, uint16_t y, ColorT color);
static void (*pmVBESetDisplayStart)(void);
void (*videoSurfacePixelSet)(uint16_t x, uint16_t y, ColorT color);
void platformEventGet(EventT *event) {
@ -25,21 +153,417 @@ void platformEventGet(EventT *event) {
void platformShutdown(void) {
__dpmi_regs r;
__dpmi_meminfo m;
if (_vbeSurface.vbeInitBoolean == 0) {
r.x.ax = 0x03; // make sure we're in 3h
__dpmi_int(0x10, &r); // for buggy vesa implementations
//return(1);
}
if (_yTable) free(_yTable);
// free mapping etc.
m.size = (_vbeInfo.totalMemory * 64 * 1024);
m.address = _vbeSurface.lfbLinearAddress;
__dpmi_unlock_linear_region(&m);
__dpmi_free_physical_address_mapping(&m);
__dpmi_free_ldt_descriptor(_vbeSurface.lfbSelector);
// get rid of PMI interface
if (_pmodeInterfacePtr) free(_pmodeInterfacePtr);
if (_vbeSurface.ioSegment) {
m.address = _vbeSurface.ioLinear;
__dpmi_free_physical_address_mapping(&m);
__dpmi_free_ldt_descriptor(_vbeSurface.ioSegment);
}
// return do DOS
r.x.ax = 0x03;
__dpmi_int(0x10, &r);
// deinit VBE surface
_vbeSurface.vbeInitBoolean = 0;
_vbeSurface.vbeBoolean = 0;
// dealloc mode list
free(_vbeInfo.videoModePtr);
}
void platformStartup(int16_t width, int16_t height, int16_t depth) {
uint16_t vbeModeNumber;
if (vbeGetInfo() == NULL) {
//logWrite("No VESA BIOS Extensions found.\n");
//vbeShutdown();
return;
}
if (_vbeInfo.vbeVersion < 0x0200) {
//logWrite("VBE Version 2.0 or better required.\n");
//vbeShutdown();
return;
}
vbeGetPmodeInterface();
if ((vbeModeNumber = vbeSelectModeNumber(width, height, depth)) == 0) {
//logWrite("No appropriate video mode available.\n");
//vbeShutdown();
return;
}
if (vbeSetMode(vbeModeNumber) == NULL) {
//vbeShutdown();
return;
}
if (_vbeSurface.bitsPerPixel == 8) videoSurfacePixelSet = videoSurfacePixelSet8;
if (_vbeSurface.bitsPerPixel == 16) videoSurfacePixelSet = videoSurfacePixelSet16;
if (_vbeSurface.bitsPerPixel == 15) videoSurfacePixelSet = videoSurfacePixelSet16;
if (_vbeSurface.bitsPerPixel == 32) videoSurfacePixelSet = videoSurfacePixelSet32;
}
uint16_t videoDisplayHeightGet(void) {
static void vbeCreatePalette(void) {
uint8_t color = 0;
uint8_t red;
uint8_t green;
uint8_t blue;
// Create palette for 3:3:2 true color emulation
for (red = 4; red < 68; red += 8) {
for (green = 4; green < 68; green += 8) {
for (blue = 4; blue < 68; blue += 16) {
outportb(0x3C8, color);
outportb(0x3C9, red);
outportb(0x3C9, green);
outportb(0x3C9, blue);
color++;
}
}
}
}
static VBEInfoT *vbeGetInfo(void) {
uint16_t counter = 0;
uint16_t offset = 0;
uint16_t vbeMode = 0xFFFF;
uint16_t *vbeModeList = 0;
__dpmi_regs r;
// we want VBE 2.0+ info
memcpy(_vbeInfo.vbeSignature, "VBE2", 4);
// request info
r.x.ax = 0x4F00;
r.x.di = __tb & 0x0F;
r.x.es = (__tb >> 4) & 0xFFFF;
dosmemput(&_vbeInfo, sizeof(VBEInfoT), __tb);
__dpmi_int(0x10, &r);
if (r.x.ax != 0x004F) return NULL;
dosmemget(__tb, sizeof(VBEInfoT), &_vbeInfo);
if (strncmp(_vbeInfo.vbeSignature, "VESA", 4) != 0) return NULL; // VESA ?
// get the videomode list
do {
dosmemget(((((long)_vbeInfo.videoModePtr >> 16) & 0xFFFF) << 4) + ((long)_vbeInfo.videoModePtr & 0xFFFF) + (counter * sizeof(short)), sizeof(short), &vbeMode);
counter++;
} while (vbeMode != 0xFFFF);
vbeModeList = malloc((counter + 1) * sizeof(short));
counter = 0;
do {
dosmemget(((((long)_vbeInfo.videoModePtr >> 16) & 0xFFFF) << 4) + ((long)_vbeInfo.videoModePtr & 0xFFFF) + (counter * sizeof(short)), sizeof(short), &vbeModeList[counter]);
counter++;
} while (vbeModeList[counter - 1] != 0xFFFF);
_vbeInfo.videoModePtr = vbeModeList;
// get the OEM string
counter = 0;
do {
dosmemget(((((long)_vbeInfo.oemStringPtr >> 16) & 0xFFFF) << 4) + ((long)_vbeInfo.oemStringPtr & 0xFFFF) + counter, sizeof(char), &_vbeInfo.oemData[counter]);
counter++;
} while (_vbeInfo.oemData[counter - 1] != 0);
_vbeInfo.oemStringPtr = &_vbeInfo.oemData[0];
offset = counter;
if (_vbeInfo.vbeVersion >= 0x0200) {
// get the vendor name
counter = 0;
do {
dosmemget(((((long)_vbeInfo.oemVendorNamePtr >> 16) & 0xFFFF) << 4) + ((long)_vbeInfo.oemVendorNamePtr & 0xFFFF) + counter, sizeof(char), &_vbeInfo.oemData[counter + offset]);
counter++;
} while (_vbeInfo.oemData[counter + offset - 1] != 0);
_vbeInfo.oemVendorNamePtr = &_vbeInfo.oemData[offset];
offset = offset + counter;
// get the product name
counter = 0;
do {
dosmemget(((((long)_vbeInfo.oemProductNamePtr >> 16) & 0xFFFF) << 4) + ((long)_vbeInfo.oemProductNamePtr & 0xFFFF) + counter, sizeof(char), &_vbeInfo.oemData[counter + offset]);
counter++;
} while (_vbeInfo.oemData[counter + offset - 1] != 0);
_vbeInfo.oemProductNamePtr = &_vbeInfo.oemData[offset];
offset = offset + counter;
//get the product revision
counter = 0;
do {
dosmemget(((((long)_vbeInfo.oemProductRevPtr >> 16) & 0xFFFF) << 4) + ((long)_vbeInfo.oemProductRevPtr & 0xFFFF) + counter, sizeof(char), &_vbeInfo.oemData[counter + offset]);
counter++;
} while (_vbeInfo.oemData[counter + offset - 1] != 0);
_vbeInfo.oemProductRevPtr = &_vbeInfo.oemData[offset];
}
_vbeSurface.vbeBoolean = 1;
return(&_vbeInfo);
}
static VBEModeInfoT *vbeGetModeInfo(uint16_t vbeModeNumber) {
__dpmi_regs r;
if (_vbeSurface.vbeBoolean == 0) return NULL;
r.x.ax = 0x4F01;
r.x.cx = vbeModeNumber;
r.x.di = __tb & 0x0F;
r.x.es = (__tb >> 4) & 0xFFFF;
__dpmi_int(0x10, &r);
if (r.x.ax != 0x004F) return NULL;
dosmemget(__tb, sizeof(VBEModeInfoT), &_vbeModeInfo);
// Fake 3:3:2 true color for packed modes.
if (_vbeModeInfo.bitsPerPixel == 8) {
_vbeModeInfo.blueMaskSize = 2;
_vbeModeInfo.greenMaskSize = 3;
_vbeModeInfo.redMaskSize = 3;
}
if (_vbeModeInfo.bitsPerPixel == 16) {
// for buggy VBE implementations
_vbeModeInfo.bitsPerPixel = _vbeModeInfo.redMaskSize + _vbeModeInfo.greenMaskSize + _vbeModeInfo.blueMaskSize;
}
return(&_vbeModeInfo);
}
static void *vbeGetPmodeInterface(void) {
__dpmi_regs r;
__dpmi_meminfo m;
uint16_t *ptr;
// only available in VBE 2.0+
if (_vbeInfo.vbeVersion < 0x200) return NULL;
r.x.ax = 0x4F0A;
r.x.bx = 0;
__dpmi_int(0x10, &r);
if (r.x.ax != 0x004F) return NULL;
// copy interface
_pmodeInterfacePtr = (PModeInterfaceT *)malloc(r.x.cx);
dosmemget((r.x.es * 16) + r.x.di, r.x.cx, _pmodeInterfacePtr);
_go32_dpmi_lock_data(_pmodeInterfacePtr, r.x.cx);
// need memory-mapped IO?
if (_pmodeInterfacePtr->ioInfo) {
ptr = (uint16_t *)((char *)_pmodeInterfacePtr + _pmodeInterfacePtr->ioInfo);
// skip the port table...
while (*ptr != 0xFFFF)
ptr++;
ptr++;
// ...and get descriptor
if (*ptr != 0xFFFF) {
m.address = *((uint32_t *)ptr);
m.size = *(ptr + 2);
if (__dpmi_physical_address_mapping(&m) != 0) return NULL;
_vbeSurface.ioLinear = m.address;
__dpmi_lock_linear_region(&m);
_vbeSurface.ioSegment = __dpmi_allocate_ldt_descriptors(1);
if (_vbeSurface.ioSegment < 0) {
__dpmi_unlock_linear_region(&m);
__dpmi_free_physical_address_mapping(&m);
return NULL;
}
__dpmi_set_segment_base_address(_vbeSurface.ioSegment, _vbeSurface.ioLinear);
__dpmi_set_segment_limit(_vbeSurface.ioSegment, m.size - 1);
}
}
pmVBESetDisplayStart = (void *)((char *)_pmodeInterfacePtr + _pmodeInterfacePtr->setDisplayStart);
return pmVBESetDisplayStart;
}
static uint8_t vbeIsDesiredMode(void) {
// This is a custom filter to remove modes not supported by the calling application.
// Must be linear.
if (((_vbeModeInfo.modeAttributes) & (1<<7)) >> 7) {
// Packed or Direct Color mode.
if (_vbeModeInfo.memoryModel == VBE_MM_PACKED || _vbeModeInfo.memoryModel == VBE_MM_DCOLOR) {
// Resolution minimum of 640x480.
if (_vbeModeInfo.xResolution >= 640 && _vbeModeInfo.yResolution >= 480) {
// Multiple of 8
if (DIVISIBLE_BY_EIGHT(_vbeModeInfo.xResolution) && DIVISIBLE_BY_EIGHT(_vbeModeInfo.yResolution)) {
// Valid mode!
return 1;
}
}
}
}
// Rejected!
return 0;
}
static uint16_t vbeSelectModeNumber(uint16_t xRes, uint16_t yRes, uint8_t bpp) {
uint16_t counter;
if (_vbeSurface.vbeBoolean == 0) return(0);
for (counter = 0; ; counter++) {
if (_vbeInfo.videoModePtr[counter] == 0xFFFF) return(0);
vbeGetModeInfo(_vbeInfo.videoModePtr[counter]);
if (vbeIsDesiredMode()) {
if (_vbeModeInfo.xResolution == xRes && _vbeModeInfo.yResolution == yRes && _vbeModeInfo.bitsPerPixel == bpp)
break;
}
}
return(_vbeInfo.videoModePtr[counter]);
}
static VBESurfaceT *vbeSetMode(uint16_t vbeModeNumber) {
__dpmi_regs r;
__dpmi_meminfo m;
uint32_t counter;
if (_vbeSurface.vbeBoolean == 0) return NULL;
if (_vbeSurface.vbeInitBoolean == 1) return NULL;
if (vbeGetModeInfo(vbeModeNumber) == 0) return NULL;
if (_yTable) free(_yTable);
if ((_yTable = malloc(4 * (_vbeModeInfo.yResolution + 1))) == 0) return NULL;
for (counter = 0; counter <= _vbeModeInfo.yResolution; counter++) {
_yTable[counter] = _vbeModeInfo.xResolution * counter;// * ((_vbeModeInfo.bitsPerPixel + 1) / 8);
}
// request frame buffer
r.x.ax = 0x4F02;
r.x.bx = (vbeModeNumber | 0x4000);
__dpmi_int(0x10, &r);
if (r.x.ax != 0x004F) return(0);
m.size = (_vbeInfo.totalMemory * 64 * 1024);
m.address = _vbeModeInfo.physBasePtr;
__dpmi_physical_address_mapping(&m);
__dpmi_lock_linear_region(&m);
_vbeSurface.lfbLinearAddress = m.address;
_vbeSurface.lfbSelector = __dpmi_allocate_ldt_descriptors(1);
__dpmi_set_segment_base_address(_vbeSurface.lfbSelector, _vbeSurface.lfbLinearAddress);
__dpmi_set_segment_limit(_vbeSurface.lfbSelector, (_vbeInfo.totalMemory * 64 * 1024) - 1);
_vbeSurface.lfbNearPtr = (void *)(_vbeSurface.lfbLinearAddress + __djgpp_conventional_base);
_vbeSurface.xResolution = _vbeModeInfo.xResolution;
_vbeSurface.yResolution = _vbeModeInfo.yResolution;
_vbeSurface.bitsPerPixel = _vbeModeInfo.bitsPerPixel;
_vbeSurface.virtualXResolution = _vbeModeInfo.xResolution;
_vbeSurface.bytesPerPixel = (_vbeModeInfo.bitsPerPixel + 1) / 8;
_vbeSurface.centerX = _vbeSurface.virtualXResolution / 2;
_vbeSurface.centerY = _vbeSurface.yResolution / 2;
_vbeSurface.numberOfOffscreens = vbeSetScanlineLength(_vbeModeInfo.xResolution) / _vbeModeInfo.yResolution;
_vbeSurface.vbeInitBoolean = 1;
_vbeSurface.screenBytes = (_vbeSurface.xResolution * _vbeSurface.yResolution * _vbeSurface.bytesPerPixel);
_vbeSurface.screenDWords = _vbeSurface.screenBytes / 4;
_vbeSurface.lfbMemSize = (_vbeSurface.xResolution * _vbeSurface.yResolution * _vbeSurface.bytesPerPixel) / 1024 + _vbeModeInfo.offScreenMemSize;
for (counter = 0; counter < (_vbeSurface.lfbMemSize * 1024); counter++) {
_farpokeb(_vbeSurface.lfbSelector, counter, 0x0); // clear Lfb
}
if (_vbeModeInfo.memoryModel == VBE_MM_PACKED) {
vbeCreatePalette();
_vbeModeInfo.redFieldPosition = 5;
_vbeModeInfo.greenFieldPosition = 2;
_vbeModeInfo.blueFieldPosition = 0;
_vbeModeInfo.rsvdFieldPosition = 7;
_vbeModeInfo.redMaskSize = 3;
_vbeModeInfo.greenMaskSize = 3;
_vbeModeInfo.blueMaskSize = 2;
_vbeModeInfo.rsvdMaskSize = 0;
}
_vbeSurface.rMask = ((1UL << _vbeModeInfo.redMaskSize) - 1) << _vbeModeInfo.redFieldPosition;
_vbeSurface.gMask = ((1UL << _vbeModeInfo.greenMaskSize) - 1) << _vbeModeInfo.greenFieldPosition;
_vbeSurface.bMask = ((1UL << _vbeModeInfo.blueMaskSize) - 1) << _vbeModeInfo.blueFieldPosition;
_vbeSurface.aMask = ((1UL << _vbeModeInfo.rsvdMaskSize) - 1) << _vbeModeInfo.rsvdFieldPosition;
_vbeSurface.rShift = 8 - _vbeModeInfo.redMaskSize;
_vbeSurface.gShift = 8 - _vbeModeInfo.greenMaskSize;
_vbeSurface.bShift = 8 - _vbeModeInfo.blueMaskSize;
_vbeSurface.aShift = 8 - _vbeModeInfo.rsvdMaskSize;
_vbeSurface.rPos = _vbeModeInfo.redFieldPosition;
_vbeSurface.gPos = _vbeModeInfo.greenFieldPosition;
_vbeSurface.bPos = _vbeModeInfo.blueFieldPosition;
_vbeSurface.aPos = _vbeModeInfo.rsvdFieldPosition;
return(&_vbeSurface);
}
static uint16_t vbeSetScanlineLength(uint16_t pixelLength) {
__dpmi_regs r;
if (_vbeSurface.vbeBoolean == 0) return(0);
r.x.ax = 0x4F06;
r.x.bx = 0x0000;
r.x.cx = pixelLength;
__dpmi_int(0x10, &r);
if (r.h.ah != 0) return(0);
if (r.x.cx != pixelLength) return(0);
_vbeSurface.virtualXResolution = pixelLength;
return(r.x.dx);
}
ColorT videoColorMake(uint8_t red, uint8_t green, uint8_t blue) {
return
(((red >> _vbeSurface.rShift) << _vbeSurface.rPos) & _vbeSurface.rMask) |
(((green >> _vbeSurface.gShift) << _vbeSurface.gPos) & _vbeSurface.gMask) |
(((blue >> _vbeSurface.bShift) << _vbeSurface.bPos) & _vbeSurface.bMask);
}
uint16_t videoDisplayHeightGet(void) {
return _vbeSurface.yResolution;
}
uint16_t videoDisplayWidthGet(void) {
return 0;
return _vbeSurface.xResolution;
}
@ -49,39 +573,150 @@ void videoModesShow(void) {
void videoSurfaceBlit(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source) {
uint16_t y1;
size_t offsetTarget;
size_t offsetSource;
// HACK! Are we copying to the screen? This assumes a full screen update.
if (!target) {
_movedatal(_my_ds(), (int32_t)source->buffer.bits32, _vbeSurface.lfbSelector, 0x0, _vbeSurface.screenDWords);
return;
}
if (targetX == 0 && targetY == 0 && target->width == source->width && target->height == source->height) {
// Direct blit of entire surface.
memcpy(target->buffer.bits8, source->buffer.bits8, source->bytes);
} else {
// Blit into larger surface.
offsetTarget = targetY * _activeSurface->scanline + targetX * _vbeSurface.bytesPerPixel;
offsetSource = 0;
for (y1=targetY; y1<targetY+source->height; y1++) {
memcpy(&target->buffer.bits8[offsetTarget], &source->buffer.bits8[offsetSource], source->scanline);
offsetTarget += target->scanline;
offsetSource += source->scanline;
}
}
}
void videoSurfaceBlitWithTransparency(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source, ColorT transparent) {
uint16_t x1;
uint16_t y1;
uint16_t x2 = source->width;
uint16_t y2 = source->height;
ColorT pixel;
SurfaceT *t = videoSurfaceGet();
videoSurfaceSet(target);
// Clip on right and bottom
if (targetX + x2 > target->width) x2 -= targetX + x2 - target->width;
if (targetY + y2 > target->height) y2 -= targetY + y2 - target->height;
for (y1=0; y1<y2; y1++) {
for (x1=0; x1<x2; x1++) {
pixel = source->buffer.bits32[y1 * source->width + x1];
if (transparent != pixel) {
videoSurfacePixelSet(targetX + x1, targetY + y1, pixel);
}
}
}
videoSurfaceSet(t);
}
void videoSurfaceClear(ColorT color) {
uint16_t x;
size_t offsetTarget;
// Draw the top line.
for (x=0; x<_activeSurface->width; x++) {
videoSurfacePixelSet(x, 0, color);
}
// Copy it to the other lines.
offsetTarget = _activeSurface->scanline;
for (x=1; x<_activeSurface->height; x++) {
memcpy(&_activeSurface->buffer.bits8[offsetTarget], &_activeSurface->buffer.bits8[0], _activeSurface->scanline);
offsetTarget += _activeSurface->scanline;
}
}
SurfaceT *videoSurfaceCreate(int16_t width, int16_t height) {
SurfaceT *surface = NULL;
SurfaceT *surface = (SurfaceT *)malloc(sizeof(SurfaceT));
if (!surface) return NULL;
surface->width = width;
surface->height = height;
surface->scanline = width * _vbeSurface.bytesPerPixel;
surface->bytes = surface->scanline * height;
surface->buffer.bits8 = malloc(surface->bytes);
if (!surface->buffer.bits8) {
free(surface);
return NULL;
}
memset(surface->buffer.bits8, 0, surface->bytes);
return surface;
}
void videoSurfaceDestroy(SurfaceT *surface) {
}
void videoSurfaceBox(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT c) {
videoSurfaceLineH(x1, x2, y1, c);
videoSurfaceLineH(x1, x2, y2, c);
videoSurfaceLineV(x1, y1, y2, c);
videoSurfaceLineV(x2, y1, y2, c);
}
void videoSurfaceBoxFilled(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT c) {
int16_t i;
size_t offsetTarget;
size_t offsetSource;
uint16_t width;
if (x1 > x2) {
i = x1;
x1 = x2;
x2 = i;
}
if (y1 > y2) {
i = y1;
y1 = y2;
y2 = i;
}
width = (x2 - x1 + 1) * _vbeSurface.bytesPerPixel;
// Draw the top line.
for (i=x1; i<=x2; i++) {
videoSurfacePixelSet(i, y1, c);
}
// Copy it to the other lines.
offsetTarget = _activeSurface->scanline * (y1 + 1) + (x1 * _vbeSurface.bytesPerPixel);
offsetSource = _activeSurface->scanline * y1 + (x1 * _vbeSurface.bytesPerPixel);
for (i=y1 + 1; i<=y2; i++) {
memcpy(&_activeSurface->buffer.bits8[offsetTarget], &_activeSurface->buffer.bits8[offsetSource], width);
offsetTarget += _activeSurface->scanline;
}
}
void videoSurfaceDestroy(SurfaceT *surface) {
free(surface->buffer.bits8);
free(surface);
}
SurfaceT *videoSurfaceGet(void) {
return _activeSurface;
}
@ -90,28 +725,60 @@ int16_t videoSurfaceHeightGet(SurfaceT *surface) {
}
void videoSurfaceLineH(int16_t x1, int16_t y1, int16_t x, ColorT c) {
void videoSurfaceLineH(int16_t x1, int16_t x2, int16_t y, ColorT c) {
int16_t i;
int16_t t;
if (x1 > x2) {
t = x2;
x2 = x1;
x1 = t;
}
for (i=x1; i<=x2; i++) {
videoSurfacePixelSet(i, y, c);
}
}
void videoSurfaceLineV(int16_t x, int16_t x2, int16_t y2, ColorT c) {
void videoSurfaceLineV(int16_t x, int16_t y1, int16_t y2, ColorT c) {
int16_t i;
int16_t t;
if (y1 > y2) {
t = y2;
y2 = y1;
y1 = t;
}
for (i=y1; i<=y2; i++) {
videoSurfacePixelSet(x, i, c);
}
}
ColorT videoSurfacePixelGet(SurfaceT *surface, int16_t x, int16_t y) {
return 0;
return surface->buffer.bits32[y * surface->width + x];
}
void videoSurfacePixelSet(int16_t x, int16_t y, ColorT c) {
static void videoSurfacePixelSet8(uint16_t x, uint16_t y, ColorT color) {
_activeSurface->buffer.bits8[y * _activeSurface->width + x] = (uint8_t)color;
}
static void videoSurfacePixelSet16(uint16_t x, uint16_t y, ColorT color) {
_activeSurface->buffer.bits16[y * _activeSurface->width + x] = (uint16_t)color;
}
static void videoSurfacePixelSet32(uint16_t x, uint16_t y, ColorT color) {
_activeSurface->buffer.bits32[y * _activeSurface->width + x] = color;
}
void videoSurfaceSet(SurfaceT *surface) {
_activeSurface = surface;
}

View file

@ -5,8 +5,6 @@
#include <stdint.h>
#include <stdlib.h>
#include "gui/font.h"
typedef uint32_t ColorT;
@ -48,29 +46,26 @@ typedef struct EventS {
#define KEY_ESC 27
#define FONT_VGA_8x14 __font8x14
extern void (*videoSurfacePixelSet)(uint16_t x, uint16_t y, ColorT color);
extern FontT *__font8x14;
void fontWrite(char *message, int16_t x, int16_t y, FontT *font, ColorT foreground, ColorT background);
SurfaceT *imageLoad(char *filename);
void platformEventGet(EventT *event);
ColorT videoColorMake(uint8_t red, uint8_t green, uint8_t blue);
uint16_t videoDisplayHeightGet(void);
uint16_t videoDisplayWidthGet(void);
void videoSurfaceBlit(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source);
void videoSurfaceBlitWithTransparency(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source, ColorT transparent);
void videoSurfaceClear(ColorT color);
SurfaceT *videoSurfaceCreate(int16_t width, int16_t height);
void videoSurfaceDestroy(SurfaceT *surface);
void videoSurfaceBox(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT c);
void videoSurfaceBoxFilled(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT c);
void videoSurfaceDestroy(SurfaceT *surface);
SurfaceT *videoSurfaceGet(void);
int16_t videoSurfaceHeightGet(SurfaceT *surface);
void videoSurfaceLineH(int16_t x1, int16_t y1, int16_t x, ColorT c);
void videoSurfaceLineV(int16_t x, int16_t x2, int16_t y2, ColorT c);
ColorT videoSurfacePixelGet(SurfaceT *surface, int16_t x, int16_t y);
void videoSurfacePixelSet(int16_t x, int16_t y, ColorT c);
void videoSurfaceSet(SurfaceT *surface);
SurfaceT *videoSurfaceScreenGet(void);
int16_t videoSurfaceWidthGet(SurfaceT *surface);

View file

@ -18,21 +18,6 @@ typedef struct VideoModeS {
extern struct _GR_mouseInfo _GrMouseInfo;
SurfaceT *imageLoad(char *filename) {
int32_t x;
int32_t y;
SurfaceT *image = 0;
if (!GrQueryPng(filename, &x, &y)) {
//***TODO*** Die
}
image = videoSurfaceCreate(x, y);
GrLoadContextFromPng(image, filename, 0);
return image;
}
void platformShutdown(void) {
GrMouseEraseCursor();
GrMouseUnInit();

View file

@ -34,10 +34,12 @@ typedef GrMouseEvent EventT;
#define videoDisplayHeightGet GrScreenY
#define videoDisplayWidthGet GrScreenX
#define videoSurfaceClear GrClearContext
#define videoColorMake GrAllocColor
#define videoSurfaceCreate(w,h) GrCreateContext(w,h,0,0)
#define videoSurfaceDestroy GrDestroyContext
#define videoSurfaceBox GrBox
#define videoSurfaceBoxFilled GrFilledBox
#define videoSurfaceDestroy GrDestroyContext
#define videoSurfaceGet GrCurrentContext
#define videoSurfaceLineH GrHLine
#define videoSurfaceLineV GrVLine
#define videoSurfacePixelGet GrPixelC
@ -46,8 +48,6 @@ typedef GrMouseEvent EventT;
#define videoSurfaceScreenGet GrScreenContext
SurfaceT *imageLoad(char *filename);
void videoSurfaceBlit(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source);
void videoSurfaceBlitWithTransparency(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source, ColorT transparent);
int16_t videoSurfaceHeightGet(SurfaceT *surface);

View file

@ -24,29 +24,6 @@ extern ColorT *__guiBaseColors;
#define PUTPIXEL(s,x,y,c) s->buffer.bits32[(y) * s->width + (x)] = (c)
SurfaceT *imageLoad(char *filename) {
SurfaceT *image = NULL;
SDL_Surface *i = NULL;
SDL_Surface *s = IMG_Load(filename);
if (s) {
i = SDL_ConvertSurfaceFormat(s, _pixelFormat, 0);
if (i) {
image = videoSurfaceCreate(s->w, s->h);
if (image) {
SDL_LockSurface(i);
memcpy(image->buffer.bits8, i->pixels, image->bytes);
SDL_UnlockSurface(i);
}
SDL_FreeSurface(i);
}
SDL_FreeSurface(s);
}
return image;
}
void platformEventGet(EventT *event) {
SDL_Event e;
static uint8_t ASCII = 0;
@ -134,7 +111,6 @@ void platformShutdown(void) {
_window = NULL;
}
IMG_Quit();
SDL_Quit();
}
@ -163,7 +139,6 @@ void platformStartup(int16_t width, int16_t height, int16_t depth) {
(void)depth;
SDL_Init(SDL_INIT_EVERYTHING);
IMG_Init(IMG_INIT_PNG);
_windowScale = 3;
@ -180,7 +155,7 @@ void platformStartup(int16_t width, int16_t height, int16_t depth) {
__guiBaseColors = (ColorT *)malloc(sizeof(ColorT) * 16);
for (i=0; i<16; i++) {
__guiBaseColors[i] = COLOR(EGA[i][0], EGA[i][1], EGA[i][2]);
__guiBaseColors[i] = videoColorMake(EGA[i][0], EGA[i][1], EGA[i][2]);
}
}
@ -300,12 +275,6 @@ SurfaceT *videoSurfaceCreate(int16_t width, int16_t height) {
}
void videoSurfaceDestroy(SurfaceT *surface) {
free(surface->buffer.bits8);
free(surface);
}
void videoSurfaceBox(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT c) {
videoSurfaceLineH(x1, x2, y1, c);
videoSurfaceLineH(x1, x2, y2, c);
@ -341,7 +310,7 @@ void videoSurfaceBoxFilled(int16_t x1, int16_t y1, int16_t x2, int16_t y2, Color
// Copy it to the other lines.
offsetTarget = _activeSurface->scanline * (y1 + 1) + (x1 * BYTES_PER_PIXEL);
offsetSource = _activeSurface->scanline * y1+ (x1 * BYTES_PER_PIXEL);
offsetSource = _activeSurface->scanline * y1 + (x1 * BYTES_PER_PIXEL);
for (i=y1 + 1; i<=y2; i++) {
memcpy(&_activeSurface->buffer.bits8[offsetTarget], &_activeSurface->buffer.bits8[offsetSource], width);
offsetTarget += _activeSurface->scanline;
@ -349,6 +318,17 @@ void videoSurfaceBoxFilled(int16_t x1, int16_t y1, int16_t x2, int16_t y2, Color
}
void videoSurfaceDestroy(SurfaceT *surface) {
free(surface->buffer.bits8);
free(surface);
}
SurfaceT *videoSurfaceGet(void) {
return _activeSurface;
}
int16_t videoSurfaceHeightGet(SurfaceT *surface) {
return surface->height;
}

View file

@ -5,10 +5,9 @@
#include <stdint.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "gui/color.h"
typedef uint32_t ColorT;
typedef struct SurfaceS {
uint16_t width;
@ -49,7 +48,9 @@ typedef struct EventS {
#define KEY_ESC 27
SurfaceT *imageLoad(char *filename);
#define videoColorMake(r,g,b) (((r) << 24) | ((g) << 16) | ((b) << 8) | 255)
void platformEventGet(EventT *event);
uint16_t videoDisplayHeightGet(void);
uint16_t videoDisplayWidthGet(void);
@ -57,9 +58,10 @@ void videoSurfaceBlit(SurfaceT *target, int16_t targetX, int16_t targetY, S
void videoSurfaceBlitWithTransparency(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source, ColorT transparent);
void videoSurfaceClear(ColorT color);
SurfaceT *videoSurfaceCreate(int16_t width, int16_t height);
void videoSurfaceDestroy(SurfaceT *surface);
void videoSurfaceBox(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT c);
void videoSurfaceBoxFilled(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT c);
void videoSurfaceDestroy(SurfaceT *surface);
SurfaceT *videoSurfaceGet(void);
int16_t videoSurfaceHeightGet(SurfaceT *surface);
void videoSurfaceLineH(int16_t x1, int16_t x2, int16_t y, ColorT c);
void videoSurfaceLineV(int16_t x, int16_t y1, int16_t y2, ColorT c);

7897
client/src/thirdparty/stb_image.h vendored Normal file

File diff suppressed because it is too large Load diff