diff --git a/src/conio/cterm.c b/src/conio/cterm.c index 5bd86cb40651276a03f43c9cc8f1cc64b8c1c68f..619068124dee0c0169611e432a5392c87e13ab72 100644 --- a/src/conio/cterm.c +++ b/src/conio/cterm.c @@ -210,9 +210,392 @@ struct note_params { #endif #ifdef CTERM_WITHOUT_CONIO -/*********************************************/ -/* These funcions are used when conio is not */ -/*********************************************/ +/***************************************************************/ +/* These funcions are used when conio is not */ +/* They are mostly copied from either ciolib.c or bitmap_con.c */ +/***************************************************************/ +#define BD ((struct buffer_data *)cterm->extra) +#define CTERM_INIT() while(BD==NULL) ciolib_init(cterm) + +struct buffer_data { + unsigned char x; + unsigned char y; + unsigned char winleft; /* left window coordinate */ + unsigned char wintop; /* top window coordinate */ + unsigned char winright; /* right window coordinate */ + unsigned char winbottom; /* bottom window coordinate */ + unsigned char attr; /* text attribute */ + unsigned char currmode; /* current video mode */ + unsigned char cursor; + unsigned char *vmem; + int vflags; +}; + +static void ciolib_init(struct cterminal *cterm) +{ + BD=malloc(sizeof(struct buffer_data)); + if(!BD) + return + BD->x=1; + BD->y=1; + BD->winleft=1; + BD->wintop=1; + BD->winright=cterm->width; + BD->winbottom=cterm->height; + BD->attr=7; + BD->currmode=C80; // TODO: Adjust based on size... + BD->cursor=_NORMALCURSOR; + BD->vmem=malloc(2*cterm->height*cterm->width); + if(BD->vmem==NULL) { + free(BD) + return; + } + BD->vflags=0; +} + +static void ciolib_gotoxy(struct cterminal *cterm,int x,int y) +{ + CTERM_INIT(); + + if(x < 1 + || x > BD->winright-BD->winleft+1 + || y < 1 + || y > BD->winbottom-BD->wintop+1) + return; + + BD->x=x; + BD->y=y; +} + +static int ciolib_wherex(struct cterminal *cterm) +{ + CTERM_INIT(); + return BD->x +} + +static int ciolib_wherey(struct cterminal *cterm) +{ + CTERM_INIT(); + return BD->y +} + +static int ciolib_gettext(struct cterminal *cterm,int sx, int sy, int ex, int ey, void *fill) +{ + int x,y; + unsigned char *out; + WORD sch; + + CTERM_INIT(); + if( sx < 1 + || sy < 1 + || ex < 1 + || ey < 1 + || sx > ex + || sy > ey + || ex > cterm->width + || ey > cterm->height + || fill==NULL) + return(0); + + out=fill; + for(y=sy-1;y<ey;y++) { + for(x=sx-1;x<ex;x++) { + sch=BD->vmem[y*cio_textinfo.screenwidth+x]; + *(out++)=sch & 0xff; + *(out++)=sch >> 8; + } + } + return(1); +} + +static void ciolib_gettextinfo(struct cterminal *cterm,struct text_info *ti) +{ + CTERM_INIT(); + ti->winleft=>BD->winleft; + ti->wintop=BD->wintop; + ti->winright=BD->winright; + ti->winbottom=BD->winbottom; + ti->attribute=BD->attr; + ti->normattr=7; + ti->currmode=BD->currmode; + ti->screenheight=cterm->height; + ti->screenwidth=cterm->width; + ti->curx=BD->x; + ti->cury=BD->y; +} + +static void ciolib_textattr(struct cterminal *cterm,int attr) +{ + CTERM_INIT(); + BD->attr=attr; +} + +static void ciolib_setcursortype(struct cterminal *cterm,int cursor) +{ + CTERM_INIT(); + BD->cursor=cursor; +} + +static int ciolib_movetext(struct cterminal *cterm, int x, int y, int ex, int ey, int tox, int toy) +{ + int direction=1; + int cy; + int sy; + int destoffset; + int sourcepos; + int width=ex-x+1; + int height=ey-y+1; + + CTERM_INIT(); + if( x<1 + || y<1 + || ex<1 + || ey<1 + || tox<1 + || toy<1 + || x>cterm->width + || ex>cterm->width + || tox>cterm->width + || y>cterm->height + || ey>cterm->height + || toy>cterm->height) + return(0); + + if(toy > y) + direction=-1; + + sourcepos=(y-1)*cterm->width+(x-1); + destoffset=(((toy-1)*cterm->width+(tox-1))-sourcepos); + + for(cy=(direction==-1?(height-1):0); cy<height && cy>=0; cy+=direction) { + sourcepos=((y-1)+cy)*cio_textinfo.screenwidth+(x-1); + memmove(&(BD->vmem[sourcepos+destoffset]), &(BD->vmem[sourcepos]), sizeof(BD->vmem[0])*width); + } + return(1); +} + +static void conio_clreol(struct cterminal *cterm) +{ + int pos,x; + WORD fill=(BD->attr<<8)|space; + + CTERM_INIT(); + pos=(BD->y+BD->wintop-2)*cterm->width; + for(x=BD->x+BD->winleft-2; x<BD->right; x++) + BD->vmem[pos+x]=fill; +} + +static void ciolib_clrscr(struct cterminal *cterm) +{ + int x,y; + WORD fill=(BD->attr<<8)|space; + + CTERM_INIT(); + for(y=cio_textinfo.wintop-1; y<cio_textinfo.winbottom; y++) { + for(x=BD->winleft-1; x<BD->winright; x++) + BD->vmem[y*cterm->width+x]=fill; + } +} + +static void ciolib_setvideoflags(struct cterminal *cterm, int flags) +{ + CTERM_INIT(); + BD->vflags=flags; +} + +static int ciolib_getvideoflags(struct cterminal *cterm) +{ + CTERM_INIT(); + return BD->vflags; +} + +static void ciolib_wscroll(struct cterminal *cterm) +{ + int os; + + CTERM_INIT(); + MOVETEXT(BD->winleft + ,BD->wintop+1 + ,BD->winright + ,BD->winbottom + ,BD->winleft + ,BD->wintop); + GOTOXY(cterm, 1,BD->winbottom-BD->wintop+1); + os=_wscroll; + _wscroll=0; + CLREOL(cterm); + _wscroll=os; + GOTOXY(cterm, BD->x,BD->y); +} + +static int ciolib_putch(struct cterminal *cterm,int a) +{ + unsigned char a1=a; + unsigned char buf[2]; + int i; + + CTERM_INIT(); + buf[0]=a1; + buf[1]=BD->attr; + + switch(a1) { + case '\r': + GOTOXY(1,cio_textinfo.cury); + break; + case '\n': + if(BD->y==BD->winbottom-BD->wintop+1) + ciolib_wscroll(cterm); + else + GOTOXY(BD->x, BD->y+1); + break; + case '\b': + if(BD->x>1) { + GOTOXY(BD->x-1,BD->y); + buf[0]=' '; + PUTTEXT(BD->x+BD->winleft-1 + ,BD->y+BD->wintop-1 + ,BD->x+BD->winleft-1 + ,BD->y+BD->wintop-1 + ,buf); + } + break; + case 7: /* Bell */ + break; + case '\t': + for(i=0;i<(sizeof(cterm_tabs)/sizeof(int));i++) { + if(cterm_tabs[i]>BD->x) { + buf[0]=' '; + while(BD->x<cterm_tabs[i]) { + PUTTEXT(BD->x+BD->winleft-1 + ,BD->y+BD->wintop-1 + ,BD->x+BD->winleft-1 + ,BD->y+BD->wintop-1 + ,buf); + GOTOXY(BD->x+1,BD->y); + if(BD->x==cterm->width) + break; + } + break; + } + } + if(BD->x==cterm->width) { + GOTOXY(1,BD->y); + if(BD->y==BD->winbottom-BD->wintop+1) + ciolib_wscroll(cterm); + else + GOTOXY(BD->x, BD->y+1); + } + break; + default: + if(BD->y==BD->winbottom-BD->wintop+1 + && BD->x==BD->winright-BD->winleft+1) { + PUTTEXT(WHEREX()+BD->winleft-1 + ,WHEREY()+BD->wintop-1 + ,WHEREX()+BD->winleft-1 + ,WHEREY()+BD->wintop-1 + ,buf); + ciolib_wscroll(cterm); + GOTOXY(1, BD->winbottom-BD->wintop+1); + } + else { + if(BD->x==BD->winright-BD->winleft+1) { + PUTTEXT(WHEREX()+BD->winleft-1 + ,WHEREY()+BD->wintop-1 + ,WHEREX()+BD->winleft-1 + ,WHEREY()+BD->wintop-1 + ,buf); + GOTOXY(1,BD->y+1); + } + else { + PUTTEXT(WHEREX()+BD->winleft-1 + ,WHEREY()+BD->wintop-1 + ,WHEREX()+BD->winleft-1 + ,WHEREY()+BD->wintop-1 + ,buf); + GOTOXY(BD->x+1, BD->y); + } + } + break; + } + + return(a1); +} + +static int ciolib_puttext(struct cterminal *cterm,int sx, int sy, int ex, int ey, void *fill) +{ + int x,y; + unsigned char *out; + WORD sch; + + CTERM_INIT(); + if( sx < 1 + || sy < 1 + || ex < 1 + || ey < 1 + || sx > cterm->width + || sy > cterm->height + || sx > ex + || sy > ey + || ex > cterm->width + || ey > cterm->height + || fill==NULL) + return(0); + + out=fill; + for(y=sy-1;y<ey;y++) { + for(x=sx-1;x<ex;x++) { + sch=*(out++); + sch |= (*(out++))<<8; + BD->vmem[y*cterm->width+x]=sch; + } + } + return(1); +} + +static void ciolib_window(struct cterminal *cterm,int sx, int sy, int ex, int ey) +{ + CTERM_INIT(); + if( sx < 1 + || sy < 1 + || ex < 1 + || ey < 1 + || sx > cterm->width + || sy > cterm->height + || sx > ex + || sy > ey + || ex > cterm->width + || ey > cterm->height) + return; + BD->winleft=sx; + BD->wintop=sy; + BD->winright=ex; + BD->winbottom=ey; + GOTOXY(1,1); +} + +static int ciolib_cputs(struct cterminal *cterm, char *str) +{ + int pos; + int ret=0; + int olddmc; + + CTERM_INIT(); + for(pos=0;str[pos];pos++) + { + ret=str[pos]; + if(str[pos]=='\n') + PUTCH('\r'); + PUTCH(str[pos]); + } + GOTOXY(WHEREX(),WHEREY()); + return(ret); +} + +static int ciolib_setfont(struct cterminal *,int font, int force, int font_num) +{ + CTERM_INIT(); + return -1; +} #endif static void playnote_thread(void *args) @@ -2156,7 +2539,10 @@ void cterm_end(struct cterminal *cterm) int i; cterm_closelog(cterm); -#ifndef CTERM_WITHOUT_CONIO +#ifdef CTERM_WITHOUT_CONIO + FREE_AND_NULL(BD->vmem); + FREE_AND_NULL(BD); +#else for(i=CONIO_FIRST_FREE_FONT; i < 256; i++) { FREE_AND_NULL(conio_fontdata[i].eight_by_sixteen); FREE_AND_NULL(conio_fontdata[i].eight_by_fourteen); diff --git a/src/conio/cterm.h b/src/conio/cterm.h index 8be56ba31d014ef7e5f7c28b74ae4e70134ab375..5d7e41f17ed43ef6dcd7c9b08afde7665df70456 100644 --- a/src/conio/cterm.h +++ b/src/conio/cterm.h @@ -137,21 +137,22 @@ struct cterminal { int (*ciolib_gettext) (int,int,int,int,unsigned char *); void (*ciolib_gettextinfo) (struct text_info *); void (*ciolib_textattr) (int); - void (*ciolib_setcursortype)(int); + void (*ciolib_setcursortype) (int); int (*ciolib_movetext) (int,int,int,int,int,int); void (*ciolib_clreol) (void); void (*ciolib_clrscr) (void); - void (*ciolib_setvideoflags)(int flags); - int (*ciolib_getvideoflags)(void); - int (*ciolib_putch) (int); + void (*ciolib_setvideoflags) (int flags); + int (*ciolib_getvideoflags) (void); + int (*ciolib_putch) (int); int (*ciolib_puttext) (int,int,int,int,unsigned char *); void (*ciolib_window) (int,int,int,int); - int (*ciolib_cputs) (char *); + int (*ciolib_cputs) (char *); int (*ciolib_setfont) (int font, int force, int font_num); #endif int *_wscroll; int *puttext_can_move; int *hold_update; + void *extra; }; #ifdef __cplusplus