From c9bc4bc9bf4b4a9c9192cdca34c7d4815487e967 Mon Sep 17 00:00:00 2001 From: deuce <> Date: Sat, 4 Feb 2006 22:12:42 +0000 Subject: [PATCH] Do cleareol and clearscreen optimizations. List the scroll optimzation is left. --- src/conio/ansi_cio.c | 117 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 99 insertions(+), 18 deletions(-) diff --git a/src/conio/ansi_cio.c b/src/conio/ansi_cio.c index a50a664a73..26a621e880 100644 --- a/src/conio/ansi_cio.c +++ b/src/conio/ansi_cio.c @@ -217,6 +217,7 @@ void ansi_sendstr(char *str,int len) int ansi_puttext(int sx, int sy, int ex, int ey, void* buf) { int x,y; + int cx,cy,i,j; unsigned char *out; WORD sch; struct text_info ti; @@ -240,25 +241,103 @@ int ansi_puttext(int sx, int sy, int ex, int ey, void* buf) out=fill; attrib=ti.attribute; - for(y=sy-1;y<ey;y++) { - for(x=sx-1;x<ex;x++) { - sch=*(out++); - if(sch==27) - sch=' '; - if(sch==0) - sch=' '; - sch |= (*(out++))<<8; - if(ansivmem[y*ansi_cols+x]==sch) - continue; - ansivmem[y*ansi_cols+x]=sch; - ansi_gotoxy(x+1,y+1); - if(y>=ansi_rows-1 && x>=ansi_cols-1) - continue; - if(attrib!=sch>>8) { - textattr(sch>>8); - attrib=sch>>8; + + i=0; /* Did a nasty. */ + /* Check if this is a nasty scroll */ + + /* Check if this is a nasty screen clear... */ + j=0; /* We can clearscreen */ + if(sx==1 && sy==1 && ex==ti.screenwidth && ey==ti.screenheight && (*out==' ' || *out==0)) { + j=1; /* We can clearscreen */ + for(cy=sy-1;cy<ey;cy++) { + for(cx=sx-1;cx<ex;cx++) { + if(out[(cy*ti.screenwidth+cx)*2]!=*out + || out[(cy*ti.screenwidth+cx)*2+1]!=*(out+1)) { + j=0; + cx=ex; + cy=ey; + } + } + } + } + if(j) { + textattr(*(out+1)); + /* Many terminals make ESC[2J home the cursor */ + ansi_sendstr("\033[2J\033[1;1H",-1); + ansi_col=0; + ansi_row=0; + memcpy(ansivmem,out,ti.screenwidth*ti.screenheight*2); + i=1; + } + if(!i) { + for(y=sy-1;y<ey;y++) { + for(x=sx-1;x<ex;x++) { + /* + * Check if we can use clear2eol now... this means the rest of the + * chars on the line are the same attr, and are all spaces or NULLs + * Also, if there's less than four chars left, it's not worth it. + */ + i=0; /* number of differing chars from screen */ + j=1; /* Can use clrtoeol? */ + for(cx=x; cx<ti.screenwidth; cx++) { + /* Compare to source buffer */ + if(cx<ex) { + /* a blank? */ + if(*(out+(cx-x)*2)==' ' || *(out+(cx-x)*2)==0) { + /* same colour? */ + if(*(out+(cx-x)*2+1)==*(out+1)) { + /* Is it any change? */ + if(*((WORD *)(out+(cx-x)*2)) != ansivmem[y*2+cx]) + /* And it's different! */ + i++; + } + else { + j=0; + break; + } + } + else { + j=0; + break; + } + } + else { + /* Compare to screen */ + /* a blank? */ + if((ansivmem[y*2+cx]&0xff)!=' ' && (ansivmem[y*2+cx]&0xff)!=0) { + j=0; + break; + } + } + } + if(j && i>3) { + ansi_gotoxy(x+1,y+1); + textattr(*(out+1)); + ansi_sendstr("\033[K",-1); + for(cx=x; cx<ex; cx++) { + ansivmem[y*ansi_cols+cx]=*(out++); + ansivmem[y*ansi_cols+cx]|=(*(out++))<<8; + } + break; + } + sch=*(out++); + if(sch==27) + sch=' '; + if(sch==0) + sch=' '; + sch |= (*(out++))<<8; + if(ansivmem[y*ansi_cols+x]==sch) + continue; + ansivmem[y*ansi_cols+x]=sch; + ansi_gotoxy(x+1,y+1); + if(y>=ansi_rows-1 && x>=ansi_cols-1) + continue; + if(attrib!=sch>>8) { + textattr(sch>>8); + attrib=sch>>8; + } + ansi_sendch((char)(sch&0xff)); } - ansi_sendch((char)(sch&0xff)); } } @@ -611,6 +690,8 @@ void ansi_gotoxy(int x, int y) || y > ansi_rows) return; + /* ToDo optimizations: use tabs for horizontal movement to tabstops */ + /* Movement forced... always send position code */ if(force_move) { sprintf(str,"\033[%d;%dH",y,x); -- GitLab