X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=vid_sdl.c;h=ba869c21ece248c48eb02eb565b8457b00c36a88;hb=cd4804cec4feb9908ee83131d8fc59319310dfc5;hp=ea0e80005f2dd4eb3528b872da1bd5882c6e69a2;hpb=2e9672e5e2e088ff3b50e5000b00170d70ab44aa;p=xonotic%2Fdarkplaces.git diff --git a/vid_sdl.c b/vid_sdl.c index ea0e8000..ba869c21 100644 --- a/vid_sdl.c +++ b/vid_sdl.c @@ -18,9 +18,41 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #undef WIN32_LEAN_AND_MEAN //hush a warning, SDL.h redefines this #include +#include #include #include "quakedef.h" +#include "image.h" + +#ifdef MACOSX +#include +#include +#include +#include +static cvar_t apple_mouse_noaccel = {CVAR_SAVE, "apple_mouse_noaccel", "1", "disables mouse acceleration while DarkPlaces is active"}; +static qboolean vid_usingnoaccel; +static double originalMouseSpeed = -1.0; +io_connect_t IN_GetIOHandle(void) +{ + io_connect_t iohandle = MACH_PORT_NULL; + kern_return_t status; + io_service_t iohidsystem = MACH_PORT_NULL; + mach_port_t masterport; + + status = IOMasterPort(MACH_PORT_NULL, &masterport); + if(status != KERN_SUCCESS) + return 0; + + iohidsystem = IORegistryEntryFromPath(masterport, kIOServicePlane ":/IOResources/IOHIDSystem"); + if(!iohidsystem) + return 0; + + status = IOServiceOpen(iohidsystem, mach_task_self(), kIOHIDParamConnectType, &iohandle); + IOObjectRelease(iohidsystem); + + return iohandle; +} +#endif #ifdef WIN32 #define SDL_R_RESTART @@ -52,6 +84,7 @@ cvar_t joy_sensitivityup = {0, "joy_sensitivityup", "1", "movement multiplier"}; cvar_t joy_sensitivitypitch = {0, "joy_sensitivitypitch", "1", "movement multiplier"}; cvar_t joy_sensitivityyaw = {0, "joy_sensitivityyaw", "-1", "movement multiplier"}; cvar_t joy_sensitivityroll = {0, "joy_sensitivityroll", "1", "movement multiplier"}; +cvar_t joy_axiskeyevents = {CVAR_SAVE, "joy_axiskeyevents", "0", "generate uparrow/leftarrow etc. keyevents for joystick axes, use if your joystick driver is not generating them"}; static qboolean vid_usingmouse = false; static qboolean vid_usinghidecursor = false; @@ -66,6 +99,16 @@ static int video_bpp, video_flags; static SDL_Surface *screen; +// joystick axes state +#define MAX_JOYSTICK_AXES 16 +typedef struct +{ + float oldmove; + float move; + double keytime; +}joy_axiscache_t; +static joy_axiscache_t joy_axescache[MAX_JOYSTICK_AXES]; + ///////////////////////// // Input handling //// @@ -239,11 +282,68 @@ static int MapKey( unsigned int sdlkey ) void VID_SetMouse(qboolean fullscreengrab, qboolean relative, qboolean hidecursor) { +#ifdef MACOSX + if(relative) + if(vid_usingmouse && (vid_usingnoaccel != !!apple_mouse_noaccel.integer)) + VID_SetMouse(false, false, false); // ungrab first! +#endif if (vid_usingmouse != relative) { vid_usingmouse = relative; cl_ignoremousemoves = 2; SDL_WM_GrabInput( relative ? SDL_GRAB_ON : SDL_GRAB_OFF ); +#ifdef MACOSX + if(relative) + { + // Save the status of mouse acceleration + originalMouseSpeed = -1.0; // in case of error + if(apple_mouse_noaccel.integer) + { + io_connect_t mouseDev = IN_GetIOHandle(); + if(mouseDev != 0) + { + if(IOHIDGetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), &originalMouseSpeed) == kIOReturnSuccess) + { + Con_DPrintf("previous mouse acceleration: %f\n", originalMouseSpeed); + if(IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), -1.0) != kIOReturnSuccess) + { + Con_Print("Could not disable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n"); + Cvar_SetValueQuick(&apple_mouse_noaccel, 0); + } + } + else + { + Con_Print("Could not disable mouse acceleration (failed at IOHIDGetAccelerationWithKey).\n"); + Cvar_SetValueQuick(&apple_mouse_noaccel, 0); + } + IOServiceClose(mouseDev); + } + else + { + Con_Print("Could not disable mouse acceleration (failed at IO_GetIOHandle).\n"); + Cvar_SetValueQuick(&apple_mouse_noaccel, 0); + } + } + + vid_usingnoaccel = !!apple_mouse_noaccel.integer; + } + else + { + if(originalMouseSpeed != -1.0) + { + io_connect_t mouseDev = IN_GetIOHandle(); + if(mouseDev != 0) + { + Con_DPrintf("restoring mouse acceleration to: %f\n", originalMouseSpeed); + if(IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), originalMouseSpeed) != kIOReturnSuccess) + Con_Print("Could not re-enable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n"); + IOServiceClose(mouseDev); + } + else + Con_Print("Could not re-enable mouse acceleration (failed at IO_GetIOHandle).\n"); + } + } +#endif } if (vid_usinghidecursor != hidecursor) { @@ -264,12 +364,79 @@ static double IN_JoystickGetAxis(SDL_Joystick *joy, int axis, double sensitivity return value * sensitivity; } +///////////////////// +// Joystick axis keyevents +// a sort of hack emulating Arrow keys for joystick axises +// as some drives dont send such keyevents for them +// additionally we should block drivers that do send arrow keyevents to prevent double events +//// + +static void IN_JoystickKeyeventForAxis(SDL_Joystick *joy, int axis, int key_pos, int key_neg) +{ + double joytime; + + if (axis < 0 || axis >= SDL_JoystickNumAxes(joy)) + return; // no such axis on this joystick + + joytime = Sys_DoubleTime(); + // no key event, continuous keydown event + if (joy_axescache[axis].move == joy_axescache[axis].oldmove) + { + if (joy_axescache[axis].move != 0 && joytime > joy_axescache[axis].keytime) + { + //Con_Printf("joy %s %i %f\n", Key_KeynumToString((joy_axescache[axis].move > 0) ? key_pos : key_neg), 1, cl.time); + Key_Event((joy_axescache[axis].move > 0) ? key_pos : key_neg, 0, 1); + joy_axescache[axis].keytime = joytime + 0.5 / 20; + } + return; + } + // generate key up event + if (joy_axescache[axis].oldmove) + { + //Con_Printf("joy %s %i %f\n", Key_KeynumToString((joy_axescache[axis].oldmove > 0) ? key_pos : key_neg), 1, cl.time); + Key_Event((joy_axescache[axis].oldmove > 0) ? key_pos : key_neg, 0, 0); + } + // generate key down event + if (joy_axescache[axis].move) + { + //Con_Printf("joy %s %i %f\n", Key_KeynumToString((joy_axescache[axis].move > 0) ? key_pos : key_neg), 1, cl.time); + Key_Event((joy_axescache[axis].move > 0) ? key_pos : key_neg, 0, 1); + joy_axescache[axis].keytime = joytime + 0.5; + } +} + +static qboolean IN_JoystickBlockDoubledKeyEvents(int keycode) +{ + if (!joy_axiskeyevents.integer) + return false; + + // block keyevent if it's going to be provided by joystick keyevent system + if (vid_numjoysticks && joy_enable.integer && joy_index.integer >= 0 && joy_index.integer < vid_numjoysticks) + { + SDL_Joystick *joy = vid_joysticks[joy_index.integer]; + + if (keycode == K_UPARROW || keycode == K_DOWNARROW) + if (IN_JoystickGetAxis(joy, joy_axisforward.integer, 1, 0.01) || joy_axescache[joy_axisforward.integer].move || joy_axescache[joy_axisforward.integer].oldmove) + return true; + if (keycode == K_RIGHTARROW || keycode == K_LEFTARROW) + if (IN_JoystickGetAxis(joy, joy_axisside.integer, 1, 0.01) || joy_axescache[joy_axisside.integer].move || joy_axescache[joy_axisside.integer].oldmove) + return true; + } + + return false; +} + +///////////////////// +// Movement handling +//// + void IN_Move( void ) { int j; static int old_x = 0, old_y = 0; static int stuck = 0; - int x, y; + int x, y, numaxes, numballs; + if (vid_usingmouse) { if(vid_stick_mouse.integer) @@ -307,19 +474,38 @@ void IN_Move( void ) if (vid_numjoysticks && joy_enable.integer && joy_index.integer >= 0 && joy_index.integer < vid_numjoysticks) { SDL_Joystick *joy = vid_joysticks[joy_index.integer]; - int numballs = SDL_JoystickNumBalls(joy); + + // balls convert to mousemove + numballs = SDL_JoystickNumBalls(joy); for (j = 0;j < numballs;j++) { SDL_JoystickGetBall(joy, j, &x, &y); in_mouse_x += x; in_mouse_y += y; } + + // axes cl.cmd.forwardmove += IN_JoystickGetAxis(joy, joy_axisforward.integer, joy_sensitivityforward.value, joy_deadzoneforward.value) * cl_forwardspeed.value; cl.cmd.sidemove += IN_JoystickGetAxis(joy, joy_axisside.integer, joy_sensitivityside.value, joy_deadzoneside.value) * cl_sidespeed.value; cl.cmd.upmove += IN_JoystickGetAxis(joy, joy_axisup.integer, joy_sensitivityup.value, joy_deadzoneup.value) * cl_upspeed.value; cl.viewangles[0] += IN_JoystickGetAxis(joy, joy_axispitch.integer, joy_sensitivitypitch.value, joy_deadzonepitch.value) * cl.realframetime * cl_pitchspeed.value; cl.viewangles[1] += IN_JoystickGetAxis(joy, joy_axisyaw.integer, joy_sensitivityyaw.value, joy_deadzoneyaw.value) * cl.realframetime * cl_yawspeed.value; //cl.viewangles[2] += IN_JoystickGetAxis(joy, joy_axisroll.integer, joy_sensitivityroll.value, joy_deadzoneroll.value) * cl.realframetime * cl_rollspeed.value; + + // cache state of axes to emulate button events for them + numaxes = min(MAX_JOYSTICK_AXES, SDL_JoystickNumAxes(joy)); + for (j = 0; j < numaxes; j++) + { + joy_axescache[j].oldmove = joy_axescache[j].move; + joy_axescache[j].move = IN_JoystickGetAxis(joy, j, 1, 0.01); + } + + // run keyevents + if (joy_axiskeyevents.integer) + { + IN_JoystickKeyeventForAxis(joy, joy_axisforward.integer, K_DOWNARROW, K_UPARROW); + IN_JoystickKeyeventForAxis(joy, joy_axisside.integer, K_RIGHTARROW, K_LEFTARROW); + } } } @@ -379,6 +565,7 @@ static keynum_t buttonremap[18] = void Sys_SendKeyEvents( void ) { static qboolean sound_active = true; + int keycode; SDL_Event event; while( SDL_PollEvent( &event ) ) @@ -388,7 +575,9 @@ void Sys_SendKeyEvents( void ) break; case SDL_KEYDOWN: case SDL_KEYUP: - Key_Event( MapKey( event.key.keysym.sym ), (char)event.key.keysym.unicode, (event.key.state == SDL_PRESSED) ); + keycode = MapKey(event.key.keysym.sym); + if (!IN_JoystickBlockDoubledKeyEvents(keycode)) + Key_Event(keycode, event.key.keysym.unicode, (event.key.state == SDL_PRESSED)); break; case SDL_ACTIVEEVENT: if( event.active.state & SDL_APPACTIVE ) @@ -465,6 +654,9 @@ static qboolean vid_sdl_initjoysticksystem = false; void VID_Init (void) { +#ifdef MACOSX + Cvar_RegisterVariable(&apple_mouse_noaccel); +#endif Cvar_RegisterVariable(&joy_detected); Cvar_RegisterVariable(&joy_enable); Cvar_RegisterVariable(&joy_index); @@ -486,9 +678,10 @@ void VID_Init (void) Cvar_RegisterVariable(&joy_sensitivitypitch); Cvar_RegisterVariable(&joy_sensitivityyaw); //Cvar_RegisterVariable(&joy_sensitivityroll); + Cvar_RegisterVariable(&joy_axiskeyevents); #ifdef SDL_R_RESTART - R_RegisterModule("SDL", sdl_start, sdl_shutdown, sdl_newmap); + R_RegisterModule("SDL", sdl_start, sdl_shutdown, sdl_newmap, NULL, NULL); #endif if (SDL_Init(SDL_INIT_VIDEO) < 0) @@ -503,7 +696,7 @@ void VID_Init (void) #ifdef WIN32 #include "resource.h" #include -static void VID_SetCaption() +static void VID_SetCaption(void) { SDL_SysWMinfo info; HICON icon; @@ -530,7 +723,10 @@ static void VID_SetCaption() #endif SetClassLongPtr( info.window, GCLP_HICON, (LONG_PTR)icon ); } -static void VID_SetIcon() +static void VID_SetIcon_Pre(void) +{ +} +static void VID_SetIcon_Post(void) { } #else @@ -538,7 +734,7 @@ static void VID_SetIcon() #include "darkplaces.xpm" #include "nexuiz.xpm" static SDL_Surface *icon = NULL; -static void VID_SetIcon() +static void VID_SetIcon_Pre(void) { /* * Somewhat restricted XPM reader. Only supports XPMs saved by GIMP 2.4 at @@ -549,104 +745,213 @@ static void VID_SetIcon() int thenone = -1; static SDL_Color palette[256]; unsigned short palenc[256]; // store color id by char + char *xpm; + char **idata, *data; + const SDL_version *version; - char **idata = ENGINE_ICON; - char *data = idata[0]; - - if(sscanf(data, "%i %i %i %i", &width, &height, &colors, &isize) != 4) + version = SDL_Linked_Version(); + // only use non-XPM icon support in SDL v1.3 and higher + // SDL v1.2 does not support "smooth" transparency, and thus is better + // off the xpm way + if(version->major >= 2 || (version->major == 1 && version->minor >= 3)) { - // NOTE: Only 1-char colornames are supported - Con_Printf("Sorry, but this does not even look similar to an XPM.\n"); - return; - } + data = (char *) loadimagepixelsbgra("darkplaces-icon", false, false, false, NULL); + if(data) + { + unsigned int red = 0x00FF0000; + unsigned int green = 0x0000FF00; + unsigned int blue = 0x000000FF; + unsigned int alpha = 0xFF000000; + width = image_width; + height = image_height; + + // reallocate with malloc, as this is in tempmempool (do not want) + xpm = data; + data = malloc(width * height * 4); + memcpy(data, xpm, width * height * 4); + Mem_Free(xpm); + xpm = NULL; + + icon = SDL_CreateRGBSurface(SDL_SRCALPHA, width, height, 32, LittleLong(red), LittleLong(green), LittleLong(blue), LittleLong(alpha)); + + if(icon == NULL) { + Con_Printf( "Failed to create surface for the window Icon!\n" + "%s\n", SDL_GetError()); + free(data); + return; + } - if(isize != 1) - { - // NOTE: Only 1-char colornames are supported - Con_Printf("This XPM's palette is either huge or idiotically unoptimized. It's key size is %i\n", isize); - return; + icon->pixels = data; + } } - for(i = 0; i < colors; ++i) + // we only get here if non-XPM icon was missing, or SDL version is not + // sufficient for transparent non-XPM icons + if(!icon) { - unsigned int r, g, b; - char idx; + xpm = (char *) FS_LoadFile("darkplaces-icon.xpm", tempmempool, false, NULL); + idata = NULL; + if(xpm) + idata = XPM_DecodeString(xpm); + if(!idata) + idata = ENGINE_ICON; + if(xpm) + Mem_Free(xpm); + + data = idata[0]; + + if(sscanf(data, "%i %i %i %i", &width, &height, &colors, &isize) != 4) + { + // NOTE: Only 1-char colornames are supported + Con_Printf("Sorry, but this does not even look similar to an XPM.\n"); + return; + } - if(sscanf(idata[i+1], "%c c #%02x%02x%02x", &idx, &r, &g, &b) != 4) + if(isize != 1) { - char foo[2]; - if(sscanf(idata[i+1], "%c c Non%1[e]", &idx, foo) != 2) // I take the DailyWTF credit for this. --div0 + // NOTE: Only 1-char colornames are supported + Con_Printf("This XPM's palette is either huge or idiotically unoptimized. It's key size is %i\n", isize); + return; + } + + for(i = 0; i < colors; ++i) + { + unsigned int r, g, b; + char idx; + + if(sscanf(idata[i+1], "%c c #%02x%02x%02x", &idx, &r, &g, &b) != 4) { - Con_Printf("This XPM's palette looks odd. Can't continue.\n"); - return; + char foo[2]; + if(sscanf(idata[i+1], "%c c Non%1[e]", &idx, foo) != 2) // I take the DailyWTF credit for this. --div0 + { + Con_Printf("This XPM's palette looks odd. Can't continue.\n"); + return; + } + else + { + palette[i].r = 255; // color key + palette[i].g = 0; + palette[i].b = 255; + thenone = i; // weeeee + } } else { - palette[i].r = 255; // color key - palette[i].g = 0; - palette[i].b = 255; - thenone = i; // weeeee + palette[i].r = r - (r == 255 && g == 0 && b == 255); // change 255/0/255 pink to 254/0/255 for color key + palette[i].g = g; + palette[i].b = b; } + + palenc[(unsigned char) idx] = i; } - else + + // allocate the image data + data = (char*) malloc(width*height); + + for(j = 0; j < height; ++j) { - palette[i].r = r - (r == 255 && g == 0 && b == 255); // change 255/0/255 pink to 254/0/255 for color key - palette[i].g = g; - palette[i].b = b; + for(i = 0; i < width; ++i) + { + // casting to the safest possible datatypes ^^ + data[j * width + i] = palenc[((unsigned char*)idata[colors+j+1])[i]]; + } } - palenc[(unsigned char) idx] = i; - } + if(icon != NULL) + { + // SDL_FreeSurface should free the data too + // but for completeness' sake... + if(icon->flags & SDL_PREALLOC) + { + free(icon->pixels); + icon->pixels = NULL; // safety + } + SDL_FreeSurface(icon); + } - // allocate the image data - data = (char*) malloc(width*height); + icon = SDL_CreateRGBSurface(SDL_SRCCOLORKEY, width, height, 8, 0,0,0,0);// rmask, gmask, bmask, amask); no mask needed + // 8 bit surfaces get an empty palette allocated according to the docs + // so it's a palette image for sure :) no endian check necessary for the mask - for(j = 0; j < height; ++j) - { - for(i = 0; i < width; ++i) - { - // casting to the safest possible datatypes ^^ - data[j * width + i] = palenc[((unsigned char*)idata[colors+j+1])[i]]; + if(icon == NULL) { + Con_Printf( "Failed to create surface for the window Icon!\n" + "%s\n", SDL_GetError()); + free(data); + return; } + + icon->pixels = data; + SDL_SetPalette(icon, SDL_PHYSPAL|SDL_LOGPAL, palette, 0, colors); + SDL_SetColorKey(icon, SDL_SRCCOLORKEY, thenone); } - if(icon != NULL) + SDL_WM_SetIcon(icon, NULL); +} +static void VID_SetIcon_Post(void) +{ +#if SDL_VIDEO_DRIVER_X11 && !SDL_VIDEO_DRIVER_QUARTZ + int j; + char *data; + const SDL_version *version; + + version = SDL_Linked_Version(); + // only use non-XPM icon support in SDL v1.3 and higher + // SDL v1.2 does not support "smooth" transparency, and thus is better + // off the xpm way + if(!(version->major >= 2 || (version->major == 1 && version->minor >= 3))) { - // SDL_FreeSurface should free the data too - // but for completeness' sake... - if(icon->flags & SDL_PREALLOC) + // in this case, we did not set the good icon yet + SDL_SysWMinfo info; + SDL_VERSION(&info.version); + if(SDL_GetWMInfo(&info) == 1 && info.subsystem == SDL_SYSWM_X11) { - free(icon->pixels); - icon->pixels = NULL; // safety - } - SDL_FreeSurface(icon); - } + data = (char *) loadimagepixelsbgra("darkplaces-icon", false, false, false, NULL); + if(data) + { + // use _NET_WM_ICON too + static long netwm_icon[MAX_NETWM_ICON]; + int pos = 0; + int i = 1; - icon = SDL_CreateRGBSurface(SDL_SRCCOLORKEY, width, height, 8, 0,0,0,0);// rmask, gmask, bmask, amask); no mask needed - // 8 bit surfaces get an empty palette allocated according to the docs - // so it's a palette image for sure :) no endian check necessary for the mask + while(data) + { + if(pos + 2 * image_width * image_height < MAX_NETWM_ICON) + { + netwm_icon[pos++] = image_width; + netwm_icon[pos++] = image_height; + for(i = 0; i < image_height; ++i) + for(j = 0; j < image_width; ++j) + netwm_icon[pos++] = BuffLittleLong((unsigned char *) &data[(i*image_width+j)*4]); + } + else + { + Con_Printf("Skipping NETWM icon #%d because there is no space left\n", i); + } + ++i; + Mem_Free(data); + data = (char *) loadimagepixelsbgra(va("darkplaces-icon%d", i), false, false, false, NULL); + } - if(icon == NULL) { - Con_Printf( "Failed to create surface for the window Icon!\n" - "%s\n", SDL_GetError()); - free(data); - return; + info.info.x11.lock_func(); + { + Atom net_wm_icon = XInternAtom(info.info.x11.display, "_NET_WM_ICON", false); + XChangeProperty(info.info.x11.display, info.info.x11.wmwindow, net_wm_icon, XA_CARDINAL, 32, PropModeReplace, (const unsigned char *) netwm_icon, pos); + } + info.info.x11.unlock_func(); + } + } } - icon->pixels = data; - SDL_SetPalette(icon, SDL_PHYSPAL|SDL_LOGPAL, palette, 0, colors); - SDL_SetColorKey(icon, SDL_SRCCOLORKEY, thenone); - - SDL_WM_SetIcon(icon, NULL); +#endif } -static void VID_SetCaption() +static void VID_SetCaption(void) { SDL_WM_SetCaption( gamename, NULL ); } #endif -static void VID_OutputVersion() +static void VID_OutputVersion(void) { const SDL_version *version; version = SDL_Linked_Version(); @@ -656,15 +961,15 @@ static void VID_OutputVersion() version->major, version->minor, version->patch ); } -int VID_InitMode(int fullscreen, int *width, int *height, int bpp, int refreshrate, int stereobuffer, int samples) +qboolean VID_InitMode(viddef_mode_t *mode) { int i; static int notfirstvideomode = false; int flags = SDL_OPENGL; const char *drivername; - win_half_width = *width>>1; - win_half_height = *height>>1; + win_half_width = mode->width>>1; + win_half_height = mode->height>>1; if(vid_resizable.integer) flags |= SDL_RESIZABLE; @@ -703,14 +1008,14 @@ int VID_InitMode(int fullscreen, int *width, int *height, int bpp, int refreshra // Knghtbrd: should do platform-specific extension string function here vid_isfullscreen = false; - if (fullscreen) { + if (mode->fullscreen) { flags |= SDL_FULLSCREEN; vid_isfullscreen = true; } //flags |= SDL_HWSURFACE; SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); - if (bpp >= 32) + if (mode->bitsperpixel >= 32) { SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 8); @@ -726,26 +1031,27 @@ int VID_InitMode(int fullscreen, int *width, int *height, int bpp, int refreshra SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5); SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 16); } - if (stereobuffer) + if (mode->stereobuffer) SDL_GL_SetAttribute (SDL_GL_STEREO, 1); if (vid_vsync.integer) SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1); else SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 0); - if (samples > 1) + if (mode->samples > 1) { SDL_GL_SetAttribute (SDL_GL_MULTISAMPLEBUFFERS, 1); - SDL_GL_SetAttribute (SDL_GL_MULTISAMPLESAMPLES, samples); + SDL_GL_SetAttribute (SDL_GL_MULTISAMPLESAMPLES, mode->samples); } - video_bpp = bpp; + video_bpp = mode->bitsperpixel; video_flags = flags; - VID_SetIcon(); - screen = SDL_SetVideoMode(*width, *height, bpp, flags); + VID_SetIcon_Pre(); + screen = SDL_SetVideoMode(mode->width, mode->height, mode->bitsperpixel, flags); + VID_SetIcon_Post(); if (screen == NULL) { - Con_Printf("Failed to set video mode to %ix%i: %s\n", *width, *height, SDL_GetError()); + Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError()); VID_Shutdown(); return false; } @@ -761,7 +1067,6 @@ int VID_InitMode(int fullscreen, int *width, int *height, int bpp, int refreshra gl_platform = "SDL"; gl_platformextensions = ""; - gl_videosyncavailable = true; GL_Init(); @@ -830,7 +1135,7 @@ void VID_Finish (void) VID_UpdateGamma(false, 256); - if (r_render.integer && !vid_hidden) + if (!vid_hidden) { CHECKGLERROR if (r_speeds.integer == 2 || gl_finish.integer)