diff --git a/client/src/gui/gui.c b/client/src/gui/gui.c index 8d0a8e3..828ccb9 100644 --- a/client/src/gui/gui.c +++ b/client/src/gui/gui.c @@ -28,18 +28,19 @@ static ColorT _mouseTransparency; void guiEventsDo(void) { EventT event = { 0 }; - // Read mouse & keyboard. - platformEventGet(&event); - // Paint desktop. surfaceSet(__guiBackBuffer); surfaceClear(GUI_CYAN); - // Paint GUI. + // Read mouse & keyboard. + platformEventGet(&event); + + // Handle GUI window manager and widgets. wmUpdate(&event); // Paint mouse pointer. - surfaceBlitWithTransparency(__guiBackBuffer, event.x, event.y, _mousePointer, _mouseTransparency); + surfaceSet(__guiBackBuffer); + surfaceBlitWithTransparency(event.x, event.y, _mousePointer, _mouseTransparency); // Copy to screen. videoBlit(0, 0, __guiBackBuffer); @@ -118,11 +119,9 @@ uint8_t guiStartup(int16_t width, int16_t height, int16_t depth) { __guiBaseColors[i] = surfaceColorMake(EGA[i][0], EGA[i][1], EGA[i][2]); } - __guiBackBuffer = surfaceCreate(videoDisplayWidthGet(), videoDisplayHeightGet()); - surfaceSet(__guiBackBuffer); - - _mousePointer = imageLoad("mouse.png"); - _mouseTransparency = surfacePixelGet(_mousePointer, surfaceWidthGet(_mousePointer) - 2, 0); // Find our transparency color. + _mousePointer = imageLoad("mouse.png"); + surfaceSet(_mousePointer); + _mouseTransparency = surfacePixelGet(_mousePointer, surfaceWidthGet() - 2, 0); // Find our transparency color. __guiFontVGA8x8 = fontLoad("vga8x8.dat"); __guiFontVGA8x14 = fontLoad("vga8x14.dat"); @@ -130,6 +129,9 @@ uint8_t guiStartup(int16_t width, int16_t height, int16_t depth) { fontSet(__guiFontVGA8x14); fontColorSet(GUI_WHITE, GUI_BLACK); + __guiBackBuffer = surfaceCreate(videoDisplayWidthGet(), videoDisplayHeightGet()); + surfaceSet(__guiBackBuffer); + wmStartup(); // Register all known widgets with the GUI. diff --git a/client/src/gui/surface.c b/client/src/gui/surface.c index cc2e216..dab7450 100644 --- a/client/src/gui/surface.c +++ b/client/src/gui/surface.c @@ -19,52 +19,75 @@ static void surfacePixelSet8(uint16_t x, uint16_t y, ColorT color); static void surfacePixelSet16(uint16_t x, uint16_t y, ColorT color); static void surfacePixelSet32(uint16_t x, uint16_t y, ColorT color); +#include "gui.h" -void surfaceBlit(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source) { - uint16_t y1; +void surfaceBlit(int16_t targetX, int16_t targetY, SurfaceT *source) { + int16_t y; + int16_t x1 = 0; + int16_t y1 = 0; + int16_t x2 = source->width; + int16_t y2 = source->height; + size_t bytes; size_t offsetTarget; size_t offsetSource; - if (targetX == 0 && targetY == 0 && target->width == source->width && target->height == source->height) { + // Clip on top and left. x1 & y1 are pixel locations inside the source bitmap. + if (targetX < 0) x1 = -targetX; + if (targetY < 0) y1 = -targetY; + + // Clip on right and bottom. + if (targetX + x2 > __surfaceActive->width) x2 -= targetX + x2 - __surfaceActive->width; + if (targetY + y2 > __surfaceActive->height) y2 -= targetY + y2 - __surfaceActive->height; + + // Are we still on the screen? + if (x1 < 0 || y1 < 0 || x2 < x1 || y2 < y1) return; + + if (targetX == 0 && targetY == 0 && __surfaceActive->width == source->width && __surfaceActive->height == source->height) { // Direct blit of entire surface. - memcpy(target->buffer.bits8, source->buffer.bits8, source->bytes); + memcpy(__surfaceActive->buffer.bits8, source->buffer.bits8, source->bytes); } else { // Blit into larger surface. - offsetTarget = targetY * __surfaceActive->scanline + targetX * __surfaceBytesPerPixel; - offsetSource = 0; - for (y1=targetY; y1height; y1++) { - memcpy(&target->buffer.bits8[offsetTarget], &source->buffer.bits8[offsetSource], source->scanline); - offsetTarget += target->scanline; + offsetTarget = (targetY + y1) * __surfaceActive->scanline + (targetX + x1) * __surfaceBytesPerPixel; + offsetSource = y1 * source->scanline + x1 * __surfaceBytesPerPixel; + bytes = (x2 - x1) * __surfaceBytesPerPixel; + for (y=y1; ybuffer.bits8[offsetTarget], &source->buffer.bits8[offsetSource], bytes); + offsetTarget += __surfaceActive->scanline; offsetSource += source->scanline; } } } -void surfaceBlitWithTransparency(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source, ColorT transparent) { - uint16_t x1; - uint16_t y1; - uint16_t x2 = source->width; - uint16_t y2 = source->height; +void surfaceBlitWithTransparency(int16_t targetX, int16_t targetY, SurfaceT *source, ColorT transparent) { + int16_t x; + int16_t y; + int16_t x1 = 0; + int16_t y1 = 0; + int16_t x2 = source->width; + int16_t y2 = source->height; ColorT pixel; - SurfaceT *t = surfaceGet(); - surfaceSet(target); + // Clip on top and left. x1 & y1 are pixel locations inside the source bitmap. ox & oy offset those into screen coordinates. + if (targetX < 0) x1 = -targetX; + if (targetY < 0) y1 = -targetY; - // Clip on right and bottom - if (targetX + x2 > target->width) x2 -= targetX + x2 - target->width; - if (targetY + y2 > target->height) y2 -= targetY + y2 - target->height; + // Clip on right and bottom. + if (targetX + x2 > __surfaceActive->width) x2 -= targetX + x2 - __surfaceActive->width; + if (targetY + y2 > __surfaceActive->height) y2 -= targetY + y2 - __surfaceActive->height; - for (y1=0; y1height; +int16_t surfaceHeightGet(void) { + return __surfaceActive->height; } @@ -381,8 +404,8 @@ void surfaceStartup(uint8_t bits) { } -int16_t surfaceWidthGet(SurfaceT *surface) { - return surface->width; +int16_t surfaceWidthGet() { + return __surfaceActive->width; } diff --git a/client/src/gui/surface.h b/client/src/gui/surface.h index 924edcd..92a8c57 100644 --- a/client/src/gui/surface.h +++ b/client/src/gui/surface.h @@ -45,8 +45,8 @@ extern ColorT (*surfacePixelGet)(SurfaceT *surface, int16_t x, int16_t y); extern void (*surfacePixelSet)(uint16_t x, uint16_t y, ColorT color); -void surfaceBlit(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source); -void surfaceBlitWithTransparency(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source, ColorT transparent); +void surfaceBlit(int16_t targetX, int16_t targetY, SurfaceT *source); +void surfaceBlitWithTransparency(int16_t targetX, int16_t targetY, SurfaceT *source, ColorT transparent); void surfaceClear(ColorT color); ColorT surfaceColorMake(uint8_t r, uint8_t g, uint8_t b); SurfaceT *surfaceCreate(int16_t width, int16_t height); @@ -55,14 +55,14 @@ void surfaceBoxFilled(int16_t x1, int16_t y1, int16_t x2, int16_t y2, Color void surfaceBoxHighlight(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT highlight, ColorT shadow); void surfaceDestroy(SurfaceT **surface); SurfaceT *surfaceGet(void); -int16_t surfaceHeightGet(SurfaceT *surface); +int16_t surfaceHeightGet(void); 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); void surfaceSet(SurfaceT *surface); void surfaceShutdown(void); void surfaceStartup(uint8_t bits); -int16_t surfaceWidthGet(SurfaceT *surface); +int16_t surfaceWidthGet(void); #endif // SURFACE_H diff --git a/client/src/gui/wmwindow.c b/client/src/gui/wmwindow.c index 07d81a0..903c219 100644 --- a/client/src/gui/wmwindow.c +++ b/client/src/gui/wmwindow.c @@ -3,9 +3,6 @@ #include "font.h" -#define USE_CACHING - - uint8_t __MAGIC_WINDOW = 0; static WindowT **_windowList = NULL; @@ -172,7 +169,6 @@ void windowPaint(struct WidgetS *widget, ...) { target = surfaceGet(); w = (WindowT *)widget; -#ifdef USE_CACHING // Do we need redrawn? if (guiWidgetDirtyGet(widget)) { guiWidgetDirtySet(widget, 0); @@ -186,7 +182,8 @@ void windowPaint(struct WidgetS *widget, ...) { // Do we have a cached surface already? if (w->cached) { // Did the size change? - if ((surfaceWidthGet(w->cached) != w->base.r.w) || (surfaceHeightGet(w->cached) != w->base.r.h)) { + surfaceSet(w->cached); + if ((surfaceWidthGet() != w->base.r.w) || (surfaceHeightGet() != w->base.r.h)) { // Yeah. We will recreate it. surfaceDestroy(&w->cached); } @@ -198,7 +195,6 @@ void windowPaint(struct WidgetS *widget, ...) { // Draw into cache. surfaceSet(w->cached); -#endif // Determine some colors. titleBackgroundColor = (w == _windowTop) ? GUI_DARKGRAY : GUI_LIGHTGRAY; @@ -314,14 +310,13 @@ void windowPaint(struct WidgetS *widget, ...) { // Fake Window contents. surfaceBoxFilled(w->bounds.x, w->bounds.y, w->bounds.x2, w->bounds.y2, GUI_BLACK); -#ifdef USE_CACHING // Fixup all the widget coordinates. windowMoveTo(w, originalX, originalY); } // By now we have a valid cached window. Blit it. - surfaceBlit(target, w->base.r.x, w->base.r.y, w->cached); -#endif + surfaceSet(target); + surfaceBlit(w->base.r.x, w->base.r.y, w->cached); } @@ -359,8 +354,6 @@ void wmUpdate(EventT *event) { widget->reg->paint(widget); } - if (dragging) sleep(1); - // Get top window. win = _windowList[arrlen(_windowList) - 1]; @@ -373,6 +366,7 @@ void wmUpdate(EventT *event) { // Is the left mouse button down? if (event->buttons & BUTTON_LEFT) { + /* // DEBUG - draw active regions. ***TODO*** No resize grabber here. surfaceSet(__guiBackBuffer); surfaceBox(win->base.r.x, win->base.r.y, x2, y2, GUI_YELLOW); @@ -381,6 +375,7 @@ void wmUpdate(EventT *event) { surfaceBox(win->titlebar.x, win->titlebar.y, win->titlebar.x2, win->titlebar.y2, GUI_LIGHTCYAN); surfaceBox(win->minimize.x, win->minimize.y, win->minimize.x2, win->minimize.y2, GUI_LIGHTGREEN); surfaceBox(win->maximize.x, win->maximize.y, win->maximize.x2, win->maximize.y2, GUI_RED); + */ // Are we currently dragging? if (dragging) {