Newer
Older
#if (defined(__MACH__) && defined(__APPLE__))
#include <Carbon/Carbon.h>
#endif
#include <stdarg.h>
#include <stdio.h> /* NULL */
#include <string.h>
#include "gen_defs.h"
#include "genwrap.h"
#include "dirwrap.h"
#include "xpbeep.h"
#ifdef __unix__
#include <xp_dl.h>
#endif
#if (defined CIOLIB_IMPORTS)
#undef CIOLIB_IMPORTS
#endif
#if (defined CIOLIB_EXPORTS)
#undef CIOLIB_EXPORTS
#endif
#include "ciolib.h"
#include "vidmodes.h"
#include "SDL.h"
int bitmap_width,bitmap_height;
/* 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 */
/* *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;
SDL_sem *sdl_ufunc_ret;
int sdl_ufunc_retval;
SDL_mutex *funcret_mutex;
SDL_sem *sdl_flush_sem;
int pending_updates=0;
int sdl_init_good=0;
SDL_mutex *sdl_keylock;
SDL_sem *sdl_key_pending;
static unsigned int sdl_pending_mousekeys=0;
Uint32 sdl_dac_default[sizeof(dac_default)/sizeof(struct dac_colors)];
SDL_Rect *upd_rects=NULL;
int rectspace=0;
int rectsused=0;
struct yuv_settings {
int enabled;
int win_width;
int win_height;
SDL_Overlay *overlay;
Uint8 colours[sizeof(dac_default)/sizeof(struct dac_colors)][3];
};
static struct yuv_settings yuv={0,0,0,0,0,0,0,NULL};
struct sdl_keyvals {
int keysym
,key
,shift
,ctrl
,alt;
};
struct update_rect {
int x;
int y;
int width;
int height;
unsigned char *data;
};
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
};
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},
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
174
175
176
177
178
179
180
181
182
183
184
185
{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},
{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_QUOTE, '\'', '"', 0, 0x2800},
{SDLK_COMMA, ',', '<', 0, 0x3300},
{SDLK_PERIOD, '.', '>', 0, 0x3400},
{SDLK_BACKQUOTE, '`', '~', 0, 0x2900},
{0, 0, 0, 0, 0} /** END **/
};
#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
void RGBtoYUV(Uint8 r, Uint8 g, Uint8 b, Uint8 *yuv_array, int monochrome, int luminance)
{
if (monochrome)
{
#if 0 /* these are the two formulas that I found on the FourCC site... */
yuv_array[0] = 0.299*r + 0.587*g + 0.114*b;
yuv_array[1] = 128;
yuv_array[2] = 128;
#else
yuv_array[0] = (Uint8)((0.257 * r) + (0.504 * g) + (0.098 * b) + 16);
yuv_array[1] = 128;
yuv_array[2] = 128;
#endif
}
else
{
#if 0 /* these are the two formulas that I found on the FourCC site... */
yuv_array[0] = 0.299*r + 0.587*g + 0.114*b;
yuv_array[1] = (b-yuv[0])*0.565 + 128;
yuv_array[2] = (r-yuv[0])*0.713 + 128;
#else
yuv_array[0] = (Uint8)((0.257 * r) + (0.504 * g) + (0.098 * b) + 16);
yuv_array[1] = (Uint8)(128 - (0.148 * r) - (0.291 * g) + (0.439 * b));
yuv_array[2] = (Uint8)(128 + (0.439 * r) - (0.368 * g) - (0.071 * b));
#endif
}
if (luminance!=100)
yuv_array[0]=yuv_array[0]*luminance/100;
}
void yuv_fillrect(SDL_Overlay *overlay, SDL_Rect *r, int dac_entry)
int uplane,vplane; /* Planar formats */
int y0pack, y1pack, u0pack, v0pack; /* Packed formats */
if(!overlay)
return;
if(r->x > overlay->w || r->y > overlay->h)
return;
if(r->x + r->w > overlay->w)
r->w=overlay->w-r->x;
if(r->y + r->h > overlay->h)
r->h=overlay->h-r->y;
yuv.changed=1;
switch(overlay->format) {
case SDL_IYUV_OVERLAY:
/* YUV 4:2:0 NxM Y followed by (N/2)x(M/2) U and V (12bpp) */
uplane=1;
vplane=2;
goto planar;
case SDL_YV12_OVERLAY:
/* YUV 4:2:0 NxM Y followed by (N/2)x(M/2) V and U (12bpp) */
goto planar;
case SDL_YUY2_OVERLAY:
y0pack=0;
u0pack=1;
v0pack=3;
goto packed;
case SDL_UYVY_OVERLAY:
goto packed;
case SDL_YVYU_OVERLAY:
y1pack=2;
u0pack=3;
goto packed;
}
return;
planar:
sdl.LockYUVOverlay(overlay);
Uint8 *Y,*U,*V;
int odd_line;
int uvlen=(r->w)>>1;
int uvoffset=overlay->pitches[1]*((r->y+1)>>1)+((r->x+1)>>1);
odd_line=(r->y)&1;
Y=overlay->pixels[0]+overlay->pitches[0]*(r->y)+(r->x);
U=overlay->pixels[uplane]+uvoffset;
V=overlay->pixels[vplane]+uvoffset;
for(y=0; y<r->h; y++)
{
memset(Y, yuv.colours[dac_entry][0], r->w);
Y+=overlay->pitches[0];
if(odd_line) {
U+=overlay->pitches[uplane];
V+=overlay->pitches[vplane];
}
else {
memset(U, yuv.colours[dac_entry][1], uvlen);
memset(V, yuv.colours[dac_entry][2], uvlen);
}
sdl.UnlockYUVOverlay(overlay);
return;
packed:
sdl.LockYUVOverlay(overlay);
{
int x,y;
Uint32 colour;
Uint32 *offset;
colour_array[y0pack]=yuv.colours[dac_entry][0];
colour_array[y1pack]=yuv.colours[dac_entry][0];
colour_array[u0pack]=yuv.colours[dac_entry][1];
colour_array[v0pack]=yuv.colours[dac_entry][2];
offset=(Uint32 *)(overlay->pixels[0]+overlay->pitches[0]*(r->y));
for(y=0; y<r->h; y++)
{
for(x=0; x<r->w; x+=2)
sdl.UnlockYUVOverlay(overlay);
void sdl_user_func(int func, ...)
{
va_list argptr;
ev.type=SDL_USEREVENT;
ev.user.data1=NULL;
ev.user.data2=NULL;
ev.user.code=func;
va_start(argptr, func);
switch(func) {
ev.user.data1=va_arg(argptr, void *);
if((ev.user.data2=(unsigned long *)malloc(sizeof(unsigned long)))==NULL) {
*(unsigned long *)ev.user.data2=va_arg(argptr, unsigned long);
while(sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, 0xffffffff)!=1)
YIELD();
case SDL_USEREVENT_SETTITLE:
if((ev.user.data1=strdup(va_arg(argptr, char *)))==NULL) {
va_end(argptr);
return;
}
while(sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, 0xffffffff)!=1)
YIELD();
ev.user.data1=va_arg(argptr, struct update_rect *);
while(sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, 0xffffffff)!=1)
YIELD();
case SDL_USEREVENT_COPY:
case SDL_USEREVENT_PASTE:
case SDL_USEREVENT_SHOWMOUSE:
case SDL_USEREVENT_HIDEMOUSE:
while(sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, 0xffffffff)!=1)
YIELD();
}
va_end(argptr);
}
/* Called from main thread only */
int sdl_user_func_ret(int func, ...)
{
va_list argptr;
SDL_Event ev;
int passed=FALSE;
sdl.mutexP(funcret_mutex);
ev.type=SDL_USEREVENT;
ev.user.data1=NULL;
ev.user.data2=NULL;
ev.user.code=func;
va_start(argptr, func);
while(1) {
switch(func) {
case SDL_USEREVENT_SETVIDMODE:
case SDL_USEREVENT_FLUSH:
case SDL_USEREVENT_INIT:
case SDL_USEREVENT_QUIT:
while(sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, 0xffffffff)!=1)
YIELD();
passed=TRUE;
break;
}
if(passed) {
if(sdl.SemWaitTimeout(sdl_ufunc_ret, 100)==0)
break;
}
else {
sdl_ufunc_retval=-1;
}
va_end(argptr);
sdl.mutexV(funcret_mutex);
return(sdl_ufunc_retval);
}
void exit_sdl_con(void)
{
sdl_user_func_ret(SDL_USEREVENT_QUIT);
}
void sdl_copytext(const char *text, size_t buflen)
{
#if (defined(__MACH__) && defined(__APPLE__))
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);
return;
}
char *sdl_getcliptext(void)
{
char *ret=NULL;
#if (defined(__MACH__) && defined(__APPLE__))
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);
else
sdl.SemPost(sdl_pastebuf_copied);
#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);
}
else
ret=NULL;
sdl.SemPost(sdl_pastebuf_copied);
return(ret);
}
void sdl_drawrect(int xoffset,int yoffset,int width,int height,unsigned char *data)
rect=(struct update_rect *)malloc(sizeof(struct update_rect));
if(rect) {
rect->x=xoffset;
rect->y=yoffset;
rect->width=width;
rect->height=height;
rect->data=data;
sdl_user_func(SDL_USEREVENT_UPDATERECT, rect);
}
else
free(data);
sdl_user_func_ret(SDL_USEREVENT_FLUSH);
int sdl_init_mode(int mode)
int oldcols=vstat.cols;
sdl_user_func_ret(SDL_USEREVENT_FLUSH);
/* Deal with 40 col doubling */
if(yuv.enabled) {
vstat.scaling=2;
}
else {
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_ret(SDL_USEREVENT_SETVIDMODE);
return(0);
}
/* Called from main thread only (Passes Event) */
#if !defined(NO_X) && defined(__unix__)
dll_handle dl;
const char *libnames[2]={"X11", NULL};
if(init_sdl_video()) {
fprintf(stderr, "SDL Video Init Failed\n");
bitmap_init(sdl_drawrect, sdl_flush);
if(mode==CIOLIB_MODE_SDL_FULLSCREEN)
fullscreen=1;
yuv.enabled=1;
if(mode==CIOLIB_MODE_SDL_YUV_FULLSCREEN) {
yuv.enabled=1;
fullscreen=1;
}
#if (SDL_MAJOR_VERSION > 1) || (SDL_MINOR_VERSION > 2) || (SDL_PATCHLEVEL > 9)
if(yuv.enabled) {
if(linked->major > 1 || linked->minor > 2 || linked->patch > 9) {
yuv.screen_width=sdl.initial_videoinfo.current_w;
yuv.screen_height=sdl.initial_videoinfo.current_h;
}
if(yuv.enabled && yuv.overlay==NULL) {
fprintf(stderr, "YUV Enabled, but overlay is NULL\n");
sdl_init_good=0;
sdl_user_func_ret(SDL_USEREVENT_INIT);
if(sdl_init_good) {
cio_api.mode=fullscreen?CIOLIB_MODE_SDL_FULLSCREEN:CIOLIB_MODE_SDL;
FreeConsole();
#endif
#if !defined(NO_X) && defined(__unix__)
dl=xp_dlopen(libnames,RTLD_LAZY|RTLD_GLOBAL,7);
if(dl!=NULL) {
sdl_x11available=TRUE;
if(sdl_x11available && (sdl_x11.XFree=xp_dlsym(dl,XFree))==NULL) {
xp_dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XGetSelectionOwner=xp_dlsym(dl,XGetSelectionOwner))==NULL) {
xp_dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XConvertSelection=xp_dlsym(dl,XConvertSelection))==NULL) {
xp_dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XGetWindowProperty=xp_dlsym(dl,XGetWindowProperty))==NULL) {
xp_dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XChangeProperty=xp_dlsym(dl,XChangeProperty))==NULL) {
xp_dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XSendEvent=xp_dlsym(dl,XSendEvent))==NULL) {
xp_dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XSetSelectionOwner=xp_dlsym(dl,XSetSelectionOwner))==NULL) {
xp_dlclose(dl);
sdl_x11available=FALSE;
}
}
if(sdl_x11available)
}
/* Called from main thread only */
int sdl_kbhit(void)
{
int ret;
ret=(sdl_key!=sdl_keynext);
return(ret);
}
/* Called from main thread only */
int sdl_getch(void)
{
int ch;
/* This always frees up space in keybuf for one more char */
ch=sdl_keybuf[sdl_key++];
/* If we have missed mouse keys, tack them on to the end of the buffer now */
if(sdl_pending_mousekeys) {
if(sdl_pending_mousekeys & 1) /* Odd number... second char */
sdl_keybuf[sdl_keynext++]=CIO_KEY_MOUSE >> 8;
else /* Even number... first char */
sdl_keybuf[sdl_keynext++]=CIO_KEY_MOUSE & 0xff;
sdl.SemPost(sdl_key_pending);
sdl_pending_mousekeys--;
}
return(ch);
}
/* 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_get_window_info(int *width, int *height, int *xpos, int *ypos)
{
if(width)
if(xpos)
*xpos=-1;
if(ypos)
*ypos=-1;
return(0);
}
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
/* Called from events thread only */
int sdl_setup_colours(SDL_Surface *surf)
{
int i;
int ret=0;
SDL_Color co[sizeof(dac_default)/sizeof(struct dac_colors)];
for(i=0; i<(sizeof(dac_default)/sizeof(struct dac_colors)); i++) {
co[i].r=dac_default[i].red;
co[i].g=dac_default[i].green;
co[i].b=dac_default[i].blue;
}
sdl.SetColors(surf, co, 0, sizeof(dac_default)/sizeof(struct dac_colors));
for(i=0; i<(sizeof(dac_default)/sizeof(struct dac_colors)); i++) {
sdl_dac_default[i]=sdl.MapRGB(win->format, co[i].r, co[i].g, co[i].b);
}
return(ret);
}
int sdl_setup_yuv_colours(void)
{
int i;
int ret=0;
if(yuv.enabled) {
for(i=0; i<(sizeof(dac_default)/sizeof(struct dac_colors)); i++) {
RGBtoYUV(dac_default[i].red, dac_default[i].green, dac_default[i].blue, &(yuv.colours[i][0]), 0, 100);
}
}
return(ret);
}
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
void setup_surfaces(void)
{
int char_width=vstat.charwidth*vstat.cols*vstat.scaling;
int char_height=vstat.charheight*vstat.rows*vstat.scaling;
int flags=SDL_HWSURFACE|SDL_ANYFORMAT;
SDL_Surface *tmp_rect;
SDL_Event ev;
if(fullscreen)
flags |= SDL_FULLSCREEN;
else
flags |= SDL_RESIZABLE;
if(yuv.enabled) {
if(!yuv.win_width)
yuv.win_width=vstat.charwidth*vstat.cols;
if(!yuv.win_height)
yuv.win_height=vstat.charheight*vstat.rows;
if(fullscreen && yuv.screen_width && yuv.screen_height)
win=sdl.SetVideoMode(yuv.screen_width,yuv.screen_height,0,flags);
else
win=sdl.SetVideoMode(yuv.win_width,yuv.win_height,0,flags);
}
else
win=sdl.SetVideoMode(char_width,char_height,8,flags);
if(sdl_x11available && sdl_using_x11) {
XEvent respond;
SDL_SysWMinfo wmi;
SDL_VERSION(&(wmi.version));
sdl.GetWMInfo(&wmi);
respond.type=ConfigureNotify;
respond.xconfigure.height = win->h;
respond.xconfigure.width = win->w;
sdl_x11.XSendEvent(wmi.info.x11.display,wmi.info.x11.window,0,0,&respond);
}
if(win!=NULL) {
if(new_rect)
sdl.FreeSurface(new_rect);
new_rect=NULL;
tmp_rect=sdl.CreateRGBSurface(SDL_HWSURFACE
, char_width
, char_height
, 8, 0, 0, 0, 0);
if(tmp_rect) {
if(yuv.enabled) {
new_rect=tmp_rect;
}
else {
new_rect=sdl.DisplayFormat(tmp_rect);
sdl.FreeSurface(tmp_rect);
}
}
if(yuv.enabled) {
if(yuv.overlay)
sdl.FreeYUVOverlay(yuv.overlay);
if(yuv.best_format==0) {
yuv.overlay=sdl.CreateYUVOverlay(char_width,char_height, SDL_YV12_OVERLAY, win);
if(yuv.overlay)
yuv.best_format=yuv.overlay->format;
if(yuv.overlay==NULL || !yuv.overlay->hw_overlay) {
if (yuv.overlay)
sdl.FreeYUVOverlay(yuv.overlay);
yuv.overlay=sdl.CreateYUVOverlay(char_width,char_height, SDL_YUY2_OVERLAY, win);
if(yuv.overlay)
yuv.best_format=yuv.overlay->format;
if(yuv.overlay==NULL || !yuv.overlay->hw_overlay) {
if (yuv.overlay)
sdl.FreeYUVOverlay(yuv.overlay);
yuv.overlay=sdl.CreateYUVOverlay(char_width,char_height, SDL_YVYU_OVERLAY, win);
if(yuv.overlay)
yuv.best_format=yuv.overlay->format;
if(yuv.overlay==NULL || !yuv.overlay->hw_overlay) {
if (yuv.overlay)
sdl.FreeYUVOverlay(yuv.overlay);
yuv.overlay=sdl.CreateYUVOverlay(char_width,char_height, SDL_UYVY_OVERLAY, win);
if(yuv.overlay)
yuv.best_format=yuv.overlay->format;
if(yuv.overlay==NULL || !yuv.overlay->hw_overlay) {
if (yuv.overlay)
sdl.FreeYUVOverlay(yuv.overlay);
yuv.overlay=sdl.CreateYUVOverlay(char_width,char_height, SDL_IYUV_OVERLAY, win);
if(yuv.overlay)
yuv.best_format=yuv.overlay->format;
}
}
}
}
if(yuv.overlay)
sdl.FreeYUVOverlay(yuv.overlay);
}
yuv.overlay=sdl.CreateYUVOverlay(char_width,char_height, yuv.best_format, win);
sdl_setup_yuv_colours();
}
sdl_setup_colours(new_rect);
sdl_setup_colours(win);
force_redraws++;
}
else if(sdl_init_good) {
ev.type=SDL_QUIT;
sdl_exitcode=1;
sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, 0xffffffff);
}
}
/* Called from event thread only */
void sdl_add_key(unsigned int keyval)
{
if(keyval==0xa600) {
fullscreen=!fullscreen;
if(yuv.enabled)
cio_api.mode=fullscreen?CIOLIB_MODE_SDL_YUV_FULLSCREEN:CIOLIB_MODE_SDL_YUV;
else
cio_api.mode=fullscreen?CIOLIB_MODE_SDL_FULLSCREEN:CIOLIB_MODE_SDL;
setup_surfaces();
return;
}
if(keyval <= 0xffff) {
if(sdl_keynext+1==sdl_key) {
return;
}
if((sdl_keynext+2==sdl_key) && keyval > 0xff) {
if(keyval==CIO_KEY_MOUSE)
sdl_pending_mousekeys+=2;
else
return;
}
sdl_keybuf[sdl_keynext++]=keyval & 0xff;
if(keyval>0xff) {
sdl_keybuf[sdl_keynext++]=keyval >> 8;
}
}
unsigned int cp437_convert(unsigned int unicode)
{
if(unicode < 0x80)
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
switch(unicode) {
case 0x00c7:
return(0x80);
case 0x00fc:
return(0x81);
case 0x00e9:
return(0x82);
case 0x00e2:
return(0x83);
case 0x00e4:
return(0x84);
case 0x00e0:
return(0x85);
case 0x00e5:
return(0x86);
case 0x00e7:
return(0x87);
case 0x00ea:
return(0x88);
case 0x00eb:
return(0x89);
case 0x00e8:
return(0x8a);
case 0x00ef:
return(0x8b);
case 0x00ee:
return(0x8c);
case 0x00ec:
return(0x8d);
case 0x00c4:
return(0x8e);
case 0x00c5:
return(0x8f);
case 0x00c9:
return(0x90);
case 0x00e6:
return(0x91);
case 0x00c6:
return(0x92);