From 22954a848a17e448530eb0125443ec8581c2a01e Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Sun, 7 Nov 2021 17:50:42 -0600 Subject: [PATCH] Surface and drawing code isolated to ease porting. --- client/client.pro | 3 + client/src/dos/vesa.c | 181 +++++---------------------- client/src/gui/button.c | 4 +- client/src/gui/checkbox.c | 4 +- client/src/gui/desktop.c | 6 +- client/src/gui/font.c | 17 +-- client/src/gui/frame.c | 2 +- client/src/gui/gui.c | 192 ++++++++-------------------- client/src/gui/gui.h | 5 +- client/src/gui/image.c | 17 +-- client/src/gui/image.h | 2 +- client/src/gui/listbox.c | 26 ++-- client/src/gui/radio.c | 12 +- client/src/gui/terminal.c | 32 ++--- client/src/gui/textbox.c | 6 +- client/src/gui/updown.c | 26 ++-- client/src/gui/window.c | 14 +-- client/src/linux/linux.c | 139 +++++---------------- client/src/main.c | 15 ++- client/src/system/color.h | 31 +++++ client/src/system/surface.c | 243 ++++++++++++++++++++++++++++++++++++ client/src/system/surface.h | 61 +++++++++ client/src/system/task.h | 2 +- client/src/system/vesa.h | 37 ++---- 24 files changed, 561 insertions(+), 516 deletions(-) create mode 100644 client/src/system/color.h create mode 100644 client/src/system/surface.c create mode 100644 client/src/system/surface.h diff --git a/client/client.pro b/client/client.pro index f6660a0..7185c6e 100644 --- a/client/client.pro +++ b/client/client.pro @@ -47,6 +47,8 @@ INCLUDEPATH += \ HEADERS = \ $$LINUX_HEADERS \ + src/system/color.h \ + src/system/surface.h \ src/thirdparty/stb_ds.h \ src/thirdparty/stb_image.h \ src/thirdparty/memwatch/memwatch.h \ @@ -81,6 +83,7 @@ HEADERS = \ SOURCES = \ $$LINUX_SOURCES \ + src/system/surface.c \ src/thirdparty/memwatch/memwatch.c \ src/system/memory.c \ src/system/array.c \ diff --git a/client/src/dos/vesa.c b/client/src/dos/vesa.c index 4c4bd48..e6a28fb 100644 --- a/client/src/dos/vesa.c +++ b/client/src/dos/vesa.c @@ -131,28 +131,22 @@ typedef struct VBESurfaceS { } VBESurfaceT; -VBEInfoT *vbeGetInfo(void); -VBEModeInfoT *vbeGetModeInfo(uint16_t vbeModeNumber); -VBEModeInfoT *vbeGetModeInfoPtr(void); -void *vbeGetPmodeInterface(void); -VBESurfaceT *vbeGetVBESurfacePtr(void); -VBESurfaceT *vbeModeInit(uint16_t xRes, uint16_t yRes, uint8_t bpp); -void vbePresent(void); -uint16_t vbeSelectModeNumber(uint16_t xRes, uint16_t yRes, uint8_t bpp); -void vbeSetDisplayStart(uint32_t pixel, uint32_t scanline); -VBESurfaceT *vbeSetMode(uint16_t vbeModeNumber); -uint16_t vbeSetScanlineLength(uint16_t pixelLength); - -void (*vbePutPixel)(uint16_t x, uint16_t y, ColorT color); +static void vbeCreatePalette(void); +static VBEInfoT *vbeGetInfo(void); +static VBEModeInfoT *vbeGetModeInfo(uint16_t vbeModeNumber); +static VBEModeInfoT *vbeGetModeInfoPtr(void); +static void *vbeGetPmodeInterface(void); +static VBESurfaceT *vbeGetVBESurfacePtr(void); +static uint8_t vbeIsDesiredMode(void); +static VBESurfaceT *vbeModeInit(uint16_t xRes, uint16_t yRes, uint8_t bpp); +static uint16_t vbeSelectModeNumber(uint16_t xRes, uint16_t yRes, uint8_t bpp); +static void vbeSetDisplayStart(uint32_t pixel, uint32_t scanline); +static VBESurfaceT *vbeSetMode(uint16_t vbeModeNumber); +static uint16_t vbeSetScanlineLength(uint16_t pixelLength); static void (*pmVBESetDisplayStart)(void); - -static void vbeCreatePalette(void); -static uint8_t vbeIsDesiredMode(void); -static void vbePutPixel8(uint16_t x, uint16_t y, ColorT color); -static void vbePutPixel16(uint16_t x, uint16_t y, ColorT color); -static void vbePutPixel32(uint16_t x, uint16_t y, ColorT color); +void (*surfacePutPixel)(uint16_t x, uint16_t y, ColorT color); static VBESurfaceT _vbeSurface; @@ -160,8 +154,6 @@ static VBEInfoT _vbeInfo; static VBEModeInfoT _vbeModeInfo; static PModeInterfaceT *_pmodeInterfacePtr; static uint32_t *_yTable; -static SurfaceT *_activeSurface; -static SurfaceT *_offScreenSurface; static void vbeCreatePalette(void) { @@ -185,11 +177,16 @@ static void vbeCreatePalette(void) { } -uint8_t vbeDisplayDepthGet(void) { +uint8_t vbeDisplayDepthBitsGet(void) { return _vbeSurface.bitsPerPixel; } +uint8_t vbeDisplayDepthBytesGet(void) { + return _vbeSurface.bytesPerPixel; +} + + uint16_t vbeDisplayHeightGet(void) { return _vbeSurface.yResolution; } @@ -200,7 +197,7 @@ uint16_t vbeDisplayWidthGet(void) { } -VBEInfoT *vbeGetInfo(void) { +static VBEInfoT *vbeGetInfo(void) { uint16_t counter = 0; uint16_t offset = 0; uint16_t vbeMode = 0xFFFF; @@ -278,7 +275,7 @@ VBEInfoT *vbeGetInfo(void) { } -VBEModeInfoT *vbeGetModeInfo(uint16_t vbeModeNumber) { +static VBEModeInfoT *vbeGetModeInfo(uint16_t vbeModeNumber) { __dpmi_regs r; if (_vbeSurface.vbeBoolean == 0) return NULL; @@ -309,12 +306,12 @@ VBEModeInfoT *vbeGetModeInfo(uint16_t vbeModeNumber) { } -VBEModeInfoT *vbeGetModeInfoPtr(void) { +static VBEModeInfoT *vbeGetModeInfoPtr(void) { return(&_vbeModeInfo); } -void *vbeGetPmodeInterface(void) { +static void *vbeGetPmodeInterface(void) { __dpmi_regs r; __dpmi_meminfo m; uint16_t *ptr; @@ -364,7 +361,7 @@ void *vbeGetPmodeInterface(void) { } -VBESurfaceT *vbeGetVBESurfacePtr(void) { +static VBESurfaceT *vbeGetVBESurfacePtr(void) { return(&_vbeSurface); } @@ -392,7 +389,7 @@ static uint8_t vbeIsDesiredMode(void) { } -ColorT vbeMakeColor(uint8_t red, uint8_t green, uint8_t blue) { +ColorT vbeColorMake(uint8_t red, uint8_t green, uint8_t blue) { return (((red >> _vbeSurface.rShift) << _vbeSurface.rPos) & _vbeSurface.rMask) | (((green >> _vbeSurface.gShift) << _vbeSurface.gPos) & _vbeSurface.gMask) | @@ -400,7 +397,7 @@ ColorT vbeMakeColor(uint8_t red, uint8_t green, uint8_t blue) { } -VBESurfaceT *vbeModeInit(uint16_t xRes, uint16_t yRes, uint8_t bpp) { +static VBESurfaceT *vbeModeInit(uint16_t xRes, uint16_t yRes, uint8_t bpp) { uint16_t vbeModeNumber; __dpmi_meminfo m; @@ -425,30 +422,11 @@ VBESurfaceT *vbeModeInit(uint16_t xRes, uint16_t yRes, uint8_t bpp) { void vbePresent(void) { - _movedatal(_my_ds(), (int32_t)_offScreenSurface->buffer.bits32, _vbeSurface.lfbSelector, 0x0, _vbeSurface.screenDWords); - //memset(_offScreenSurface->buffer.bits8, 0, _offScreenSurface->bytes); + _movedatal(_my_ds(), (int32_t)surfaceOffscreenGet()->buffer.bits32, _vbeSurface.lfbSelector, 0x0, _vbeSurface.screenDWords); } -static void vbePutPixel8(uint16_t x, uint16_t y, ColorT color) { - //_farpokeb(_vbeSurface.lfbSelector, _yTable[y] + x, (uint8_t)color); - _activeSurface->buffer.bits8[y * _activeSurface->width + x] = (uint8_t)color; -} - - -static void vbePutPixel16(uint16_t x, uint16_t y, ColorT color) { - //_farpokew(_vbeSurface.lfbSelector, _yTable[y] + (x << 1), (uint16_t)color); - _activeSurface->buffer.bits16[y * _activeSurface->width + x] = (uint16_t)color; -} - - -static void vbePutPixel32(uint16_t x, uint16_t y, ColorT color) { - //_farpokel(_vbeSurface.lfbSelector, _yTable[y] + (x << 2), color); - _activeSurface->buffer.bits32[y * _activeSurface->width + x] = color; -} - - -uint16_t vbeSelectModeNumber(uint16_t xRes, uint16_t yRes, uint8_t bpp) { +static uint16_t vbeSelectModeNumber(uint16_t xRes, uint16_t yRes, uint8_t bpp) { uint16_t counter; if (_vbeSurface.vbeBoolean == 0) return(0); @@ -466,7 +444,7 @@ uint16_t vbeSelectModeNumber(uint16_t xRes, uint16_t yRes, uint8_t bpp) { } -void vbeSetDisplayStart(uint32_t pixel, uint32_t scanline) { +static void vbeSetDisplayStart(uint32_t pixel, uint32_t scanline) { __dpmi_regs r; int32_t address; int32_t selector; @@ -501,7 +479,7 @@ void vbeSetDisplayStart(uint32_t pixel, uint32_t scanline) { } -VBESurfaceT *vbeSetMode(uint16_t vbeModeNumber) { +static VBESurfaceT *vbeSetMode(uint16_t vbeModeNumber) { __dpmi_regs r; __dpmi_meminfo m; uint32_t counter; @@ -510,7 +488,6 @@ VBESurfaceT *vbeSetMode(uint16_t vbeModeNumber) { if (_vbeSurface.vbeInitBoolean == 1) return NULL; if (vbeGetModeInfo(vbeModeNumber) == 0) return NULL; - // create lookup table for putPixel routines if (_yTable) free(_yTable); if ((_yTable = malloc(4 * (_vbeModeInfo.yResolution + 1))) == 0) return NULL; for (counter = 0; counter <= _vbeModeInfo.yResolution; counter++) { @@ -552,8 +529,6 @@ VBESurfaceT *vbeSetMode(uint16_t vbeModeNumber) { _farpokeb(_vbeSurface.lfbSelector, counter, 0x0); // clear Lfb } - _offScreenSurface = vbeSurfaceCreate(_vbeSurface.xResolution, _vbeSurface.yResolution); - if (_vbeModeInfo.memoryModel == VBE_MM_PACKED) { vbeCreatePalette(); @@ -583,16 +558,11 @@ VBESurfaceT *vbeSetMode(uint16_t vbeModeNumber) { _vbeSurface.bPos = _vbeModeInfo.blueFieldPosition; _vbeSurface.aPos = _vbeModeInfo.rsvdFieldPosition; - if (_vbeSurface.bitsPerPixel == 8) vbePutPixel = vbePutPixel8; - if (_vbeSurface.bitsPerPixel == 16) vbePutPixel = vbePutPixel16; - if (_vbeSurface.bitsPerPixel == 15) vbePutPixel = vbePutPixel16; - if (_vbeSurface.bitsPerPixel == 32) vbePutPixel = vbePutPixel32; - return(&_vbeSurface); } -uint16_t vbeSetScanlineLength(uint16_t pixelLength) { +static uint16_t vbeSetScanlineLength(uint16_t pixelLength) { __dpmi_regs r; if (_vbeSurface.vbeBoolean == 0) return(0); @@ -610,7 +580,7 @@ uint16_t vbeSetScanlineLength(uint16_t pixelLength) { } -int16_t vbeShowInfo(void) { +int16_t vbeInfoShow(void) { int8_t counter; // 0 1 2 3 4 5 6 7 8 @@ -694,8 +664,6 @@ int16_t vbeShutdown(void) { __dpmi_free_ldt_descriptor(_vbeSurface.ioSegment); } - vbeSurfaceDestroy(&_offScreenSurface); - // return do DOS r.x.ax = 0x03; __dpmi_int(0x10, &r); @@ -738,90 +706,7 @@ uint8_t vbeStartup(uint16_t xRes, uint16_t yRes, uint8_t bpp) { } -void vbeSurfaceBlit(SurfaceT *source, uint16_t x, uint16_t y) { - uint16_t y1; - size_t offsetTarget; - size_t offsetSource; - - if (x == 0 && y == 0 && _activeSurface->width == source->width && _activeSurface->height == source->height) { - // Direct blit of entire surface. - memcpy(_activeSurface->buffer.bits8, source->buffer.bits8, source->bytes); - } else { - // Blit into larger surface. - offsetTarget = y * _activeSurface->scanline + x * _vbeSurface.bytesPerPixel; - offsetSource = 0; - for (y1=y; y1height; y1++) { - memcpy(&_activeSurface->buffer.bits8[offsetTarget], &source->buffer.bits8[offsetSource], source->scanline); - offsetTarget += _activeSurface->scanline; - offsetSource += source->scanline; - } - } -} - - -void vbeSurfaceClear(ColorT color) { - uint16_t x; - uint16_t y; - - for (y=0; y<_activeSurface->height; y++) { - for (x=0; x<_activeSurface->width; x++) { - vbePutPixel(x, y, color); - } - } -} - - -SurfaceT *vbeSurfaceCreate(uint16_t width, uint16_t height) { - 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 vbeSurfaceDestroy(SurfaceT **surface) { - SurfaceT *s = *surface; - - free(s->buffer.bits8); - free(s); - s = NULL; -} - - -uint16_t vbeSurfaceHeightGet(void) { - return _activeSurface->height; -} - - -uint16_t vbeSurfaceWidthGet(void) { - return _activeSurface->width; -} - - -void vbeSurfaceSet(SurfaceT *surface) { - if (surface) { - _activeSurface = surface; - } else { - _activeSurface = _offScreenSurface; - } -} - - -void vbeWaitVBlank(void) { +void vbeVBlankWait(void) { while(inportb(0x3DA) & 8); while(!(inportb(0x3DA) & 8)); } diff --git a/client/src/gui/button.c b/client/src/gui/button.c index a844099..c092adf 100644 --- a/client/src/gui/button.c +++ b/client/src/gui/button.c @@ -115,11 +115,11 @@ static void buttonPaint(WidgetT *widget, RectT pos) { // Draw bezel. for (i=0; i<_guiMetric[METRIC_BUTTON_BEZEL_SIZE]; i++) { - guiDrawHighlightFrame(pos.x + i, pos.y + i, pos.x + pos.w - i, pos.y + pos.h - i, highlight, shadow); + surfaceDrawHighlightFrame(pos.x + i, pos.y + i, pos.x + pos.w - i, pos.y + pos.h - i, highlight, shadow); } // Draw background (depends on x from above). - guiDrawRectangleFilled(pos.x + i, pos.y + i, pos.x + pos.w - i, pos.y + pos.h - i, _guiColor[COLOR_BUTTON_BACKGROUND]); + surfaceDrawRectangleFilled(pos.x + i, pos.y + i, pos.x + pos.w - i, pos.y + pos.h - i, _guiColor[COLOR_BUTTON_BACKGROUND]); // Draw title (depends on x from above). fontRender(_guiFont, b->title, _guiColor[COLOR_BUTTON_TEXT], _guiColor[COLOR_BUTTON_BACKGROUND], pos.x + i + _guiMetric[METRIC_BUTTON_HORIZONTAL_PADDING] + active, pos.y + i + _guiMetric[METRIC_BUTTON_VERTICAL_PADDING] + active); diff --git a/client/src/gui/checkbox.c b/client/src/gui/checkbox.c index 7d3408f..522f370 100644 --- a/client/src/gui/checkbox.c +++ b/client/src/gui/checkbox.c @@ -109,10 +109,10 @@ static void checkboxPaint(WidgetT *widget, RectT pos) { o = (_guiFont->height - 10) * 0.5; // Draw outline of checkbox. - guiDrawHighlightFrame(pos.x, pos.y + o, pos.x + 10, pos.y + 10 + o, highlight, shadow); + surfaceDrawHighlightFrame(pos.x, pos.y + o, pos.x + 10, pos.y + 10 + o, highlight, shadow); // Draw background. - guiDrawRectangleFilled(pos.x + 1, pos.y + o + 1, pos.x + 9, pos.y + + o + 9, fill); + surfaceDrawRectangleFilled(pos.x + 1, pos.y + o + 1, pos.x + 9, pos.y + + o + 9, fill); // Draw title. fontRender(_guiFont, c->title, _guiColor[COLOR_CHECKBOX_TEXT], _guiColor[COLOR_WINDOW_BACKGROUND], pos.x + 10 + _guiMetric[METRIC_CHECKBOX_PADDING], pos.y); diff --git a/client/src/gui/desktop.c b/client/src/gui/desktop.c index b86a21f..85b4f1b 100644 --- a/client/src/gui/desktop.c +++ b/client/src/gui/desktop.c @@ -29,7 +29,7 @@ static void desktopPaint(WidgetT *desktop, RectT pos); static void desktopDel(WidgetT **widget) { DesktopT *d = (DesktopT *)*widget; - vbeSurfaceDestroy(&d->base.surface); + surfaceDestroy(&d->base.surface); free(d); d = NULL; } @@ -43,7 +43,7 @@ WidgetT *desktopInit(WidgetT *desktop) { d->base.paintMethod = desktopPaint; GUI_SET_FLAG(desktop, WIDGET_FLAG_OWNS_SURFACE); - d->base.surface = vbeSurfaceCreate(d->base.pos.w, d->base.pos.h); + d->base.surface = surfaceCreate(d->base.pos.w, d->base.pos.h); if (!d->base.surface) { free(d); return NULL; @@ -75,7 +75,7 @@ static void desktopPaint(WidgetT *desktop, RectT pos) { (void)pos; if (GUI_GET_FLAG(desktop, WIDGET_FLAG_DIRTY)) { - vbeSurfaceClear(_guiColor[COLOR_DESKTOP]); + surfaceClear(_guiColor[COLOR_DESKTOP]); GUI_CLEAR_FLAG(desktop, WIDGET_FLAG_DIRTY); } } diff --git a/client/src/gui/font.c b/client/src/gui/font.c index a39e34d..e7ca463 100644 --- a/client/src/gui/font.c +++ b/client/src/gui/font.c @@ -19,6 +19,7 @@ #include "font.h" +#include "surface.h" uint16_t fontHeightGet(FontT *font) { @@ -92,14 +93,14 @@ void fontRender(FontT *font, char *string, ColorT foreground, ColorT background, // We do 8 pixels unrolled hoping it's fast. data = font->bits[offset]; offset += font->span; - vbePutPixel(x, yp, data & 0x80 ? foreground : background); - vbePutPixel(x + 1, yp, data & 0x40 ? foreground : background); - vbePutPixel(x + 2, yp, data & 0x20 ? foreground : background); - vbePutPixel(x + 3, yp, data & 0x10 ? foreground : background); - vbePutPixel(x + 4, yp, data & 0x08 ? foreground : background); - vbePutPixel(x + 5, yp, data & 0x04 ? foreground : background); - vbePutPixel(x + 6, yp, data & 0x02 ? foreground : background); - vbePutPixel(x + 7, yp, data & 0x01 ? foreground : background); + surfacePutPixel(x, yp, data & 0x80 ? foreground : background); + surfacePutPixel(x + 1, yp, data & 0x40 ? foreground : background); + surfacePutPixel(x + 2, yp, data & 0x20 ? foreground : background); + surfacePutPixel(x + 3, yp, data & 0x10 ? foreground : background); + surfacePutPixel(x + 4, yp, data & 0x08 ? foreground : background); + surfacePutPixel(x + 5, yp, data & 0x04 ? foreground : background); + surfacePutPixel(x + 6, yp, data & 0x02 ? foreground : background); + surfacePutPixel(x + 7, yp, data & 0x01 ? foreground : background); yp++; } diff --git a/client/src/gui/frame.c b/client/src/gui/frame.c index 933c8cd..0ee8ef0 100644 --- a/client/src/gui/frame.c +++ b/client/src/gui/frame.c @@ -70,7 +70,7 @@ static void framePaint(WidgetT *widget, RectT pos) { if (GUI_GET_FLAG(widget, WIDGET_FLAG_DIRTY)) { // Draw frame. - guiDrawHighlightFrame(pos.x, pos.y + (fontHeightGet(_guiFont) * 0.5), pos.x + pos.w, pos.y + pos.h, _guiColor[COLOR_FRAME_SHADOW], _guiColor[COLOR_FRAME_HIGHLIGHT]); + surfaceDrawHighlightFrame(pos.x, pos.y + (fontHeightGet(_guiFont) * 0.5), pos.x + pos.w, pos.y + pos.h, _guiColor[COLOR_FRAME_SHADOW], _guiColor[COLOR_FRAME_HIGHLIGHT]); // Draw title. fontRender(_guiFont, f->title, _guiColor[COLOR_FRAME_TEXT], _guiColor[COLOR_WINDOW_BACKGROUND], pos.x + 10, pos.y); diff --git a/client/src/gui/gui.c b/client/src/gui/gui.c index 832807e..461e8b3 100644 --- a/client/src/gui/gui.c +++ b/client/src/gui/gui.c @@ -123,11 +123,11 @@ void guiComposite() { // Repaint anyone who needs it. guiPaint(widget); - vbeSurfaceSet(NULL); + surfaceSet(NULL); // Render us? if (GUI_GET_FLAG(widget, WIDGET_FLAG_OWNS_SURFACE)) { - vbeSurfaceBlit(widget->surface, widget->pos.x, widget->pos.y); + surfaceBlit(widget->surface, widget->pos.x, widget->pos.y); } //***TODO*** This is wrong. Should be recursive. @@ -136,7 +136,7 @@ void guiComposite() { if (len > 0) { for (x=0; xchildren[x], WIDGET_FLAG_OWNS_SURFACE)) { - vbeSurfaceBlit(widget->children[x]->surface, widget->children[x]->pos.x, widget->children[x]->pos.y); + surfaceBlit(widget->children[x]->surface, widget->children[x]->pos.x, widget->children[x]->pos.y); } } } @@ -159,95 +159,7 @@ void guiDelete(WidgetT **widget) { w->delMethod(&w); // Make sure we're not drawing into oblivion. - vbeSurfaceSet(NULL); -} - - -void guiDrawHighlightFrame(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ColorT upperLeft, ColorT lowerRight) { - guiDrawLine(x1, y1, x2, y1, upperLeft); - guiDrawLine(x1, y1, x1, y2, upperLeft); - guiDrawLine(x1, y2, x2, y2, lowerRight); - guiDrawLine(x2, y1, x2, y2, lowerRight); -} - - -void guiDrawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color) { - int16_t x; - int16_t y; - int16_t dx; - int16_t dy; - int16_t incX; - int16_t incY; - int16_t balance; - - if (x2 >= x1) { - dx = x2 - x1; - incX = 1; - } else { - dx = x1 - x2; - incX = -1; - } - - if (y2 >= y1) { - dy = y2 - y1; - incY = 1; - } else { - dy = y1 - y2; - incY = -1; - } - - x = x1; - y = y1; - - if (dx >= dy) { - dy <<= 1; - balance = dy - dx; - dx <<= 1; - while (x != x2) { - vbePutPixel(x, y, color); - if (balance >= 0) { - y += incY; - balance -= dx; - } - balance += dy; - x += incX; - } - vbePutPixel(x, y, color); - } else { - dx <<= 1; - balance = dx - dy; - dy <<= 1; - while (y != y2) { - vbePutPixel(x, y, color); - if (balance >= 0) { - x += incX; - balance -= dy; - } - balance += dx; - y += incY; - } - vbePutPixel(x, y, color); - } -} - - -void guiDrawRectangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color) { - guiDrawLine(x1, y1, x2, y1, color); - guiDrawLine(x2, y1, x2, y2, color); - guiDrawLine(x1, y2, x2, y2, color); - guiDrawLine(x1, y1, x1, y2, color); -} - - -void guiDrawRectangleFilled(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color) { - uint16_t x; - uint16_t y; - - for (y=y1; y<=y2; y++) { - for (x=x1; x<=x2; x++) { - vbePutPixel(x, y, color); - } - } + surfaceSet(NULL); } @@ -295,7 +207,7 @@ void guiPaint(WidgetT *widget) { // Paint us. Widget handles dirty flag so they can animate if needed. if (widget->paintMethod) { - vbeSurfaceSet(widget->surface); + surfaceSet(widget->surface); guiPaintBoundsGet(widget, &pos); widget->paintMethod(widget, pos); } @@ -488,53 +400,53 @@ DesktopT *guiStartup(void) { _guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING] = 2; _guiMetric[METRIC_LISTBOX_VERTICAL_PADDING] = 2; - _guiColor[COLOR_BUTTON_BACKGROUND] = vbeMakeColor(168, 168, 168); - _guiColor[COLOR_BUTTON_HIGHLIGHT] = vbeMakeColor(248, 252, 248); - _guiColor[COLOR_BUTTON_SHADOW] = vbeMakeColor( 80, 84, 80); - _guiColor[COLOR_BUTTON_TEXT] = vbeMakeColor( 0, 0, 0); - _guiColor[COLOR_DESKTOP] = vbeMakeColor( 51, 153, 255); - _guiColor[COLOR_WINDOW_BACKGROUND] = vbeMakeColor(168, 168, 168); - _guiColor[COLOR_WINDOW_HIGHLIGHT] = vbeMakeColor(248, 252, 248); - _guiColor[COLOR_WINDOW_SHADOW] = vbeMakeColor( 80, 84, 80); - _guiColor[COLOR_WINDOW_TITLE_ACTIVE] = vbeMakeColor( 80, 84, 80); - _guiColor[COLOR_WINDOW_TITLE_INACTIVE] = vbeMakeColor(168, 168, 168); - _guiColor[COLOR_WINDOW_TITLE_TEXT_ACTIVE] = vbeMakeColor(248, 252, 248); - _guiColor[COLOR_WINDOW_TITLE_TEXT_INACTIVE] = vbeMakeColor( 0, 0, 0); - _guiColor[COLOR_LABEL_TEXT_INACTIVE] = vbeMakeColor(248, 252, 248); - _guiColor[COLOR_LABEL_TEXT_INACTIVE] = vbeMakeColor( 0, 0, 0); - _guiColor[COLOR_CHECKBOX_HIGHLIGHT] = vbeMakeColor(248, 252, 248); - _guiColor[COLOR_CHECKBOX_SHADOW] = vbeMakeColor( 0, 0, 0); - _guiColor[COLOR_CHECKBOX_ACTIVE] = vbeMakeColor( 80, 84, 80); - _guiColor[COLOR_CHECKBOX_INACTIVE] = vbeMakeColor(168, 168, 168); - _guiColor[COLOR_CHECKBOX_TEXT] = vbeMakeColor( 0, 0, 0); - _guiColor[COLOR_RADIOBUTTON_HIGHLIGHT] = vbeMakeColor(248, 252, 248); - _guiColor[COLOR_RADIOBUTTON_SHADOW] = vbeMakeColor( 0, 0, 0); - _guiColor[COLOR_RADIOBUTTON_ACTIVE] = vbeMakeColor( 80, 84, 80); - _guiColor[COLOR_RADIOBUTTON_INACTIVE] = vbeMakeColor(168, 168, 168); - _guiColor[COLOR_RADIOBUTTON_TEXT] = vbeMakeColor( 0, 0, 0); - _guiColor[COLOR_FRAME_HIGHLIGHT] = vbeMakeColor(248, 252, 248); - _guiColor[COLOR_FRAME_SHADOW] = vbeMakeColor( 0, 0, 0); - _guiColor[COLOR_FRAME_TEXT] = vbeMakeColor( 0, 0, 0); - _guiColor[COLOR_TEXTBOX_HIGHLIGHT] = vbeMakeColor(248, 252, 248); - _guiColor[COLOR_TEXTBOX_SHADOW] = vbeMakeColor( 0, 0, 0); - _guiColor[COLOR_TEXTBOX_TEXT] = vbeMakeColor( 0, 0, 0); - _guiColor[COLOR_TEXTBOX_BACKGROUND] = vbeMakeColor(248, 252, 248); - _guiColor[COLOR_UPDOWN_HIGHLIGHT] = vbeMakeColor(248, 252, 248); - _guiColor[COLOR_UPDOWN_SHADOW] = vbeMakeColor( 0, 0, 0); - _guiColor[COLOR_UPDOWN_TEXT] = vbeMakeColor( 0, 0, 0); - _guiColor[COLOR_UPDOWN_BACKGROUND] = vbeMakeColor(248, 252, 248); - _guiColor[COLOR_UPDOWN_ARROWS_BACKGROUND] = vbeMakeColor(124, 126, 124); - _guiColor[COLOR_UPDOWN_ARROWS_ACTIVE] = vbeMakeColor(168, 168, 168); - _guiColor[COLOR_UPDOWN_ARROWS_INACTIVE] = vbeMakeColor( 80, 84, 80); - _guiColor[COLOR_LISTBOX_HIGHLIGHT] = vbeMakeColor(248, 252, 248); - _guiColor[COLOR_LISTBOX_SHADOW] = vbeMakeColor( 0, 0, 0); - _guiColor[COLOR_LISTBOX_TEXT] = vbeMakeColor( 0, 0, 0); - _guiColor[COLOR_LISTBOX_BACKGROUND] = vbeMakeColor(248, 252, 248); - _guiColor[COLOR_LISTBOX_SELECTED_TEXT] = vbeMakeColor(248, 252, 248); - _guiColor[COLOR_LISTBOX_SELECTED_BACKGROUND] = vbeMakeColor( 0, 0, 0); - _guiColor[COLOR_LISTBOX_ARROWS_BACKGROUND] = vbeMakeColor(124, 126, 124); - _guiColor[COLOR_LISTBOX_ARROWS_ACTIVE] = vbeMakeColor(168, 168, 168); - _guiColor[COLOR_LISTBOX_ARROWS_INACTIVE] = vbeMakeColor( 80, 84, 80); + _guiColor[COLOR_BUTTON_BACKGROUND] = vbeColorMake(168, 168, 168); + _guiColor[COLOR_BUTTON_HIGHLIGHT] = vbeColorMake(248, 252, 248); + _guiColor[COLOR_BUTTON_SHADOW] = vbeColorMake( 80, 84, 80); + _guiColor[COLOR_BUTTON_TEXT] = vbeColorMake( 0, 0, 0); + _guiColor[COLOR_DESKTOP] = vbeColorMake( 51, 153, 255); + _guiColor[COLOR_WINDOW_BACKGROUND] = vbeColorMake(168, 168, 168); + _guiColor[COLOR_WINDOW_HIGHLIGHT] = vbeColorMake(248, 252, 248); + _guiColor[COLOR_WINDOW_SHADOW] = vbeColorMake( 80, 84, 80); + _guiColor[COLOR_WINDOW_TITLE_ACTIVE] = vbeColorMake( 80, 84, 80); + _guiColor[COLOR_WINDOW_TITLE_INACTIVE] = vbeColorMake(168, 168, 168); + _guiColor[COLOR_WINDOW_TITLE_TEXT_ACTIVE] = vbeColorMake(248, 252, 248); + _guiColor[COLOR_WINDOW_TITLE_TEXT_INACTIVE] = vbeColorMake( 0, 0, 0); + _guiColor[COLOR_LABEL_TEXT_INACTIVE] = vbeColorMake(248, 252, 248); + _guiColor[COLOR_LABEL_TEXT_INACTIVE] = vbeColorMake( 0, 0, 0); + _guiColor[COLOR_CHECKBOX_HIGHLIGHT] = vbeColorMake(248, 252, 248); + _guiColor[COLOR_CHECKBOX_SHADOW] = vbeColorMake( 0, 0, 0); + _guiColor[COLOR_CHECKBOX_ACTIVE] = vbeColorMake( 80, 84, 80); + _guiColor[COLOR_CHECKBOX_INACTIVE] = vbeColorMake(168, 168, 168); + _guiColor[COLOR_CHECKBOX_TEXT] = vbeColorMake( 0, 0, 0); + _guiColor[COLOR_RADIOBUTTON_HIGHLIGHT] = vbeColorMake(248, 252, 248); + _guiColor[COLOR_RADIOBUTTON_SHADOW] = vbeColorMake( 0, 0, 0); + _guiColor[COLOR_RADIOBUTTON_ACTIVE] = vbeColorMake( 80, 84, 80); + _guiColor[COLOR_RADIOBUTTON_INACTIVE] = vbeColorMake(168, 168, 168); + _guiColor[COLOR_RADIOBUTTON_TEXT] = vbeColorMake( 0, 0, 0); + _guiColor[COLOR_FRAME_HIGHLIGHT] = vbeColorMake(248, 252, 248); + _guiColor[COLOR_FRAME_SHADOW] = vbeColorMake( 0, 0, 0); + _guiColor[COLOR_FRAME_TEXT] = vbeColorMake( 0, 0, 0); + _guiColor[COLOR_TEXTBOX_HIGHLIGHT] = vbeColorMake(248, 252, 248); + _guiColor[COLOR_TEXTBOX_SHADOW] = vbeColorMake( 0, 0, 0); + _guiColor[COLOR_TEXTBOX_TEXT] = vbeColorMake( 0, 0, 0); + _guiColor[COLOR_TEXTBOX_BACKGROUND] = vbeColorMake(248, 252, 248); + _guiColor[COLOR_UPDOWN_HIGHLIGHT] = vbeColorMake(248, 252, 248); + _guiColor[COLOR_UPDOWN_SHADOW] = vbeColorMake( 0, 0, 0); + _guiColor[COLOR_UPDOWN_TEXT] = vbeColorMake( 0, 0, 0); + _guiColor[COLOR_UPDOWN_BACKGROUND] = vbeColorMake(248, 252, 248); + _guiColor[COLOR_UPDOWN_ARROWS_BACKGROUND] = vbeColorMake(124, 126, 124); + _guiColor[COLOR_UPDOWN_ARROWS_ACTIVE] = vbeColorMake(168, 168, 168); + _guiColor[COLOR_UPDOWN_ARROWS_INACTIVE] = vbeColorMake( 80, 84, 80); + _guiColor[COLOR_LISTBOX_HIGHLIGHT] = vbeColorMake(248, 252, 248); + _guiColor[COLOR_LISTBOX_SHADOW] = vbeColorMake( 0, 0, 0); + _guiColor[COLOR_LISTBOX_TEXT] = vbeColorMake( 0, 0, 0); + _guiColor[COLOR_LISTBOX_BACKGROUND] = vbeColorMake(248, 252, 248); + _guiColor[COLOR_LISTBOX_SELECTED_TEXT] = vbeColorMake(248, 252, 248); + _guiColor[COLOR_LISTBOX_SELECTED_BACKGROUND] = vbeColorMake( 0, 0, 0); + _guiColor[COLOR_LISTBOX_ARROWS_BACKGROUND] = vbeColorMake(124, 126, 124); + _guiColor[COLOR_LISTBOX_ARROWS_ACTIVE] = vbeColorMake(168, 168, 168); + _guiColor[COLOR_LISTBOX_ARROWS_INACTIVE] = vbeColorMake( 80, 84, 80); // Load all font sizes. _guiFont8 = fontLoad("vga8x8.dat"); diff --git a/client/src/gui/gui.h b/client/src/gui/gui.h index b25de68..507ded7 100644 --- a/client/src/gui/gui.h +++ b/client/src/gui/gui.h @@ -24,6 +24,7 @@ #include "os.h" #include "vesa.h" +#include "surface.h" #include "array.h" #include "mouse.h" #include "font.h" @@ -161,10 +162,6 @@ extern WindowT *_guiActiveWindow; void guiAttach(WidgetT *parent, WidgetT *child); void guiComposite(void); void guiDelete(WidgetT **widget); -void guiDrawHighlightFrame(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ColorT upperLeft, ColorT lowerRight); -void guiDrawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color); -void guiDrawRectangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color); -void guiDrawRectangleFilled(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color); WidgetT *guiFocusGet(void); void guiFocusSet(WidgetT *widget); void guiMousePositionOnWidgetGet(WidgetT *widget, MouseT *mouse, uint16_t *x, uint16_t *y); diff --git a/client/src/gui/image.c b/client/src/gui/image.c index 6228931..e93e3af 100644 --- a/client/src/gui/image.c +++ b/client/src/gui/image.c @@ -22,6 +22,9 @@ #define STBI_ONLY_PNG #include "image.h" +#include "surface.h" +#include "vesa.h" + ImageT *imageAllocate(uint16_t w, uint16_t h) { uint16_t x; @@ -120,7 +123,7 @@ ImageT *imageLoad(char *filename) { b = 0; for (y=0; yheight; y++) { for (x=0; xwidth; x++) { - image->pixels[x][y] = vbeMakeColor(raw[b], raw[b + 1], raw[b + 2]); + image->pixels[x][y] = vbeColorMake(raw[b], raw[b + 1], raw[b + 2]); b += 3; } } @@ -143,12 +146,12 @@ void imageRender(ImageT *image, uint16_t x, uint16_t y) { uint16_t y2 = image->height; // Clip on right and bottom - if (x + x2 > vbeSurfaceWidthGet()) x2 -= x + x2 - vbeSurfaceWidthGet(); - if (y + y2 > vbeSurfaceHeightGet()) y2 -= y + y2 - vbeSurfaceHeightGet(); + if (x + x2 > surfaceWidthGet()) x2 -= x + x2 - surfaceWidthGet(); + if (y + y2 > surfaceHeightGet()) y2 -= y + y2 - surfaceHeightGet(); for (y1=0; y1pixels[x1][y1]); + surfacePutPixel(x + x1, y + y1, image->pixels[x1][y1]); } } } @@ -161,13 +164,13 @@ void imageRenderWithAlpha(ImageT *image, uint16_t x, uint16_t y, ColorT alpha) { uint16_t y2 = image->height; // Clip on right and bottom - if (x + x2 > vbeSurfaceWidthGet()) x2 -= x + x2 - vbeSurfaceWidthGet(); - if (y + y2 > vbeSurfaceHeightGet()) y2 -= y + y2 - vbeSurfaceHeightGet(); + if (x + x2 > surfaceWidthGet()) x2 -= x + x2 - surfaceWidthGet(); + if (y + y2 > surfaceHeightGet()) y2 -= y + y2 - surfaceHeightGet(); for (y1=0; y1pixels[x1][y1]) { - vbePutPixel(x + x1, y + y1, image->pixels[x1][y1]); + surfacePutPixel(x + x1, y + y1, image->pixels[x1][y1]); } } } diff --git a/client/src/gui/image.h b/client/src/gui/image.h index 4a824f7..a5143fd 100644 --- a/client/src/gui/image.h +++ b/client/src/gui/image.h @@ -23,7 +23,7 @@ #include "os.h" -#include "vesa.h" +#include "color.h" #include "stb_image.h" diff --git a/client/src/gui/listbox.c b/client/src/gui/listbox.c index 6a21cba..3472143 100644 --- a/client/src/gui/listbox.c +++ b/client/src/gui/listbox.c @@ -238,16 +238,16 @@ static void listboxPaint(WidgetT *widget, RectT pos) { fontRender(_guiFont, l->title, _guiColor[COLOR_LISTBOX_TEXT], _guiColor[COLOR_WINDOW_BACKGROUND], pos.x, pos.y); // Draw outline of listbox. - guiDrawHighlightFrame(pos.x, _valueTop, pos.x + _valueWidth, _valueBottom, _guiColor[COLOR_LISTBOX_SHADOW], _guiColor[COLOR_LISTBOX_HIGHLIGHT]); + surfaceDrawHighlightFrame(pos.x, _valueTop, pos.x + _valueWidth, _valueBottom, _guiColor[COLOR_LISTBOX_SHADOW], _guiColor[COLOR_LISTBOX_HIGHLIGHT]); // Draw background of listbox. - guiDrawRectangleFilled(pos.x + 1, _valueTop + 1, pos.x + _valueWidth - 1, _valueBottom - 1, _guiColor[COLOR_LISTBOX_BACKGROUND]); + surfaceDrawRectangleFilled(pos.x + 1, _valueTop + 1, pos.x + _valueWidth - 1, _valueBottom - 1, _guiColor[COLOR_LISTBOX_BACKGROUND]); // Draw listbox contents. o = _valueTop + 1 + _guiMetric[METRIC_LISTBOX_VERTICAL_PADDING]; for (i=0; iselected) { - guiDrawRectangleFilled(pos.x + _guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o, pos.x + _valueWidth - _guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o + fontHeightGet(_guiFont) - 1, _guiColor[COLOR_LISTBOX_SELECTED_BACKGROUND]); + surfaceDrawRectangleFilled(pos.x + _guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o, pos.x + _valueWidth - _guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o + fontHeightGet(_guiFont) - 1, _guiColor[COLOR_LISTBOX_SELECTED_BACKGROUND]); fontRender(_guiFont, l->values[l->offset + i], _guiColor[COLOR_LISTBOX_SELECTED_TEXT], _guiColor[COLOR_LISTBOX_SELECTED_BACKGROUND], pos.x + 1 + _guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o); } else { fontRender(_guiFont, l->values[l->offset + i], _guiColor[COLOR_LISTBOX_TEXT], _guiColor[COLOR_LISTBOX_BACKGROUND], pos.x + 1 + _guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o); @@ -256,31 +256,31 @@ static void listboxPaint(WidgetT *widget, RectT pos) { } // Draw outline of arrows. - guiDrawHighlightFrame(_arrowStart, _valueTop, _arrowStart + _arrowWidth, _valueBottom, _guiColor[COLOR_LISTBOX_SHADOW], _guiColor[COLOR_LISTBOX_HIGHLIGHT]); + surfaceDrawHighlightFrame(_arrowStart, _valueTop, _arrowStart + _arrowWidth, _valueBottom, _guiColor[COLOR_LISTBOX_SHADOW], _guiColor[COLOR_LISTBOX_HIGHLIGHT]); // Draw background of arrows. - guiDrawRectangleFilled(_arrowStart + 1, _valueTop + 1, _arrowStart + _arrowWidth - 1, _valueBottom - 1, _guiColor[COLOR_LISTBOX_ARROWS_BACKGROUND]); + surfaceDrawRectangleFilled(_arrowStart + 1, _valueTop + 1, _arrowStart + _arrowWidth - 1, _valueBottom - 1, _guiColor[COLOR_LISTBOX_ARROWS_BACKGROUND]); // Draw up arrow _arrowStart += _halfFont + 1 + _guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING]; // Center of up arrow o = _valueTop + 1 + _guiMetric[METRIC_LISTBOX_VERTICAL_PADDING]; // Top of up arrow color = l->offset + l->selected > 0 ? _guiColor[COLOR_LISTBOX_ARROWS_ACTIVE] : _guiColor[COLOR_LISTBOX_ARROWS_INACTIVE]; for (i=0; i<=fontHeightGet(_guiFont); i++) { - guiDrawLine(_arrowStart - i * 0.5, o + i, _arrowStart + i * 0.5, o + i, color); + surfaceDrawLine(_arrowStart - i * 0.5, o + i, _arrowStart + i * 0.5, o + i, color); } - guiDrawLine(_arrowStart, o, _arrowStart + _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_LISTBOX_SHADOW]); - guiDrawLine(_arrowStart - _halfFont, o + fontHeightGet(_guiFont), _arrowStart + _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_LISTBOX_SHADOW]); - guiDrawLine(_arrowStart, o, _arrowStart - _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_LISTBOX_HIGHLIGHT]); + surfaceDrawLine(_arrowStart, o, _arrowStart + _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_LISTBOX_SHADOW]); + surfaceDrawLine(_arrowStart - _halfFont, o + fontHeightGet(_guiFont), _arrowStart + _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_LISTBOX_SHADOW]); + surfaceDrawLine(_arrowStart, o, _arrowStart - _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_LISTBOX_HIGHLIGHT]); // Draw down arrow o = _valueBottom - 1 - _guiMetric[METRIC_LISTBOX_VERTICAL_PADDING]; // Bottom of down arrow color = l->offset + l->selected < len - 1 ? _guiColor[COLOR_UPDOWN_ARROWS_ACTIVE] : _guiColor[COLOR_UPDOWN_ARROWS_INACTIVE]; for (i=0; i<=fontHeightGet(_guiFont); i++) { - guiDrawLine(_arrowStart - i * 0.5, o - i, _arrowStart + i * 0.5, o - i, color); + surfaceDrawLine(_arrowStart - i * 0.5, o - i, _arrowStart + i * 0.5, o - i, color); } - guiDrawLine(_arrowStart, o, _arrowStart + _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_SHADOW]); - guiDrawLine(_arrowStart - _halfFont, o - fontHeightGet(_guiFont), _arrowStart + _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]); - guiDrawLine(_arrowStart, o, _arrowStart - _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]); + surfaceDrawLine(_arrowStart, o, _arrowStart + _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_SHADOW]); + surfaceDrawLine(_arrowStart - _halfFont, o - fontHeightGet(_guiFont), _arrowStart + _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]); + surfaceDrawLine(_arrowStart, o, _arrowStart - _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]); GUI_CLEAR_FLAG(widget, WIDGET_FLAG_DIRTY); } diff --git a/client/src/gui/radio.c b/client/src/gui/radio.c index 4680535..6ec4ee5 100644 --- a/client/src/gui/radio.c +++ b/client/src/gui/radio.c @@ -165,15 +165,15 @@ static void radioPaint(WidgetT *widget, RectT pos) { o = (_guiFont->height - 10) * 0.5; // Draw outline of radio button. - guiDrawLine(pos.x, pos.y + o + 5, pos.x + 5, pos.y + o, highlight); - guiDrawLine(pos.x + 5, pos.y + o, pos.x + 10, pos.y + o + 5, highlight); - guiDrawLine(pos.x, pos.y + o + 5, pos.x + 5, pos.y + o + 10, shadow); - guiDrawLine(pos.x + 5, pos.y + o + 10, pos.x + 10, pos.y + o + 5, shadow); + surfaceDrawLine(pos.x, pos.y + o + 5, pos.x + 5, pos.y + o, highlight); + surfaceDrawLine(pos.x + 5, pos.y + o, pos.x + 10, pos.y + o + 5, highlight); + surfaceDrawLine(pos.x, pos.y + o + 5, pos.x + 5, pos.y + o + 10, shadow); + surfaceDrawLine(pos.x + 5, pos.y + o + 10, pos.x + 10, pos.y + o + 5, shadow); // Fill radio button. for (i=0; i<4; i++) { - guiDrawLine(pos.x + 5 - i, pos.y + o + i + 1, pos.x + 5 + i, pos.y + o + i + 1, fill); - guiDrawLine(pos.x + 5 - i, pos.y + o - i + 8, pos.x + 5 + i, pos.y + o - i + 8, fill); + surfaceDrawLine(pos.x + 5 - i, pos.y + o + i + 1, pos.x + 5 + i, pos.y + o + i + 1, fill); + surfaceDrawLine(pos.x + 5 - i, pos.y + o - i + 8, pos.x + 5 + i, pos.y + o - i + 8, fill); } // Draw title. diff --git a/client/src/gui/terminal.c b/client/src/gui/terminal.c index a73ee99..a55dbd3 100644 --- a/client/src/gui/terminal.c +++ b/client/src/gui/terminal.c @@ -168,22 +168,22 @@ WidgetT *terminalInit(WidgetT *widget, uint16_t cols, uint16_t rows) { } // Set up default palette. - t->palette[TERMINAL_COLOR_BLACK] = vbeMakeColor( 0, 0, 0); - t->palette[TERMINAL_COLOR_BLUE] = vbeMakeColor(170, 0, 0); - t->palette[TERMINAL_COLOR_GREEN] = vbeMakeColor( 0, 170, 0); - t->palette[TERMINAL_COLOR_CYAN] = vbeMakeColor(170, 85, 0); - t->palette[TERMINAL_COLOR_RED] = vbeMakeColor( 0, 0, 170); - t->palette[TERMINAL_COLOR_MAGENTA] = vbeMakeColor(170, 0, 170); - t->palette[TERMINAL_COLOR_BROWN] = vbeMakeColor( 0, 170, 170); - t->palette[TERMINAL_COLOR_LIGHT_GRAY] = vbeMakeColor(170, 170, 170); - t->palette[TERMINAL_COLOR_DARK_GRAY] = vbeMakeColor( 85, 85, 85); - t->palette[TERMINAL_COLOR_BRIGHT_BLUE] = vbeMakeColor(255, 85, 85); - t->palette[TERMINAL_COLOR_BRIGHT_GREEN] = vbeMakeColor( 85, 255, 85); - t->palette[TERMINAL_COLOR_BRIGHT_CYAN] = vbeMakeColor(255, 255, 85); - t->palette[TERMINAL_COLOR_BRIGHT_RED] = vbeMakeColor( 85, 85, 255); - t->palette[TERMINAL_COLOR_BRIGHT_MAGENTA] = vbeMakeColor(255, 85, 255); - t->palette[TERMINAL_COLOR_YELLOW] = vbeMakeColor( 85, 255, 255); - t->palette[TERMINAL_COLOR_WHITE] = vbeMakeColor(255, 255, 255); + t->palette[TERMINAL_COLOR_BLACK] = vbeColorMake( 0, 0, 0); + t->palette[TERMINAL_COLOR_BLUE] = vbeColorMake(170, 0, 0); + t->palette[TERMINAL_COLOR_GREEN] = vbeColorMake( 0, 170, 0); + t->palette[TERMINAL_COLOR_CYAN] = vbeColorMake(170, 85, 0); + t->palette[TERMINAL_COLOR_RED] = vbeColorMake( 0, 0, 170); + t->palette[TERMINAL_COLOR_MAGENTA] = vbeColorMake(170, 0, 170); + t->palette[TERMINAL_COLOR_BROWN] = vbeColorMake( 0, 170, 170); + t->palette[TERMINAL_COLOR_LIGHT_GRAY] = vbeColorMake(170, 170, 170); + t->palette[TERMINAL_COLOR_DARK_GRAY] = vbeColorMake( 85, 85, 85); + t->palette[TERMINAL_COLOR_BRIGHT_BLUE] = vbeColorMake(255, 85, 85); + t->palette[TERMINAL_COLOR_BRIGHT_GREEN] = vbeColorMake( 85, 255, 85); + t->palette[TERMINAL_COLOR_BRIGHT_CYAN] = vbeColorMake(255, 255, 85); + t->palette[TERMINAL_COLOR_BRIGHT_RED] = vbeColorMake( 85, 85, 255); + t->palette[TERMINAL_COLOR_BRIGHT_MAGENTA] = vbeColorMake(255, 85, 255); + t->palette[TERMINAL_COLOR_YELLOW] = vbeColorMake( 85, 255, 255); + t->palette[TERMINAL_COLOR_WHITE] = vbeColorMake(255, 255, 255); // Default attributes is gray on black, no bold, no blink, and dirty. for (y=0; ytitle, _guiColor[COLOR_TEXTBOX_TEXT], _guiColor[COLOR_WINDOW_BACKGROUND], pos.x, pos.y + 2 + _guiMetric[METRIC_TEXTBOX_VERTICAL_PADDING]); // Draw outline of textbox. - guiDrawHighlightFrame( pos.x + labelWidth, pos.y, pos.x + labelWidth + valueWidth + 2, pos.y + pos.h, _guiColor[COLOR_TEXTBOX_SHADOW], _guiColor[COLOR_TEXTBOX_HIGHLIGHT]); - guiDrawRectangle( pos.x + labelWidth + 1, pos.y + 1, pos.x + labelWidth + valueWidth + 1, pos.y + pos.h - 1, _guiColor[COLOR_WINDOW_BACKGROUND]); + surfaceDrawHighlightFrame( pos.x + labelWidth, pos.y, pos.x + labelWidth + valueWidth + 2, pos.y + pos.h, _guiColor[COLOR_TEXTBOX_SHADOW], _guiColor[COLOR_TEXTBOX_HIGHLIGHT]); + surfaceDrawRectangle( pos.x + labelWidth + 1, pos.y + 1, pos.x + labelWidth + valueWidth + 1, pos.y + pos.h - 1, _guiColor[COLOR_WINDOW_BACKGROUND]); // Draw background. - guiDrawRectangleFilled(pos.x + labelWidth + 2, pos.y + 2, pos.x + labelWidth + valueWidth, pos.y + pos.h - 2, _guiColor[COLOR_TEXTBOX_BACKGROUND]); + surfaceDrawRectangleFilled(pos.x + labelWidth + 2, pos.y + 2, pos.x + labelWidth + valueWidth, pos.y + pos.h - 2, _guiColor[COLOR_TEXTBOX_BACKGROUND]); // Where's the text display start? textX = pos.x + labelWidth + 2 + _guiMetric[METRIC_TEXTBOX_HORIZONTAL_PADDING]; diff --git a/client/src/gui/updown.c b/client/src/gui/updown.c index 1619f7e..e39ed09 100644 --- a/client/src/gui/updown.c +++ b/client/src/gui/updown.c @@ -254,39 +254,39 @@ static void updownPaint(WidgetT *widget, RectT pos) { fontRender(_guiFont, u->title, _guiColor[COLOR_UPDOWN_TEXT], _guiColor[COLOR_WINDOW_BACKGROUND], pos.x, pos.y + 2 + _guiMetric[METRIC_UPDOWN_VERTICAL_PADDING]); // Draw outline of text. - guiDrawHighlightFrame( pos.x + _labelWidth, pos.y, pos.x + _labelWidth + _valueWidth + 2, pos.y + pos.h, _guiColor[COLOR_UPDOWN_SHADOW], _guiColor[COLOR_UPDOWN_HIGHLIGHT]); - guiDrawRectangle( pos.x + _labelWidth + 1, pos.y + 1, pos.x + _labelWidth + _valueWidth + 1, pos.y + pos.h - 1, _guiColor[COLOR_WINDOW_BACKGROUND]); + surfaceDrawHighlightFrame( pos.x + _labelWidth, pos.y, pos.x + _labelWidth + _valueWidth + 2, pos.y + pos.h, _guiColor[COLOR_UPDOWN_SHADOW], _guiColor[COLOR_UPDOWN_HIGHLIGHT]); + surfaceDrawRectangle( pos.x + _labelWidth + 1, pos.y + 1, pos.x + _labelWidth + _valueWidth + 1, pos.y + pos.h - 1, _guiColor[COLOR_WINDOW_BACKGROUND]); // Draw text background. - guiDrawRectangleFilled(pos.x + _labelWidth + 2, pos.y + 2, pos.x + _labelWidth + _valueWidth, pos.y + pos.h - 2, _guiColor[COLOR_UPDOWN_BACKGROUND]); + surfaceDrawRectangleFilled(pos.x + _labelWidth + 2, pos.y + 2, pos.x + _labelWidth + _valueWidth, pos.y + pos.h - 2, _guiColor[COLOR_UPDOWN_BACKGROUND]); // Draw arrows outline - guiDrawHighlightFrame(_arrowStart, pos.y, _arrowStart + _arrowWidth + 1, pos.y + pos.h, _guiColor[COLOR_UPDOWN_SHADOW], _guiColor[COLOR_UPDOWN_HIGHLIGHT]); + surfaceDrawHighlightFrame(_arrowStart, pos.y, _arrowStart + _arrowWidth + 1, pos.y + pos.h, _guiColor[COLOR_UPDOWN_SHADOW], _guiColor[COLOR_UPDOWN_HIGHLIGHT]); // Draw arrows background - guiDrawRectangleFilled(_arrowStart + 1, pos.y + 1, _arrowStart + _arrowWidth, pos.y + pos.h - 1, _guiColor[COLOR_UPDOWN_ARROWS_BACKGROUND]); + surfaceDrawRectangleFilled(_arrowStart + 1, pos.y + 1, _arrowStart + _arrowWidth, pos.y + pos.h - 1, _guiColor[COLOR_UPDOWN_ARROWS_BACKGROUND]); // Draw up arrow _arrowStart += _halfFont + 1 + _guiMetric[METRIC_UPDOWN_HORIZONTAL_PADDING]; // Center of up arrow o = pos.y + 1 + _guiMetric[METRIC_UPDOWN_VERTICAL_PADDING]; // Top of up arrow color = u->value < u->maximum ? _guiColor[COLOR_UPDOWN_ARROWS_ACTIVE] : _guiColor[COLOR_UPDOWN_ARROWS_INACTIVE]; for (i=0; i<=fontHeightGet(_guiFont); i++) { - guiDrawLine(_arrowStart - i * 0.5, o + i, _arrowStart + i * 0.5, o + i, color); + surfaceDrawLine(_arrowStart - i * 0.5, o + i, _arrowStart + i * 0.5, o + i, color); } - guiDrawLine(_arrowStart, o, _arrowStart + _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_SHADOW]); - guiDrawLine(_arrowStart - _halfFont, o + fontHeightGet(_guiFont), _arrowStart + _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_SHADOW]); - guiDrawLine(_arrowStart, o, _arrowStart - _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]); + surfaceDrawLine(_arrowStart, o, _arrowStart + _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_SHADOW]); + surfaceDrawLine(_arrowStart - _halfFont, o + fontHeightGet(_guiFont), _arrowStart + _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_SHADOW]); + surfaceDrawLine(_arrowStart, o, _arrowStart - _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]); // Draw down arrow _arrowStart += fontHeightGet(_guiFont) + 1; // Center of down arrow o += fontHeightGet(_guiFont); // Bottom of down arrow color = u->value > u->minimum ? _guiColor[COLOR_UPDOWN_ARROWS_ACTIVE] : _guiColor[COLOR_UPDOWN_ARROWS_INACTIVE]; for (i=0; i<=fontHeightGet(_guiFont); i++) { - guiDrawLine(_arrowStart - i * 0.5, o - i, _arrowStart + i * 0.5, o - i, color); + surfaceDrawLine(_arrowStart - i * 0.5, o - i, _arrowStart + i * 0.5, o - i, color); } - guiDrawLine(_arrowStart, o, _arrowStart + _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_SHADOW]); - guiDrawLine(_arrowStart - _halfFont, o - fontHeightGet(_guiFont), _arrowStart + _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]); - guiDrawLine(_arrowStart, o, _arrowStart - _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]); + surfaceDrawLine(_arrowStart, o, _arrowStart + _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_SHADOW]); + surfaceDrawLine(_arrowStart - _halfFont, o - fontHeightGet(_guiFont), _arrowStart + _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]); + surfaceDrawLine(_arrowStart, o, _arrowStart - _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]); // Where's the text display start? textX = pos.x + _labelWidth + 2 + _guiMetric[METRIC_UPDOWN_HORIZONTAL_PADDING]; diff --git a/client/src/gui/window.c b/client/src/gui/window.c index 92c5c72..f0ebe27 100644 --- a/client/src/gui/window.c +++ b/client/src/gui/window.c @@ -50,7 +50,7 @@ static void windowDeactivateAll(WidgetT *widget) { static void windowDel(WidgetT **widget) { WindowT *w = (WindowT *)*widget; - vbeSurfaceDestroy(&w->base.surface); + surfaceDestroy(&w->base.surface); if (w->title) free(w->title); free(w); w = NULL; @@ -69,7 +69,7 @@ WidgetT *windowInit(WidgetT *window, char *title) { windowSetTitle(win, title); GUI_SET_FLAG(window, WIDGET_FLAG_OWNS_SURFACE); - win->base.surface = vbeSurfaceCreate(win->base.pos.w, win->base.pos.h); + win->base.surface = surfaceCreate(win->base.pos.w, win->base.pos.h); if (!win->base.surface) { free(win->title); free(win); @@ -155,17 +155,17 @@ static void windowPaint(WidgetT *widget, RectT pos) { text = GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE) ? _guiColor[COLOR_WINDOW_TITLE_TEXT_ACTIVE] : _guiColor[COLOR_WINDOW_TITLE_TEXT_INACTIVE]; // Background. - vbeSurfaceClear(_guiColor[COLOR_WINDOW_BACKGROUND]); + surfaceClear(_guiColor[COLOR_WINDOW_BACKGROUND]); // Outer edge. - guiDrawHighlightFrame(0, 0, x2, y2, _guiColor[COLOR_WINDOW_HIGHLIGHT], _guiColor[COLOR_WINDOW_SHADOW]); + surfaceDrawHighlightFrame(0, 0, x2, y2, _guiColor[COLOR_WINDOW_HIGHLIGHT], _guiColor[COLOR_WINDOW_SHADOW]); // Inner edge - skip METRIC_WINDOW_BORDER_WIDTH pixels. Be sure shadow and highlight are not included in the width. - guiDrawHighlightFrame(_guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 2, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 2, x2 - _guiMetric[METRIC_WINDOW_BORDER_WIDTH] - 2, y2 - _guiMetric[METRIC_WINDOW_BORDER_WIDTH] - 2, _guiColor[COLOR_WINDOW_SHADOW], _guiColor[COLOR_WINDOW_HIGHLIGHT]); + surfaceDrawHighlightFrame(_guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 2, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 2, x2 - _guiMetric[METRIC_WINDOW_BORDER_WIDTH] - 2, y2 - _guiMetric[METRIC_WINDOW_BORDER_WIDTH] - 2, _guiColor[COLOR_WINDOW_SHADOW], _guiColor[COLOR_WINDOW_HIGHLIGHT]); // Title bar - METRIC_WINDOW_TITLE_HEIGHT pixels high. Be sure shadow and highlight are not included in the width. - guiDrawHighlightFrame(_guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 3, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 3, x2 - _guiMetric[METRIC_WINDOW_BORDER_WIDTH] - 3, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + _guiMetric[METRIC_WINDOW_TITLE_HEIGHT] + 4, _guiColor[COLOR_WINDOW_HIGHLIGHT], _guiColor[COLOR_WINDOW_SHADOW]); - guiDrawRectangleFilled(_guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 4, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 4, x2 - _guiMetric[METRIC_WINDOW_BORDER_WIDTH] - 4, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + _guiMetric[METRIC_WINDOW_TITLE_HEIGHT] + 2, background); + surfaceDrawHighlightFrame(_guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 3, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 3, x2 - _guiMetric[METRIC_WINDOW_BORDER_WIDTH] - 3, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + _guiMetric[METRIC_WINDOW_TITLE_HEIGHT] + 4, _guiColor[COLOR_WINDOW_HIGHLIGHT], _guiColor[COLOR_WINDOW_SHADOW]); + surfaceDrawRectangleFilled(_guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 4, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 4, x2 - _guiMetric[METRIC_WINDOW_BORDER_WIDTH] - 4, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + _guiMetric[METRIC_WINDOW_TITLE_HEIGHT] + 2, background); fontRender(_guiFont, w->title, text, background, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 16, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 5); diff --git a/client/src/linux/linux.c b/client/src/linux/linux.c index 4ce95f3..e288ad5 100644 --- a/client/src/linux/linux.c +++ b/client/src/linux/linux.c @@ -24,6 +24,7 @@ #include "mouse.h" #include "vesa.h" +#include "surface.h" #define SECONDS_IN_DAY 86400 @@ -36,8 +37,6 @@ static MouseT _mouse; static SDL_Window *_window = NULL; static SDL_Renderer *_renderer = NULL; static SDL_Surface *_surface = NULL; -static SurfaceT *_offScreenBuffer = NULL; -static SurfaceT *_activeSurface = NULL; static uint16_t _width = 0; static uint16_t _height = 0; static uint8_t _windowScale = 1; @@ -55,11 +54,7 @@ static long _timerTicks = 0; static SDL_TimerID _timerID; -void (*vbePutPixel)(uint16_t x, uint16_t y, ColorT color); - - static void processEvent(void); -static void vbePutPixel32(uint16_t x, uint16_t y, ColorT color); long biostime(int cmd, long newtime) { @@ -237,11 +232,16 @@ uint32_t timerCallback(uint32_t interval, void *param) { } -uint8_t vbeDisplayDepthGet(void) { +uint8_t vbeDisplayDepthBitsGet(void) { return 32; } +uint8_t vbeDisplayDepthBytesGet(void) { + return 4; +} + + uint16_t vbeDisplayHeightGet(void) { return _height; } @@ -252,43 +252,51 @@ uint16_t vbeDisplayWidthGet(void) { } -ColorT vbeMakeColor(uint8_t red, uint8_t green, uint8_t blue) { +ColorT vbeColorMake(uint8_t red, uint8_t green, uint8_t blue) { return - (red << 24) | + (red << 24) | (green << 16) | - (blue << 8); + (blue << 8); } void vbePresent(void) { + uint16_t x; + uint16_t y; + SurfaceT *s = surfaceOffscreenGet(); + uint32_t p; + uint8_t r; + uint8_t g; + uint8_t b; + SDL_SetRenderTarget(_renderer, NULL); - vbeSurfaceBlit(_offScreenBuffer, 0, 0); + + //***TODO*** This is stupid inefficient. + for (y=0; yheight; y++) { + for (x=0; xwidth; x++) { + p = s->buffer.bits32[y * s->width + x]; + r = (p & 0xFF000000) >> 24; + g = (p & 0x00FF0000) >> 16; + b = (p & 0x0000FF00) >> 8; + SDL_SetRenderDrawColor(_renderer, r, g, b, 255); + SDL_RenderDrawPoint(_renderer, x, y); + } + } + SDL_RenderPresent(_renderer); // Throttle this to some sane frame rate. - SDL_Delay(32); + //SDL_Delay(32); } -static void vbePutPixel32(uint16_t x, uint16_t y, ColorT color) { - uint8_t red = (color & 0xff000000) >> 24; - uint8_t green = (color & 0x00ff0000) >> 16; - uint8_t blue = (color & 0x0000ff00) >> 8; - - SDL_SetRenderDrawColor(_renderer, red, green, blue, 0xff); - SDL_RenderDrawPoint(_renderer, x, y); -} - - -int16_t vbeShowInfo(void) { +int16_t vbeInfoShow(void) { // Eh, don't care. return 0; } int16_t vbeShutdown(void) { - vbeSurfaceDestroy(&_offScreenBuffer); - if (_renderer) { SDL_DestroyRenderer(_renderer); _renderer = NULL; @@ -313,7 +321,6 @@ uint8_t vbeStartup(uint16_t xRes, uint16_t yRes, uint8_t bpp) { (void)bpp; _windowScale = 3; - vbePutPixel = vbePutPixel32; SDL_Init(SDL_INIT_EVERYTHING); @@ -324,8 +331,6 @@ uint8_t vbeStartup(uint16_t xRes, uint16_t yRes, uint8_t bpp) { SDL_RenderSetLogicalSize(_renderer, xRes, yRes); SDL_SetWindowSize(_window, xRes * _windowScale, yRes * _windowScale); - _offScreenBuffer = vbeSurfaceCreate(xRes, yRes); - _width = xRes; _height = yRes; @@ -336,83 +341,7 @@ uint8_t vbeStartup(uint16_t xRes, uint16_t yRes, uint8_t bpp) { } -void vbeSurfaceBlit(SurfaceT *source, uint16_t x, uint16_t y) { - SDL_Rect r; - - r.x = x; - r.y = y; - r.w = source->width; - r.h = source->height; - - SDL_RenderCopy(_renderer, (SDL_Texture *)source->buffer.bits8, NULL, &r); -} - - -void vbeSurfaceClear(ColorT color) { - uint8_t red = (color & 0xff000000) >> 24; - uint8_t green = (color & 0x00ff0000) >> 16; - uint8_t blue = (color & 0x0000ff00) >> 8; - - SDL_SetRenderDrawColor(_renderer, red, green, blue, 0xff); - SDL_RenderClear(_renderer); -} - - -SurfaceT *vbeSurfaceCreate(uint16_t width, uint16_t height) { - SDL_Texture *texture = SDL_CreateTexture(_renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height); - SDL_Texture *target = SDL_GetRenderTarget(_renderer); - SurfaceT *surface = (SurfaceT *)malloc(sizeof(SurfaceT)); - - surface->width = width; - surface->height = height; - surface->scanline = width * 4; // Always 32 bit. - surface->bytes = surface->scanline * height; - surface->buffer.bits8 = (uint8_t *)texture; - - SDL_SetRenderTarget(_renderer, texture); - SDL_SetRenderDrawColor(_renderer, 0, 0, 0, 0xff); - SDL_RenderClear(_renderer); - - SDL_SetRenderTarget(_renderer, target); - - return surface; -} - - -void vbeSurfaceDestroy(SurfaceT **surface) { - SurfaceT *s = *surface; - - SDL_DestroyTexture((SDL_Texture *)s->buffer.bits8); - free(s); - s = NULL; -} - - -uint16_t vbeSurfaceHeightGet(void) { - return _activeSurface->height; -} - - -uint16_t vbeSurfaceWidthGet(void) { - return _activeSurface->width; -} - - -void vbeSurfaceSet(SurfaceT *surface) { - SDL_Texture *texture = NULL; - - if (surface) { - _activeSurface = surface; - } else { - _activeSurface = _offScreenBuffer; - } - - texture = (SDL_Texture *)_activeSurface->buffer.bits8; - SDL_SetRenderTarget(_renderer, texture); -} - - -void vbeWaitVBlank(void) { +void vbeVBlankWait(void) { // Eh, don't care. } diff --git a/client/src/main.c b/client/src/main.c index db229f0..02e1068 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -27,18 +27,19 @@ * - Methods that can change the width of a widget (such as setTitle) need to repaint the parent window as well * - Metrics, colors, etc. should be defined in each widget and not in GUI * - Widgets should support a "changed" callback that can cancel the change - * - Move drawing and surface code into it's own file * - Use LabelT in all widgets that have a label * - Find a light grey to replace white widget data areas * - No thumb in listbox scrollbar + * - Window dragging is being screwball * - * - Random crash after adding listbox - looks memwatch / task related + * - Random crash on exit - looks memwatch / task related */ #include "stddclmr.h" #include "os.h" #include "vesa.h" +#include "surface.h" #include "mouse.h" #include "keyboard.h" #include "task.h" @@ -79,11 +80,11 @@ void drawWidgetDebug(WidgetT *widget, uint8_t debugToggle) { if (debugToggle) { // Clipping region (blue) guiWidgetBoundsDrawableOnScreenGet(widget, &r); - guiDrawRectangle(r.x, r.y, r.x + r.w, r.y + r.h, vbeMakeColor(0, 0, 255)); + surfaceDrawRectangle(r.x, r.y, r.x + r.w, r.y + r.h, vbeColorMake(0, 0, 255)); } else { // Widget border (red) guiWidgetPositionOnScreenGet(widget, &r); - guiDrawRectangle(r.x, r.y, r.x + widget->pos.w, r.y + widget->pos.h, vbeMakeColor(255, 0, 0)); + surfaceDrawRectangle(r.x, r.y, r.x + widget->pos.w, r.y + widget->pos.h, vbeColorMake(255, 0, 0)); } if (len > 0) { @@ -129,7 +130,7 @@ void mainLoop(void *data) { if (debugState > 0) drawWidgetDebug(guiRootGet(), debugState - 1); //if (timerHalfSecondOn) guiDrawRectangle(0, 0, vbeSurfaceWidthGet() - 1, vbeSurfaceHeightGet() - 1, vbeMakeColor(255, 255, 255)); - vbeWaitVBlank(); + vbeVBlankWait(); vbePresent(); taskYield(); } while (key != 27); // Exit on ESC. @@ -288,7 +289,7 @@ int main(int argc, char *argv[]) { // Command line needs to have the desired resolution and color depth on it. if (argc != 4) { - vbeShowInfo(); + vbeInfoShow(); fflush(stdout); memoryShutdown(); return 0; @@ -304,6 +305,7 @@ int main(int argc, char *argv[]) { return 1; } + surfaceStartup(); mouseStartup(); timerStartup(); guiStartup(); @@ -317,6 +319,7 @@ int main(int argc, char *argv[]) { guiShutdown(); timerShutdown(); mouseShutdown(); + surfaceShutdown(); vbeShutdown(); logClose(); diff --git a/client/src/system/color.h b/client/src/system/color.h new file mode 100644 index 0000000..4db4955 --- /dev/null +++ b/client/src/system/color.h @@ -0,0 +1,31 @@ +/* + * Kangaroo Punch MultiPlayer Game Server Mark II + * Copyright (C) 2020-2021 Scott Duensing + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#ifndef COLOR_H +#define COLOR_H + + +#include "os.h" + + +typedef uint32_t ColorT; + + +#endif // COLOR_H diff --git a/client/src/system/surface.c b/client/src/system/surface.c new file mode 100644 index 0000000..f4becfc --- /dev/null +++ b/client/src/system/surface.c @@ -0,0 +1,243 @@ +/* + * Kangaroo Punch MultiPlayer Game Server Mark II + * Copyright (C) 2020-2021 Scott Duensing + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#include "surface.h" +#include "vesa.h" + + +static SurfaceT *_offScreenSurface; +static SurfaceT *_activeSurface; + + +static void surfacePutPixel8(uint16_t x, uint16_t y, ColorT color); +static void surfacePutPixel16(uint16_t x, uint16_t y, ColorT color); +static void surfacePutPixel32(uint16_t x, uint16_t y, ColorT color); + + +void (*surfacePutPixel)(uint16_t x, uint16_t y, ColorT color); + + + +static void surfacePutPixel8(uint16_t x, uint16_t y, ColorT color) { + _activeSurface->buffer.bits8[y * _activeSurface->width + x] = (uint8_t)color; +} + + +static void surfacePutPixel16(uint16_t x, uint16_t y, ColorT color) { + _activeSurface->buffer.bits16[y * _activeSurface->width + x] = (uint16_t)color; +} + + +static void surfacePutPixel32(uint16_t x, uint16_t y, ColorT color) { + _activeSurface->buffer.bits32[y * _activeSurface->width + x] = color; +} + + +void surfaceBlit(SurfaceT *source, uint16_t x, uint16_t y) { + uint16_t y1; + size_t offsetTarget; + size_t offsetSource; + + if (x == 0 && y == 0 && _activeSurface->width == source->width && _activeSurface->height == source->height) { + // Direct blit of entire surface. + memcpy(_activeSurface->buffer.bits8, source->buffer.bits8, source->bytes); + } else { + // Blit into larger surface. + offsetTarget = y * _activeSurface->scanline + x * vbeDisplayDepthBytesGet(); + offsetSource = 0; + for (y1=y; y1height; y1++) { + memcpy(&_activeSurface->buffer.bits8[offsetTarget], &source->buffer.bits8[offsetSource], source->scanline); + offsetTarget += _activeSurface->scanline; + offsetSource += source->scanline; + } + } +} + + +void surfaceClear(ColorT color) { + uint16_t x; + uint16_t y; + + for (y=0; y<_activeSurface->height; y++) { + for (x=0; x<_activeSurface->width; x++) { + surfacePutPixel(x, y, color); + } + } +} + + +SurfaceT *surfaceCreate(uint16_t width, uint16_t height) { + SurfaceT *surface = (SurfaceT *)malloc(sizeof(SurfaceT)); + + if (!surface) return NULL; + + surface->width = width; + surface->height = height; + surface->scanline = width * vbeDisplayDepthBytesGet(); + 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 surfaceDestroy(SurfaceT **surface) { + SurfaceT *s = *surface; + + free(s->buffer.bits8); + free(s); + s = NULL; +} + + +void surfaceDrawHighlightFrame(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ColorT upperLeft, ColorT lowerRight) { + surfaceDrawLine(x1, y1, x2, y1, upperLeft); + surfaceDrawLine(x1, y1, x1, y2, upperLeft); + surfaceDrawLine(x1, y2, x2, y2, lowerRight); + surfaceDrawLine(x2, y1, x2, y2, lowerRight); +} + + +void surfaceDrawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color) { + int16_t x; + int16_t y; + int16_t dx; + int16_t dy; + int16_t incX; + int16_t incY; + int16_t balance; + + if (x2 >= x1) { + dx = x2 - x1; + incX = 1; + } else { + dx = x1 - x2; + incX = -1; + } + + if (y2 >= y1) { + dy = y2 - y1; + incY = 1; + } else { + dy = y1 - y2; + incY = -1; + } + + x = x1; + y = y1; + + if (dx >= dy) { + dy <<= 1; + balance = dy - dx; + dx <<= 1; + while (x != x2) { + surfacePutPixel(x, y, color); + if (balance >= 0) { + y += incY; + balance -= dx; + } + balance += dy; + x += incX; + } + surfacePutPixel(x, y, color); + } else { + dx <<= 1; + balance = dx - dy; + dy <<= 1; + while (y != y2) { + surfacePutPixel(x, y, color); + if (balance >= 0) { + x += incX; + balance -= dy; + } + balance += dx; + y += incY; + } + surfacePutPixel(x, y, color); + } +} + + +void surfaceDrawRectangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color) { + surfaceDrawLine(x1, y1, x2, y1, color); + surfaceDrawLine(x2, y1, x2, y2, color); + surfaceDrawLine(x1, y2, x2, y2, color); + surfaceDrawLine(x1, y1, x1, y2, color); +} + + +void surfaceDrawRectangleFilled(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color) { + uint16_t x; + uint16_t y; + + for (y=y1; y<=y2; y++) { + for (x=x1; x<=x2; x++) { + surfacePutPixel(x, y, color); + } + } +} + + +uint16_t surfaceHeightGet(void) { + return _activeSurface->height; +} + + +uint16_t surfaceWidthGet(void) { + return _activeSurface->width; +} + + +SurfaceT *surfaceOffscreenGet(void) { + return _offScreenSurface; +} + + +void surfaceSet(SurfaceT *surface) { + if (surface) { + _activeSurface = surface; + } else { + _activeSurface = _offScreenSurface; + } +} + + +void surfaceShutdown(void) { + surfaceDestroy(&_offScreenSurface); +} + + +uint8_t surfaceStartup(void) { + _offScreenSurface = surfaceCreate(vbeDisplayWidthGet(), vbeDisplayHeightGet()); + + if (vbeDisplayDepthBitsGet() == 8) surfacePutPixel = surfacePutPixel8; + if (vbeDisplayDepthBitsGet() == 16) surfacePutPixel = surfacePutPixel16; + if (vbeDisplayDepthBitsGet() == 15) surfacePutPixel = surfacePutPixel16; + if (vbeDisplayDepthBitsGet() == 32) surfacePutPixel = surfacePutPixel32; + + return (_offScreenSurface == NULL ? 1 : 0); +} diff --git a/client/src/system/surface.h b/client/src/system/surface.h new file mode 100644 index 0000000..61b1328 --- /dev/null +++ b/client/src/system/surface.h @@ -0,0 +1,61 @@ +/* + * Kangaroo Punch MultiPlayer Game Server Mark II + * Copyright (C) 2020-2021 Scott Duensing + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#ifndef SURFACE_H +#define SURFACE_H + + +#include "os.h" +#include "color.h" + + +typedef struct SurfaceS { + uint16_t width; + uint16_t height; + size_t scanline; + size_t bytes; + union { + uint8_t *bits8; + uint16_t *bits16; + uint32_t *bits32; + } buffer; +} SurfaceT; + + +extern void (*surfacePutPixel)(uint16_t x, uint16_t y, ColorT color); + + +void surfaceBlit(SurfaceT *source, uint16_t x, uint16_t y); +void surfaceClear(ColorT color); +SurfaceT *surfaceCreate(uint16_t width, uint16_t height); +void surfaceDestroy(SurfaceT **surface); +void surfaceDrawHighlightFrame(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ColorT upperLeft, ColorT lowerRight); +void surfaceDrawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color); +void surfaceDrawRectangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color); +void surfaceDrawRectangleFilled(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color); +uint16_t surfaceHeightGet(void); +uint16_t surfaceWidthGet(void); +SurfaceT *surfaceOffscreenGet(void); +void surfaceSet(SurfaceT *surface); +void surfaceShutdown(void); +uint8_t surfaceStartup(void); + + +#endif // SURFACE_H diff --git a/client/src/system/task.h b/client/src/system/task.h index 543fab2..2b9c776 100644 --- a/client/src/system/task.h +++ b/client/src/system/task.h @@ -22,7 +22,7 @@ #define TASK_H -#include +#include "os.h" uint8_t taskCreate(void (*function)(void *), void *data); diff --git a/client/src/system/vesa.h b/client/src/system/vesa.h index 50481f2..3e6191d 100644 --- a/client/src/system/vesa.h +++ b/client/src/system/vesa.h @@ -23,42 +23,19 @@ #include "os.h" +#include "color.h" -typedef uint32_t ColorT; - - -typedef struct SurfaceS { - uint16_t width; - uint16_t height; - size_t scanline; - size_t bytes; - union { - uint8_t *bits8; - uint16_t *bits16; - uint32_t *bits32; - } buffer; -} SurfaceT; - - -uint8_t vbeStartup(uint16_t xRes, uint16_t yRes, uint8_t bpp); -uint8_t vbeDisplayDepthGet(void); +uint8_t vbeDisplayDepthBitsGet(void); +uint8_t vbeDisplayDepthBytesGet(void); uint16_t vbeDisplayHeightGet(void); uint16_t vbeDisplayWidthGet(void); -ColorT vbeMakeColor(uint8_t red, uint8_t green, uint8_t blue); +ColorT vbeColorMake(uint8_t red, uint8_t green, uint8_t blue); void vbePresent(void); -int16_t vbeShowInfo(void); +int16_t vbeInfoShow(void); int16_t vbeShutdown(void); -void vbeSurfaceBlit(SurfaceT *source, uint16_t x, uint16_t y); -void vbeSurfaceClear(ColorT color); -SurfaceT *vbeSurfaceCreate(uint16_t width, uint16_t height); -void vbeSurfaceDestroy(SurfaceT **surface); -uint16_t vbeSurfaceHeightGet(void); -uint16_t vbeSurfaceWidthGet(void); -void vbeSurfaceSet(SurfaceT *surface); -void vbeWaitVBlank(void); - -extern void (*vbePutPixel)(uint16_t x, uint16_t y, ColorT color); +uint8_t vbeStartup(uint16_t xRes, uint16_t yRes, uint8_t bpp); +void vbeVBlankWait(void); #endif // VESA20_H