From 1f36554a251cc9edafd97a86f140335fa6e592f8 Mon Sep 17 00:00:00 2001 From: deuce <> Date: Sun, 2 Oct 2005 11:24:06 +0000 Subject: [PATCH] Add SDL ciolib add-on. Currently only build with *nix builds. --- src/conio/Common.gmake | 34 + src/conio/GNUmakefile | 5 + src/conio/ciolib.c | 46 +- src/conio/ciolib.h | 1 + src/conio/console.c | 1 - src/conio/objects.mk | 1 + src/conio/sdl_con.c | 1049 +++++++++++++++++++++++++++ src/conio/sdl_con.h | 43 ++ src/conio/{vgafont.h => vidmodes.c} | 181 ++++- src/conio/vidmodes.h | 153 +--- 10 files changed, 1364 insertions(+), 150 deletions(-) create mode 100644 src/conio/sdl_con.c create mode 100644 src/conio/sdl_con.h rename src/conio/{vgafont.h => vidmodes.c} (97%) diff --git a/src/conio/Common.gmake b/src/conio/Common.gmake index 28591417b3..5936c780d8 100644 --- a/src/conio/Common.gmake +++ b/src/conio/Common.gmake @@ -1,3 +1,37 @@ +# Find SDL headers! +ifndef WITHOUT_SDL + ifndef SDL_CONFIG + ifeq ($(shell sdl12-config --cflags > /dev/null && echo YES),YES) + SDL_CONFIG := sdl12-config + WITH_SDL := 1 + else + ifeq ($(shell sdl11-config --cflags > /dev/null && echo YES),YES) + SDL_CONFIG := sdl11-config + WITH_SDL := 1 + else + ifeq ($(shell sdl-config --cflags > /dev/null && echo YES),YES) + SDL_CONFIG := sdl-config + WITH_SDL := 1 + endif + endif + endif + + ifdef WITH_SDL + ifdef SDL_CONFIG + ifeq ($(shell ${SDL_CONFIG} --cflags > /dev/null && echo YES),YES) + CIOLIB-MT_CFLAGS += -DWITH_SDL + CIOLIB-MT_CFLAGS += $(shell $(SDL_CONFIG) --cflags) + ifdef STATIC_SDL + CIOLIB-MT_LIBS += $(shell $(SDL_CONFIG) --static-libs) + else + CIOLIB-MT_LIBS += $(shell $(SDL_CONFIG) --libs) + endif + endif + endif + endif + endif +endif + ifeq ($(os),sunos) X_PATH ?= /usr/X else diff --git a/src/conio/GNUmakefile b/src/conio/GNUmakefile index 9151ede717..59c6ba9dcd 100644 --- a/src/conio/GNUmakefile +++ b/src/conio/GNUmakefile @@ -12,6 +12,11 @@ else OBJS += $(MTOBJODIR)$(DIRSEP)console$(OFILE) \ $(MTOBJODIR)$(DIRSEP)x_cio$(OFILE) endif + +ifdef WITH_SDL + OBJS += $(MTOBJODIR)$(DIRSEP)sdl_con$(OFILE) +endif + ifeq ($(os),netbsd) CFLAGS += -DN_CURSES_LIB endif diff --git a/src/conio/ciolib.c b/src/conio/ciolib.c index ea4179a7a8..3713a7f253 100644 --- a/src/conio/ciolib.c +++ b/src/conio/ciolib.c @@ -40,6 +40,9 @@ #define CIOLIB_NO_MACROS #include "ciolib.h" +#ifdef WITH_SDL + #include "sdl_con.h" +#endif #ifdef _WIN32 #include "win32cio.h" #else @@ -99,6 +102,37 @@ char *ciolib_getcliptext(void); #define CIOLIB_INIT() { if(!initialized) initciolib(CIOLIB_MODE_AUTO); } +#ifdef WITH_SDL +int try_sdl_init(int mode) +{ + if(!sdl_init()) { + cio_api.mode=CIOLIB_MODE_SDL; + cio_api.mouse=1; + cio_api.puttext=sdl_puttext; + cio_api.gettext=sdl_gettext; + cio_api.textattr=sdl_textattr; + cio_api.kbhit=sdl_kbhit; + cio_api.delay=sdl_delay; + cio_api.wherey=sdl_wherey; + cio_api.wherex=sdl_wherex; + cio_api.putch=sdl_putch; + cio_api.gotoxy=sdl_gotoxy; + cio_api.gettextinfo=sdl_gettextinfo; + cio_api.setcursortype=sdl_setcursortype; + cio_api.getch=sdl_getch; + cio_api.getche=sdl_getche; + cio_api.textmode=sdl_textmode; + cio_api.showmouse=sdl_showmouse; + cio_api.hidemouse=sdl_hidemouse; + cio_api.settitle=sdl_settitle; + cio_api.copytext=NULL; + cio_api.getcliptext=NULL; + return(1); + } + return(0); +} +#endif + #ifndef _WIN32 #ifndef NO_X int try_x_init(int mode) @@ -227,15 +261,19 @@ int initciolib(int mode) { switch(mode) { case CIOLIB_MODE_AUTO: +#ifdef WITH_SDL + if(!try_sdl_init(mode)) + +#endif #ifdef _WIN32 - if(!try_conio_init(mode)) + if(!try_conio_init(mode)) #else #ifndef NO_X - if(!try_x_init(mode)) + if(!try_x_init(mode)) #endif - if(!try_curses_init(mode)) + if(!try_curses_init(mode)) #endif - try_ansi_init(mode); + try_ansi_init(mode); break; #ifdef _WIN32 case CIOLIB_MODE_CONIO: diff --git a/src/conio/ciolib.h b/src/conio/ciolib.h index 619c2a52ef..de9e6f4d7d 100644 --- a/src/conio/ciolib.h +++ b/src/conio/ciolib.h @@ -44,6 +44,7 @@ enum { ,CIOLIB_MODE_ANSI ,CIOLIB_MODE_X ,CIOLIB_MODE_CONIO + ,CIOLIB_MODE_SDL }; #if defined(_WIN32) /* presumably, Win32 */ diff --git a/src/conio/console.c b/src/conio/console.c index 01b8aba8ff..f2e0245345 100644 --- a/src/conio/console.c +++ b/src/conio/console.c @@ -117,7 +117,6 @@ #include "keys.h" #include "mouse.h" -#include "vgafont.h" #define CONSOLE_MAX_ROWS 61 #define CONSOLE_MAX_COLS 81 diff --git a/src/conio/objects.mk b/src/conio/objects.mk index 2ad2bc4cb1..f52d79f506 100644 --- a/src/conio/objects.mk +++ b/src/conio/objects.mk @@ -1,4 +1,5 @@ OBJS = $(MTOBJODIR)$(DIRSEP)ansi_cio$(OFILE)\ $(MTOBJODIR)$(DIRSEP)ciolib$(OFILE)\ $(MTOBJODIR)$(DIRSEP)cterm$(OFILE)\ + $(MTOBJODIR)$(DIRSEP)vidmodes$(OFILE)\ $(MTOBJODIR)$(DIRSEP)mouse$(OFILE) diff --git a/src/conio/sdl_con.c b/src/conio/sdl_con.c new file mode 100644 index 0000000000..437ff63bb5 --- /dev/null +++ b/src/conio/sdl_con.c @@ -0,0 +1,1049 @@ +#include <stdarg.h> +#include <stdio.h> /* NULL */ +#include <string.h> + +#include "SDL.h" + +#include "gen_defs.h" +#include "genwrap.h" +#include "xpbeep.h" +#include "link_list.h" + +#include "ciolib.h" +#include "vidmodes.h" + +/********************************************************/ +/* Low Level Stuff */ +/* This should all be called from the same thread! */ +/********************************************************/ + +link_list_t sdl_updates; + +SDL_Surface *win=NULL; +SDL_mutex *sdl_keylock; +SDL_sem *sdl_key_pending; + +SDL_Surface *sdl_font=NULL; +SDL_Surface *sdl_cursor=NULL; + +struct video_stats vstat; +int fullscreen=1; + +/* 256 bytes so I can cheat */ +unsigned char sdl_keybuf[256]; /* Keyboard buffer */ +unsigned char sdl_key=0; /* Index into keybuf for next key in buffer */ +unsigned char sdl_keynext=0; /* Index into keybuf for next free position */ + +struct sdl_keyvals { + int keysym + ,key + ,shift + ,ctrl + ,alt; +}; + +struct sdl_drawchar { + int x + ,y + ,ch + ,fg + ,bg + ,blink; +}; + +enum { + SDL_USEREVENT_UPDATERECT + ,SDL_USEREVENT_DRAWCHAR + ,SDL_USEREVENT_SETTITLE + ,SDL_USEREVENT_SETVIDMODE + ,SDL_USEREVENT_SHOWMOUSE + ,SDL_USEREVENT_HIDEMOUSE + ,SDL_USEREVENT_SHOWCURSOR +}; + +const struct sdl_keyvals sdl_keyval[] = +{ + {SDLK_BACKSPACE, 0x08, 0x08, 0x7f, 0x0e00}, + {SDLK_TAB, 0x09, 0x0f00, 0x9400, 0xa500}, + {SDLK_RETURN, 0x0d, 0x0d, 0x0a, 0xa600}, + {SDLK_ESCAPE, 0x1b, 0x1b, 0x1b, 0x0100}, + {SDLK_SPACE, 0x20, 0x20, 0x0300, 0x20,}, + {SDLK_0, '0', ')', 0, 0x8100}, + {SDLK_1, '1', '!', 0, 0x7800}, + {SDLK_2, '2', '@', 0x0300, 0x7900}, + {SDLK_3, '3', '#', 0, 0x7a00}, + {SDLK_4, '4', '$', 0, 0x7b00}, + {SDLK_5, '5', '%', 0, 0x7c00}, + {SDLK_6, '6', '^', 0x1e, 0x7d00}, + {SDLK_7, '7', '&', 0, 0x7e00}, + {SDLK_8, '8', '*', 0, 0x7f00}, + {SDLK_9, '9', '(', 0, 0x8000}, + {SDLK_a, 'a', 'A', 0x01, 0x1e00}, + {SDLK_b, 'b', 'B', 0x02, 0x3000}, + {SDLK_c, 'c', 'C', 0x03, 0x2e00}, + {SDLK_d, 'd', 'D', 0x04, 0x2000}, + {SDLK_e, 'e', 'E', 0x05, 0x1200}, + {SDLK_f, 'f', 'F', 0x06, 0x2100}, + {SDLK_g, 'g', 'G', 0x07, 0x2200}, + {SDLK_h, 'h', 'H', 0x08, 0x2300}, + {SDLK_i, 'i', 'I', 0x09, 0x1700}, + {SDLK_j, 'j', 'J', 0x0a, 0x2400}, + {SDLK_k, 'k', 'K', 0x0b, 0x2500}, + {SDLK_l, 'l', 'L', 0x0c, 0x2600}, + {SDLK_m, 'm', 'M', 0x0d, 0x3200}, + {SDLK_n, 'n', 'N', 0x0e, 0x3100}, + {SDLK_o, 'o', 'O', 0x0f, 0x1800}, + {SDLK_p, 'p', 'P', 0x10, 0x1900}, + {SDLK_q, 'q', 'Q', 0x11, 0x1000}, + {SDLK_r, 'r', 'R', 0x12, 0x1300}, + {SDLK_s, 's', 'S', 0x13, 0x1f00}, + {SDLK_t, 't', 'T', 0x14, 0x1400}, + {SDLK_u, 'u', 'U', 0x15, 0x1600}, + {SDLK_v, 'v', 'V', 0x16, 0x2f00}, + {SDLK_w, 'w', 'W', 0x17, 0x1100}, + {SDLK_x, 'x', 'X', 0x18, 0x2d00}, + {SDLK_y, 'y', 'Y', 0x19, 0x1500}, + {SDLK_z, 'z', 'Z', 0x1a, 0x2c00}, + {SDLK_PAGEUP, 0x4900, 0x4900, 0x8400, 0x9900}, + {SDLK_PAGEDOWN, 0x5100, 0x5100, 0x7600, 0xa100}, + {SDLK_END, 0x4f00, 0x4f00, 0x7500, 0x9f00}, + {SDLK_HOME, 0x4700, 0x4700, 0x7700, 0x9700}, + {SDLK_LEFT, 0x4b00, 0x4b00, 0x7300, 0x9b00}, + {SDLK_UP, 0x4800, 0x4800, 0x8d00, 0x9800}, + {SDLK_RIGHT, 0x4d00, 0x4d00, 0x7400, 0x9d00}, + {SDLK_DOWN, 0x5000, 0x5000, 0x9100, 0xa000}, + {SDLK_INSERT, 0x5200, 0x5200, 0x9200, 0xa200}, + {SDLK_DELETE, 0x5300, 0x5300, 0x9300, 0xa300}, + {SDLK_KP0, 0x5200, 0x5200, 0x9200, 0}, + {SDLK_KP1, 0x4f00, 0x4f00, 0x7500, 0}, + {SDLK_KP2, 0x5000, 0x5000, 0x9100, 0}, + {SDLK_KP3, 0x5100, 0x5100, 0x7600, 0}, + {SDLK_KP4, 0x4b00, 0x4b00, 0x7300, 0}, + {SDLK_KP5, 0x4c00, 0x4c00, 0x8f00, 0}, + {SDLK_KP6, 0x4d00, 0x4d00, 0x7400, 0}, + {SDLK_KP7, 0x4700, 0x4700, 0x7700, 0}, + {SDLK_KP8, 0x4800, 0x4800, 0x8d00, 0}, + {SDLK_KP9, 0x4900, 0x4900, 0x8400, 0}, + {SDLK_KP_MULTIPLY, '*', '*', 0x9600, 0x3700}, + {SDLK_KP_PLUS, '+', '+', 0x9000, 0x4e00}, + {SDLK_KP_MINUS, '-', '-', 0x8e00, 0x4a00}, + {SDLK_KP_PERIOD, '.', '.', 0x5300, 0x9300}, + {SDLK_KP_DIVIDE, '/', '/', 0x9500, 0xa400}, + {SDLK_F1, 0x3b00, 0x5400, 0x5e00, 0x6800}, + {SDLK_F2, 0x3c00, 0x5500, 0x5f00, 0x6900}, + {SDLK_F3, 0x3d00, 0x5600, 0x6000, 0x6a00}, + {SDLK_F4, 0x3e00, 0x5700, 0x6100, 0x6b00}, + {SDLK_F5, 0x3f00, 0x5800, 0x6200, 0x6c00}, + {SDLK_F6, 0x4000, 0x5900, 0x6300, 0x6d00}, + {SDLK_F7, 0x4100, 0x5a00, 0x6400, 0x6e00}, + {SDLK_F8, 0x4200, 0x5b00, 0x6500, 0x6f00}, + {SDLK_F9, 0x4300, 0x5c00, 0x6600, 0x7000}, + {SDLK_F10, 0x4400, 0x5d00, 0x6700, 0x7100}, + {SDLK_F11, 0x8500, 0x8700, 0x8900, 0x8b00}, + {SDLK_F12, 0x8600, 0x8800, 0x8a00, 0x8c00}, + {SDLK_BACKSLASH, '\\', '|', 0x1c, 0x2b00}, + {SDLK_SLASH, '/', '?', 0, 0x3500}, + {SDLK_MINUS, '-', '_', 0x1f, 0x8200}, + {SDLK_EQUALS, '=', '+', 0, 0x8300}, + {SDLK_LEFTBRACKET, '[', '{', 0x1b, 0x1a00}, + {SDLK_RIGHTBRACKET, ']', '}', 0x1d, 0x1b00}, + {SDLK_SEMICOLON, ';', ':', 0, 0x2700}, + {SDLK_BACKSLASH, '\'', '"', 0, 0x2800}, + {SDLK_COMMA, ',', '<', 0, 0x3300}, + {SDLK_PERIOD, '.', '>', 0, 0x3400}, + {SDLK_BACKQUOTE, '`', '~', 0, 0x2900}, + {0, 0, 0, 0, 0} /** END **/ +}; +const int sdl_tabs[10]={9,17,25,33,41,49,57,65,73,80}; + +/* Called from event thread only */ +unsigned int sdl_get_char_code(unsigned int keysym, unsigned int mod) +{ + int i; + + for(i=0;sdl_keyval[i].keysym;i++) { + if(sdl_keyval[i].keysym==keysym) { + if(mod & (KMOD_META|KMOD_ALT)) + return(sdl_keyval[i].alt); + if(mod & KMOD_CTRL) + return(sdl_keyval[i].ctrl); + if(mod & KMOD_SHIFT) + return(sdl_keyval[i].shift); + return(sdl_keyval[i].key); + } + } + return(0x01ffff); +} + +/* Called from event thread only */ +void sdl_add_key(unsigned int keyval) +{ + if(keyval <= 0xffff) { + SDL_mutexP(sdl_keylock); + if(sdl_keynext+1==sdl_key) { + sdl_beep(); + SDL_mutexV(sdl_keylock); + return; + } + if((sdl_keynext+2==sdl_key) && keyval > 0xff) { + sdl_beep(); + SDL_mutexV(sdl_keylock); + return; + } + sdl_keybuf[sdl_keynext++]=keyval & 0xff; + SDL_SemPost(sdl_key_pending); + if(keyval>0xff) { + sdl_keybuf[sdl_keynext++]=keyval >> 8; + SDL_SemPost(sdl_key_pending); + } + SDL_mutexV(sdl_keylock); + } +} + +/* Called from event thread only */ +int sdl_load_font(char *filename) +{ + unsigned char *font; + unsigned int fontsize; + int fw; + int fh; + int ch; + int x; + int y; + int charrow; + int charcol; + SDL_Rect r; + + /* I don't actually do this yet! */ + if(filename != NULL) + return(-1); + + fh=vstat.charheight; + fw=vstat.charwidth/8+(vstat.charwidth%8?1:0); + + fontsize=fw*fh*256*sizeof(unsigned char); + + if((font=(unsigned char *)malloc(fontsize))==NULL) + return(-1); + + switch(vstat.charwidth) { + case 8: + switch(vstat.charheight) { + case 8: + memcpy(font, vga_font_bitmap8, fontsize); + break; + case 14: + memcpy(font, vga_font_bitmap14, fontsize); + break; + case 16: + memcpy(font, vga_font_bitmap, fontsize); + break; + default: + return(-1); + } + break; + default: + return(-1); + } + + if(sdl_font!=NULL) + SDL_FreeSurface(sdl_font); + sdl_font=SDL_CreateRGBSurface(SDL_HWSURFACE|SDL_SRCCOLORKEY, vstat.charwidth, vstat.charheight*256, 8, 0, 0, 0, 0); + for(ch=0; ch<256; ch++) { + for(charrow=0; charrow<vstat.charheight; charrow++) { + for(charcol=0; charcol<vstat.charheight; charcol++) { + if(font[(ch*vstat.charheight+charrow)*fw+(charcol/8)] & (1<<(charcol%8))) { + r.x=charcol*vstat.scaling; + r.y=(ch*vstat.charheight+charrow)*vstat.scaling; + r.w=vstat.scaling; + r.h=vstat.scaling; + SDL_FillRect(sdl_font, &r, 1); + } + } + } + } + + return(0); +} + +/* Called from all threads */ +void sdl_user_func(int func, ...) +{ + static int sent_update=0; + unsigned int *i; + va_list argptr; + void **args; + SDL_Event *ev; + SDL_Event evnt; + + if((ev=(SDL_Event *)malloc(sizeof(SDL_Event)))==NULL) + return; + ev->type=SDL_USEREVENT; + ev->user.data1=NULL; + ev->user.data2=NULL; + ev->user.code=func; + va_start(argptr, func); + switch(func) { + case SDL_USEREVENT_UPDATERECT: + if((ev->user.data1=(void *)malloc(sizeof(SDL_Rect)))==NULL) { + free(ev); + va_end(argptr); + return; + } + ((SDL_Rect *)ev->user.data1)->x=va_arg(argptr, unsigned int); + ((SDL_Rect *)ev->user.data1)->y=va_arg(argptr, unsigned int); + ((SDL_Rect *)ev->user.data1)->w=va_arg(argptr, unsigned int); + ((SDL_Rect *)ev->user.data1)->h=va_arg(argptr, unsigned int); + listPushNode(&sdl_updates,ev); + evnt.type=SDL_USEREVENT; + evnt.user.code=-1; + evnt.user.data1=NULL; + evnt.user.data2=NULL; + while(SDL_PeepEvents(&evnt, 1, SDL_ADDEVENT, 0xffffffff)!=1); + break; + case SDL_USEREVENT_SETTITLE: + if((ev->user.data1=strdup(va_arg(argptr, char *)))==NULL) { + free(ev); + va_end(argptr); + return; + } + listPushNode(&sdl_updates,ev); + break; + case SDL_USEREVENT_SETVIDMODE: + if((ev->user.data1=(void *)malloc(sizeof(int)))==NULL) { + free(ev); + va_end(argptr); + return; + } + *((int *)ev->user.data1)=va_arg(argptr, int); + if((ev->user.data2=(void *)malloc(sizeof(int)))==NULL) { + free(ev->user.data1); + free(ev); + va_end(argptr); + return; + } + *((int *)ev->user.data2)=va_arg(argptr, int); + listPushNode(&sdl_updates,ev); + evnt.type=SDL_USEREVENT; + evnt.user.code=-1; + evnt.user.data1=NULL; + evnt.user.data2=NULL; + while(SDL_PeepEvents(&evnt, 1, SDL_ADDEVENT, 0xffffffff)!=1); + break; + case SDL_USEREVENT_DRAWCHAR: + if((ev->user.data1=(void *)malloc(sizeof(struct sdl_drawchar)))==NULL) { + free(ev); + va_end(argptr); + return; + } + ((struct sdl_drawchar *)ev->user.data1)->x=va_arg(argptr, unsigned int); + ((struct sdl_drawchar *)ev->user.data1)->y=va_arg(argptr, unsigned int); + ((struct sdl_drawchar *)ev->user.data1)->ch=va_arg(argptr, unsigned int); + ((struct sdl_drawchar *)ev->user.data1)->fg=va_arg(argptr, unsigned int); + ((struct sdl_drawchar *)ev->user.data1)->bg=va_arg(argptr, unsigned int); + ((struct sdl_drawchar *)ev->user.data1)->blink=va_arg(argptr, unsigned int); + listPushNode(&sdl_updates,ev); + break; + case SDL_USEREVENT_SHOWMOUSE: + listPushNode(&sdl_updates,ev); + evnt.type=SDL_USEREVENT; + evnt.user.code=-1; + while(SDL_PeepEvents(&evnt, 1, SDL_ADDEVENT, 0xffffffff)!=1); + break; + case SDL_USEREVENT_HIDEMOUSE: + listPushNode(&sdl_updates,ev); + evnt.type=SDL_USEREVENT; + evnt.user.code=-1; + while(SDL_PeepEvents(&evnt, 1, SDL_ADDEVENT, 0xffffffff)!=1); + break; + case SDL_USEREVENT_SHOWCURSOR: + listPushNode(&sdl_updates,ev); + evnt.type=SDL_USEREVENT; + evnt.user.code=-1; + while(SDL_PeepEvents(&evnt, 1, SDL_ADDEVENT, 0xffffffff)!=1); + break; + default: + free(ev); + } + va_end(argptr); +} + +/* Event Thread */ +void sdl_event_thread(void *data) +{ + unsigned int i; + SDL_Event ev; + + SDL_EnableUNICODE(1); + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); + while(1) { + if(SDL_WaitEvent(&ev)==1) { + switch (ev.type) { + case SDL_ACTIVEEVENT: /* Focus change */ + break; + case SDL_KEYDOWN: /* Keypress */ + if(ev.key.keysym.unicode&0x7f) /* ASCII Key (Whoopee!) */ + sdl_add_key(ev.key.keysym.unicode&0x7f); + else + sdl_add_key(sdl_get_char_code(ev.key.keysym.sym, ev.key.keysym.mod)); + break; + case SDL_KEYUP: /* Ignored (handled in KEYDOWN event) */ + break; + case SDL_MOUSEMOTION: + ciomouse_gotevent(CIOLIB_MOUSE_MOVE,ev.motion.x,ev.motion.y); + break; + case SDL_MOUSEBUTTONDOWN: + switch(ev.button.button) { + case SDL_BUTTON_LEFT: + ciomouse_gotevent(CIOLIB_BUTTON_RELEASE(1),ev.button.x,ev.button.y); + break; + case SDL_BUTTON_MIDDLE: + ciomouse_gotevent(CIOLIB_BUTTON_RELEASE(2),ev.button.x,ev.button.y); + break; + case SDL_BUTTON_RIGHT: + ciomouse_gotevent(CIOLIB_BUTTON_RELEASE(3),ev.button.x,ev.button.y); + break; + } + break; + case SDL_MOUSEBUTTONUP: + switch(ev.button.button) { + case SDL_BUTTON_LEFT: + ciomouse_gotevent(CIOLIB_BUTTON_PRESS(1),ev.button.x,ev.button.y); + break; + case SDL_BUTTON_MIDDLE: + ciomouse_gotevent(CIOLIB_BUTTON_PRESS(2),ev.button.x,ev.button.y); + break; + case SDL_BUTTON_RIGHT: + ciomouse_gotevent(CIOLIB_BUTTON_PRESS(3),ev.button.x,ev.button.y); + break; + } + break; + case SDL_QUIT: + SDL_Quit(); + exit(0); + break; + case SDL_VIDEORESIZE: + if(ev.resize.w > 0 && ev.resize.h > 0) { + vstat.scaling=(int)(ev.resize.w/(vstat.charwidth*vstat.cols)); + if(vstat.scaling < 1) + vstat.scaling=1; + win=SDL_SetVideoMode(vstat.charwidth*vstat.cols*vstat.scaling, vstat.charheight*vstat.rows*vstat.scaling, 8, SDL_HWSURFACE|SDL_HWPALETTE|(fullscreen?SDL_FULLSCREEN:0)|SDL_RESIZABLE|SDL_DOUBLEBUF); + if(sdl_cursor!=NULL) + SDL_FreeSurface(sdl_cursor); + sdl_cursor=SDL_CreateRGBSurface(SDL_HWSURFACE|SDL_SRCCOLORKEY, vstat.charwidth, vstat.charheight, 8, 0, 0, 0, 0); + /* Update font. */ + sdl_load_font(NULL); + sdl_setup_colours(win,0); + sdl_screen_redraw(); + } + break; + case SDL_VIDEOEXPOSE: + SDL_UpdateRect(win,0,0,0,0); + break; + case SDL_USEREVENT: { + SDL_Event *inev; + /* Tell SDL to do various stuff... */ + while(listCountNodes(&sdl_updates) && ((inev=listShiftNode(&sdl_updates))!=NULL)) { + switch(inev->user.code) { + case SDL_USEREVENT_UPDATERECT: + SDL_UpdateRect(win,((SDL_Rect *)inev->user.data1)->x,((SDL_Rect *)inev->user.data1)->y,((SDL_Rect *)inev->user.data1)->w,((SDL_Rect *)inev->user.data1)->h); + free(inev->user.data1); + break; + case SDL_USEREVENT_SETTITLE: + SDL_WM_SetCaption((char *)inev->user.data1,NULL); + free(inev->user.data1); + break; + case SDL_USEREVENT_SETVIDMODE: + win=SDL_SetVideoMode(*((int *)inev->user.data1),*((int *)inev->user.data2),8, SDL_HWSURFACE|SDL_HWPALETTE|(fullscreen?SDL_FULLSCREEN:0)|SDL_RESIZABLE|SDL_DOUBLEBUF); + if(sdl_cursor!=NULL) + SDL_FreeSurface(sdl_cursor); + sdl_cursor=SDL_CreateRGBSurface(SDL_HWSURFACE|SDL_SRCCOLORKEY, vstat.charwidth, vstat.charheight, 8, 0, 0, 0, 0); + /* Update font. */ + sdl_load_font(NULL); + free(inev->user.data1); + free(inev->user.data2); + sdl_setup_colours(win,0); + break; + case SDL_USEREVENT_DRAWCHAR: { + SDL_Color co; + SDL_Rect src; + SDL_Rect dst; + + co.r=dac_default256[vstat.palette[((struct sdl_drawchar *)inev->user.data1)->fg]].red; + co.g=dac_default256[vstat.palette[((struct sdl_drawchar *)inev->user.data1)->fg]].green; + co.b=dac_default256[vstat.palette[((struct sdl_drawchar *)inev->user.data1)->fg]].blue; + SDL_SetColors(sdl_font, &co, 1, 1); + co.r=dac_default256[vstat.palette[((struct sdl_drawchar *)inev->user.data1)->bg]].red; + co.g=dac_default256[vstat.palette[((struct sdl_drawchar *)inev->user.data1)->bg]].green; + co.b=dac_default256[vstat.palette[((struct sdl_drawchar *)inev->user.data1)->bg]].blue; + SDL_SetColors(sdl_font, &co, 0, 1); + dst.x=((struct sdl_drawchar *)inev->user.data1)->x*vstat.charwidth*vstat.scaling; + dst.y=((struct sdl_drawchar *)inev->user.data1)->y*vstat.charheight*vstat.scaling; + dst.w=vstat.charwidth*vstat.scaling; + dst.h=vstat.charheight*vstat.scaling; + src.x=0; + src.w=vstat.charwidth; + src.h=vstat.charheight; + src.y=vstat.charheight*vstat.scaling; + if(((struct sdl_drawchar *)inev->user.data1)->blink && !(vstat.blink)) + src.y *= ' '; + else + src.y *= ((struct sdl_drawchar *)inev->user.data1)->ch; + SDL_BlitSurface(sdl_font, &src, win, &dst); + free(inev->user.data1); + } + break; + case SDL_USEREVENT_HIDEMOUSE: + SDL_ShowCursor(SDL_DISABLE); + break; + case SDL_USEREVENT_SHOWMOUSE: + SDL_ShowCursor(SDL_ENABLE); + break; + case SDL_USEREVENT_SHOWCURSOR: { + static int lastcursor_x=0; + static int lastcursor_y=0; + SDL_Rect src; + SDL_Rect dst; + + /* Erase old cursor */ + sdl_user_func(SDL_USEREVENT_DRAWCHAR + ,lastcursor_x + ,lastcursor_y + ,vstat.vmem[vstat.curs_row*vstat.cols+vstat.curs_col] & 0xff + ,(vstat.vmem[vstat.curs_row*vstat.cols+vstat.curs_col]>>8) & 0x0f + ,(vstat.vmem[vstat.curs_row*vstat.cols+vstat.curs_col]>>12) & 0x07 + ,(vstat.vmem[vstat.curs_row*vstat.cols+vstat.curs_col]>>15) + ); + + if(vstat.curs_start<=vstat.curs_end) { + dst.x=0; + dst.y=0; + dst.w=vstat.charwidth*vstat.scaling; + dst.h=(vstat.curs_end-vstat.curs_start+1)*vstat.scaling; + src.x=vstat.curs_col*vstat.charwidth*vstat.scaling; + src.y=(vstat.curs_row*vstat.charheight+vstat.curs_start)*vstat.scaling; + src.w=vstat.charwidth*vstat.scaling; + src.h=(vstat.curs_end-vstat.curs_start+1)*vstat.scaling; + sdl_setup_colours(sdl_cursor, 0); + SDL_BlitSurface(sdl_cursor, &src, win, &dst); + sdl_setup_colours(sdl_cursor, vstat.currattr); + SDL_BlitSurface(win, &dst, sdl_cursor, &src); + SDL_UpdateRect(win, src.x, src.y, src.w, src.h); + lastcursor_x=vstat.curs_col; + lastcursor_y=vstat.curs_row; + } + } + break; + } + free(inev); + } + break; + } + /* Ignore this stuff */ + case SDL_SYSWMEVENT: /* ToDo... This is where Copy/Paste needs doing */ + case SDL_JOYAXISMOTION: + case SDL_JOYBALLMOTION: + case SDL_JOYHATMOTION: + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + default: + break; + } + } + } +} + +/* Called from blinker thread only, (Passes Event) */ +int sdl_blink(void) +{ + int x; + int y; + int ret=0; + unsigned int fg; + unsigned int bg; + unsigned int blink; + unsigned int ch; + + for(x=0;x<vstat.cols;x++) { + for(y=0;y<vstat.rows;y++) { + blink=vstat.vmem[y*vstat.cols+x]>>15; + if(blink) { + bg=(vstat.vmem[y*vstat.cols+x]>>12) & 0x07; + fg=(vstat.vmem[y*vstat.cols+x]>>8) & 0x0f; + ch=vstat.vmem[y*vstat.cols+x] & 0xff; + + sdl_user_func(SDL_USEREVENT_DRAWCHAR, x, y, ch, fg, bg, blink); + } + } + } + /* ToDo: Should this only update the blinked chars? */ + sdl_user_func(SDL_USEREVENT_SHOWCURSOR); + sdl_user_func(SDL_USEREVENT_UPDATERECT,0,0,0,0); + + return(ret); +} + +/* Blinker Thread */ +void sdl_blinker_thread(void *data) +{ + while(1) { + SLEEP(500); + if(vstat.blink) + vstat.blink=FALSE; + else + vstat.blink=TRUE; + sdl_blink(); + } +} + +/* Called from main thread only (Passes Event) */ +int sdl_init_mode(int mode) +{ + struct video_params vmode; + int idx; /* Index into vmode */ + int i; + + if(load_vmode(&vstat, mode)) + return(-1); + + sdl_user_func(SDL_USEREVENT_SETVIDMODE,vstat.charwidth*vstat.cols*vstat.scaling, vstat.charheight*vstat.rows*vstat.scaling); + + /* Initialize video memory with black background, white foreground */ + for (i = 0; i < vstat.cols*vstat.rows; ++i) + vstat.vmem[i] = 0x0700; + vstat.currattr=7; + + /* Load 'pixels[]' from default DAC values. */ + sdl_screen_redraw(); + + vstat.mode=mode; + + return(0); +} + +/* Called from events thread only */ +int sdl_setup_colours(SDL_Surface *surf, int xor) +{ + int i; + int ret=0; + SDL_Color co; + + for(i=0; i<16; i++) { + co.r=dac_default256[vstat.palette[i]^xor].red; + co.g=dac_default256[vstat.palette[i]^xor].green; + co.b=dac_default256[vstat.palette[i]^xor].blue; + SDL_SetColors(surf, &co, i, 1); + } + return(ret); +} + +/* Called from main thread only */ +int sdl_fillrect(SDL_Rect *r, int colour) +{ + int x; + int y; + int x2; + int y2; + unsigned int pos; + + x2=r->x+r->w; + y2=r->y+r->h; +// SDL_LockSurface(win); + for(y=r->y; y<y2; y++) { + pos=y*vstat.charwidth*vstat.cols*vstat.scaling+r->x; + for(x=r->x; x<x2; x++) { + pos++; + if(pos<vstat.charwidth*vstat.cols*vstat.scaling * vstat.charheight*vstat.rows*vstat.scaling) { + ((unsigned char *)win->pixels)[pos]=colour; + } + } + } +// SDL_UnlockSurface(win); +} + +/* Called from main thread only (Passes Event) */ +int sdl_draw_char(unsigned short vch, int xpos, int ypos, int update) +{ + unsigned int fg; + unsigned int bg; + unsigned int blink; + unsigned int ch; + + bg=(vch>>12) & 0x07; + fg=(vch>>8) & 0x0f; + blink=vch>>15; + ch=vch & 0xff; + + vstat.vmem[ypos*vstat.cols+xpos]=vch; + sdl_user_func(SDL_USEREVENT_DRAWCHAR, xpos, ypos, ch, fg, bg, blink); + + if(update) { + sdl_user_func(SDL_USEREVENT_SHOWCURSOR); + sdl_user_func(SDL_USEREVENT_UPDATERECT,xpos*vstat.charwidth*vstat.scaling,ypos*vstat.charheight*vstat.scaling,vstat.charwidth*vstat.scaling,vstat.charheight*vstat.scaling); + } + + return(0); +} + +/* Called from main thread only, (Passes Event) */ +int sdl_screen_redraw(void) +{ + int x; + int y; + int ret=0; + + for(x=0;x<vstat.cols;x++) { + for(y=0;y<vstat.rows;y++) { + if(sdl_draw_char(vstat.vmem[y*vstat.cols+x], x, y, FALSE)) + ret=-1; + } + } + sdl_user_func(SDL_USEREVENT_SHOWCURSOR); + sdl_user_func(SDL_USEREVENT_UPDATERECT,0,0,0,0); + + return(ret); +} + +/* Called from main thread only (Passes Event) */ +int sdl_init(void) +{ + vstat.vmem=NULL; + vstat.scaling=1; + + listInit(&sdl_updates,0); + + if(SDL_Init(SDL_INIT_VIDEO)) + return(-1); + + if((sdl_key_pending=SDL_CreateSemaphore(0))==NULL) { + SDL_Quit(); + return(-1); + } + + SDL_CreateThread(sdl_event_thread,NULL); + SDL_CreateThread(sdl_blinker_thread,NULL); + + if(sdl_init_mode(3)) + return(-1); + + atexit(SDL_Quit); + + init_mouse(); + + return(0); +} + +/********************************************************/ +/* High Level Stuff */ +/********************************************************/ + +/* Called from main thread only (Passes Event) */ +int sdl_puttext(int sx, int sy, int ex, int ey, void *fill) +{ + int x,y; + unsigned char *out; + WORD sch; + struct text_info ti; + + gettextinfo(&ti); + + if( sx < 1 + || sy < 1 + || ex < 1 + || ey < 1 + || sx > ti.screenwidth + || sy > ti.screenheight + || sx > ex + || sy > ey + || ex > ti.screenwidth + || ey > ti.screenheight + || 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; + sdl_draw_char(sch,x,y,FALSE); + } + } + sdl_user_func(SDL_USEREVENT_SHOWCURSOR); + sdl_user_func(SDL_USEREVENT_UPDATERECT + ,(sx-1)*vstat.charwidth*vstat.scaling + ,(sy-1)*vstat.charheight*vstat.scaling + ,(ex-sx+1)*vstat.charwidth*vstat.scaling + ,(ey-sy+1)*vstat.charheight*vstat.scaling + ); + return(1); +} + +/* Called from main thread only */ +int sdl_gettext(int sx, int sy, int ex, int ey, void *fill) +{ + int x,y; + unsigned char *out; + WORD sch; + struct text_info ti; + + gettextinfo(&ti); + + if( sx < 1 + || sy < 1 + || ex < 1 + || ey < 1 + || sx > ti.screenwidth + || sy > ti.screenheight + || sx > ex + || sy > ey + || ex > ti.screenwidth + || ey > ti.screenheight + || fill==NULL) + return(0); + + out=fill; + for(y=sy-1;y<ey;y++) { + for(x=sx-1;x<ex;x++) { + sch=vstat.vmem[y*vstat.cols+x]; + *(out++)=sch & 0xff; + *(out++)=sch >> 8; + } + } + return(1); +} + +/* Called from main thread only */ +void sdl_textattr(int attr) +{ + vstat.currattr=attr; +} + +/* Called from main thread only */ +int sdl_kbhit(void) +{ + int ret; + + SDL_mutexP(sdl_keylock); + ret=(sdl_key!=sdl_keynext); + SDL_mutexV(sdl_keylock); + return(ret); +} + +/* Called from main thread only */ +void sdl_delay(long msec) +{ + usleep(msec*1000); +} + +/* Called from main thread only */ +int sdl_wherey(void) +{ + return(vstat.curs_row+1); +} + +/* Called from main thread only */ +int sdl_wherex(void) +{ + return(vstat.curs_col+1); +} + +/* Put the character _c on the screen at the current cursor position. + * The special characters return, linefeed, bell, and backspace are handled + * properly, as is line wrap and scrolling. The cursor position is updated. + */ +/* Called from main thread only */ +int sdl_putch(int ch) +{ + struct text_info ti; + WORD sch; + int i; + + sch=(vstat.currattr<<8)|ch; + + switch(ch) { + case '\r': + gettextinfo(&ti); + vstat.curs_col=ti.winleft-1; + break; + case '\n': + gettextinfo(&ti); + if(wherey()==ti.winbottom-ti.wintop+1) + wscroll(); + else + vstat.curs_row++; + break; + case '\b': + if(vstat.curs_col>0) + vstat.curs_col--; + sdl_draw_char((vstat.currattr<<8)|' ',vstat.curs_col,vstat.curs_row,TRUE); + break; + case 7: /* Bell */ + sdl_beep(); + break; + case '\t': + for(i=0;i<10;i++) { + if(sdl_tabs[i]>wherex()) { + while(wherex()<sdl_tabs[i]) { + putch(' '); + } + break; + } + } + if(i==10) { + putch('\r'); + putch('\n'); + } + break; + default: + gettextinfo(&ti); + if(wherey()==ti.winbottom-ti.wintop+1 + && wherex()==ti.winright-ti.winleft+1) { + sdl_draw_char(sch,vstat.curs_col,vstat.curs_row,TRUE); + wscroll(); + gotoxy(ti.winleft,wherey()); + } + else { + if(wherex()==ti.winright-ti.winleft+1) { + sdl_draw_char(sch,vstat.curs_col,vstat.curs_row,TRUE); + gotoxy(ti.winleft,ti.cury+1); + } + else { + sdl_draw_char(sch,vstat.curs_col,vstat.curs_row,TRUE); + gotoxy(ti.curx+1,ti.cury); + } + } + break; + } + + return(ch); +} + +/* Called from main thread only */ +void sdl_gotoxy(int x, int y) +{ + vstat.curs_row=y-1; + vstat.curs_col=x-1; +} + +/* Called from main thread only */ +void sdl_gettextinfo(struct text_info *info) +{ + info->currmode=vstat.mode; + info->screenheight=vstat.rows; + info->screenwidth=vstat.cols; + info->curx=sdl_wherex(); + info->cury=sdl_wherey(); + info->attribute=vstat.currattr; +} + +/* Called from main thread only */ +void sdl_setcursortype(int type) +{ + switch(type) { + case _NOCURSOR: + vstat.curs_start=0xff; + vstat.curs_end=0; + break; + case _SOLIDCURSOR: + vstat.curs_start=0; + vstat.curs_end=vstat.charheight-1; + break; + default: + vstat.curs_start = vstat.default_curs_start; + vstat.curs_end = vstat.default_curs_start; + break; + } +} + +/* Called from main thread only */ +int sdl_getch(void) +{ + int ch; + + SDL_SemWait(sdl_key_pending); + SDL_mutexP(sdl_keylock); + ch=sdl_keybuf[sdl_key++]; + SDL_mutexV(sdl_keylock); + return(ch); +} + +/* Called from main thread only */ +int sdl_getche(void) +{ + int ch; + + while(1) { + ch=sdl_getch(); + if(ch) { + putch(ch); + return(ch); + } + ch=sdl_getch(); + } +} + +/* Called from BOTH THREADS */ +int sdl_beep(void) +{ + /* ToDo BEEP! */ + BEEP(440,100); + return(0); +} + +/* Called from main thread only */ +void sdl_textmode(int mode) +{ + sdl_init_mode(mode); +} + +/* Called from main thread only (Passes Event) */ +int sdl_settitle(const char *title) +{ + sdl_user_func(SDL_USEREVENT_SETTITLE,title); + return(0); +} + +int sdl_showmouse(void) +{ + sdl_user_func(SDL_USEREVENT_SHOWMOUSE); + return(1); +} + +int sdl_hidemouse(void) +{ + sdl_user_func(SDL_USEREVENT_HIDEMOUSE); +} + +#if 0 /* ToDo Copy/Paste */ +void sdl_copytext(const char *text, size_t buflen) +{ + pthread_mutex_lock(©buf_mutex); + if(copybuf!=NULL) { + free(copybuf); + copybuf=NULL; + } + + copybuf=(char *)malloc(buflen+1); + if(copybuf!=NULL) { + strcpy(copybuf, text); + sem_post(©buf_set); + } + pthread_mutex_unlock(©buf_mutex); + return; +} + +char *sdl_getcliptext(void) +{ + char *ret=NULL; + + sem_post(&pastebuf_request); + sem_wait(&pastebuf_set); + if(pastebuf!=NULL) { + ret=(char *)malloc(strlen(pastebuf)+1); + if(ret!=NULL) + strcpy(ret,pastebuf); + } + sem_post(&pastebuf_request); + return(ret); +} +#endif diff --git a/src/conio/sdl_con.h b/src/conio/sdl_con.h new file mode 100644 index 0000000000..3d79222887 --- /dev/null +++ b/src/conio/sdl_con.h @@ -0,0 +1,43 @@ +#ifndef _SDL_CON_H_ +#define _SDL_CON_H_ + +#ifdef __cplusplus +extern "C" { +#endif +/* Low-Level stuff (Shouldn't be used by ciolib programs */ +int sdl_init(void); +int sdl_load_font(char *filename, int width, int height, double scale); +int sdl_init_mode(int mode); +int sdl_setup_colours(void); +int sdl_draw_char(unsigned short vch, int xpos, int ypos); +int sdl_screen_redraw(void); + +/* High-level stuff */ +int sdl_puttext(int sx, int sy, int ex, int ey, void *fill); +int sdl_gettext(int sx, int sy, int ex, int ey, void *fill); +void sdl_textattr(int attr); +int sdl_kbhit(void); +void sdl_delay(long msec); +int sdl_wherey(void); +int sdl_wherex(void); +int sdl_putch(int ch); +void sdl_gotoxy(int x, int y); +void sdl_initciolib(long inmode); +void sdl_gettextinfo(struct text_info *info); +void sdl_setcursortype(int type); +int sdl_getch(void); +int sdl_getche(void); +int sdl_beep(void); +void sdl_textmode(int mode); +void sdl_settitle(const char *title); +int sdl_hidemouse(void); +int sdl_showmouse(void); +#if 0 +void sdl_copytext(const char *text, size_t buflen); +char *sdl_getcliptext(void); +#endif +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/conio/vgafont.h b/src/conio/vidmodes.c similarity index 97% rename from src/conio/vgafont.h rename to src/conio/vidmodes.c index d595d27811..2d0429344b 100644 --- a/src/conio/vgafont.h +++ b/src/conio/vidmodes.c @@ -1,35 +1,4 @@ -/* $Id$ */ - -/**************************************************************************** - * @format.tab-size 4 (Plain Text/Source Code File Header) * - * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * - * * - * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public License * - * as published by the Free Software Foundation; either version 2 * - * of the License, or (at your option) any later version. * - * See the GNU Lesser General Public License for more details: lgpl.txt or * - * http://www.fsf.org/copyleft/lesser.html * - * * - * Anonymous FTP access to the most recent released source is available at * - * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * - * * - * Anonymous CVS access to the development source and modification history * - * is available at cvs.synchro.net:/cvsroot/sbbs, example: * - * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * - * (just hit return, no password is necessary) * - * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * - * * - * For Synchronet coding style and modification guidelines, see * - * http://www.synchro.net/source.html * - * * - * You are encouraged to submit any modifications (preferably in Unix diff * - * format) via e-mail to mods@synchro.net * - * * - * Note: If this box doesn't appear square, then you need to fix your tabs. * - ****************************************************************************/ +#include "vidmodes.h" #define B_00000000_B 0x00 #define B_10000000_B 0x01 @@ -10792,3 +10761,151 @@ char vga_font_bitmap8[2048]={ ,B_00000000_B }; + +struct video_params vparams[36] = { + /* BW 40x25 */ + {BW40, GREYSCALE_PALETTE, 40, 25, 14, 15, 16, 8}, + /* CO 40x25 */ + {C40, COLOUR_PALETTE, 40, 25, 14, 15, 16, 8}, + /* BW 80x25 */ + {BW80, GREYSCALE_PALETTE, 80, 25, 14, 15, 16, 8}, + /* CO 80x25 */ + {C80, COLOUR_PALETTE, 80, 25, 14, 15, 16, 8}, + /* MONO */ + {MONO, 0, 80, 25, 14, 15, 16, 8}, + /* CO 40x14 */ + {C40X14, COLOUR_PALETTE, 40, 14, 14, 15, 16, 8}, + /* CO 40x21 */ + {C40X21, COLOUR_PALETTE, 40, 21, 14, 15, 16, 8}, + /* CO 40x28 */ + {C40X28, COLOUR_PALETTE, 40, 28, 12, 13, 14, 8}, + /* CO 40x43 */ + {C40X43, COLOUR_PALETTE, 40, 43, 7, 7, 8, 8}, + /* CO 40x50 */ + {C40X50, COLOUR_PALETTE, 40, 50, 7, 7, 8, 8}, + /* CO 40x60 */ + {C40X60, COLOUR_PALETTE, 40, 60, 7, 7, 8, 8}, + /* CO 80x14 */ + {C80X14, COLOUR_PALETTE, 80, 14, 14, 15, 16, 8}, + /* CO 80x21 */ + {C80X21, COLOUR_PALETTE, 80, 21, 14, 15, 16, 8}, + /* CO 80x28 */ + {C80X28, COLOUR_PALETTE, 80, 28, 12, 13, 14, 8}, + /* CO 80x43 */ + {C80X43, COLOUR_PALETTE, 80, 43, 7, 7, 8, 8}, + /* CO 80x50 */ + {C80X50, COLOUR_PALETTE, 80, 50, 7, 7, 8, 8}, + /* CO 80x60 */ + {C80X60, COLOUR_PALETTE, 80, 60, 7, 7, 8, 8}, + /* B 40x14 */ + {BW40X14, GREYSCALE_PALETTE, 40, 14, 14, 15, 16, 8}, + /* BW 40x21 */ + {BW40X21, GREYSCALE_PALETTE, 40, 21, 14, 15, 16, 8}, + /* BW 40x28 */ + {BW40X28, GREYSCALE_PALETTE, 40, 28, 12, 13, 14, 8}, + /* BW 40x43 */ + {BW40X43, GREYSCALE_PALETTE, 40, 43, 7, 7, 8, 8}, + /* BW 40x50 */ + {BW40X50, GREYSCALE_PALETTE, 40, 50, 7, 7, 8, 8}, + /* BW 40x60 */ + {BW40X60, GREYSCALE_PALETTE, 40, 60, 7, 7, 8, 8}, + /* BW 80x14 */ + {BW80X14, GREYSCALE_PALETTE, 80, 14, 14, 15, 16, 8}, + /* BW 80x21 */ + {BW80X21, GREYSCALE_PALETTE, 80, 21, 14, 15, 16, 8}, + /* BW 80x28 */ + {BW80X28, GREYSCALE_PALETTE, 80, 28, 12, 13, 14, 8}, + /* BW 80x43 */ + {BW80X43, GREYSCALE_PALETTE, 80, 43, 7, 7, 8, 8}, + /* BW 80x50 */ + {BW80X50, GREYSCALE_PALETTE, 80, 50, 7, 7, 8, 8}, + /* BW 80x60 */ + {BW80X60, GREYSCALE_PALETTE, 80, 60, 7, 7, 8, 8}, + /* MONO 80x14 */ + {MONO14, MONO_PALETTE, 80, 14, 14, 15, 16, 8}, + /* MONO 80x21 */ + {MONO21, MONO_PALETTE, 80, 21, 14, 15, 16, 8}, + /* MONO 80x28 */ + {MONO28, MONO_PALETTE, 80, 28, 12, 13, 14, 8}, + /* MONO 80x43 */ + {MONO43, MONO_PALETTE, 80, 43, 7, 7, 8, 8}, + /* MONO 80x50 */ + {MONO50, MONO_PALETTE, 80, 50, 7, 7, 8, 8}, + /* MONO 80x60 */ + {MONO60, MONO_PALETTE, 80, 60, 7, 7, 8, 8}, + /* Magical C4350 Mode */ + {C4350, COLOUR_PALETTE, 80, 50, 7, 7, 8, 8}, +}; + +unsigned char palettes[3][16] = { + /* Mono */ + { 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07 + }, + /* Black and White */ + { 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f + }, + /* Colour */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } +}; + +struct dac_colors dac_default16[16] = { + {0, 0, 0}, {0, 0, 42}, {0, 42, 0}, {0, 42, 42}, + {42, 0, 0}, {42, 0, 42}, {42, 21, 0}, {42, 42, 42}, + {21, 21, 21}, {21, 21, 63}, {21, 63, 21}, {21, 63, 63}, + {63, 21, 21}, {63, 21, 63}, {63, 63, 21}, {63, 63, 63} +}; + +struct dac_colors dac_default256[16] = { + {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}, + {255, 84, 84}, {255, 84, 255}, {255, 255, 84}, {255, 255, 255} +}; + +int find_vmode(int mode) +{ + unsigned i; + + for (i = 0; i < NUMMODES; i++) + if (vparams[i].mode == mode) + return i; + + return -1; +} + +int load_vmode(struct video_stats *vs, int mode) +{ + int i; + unsigned short *newvmem; + + i=find_vmode(mode); + if(i==-1) + return(-1); + newvmem=(unsigned short *)realloc(vs->vmem, vparams[i].cols*vparams[i].rows*sizeof(unsigned short)); + if(newvmem==NULL) + return(-1); + vs->vmem=newvmem; + vs->rows=vparams[i].rows; + vs->cols=vparams[i].cols; + vs->curs_start=vparams[i].curs_start; + vs->curs_end=vparams[i].curs_end; + vs->default_curs_start=vparams[i].curs_start; + vs->default_curs_end=vparams[i].curs_end; + if(vs->curs_row < 0) + vs->curs_row=0; + if(vs->curs_row >= vparams[i].rows) + vs->curs_row=vparams[i].rows-1; + if(vs->curs_col < 0) + vs->curs_col=0; + if(vs->curs_col >= vparams[i].cols) + vs->curs_col=vparams[i].cols-1; + vs->palette=palettes[vparams[i].palette]; + vs->charheight=vparams[i].charheight; + vs->charwidth=vparams[i].charwidth; + vs->mode=mode; + return(0); +} diff --git a/src/conio/vidmodes.h b/src/conio/vidmodes.h index c7a614246f..227c4d67cd 100644 --- a/src/conio/vidmodes.h +++ b/src/conio/vidmodes.h @@ -47,127 +47,54 @@ struct video_params { int charwidth; }; -enum { - MONO_PALETTE - ,GREYSCALE_PALETTE - ,COLOUR_PALETTE -}; - -static struct video_params vparams[] = { - /* BW 40x25 */ - {BW40, GREYSCALE_PALETTE, 40, 25, 14, 15, 16, 8}, - /* CO 40x25 */ - {C40, COLOUR_PALETTE, 40, 25, 14, 15, 16, 8}, - /* BW 80x25 */ - {BW80, GREYSCALE_PALETTE, 80, 25, 14, 15, 16, 8}, - /* CO 80x25 */ - {C80, COLOUR_PALETTE, 80, 25, 14, 15, 16, 8}, - /* MONO */ - {MONO, 0, 80, 25, 14, 15, 16, 8}, - /* CO 40x14 */ - {C40X14, COLOUR_PALETTE, 40, 14, 14, 15, 16, 8}, - /* CO 40x21 */ - {C40X21, COLOUR_PALETTE, 40, 21, 14, 15, 16, 8}, - /* CO 40x28 */ - {C40X28, COLOUR_PALETTE, 40, 28, 12, 13, 14, 8}, - /* CO 40x43 */ - {C40X43, COLOUR_PALETTE, 40, 43, 7, 7, 8, 8}, - /* CO 40x50 */ - {C40X50, COLOUR_PALETTE, 40, 50, 7, 7, 8, 8}, - /* CO 40x60 */ - {C40X60, COLOUR_PALETTE, 40, 60, 7, 7, 8, 8}, - /* CO 80x14 */ - {C80X14, COLOUR_PALETTE, 80, 14, 14, 15, 16, 8}, - /* CO 80x21 */ - {C80X21, COLOUR_PALETTE, 80, 21, 14, 15, 16, 8}, - /* CO 80x28 */ - {C80X28, COLOUR_PALETTE, 80, 28, 12, 13, 14, 8}, - /* CO 80x43 */ - {C80X43, COLOUR_PALETTE, 80, 43, 7, 7, 8, 8}, - /* CO 80x50 */ - {C80X50, COLOUR_PALETTE, 80, 50, 7, 7, 8, 8}, - /* CO 80x60 */ - {C80X60, COLOUR_PALETTE, 80, 60, 7, 7, 8, 8}, - /* B 40x14 */ - {BW40X14, GREYSCALE_PALETTE, 40, 14, 14, 15, 16, 8}, - /* BW 40x21 */ - {BW40X21, GREYSCALE_PALETTE, 40, 21, 14, 15, 16, 8}, - /* BW 40x28 */ - {BW40X28, GREYSCALE_PALETTE, 40, 28, 12, 13, 14, 8}, - /* BW 40x43 */ - {BW40X43, GREYSCALE_PALETTE, 40, 43, 7, 7, 8, 8}, - /* BW 40x50 */ - {BW40X50, GREYSCALE_PALETTE, 40, 50, 7, 7, 8, 8}, - /* BW 40x60 */ - {BW40X60, GREYSCALE_PALETTE, 40, 60, 7, 7, 8, 8}, - /* BW 80x14 */ - {BW80X14, GREYSCALE_PALETTE, 80, 14, 14, 15, 16, 8}, - /* BW 80x21 */ - {BW80X21, GREYSCALE_PALETTE, 80, 21, 14, 15, 16, 8}, - /* BW 80x28 */ - {BW80X28, GREYSCALE_PALETTE, 80, 28, 12, 13, 14, 8}, - /* BW 80x43 */ - {BW80X43, GREYSCALE_PALETTE, 80, 43, 7, 7, 8, 8}, - /* BW 80x50 */ - {BW80X50, GREYSCALE_PALETTE, 80, 50, 7, 7, 8, 8}, - /* BW 80x60 */ - {BW80X60, GREYSCALE_PALETTE, 80, 60, 7, 7, 8, 8}, - /* MONO 80x14 */ - {MONO14, MONO_PALETTE, 80, 14, 14, 15, 16, 8}, - /* MONO 80x21 */ - {MONO21, MONO_PALETTE, 80, 21, 14, 15, 16, 8}, - /* MONO 80x28 */ - {MONO28, MONO_PALETTE, 80, 28, 12, 13, 14, 8}, - /* MONO 80x43 */ - {MONO43, MONO_PALETTE, 80, 43, 7, 7, 8, 8}, - /* MONO 80x50 */ - {MONO50, MONO_PALETTE, 80, 50, 7, 7, 8, 8}, - /* MONO 80x60 */ - {MONO60, MONO_PALETTE, 80, 60, 7, 7, 8, 8}, - /* Magical C4350 Mode */ - {C4350, COLOUR_PALETTE, 80, 50, 7, 7, 8, 8}, -}; - -#define NUMMODES (sizeof(vparams) / sizeof(struct video_params)) - -static unsigned char palettes[][16] = { - /* Mono */ - { 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07 - }, - /* Black and White */ - { 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x08, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f - }, - /* Colour */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f - } +struct video_stats { + int rows; + int cols; + int curs_row; + int curs_col; + int curs_start; + int curs_end; + int default_curs_start; + int default_curs_end; + int mode; + int charheight; + int charwidth; + int blink; + int currattr; + int scaling; + unsigned char *palette; + unsigned short *vmem; }; -/* Entry type for the DAC table. Each value is actually 6 bits wide. */ +/* Entry type for the DAC table. */ struct dac_colors { - BYTE red; - BYTE green; - BYTE blue; + unsigned char red; + unsigned char green; + unsigned char blue; }; -static struct dac_colors dac_default16[] = { - {0, 0, 0}, {0, 0, 42}, {0, 42, 0}, {0, 42, 42}, - {42, 0, 0}, {42, 0, 42}, {42, 21, 0}, {42, 42, 42}, - {21, 21, 21}, {21, 21, 63}, {21, 63, 21}, {21, 63, 63}, - {63, 21, 21}, {63, 21, 63}, {63, 63, 21}, {63, 63, 63} +enum { + MONO_PALETTE + ,GREYSCALE_PALETTE + ,COLOUR_PALETTE }; -static int find_vmode(int mode) -{ - unsigned i; - - for (i = 0; i < NUMMODES; i++) - if (vparams[i].mode == mode) - return i; +extern struct video_params vparams[36]; +#define NUMMODES (sizeof(vparams) / sizeof(struct video_params)) +extern unsigned char palettes[3][16]; +extern struct dac_colors dac_default16[16]; +extern struct dac_colors dac_default256[16]; +extern char vga_font_bitmap[4096]; +extern char vga_font_bitmap14[3584]; +extern char vga_font_bitmap8[2048]; - return -1; +#ifdef __cplusplus +extern "C" { +#endif +int find_vmode(int mode); +int load_vmode(struct video_stats *vs, int mode); +#ifdef __cplusplus } +#endif #endif -- GitLab