-
Notifications
You must be signed in to change notification settings - Fork 0
/
消除图层刷新10.txt
227 lines (195 loc) · 7.9 KB
/
消除图层刷新10.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
在刷新Box窗体时,也同时在刷新底层桌面
一个窗体,它的高度是10,那么它刷新时,高度为0到9的窗体根本不需要跟着刷新
否则产生闪烁
win_sheet.c中更改
sheet_refreshsub 是用来刷新图层的,这次改动就增加了一个参数h0, 这个h0就表示当前要刷新的图层的高度
在for 循环不再从0开始,而是从h0开始,也就是从当前图层的高度往上进行刷新
void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0) {
....
for (h = h0; h <= ctl->top; h++) {
.....
}
.....
}
其它调用了它的函数也要做更改,在调用sheet_refreshsub的时候多添加一个参数
int sheet_refresh(struct SHTCTL *ctl, struct SHEET *sht, int bx0, int by0, int bx1, int by1) {
if (sht->height >= 0) {
//多添加一个图层高度的参数
sheet_refreshsub(ctl, sht->vx0 + bx0, sht->vy0 + by0, sht->vx0 + bx1,
sht->vy0 + by1, sht->height);
}
return 0;
}
void sheet_slide(struct SHTCTL *ctl, struct SHEET *sht, int vx0, int vy0) {
int old_vx0 = sht->vx0, old_vy0 = sht->vy0;
sht->vx0 = vx0;
sht->vy0 = vy0;
if (sht->height >= 0) {
sheet_refreshsub(ctl, old_vx0, old_vy0, old_vx0 + sht->bxsize, old_vy0 + sht->bysize, 0);
sheet_refreshsub(ctl, vx0, vy0, vx0+sht->bxsize, vy0+sht->bysize, sht->height);
}
}
void sheet_slide(struct SHTCTL *ctl, struct SHEET *sht, int vx0, int vy0) {
int old_vx0 = sht->vx0, old_vy0 = sht->vy0;
sht->vx0 = vx0;
sht->vy0 = vy0;
if (sht->height >= 0) {
//多添加一个图层高度的参数
sheet_refreshsub(ctl, old_vx0, old_vy0, old_vx0 + sht->bxsize, old_vy0 + sht->bysize, 0);
sheet_refreshsub(ctl, vx0, vy0, vx0+sht->bxsize, vy0+sht->bysize, sht->height);
}
}
void sheet_updown(struct SHTCTL *ctl, struct SHEET *sht, int height) {
....
if (old > height) {
....
if (height >= 0) {
.....
//多添加一个图层高度的参数
sheet_refreshsub(ctl, sht->vx0, sht->vy0,
sht->vx0+sht->bxsize, sht->vy0+sht->bysize, height+1);
}
} else {
....
//多添加一个图层高度的参数
sheet_refreshsub(ctl, sht->vx0, sht->vy0,
sht->vx0+sht->bxsize, sht->vy0+sht->bysize,0);
}
else {
....
//多添加一个图层高度的参数
sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0+sht->bxsize, sht->vy0+sht->bysize,
height);
}
}
解决了普通图层的闪烁问题,当鼠标放置图层上,鼠标疯狂闪烁
鼠标图层比Message Box 高,当鼠标与Box重叠时,Box的刷新会导致鼠标的刷新
窗体自身刷新时,它会把处于它上方的窗体也进行刷新,这是没必要的
刷新方法更改,只更改与上层图层不重叠的区域。
// 增加map变量,记录图层每一个像素点所对应的窗体编号
struct SHTCTL {
unsigned char *vram, *map;
int xsize, ysize, top;
struct SHEET *sheets[MAX_SHEETS];
struct SHEET sheets0[MAX_SHEETS];
};
struct SHTCTL *shtctl_init(struct MEMMAN *memman, unsigned char *vram,
int xsize, int ysize) {
....
//为图层像素编号数值分配内存
ctl->map = (unsigned char*)memman_alloc_4k(memman, xsize * ysize);
if (ctl->map == 0) {
memman_free_4k(memman, (int)ctl, SIZE_OF_SHTCTL);
return 0;
}
.....
}
// 将图层对象在这个数值中的下标作为它的窗体编号
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变量里
map[vy * ctl->xsize + vx] = sid;
}
}
}
}
return;
}
用来设置像素对应的图层编号,
假如窗口1的某个像素位于坐标(20, 30),map[30*xsize + 20]=1
窗口2移动后,有像素点也移动到了坐标(20,30),map[30*xsize + 20]=2
像素所在位置对应的窗口号,就可以只刷新对应窗口的像素点
void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0, int h1) {
int h, bx, by, vx, vy;
unsigned char *buf, c, *vram = ctl->vram, *map = ctl->map, sid;
struct SHEET *sht;
if (vx0 < 0) {vx0 = 0;}
if (vy0 < 9) {vy0 = 0;}
if (vx1 > ctl->xsize) {vx1 = ctl->xsize;}
if (vy1 > ctl->ysize) {vy1 = ctl->ysize;}
for (h = h0; h <= h1; h++) {
sht = ctl->sheets[h];
buf = sht->buf;
//获得当前图层对应的窗口号
sid = sht - ctl->sheets0;
for (by = 0; by < sht->bysize; by++) {
vy = sht->vy0 + by;
for (bx = 0; bx < sht->bxsize; bx++) {
vx = sht->vx0 + bx;
if (vx0 <= vx && vx < vx1 && vy0 <= vy && vy < vy1) {
c = buf[by * sht->bxsize + bx];
//确定当前坐标对应的素点是否属于要刷新的窗口
if (map[vy * ctl->xsize + vx] == sid && c != sht->col_inv) {
vram[vy * ctl->xsize + vx] = c;
}
}
}
}
}
}
其他对应的图层刷新函数也做相应改动:
void sheet_slide(struct SHTCTL *ctl, struct SHEET *sht, int vx0, int vy0) {
int old_vx0 = sht->vx0, old_vy0 = sht->vy0;
sht->vx0 = vx0;
sht->vy0 = vy0;
if (sht->height >= 0) {
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);
}
}
void sheet_updown(struct SHTCTL *ctl, struct SHEET *sht, int height) {
....
if (old > height) {
....
if (height >= 0) {
....
//窗体高度更新后,要更改像素点所在位置的窗体标号
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 {
....
//窗体高度更新后,要更改像素点所在位置的窗体标号
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 {
....
//窗体高度更新后,要更改像素点所在位置的窗体标号
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);
}
}