Skip to content

Commit

Permalink
Optimized drawing.
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomaz Stih committed Aug 23, 2015
1 parent bc5701a commit e1b1c89
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 39 deletions.
2 changes: 1 addition & 1 deletion buddy/Makefile
Expand Up @@ -9,7 +9,7 @@ ASFLAGS = -xlos -g
LD = sdcc
LDFLAGS = -mz80 --no-std-crt0 \
--nostdlib --code-loc 0x8032 \
--data-loc 0xb000 -Wl -b_HEADER=0x8000
--data-loc 0xc000 -Wl -b_HEADER=0x8000
# Deps.
CSRCS = $(wildcard *.c)
SSRCS = $(wildcard *.s)
Expand Down
86 changes: 80 additions & 6 deletions buddy/buddy.c
Expand Up @@ -37,6 +37,7 @@ void temp_shit() {
35,
213,
160);

w3=window_create(
"Window 3",
window_desktop,
Expand All @@ -46,6 +47,7 @@ void temp_shit() {
80,
60,
132);

w4=window_create(
"Window 4",
window_desktop,
Expand Down Expand Up @@ -91,7 +93,6 @@ void temp_shit() {
150,
250,
180);

}

void buddy_init() {
Expand Down Expand Up @@ -124,7 +125,7 @@ void buddy_harvest_events() {
if (mouse_rect.x0!=mi.x || mouse_rect.y0!=mi.y) { /* coord changed */

/* operation in progress? */
if (buddy_op.op==BUDDY_OP_MOVING)
if (buddy_op.op==BUDDY_OP_MOVING || buddy_op.op==BUDDY_OP_SIZING)
buddy_xor_op_rect(); /* del old rect */

/* first repaint mouse */
Expand Down Expand Up @@ -156,6 +157,10 @@ void buddy_dispatch(byte id, word param1, word param2) {
boolean lr,ud;
byte dx,dy;
byte hit=WND_HIT_NONE;
rect_t affectedrect;
rect_t client;
byte num;
rect_t smaller[4];

switch (id) {

Expand All @@ -175,7 +180,7 @@ void buddy_dispatch(byte id, word param1, word param2) {
}

/* hit test window for system areas? */
message_send(affectedwnd,MSG_WND_HITTEST,(word)&hit,0);
message_send(affectedwnd,MSG_WND_HITTEST,(word)&hit,(word)param1<<8|(word)param2);

/* store mouse to current operation (whatever) */
buddy_op.mx=(byte)param1;
Expand All @@ -196,6 +201,34 @@ void buddy_dispatch(byte id, word param1, word param2) {
sizeof(rect_t)
);
break;
case WND_HIT_RESIZE: /* start window resize operation */
buddy_op.op=BUDDY_OP_SIZE;
buddy_op.wnd=appwnd;
buddy_op.ix=buddy_op.mx;
buddy_op.iy=buddy_op.my;
yx->copy(
(void*)affectedwnd->graphics->area,
(void*)&(buddy_op.rect),
sizeof(rect_t)
);
break;
case WND_HIT_CLOSE:
/* hide mouse */
mouse_hide_cursor();

/* remember the rectangle */
yx->copy(
(void*)appwnd->graphics->area,
(void*)&(affectedrect),
sizeof(rect_t)
);
message_send(appwnd,MSG_WND_CLOSE,0,0);
window_destroy(appwnd);
window_invalidate(&affectedrect, window_desktop, window_desktop->first_child);

/* show mouse */
mouse_show_cursor(mi.x, mi.y, current_cursor);
break;
}
}
break;
Expand All @@ -206,6 +239,13 @@ void buddy_dispatch(byte id, word param1, word param2) {
/* clean last drag */
buddy_xor_op_rect();

/* store affected rect */
yx->copy(
(void*)((buddy_op.wnd)->graphics->area),
(void*)&affectedrect,
sizeof(rect_t)
);

/* move window */
if (lr=(buddy_op.ix > (byte)param1))
dx=buddy_op.ix - (byte)param1;
Expand All @@ -217,8 +257,26 @@ void buddy_dispatch(byte id, word param1, word param2) {
dy=(byte)param2 - buddy_op.iy;
window_move(buddy_op.wnd, dx, lr, dy, ud);

/* redraw all for now */
window_draw(window_desktop);
/* invalidate affected rect */
window_invalidate(&affectedrect, window_desktop, window_desktop->first_child);

/* redraw window at new position */
window_draw(buddy_op.wnd);

} else if (buddy_op.op==BUDDY_OP_SIZING) {

/* clean last drag */
buddy_xor_op_rect();

/* get difference between xor rect and window rect */
rect_intersect(&(buddy_op.rect), (buddy_op.wnd)->graphics->area, &affectedrect);
rect_subtract((buddy_op.wnd)->graphics->area, &affectedrect, smaller, &num);

/* and invalidate "the difference" */
while(num) {
window_invalidate(&(smaller[num-1]), window_desktop, window_desktop->first_child);
num--;
}

} else {
/* find affected window */
Expand All @@ -242,9 +300,24 @@ void buddy_dispatch(byte id, word param1, word param2) {
if (buddy_op.op==BUDDY_OP_MOVE) /* initial move */
buddy_op.op=BUDDY_OP_MOVING;

if (buddy_op.op==BUDDY_OP_SIZE) /* initial resize */
buddy_op.op=BUDDY_OP_SIZING;

if (buddy_op.op==BUDDY_OP_MOVING) {
/* calculate new position */
rect_delta_offset(&(buddy_op.rect), buddy_op.mx, (byte)param1, buddy_op.my, (byte)param2);
rect_delta_offset(&(buddy_op.rect), buddy_op.mx, (byte)param1, buddy_op.my, (byte)param2, FALSE);

/* store new coords */
buddy_op.mx=(byte)param1;
buddy_op.my=(byte)param2;

/* and draw */
buddy_xor_op_rect();
}

if (buddy_op.op==BUDDY_OP_SIZING) {
/* calculate new size */
rect_delta_offset(&(buddy_op.rect), buddy_op.mx, (byte)param1, buddy_op.my, (byte)param2, TRUE);

/* store new coords */
buddy_op.mx=(byte)param1;
Expand All @@ -253,6 +326,7 @@ void buddy_dispatch(byte id, word param1, word param2) {
/* and draw */
buddy_xor_op_rect();
}

break;
}
}
Expand Down
24 changes: 14 additions & 10 deletions buddy/graphics/rect.c
Expand Up @@ -143,51 +143,55 @@ void rect_subtract(
byte *num) { /* returns actual rects in result */

*num = 0; /* assume */
if (outer->y1 < inner->y1) {
if (outer->y0 < inner->y0) {
result->x0=outer->x0;
result->y0=outer->y0;
result->x1=outer->x1;
result->y1=inner->y0;
result->y1=inner->y0-1;
(*num)++;
result++;
}
if (inner->y1 < outer->y1) {
result->x0=outer->x0;
result->y0=inner->y1;
result->y0=inner->y1+1;
result->x1=outer->x1;
result->y1=outer->y1;
(*num)++;
result++;
}
if (outer->x0 < inner->x0) {
result->x0=outer->x0;
result->y0=inner->y0;
result->x1=inner->x0;
result->x1=inner->x0-1;
result->y1=inner->y1;
(*num)++;
result++;
}
if (inner->x1 < outer->x1) {
result->x0=inner->x1;
result->x0=inner->x1+1;
result->y0=inner->y0;
result->x1=outer->x1;
result->y1=inner->y1;
(*num)++;
result++;
}
}

/* TODO: careful at scren edges */
void rect_delta_offset(rect_t *rect, byte oldx, byte newx, byte oldy, byte newy) {
void rect_delta_offset(rect_t *rect, byte oldx, byte newx, byte oldy, byte newy, byte size_only) {
if (oldx > newx) { /* move left */
rect->x0 = rect->x0 - (oldx-newx);
if (!size_only) rect->x0 = rect->x0 - (oldx-newx);
rect->x1 = rect->x1 - (oldx-newx);
} else { /* move right */
rect->x0 = rect->x0 + (newx-oldx);
if (!size_only) rect->x0 = rect->x0 + (newx-oldx);
rect->x1 = rect->x1 + (newx-oldx);
}

if (oldy > newy) { /* move up */
rect->y0 = rect->y0 - (oldy-newy);
if (!size_only) rect->y0 = rect->y0 - (oldy-newy);
rect->y1 = rect->y1 - (oldy-newy);
} else { /* move down */
rect->y0 = rect->y0 + (newy-oldy);
if (!size_only) rect->y0 = rect->y0 + (newy-oldy);
rect->y1 = rect->y1 + (newy-oldy);
}
}
2 changes: 1 addition & 1 deletion buddy/include/rect.h
Expand Up @@ -23,6 +23,6 @@ extern rect_t* rect_inflate(rect_t* rect, sbyte dx, sbyte dy) __naked;
extern rect_t* rect_intersect(rect_t *a, rect_t *b, rect_t *intersect);
extern rect_t* rect_rel2abs(rect_t* abs, rect_t* rel, rect_t* out) __naked;
extern void rect_subtract(rect_t *outer, rect_t *inner, rect_t *result, byte *num);
extern void rect_delta_offset(rect_t *rect, byte oldx, byte newx, byte oldy, byte newy);
extern void rect_delta_offset(rect_t *rect, byte oldx, byte newx, byte oldy, byte newy, byte size_only);

#endif /* _RECT_H */
77 changes: 69 additions & 8 deletions buddy/stdwnd.c
Expand Up @@ -12,12 +12,22 @@
extern yx_t* yx;

result desktop_wnd_proc(window_t* wnd, byte id, word param1, word param2) {
id,param1, param2;

rect_t clip_rect;
param2; /* unused */

switch(id) {
case MSG_SYS_PAINT:
case MSG_SYS_PAINT:
/* set clip */
if (param1) {
yx->copy((void*)wnd->graphics->clip,(void*)&clip_rect,sizeof(rect_t));
yx->copy((void*)param1,(void*)wnd->graphics->clip,sizeof(rect_t));
}
/* clear screen space */
graphics_fill_rect(wnd->graphics,wnd->rect,(byte*)&msk_percent50_8x8, MODE_COPY);
/* restore clip */
if (param1)
yx->copy((void*)&clip_rect,(void*)wnd->graphics->clip,sizeof(rect_t));
}

return SUCCESS; /* we are the desktop!!! */
Expand All @@ -35,9 +45,13 @@ void draw_double_frame(window_t *wnd, rect_t *rect) {
}

result app_wnd_proc(window_t* wnd, byte id, word param1, word param2) {

rect_t *wrct;
rect_t title_rect;
rect_t clip_rect;
rect_t client;
byte *hit_result;
byte x,y;

id, param1, param2;

Expand All @@ -57,6 +71,12 @@ result app_wnd_proc(window_t* wnd, byte id, word param1, word param2) {
return SUCCESS;

case MSG_SYS_PAINT:
/* set clip */
if (param1) {
yx->copy((void*)wnd->graphics->clip,(void*)&clip_rect,sizeof(rect_t));
yx->copy((void*)param1,(void*)wnd->graphics->clip,sizeof(rect_t));
}

/* window border */
if (wnd->flags & WF_HASBORDER) draw_double_frame(wnd, wnd->rect);

Expand All @@ -72,7 +92,16 @@ result app_wnd_proc(window_t* wnd, byte id, word param1, word param2) {
}

/* client window */
message_send(wnd->first_child, MSG_WND_PAINT, 0, 0);
if (param1) {
rect_intersect(wnd->first_child->graphics->clip, (rect_t*)param1, &client);
message_send(wnd->first_child, MSG_WND_PAINT, (word)&client, 0);
} else
message_send(wnd->first_child, MSG_WND_PAINT, 0, 0);

/* restore clip */
if (param1)
yx->copy((void*)&clip_rect,(void*)wnd->graphics->clip,sizeof(rect_t));

return SUCCESS;

case MSG_WND_SIZE:
Expand All @@ -82,12 +111,32 @@ result app_wnd_proc(window_t* wnd, byte id, word param1, word param2) {
wrct->x1=wrct->x0+APP_WND_MIN_WIDTH-1;
if (wrct->y1-wrct->y0+1 < APP_WND_MIN_HEIGHT)
wrct->y1=wrct->y0+APP_WND_MIN_HEIGHT-1;
/* update client rect
if (wnd->first_child) {
client.x0=wrct->x0 + APP_WND_BORDER_WIDTH;
client.y0=wrct->y0 + APP_WND_BORDER_HEIGHT + APP_WND_TITLE_HEIGHT - 1;
client.x1=wrct->x1 - APP_WND_BORDER_WIDTH;
client.y1=wrct->y1 - APP_WND_BORDER_HEIGHT;
yx->copy((void*)&client,(void*)wnd->first_child->graphics->area,sizeof(rect_t));
yx->copy((void*)&client,(void*)wnd->first_child->graphics->clip,sizeof(rect_t));
//message_send(wnd->first_child,MSG_WND_SIZE,(word)&client,0);
}
*/
return SUCCESS;

case MSG_WND_HITTEST:
/* always return title for now */
/* these are absolute coordinates */
hit_result=(byte *)param1;
*hit_result=WND_HIT_TITLE;
y=param2&0x00ff;
x=param2>>8;

if (x > wnd->graphics->area->x1 - 5 && y > wnd->graphics->area->y1-5)
*hit_result=WND_HIT_RESIZE;
else if (x < wnd->graphics->area->x0 + 8 && y < wnd->graphics->area->y0 + 8)
*hit_result=WND_HIT_CLOSE;
else
*hit_result=WND_HIT_TITLE;

return SUCCESS;
}

Expand All @@ -96,14 +145,26 @@ result app_wnd_proc(window_t* wnd, byte id, word param1, word param2) {
}

result client_wnd_proc(window_t* wnd, byte id, word param1, word param2) {
id, param1, param2;

rect_t clip_rect;

param2;

switch(id) {

case MSG_WND_PAINT:
case MSG_WND_PAINT:
/* set clip */
if (param1) {
yx->copy((void*)wnd->graphics->clip,(void*)&clip_rect,sizeof(rect_t));
yx->copy((void*)param1,(void*)wnd->graphics->clip,sizeof(rect_t));
}
graphics_fill_rect(wnd->graphics,wnd->rect,(byte*)&msk_empty_8x8, MODE_COPY);
/* restore clip */
if (param1)
yx->copy((void*)&clip_rect,(void*)wnd->graphics->clip,sizeof(rect_t));
return SUCCESS;

case MSG_WND_SIZE:
break;
}

return NOT_PROCESSED;
Expand Down

0 comments on commit e1b1c89

Please sign in to comment.