@@ -12,6 +12,11 @@ struct SHTCTL *shtctl_init(struct MEMMAN *memman, unsigned char *vram, int xsize
1212 if (ctl == 0 ) {
1313 goto err ;
1414 }
15+ ctl -> map = (unsigned char * ) memman_alloc_4k (memman , xsize * ysize );
16+ if (ctl -> map == 0 ) {
17+ memman_free_4k (memman , (int ) ctl , sizeof (struct SHTCTL ));
18+ goto err ;
19+ }
1520 ctl -> vram = vram ;
1621 ctl -> xsize = xsize ;
1722 ctl -> ysize = ysize ;
@@ -60,7 +65,7 @@ void sheet_updown(struct SHEET *sht, int height)
6065 }
6166 sht -> height = height ;/* 设定高度 */
6267
63- /* 下面主要是进行sheets[ ]的重新排列 */
68+ /* 下面主要是进行sheets[]的重新排列 */
6469 if (old > height ) { /* 比以前低 */
6570 if (height >= 0 ) {
6671 /* 把中间的往上提 */
@@ -69,7 +74,8 @@ void sheet_updown(struct SHEET *sht, int height)
6974 ctl -> sheets [h ]-> height = h ;
7075 }
7176 ctl -> sheets [height ] = sht ;
72- sheet_refreshsub (ctl , sht -> vx0 , sht -> vy0 , sht -> vx0 + sht -> bxsize , sht -> vy0 + sht -> bysize , height + 1 );
77+ sheet_refreshmap (ctl , sht -> vx0 , sht -> vy0 , sht -> vx0 + sht -> bxsize , sht -> vy0 + sht -> bysize , height + 1 );
78+ sheet_refreshsub (ctl , sht -> vx0 , sht -> vy0 , sht -> vx0 + sht -> bxsize , sht -> vy0 + sht -> bysize , height + 1 , old );
7379 } else { /* 隐藏 */
7480 if (ctl -> top > old ) {
7581 /* 把上面的降下来 */
@@ -79,8 +85,9 @@ void sheet_updown(struct SHEET *sht, int height)
7985 }
8086 }
8187 ctl -> top -- ; /* 由于显示中的图层减少了一个,所以最上面的图层高度下降 */
82- sheet_refreshsub (ctl , sht -> vx0 , sht -> vy0 , sht -> vx0 + sht -> bxsize , sht -> vy0 + sht -> bysize , 0 );
83- }
88+ sheet_refreshmap (ctl , sht -> vx0 , sht -> vy0 , sht -> vx0 + sht -> bxsize , sht -> vy0 + sht -> bysize , 0 );
89+ sheet_refreshsub (ctl , sht -> vx0 , sht -> vy0 , sht -> vx0 + sht -> bxsize , sht -> vy0 + sht -> bysize , 0 , old - 1 );
90+ }
8491 } else if (old < height ) { /* 比以前高 */
8592 if (old >= 0 ) {
8693 /* 把中间的拉下去 */
@@ -98,23 +105,24 @@ void sheet_updown(struct SHEET *sht, int height)
98105 ctl -> sheets [height ] = sht ;
99106 ctl -> top ++ ; /* 由于已显示的图层增加了1个,所以最上面的图层高度增加 */
100107 }
101- sheet_refreshsub (ctl , sht -> vx0 , sht -> vy0 , sht -> vx0 + sht -> bxsize , sht -> vy0 + sht -> bysize , height ); /* 按新图层信息重新绘制画面 */
108+ sheet_refreshmap (ctl , sht -> vx0 , sht -> vy0 , sht -> vx0 + sht -> bxsize , sht -> vy0 + sht -> bysize , height );
109+ sheet_refreshsub (ctl , sht -> vx0 , sht -> vy0 , sht -> vx0 + sht -> bxsize , sht -> vy0 + sht -> bysize , height , height ); /* 按新图层信息重新绘制画面 */
102110 }
103111 return ;
104112}
105113
106114void sheet_refresh (struct SHEET * sht , int bx0 , int by0 , int bx1 , int by1 )
107115{
108116 if (sht -> height >= 0 ) { /* 如果正在显示,则按新图层的信息刷新画面*/
109- sheet_refreshsub (sht -> ctl , sht -> vx0 + bx0 , sht -> vy0 + by0 , sht -> vx0 + bx1 , sht -> vy0 + by1 , sht -> height );
117+ sheet_refreshsub (sht -> ctl , sht -> vx0 + bx0 , sht -> vy0 + by0 , sht -> vx0 + bx1 , sht -> vy0 + by1 , sht -> height , sht -> height );
110118 }
111119 return ;
112120}
113121
114- void sheet_refreshsub (struct SHTCTL * ctl , int vx0 , int vy0 , int vx1 , int vy1 , int h0 )
122+ void sheet_refreshsub (struct SHTCTL * ctl , int vx0 , int vy0 , int vx1 , int vy1 , int h0 , int h1 )
115123{
116124 int h , bx , by , vx , vy , bx0 , by0 , bx1 , by1 ;
117- unsigned char * buf , c , * vram = ctl -> vram ;
125+ unsigned char * buf , * vram = ctl -> vram , * map = ctl -> map , sid ;
118126 struct SHEET * sht ;
119127
120128 /* 如果refresh的范围超出了画面则修正 */
@@ -126,6 +134,8 @@ void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, in
126134 for (h = h0 ; h <= ctl -> top ; h ++ ) {
127135 sht = ctl -> sheets [h ];
128136 buf = sht -> buf ;
137+ sid = sht - ctl -> sheets0 ;
138+
129139 /* 使用vx0~vy1,对bx0~by1进行倒推 */
130140 bx0 = vx0 - sht -> vx0 ;
131141 by0 = vy0 - sht -> vy0 ;
@@ -140,25 +150,63 @@ void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, in
140150 vy = sht -> vy0 + by ;
141151 for (bx = bx0 ; bx < bx1 ; bx ++ ) {
142152 vx = sht -> vx0 + bx ;
143- c = buf [by * sht -> bxsize + bx ];
144- if (c != sht -> col_inv ) {
145- vram [vy * ctl -> xsize + vx ] = c ;
153+ if (map [vy * ctl -> xsize + vx ] == sid ) {
154+ vram [vy * ctl -> xsize + vx ] = buf [by * sht -> bxsize + bx ];
146155 }
147156 }
148157 }
149158 }
150159 return ;
151160}
152161
162+ void sheet_refreshmap (struct SHTCTL * ctl , int vx0 , int vy0 , int vx1 , int vy1 , int h0 )
163+ {
164+ int h , bx , by , vx , vy , bx0 , by0 , bx1 , by1 ;
165+ unsigned char * buf , sid , * map = ctl -> map ;
166+ struct SHEET * sht ;
167+
168+ if (vx0 < 0 ) { vx0 = 0 ; }
169+ if (vy0 < 0 ) { vy0 = 0 ; }
170+ if (vx1 > ctl -> xsize ) { vx1 = ctl -> xsize ; }
171+ if (vy1 > ctl -> ysize ) { vy1 = ctl -> ysize ; }
172+
173+ for (h = h0 ; h <= ctl -> top ; h ++ ) {
174+ sht = ctl -> sheets [h ];
175+ sid = sht - ctl -> sheets0 ; /* 将进行了减法计算的地址作为图层号码使用 */
176+ buf = sht -> buf ;
177+ bx0 = vx0 - sht -> vx0 ;
178+ by0 = vy0 - sht -> vy0 ;
179+ bx1 = vx1 - sht -> vx0 ;
180+ by1 = vy1 - sht -> vy0 ;
181+ if (bx0 < 0 ) { bx0 = 0 ; }
182+ if (by0 < 0 ) { by0 = 0 ; }
183+ if (bx1 > sht -> bxsize ) { bx1 = sht -> bxsize ; }
184+ if (by1 > sht -> bysize ) { by1 = sht -> bysize ; }
185+
186+ for (by = by0 ; by < by1 ; by ++ ) {
187+ vy = sht -> vy0 + by ;
188+ for (bx = bx0 ; bx < bx1 ; bx ++ ) {
189+ vx = sht -> vx0 + bx ;
190+ if (buf [by * sht -> bxsize + bx ] != sht -> col_inv ) {
191+ map [vy * ctl -> xsize + vx ] = sid ;
192+ }
193+ }
194+ }
195+ }
196+ return ;
197+ }
153198
154199void sheet_slide (struct SHEET * sht , int vx0 , int vy0 )
155200{
201+ struct SHTCTL * ctl = sht -> ctl ;
156202 int old_vx0 = sht -> vx0 , old_vy0 = sht -> vy0 ;
157203 sht -> vx0 = vx0 ;
158204 sht -> vy0 = vy0 ;
159205 if (sht -> height >= 0 ) { /* 如果正在显示,则按新图层的信息刷新画面 */
160- sheet_refreshsub (sht -> ctl , old_vx0 , old_vy0 , old_vx0 + sht -> bxsize , old_vy0 + sht -> bysize , 0 );
161- sheet_refreshsub (sht -> ctl , vx0 , vy0 , vx0 + sht -> bxsize , vy0 + sht -> bysize , sht -> height );
206+ sheet_refreshmap (ctl , old_vx0 , old_vy0 , old_vx0 + sht -> bxsize , old_vy0 + sht -> bysize , 0 );
207+ sheet_refreshmap (ctl , vx0 , vy0 , vx0 + sht -> bxsize , vy0 + sht -> bysize , sht -> height );
208+ sheet_refreshsub (ctl , old_vx0 , old_vy0 , old_vx0 + sht -> bxsize , old_vy0 + sht -> bysize , 0 , sht -> height - 1 );
209+ sheet_refreshsub (ctl , vx0 , vy0 , vx0 + sht -> bxsize , vy0 + sht -> bysize , sht -> height , sht -> height );
162210 }
163211 return ;
164212}
0 commit comments