Commit e44ec674 authored by deuce's avatar deuce
Browse files

Various changes around more EGA/VGA capabilities, specifically:

1) The ability to make attribute bit three select a second character set
2) The ability to make the blink attribute toggle background intensity
3) The ability to make attribute bit three NOT select high intensity
4) More control over the cursor than just three constants

CTerm support to follow using private set mode parameters.
parent 33c90c56
......@@ -31,6 +31,7 @@ int screenheight=0;
#define PIXEL_OFFSET(x,y) ( (y)*screenwidth+(x) )
static int current_font=-99;
static int current_secondary_font=-99;
static int bitmap_initialized=0;
struct video_stats vstat;
static int *damaged=NULL;
......@@ -44,6 +45,7 @@ pthread_mutex_t vstatlock;
pthread_mutex_t screenlock;
static struct bitmap_callbacks callbacks;
static unsigned char *font;
static unsigned char *secondary_font;
static unsigned char space=' ';
int force_redraws=0;
......@@ -214,6 +216,42 @@ end:
/* Called from main thread only (Passes Event) */
void bitmap_getcustomcursor(int *s, int *e, int *r, int *b, int *v)
{
pthread_mutex_lock(&vstatlock);
if(s)
*s=vstat.curs_start;
if(e)
*e=vstat.curs_end;
if(r)
*r=vstat.charheight;
if(b)
*b=vstat.curs_blink;
if(v)
*v=vstat.curs_visible;
pthread_mutex_unlock(&vstatlock);
}
void bitmap_setcustomcursor(int s, int e, int r, int b, int v)
{
double ratio;
pthread_mutex_lock(&vstatlock);
if(r==0)
ratio=0;
else
ratio=vstat.charheight/r;
if(s>=0)
vstat.curs_start=s*ratio;
if(e>=0)
vstat.curs_end=e*ratio;
if(b>=0)
vstat.curs_blink=b;
if(v>=0)
vstat.curs_visible=v;
pthread_mutex_unlock(&vstatlock);
}
int bitmap_movetext(int x, int y, int ex, int ey, int tox, int toy)
{
int direction=1;
......@@ -373,7 +411,7 @@ void bitmap_setcursortype(int type)
pthread_mutex_unlock(&vstatlock);
}
int bitmap_setfont(int font, int force)
int bitmap_setfont(int font, int force, int font_num)
{
int changemode=0;
int newmode=-1;
......@@ -425,13 +463,19 @@ int bitmap_setfont(int font, int force)
}
break;
}
if(changemode && newmode==-1)
if(changemode && (newmode==-1 || font_num!=0))
goto error_return;
current_font=font;
if(font==36 /* ATARI */)
space=0;
else
space=' ';
switch(font_num) {
case 0:
current_font=font;
if(font==36 /* ATARI */)
space=0;
else
space=' ';
break;
case 1:
current_secondary_font=font;
}
pthread_mutex_unlock(&vstatlock);
if(changemode) {
......@@ -517,6 +561,13 @@ int bitmap_loadfont(char *filename)
else if(conio_fontdata[current_font].desc==NULL)
return(-1);
if(current_secondary_font==-99)
current_secondary_font=current_font;
if(current_secondary_font==-1)
;
else if(conio_fontdata[current_secondary_font].desc==NULL)
current_secondary_font=current_font;
pthread_mutex_lock(&vstatlock);
fh=vstat.charheight;
fw=vstat.charwidth/8+(vstat.charwidth%8?1:0);
......@@ -525,8 +576,12 @@ int bitmap_loadfont(char *filename)
if(font)
FREE_AND_NULL(font);
if(secondary_font)
FREE_AND_NULL(secondary_font);
if((font=(unsigned char *)malloc(fontsize))==NULL)
goto error_return;
if((secondary_font=(unsigned char *)malloc(fontsize))==NULL)
goto error_return;
if(filename != NULL) {
if(flength(filename)!=fontsize)
......@@ -540,25 +595,51 @@ int bitmap_loadfont(char *filename)
current_font=-1;
if(filename != current_filename)
SAFECOPY(current_filename,filename);
if(current_secondary_font==-1)
memcpy(secondary_font, font, fontsize);
}
else {
if(current_font != -1 || secondary_font != -1) {
switch(vstat.charwidth) {
case 8:
switch(vstat.charheight) {
case 8:
if(conio_fontdata[current_font].eight_by_eight==NULL)
goto error_return;
memcpy(font, conio_fontdata[current_font].eight_by_eight, fontsize);
if(current_font != -1) {
if(conio_fontdata[current_font].eight_by_eight==NULL)
goto error_return;
memcpy(font, conio_fontdata[current_font].eight_by_eight, fontsize);
}
if(secondary_font != -1) {
if(conio_fontdata[current_secondary_font].eight_by_eight==NULL)
FREE_AND_NULL(secondary_font);
else
memcpy(font, conio_fontdata[current_secondary_font].eight_by_eight, fontsize);
}
break;
case 14:
if(conio_fontdata[current_font].eight_by_fourteen==NULL)
goto error_return;
memcpy(font, conio_fontdata[current_font].eight_by_fourteen, fontsize);
if(current_font != -1) {
if(conio_fontdata[current_font].eight_by_fourteen==NULL)
goto error_return;
memcpy(font, conio_fontdata[current_font].eight_by_fourteen, fontsize);
}
if(secondary_font != -1) {
if(conio_fontdata[current_secondary_font].eight_by_fourteen==NULL)
FREE_AND_NULL(secondary_font);
else
memcpy(font, conio_fontdata[current_secondary_font].eight_by_fourteen, fontsize);
}
break;
case 16:
if(conio_fontdata[current_font].eight_by_sixteen==NULL)
goto error_return;
memcpy(font, conio_fontdata[current_font].eight_by_sixteen, fontsize);
if(current_font != -1) {
if(conio_fontdata[current_font].eight_by_sixteen==NULL)
goto error_return;
memcpy(font, conio_fontdata[current_font].eight_by_sixteen, fontsize);
}
if(secondary_font != -1) {
if(conio_fontdata[current_secondary_font].eight_by_sixteen==NULL)
FREE_AND_NULL(secondary_font);
else
memcpy(font, conio_fontdata[current_secondary_font].eight_by_sixteen, fontsize);
}
break;
default:
goto error_return;
......@@ -575,6 +656,7 @@ int bitmap_loadfont(char *filename)
error_return:
FREE_AND_NULL(font);
FREE_AND_NULL(secondary_font);
if(fontfile)
fclose(fontfile);
pthread_mutex_unlock(&vstatlock);
......@@ -593,26 +675,28 @@ static void bitmap_draw_cursor()
if(!bitmap_initialized)
return;
if(vstat.blink) {
if(vstat.curs_start<=vstat.curs_end) {
xoffset=(vstat.curs_col-1)*vstat.charwidth;
yoffset=(vstat.curs_row-1)*vstat.charheight;
if(xoffset < 0 || yoffset < 0)
return;
attr=cio_textinfo.attribute&0x0f;
width=vstat.charwidth;
pthread_mutex_lock(&screenlock);
for(y=vstat.curs_start; y<=vstat.curs_end; y++) {
if(xoffset < screenwidth && (yoffset+y) < screenheight) {
pixel=PIXEL_OFFSET(xoffset, yoffset+y);
for(x=0;x<vstat.charwidth;x++)
screen[pixel++]=attr;
//memset(screen+pixel,attr,width);
if(vstat.curs_visible) {
if(vstat.blink || (!vstat.curs_blink)) {
if(vstat.curs_start<=vstat.curs_end) {
xoffset=(vstat.curs_col-1)*vstat.charwidth;
yoffset=(vstat.curs_row-1)*vstat.charheight;
if(xoffset < 0 || yoffset < 0)
return;
attr=cio_textinfo.attribute&0x0f;
width=vstat.charwidth;
pthread_mutex_lock(&screenlock);
for(y=vstat.curs_start; y<=vstat.curs_end; y++) {
if(xoffset < screenwidth && (yoffset+y) < screenheight) {
pixel=PIXEL_OFFSET(xoffset, yoffset+y);
for(x=0;x<vstat.charwidth;x++)
screen[pixel++]=attr;
//memset(screen+pixel,attr,width);
}
}
pthread_mutex_unlock(&screenlock);
send_rectangle(xoffset, yoffset+vstat.curs_start, vstat.charwidth, vstat.curs_end-vstat.curs_start+1,FALSE);
}
pthread_mutex_unlock(&screenlock);
send_rectangle(xoffset, yoffset+vstat.curs_start, vstat.charwidth, vstat.curs_end-vstat.curs_start+1,FALSE);
}
}
}
......@@ -644,6 +728,7 @@ static int bitmap_draw_one_char(unsigned int xpos, unsigned int ypos)
int x;
int y;
int fontoffset;
unsigned char *this_font;
WORD sch;
if(!bitmap_initialized)
......@@ -659,18 +744,35 @@ static int bitmap_draw_one_char(unsigned int xpos, unsigned int ypos)
return(-1);
sch=vstat.vmem[(ypos-1)*cio_textinfo.screenwidth+(xpos-1)];
bg=(sch&0x7000)>>12;
if(sch&0x8000 && vstat.blink)
fg=bg;
else
if(vstat.bright_background) {
bg=(sch&0xf000)>>12;
fg=(sch&0x0f00)>>8;
}
else {
bg=(sch&0x7000)>>12;
if(sch&0x8000 && vstat.blink)
fg=bg;
else
fg=(sch&0x0f00)>>8;
}
this_font=font;
if(vstat.bright_altcharset) {
if(fg & 0x80) {
this_font=secondary_font;
if(this_font==NULL)
this_font=font;
}
}
if(vstat.no_bright)
fg &= 0x07;
fontoffset=(sch&0xff)*vstat.charheight;
pthread_mutex_lock(&screenlock);
for(y=0; y<vstat.charheight; y++) {
memset(&screen[PIXEL_OFFSET(xoffset, yoffset+y)],bg,vstat.charwidth);
for(x=0; x<vstat.charwidth; x++) {
if(font[fontoffset] & (0x80 >> x))
if(this_font[fontoffset] & (0x80 >> x))
screen[PIXEL_OFFSET(xoffset+x, yoffset+y)]=fg;
}
fontoffset++;
......
......@@ -24,5 +24,7 @@ int bitmap_init(void (*drawrect_cb) (int xpos, int ypos, int width, int height,
int bitmap_movetext(int x, int y, int ex, int ey, int tox, int toy);
void bitmap_clreol(void);
void bitmap_clrscr(void);
void bitmap_getcustomcursor(int *s, int *e, int *r, int *b, int *v);
void bitmap_setcustomcursor(int s, int e, int r, int b, int v);
#endif
......@@ -131,6 +131,8 @@ int try_sdl_init(int mode)
cio_api.movetext=bitmap_movetext;
cio_api.clreol=bitmap_clreol;
cio_api.clrscr=bitmap_clrscr;
cio_api.getcustomcursor=bitmap_getcustomcursor;
cio_api.setcustomcursor=bitmap_setcustomcursor;
cio_api.kbhit=sdl_kbhit;
cio_api.getch=sdl_getch;
......@@ -172,6 +174,8 @@ int try_x_init(int mode)
cio_api.movetext=bitmap_movetext;
cio_api.clreol=bitmap_clreol;
cio_api.clrscr=bitmap_clrscr;
cio_api.getcustomcursor=bitmap_getcustomcursor;
cio_api.setcustomcursor=bitmap_setcustomcursor;
cio_api.kbhit=x_kbhit;
cio_api.getch=x_getch;
......@@ -263,6 +267,8 @@ int try_conio_init(int mode)
cio_api.getcliptext=win32_getcliptext;
cio_api.suspend=win32_suspend;
cio_api.resume=win32_resume;
cio_api.getcustomcursor=win32_getcustomcursor;
cio_api.setcustomcursor=win32_setcustomcursor;
return(1);
}
return(0);
......@@ -1217,12 +1223,12 @@ CIOLIBEXPORT char * CIOLIBCALL ciolib_getcliptext(void)
}
/* Optional */
CIOLIBEXPORT int CIOLIBCALL ciolib_setfont(int font, int force)
CIOLIBEXPORT int CIOLIBCALL ciolib_setfont(int font, int force, int font_num)
{
CIOLIB_INIT();
if(cio_api.setfont!=NULL)
return(cio_api.setfont(font,force));
return(cio_api.setfont(font,force,font_num));
else
return(-1);
}
......@@ -1277,3 +1283,17 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_beep(void)
BEEP(440,100);
return(0);
}
/* Optional */
CIOLIBEXPORT void ciolib_getcustomcursor(int *start, int *end, int *range, int *blink, int *visible)
{
if(cio_api.getcustomcursor)
cio_api.getcustomcursor(start,end,range,blink,visible);
}
/* Optional */
CIOLIBEXPORT void ciolib_setcustomcursor(int start, int end, int range, int blink, int visible)
{
if(cio_api.setcustomcursor)
cio_api.setcustomcursor(start,end,range,blink,visible);
}
......@@ -263,10 +263,12 @@ typedef struct {
char *(*getcliptext) (void);
void (*suspend) (void);
void (*resume) (void);
int (*setfont) (int font, int force);
int (*setfont) (int font, int force, int font_num);
int (*getfont) (void);
int (*loadfont) (char *filename);
int (*get_window_info) (int* width, int* height, int* xpos, int* ypos);
void (*getcustomcursor) (int *startline, int *endline, int *range, int *blink, int *visible);
void (*setcustomcursor) (int startline, int endline, int range, int blink, int visible);
int *ESCDELAY;
} cioapi_t;
......@@ -323,11 +325,13 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_showmouse(void);
CIOLIBEXPORT int CIOLIBCALL ciolib_hidemouse(void);
CIOLIBEXPORT void CIOLIBCALL ciolib_copytext(const char *text, size_t buflen);
CIOLIBEXPORT char * CIOLIBCALL ciolib_getcliptext(void);
CIOLIBEXPORT int CIOLIBCALL ciolib_setfont(int font, int force);
CIOLIBEXPORT int CIOLIBCALL ciolib_setfont(int font, int force, int font_num);
CIOLIBEXPORT int CIOLIBCALL ciolib_getfont(void);
CIOLIBEXPORT int CIOLIBCALL ciolib_loadfont(char *filename);
CIOLIBEXPORT int CIOLIBCALL ciolib_get_window_info(int *width, int *height, int *xpos, int *ypos);
CIOLIBEXPORT int CIOLIBCALL ciolib_beep(void);
CIOLIBEXPORT void CIOLIBCALL ciolib_getcustomcursor(int *startline, int *endline, int *range, int *blink, int *visible);
CIOLIBEXPORT void CIOLIBCALL ciolib_setcustomcursor(int startline, int endline, int range, int blink, int visible);
/* DoorWay specific stuff that's only applicable to ANSI mode. */
CIOLIBEXPORT void CIOLIBCALL ansi_ciolib_setdoorway(int enable);
......@@ -378,11 +382,13 @@ CIOLIBEXPORT void CIOLIBCALL ansi_ciolib_setdoorway(int enable);
#define settitle(a) ciolib_settitle(a)
#define copytext(a,b) ciolib_copytext(a,b)
#define getcliptext() ciolib_getcliptext()
#define setfont(a,b) ciolib_setfont(a,b)
#define setfont(a,b,c) ciolib_setfont(a,b,c)
#define getfont() ciolib_getfont()
#define loadfont(a) ciolib_loadfont(a)
#define get_window_info(a,b,c,d) ciolib_get_window_info(a,b,c,d)
#define beep() ciolib_beep()
#define getcustomcursor(a,b,c,d,e) ciolib_getcustomcursor(a,b,c,d,e)
#define setcustomcursor(a,b,c,d,e) ciolib_setcustomcursor(a,b,c,d,e)
#endif
#ifdef WITH_SDL
......
......@@ -664,8 +664,10 @@ void do_ansi(char *retbuf, size_t retsize, int *speed)
j=atoi(p);
}
}
if(i==0) { /* Only the primary font is currently supported */
setfont(j,FALSE);
switch(i) {
case 0: /* Only the primary and secondary font is currently supported */
case 1:
setfont(j,FALSE,i);
}
}
}
......@@ -1851,15 +1853,15 @@ char *cterm_write(unsigned char *buf, int buflen, char *retbuf, size_t retsize,
/* Font change... whee! */
case 14: /* Lower case font */
if(ti.currmode == C64_40X25)
setfont(33,FALSE);
setfont(33,FALSE,0);
else /* Assume C128 */
setfont(35,FALSE);
setfont(35,FALSE,0);
break;
case 142: /* Upper case font */
if(ti.currmode == C64_40X25)
setfont(32,FALSE);
setfont(32,FALSE,0);
else /* Assume C128 */
setfont(34,FALSE);
setfont(34,FALSE,0);
break;
case 18: /* Reverse mode on */
cterm.c64reversemode = 1;
......
......@@ -45,4 +45,4 @@
#define CIO_KEY_ALT_F(x) ((x<11)?((0x67+x) << 8):((0x80+x) << 8))
#define CIO_KEY_MOUSE 0x7d00 // This is the right mouse on Schneider/Amstrad PC1512 PC keyboards
#define CIO_KEY_ABORTED 0x0100 // ESC key by scancode
#define CIO_KEY_ABORTED 0x01E0 // ESC key by scancode
......@@ -128,7 +128,7 @@ unsigned char palettes[5][16] = {
},
};
struct dac_colors dac_default[34] = {
struct dac_colors dac_default[TOTAL_DAC_SIZE] = {
{0, 0, 0}, {0, 0, 168}, {0, 168, 0}, {0, 168, 168},
{168, 0, 0}, {168, 0, 168}, {168, 84, 0}, {168, 168, 168},
{84, 84, 84}, {84, 84, 255}, {84, 255, 84}, {84, 255, 255},
......@@ -176,6 +176,11 @@ int load_vmode(struct video_stats *vs, int mode)
vs->curs_end=vparams[i].curs_end;
vs->default_curs_start=vparams[i].curs_start;
vs->default_curs_end=vparams[i].curs_end;
vs->curs_blink=1;
vs->curs_visible=1;
vs->bright_background=0;
vs->no_bright=0;
vs->bright_altcharset=0;
if(vs->curs_row < 0)
vs->curs_row=0;
if(vs->curs_row >= vparams[i].rows)
......@@ -184,7 +189,8 @@ int load_vmode(struct video_stats *vs, int mode)
vs->curs_col=0;
if(vs->curs_col >= vparams[i].cols)
vs->curs_col=vparams[i].cols-1;
vs->palette=palettes[vparams[i].palette];
memcpy(vs->palette, palettes[vparams[i].palette], sizeof(vs->palette));
memcpy(vs->dac_colors, dac_default, sizeof(dac_default));
vs->charheight=vparams[i].charheight;
vs->charwidth=vparams[i].charwidth;
vs->mode=mode;
......
......@@ -43,6 +43,15 @@
#include "ciolib.h"
#define TOTAL_DAC_SIZE 34
/* Entry type for the DAC table. */
struct dac_colors {
unsigned char red;
unsigned char green;
unsigned char blue;
};
struct video_params {
int mode;
int palette;
......@@ -61,25 +70,24 @@ struct video_stats {
int curs_col;
int curs_start;
int curs_end;
int curs_blink;
int curs_visible;
int default_curs_start;
int default_curs_end;
int mode;
int charheight;
int charwidth;
int bright_background;
int blink;
int no_bright;
int bright_altcharset;
int currattr;
int scaling;
unsigned char *palette;
struct dac_colors dac_colors[256];
unsigned char palette[16];
unsigned short *vmem;
};
/* Entry type for the DAC table. */
struct dac_colors {
unsigned char red;
unsigned char green;
unsigned char blue;
};
enum {
MONO_PALETTE
,GREYSCALE_PALETTE
......@@ -91,7 +99,7 @@ enum {
extern struct video_params vparams[49];
#define NUMMODES (sizeof(vparams) / sizeof(struct video_params))
extern unsigned char palettes[5][16];
extern struct dac_colors dac_default[34];
extern struct dac_colors dac_default[TOTAL_DAC_SIZE];
extern char vga_font_bitmap[4096];
extern char vga_font_bitmap14[3584];
extern char vga_font_bitmap8[2048];
......
......@@ -826,3 +826,43 @@ char *win32_getcliptext(void)
return(ret);
}
void win32_getcustomcursor(int *s, int *e, int *r, int *b, int *v)
{
CONSOLE_CURSOR_INFO ci;
HANDLE h;
if((h=GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE)
return(0);
GetConsoleCursorInfo(h, &ci);
if(s)
*s=100-ci.dwSize;
if(e)
*e=99;
if(r)
*r=100;
if(b)
*b=1;
if(v)
*v=ci.bVisible?1:0;
}
void win32_set customcursor(int s, int e, int r, int b, int v)
{
CONSOLE_CURSOR_INFO ci;
HANDLE h;
if((h=GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE)
return(0);
ci.bVisible=v;
if(e>s)
ci.bVisible=0;
else {
if(r>0)
ci.dwSize=(1+e-s)/r;
else
ci.dwSize=100;
}
}
......@@ -56,6 +56,8 @@ void win32_copytext(const char *text, size_t buflen);
char *win32_getcliptext(void);
void win32_suspend(void);
void win32_resume(void);
void win32_getcustomcursor(int *s, int *e, int *r, int *b, int *v);
void win32_setcustomcursor(int s, int e, int r, int b, int v);
#ifdef __cplusplus
}
......
......@@ -217,9 +217,9 @@ static int init_window()
/* Get the pixel and GC values */
for(i=0; i<sizeof(dac_default)/sizeof(struct dac_colors); i++) {
color.red=dac_default[i].red << 8;
color.green=dac_default[i].green << 8;
color.blue=dac_default[i].blue << 8;
color.red=dac_default[i].red << 8 | dac_default[i].red;
color.green=dac_default[i].green << 8 | dac_default[i].green;
color.blue=dac_default[i].blue << 8 | dac_default[i].blue;
if(x11.XAllocColor(dpy, DefaultColormap(dpy, DefaultScreen(dpy)), &color))
pixel[i]=color.pixel;
gcv.foreground=color.pixel;
......
......@@ -53,7 +53,7 @@ void changechar (unsigned char *fmt, int ind, int qt)
conio_fontdata[255].eight_by_eight=newfont;
break;
}
setfont(255,0);
setfont(255,0,0);
}
}
......
#include <ciolib.h>
#include <vidmodes.h>
static int curr_shape=0x2f00;
......@@ -8,6 +9,11 @@ void setcursorsh (unsigned int shape) //changes the cursor shape.
//bits 12-8 -> upper scan line bits 4-0 -> lower scan line
//Data from Ralf Brown Files
{
struct text_info ti;