From b55a8413973131b325e3c0a615ef98cadd1f225e Mon Sep 17 00:00:00 2001 From: Yourtion Date: Fri, 15 Apr 2016 11:48:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B6=88=E9=99=A4=E9=97=AA=E7=83=81=EF=BC=882?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 11_day/bootpack.h | 2 +- 11_day/sheet.c | 74 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 62 insertions(+), 14 deletions(-) diff --git a/11_day/bootpack.h b/11_day/bootpack.h index 041ffd6..4f154c9 100644 --- a/11_day/bootpack.h +++ b/11_day/bootpack.h @@ -153,7 +153,7 @@ struct SHEET { }; struct SHTCTL { - unsigned char *vram; + unsigned char *vram, *map; int xsize, ysize, top; struct SHEET *sheets[MAX_SHEETS]; struct SHEET sheets0[MAX_SHEETS]; diff --git a/11_day/sheet.c b/11_day/sheet.c index f83122e..61386c0 100644 --- a/11_day/sheet.c +++ b/11_day/sheet.c @@ -12,6 +12,11 @@ struct SHTCTL *shtctl_init(struct MEMMAN *memman, unsigned char *vram, int xsize if (ctl == 0) { goto err; } + ctl->map = (unsigned char *) memman_alloc_4k(memman, xsize * ysize); + if (ctl->map == 0) { + memman_free_4k(memman, (int) ctl, sizeof (struct SHTCTL)); + goto err; + } ctl->vram = vram; ctl->xsize = xsize; ctl->ysize = ysize; @@ -60,7 +65,7 @@ void sheet_updown(struct SHEET *sht, int height) } sht->height = height;/* 设定高度 */ - /* 下面主要是进行sheets[ ]的重新排列 */ + /* 下面主要是进行sheets[]的重新排列 */ if (old > height) { /* 比以前低 */ if (height >= 0) { /* 把中间的往上提 */ @@ -69,7 +74,8 @@ void sheet_updown(struct SHEET *sht, int height) ctl->sheets[h]->height = h; } ctl->sheets[height] = sht; - sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height + 1); + sheet_refreshmap(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height + 1); + sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height + 1, old); } else { /* 隐藏 */ if (ctl->top > old) { /* 把上面的降下来 */ @@ -79,8 +85,9 @@ void sheet_updown(struct SHEET *sht, int height) } } ctl->top--; /* 由于显示中的图层减少了一个,所以最上面的图层高度下降 */ - sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, 0); - } + sheet_refreshmap(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, 0); + sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, 0, old - 1); + } } else if (old < height) { /* 比以前高 */ if (old >= 0) { /* 把中间的拉下去 */ @@ -98,7 +105,8 @@ void sheet_updown(struct SHEET *sht, int height) ctl->sheets[height] = sht; ctl->top++; /* 由于已显示的图层增加了1个,所以最上面的图层高度增加 */ } - sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height); /* 按新图层信息重新绘制画面 */ + sheet_refreshmap(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height); + sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height, height); /* 按新图层信息重新绘制画面 */ } return; } @@ -106,15 +114,15 @@ void sheet_updown(struct SHEET *sht, int height) void sheet_refresh(struct SHEET *sht, int bx0, int by0, int bx1, int by1) { if (sht->height >= 0) { /* 如果正在显示,则按新图层的信息刷新画面*/ - sheet_refreshsub(sht->ctl, sht->vx0 + bx0, sht->vy0 + by0, sht->vx0 + bx1, sht->vy0 + by1, sht->height); + sheet_refreshsub(sht->ctl, sht->vx0 + bx0, sht->vy0 + by0, sht->vx0 + bx1, sht->vy0 + by1, sht->height, sht->height); } return; } -void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0) +void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0, int h1) { int h, bx, by, vx, vy, bx0, by0, bx1, by1; - unsigned char *buf, c, *vram = ctl->vram; + unsigned char *buf, *vram = ctl->vram, *map = ctl->map, sid; struct SHEET *sht; /* 如果refresh的范围超出了画面则修正 */ @@ -126,6 +134,8 @@ void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, in for (h = h0; h <= ctl->top; h++) { sht = ctl->sheets[h]; buf = sht->buf; + sid = sht -ctl->sheets0; + /* 使用vx0~vy1,对bx0~by1进行倒推 */ bx0 = vx0 - sht->vx0; by0 = vy0 - sht->vy0; @@ -140,9 +150,8 @@ void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, in vy = sht->vy0 + by; for (bx = bx0; bx < bx1; bx++) { vx = sht->vx0 + bx; - c = buf[by * sht->bxsize + bx]; - if (c != sht->col_inv) { - vram[vy * ctl->xsize + vx] = c; + if (map[vy * ctl->xsize + vx] == sid) { + vram[vy * ctl->xsize + vx] = buf[by * sht->bxsize + bx]; } } } @@ -150,15 +159,54 @@ void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, in return; } +void sheet_refreshmap(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0) +{ + int h, bx, by, vx, vy, bx0, by0, bx1, by1; + unsigned char *buf, sid, *map = ctl->map; + struct SHEET *sht; + + if (vx0 < 0) { vx0 = 0; } + if (vy0 < 0) { vy0 = 0; } + if (vx1 > ctl->xsize) { vx1 = ctl->xsize; } + if (vy1 > ctl->ysize) { vy1 = ctl->ysize; } + + for (h = h0; h <= ctl->top; h++) { + sht = ctl->sheets[h]; + sid = sht - ctl->sheets0; /* 将进行了减法计算的地址作为图层号码使用 */ + buf = sht->buf; + bx0 = vx0 - sht->vx0; + by0 = vy0 - sht->vy0; + bx1 = vx1 - sht->vx0; + by1 = vy1 - sht->vy0; + if (bx0 < 0) { bx0 = 0; } + if (by0 < 0) { by0 = 0; } + if (bx1 > sht->bxsize) { bx1 = sht->bxsize; } + if (by1 > sht->bysize) { by1 = sht->bysize; } + + for (by = by0; by < by1; by++) { + vy = sht->vy0 + by; + for (bx = bx0; bx < bx1; bx++) { + vx = sht->vx0 + bx; + if (buf[by * sht->bxsize + bx] != sht->col_inv) { + map[vy * ctl->xsize + vx] = sid; + } + } + } + } + return; +} void sheet_slide(struct SHEET *sht, int vx0, int vy0) { + struct SHTCTL *ctl = sht->ctl; int old_vx0 = sht->vx0, old_vy0 = sht->vy0; sht->vx0 = vx0; sht->vy0 = vy0; if (sht->height >= 0) { /* 如果正在显示,则按新图层的信息刷新画面 */ - sheet_refreshsub(sht->ctl, old_vx0, old_vy0, old_vx0 + sht->bxsize, old_vy0 + sht->bysize, 0); - sheet_refreshsub(sht->ctl, vx0, vy0, vx0 + sht->bxsize, vy0 + sht->bysize, sht->height); + sheet_refreshmap(ctl, old_vx0, old_vy0, old_vx0 + sht->bxsize, old_vy0 + sht->bysize, 0); + sheet_refreshmap(ctl, vx0, vy0, vx0 + sht->bxsize, vy0 + sht->bysize, sht->height); + sheet_refreshsub(ctl, old_vx0, old_vy0, old_vx0 + sht->bxsize, old_vy0 + sht->bysize, 0, sht->height - 1); + sheet_refreshsub(ctl, vx0, vy0, vx0 + sht->bxsize, vy0 + sht->bysize, sht->height, sht->height); } return; }