From 9494dee16d658caf7462867785390b9c7d527af3 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Mon, 25 Oct 2021 21:11:46 -0500 Subject: [PATCH] Basic interval timers working. --- client/src/gui/os.h | 4 +++- client/src/gui/timer.c | 39 +++++++++++++++++++++++++++++++++++++- client/src/gui/timer.h | 7 +++++++ client/src/gui/window.c | 17 ++++++++++------- client/src/linux/linux.c | 41 ++++++++++++++++++++++++++++++++++++++-- client/src/main.c | 18 +++++++++++------- 6 files changed, 108 insertions(+), 18 deletions(-) diff --git a/client/src/gui/os.h b/client/src/gui/os.h index 3055d44..8600740 100644 --- a/client/src/gui/os.h +++ b/client/src/gui/os.h @@ -33,14 +33,16 @@ #ifdef __linux__ +long biostime(int cmd, long newtime); + #else #include #include #include #include -#include #include +#include #endif diff --git a/client/src/gui/timer.c b/client/src/gui/timer.c index 3ff9246..c0eb1ca 100644 --- a/client/src/gui/timer.c +++ b/client/src/gui/timer.c @@ -21,16 +21,53 @@ #include "timer.h" +#define SECONDS_IN_DAY 86400 +#define TICKS_PER_SECOND 18.2 +#define TICKS_PER_DAY (SECONDS_IN_DAY * TICKS_PER_SECOND) + + +uint8_t timerHalfSecondOn = 0; +uint8_t timerSecondOn = 0; + + +static long _timerLast = 0; +static uint8_t _timerSecond = 2; + + void timerShutdown(void) { // Nothing yet. } void timerStartup(void) { - // Nothing yet. + _timerLast = biostime(0, 0); } void timerUpdate(void) { + long now; + long delta; + now = biostime(0, 0); + + // Ensure we haven't rolled past midnight between calls. + if (now >= _timerLast) { + delta = now - _timerLast; + } else { + // Compensate for midnight rollover. + delta = (now + TICKS_PER_DAY) - _timerLast; + } + + if (delta > TICKS_PER_SECOND * 0.5) { + _timerLast = now; + + // Half Second timer + timerHalfSecondOn = !timerHalfSecondOn; + + // Second timer + if (--_timerSecond == 0) { + _timerSecond = 2; + timerSecondOn = !timerSecondOn; + } + } } diff --git a/client/src/gui/timer.h b/client/src/gui/timer.h index efcdf12..c60ff87 100644 --- a/client/src/gui/timer.h +++ b/client/src/gui/timer.h @@ -22,6 +22,13 @@ #define TIMER_H +#include "os.h" + + +extern uint8_t timerHalfSecondOn; +extern uint8_t timerSecondOn; + + void timerShutdown(void); void timerStartup(void); void timerUpdate(void); diff --git a/client/src/gui/window.c b/client/src/gui/window.c index 4c895af..39041bf 100644 --- a/client/src/gui/window.c +++ b/client/src/gui/window.c @@ -23,7 +23,7 @@ static void windowDeactivateAll(WidgetT *widget); static void windowMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event); -static void windowPaint(WidgetT *widget); +static void windowPaint(WidgetT *widget, RectT pos); static void windowDeactivateAll(WidgetT *widget) { @@ -140,15 +140,18 @@ WindowT *windowNew(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *title) } -static void windowPaint(WidgetT *widget) { +static void windowPaint(WidgetT *widget, RectT pos) { WindowT *w = (WindowT *)widget; - uint16_t x2 = w->base.pos.w - 1; - uint16_t y2 = w->base.pos.h - 1; - ColorT background = GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE) ? _guiColor[COLOR_WINDOW_TITLE_ACTIVE] : _guiColor[COLOR_WINDOW_TITLE_INACTIVE]; - ColorT text = GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE) ? _guiColor[COLOR_WINDOW_TITLE_TEXT_ACTIVE] : _guiColor[COLOR_WINDOW_TITLE_TEXT_INACTIVE]; + uint16_t x2; + uint16_t y2; + ColorT background; + ColorT text; if (GUI_GET_FLAG(widget, WIDGET_FLAG_DIRTY)) { - vbeSurfaceSet(w->base.surface); + x2 = pos.w - 1; + y2 = pos.h - 1; + background = GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE) ? _guiColor[COLOR_WINDOW_TITLE_ACTIVE] : _guiColor[COLOR_WINDOW_TITLE_INACTIVE]; + 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]); diff --git a/client/src/linux/linux.c b/client/src/linux/linux.c index 4e8c1fa..3481d7f 100644 --- a/client/src/linux/linux.c +++ b/client/src/linux/linux.c @@ -26,6 +26,12 @@ #include "vesa.h" +#define SECONDS_IN_DAY 86400 +#define TICKS_PER_SECOND 18.2 +#define TICKS_PER_DAY (SECONDS_IN_DAY * TICKS_PER_SECOND) +#define TIMER_INTERVAL (1000 / TICKS_PER_SECOND) + + static MouseT _mouse; static SDL_Window *_window = NULL; static SDL_Renderer *_renderer = NULL; @@ -44,6 +50,8 @@ static uint8_t _ASCIIKeep = 0; static uint8_t _scanCodeKeep = 0; static uint8_t _keyPressed = 0; static uint8_t _debounce = 0; +static long _timerTicks = 0; +static SDL_TimerID _timerID; void (*vbePutPixel)(uint16_t x, uint16_t y, ColorT color); @@ -53,6 +61,14 @@ static void processEvent(void); static void vbePutPixel32(uint16_t x, uint16_t y, ColorT color); +long biostime(int cmd, long newtime) { + (void)cmd; + (void)newtime; + + return _timerTicks; +} + + uint8_t keyAlt(void) { return _alt; } @@ -178,8 +194,11 @@ static void processEvent(void) { _shift = ((SDL_GetModState() & KMOD_SHIFT) != 0); _alt = ((SDL_GetModState() & KMOD_ALT) != 0); _control = ((SDL_GetModState() & KMOD_CTRL) != 0); - _keyPressed = 1; - _debounce = 1; + if (e.key.keysym.scancode != 0) { + // Not a meta key + _keyPressed = 1; + _debounce = 1; + } } break; } @@ -187,6 +206,18 @@ static void processEvent(void) { } +uint32_t timerCallback(uint32_t interval, void *param) { + (void)param; + + _timerTicks++; + if (_timerTicks > TICKS_PER_DAY) { + _timerTicks = 0; + } + + return interval; +} + + uint8_t vbeDisplayDepthGet(void) { return 32; } @@ -249,6 +280,9 @@ int16_t vbeShutdown(void) { _window = NULL; } + // Stop timer. + SDL_RemoveTimer(_timerID); + SDL_Quit(); return 0; @@ -276,6 +310,9 @@ uint8_t vbeStartup(uint16_t xRes, uint16_t yRes, uint8_t bpp) { _width = xRes; _height = yRes; + // We do timer startup here, too. + _timerID = SDL_AddTimer(TIMER_INTERVAL, timerCallback, NULL); + return 0; } diff --git a/client/src/main.c b/client/src/main.c index c095164..2d51a00 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -26,7 +26,6 @@ * - More widget states: Ghosted, hidden * - Move setup math for paint events inside the dirty check * - Methods that can change the width of a widget (such as setTitle) need to repaint the parent window as well - * - 'pos' should be passed in to the paint method and the surface should already be set * */ @@ -58,7 +57,6 @@ void buttonClick(WidgetT *widget) { } - void drawWidgetDebug(WidgetT *widget, uint8_t debugToggle) { size_t len = arrlenu(widget->children); size_t i; @@ -87,7 +85,7 @@ void mainLoop(void *data) { ImageT *pointer = NULL; ColorT alpha; int8_t key = 0; - int8_t debugToggle = 0; + int8_t debugState = 0; (void)data; @@ -95,11 +93,12 @@ void mainLoop(void *data) { alpha = imagePixelGet(pointer, 5, 0); do { + timerUpdate(); mouse = mouseRead(); if (keyHit()) { key = keyASCII(); guiProcessKeyboard(keyASCII(), keyScanCode(), keyShift(), keyControl(), keyAlt()); - debugToggle = !debugToggle; + //logWrite("Key '%d' Control '%d'\n", key, keyControl()); } else { key = 0; } @@ -107,12 +106,17 @@ void mainLoop(void *data) { guiComposite(); imageRenderWithAlpha(pointer, mouse->x, mouse->y, alpha); - if (key == 'd') guiWidgetTreeDump(guiRootGet(), 0); - drawWidgetDebug(guiRootGet(), debugToggle); + if (key == '=') guiWidgetTreeDump(guiRootGet(), 0); + if (key == '+') { + debugState++; + if (debugState > 2) debugState = 0; + } + if (debugState > 0) drawWidgetDebug(guiRootGet(), debugState - 1); + if (timerHalfSecondOn) guiDrawRectangle(0, 0, vbeSurfaceWidthGet() - 1, vbeSurfaceHeightGet() - 1, vbeMakeColor(255, 255, 255)); vbeWaitVBlank(); vbePresent(); - } while (key != 27 && !(!mouse->buttonRight && mouse->buttonRightWasDown)); // Exit on release of right-click. + } while (key != 27); // Exit on ESC. imageUnload(&pointer); }