Start of dirty rectangle updating.
This commit is contained in:
parent
456b7d98df
commit
561f343436
1 changed files with 167 additions and 0 deletions
|
@ -28,6 +28,12 @@
|
|||
#include "font.h"
|
||||
|
||||
|
||||
typedef struct DamageListS {
|
||||
RectT rect;
|
||||
SurfaceT *surface;
|
||||
} DamageListT;
|
||||
|
||||
|
||||
uint8_t __MAGIC_WINDOW = 0;
|
||||
|
||||
|
||||
|
@ -666,6 +672,8 @@ void wmStartup(void) {
|
|||
|
||||
void wmUpdate(EventT *event) {
|
||||
int16_t i;
|
||||
int16_t j;
|
||||
int16_t k;
|
||||
PointT widgetLocal;
|
||||
int16_t x2;
|
||||
int16_t y2;
|
||||
|
@ -673,6 +681,12 @@ void wmUpdate(EventT *event) {
|
|||
WidgetT *widget;
|
||||
WidgetT *widgetOver = NULL;
|
||||
WindowT *win = NULL;
|
||||
WindowT *win2 = NULL;
|
||||
RectT *rect;
|
||||
RectT **rects = NULL;
|
||||
DamageListT **damageList = NULL;
|
||||
DamageListT *damageItem = NULL;
|
||||
uint8_t found;
|
||||
ClickRawInputT rawEvent = { 0 };
|
||||
static uint8_t resizing = 0;
|
||||
static PointT resizeOffset = { 0 };
|
||||
|
@ -915,6 +929,159 @@ void wmUpdate(EventT *event) {
|
|||
break;
|
||||
} // Left button processing.
|
||||
|
||||
|
||||
// Calculate visible rectangle list.
|
||||
//
|
||||
// Start with the top window and divide it into smaller rectangles
|
||||
// using the edges of every other window. Add these to the "damage
|
||||
// list".
|
||||
//
|
||||
// Then iterate through the remaining windows from top to bottom
|
||||
// dividing them with the edges of every other window. When finished
|
||||
// with each window, compare the list of new rectangles to the existing
|
||||
// damage list. Add any rectangles that are not already there.
|
||||
//
|
||||
// Finally do the same as the remaining windows with the entire screen.
|
||||
|
||||
// Iterate over all windows, top to bottom.
|
||||
for (i=0; i<=arrlen(_windowList); i++) {
|
||||
|
||||
// New rectangle.
|
||||
NEW(RectT, rect);
|
||||
|
||||
// Are we comparing the desktop?
|
||||
if (i == arrlen(_windowList)) {
|
||||
// Yes. Fake a window.
|
||||
win = NULL;
|
||||
rect->x = 0;
|
||||
rect->y = 0;
|
||||
rect->x2 = videoDisplayWidthGet() - 1;
|
||||
rect->y2 = videoDisplayHeightGet() - 1;
|
||||
} else {
|
||||
// Get this window.
|
||||
win = (WindowT *)_windowList[i];
|
||||
rect->x = win->base.r.x;
|
||||
rect->y = win->base.r.y;
|
||||
rect->x2 = win->base.r.x + win->base.r.w - 1;
|
||||
rect->y2 = win->base.r.y + win->base.r.h - 1;
|
||||
}
|
||||
|
||||
// Add this window to the rectangle list.
|
||||
arrput(rects, rect);
|
||||
|
||||
// Iterate over all the other windows.
|
||||
for (j=0; j<arrlen(_windowList); j++) {
|
||||
win2 = (WindowT *)_windowList[j];
|
||||
if (win != win2) {
|
||||
|
||||
// Get win2 extents.
|
||||
x2 = win2->base.r.x + win2->base.r.w - 1;
|
||||
y2 = win2->base.r.y + win2->base.r.h - 1;
|
||||
|
||||
// Check the edges of this window against all the
|
||||
// rectangles in the current rectangle list. Split
|
||||
// and create new rectangles on any lines that intersect.
|
||||
for (k=0; k<arrlen(rects); k++) {
|
||||
// Compare Window Top
|
||||
if ((win2->base.r.y > rects[k]->y) && (win2->base.r.y < rects[k]->y2)) {
|
||||
NEW(RectT, rect);
|
||||
rect->x = rects[k]->x;
|
||||
rect->x2 = rects[k]->x2;
|
||||
rect->y2 = rects[k]->y2;
|
||||
rects[k]->y2 = win2->base.r.y;
|
||||
rect->y = win2->base.r.y;
|
||||
arrput(rects, rect);
|
||||
}
|
||||
// Compare Window Bottom
|
||||
if ((y2 > rects[k]->y) && (y2 < rects[k]->y2)) {
|
||||
NEW(RectT, rect);
|
||||
rect->x = rects[k]->x;
|
||||
rect->x2 = rects[k]->x2;
|
||||
rect->y2 = rects[k]->y2;
|
||||
rects[k]->y2 = y2;
|
||||
rect->y = y2;
|
||||
arrput(rects, rect);
|
||||
}
|
||||
// Compare Window Left
|
||||
if ((win2->base.r.x > rects[k]->x) && (win2->base.r.x < rects[k]->x2)) {
|
||||
NEW(RectT, rect);
|
||||
rect->y = rects[k]->y;
|
||||
rect->x2 = rects[k]->x2;
|
||||
rect->y2 = rects[k]->y2;
|
||||
rects[k]->x2 = win2->base.r.x;
|
||||
rect->x = win2->base.r.x;
|
||||
arrput(rects, rect);
|
||||
}
|
||||
// Compare Window Right
|
||||
if ((x2 > rects[k]->x) && (x2 < rects[k]->x2)) {
|
||||
NEW(RectT, rect);
|
||||
rect->y = rects[k]->y;
|
||||
rect->x2 = rects[k]->x2;
|
||||
rect->y2 = rects[k]->y2;
|
||||
rects[k]->x2 = x2;
|
||||
rect->x = x2;
|
||||
arrput(rects, rect);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Add rectangles to the damage list. Clear rectangle list.
|
||||
while (arrlen(rects) > 0) {
|
||||
found = 0;
|
||||
// Is this the top window?
|
||||
if (i != 0) {
|
||||
// No. Compare rectangles to existing damage list.
|
||||
for (k=0; k<arrlen(damageList); k++) {
|
||||
if ((rects[0]->x == damageList[k]->rect.x ) &&
|
||||
(rects[0]->y == damageList[k]->rect.y ) &&
|
||||
(rects[0]->x2 == damageList[k]->rect.x2) &&
|
||||
(rects[0]->y2 == damageList[k]->rect.y2)) {
|
||||
// We already have this. Skip it.
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do we have this section of the screen yet?
|
||||
if (!found) {
|
||||
// Nope! Add it.
|
||||
NEW(DamageListT, damageItem);
|
||||
//memcpy(&damageItem->rect, &rects[0], sizeof(RectT));
|
||||
damageItem->rect.x = rects[0]->x;
|
||||
damageItem->rect.y = rects[0]->y;
|
||||
damageItem->rect.x2 = rects[0]->x2;
|
||||
damageItem->rect.y2 = rects[0]->y2;
|
||||
if (win != NULL) {
|
||||
damageItem->surface = win->cached;
|
||||
} else {
|
||||
damageItem->surface = NULL;
|
||||
}
|
||||
arrput(damageList, damageItem);
|
||||
}
|
||||
|
||||
// Delete this rect.
|
||||
DEL(rects[0]);
|
||||
arrdel(rects, 0);
|
||||
}
|
||||
arrfree(rects);
|
||||
|
||||
//***DEBUG*** Draw the damage list.
|
||||
surfaceSet(__guiBackBuffer);
|
||||
for (k=0; k<arrlen(damageList); k++) {
|
||||
surfaceBox(damageList[k]->rect.x, damageList[k]->rect.y, damageList[k]->rect.x2, damageList[k]->rect.y2, GUI_RED);
|
||||
}
|
||||
|
||||
// Delete damage list.
|
||||
while (arrlen(damageList) > 0) {
|
||||
DEL(damageList[0]);
|
||||
arrdel(damageList, 0);
|
||||
}
|
||||
arrfree(damageList);
|
||||
}
|
||||
|
||||
} // Do we have windows?
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue