Skip to content
Snippets Groups Projects
Commit 4e6bdc70 authored by deuce's avatar deuce
Browse files

Add thread-safe buffer functions

parent 1d08b781
No related branches found
No related tags found
No related merge requests found
......@@ -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);
......
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment