Newer
Older
#if (defined(__MACH__) && defined(__APPLE__))
#include <Carbon/Carbon.h>
#endif
#include <stdarg.h>
#include <stdio.h> /* NULL */
#include <string.h>
#ifdef __unix__
#include <dlfcn.h>
#include "gen_defs.h"
#include "genwrap.h"
#include "dirwrap.h"
#include "xpbeep.h"
#if (defined CIOLIB_IMPORTS)
#undef CIOLIB_IMPORTS
#endif
#if (defined CIOLIB_EXPORTS)
#undef CIOLIB_EXPORTS
#endif
#include "ciolib.h"
#include "vidmodes.h"
#include "allfonts.h"
#include "SDL.h"
/********************************************************/
/* Low Level Stuff */
/* This should all be called from the same thread! */
/********************************************************/
SDL_Surface *win=NULL;
SDL_mutex *sdl_keylock;
SDL_mutex *sdl_ufunc_lock;
SDL_sem *sdl_key_pending;
SDL_sem *sdl_init_complete;
SDL_sem *sdl_ufunc_ret;
int sdl_ufunc_retval;
SDL_Surface *sdl_font=NULL;
SDL_Surface *sdl_cursor=NULL;
static int lastcursor_x=0;
static int lastcursor_y=0;
static int sdl_current_font=-99;
static int lastfg=-1;
static int lastbg=-1;
static unsigned int sdl_pending_mousekeys=0;
static SDL_Thread *blinker_thread;
static SDL_Thread *mouse_thread;
struct video_stats vstat;
/* 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_SETTITLE
,SDL_USEREVENT_SETNAME
,SDL_USEREVENT_SETVIDMODE
,SDL_USEREVENT_SHOWMOUSE
,SDL_USEREVENT_HIDEMOUSE
,SDL_USEREVENT_COPY
,SDL_USEREVENT_PASTE
,SDL_USEREVENT_LOADFONT
};
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},
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
{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, 0x7f, 0x7f, 0x5300, 0x9300},
{SDLK_KP_DIVIDE, '/', '/', 0x9500, 0xa400},
{SDLK_KP_ENTER, 0x0d, 0x0d, 0x0a, 0xa600},
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
{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};
/* *nix copy/paste stuff */
SDL_sem *sdl_pastebuf_set;
SDL_sem *sdl_pastebuf_copied;
SDL_mutex *sdl_copybuf_mutex;
char *sdl_copybuf=NULL;
char *sdl_pastebuf=NULL;
#if !defined(NO_X) && defined(__unix__)
#include "SDL_syswm.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#define CONSOLE_CLIPBOARD XA_PRIMARY
int sdl_x11available=0;
/* X functions */
struct x11 {
int (*XFree) (void *data);
Window (*XGetSelectionOwner) (Display*, Atom);
int (*XConvertSelection) (Display*, Atom, Atom, Atom, Window, Time);
int (*XGetWindowProperty) (Display*, Window, Atom, long, long, Bool, Atom, Atom*, int*, unsigned long *, unsigned long *, unsigned char **);
int (*XChangeProperty) (Display*, Window, Atom, Atom, int, int, _Xconst unsigned char*, int);
Status (*XSendEvent) (Display*, Window, Bool, long, XEvent*);
int (*XSetSelectionOwner) (Display*, Atom, Window, Time);
};
struct x11 sdl_x11;
#endif
/* Called from all threads */
void sdl_user_func(int func, ...)
{
unsigned int *i;
va_list argptr;
void **args;
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:
/* Only send event if the last event wasn't already handled */
case SDL_USEREVENT_SETNAME:
if((ev.user.data1=strdup(va_arg(argptr, char *)))==NULL) {
va_end(argptr);
return;
}
case SDL_USEREVENT_SETICON:
ev.user.data1=va_arg(argptr, void *);
if((ev.user.data2=(unsigned long *)malloc(sizeof(unsigned long)))==NULL) {
va_end(argptr);
return;
}
*(unsigned long *)ev.user.data2=va_arg(argptr, unsigned long);
while(sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, 0xffffffff)!=1);
break;
case SDL_USEREVENT_SETTITLE:
if((ev.user.data1=strdup(va_arg(argptr, char *)))==NULL) {
va_end(argptr);
return;
}
break;
case SDL_USEREVENT_SETVIDMODE:
if((ev.user.data1=(void *)malloc(sizeof(int)))==NULL) {
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);
va_end(argptr);
return;
}
*((int *)ev.user.data2)=va_arg(argptr, int);
case SDL_USEREVENT_COPY:
case SDL_USEREVENT_PASTE:
case SDL_USEREVENT_SHOWMOUSE:
case SDL_USEREVENT_HIDEMOUSE:
}
va_end(argptr);
}
/* Called from main thread only */
int sdl_user_func_ret(int func, ...)
{
unsigned int *i;
va_list argptr;
void **args;
SDL_Event ev;
int passed=FALSE;
char *p;
sdl.mutexP(sdl_ufunc_lock);
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_LOADFONT:
p=va_arg(argptr, char *);
if(p!=NULL) {
if((ev.user.data1=strdup(p))==NULL) {
va_end(argptr);
}
}
while(sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, 0xffffffff)!=1);
passed=TRUE;
break;
case SDL_USEREVENT_QUIT:
while(sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, 0xffffffff)!=1);
passed=TRUE;
break;
}
if(passed)
sdl.SemWait(sdl_ufunc_ret);
else
sdl_ufunc_retval=-1;
sdl.mutexV(sdl_ufunc_lock);
va_end(argptr);
return(sdl_ufunc_retval);
}
void exit_sdl_con(void)
{
sdl_user_func_ret(SDL_USEREVENT_QUIT);
}
#if (defined(__MACH__) && defined(__APPLE__))
int sdl_using_quartz=0;
#endif
#if !defined(NO_X) && defined(__unix__)
int sdl_using_x11()
{
char driver[16];
return(FALSE);
if(!strcmp(driver,"x11"))
return(TRUE);
if(!strcmp(driver,"dga"))
return(TRUE);
return(FALSE);
}
#endif
void sdl_copytext(const char *text, size_t buflen)
{
#if (defined(__MACH__) && defined(__APPLE__))
if(sdl_using_quartz) {
FREE_AND_NULL(sdl_copybuf);
sdl_copybuf=(char *)malloc(buflen+1);
if(sdl_copybuf!=NULL) {
strcpy(sdl_copybuf, text);
sdl_user_func(SDL_USEREVENT_COPY,0,0,0,0);
return;
}
#endif
#if !defined(NO_X) && defined(__unix__)
if(sdl_x11available && sdl_using_x11()) {
FREE_AND_NULL(sdl_copybuf);
sdl_copybuf=(char *)malloc(buflen+1);
if(sdl_copybuf!=NULL) {
strcpy(sdl_copybuf, text);
sdl_user_func(SDL_USEREVENT_COPY,0,0,0,0);
}
FREE_AND_NULL(sdl_copybuf);
sdl_copybuf=(char *)malloc(buflen+1);
if(sdl_copybuf!=NULL)
strcpy(sdl_copybuf, text);
return;
}
char *sdl_getcliptext(void)
{
char *ret=NULL;
#if (defined(__MACH__) && defined(__APPLE__))
if(sdl_using_quartz) {
sdl_user_func(SDL_USEREVENT_PASTE,0,0,0,0);
if(sdl_pastebuf!=NULL) {
ret=(char *)malloc(strlen(sdl_pastebuf)+1);
if(ret!=NULL)
strcpy(ret,sdl_pastebuf);
#if !defined(NO_X) && defined(__unix__)
if(sdl_x11available && sdl_using_x11()) {
sdl_user_func(SDL_USEREVENT_PASTE,0,0,0,0);
if(sdl_pastebuf!=NULL) {
ret=(char *)malloc(strlen(sdl_pastebuf)+1);
if(ret!=NULL)
strcpy(ret,sdl_pastebuf);
ret=(char *)malloc(strlen(sdl_pastebuf)+1);
if(ret!=NULL)
strcpy(ret,sdl_copybuf);
return(ret);
}
/* Blinker Thread */
while(1) {
SLEEP(500);
if(vstat.blink)
vstat.blink=FALSE;
else
vstat.blink=TRUE;
sdl_user_func(SDL_USEREVENT_UPDATERECT,0,0,0,0);
/* Called from main thread only (Passes Event) */
int sdl_init_mode(int mode)
struct video_params vmode;
int idx; /* Index into vmode */
int i;
int oldcols=vstat.cols;
if(load_vmode(&vstat, mode))
return(-1);
/* Deal with 40 col doubling */
if(oldcols != vstat.cols) {
if(oldcols == 40)
vstat.scaling /= 2;
if(vstat.cols == 40)
vstat.scaling *= 2;
}
if(vstat.scaling < 1)
vstat.scaling = 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;
vstat.mode=mode;
sdl_user_func(SDL_USEREVENT_UPDATERECT,0,0,0,0);
return(0);
}
/* Called from main thread only (Passes Event) */
int sdl_draw_char(unsigned short vch, int xpos, int ypos, int update)
vstat.vmem[ypos*vstat.cols+xpos]=vch;
if(update) {
#if 0 /* Currently, an update always updates the whole screen... so don't hold the mutex */
sdl_user_func(SDL_USEREVENT_UPDATERECT,xpos*vstat.charwidth*vstat.scaling,ypos*vstat.charheight*vstat.scaling,vstat.charwidth*vstat.scaling,vstat.charheight*vstat.scaling);
#else
sdl_user_func(SDL_USEREVENT_UPDATERECT,0,0,0,0);
#endif
return(0);
/* Called from main thread only (Passes Event) */
#if !defined(NO_X) && defined(__unix__)
void *dl;
#endif
vstat.vmem=NULL;
vstat.scaling=1;
sdl_updated=1;
if(mode==CIOLIB_MODE_SDL_FULLSCREEN)
fullscreen=1;
sdl_init_mode(3);
sdl_user_func(SDL_USEREVENT_INIT);
if(sdl_init_good) {
cio_api.mode=fullscreen?CIOLIB_MODE_SDL_FULLSCREEN:CIOLIB_MODE_SDL;
FreeConsole();
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
#endif
#if !defined(NO_X) && defined(__unix__)
#if defined(__APPLE__) && defined(__MACH__) && defined(__POWERPC__)
if((dl=dlopen("/usr/X11R6/lib/libX11.dylib",RTLD_LAZY|RTLD_GLOBAL))!=NULL) {
#else
if((dl=dlopen("libX11.so",RTLD_LAZY))!=NULL) {
#endif
sdl_x11available=TRUE;
if(sdl_x11available && (sdl_x11.XFree=dlsym(dl,"XFree"))==NULL) {
dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XGetSelectionOwner=dlsym(dl,"XGetSelectionOwner"))==NULL) {
dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XConvertSelection=dlsym(dl,"XConvertSelection"))==NULL) {
dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XGetWindowProperty=dlsym(dl,"XGetWindowProperty"))==NULL) {
dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XChangeProperty=dlsym(dl,"XChangeProperty"))==NULL) {
dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XSendEvent=dlsym(dl,"XSendEvent"))==NULL) {
dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XSetSelectionOwner=dlsym(dl,"XSetSelectionOwner"))==NULL) {
dlclose(dl);
sdl_x11available=FALSE;
}
}
if(sdl_x11available)
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
}
/********************************************************/
/* 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;
vstat.vmem[y*vstat.cols+x]=sch;
sdl_user_func(SDL_USEREVENT_UPDATERECT,0,0,0,0);
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
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;
ret=(sdl_key!=sdl_keynext);
return(ret);
}
/* Called from main thread only */
void sdl_delay(long msec)
{
}
/* 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);
/* Called from BOTH THREADS */
int sdl_beep(void)
{
/* ToDo BEEP! */
BEEP(440,100);
return(0);
}
/* 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;
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
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)
{
if((x-1 != vstat.curs_col) || (y-1 !=vstat.curs_row)) {
vstat.curs_row=y-1;
vstat.curs_col=x-1;
sdl_user_func(SDL_USEREVENT_UPDATERECT,0,0,0,0);
}
}
/* 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;
}
/* Called from main thread only */
int sdl_getch(void)
{
int ch;
ch=sdl_keybuf[sdl_key++];
if(sdl_pending_mousekeys) {
sdl_keybuf[sdl_keynext++]=CIO_KEY_MOUSE & 0xff;
sdl.SemPost(sdl_key_pending);
sdl_keybuf[sdl_keynext++]=CIO_KEY_MOUSE >> 8;
sdl.SemPost(sdl_key_pending);
sdl_pending_mousekeys--;
}
return(ch);
}
/* Called from main thread only */
int sdl_getche(void)
{
int ch;
while(1) {
ch=sdl_getch();
if(ch) {
putch(ch);
return(ch);
}
sdl_getch();
}
}
/* Called from main thread only */
void sdl_textmode(int mode)
{
sdl_init_mode(mode);
}
/* Called from main thread only (Passes Event) */
int sdl_setname(const char *name)
{
sdl_user_func(SDL_USEREVENT_SETNAME,name);
return(0);
}
/* Called from main thread only (Passes Event) */
int sdl_seticon(const void *icon, unsigned long size)
{
sdl_user_func(SDL_USEREVENT_SETICON,icon,size);
return(0);
}
/* 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);
int sdl_loadfont(char *filename)
{
int retval;
retval=sdl_user_func_ret(SDL_USEREVENT_LOADFONT,filename);
return(retval);
}
int sdl_setfont(int font, int force)
{
int changemode=0;
int newmode=-1;
if(font < 0 || font>(sizeof(conio_fontdata)/sizeof(struct conio_font_data_struct)-2))
return(-1);
if(conio_fontdata[font].eight_by_sixteen!=NULL)
newmode=C80;
else if(conio_fontdata[font].eight_by_fourteen!=NULL)
newmode=C80X28;
else if(conio_fontdata[font].eight_by_eight!=NULL)
newmode=C80X50;
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
switch(vstat.charheight) {
case 8:
if(conio_fontdata[font].eight_by_eight==NULL) {
if(force)
return(-1);
else
changemode=1;
}
break;
case 14:
if(conio_fontdata[font].eight_by_fourteen==NULL) {
if(force)
return(-1);
else
changemode=1;
}
break;
case 16:
if(conio_fontdata[font].eight_by_sixteen==NULL) {
if(force)
return(-1);
else
changemode=1;
}
break;
}
if(changemode && newmode==-1)
return(-1);
sdl_current_font=font;
if(changemode)
sdl_init_mode(3);
return(sdl_user_func_ret(SDL_USEREVENT_LOADFONT,NULL));
}
int sdl_getfont(void)
{
return(sdl_current_font);
}
/* Called from event thread only */
void sdl_add_key(unsigned int keyval)
{
if(keyval==0xa600) {
fullscreen=!fullscreen;
cio_api.mode=fullscreen?CIOLIB_MODE_SDL_FULLSCREEN:CIOLIB_MODE_SDL;

deuce
committed
sdl_user_func(SDL_USEREVENT_SETVIDMODE,vstat.charwidth*vstat.cols, vstat.charheight*vstat.rows);
return;
}
if(keyval <= 0xffff) {
if(sdl_keynext+1==sdl_key) {
sdl_beep();
return;
}
if((sdl_keynext+2==sdl_key) && keyval > 0xff) {
if(keyval==CIO_KEY_MOUSE)
sdl_pending_mousekeys++;
else
sdl_beep();