2012-06-23 12:16:37 +00:00
|
|
|
/*
|
|
|
|
* sdl.c
|
|
|
|
* sdl interfaces -- based on svga.c
|
|
|
|
*
|
|
|
|
* (C) 2001 Damian Gryski <dgryski@uwaterloo.ca>
|
|
|
|
* Joystick code contributed by David Lau
|
|
|
|
*
|
|
|
|
* Licensed under the GPLv2, or later.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#include <SDL/SDL.h>
|
|
|
|
|
2018-01-16 23:59:50 +00:00
|
|
|
/* Von Stefan */
|
|
|
|
#include <string.h>
|
|
|
|
#include <netdb.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
|
|
|
#define BUFSIZE 5760
|
|
|
|
#define SERVICE_PORT 2323
|
|
|
|
#define FRAME_SKIP -1
|
|
|
|
/* Ende von Stefan */
|
|
|
|
|
2012-06-23 12:16:37 +00:00
|
|
|
|
|
|
|
#include "fb.h"
|
|
|
|
#include "input.h"
|
|
|
|
#include "rc.h"
|
|
|
|
|
2018-01-16 23:59:50 +00:00
|
|
|
/* By Stefan */
|
|
|
|
static struct sockaddr_in myaddr, remaddr;
|
|
|
|
static int fd, slen=sizeof(remaddr);
|
|
|
|
static char frame[BUFSIZE]; /* message buffer */
|
|
|
|
static char *server = "195.160.169.37"; /* change this to use a different server */
|
|
|
|
static int frameCount = 0;
|
|
|
|
/* End Stefan */
|
|
|
|
|
2012-06-23 12:16:37 +00:00
|
|
|
struct fb fb;
|
|
|
|
|
|
|
|
static int use_yuv = -1;
|
2017-11-22 17:15:10 +00:00
|
|
|
static int fullscreen = 0;
|
2012-06-23 12:16:37 +00:00
|
|
|
static int use_altenter = 1;
|
|
|
|
static int use_joy = 1, sdl_joy_num;
|
|
|
|
static SDL_Joystick * sdl_joy = NULL;
|
|
|
|
static const int joy_commit_range = 3276;
|
|
|
|
static char Xstatus, Ystatus;
|
|
|
|
|
|
|
|
static SDL_Surface *screen;
|
|
|
|
static SDL_Overlay *overlay;
|
|
|
|
static SDL_Rect overlay_rect;
|
|
|
|
|
|
|
|
static int vmode[3] = { 0, 0, 16 };
|
|
|
|
|
|
|
|
rcvar_t vid_exports[] =
|
|
|
|
{
|
|
|
|
RCV_VECTOR("vmode", &vmode, 3),
|
|
|
|
RCV_BOOL("yuv", &use_yuv),
|
|
|
|
RCV_BOOL("fullscreen", &fullscreen),
|
|
|
|
RCV_BOOL("altenter", &use_altenter),
|
|
|
|
RCV_END
|
|
|
|
};
|
|
|
|
|
|
|
|
rcvar_t joy_exports[] =
|
|
|
|
{
|
|
|
|
RCV_BOOL("joy", &use_joy),
|
|
|
|
RCV_END
|
|
|
|
};
|
|
|
|
|
|
|
|
/* keymap - mappings of the form { scancode, localcode } - from sdl/keymap.c */
|
|
|
|
extern int keymap[][2];
|
|
|
|
|
|
|
|
static int mapscancode(SDLKey sym)
|
|
|
|
{
|
|
|
|
/* this could be faster: */
|
|
|
|
/* build keymap as int keymap[256], then ``return keymap[sym]'' */
|
|
|
|
|
|
|
|
int i;
|
|
|
|
for (i = 0; keymap[i][0]; i++)
|
|
|
|
if (keymap[i][0] == sym)
|
|
|
|
return keymap[i][1];
|
|
|
|
if (sym >= '0' && sym <= '9')
|
|
|
|
return sym;
|
|
|
|
if (sym >= 'a' && sym <= 'z')
|
|
|
|
return sym;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void joy_init()
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int joy_count;
|
|
|
|
|
|
|
|
/* Initilize the Joystick, and disable all later joystick code if an error occured */
|
|
|
|
if (!use_joy) return;
|
|
|
|
|
|
|
|
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK))
|
|
|
|
return;
|
|
|
|
|
|
|
|
joy_count = SDL_NumJoysticks();
|
|
|
|
|
|
|
|
if (!joy_count)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* now try and open one. If, for some reason it fails, move on to the next one */
|
|
|
|
for (i = 0; i < joy_count; i++)
|
|
|
|
{
|
|
|
|
sdl_joy = SDL_JoystickOpen(i);
|
|
|
|
if (sdl_joy)
|
|
|
|
{
|
|
|
|
sdl_joy_num = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* make sure that Joystick event polling is a go */
|
|
|
|
SDL_JoystickEventState(SDL_ENABLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void overlay_init()
|
|
|
|
{
|
|
|
|
if (!use_yuv) return;
|
|
|
|
|
|
|
|
if (use_yuv < 0)
|
|
|
|
if (vmode[0] < 320 || vmode[1] < 288)
|
|
|
|
return;
|
|
|
|
|
|
|
|
overlay = SDL_CreateYUVOverlay(320, 144, SDL_YUY2_OVERLAY, screen);
|
|
|
|
|
|
|
|
if (!overlay) return;
|
|
|
|
|
|
|
|
if (!overlay->hw_overlay || overlay->planes > 1)
|
|
|
|
{
|
|
|
|
SDL_FreeYUVOverlay(overlay);
|
|
|
|
overlay = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_LockYUVOverlay(overlay);
|
|
|
|
|
|
|
|
fb.w = 160;
|
|
|
|
fb.h = 144;
|
|
|
|
fb.pelsize = 4;
|
|
|
|
fb.pitch = overlay->pitches[0];
|
|
|
|
fb.ptr = overlay->pixels[0];
|
|
|
|
fb.yuv = 1;
|
|
|
|
fb.cc[0].r = fb.cc[1].r = fb.cc[2].r = fb.cc[3].r = 0;
|
|
|
|
fb.dirty = 1;
|
|
|
|
fb.enabled = 1;
|
|
|
|
|
|
|
|
overlay_rect.x = 0;
|
|
|
|
overlay_rect.y = 0;
|
|
|
|
overlay_rect.w = vmode[0];
|
|
|
|
overlay_rect.h = vmode[1];
|
|
|
|
|
|
|
|
/* Color channels are 0=Y, 1=U, 2=V, 3=Y1 */
|
|
|
|
switch (overlay->format)
|
|
|
|
{
|
|
|
|
/* FIXME - support more formats */
|
|
|
|
case SDL_YUY2_OVERLAY:
|
|
|
|
default:
|
|
|
|
fb.cc[0].l = 0;
|
|
|
|
fb.cc[1].l = 24;
|
|
|
|
fb.cc[2].l = 8;
|
|
|
|
fb.cc[3].l = 16;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_UnlockYUVOverlay(overlay);
|
|
|
|
}
|
|
|
|
|
|
|
|
void vid_init()
|
|
|
|
{
|
|
|
|
int flags;
|
|
|
|
|
|
|
|
if (!vmode[0] || !vmode[1])
|
|
|
|
{
|
|
|
|
int scale = rc_getint("scale");
|
|
|
|
if (scale < 1) scale = 1;
|
|
|
|
vmode[0] = 160 * scale;
|
|
|
|
vmode[1] = 144 * scale;
|
|
|
|
}
|
|
|
|
|
|
|
|
flags = SDL_ANYFORMAT | SDL_HWPALETTE | SDL_HWSURFACE;
|
|
|
|
|
|
|
|
if (fullscreen)
|
|
|
|
flags |= SDL_FULLSCREEN;
|
|
|
|
|
|
|
|
if (SDL_Init(SDL_INIT_VIDEO))
|
|
|
|
die("SDL: Couldn't initialize SDL: %s\n", SDL_GetError());
|
|
|
|
|
|
|
|
if (!(screen = SDL_SetVideoMode(vmode[0], vmode[1], vmode[2], flags)))
|
|
|
|
die("SDL: can't set video mode: %s\n", SDL_GetError());
|
|
|
|
|
|
|
|
SDL_ShowCursor(0);
|
|
|
|
|
|
|
|
joy_init();
|
|
|
|
|
|
|
|
overlay_init();
|
|
|
|
|
|
|
|
if (fb.yuv) return;
|
|
|
|
|
|
|
|
SDL_LockSurface(screen);
|
|
|
|
|
|
|
|
fb.w = screen->w;
|
|
|
|
fb.h = screen->h;
|
|
|
|
fb.pelsize = screen->format->BytesPerPixel;
|
|
|
|
fb.pitch = screen->pitch;
|
|
|
|
fb.indexed = fb.pelsize == 1;
|
|
|
|
fb.ptr = screen->pixels;
|
|
|
|
fb.cc[0].r = screen->format->Rloss;
|
|
|
|
fb.cc[0].l = screen->format->Rshift;
|
|
|
|
fb.cc[1].r = screen->format->Gloss;
|
|
|
|
fb.cc[1].l = screen->format->Gshift;
|
|
|
|
fb.cc[2].r = screen->format->Bloss;
|
|
|
|
fb.cc[2].l = screen->format->Bshift;
|
|
|
|
|
|
|
|
SDL_UnlockSurface(screen);
|
|
|
|
|
|
|
|
fb.enabled = 1;
|
|
|
|
fb.dirty = 0;
|
|
|
|
|
2018-01-16 23:59:50 +00:00
|
|
|
/* Start Init Stefan */
|
|
|
|
/* create a socket */
|
|
|
|
printf("Start Init\n");
|
|
|
|
if ((fd=socket(AF_INET, SOCK_DGRAM, 0))==-1)
|
|
|
|
printf("socket created\n");
|
|
|
|
|
|
|
|
/* bind it to all local addresses and pick any port number */
|
|
|
|
|
|
|
|
memset((char *)&myaddr, 0, sizeof(myaddr));
|
|
|
|
myaddr.sin_family = AF_INET;
|
|
|
|
myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
myaddr.sin_port = htons(0);
|
|
|
|
|
|
|
|
if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
|
|
|
|
die("bind failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* now define remaddr, the address to whom we want to send messages */
|
|
|
|
/* For convenience, the host address is expressed as a numeric IP address */
|
|
|
|
/* that we will convert to a binary format via inet_aton */
|
|
|
|
|
|
|
|
memset((char *) &remaddr, 0, sizeof(remaddr));
|
|
|
|
remaddr.sin_family = AF_INET;
|
|
|
|
remaddr.sin_port = htons(SERVICE_PORT);
|
|
|
|
if (inet_aton(server, &remaddr.sin_addr)==0) {
|
|
|
|
fprintf(stderr, "inet_aton() failed\n");
|
|
|
|
die("1");
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("End Init\n");
|
|
|
|
/* Ende Stefan */
|
2012-06-23 12:16:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ev_poll()
|
|
|
|
{
|
|
|
|
event_t ev;
|
|
|
|
SDL_Event event;
|
|
|
|
int axisval;
|
|
|
|
|
|
|
|
while (SDL_PollEvent(&event))
|
|
|
|
{
|
|
|
|
switch(event.type)
|
|
|
|
{
|
|
|
|
case SDL_ACTIVEEVENT:
|
|
|
|
if (event.active.state == SDL_APPACTIVE)
|
|
|
|
fb.enabled = event.active.gain;
|
|
|
|
break;
|
|
|
|
case SDL_KEYDOWN:
|
|
|
|
if ((event.key.keysym.sym == SDLK_RETURN) && (event.key.keysym.mod & KMOD_ALT))
|
|
|
|
SDL_WM_ToggleFullScreen(screen);
|
|
|
|
ev.type = EV_PRESS;
|
|
|
|
ev.code = mapscancode(event.key.keysym.sym);
|
|
|
|
ev_postevent(&ev);
|
|
|
|
break;
|
|
|
|
case SDL_KEYUP:
|
|
|
|
ev.type = EV_RELEASE;
|
|
|
|
ev.code = mapscancode(event.key.keysym.sym);
|
|
|
|
ev_postevent(&ev);
|
|
|
|
break;
|
|
|
|
case SDL_JOYAXISMOTION:
|
|
|
|
switch (event.jaxis.axis)
|
|
|
|
{
|
|
|
|
case 0: /* X axis */
|
|
|
|
axisval = event.jaxis.value;
|
|
|
|
if (axisval > joy_commit_range)
|
|
|
|
{
|
|
|
|
if (Xstatus==2) break;
|
|
|
|
|
|
|
|
if (Xstatus==0)
|
|
|
|
{
|
|
|
|
ev.type = EV_RELEASE;
|
|
|
|
ev.code = K_JOYLEFT;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
ev.type = EV_PRESS;
|
|
|
|
ev.code = K_JOYRIGHT;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
Xstatus=2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (axisval < -(joy_commit_range))
|
|
|
|
{
|
|
|
|
if (Xstatus==0) break;
|
|
|
|
|
|
|
|
if (Xstatus==2)
|
|
|
|
{
|
|
|
|
ev.type = EV_RELEASE;
|
|
|
|
ev.code = K_JOYRIGHT;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
ev.type = EV_PRESS;
|
|
|
|
ev.code = K_JOYLEFT;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
Xstatus=0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if control reaches here, the axis is centered,
|
|
|
|
* so just send a release signal if necisary */
|
|
|
|
|
|
|
|
if (Xstatus==2)
|
|
|
|
{
|
|
|
|
ev.type = EV_RELEASE;
|
|
|
|
ev.code = K_JOYRIGHT;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Xstatus==0)
|
|
|
|
{
|
|
|
|
ev.type = EV_RELEASE;
|
|
|
|
ev.code = K_JOYLEFT;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
}
|
|
|
|
Xstatus=1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1: /* Y axis*/
|
|
|
|
axisval = event.jaxis.value;
|
|
|
|
if (axisval > joy_commit_range)
|
|
|
|
{
|
|
|
|
if (Ystatus==2) break;
|
|
|
|
|
|
|
|
if (Ystatus==0)
|
|
|
|
{
|
|
|
|
ev.type = EV_RELEASE;
|
|
|
|
ev.code = K_JOYUP;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
ev.type = EV_PRESS;
|
|
|
|
ev.code = K_JOYDOWN;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
Ystatus=2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (axisval < -joy_commit_range)
|
|
|
|
{
|
|
|
|
if (Ystatus==0) break;
|
|
|
|
|
|
|
|
if (Ystatus==2)
|
|
|
|
{
|
|
|
|
ev.type = EV_RELEASE;
|
|
|
|
ev.code = K_JOYDOWN;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
ev.type = EV_PRESS;
|
|
|
|
ev.code = K_JOYUP;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
Ystatus=0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if control reaches here, the axis is centered,
|
|
|
|
* so just send a release signal if necisary */
|
|
|
|
|
|
|
|
if (Ystatus==2)
|
|
|
|
{
|
|
|
|
ev.type = EV_RELEASE;
|
|
|
|
ev.code = K_JOYDOWN;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Ystatus==0)
|
|
|
|
{
|
|
|
|
ev.type = EV_RELEASE;
|
|
|
|
ev.code = K_JOYUP;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
}
|
|
|
|
Ystatus=1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDL_JOYBUTTONUP:
|
|
|
|
if (event.jbutton.button>15) break;
|
|
|
|
ev.type = EV_RELEASE;
|
|
|
|
ev.code = K_JOY0 + event.jbutton.button;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
break;
|
|
|
|
case SDL_JOYBUTTONDOWN:
|
|
|
|
if (event.jbutton.button>15) break;
|
|
|
|
ev.type = EV_PRESS;
|
|
|
|
ev.code = K_JOY0+event.jbutton.button;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
break;
|
|
|
|
case SDL_QUIT:
|
|
|
|
exit(1);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void vid_setpal(int i, int r, int g, int b)
|
|
|
|
{
|
|
|
|
SDL_Color col;
|
|
|
|
|
|
|
|
col.r = r; col.g = g; col.b = b;
|
|
|
|
|
|
|
|
SDL_SetColors(screen, &col, i, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void vid_preinit()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void vid_close()
|
|
|
|
{
|
|
|
|
if (overlay)
|
|
|
|
{
|
|
|
|
SDL_UnlockYUVOverlay(overlay);
|
|
|
|
SDL_FreeYUVOverlay(overlay);
|
|
|
|
}
|
|
|
|
else SDL_UnlockSurface(screen);
|
|
|
|
SDL_Quit();
|
|
|
|
fb.enabled = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void vid_settitle(char *title)
|
|
|
|
{
|
|
|
|
SDL_WM_SetCaption(title, title);
|
|
|
|
}
|
|
|
|
|
|
|
|
void vid_begin()
|
|
|
|
{
|
2018-01-16 23:59:50 +00:00
|
|
|
int x;
|
|
|
|
char y;
|
|
|
|
|
2012-06-23 12:16:37 +00:00
|
|
|
if (overlay)
|
|
|
|
{
|
|
|
|
SDL_LockYUVOverlay(overlay);
|
|
|
|
fb.ptr = overlay->pixels[0];
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
SDL_LockSurface(screen);
|
|
|
|
fb.ptr = screen->pixels;
|
2018-01-16 23:59:50 +00:00
|
|
|
|
|
|
|
frameCount++;
|
|
|
|
|
|
|
|
if (frameCount % FRAME_SKIP) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Stefan Start - Sending Frame via UDP to DFI*/
|
|
|
|
|
|
|
|
/* Geht so halb...
|
|
|
|
for(x=0; x<144*40; x++){
|
|
|
|
if(fb.ptr[x*16]==29) frame[x]=0;
|
|
|
|
if(fb.ptr[x*16]==99) frame[x]=1;
|
|
|
|
if(fb.ptr[x*16]==107) frame[x]=2;
|
|
|
|
if(fb.ptr[x*16]==156) frame[x]=3;
|
|
|
|
|
|
|
|
if(fb.ptr[(x*16)+4]==29) frame[x]+=0;
|
|
|
|
if(fb.ptr[(x*16)+4]==99) frame[x]+=4;
|
|
|
|
if(fb.ptr[(x*16)+4]==107) frame[x]+=8;
|
|
|
|
if(fb.ptr[(x*16)+4]==156) frame[x]+=12;
|
|
|
|
|
|
|
|
if(fb.ptr[(x*16)+8]==29) frame[x]+=0;
|
|
|
|
if(fb.ptr[(x*16)+8]==99) frame[x]+=16;
|
|
|
|
if(fb.ptr[(x*16)+8]==107) frame[x]+=32;
|
|
|
|
if(fb.ptr[(x*16)+8]==156) frame[x]+=48;
|
|
|
|
|
|
|
|
if(fb.ptr[(x*16)+12]==29) frame[x]+=0;
|
|
|
|
if(fb.ptr[(x*16)+12]==99) frame[x]+=64;
|
|
|
|
if(fb.ptr[(x*16)+12]==107) frame[x]+=128;
|
|
|
|
if(fb.ptr[(x*16)+12]==156) frame[x]+=192;
|
|
|
|
} */
|
|
|
|
|
|
|
|
int displaySize = 144*160;
|
|
|
|
|
|
|
|
for(x=0; x<displaySize; x++){
|
|
|
|
int color = fb.ptr[x*4];
|
|
|
|
|
|
|
|
if (color == 41) {
|
|
|
|
y=0;
|
|
|
|
} else if (color == 99) {
|
|
|
|
y=1;
|
|
|
|
} else if (color <= 107) {
|
|
|
|
y=2;
|
|
|
|
} else if (color <= 156) {
|
|
|
|
y=3;
|
|
|
|
} else {
|
|
|
|
y=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int pixelModulo = x %4;
|
|
|
|
|
|
|
|
if (pixelModulo == 0) {
|
|
|
|
frame[x/4] =y;
|
|
|
|
} else if (pixelModulo == 1) {
|
|
|
|
frame[x/4]+=(y<<2);
|
|
|
|
} else if (pixelModulo == 2) {
|
|
|
|
frame[x/4]+=(y<<4);
|
|
|
|
} else if (pixelModulo == 3) {
|
|
|
|
frame[x/4]+=(y<<6);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sendto(fd, frame, BUFSIZE, 0, (struct sockaddr *)&remaddr, slen)==-1) {
|
|
|
|
printf("error sending frame\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/*printf("send; %d\n",frameCount);*/
|
|
|
|
|
|
|
|
/* Stefan Ende */
|
2012-06-23 12:16:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void vid_end()
|
|
|
|
{
|
|
|
|
if (overlay)
|
|
|
|
{
|
|
|
|
SDL_UnlockYUVOverlay(overlay);
|
|
|
|
if (fb.enabled)
|
|
|
|
SDL_DisplayYUVOverlay(overlay, &overlay_rect);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
SDL_UnlockSurface(screen);
|
|
|
|
if (fb.enabled) SDL_Flip(screen);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|