diff --git a/FONTS b/FONTS new file mode 100644 index 0000000..b7daedb --- /dev/null +++ b/FONTS @@ -0,0 +1,35 @@ +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 . + + + +* vga8x??.png are the standard DOS fonts, from the DOSbox project. + Copyright (C) 2002-2004 The DOSBox Team + +* vga4x8.png contains a miniature, half-size font for low-resolution + displays. This is based on the Atari-Small font by Tom Fine. The + original font was standard ASCII only; this has been extended to the + full Extended ASCII range with scaled-down versions of the full-size + DOS font. Original copyright notice: + + Copyright (c) 1999, Thomas A. Fine + + License to copy, modify, and distribute for both commercial and + non-commercial use is herby granted, provided this notice + is preserved. + + Email to my last name at head.cfa.harvard.edu + http://hea-www.harvard.edu/~fine/ diff --git a/client/src/file.c b/client/src/file.c index 5841d07..ccb18ec 100644 --- a/client/src/file.c +++ b/client/src/file.c @@ -25,8 +25,12 @@ #include "taglist.h" #include "window.h" #include "label.h" +#include "timer.h" +#include "msgbox.h" #include "file.h" +#include "hangup.h" +#include "welcome.h" // All this queue nonsense allows you to request more @@ -47,12 +51,21 @@ static char *_file = NULL; static FILE *_handle = NULL; static WindowT *_winFile = NULL; static LabelT *_lblFile = NULL; +static TimerT *_timTimer = NULL; +static void btnMsgBoxOkay(MsgBoxButtonT button); static void fileCheckNext(void); static void fileShowDialog(void); static void fileShowError(char *message); static void packetHandler(PacketDecodeDataT *packet); +static void timTimerTimeout(WidgetT *widget); + + +static void btnMsgBoxOkay(MsgBoxButtonT button) { + (void)button; + hangupShow(welcomeShow); +} void fileCacheCheck(fileCallback callback, char *vpaths[]) { @@ -155,6 +168,11 @@ static void fileShowDialog(void) { T_X, 41, T_Y, 25, T_TITLE, P("Downloading..."), T_LABEL, T_DONE, + T_TIMER, O(_timTimer), + T_EVENT, P(timTimerTimeout), + T_VALUE, 4 * 5, + T_ENABLED, 1, + T_TIMER, T_DONE, T_WINDOW, T_DONE, T_END }; @@ -165,9 +183,12 @@ static void fileShowDialog(void) { static void fileShowError(char *message) { - // ***TODO*** Handle error. This is fatal. + // ***TODO*** This should close all open windows. + + // Show error. This is fatal. if (_dialogVisible) guiDelete(D(_winFile)); netChannelRelease(_channel); + msgBoxOne("Uh Oh!", MSGBOX_ICON_QUESTION, message, "Okay", btnMsgBoxOkay); } @@ -200,7 +221,6 @@ static void packetHandler(PacketDecodeDataT *packet) { break; case FILE_RESPONSE_DATA: - // Get file size. logWrite("Got FILE_RESPONSE_DATA\n"); // Receive new file data. if (!_dialogVisible) fileShowDialog(); @@ -239,9 +259,39 @@ static void packetHandler(PacketDecodeDataT *packet) { packetSend(__packetThreadData, &encoded); DEL(packetData); } + // Reset timeout timer. + timerReset(_timTimer); break; } } packetDecodeDataDestroy(&packet); } + + +static void timTimerTimeout(WidgetT *widget) { + uint8_t missing = 0; + + (void)widget; + + // Download timed out. + timerStop(_timTimer); + + // If we at least have some version of the file, try to continue. + while (arrlen(_fileList) > 0) { + while (arrlen(_fileList[0]->files) > 0) { + if (cacheFilenameGet(_fileList[0]->files[0])) { + arrdel(_fileList[0]->files, 0); + } else { + missing = 1; + } + } + // If we're good so far, call the callback. + if (!missing) _fileList[0]->callback(); + arrfree(_fileList[0]->files); + arrdel(_fileList, 0); + } + arrfree(_fileList); + + if (missing) fileShowError("Unable to download needed files."); +} diff --git a/client/src/gui/font.c b/client/src/gui/font.c index 4b48d09..e2bdb42 100644 --- a/client/src/gui/font.c +++ b/client/src/gui/font.c @@ -96,8 +96,9 @@ void fontRender(FontT *font, char *string, ColorT foreground, ColorT background, uint8_t data; uint8_t character; uint8_t c; + uint8_t odd; - //***TODO*** This only handles 8xY fonts. + //***TODO*** This only handles 4xY and 8xY fonts. for (c=0; cspan; cy = character / font->span; - // Find offset byte based on font bits. - offset = cy * font->span * font->height + cx; + // Half byte or full byte font? + if (font->width == 4) { + // Half Byte. - // Draw out 8 lines. - yp = y; - for (yl=0; ylheight; yl++) { - // We do 8 pixels unrolled hoping it's fast. - data = font->bits[offset]; - offset += font->span; - 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++; + // Which half of the byte do we want? + odd = ((cx & 1) == 1); + + // Find offset byte based on font bits. + offset = cy * (font->span / 2) * font->height + cx * ((float)font->width / 8.0f); + + for (yl=0; ylheight; yl++) { + data = font->bits[offset]; + offset += (font->span / 2); + + if (odd) { + surfacePutPixel(x, yp, data & 0x08 ? foreground : background); + surfacePutPixel(x + 1, yp, data & 0x04 ? foreground : background); + surfacePutPixel(x + 2, yp, data & 0x02 ? foreground : background); + surfacePutPixel(x + 3, yp, data & 0x01 ? foreground : background); + } else { + 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); + } + } + } else { + // Full Byte. + + // Find offset byte based on font bits. + offset = cy * font->span * font->height + cx; + + // Draw out 8 lines. + yp = y; + for (yl=0; ylheight; yl++) { + // We do 8 pixels unrolled hoping it's fast. + data = font->bits[offset]; + offset += font->span; +#ifndef FONT_DEBUGGING + 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); +#endif + yp++; + } } x += font->width; diff --git a/client/src/system/cache.c b/client/src/system/cache.c index 2264a18..600ee2f 100644 --- a/client/src/system/cache.c +++ b/client/src/system/cache.c @@ -260,6 +260,7 @@ static char *cacheFieldGet(char *virtualPath, uint8_t field) { if (osFileExists(index)) { in = fopen(index, "rt"); if (in) { + // Be sure the fread is the last conditional so it short-circuts properly. while (result == NULL && (fgets(buffer, 2048, in) != 0)) { name = strstr(buffer, " "); *name = 0; diff --git a/font/font.pro b/font/font.pro index eeb06ef..4b2fcf3 100644 --- a/font/font.pro +++ b/font/font.pro @@ -22,16 +22,26 @@ CONFIG += console DESTDIR = $$OUT_PWD/bin SHARED = $$PWD/../shared +CLIENT = $$PWD/../client/src +SYSTEM = $$CLIENT/system +GUI = $$CLIENT/gui + +DEFINES += FONT_DEBUGGING INCLUDEPATH += \ $$SHARED \ - $$SHARED/thirdparty + $$SHARED/thirdparty \ + $$CLIENT \ + $$SYSTEM \ + $$GUI HEADERS = \ $$SHARED/stddclmr.h \ $$SHARED/thirdparty/memwatch/memwatch.h \ - $$SHARED/thirdparty/stb_image.h + $$SHARED/thirdparty/stb_image.h \ + $$GUI/font.h SOURCES = \ $$SHARED/thirdparty/memwatch/memwatch.c \ + $$GUI/font.c \ src/main.c diff --git a/font/in/vga4x8.png b/font/in/vga4x8.png new file mode 100644 index 0000000..579fd48 --- /dev/null +++ b/font/in/vga4x8.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4c2a6fe844525cdd4abddd2c7aa2d6d73ec667dd82aee10e8a9c62e2f367d8b +size 18029 diff --git a/font/src/main.c b/font/src/main.c index 9dabeb9..9212673 100644 --- a/font/src/main.c +++ b/font/src/main.c @@ -27,9 +27,56 @@ #define STBI_ONLY_PNG #include "stb_image.h" +#include "font.h" #include "stddclmr.h" +void drawChar(FontT *font, char c); +void makeFont(char *source, char *target, int pixelsW, int pixelsH, int charsW, int charCount); +void test(char *fontfile); + + +void drawChar(FontT *font, char c) { + uint8_t cx; + uint8_t cy; + uint16_t offset; + uint8_t yl; + uint8_t data; + uint8_t odd; + uint16_t t; + + // Find character position in font grid. + cx = c % font->span; + cy = c / font->span; + + // Which half of the byte do we want? + odd = ((cx & 1) == 1); + + // Find offset byte based on font bits. + offset = cy * (font->span / 2) * font->height; + t = cx * ((float)font->width / 8.0f); + offset += t; + + for (yl=0; ylheight; yl++) { + data = font->bits[offset]; + offset += (font->span / 2); + + if (odd) { + printf("%c", data & 0x08 ? '#' : ' '); + printf("%c", data & 0x04 ? '#' : ' '); + printf("%c", data & 0x02 ? '#' : ' '); + printf("%c", data & 0x01 ? '#' : ' '); + } else { + printf("%c", data & 0x80 ? '#' : ' '); + printf("%c", data & 0x40 ? '#' : ' '); + printf("%c", data & 0x20 ? '#' : ' '); + printf("%c", data & 0x10 ? '#' : ' '); + } + printf("\n"); + } +} + + void makeFont(char *source, char *target, int pixelsW, int pixelsH, int charsW, int charCount) { unsigned char *font = NULL; unsigned char data = 0; @@ -53,10 +100,10 @@ void makeFont(char *source, char *target, int pixelsW, int pixelsH, int charsW, } // Provide some metadata for enhancement later. - fputc(pixelsW, out); // Width of characters in pixels - fputc(pixelsH, out); // Height of characters in pixels - fputc(charsW, out); // Number of characters per row - fputc(charCount, out); // Number of characters - 1 + fputc(pixelsW, out); // Width of characters in pixels + fputc(pixelsH, out); // Height of characters in pixels + fputc(charsW, out); // Number of characters per row + fputc(charCount - 1, out); // Number of characters - 1 // Convert bitmap to actual bits. for (y=0; y