上节实现了一个简单的消息框输出字符串显示功能,但是对图层的刷新还存在可以优化的地方,尤其是在快速变化字符时将会出现图层闪烁的问题。
快速显示字符串到指定图层上时没有必要在刷新图层遮住的窗体,只需要刷新窗体和该窗体之后的窗体。
1.win_sheet.c
修改sheet_refreshRect,增加sht图层窗口,表示刷新该图层及其该图层之后的窗体。
void sheet_refreshRect(SHTCTL *ctl,SHEET *sht,int x,int y,int width,int height){
unsigned char *vram = ctl->vram;
for(int h=sht->weight;h<=ctl->top;h++){
SHEET *sht = ctl->sheets[h];
//获取最大的原点
int x0 = x > sht->x ? x : sht->x;
int y0 = y > sht->y ? y : sht->y;
//获取右下角最小坐标
int x2 = x+width < sht->x+sht->width ? x+width : sht->x+sht->width;
int y2 = y+height < sht->y+sht->height ? y+height : sht->y+sht->height;
if(x2y)*sht->width+(j-sht->x);
char val = sht->buf[off];
if(val != sht->col_inv){
vram[i*ctl->xsize+j] = val;
}
}
}
}
}
2.os.c
增加字符显示输出背景色参数,防止下次字符显示时图层缓存区中该区域有垃圾数据。
void putChar(unsigned char *addr,int x,int y,unsigned char col,unsigned char bc,unsigned char ch,int winW){
unsigned char *pch = _ascii+(ch-0x20)*16;
for(int i=0;i<16;i++){
unsigned char temp = pch[i];
int off = (y+i)*winW;
//显示的字形最左边的是低地址,右侧的是高地址。例如:0x80,则高地址部分显示在内存的低地址,
//最低位的应该偏移7
//else为了消除该像素点上一次的颜色,填充为透明色
if((temp & 0x01) != 0){
addr[off+x+7] = col;
}
else{
addr[off+x+7] = bc;
}
if((temp & 0x02) != 0){
addr[off+x+6] = col;
}
else{
addr[off+x+6] = bc;
}
if((temp & 0x04) != 0){
addr[off+x+5] = col;
}
else{
addr[off+x+5] = bc;
}
if((temp & 0x08) != 0){
addr[off+x+4] = col;
}
else{
addr[off+x+4] = bc;
}
if((temp & 0x10) != 0){
addr[off+x+3] = col;
}
else{
addr[off+x+3] = bc;
}
if((temp & 0x20) != 0){
addr[off+x+2] = col;
}
else{
addr[off+x+2] = bc;
}
if((temp & 0x40) != 0){
addr[off+x+1] = col;
}
else{
addr[off+x+1] = bc;
}
if((temp & 0x80) != 0){
addr[off+x+0] = col;
}
else{
addr[off+x+0] = bc;
}
}
}
修改showString增加字符串显示的背景色
void showString(SHTCTL *shtctl,SHEET *sht, int x, int y,unsigned char col,unsigned char bc,char *str){
int offX = x,offY = y;
for(int i=0;str[i] != 0;i++){
if(offX>sht->width-8){
offX = 0;
offY += 16;
}
putChar(sht->buf,offX,offY,col,bc,str[i],sht->width);
offX += 8;
}
sheet_refreshRect(shtctl,sht,sht->x,sht->y+y,sht->width,offY-y+16);
}
runloop函数实现持续输出
static void runloop(){
AddrRangeDes *memDes = (AddrRangeDes *)mem_block_buf();
int memCount = mem_block_count();
int memId = -1;
int index = 0;
for(; ;){
if(_keybufInfo.len>0){
io_cli();
int len = _keybufInfo.len;
for(int t=0;t0){
io_cli();
int len = _mousebufInfo.len;
mouseCursorMoved(&_mouseDes,COLOR_INVISIBLE);
io_sti();
}
else{
index++;
int len = 0;
_tempArr[len++] = '0';
_tempArr[len++] = 'x';
for(int j=0;j<4;j++){
int temp = char2HexStr(((char *)&index)[3-j]);
_tempArr[len++] = ((char *)&temp)[0];
_tempArr[len++] = ((char *)&temp)[1];
}
_tempArr[len] = 0;
showString(_shtctl,_shtMsg,10,54,COL8_FFFFFF,COL8_C6C6C6,_tempArr);
}
}
}