From 451c95a0caf90bbccb1c87e81d0a76854fe7e979 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Fri, 24 Jun 2022 18:41:27 -0500 Subject: [PATCH] Window Manager finished? Moving on! --- client/src/gui/gui.c | 34 ++++---- client/src/gui/image.c | 42 ++++++---- client/src/gui/surface.c | 168 ++++++++++++++++++++++++++++++++++----- client/src/gui/surface.h | 6 +- shared/memory.c | 2 +- shared/util.c | 61 +++++++------- shared/util.h | 2 +- 7 files changed, 229 insertions(+), 86 deletions(-) diff --git a/client/src/gui/gui.c b/client/src/gui/gui.c index 480aec3..bd52dbe 100644 --- a/client/src/gui/gui.c +++ b/client/src/gui/gui.c @@ -75,10 +75,8 @@ void guiRegister(WidgetRegisterT widgetRegister) { void guiRun(void) { while (_guiRunning) { - // Process all GUI events. guiEventsDo(); - } } @@ -111,22 +109,22 @@ void guiShutdown(void) { uint8_t guiStartup(int16_t width, int16_t height, int16_t depth) { uint8_t i; uint8_t EGA[16][3] = { - { 0, 0, 0 }, /* black */ - { 0, 0, 170 }, /* blue */ - { 0, 170, 0 }, /* green */ - { 0, 170, 170 }, /* cyan */ - { 170, 0, 0 }, /* red */ - { 170, 0, 170 }, /* magenta */ - { 170, 85, 0 }, /* brown */ - { 170, 170, 170 }, /* light gray */ - { 85, 85, 85 }, /* dark gray */ - { 85, 85, 255 }, /* light blue */ - { 85, 255, 85 }, /* light green */ - { 85, 255, 255 }, /* light cyan */ - { 255, 85, 85 }, /* light red */ - { 255, 85, 255 }, /* light magenta */ - { 255, 255, 85 }, /* yellow */ - { 255, 255, 255 } /* white */ + { 0, 0, 0 }, // black + { 0, 0, 170 }, // blue + { 0, 170, 0 }, // green + { 0, 170, 170 }, // cyan + { 170, 0, 0 }, // red + { 170, 0, 170 }, // magenta + { 170, 85, 0 }, // brown + { 170, 170, 170 }, // light gray + { 85, 85, 85 }, // dark gray + { 85, 85, 255 }, // light blue + { 85, 255, 85 }, // light green + { 85, 255, 255 }, // light cyan + { 255, 85, 85 }, // light red + { 255, 85, 255 }, // light magenta + { 255, 255, 85 }, // yellow + { 255, 255, 255 } // white }; if (platformStartup(width, height, depth) == FAIL) return FAIL; diff --git a/client/src/gui/image.c b/client/src/gui/image.c index 3dc7d77..dc193c7 100644 --- a/client/src/gui/image.c +++ b/client/src/gui/image.c @@ -15,27 +15,37 @@ SurfaceT *imageLoad(char *filename) { int32_t r; int32_t x; int32_t y; - SurfaceT *i = NULL; - SurfaceT *t = surfaceGet(); - unsigned char *raw = NULL; + SurfaceT *i = NULL; + SurfaceT *t = surfaceGet(); + unsigned char *raw = NULL; + char *cached = NULL; - r = stbi_info(filename, &w, &h, &n); - if (r) { - raw = stbi_load(filename, &w, &h, &n, PIXEL_COMPONENTS); - if (raw) { - i = surfaceCreate(w, h); - surfaceSet(i); - n = 0; - for (y=0; ywidth; x++) { - surfacePixelSet(x, 0, color); - } + surfaceLineH(0, __surfaceActive->width - 1, 0, color); // Copy it to the other lines. offsetTarget = __surfaceActive->scanline; @@ -120,8 +128,9 @@ ColorT surfaceColorMake(uint8_t r, uint8_t g, uint8_t b) { SurfaceT *surfaceCreate(int16_t width, int16_t height) { - SurfaceT *surface = (SurfaceT *)malloc(sizeof(SurfaceT)); + SurfaceT *surface = NULL; + NEW(SurfaceT, surface); if (!surface) return NULL; surface->width = width; @@ -168,9 +177,7 @@ void surfaceBoxFilled(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT c) width = (x2 - x1 + 1) * __surfaceBytesPerPixel; // Draw the top line. - for (i=x1; i<=x2; i++) { - surfacePixelSet(i, y1, c); - } + surfaceLineH(x1, x2, y1, c); // Copy it to the other lines. offsetTarget = __surfaceActive->scanline * (y1 + 1) + (x1 * __surfaceBytesPerPixel); @@ -268,38 +275,135 @@ void surfaceLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color) { } -void surfaceLineH(int16_t x1, int16_t x2, int16_t y, ColorT c) { +static void surfaceLineH8(int16_t x1, int16_t x2, int16_t y, ColorT c) { int16_t i; - int16_t t; + size_t offset; if (x1 > x2) { - t = x2; + i = x2; x2 = x1; - x1 = t; + x1 = i; } - for (i=x1; i<=x2; i++) { - surfacePixelSet(i, y, c); + offset = y * __surfaceActive->width + x1; + for (i=x1; i<=x2; i++) __surfaceActive->buffer.bits8[offset++] = (uint8_t)c; +} + + +static void surfaceLineH16(int16_t x1, int16_t x2, int16_t y, ColorT c) { + int16_t i; + size_t offset; + + if (x1 > x2) { + i = x2; + x2 = x1; + x1 = i; + } + + offset = y * __surfaceActive->width + x1; + for (i=x1; i<=x2; i++) __surfaceActive->buffer.bits16[offset++] = (uint16_t)c; +} + + +static void surfaceLineH32(int16_t x1, int16_t x2, int16_t y, ColorT c) { + int16_t i; + size_t offset; + + if (x1 > x2) { + i = x2; + x2 = x1; + x1 = i; + } + + offset = y * __surfaceActive->width + x1; + for (i=x1; i<=x2; i++) __surfaceActive->buffer.bits32[offset++] = (uint32_t)c; +} + + +static void surfaceLineV8(int16_t x, int16_t y1, int16_t y2, ColorT c) { + int16_t i; + size_t offset; + + if (y1 > y2) { + i = y2; + y2 = y1; + y1 = i; + } + + offset = y1 * __surfaceActive->width + x; + for (i=y1; i<=y2; i++) { + __surfaceActive->buffer.bits8[offset] = (uint8_t)c; + offset += __surfaceActive->width; } } -void surfaceLineV(int16_t x, int16_t y1, int16_t y2, ColorT c) { +static void surfaceLineV16(int16_t x, int16_t y1, int16_t y2, ColorT c) { int16_t i; - int16_t t; + size_t offset; if (y1 > y2) { - t = y2; + i = y2; y2 = y1; - y1 = t; + y1 = i; } + offset = y1 * __surfaceActive->width + x; for (i=y1; i<=y2; i++) { - surfacePixelSet(x, i, c); + __surfaceActive->buffer.bits16[offset] = (uint16_t)c; + offset += __surfaceActive->width; } } +static void surfaceLineV32(int16_t x, int16_t y1, int16_t y2, ColorT c) { + int16_t i; + size_t offset; + + if (y1 > y2) { + i = y2; + y2 = y1; + y1 = i; + } + + offset = y1 * __surfaceActive->width + x; + for (i=y1; i<=y2; i++) { + __surfaceActive->buffer.bits32[offset] = (uint32_t)c; + offset += __surfaceActive->width; + } +} + + +SurfaceT *surfaceLoad(char *filename) { + char ext[5] = { 0 }; + char *name = NULL; + FILE *in = NULL; + SurfaceT *i = NULL; + + sprintf(ext, "S%d", __surfaceBitsPerPixel); + name = utilFileExtensionChange(filename, ext); + + if (!utilFileExists(name)) { + in = fopen(name, "rb"); + if (in) { + NEW(SurfaceT, i); + if (!i) return NULL; + fread(&i->width, sizeof(uint16_t), 1, in); + fread(&i->height, sizeof(uint16_t), 1, in); + fread(&i->scanline, sizeof(size_t), 1, in); + fread(&i->bytes, sizeof(size_t), 1, in); + i->buffer.bits8 = (uint8_t *)malloc(i->bytes); + fread(i->buffer.bits8, i->bytes, 1, in); + fclose(in); + } + } + + DEL(name); + + return i; +} + + static ColorT surfacePixelGet8(SurfaceT *surface, int16_t x, int16_t y) { return surface->buffer.bits8[y * surface->width + x]; } @@ -330,6 +434,28 @@ static void surfacePixelSet32(uint16_t x, uint16_t y, ColorT color) { } +void surfaceSave(SurfaceT *surface, char *filename) { + char ext[5] = { 0 }; + char *name = NULL; + FILE *out = NULL; + + sprintf(ext, "S%d", __surfaceBitsPerPixel); + name = utilFileExtensionChange(filename, ext); + + out = fopen(name, "wb"); + if (out) { + fwrite(&surface->width, sizeof(uint16_t), 1, out); + fwrite(&surface->height, sizeof(uint16_t), 1, out); + fwrite(&surface->scanline, sizeof(size_t), 1, out); + fwrite(&surface->bytes, sizeof(size_t), 1, out); + fwrite(surface->buffer.bits8, surface->bytes, 1, out); + fclose(out); + } + + DEL(name); +} + + void surfaceSet(SurfaceT *surface) { __surfaceActive = surface; } @@ -356,6 +482,8 @@ void surfaceStartup(uint8_t bits) { redMaskSize = 3; greenMaskSize = 3; blueMaskSize = 2; + surfaceLineH = surfaceLineH8; + surfaceLineV = surfaceLineV8; surfacePixelSet = surfacePixelSet8; surfacePixelGet = surfacePixelGet8; break; @@ -366,6 +494,8 @@ void surfaceStartup(uint8_t bits) { redMaskSize = 5; greenMaskSize = 6; blueMaskSize = 5; + surfaceLineH = surfaceLineH16; + surfaceLineV = surfaceLineV16; surfacePixelSet = surfacePixelSet16; surfacePixelGet = surfacePixelGet16; break; @@ -376,6 +506,8 @@ void surfaceStartup(uint8_t bits) { redMaskSize = 8; greenMaskSize = 8; blueMaskSize = 8; + surfaceLineH = surfaceLineH32; + surfaceLineV = surfaceLineV32; surfacePixelSet = surfacePixelSet32; surfacePixelGet = surfacePixelGet32; break; diff --git a/client/src/gui/surface.h b/client/src/gui/surface.h index 83a4b08..c39e3d5 100644 --- a/client/src/gui/surface.h +++ b/client/src/gui/surface.h @@ -41,6 +41,8 @@ extern uint8_t __surfaceBytesPerPixel; extern SurfaceFormatT __surfaceFormat; +extern void (*surfaceLineH)(int16_t x1, int16_t x2, int16_t y, ColorT c); +extern void (*surfaceLineV)(int16_t x, int16_t y1, int16_t y2, ColorT c); extern ColorT (*surfacePixelGet)(SurfaceT *surface, int16_t x, int16_t y); extern void (*surfacePixelSet)(uint16_t x, uint16_t y, ColorT color); @@ -57,8 +59,8 @@ void surfaceDestroy(SurfaceT **surface); SurfaceT *surfaceGet(void); int16_t surfaceHeightGet(SurfaceT *surface); void surfaceLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color); -void surfaceLineH(int16_t x1, int16_t x2, int16_t y, ColorT c); -void surfaceLineV(int16_t x, int16_t y1, int16_t y2, ColorT c); +SurfaceT *surfaceLoad(char *filename); +void surfaceSave(SurfaceT *surface, char *filename); void surfaceSet(SurfaceT *surface); void surfaceShutdown(void); void surfaceStartup(uint8_t bits); diff --git a/shared/memory.c b/shared/memory.c index 3ff5755..ad6dbba 100644 --- a/shared/memory.c +++ b/shared/memory.c @@ -37,7 +37,7 @@ void memoryShutdown(void) { void memoryStartup(char *appName) { - char *logName = utilAppNameWithNewExtensionGet(appName, "log"); + char *logName = utilFileExtensionChange(appName, "log"); _memoryLog = fopen(logName, "w"); diff --git a/shared/util.c b/shared/util.c index 7c5b615..2da51b6 100644 --- a/shared/util.c +++ b/shared/util.c @@ -6,36 +6,6 @@ char __scratch[SCRATCH_SIZE]; -char *utilAppNameWithNewExtensionGet(char *appName, char *extension) { - char *c = NULL; - char *newName = NULL; - int16_t x = strlen(appName); - uint16_t len = 2 + strlen(extension); // 2 = dot in extension and 0 terminator. - - // Find last portion of filename. - while (x > 0) { - if (appName[x] == '/' || appName[x] == '\\') break; - x--; - len++; - } - - // We use this + length of new extension for new string length. - newName = (char *)malloc(len); - if (newName) { - if (strlen(appName) - x < len) { - // Replace extension - strncpy(newName, &appName[x + 1], len - 1); - c = strstr(newName, "."); - if (c) *c = 0; - strncat(newName, ".", len - 1); - strncat(newName, extension, len - 1); - } - } - - return newName; -} - - void utilBitsPrint(uint8_t byte) { int i = 0; @@ -100,6 +70,37 @@ uint8_t utilFileExists(char *filename) { } +char *utilFileExtensionChange(char *appName, char *extension) { + char *c = NULL; + char *newName = NULL; + int16_t x = strlen(appName); + uint16_t len = 2 + strlen(extension); // 2 = dot in extension and 0 terminator. + + // Find last portion of filename. + while (x > 0) { + if (appName[x] == '/' || appName[x] == '\\') { x++; break; } + x--; + len++; + } + x--; + + // We use this + length of new extension for new string length. + newName = (char *)malloc(len); + if (newName) { + if (strlen(appName) - x < len) { + // Replace extension + strncpy(newName, &appName[x + 1], len - 1); + c = strstr(newName, "."); + if (c) *c = 0; + strncat(newName, ".", len - 1); + strncat(newName, extension, len - 1); + } + } + + return newName; +} + + uint8_t utilFromFileReadByte(FILE *f, uint8_t *result) { unsigned char c; diff --git a/shared/util.h b/shared/util.h index 93da7dd..b2e5de8 100644 --- a/shared/util.h +++ b/shared/util.h @@ -11,7 +11,7 @@ extern char __scratch[SCRATCH_SIZE]; -char *utilAppNameWithNewExtensionGet(char *appName, char *extension); +char *utilFileExtensionChange(char *appName, char *extension); void utilBitsPrint(uint8_t byte); char *utilCreateString(char *format, ...); char *utilCreateStringVArgs(char *format, va_list args);