From b55a8413973131b325e3c0a615ef98cadd1f225e Mon Sep 17 00:00:00 2001
From: Yourtion <yourtion@gmail.com>
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;
 }