]> git.xonotic.org Git - xonotic/darkplaces.git/blob - vid_sdl.c
added joy_axiskeyevents_deadzone cvar which makes the arrow key
[xonotic/darkplaces.git] / vid_sdl.c
1 /*
2 Copyright (C) 2003  T. Joseph Carter
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 */
19 #undef WIN32_LEAN_AND_MEAN  //hush a warning, SDL.h redefines this
20 #include <SDL.h>
21 #include <SDL_syswm.h>
22 #include <stdio.h>
23
24 #include "quakedef.h"
25 #include "image.h"
26 #include "dpsoftrast.h"
27
28 #ifndef __IPHONEOS__
29 #ifdef MACOSX
30 #include <Carbon/Carbon.h>
31 #include <IOKit/hidsystem/IOHIDLib.h>
32 #include <IOKit/hidsystem/IOHIDParameter.h>
33 #include <IOKit/hidsystem/event_status_driver.h>
34 static cvar_t apple_mouse_noaccel = {CVAR_SAVE, "apple_mouse_noaccel", "1", "disables mouse acceleration while DarkPlaces is active"};
35 static qboolean vid_usingnoaccel;
36 static double originalMouseSpeed = -1.0;
37 io_connect_t IN_GetIOHandle(void)
38 {
39         io_connect_t iohandle = MACH_PORT_NULL;
40         kern_return_t status;
41         io_service_t iohidsystem = MACH_PORT_NULL;
42         mach_port_t masterport;
43
44         status = IOMasterPort(MACH_PORT_NULL, &masterport);
45         if(status != KERN_SUCCESS)
46                 return 0;
47
48         iohidsystem = IORegistryEntryFromPath(masterport, kIOServicePlane ":/IOResources/IOHIDSystem");
49         if(!iohidsystem)
50                 return 0;
51
52         status = IOServiceOpen(iohidsystem, mach_task_self(), kIOHIDParamConnectType, &iohandle);
53         IOObjectRelease(iohidsystem);
54
55         return iohandle;
56 }
57 #endif
58 #endif
59
60 #ifdef WIN32
61 #define SDL_R_RESTART
62 #endif
63
64 // Tell startup code that we have a client
65 int cl_available = true;
66
67 qboolean vid_supportrefreshrate = false;
68
69 cvar_t vid_soft = {CVAR_SAVE, "vid_soft", "0", "enables use of the DarkPlaces Software Rasterizer rather than OpenGL or Direct3D"};
70 cvar_t vid_soft_threads = {CVAR_SAVE, "vid_soft_threads", "2", "the number of threads the DarkPlaces Software Rasterizer should use"}; 
71 cvar_t vid_soft_interlace = {CVAR_SAVE, "vid_soft_interlace", "1", "whether the DarkPlaces Software Rasterizer should interlace the screen bands occupied by each thread"};
72 cvar_t joy_detected = {CVAR_READONLY, "joy_detected", "0", "number of joysticks detected by engine"};
73 cvar_t joy_enable = {CVAR_SAVE, "joy_enable", "0", "enables joystick support"};
74 cvar_t joy_index = {0, "joy_index", "0", "selects which joystick to use if you have multiple"};
75 cvar_t joy_axisforward = {0, "joy_axisforward", "1", "which joystick axis to query for forward/backward movement"};
76 cvar_t joy_axisside = {0, "joy_axisside", "0", "which joystick axis to query for right/left movement"};
77 cvar_t joy_axisup = {0, "joy_axisup", "-1", "which joystick axis to query for up/down movement"};
78 cvar_t joy_axispitch = {0, "joy_axispitch", "3", "which joystick axis to query for looking up/down"};
79 cvar_t joy_axisyaw = {0, "joy_axisyaw", "2", "which joystick axis to query for looking right/left"};
80 cvar_t joy_axisroll = {0, "joy_axisroll", "-1", "which joystick axis to query for tilting head right/left"};
81 cvar_t joy_deadzoneforward = {0, "joy_deadzoneforward", "0", "deadzone tolerance, suggested values are in the range 0 to 0.01"};
82 cvar_t joy_deadzoneside = {0, "joy_deadzoneside", "0", "deadzone tolerance, suggested values are in the range 0 to 0.01"};
83 cvar_t joy_deadzoneup = {0, "joy_deadzoneup", "0", "deadzone tolerance, suggested values are in the range 0 to 0.01"};
84 cvar_t joy_deadzonepitch = {0, "joy_deadzonepitch", "0", "deadzone tolerance, suggested values are in the range 0 to 0.01"};
85 cvar_t joy_deadzoneyaw = {0, "joy_deadzoneyaw", "0", "deadzone tolerance, suggested values are in the range 0 to 0.01"};
86 cvar_t joy_deadzoneroll = {0, "joy_deadzoneroll", "0", "deadzone tolerance, suggested values are in the range 0 to 0.01"};
87 cvar_t joy_sensitivityforward = {0, "joy_sensitivityforward", "-1", "movement multiplier"};
88 cvar_t joy_sensitivityside = {0, "joy_sensitivityside", "1", "movement multiplier"};
89 cvar_t joy_sensitivityup = {0, "joy_sensitivityup", "1", "movement multiplier"};
90 cvar_t joy_sensitivitypitch = {0, "joy_sensitivitypitch", "1", "movement multiplier"};
91 cvar_t joy_sensitivityyaw = {0, "joy_sensitivityyaw", "-1", "movement multiplier"};
92 cvar_t joy_sensitivityroll = {0, "joy_sensitivityroll", "1", "movement multiplier"};
93 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"};
94 cvar_t joy_axiskeyevents_deadzone = {CVAR_SAVE, "joy_axiskeyevents_deadzone", "0.5", "deadzone value for axes"};
95
96 #ifdef __IPHONEOS__
97 # define SETVIDEOMODE 0
98 #else
99 # if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION == 2
100 #  define SETVIDEOMODE 1
101 # else
102 // LordHavoc: SDL 1.3's SDL_CreateWindow API is not finished enough to use yet, but you can set this to 0 if you want to try it...
103 #  ifndef SETVIDEOMODE
104 #   define SETVIDEOMODE 1
105 #  endif
106 # endif
107 #endif
108
109 static qboolean vid_usingmouse = false;
110 static qboolean vid_usinghidecursor = false;
111 static qboolean vid_hasfocus = false;
112 static qboolean vid_isfullscreen;
113 #if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION == 2
114 #else
115 static qboolean vid_usingvsync = false;
116 #endif
117 static int vid_numjoysticks = 0;
118 #define MAX_JOYSTICKS 8
119 static SDL_Joystick *vid_joysticks[MAX_JOYSTICKS];
120
121 static int win_half_width = 50;
122 static int win_half_height = 50;
123 static int video_bpp;
124
125 #if SETVIDEOMODE
126 static SDL_Surface *screen;
127 static int video_flags;
128 #else
129 static SDL_GLContext *context;
130 static SDL_Window *window;
131 static int window_flags;
132 #endif
133 static SDL_Surface *vid_softsurface;
134
135 // joystick axes state
136 #define MAX_JOYSTICK_AXES       16
137 typedef struct
138 {
139         float oldmove;
140         float move;
141         double keytime;
142 }joy_axiscache_t;
143 static joy_axiscache_t joy_axescache[MAX_JOYSTICK_AXES];
144
145 /////////////////////////
146 // Input handling
147 ////
148 //TODO: Add joystick support
149 //TODO: Add error checking
150
151 #ifndef SDLK_PERCENT
152 #define SDLK_PERCENT '%'
153 #define SDLK_PRINTSCREEN SDLK_PRINT
154 #define SDLK_SCROLLLOCK SDLK_SCROLLOCK
155 #define SDLK_NUMLOCKCLEAR SDLK_NUMLOCK
156 #define SDLK_KP_1 SDLK_KP1
157 #define SDLK_KP_2 SDLK_KP2
158 #define SDLK_KP_3 SDLK_KP3
159 #define SDLK_KP_4 SDLK_KP4
160 #define SDLK_KP_5 SDLK_KP5
161 #define SDLK_KP_6 SDLK_KP6
162 #define SDLK_KP_7 SDLK_KP7
163 #define SDLK_KP_8 SDLK_KP8
164 #define SDLK_KP_9 SDLK_KP9
165 #define SDLK_KP_0 SDLK_KP0
166 #endif
167
168 static int MapKey( unsigned int sdlkey )
169 {
170         switch(sdlkey)
171         {
172         default: return 0;
173 //      case SDLK_UNKNOWN:            return K_UNKNOWN;
174         case SDLK_RETURN:             return K_ENTER;
175         case SDLK_ESCAPE:             return K_ESCAPE;
176         case SDLK_BACKSPACE:          return K_BACKSPACE;
177         case SDLK_TAB:                return K_TAB;
178         case SDLK_SPACE:              return K_SPACE;
179         case SDLK_EXCLAIM:            return '!';
180         case SDLK_QUOTEDBL:           return '"';
181         case SDLK_HASH:               return '#';
182         case SDLK_PERCENT:            return '%';
183         case SDLK_DOLLAR:             return '$';
184         case SDLK_AMPERSAND:          return '&';
185         case SDLK_QUOTE:              return '\'';
186         case SDLK_LEFTPAREN:          return '(';
187         case SDLK_RIGHTPAREN:         return ')';
188         case SDLK_ASTERISK:           return '*';
189         case SDLK_PLUS:               return '+';
190         case SDLK_COMMA:              return ',';
191         case SDLK_MINUS:              return '-';
192         case SDLK_PERIOD:             return '.';
193         case SDLK_SLASH:              return '/';
194         case SDLK_0:                  return '0';
195         case SDLK_1:                  return '1';
196         case SDLK_2:                  return '2';
197         case SDLK_3:                  return '3';
198         case SDLK_4:                  return '4';
199         case SDLK_5:                  return '5';
200         case SDLK_6:                  return '6';
201         case SDLK_7:                  return '7';
202         case SDLK_8:                  return '8';
203         case SDLK_9:                  return '9';
204         case SDLK_COLON:              return ':';
205         case SDLK_SEMICOLON:          return ';';
206         case SDLK_LESS:               return '<';
207         case SDLK_EQUALS:             return '=';
208         case SDLK_GREATER:            return '>';
209         case SDLK_QUESTION:           return '?';
210         case SDLK_AT:                 return '@';
211         case SDLK_LEFTBRACKET:        return '[';
212         case SDLK_BACKSLASH:          return '\\';
213         case SDLK_RIGHTBRACKET:       return ']';
214         case SDLK_CARET:              return '^';
215         case SDLK_UNDERSCORE:         return '_';
216         case SDLK_BACKQUOTE:          return '`';
217         case SDLK_a:                  return 'a';
218         case SDLK_b:                  return 'b';
219         case SDLK_c:                  return 'c';
220         case SDLK_d:                  return 'd';
221         case SDLK_e:                  return 'e';
222         case SDLK_f:                  return 'f';
223         case SDLK_g:                  return 'g';
224         case SDLK_h:                  return 'h';
225         case SDLK_i:                  return 'i';
226         case SDLK_j:                  return 'j';
227         case SDLK_k:                  return 'k';
228         case SDLK_l:                  return 'l';
229         case SDLK_m:                  return 'm';
230         case SDLK_n:                  return 'n';
231         case SDLK_o:                  return 'o';
232         case SDLK_p:                  return 'p';
233         case SDLK_q:                  return 'q';
234         case SDLK_r:                  return 'r';
235         case SDLK_s:                  return 's';
236         case SDLK_t:                  return 't';
237         case SDLK_u:                  return 'u';
238         case SDLK_v:                  return 'v';
239         case SDLK_w:                  return 'w';
240         case SDLK_x:                  return 'x';
241         case SDLK_y:                  return 'y';
242         case SDLK_z:                  return 'z';
243         case SDLK_CAPSLOCK:           return K_CAPSLOCK;
244         case SDLK_F1:                 return K_F1;
245         case SDLK_F2:                 return K_F2;
246         case SDLK_F3:                 return K_F3;
247         case SDLK_F4:                 return K_F4;
248         case SDLK_F5:                 return K_F5;
249         case SDLK_F6:                 return K_F6;
250         case SDLK_F7:                 return K_F7;
251         case SDLK_F8:                 return K_F8;
252         case SDLK_F9:                 return K_F9;
253         case SDLK_F10:                return K_F10;
254         case SDLK_F11:                return K_F11;
255         case SDLK_F12:                return K_F12;
256         case SDLK_PRINTSCREEN:        return K_PRINTSCREEN;
257         case SDLK_SCROLLLOCK:         return K_SCROLLOCK;
258         case SDLK_PAUSE:              return K_PAUSE;
259         case SDLK_INSERT:             return K_INS;
260         case SDLK_HOME:               return K_HOME;
261         case SDLK_PAGEUP:             return K_PGUP;
262 #ifdef __IPHONEOS__
263         case SDLK_DELETE:             return K_BACKSPACE;
264 #else
265         case SDLK_DELETE:             return K_DEL;
266 #endif
267         case SDLK_END:                return K_END;
268         case SDLK_PAGEDOWN:           return K_PGDN;
269         case SDLK_RIGHT:              return K_RIGHTARROW;
270         case SDLK_LEFT:               return K_LEFTARROW;
271         case SDLK_DOWN:               return K_DOWNARROW;
272         case SDLK_UP:                 return K_UPARROW;
273         case SDLK_NUMLOCKCLEAR:       return K_NUMLOCK;
274         case SDLK_KP_DIVIDE:          return K_KP_DIVIDE;
275         case SDLK_KP_MULTIPLY:        return K_KP_MULTIPLY;
276         case SDLK_KP_MINUS:           return K_KP_MINUS;
277         case SDLK_KP_PLUS:            return K_KP_PLUS;
278         case SDLK_KP_ENTER:           return K_KP_ENTER;
279         case SDLK_KP_1:               return K_KP_1;
280         case SDLK_KP_2:               return K_KP_2;
281         case SDLK_KP_3:               return K_KP_3;
282         case SDLK_KP_4:               return K_KP_4;
283         case SDLK_KP_5:               return K_KP_5;
284         case SDLK_KP_6:               return K_KP_6;
285         case SDLK_KP_7:               return K_KP_7;
286         case SDLK_KP_8:               return K_KP_8;
287         case SDLK_KP_9:               return K_KP_9;
288         case SDLK_KP_0:               return K_KP_0;
289         case SDLK_KP_PERIOD:          return K_KP_PERIOD;
290 //      case SDLK_APPLICATION:        return K_APPLICATION;
291 //      case SDLK_POWER:              return K_POWER;
292         case SDLK_KP_EQUALS:          return K_KP_EQUALS;
293 //      case SDLK_F13:                return K_F13;
294 //      case SDLK_F14:                return K_F14;
295 //      case SDLK_F15:                return K_F15;
296 //      case SDLK_F16:                return K_F16;
297 //      case SDLK_F17:                return K_F17;
298 //      case SDLK_F18:                return K_F18;
299 //      case SDLK_F19:                return K_F19;
300 //      case SDLK_F20:                return K_F20;
301 //      case SDLK_F21:                return K_F21;
302 //      case SDLK_F22:                return K_F22;
303 //      case SDLK_F23:                return K_F23;
304 //      case SDLK_F24:                return K_F24;
305 //      case SDLK_EXECUTE:            return K_EXECUTE;
306 //      case SDLK_HELP:               return K_HELP;
307 //      case SDLK_MENU:               return K_MENU;
308 //      case SDLK_SELECT:             return K_SELECT;
309 //      case SDLK_STOP:               return K_STOP;
310 //      case SDLK_AGAIN:              return K_AGAIN;
311 //      case SDLK_UNDO:               return K_UNDO;
312 //      case SDLK_CUT:                return K_CUT;
313 //      case SDLK_COPY:               return K_COPY;
314 //      case SDLK_PASTE:              return K_PASTE;
315 //      case SDLK_FIND:               return K_FIND;
316 //      case SDLK_MUTE:               return K_MUTE;
317 //      case SDLK_VOLUMEUP:           return K_VOLUMEUP;
318 //      case SDLK_VOLUMEDOWN:         return K_VOLUMEDOWN;
319 //      case SDLK_KP_COMMA:           return K_KP_COMMA;
320 //      case SDLK_KP_EQUALSAS400:     return K_KP_EQUALSAS400;
321 //      case SDLK_ALTERASE:           return K_ALTERASE;
322 //      case SDLK_SYSREQ:             return K_SYSREQ;
323 //      case SDLK_CANCEL:             return K_CANCEL;
324 //      case SDLK_CLEAR:              return K_CLEAR;
325 //      case SDLK_PRIOR:              return K_PRIOR;
326 //      case SDLK_RETURN2:            return K_RETURN2;
327 //      case SDLK_SEPARATOR:          return K_SEPARATOR;
328 //      case SDLK_OUT:                return K_OUT;
329 //      case SDLK_OPER:               return K_OPER;
330 //      case SDLK_CLEARAGAIN:         return K_CLEARAGAIN;
331 //      case SDLK_CRSEL:              return K_CRSEL;
332 //      case SDLK_EXSEL:              return K_EXSEL;
333 //      case SDLK_KP_00:              return K_KP_00;
334 //      case SDLK_KP_000:             return K_KP_000;
335 //      case SDLK_THOUSANDSSEPARATOR: return K_THOUSANDSSEPARATOR;
336 //      case SDLK_DECIMALSEPARATOR:   return K_DECIMALSEPARATOR;
337 //      case SDLK_CURRENCYUNIT:       return K_CURRENCYUNIT;
338 //      case SDLK_CURRENCYSUBUNIT:    return K_CURRENCYSUBUNIT;
339 //      case SDLK_KP_LEFTPAREN:       return K_KP_LEFTPAREN;
340 //      case SDLK_KP_RIGHTPAREN:      return K_KP_RIGHTPAREN;
341 //      case SDLK_KP_LEFTBRACE:       return K_KP_LEFTBRACE;
342 //      case SDLK_KP_RIGHTBRACE:      return K_KP_RIGHTBRACE;
343 //      case SDLK_KP_TAB:             return K_KP_TAB;
344 //      case SDLK_KP_BACKSPACE:       return K_KP_BACKSPACE;
345 //      case SDLK_KP_A:               return K_KP_A;
346 //      case SDLK_KP_B:               return K_KP_B;
347 //      case SDLK_KP_C:               return K_KP_C;
348 //      case SDLK_KP_D:               return K_KP_D;
349 //      case SDLK_KP_E:               return K_KP_E;
350 //      case SDLK_KP_F:               return K_KP_F;
351 //      case SDLK_KP_XOR:             return K_KP_XOR;
352 //      case SDLK_KP_POWER:           return K_KP_POWER;
353 //      case SDLK_KP_PERCENT:         return K_KP_PERCENT;
354 //      case SDLK_KP_LESS:            return K_KP_LESS;
355 //      case SDLK_KP_GREATER:         return K_KP_GREATER;
356 //      case SDLK_KP_AMPERSAND:       return K_KP_AMPERSAND;
357 //      case SDLK_KP_DBLAMPERSAND:    return K_KP_DBLAMPERSAND;
358 //      case SDLK_KP_VERTICALBAR:     return K_KP_VERTICALBAR;
359 //      case SDLK_KP_DBLVERTICALBAR:  return K_KP_DBLVERTICALBAR;
360 //      case SDLK_KP_COLON:           return K_KP_COLON;
361 //      case SDLK_KP_HASH:            return K_KP_HASH;
362 //      case SDLK_KP_SPACE:           return K_KP_SPACE;
363 //      case SDLK_KP_AT:              return K_KP_AT;
364 //      case SDLK_KP_EXCLAM:          return K_KP_EXCLAM;
365 //      case SDLK_KP_MEMSTORE:        return K_KP_MEMSTORE;
366 //      case SDLK_KP_MEMRECALL:       return K_KP_MEMRECALL;
367 //      case SDLK_KP_MEMCLEAR:        return K_KP_MEMCLEAR;
368 //      case SDLK_KP_MEMADD:          return K_KP_MEMADD;
369 //      case SDLK_KP_MEMSUBTRACT:     return K_KP_MEMSUBTRACT;
370 //      case SDLK_KP_MEMMULTIPLY:     return K_KP_MEMMULTIPLY;
371 //      case SDLK_KP_MEMDIVIDE:       return K_KP_MEMDIVIDE;
372 //      case SDLK_KP_PLUSMINUS:       return K_KP_PLUSMINUS;
373 //      case SDLK_KP_CLEAR:           return K_KP_CLEAR;
374 //      case SDLK_KP_CLEARENTRY:      return K_KP_CLEARENTRY;
375 //      case SDLK_KP_BINARY:          return K_KP_BINARY;
376 //      case SDLK_KP_OCTAL:           return K_KP_OCTAL;
377 //      case SDLK_KP_DECIMAL:         return K_KP_DECIMAL;
378 //      case SDLK_KP_HEXADECIMAL:     return K_KP_HEXADECIMAL;
379         case SDLK_LCTRL:              return K_CTRL;
380         case SDLK_LSHIFT:             return K_SHIFT;
381         case SDLK_LALT:               return K_ALT;
382 //      case SDLK_LGUI:               return K_LGUI;
383         case SDLK_RCTRL:              return K_CTRL;
384         case SDLK_RSHIFT:             return K_SHIFT;
385         case SDLK_RALT:               return K_ALT;
386 //      case SDLK_RGUI:               return K_RGUI;
387 //      case SDLK_MODE:               return K_MODE;
388 //      case SDLK_AUDIONEXT:          return K_AUDIONEXT;
389 //      case SDLK_AUDIOPREV:          return K_AUDIOPREV;
390 //      case SDLK_AUDIOSTOP:          return K_AUDIOSTOP;
391 //      case SDLK_AUDIOPLAY:          return K_AUDIOPLAY;
392 //      case SDLK_AUDIOMUTE:          return K_AUDIOMUTE;
393 //      case SDLK_MEDIASELECT:        return K_MEDIASELECT;
394 //      case SDLK_WWW:                return K_WWW;
395 //      case SDLK_MAIL:               return K_MAIL;
396 //      case SDLK_CALCULATOR:         return K_CALCULATOR;
397 //      case SDLK_COMPUTER:           return K_COMPUTER;
398 //      case SDLK_AC_SEARCH:          return K_AC_SEARCH;
399 //      case SDLK_AC_HOME:            return K_AC_HOME;
400 //      case SDLK_AC_BACK:            return K_AC_BACK;
401 //      case SDLK_AC_FORWARD:         return K_AC_FORWARD;
402 //      case SDLK_AC_STOP:            return K_AC_STOP;
403 //      case SDLK_AC_REFRESH:         return K_AC_REFRESH;
404 //      case SDLK_AC_BOOKMARKS:       return K_AC_BOOKMARKS;
405 //      case SDLK_BRIGHTNESSDOWN:     return K_BRIGHTNESSDOWN;
406 //      case SDLK_BRIGHTNESSUP:       return K_BRIGHTNESSUP;
407 //      case SDLK_DISPLAYSWITCH:      return K_DISPLAYSWITCH;
408 //      case SDLK_KBDILLUMTOGGLE:     return K_KBDILLUMTOGGLE;
409 //      case SDLK_KBDILLUMDOWN:       return K_KBDILLUMDOWN;
410 //      case SDLK_KBDILLUMUP:         return K_KBDILLUMUP;
411 //      case SDLK_EJECT:              return K_EJECT;
412 //      case SDLK_SLEEP:              return K_SLEEP;
413         }
414 }
415
416 #ifdef __IPHONEOS__
417 int SDL_iPhoneKeyboardShow(SDL_Window * window);  // reveals the onscreen keyboard.  Returns 0 on success and -1 on error.
418 int SDL_iPhoneKeyboardHide(SDL_Window * window);  // hides the onscreen keyboard.  Returns 0 on success and -1 on error.
419 SDL_bool SDL_iPhoneKeyboardIsShown(SDL_Window * window);  // returns whether or not the onscreen keyboard is currently visible.
420 int SDL_iPhoneKeyboardToggle(SDL_Window * window); // toggles the visibility of the onscreen keyboard.  Returns 0 on success and -1 on error.
421 #endif
422
423 void VID_ShowKeyboard(qboolean show)
424 {
425 #ifdef __IPHONEOS__
426         if (show)
427         {
428                 if (!SDL_iPhoneKeyboardIsShown(window))
429                         SDL_iPhoneKeyboardShow(window);
430         }
431         else
432         {
433                 if (SDL_iPhoneKeyboardIsShown(window))
434                         SDL_iPhoneKeyboardHide(window);
435         }
436 #endif
437 }
438
439 #ifdef __IPHONEOS__
440 qboolean VID_ShowingKeyboard(void)
441 {
442         return SDL_iPhoneKeyboardIsShown(window);
443 }
444 #endif
445
446 void VID_SetMouse(qboolean fullscreengrab, qboolean relative, qboolean hidecursor)
447 {
448 #ifndef __IPHONEOS__
449 #ifdef MACOSX
450         if(relative)
451                 if(vid_usingmouse && (vid_usingnoaccel != !!apple_mouse_noaccel.integer))
452                         VID_SetMouse(false, false, false); // ungrab first!
453 #endif
454         if (vid_usingmouse != relative)
455         {
456                 vid_usingmouse = relative;
457                 cl_ignoremousemoves = 2;
458 #if SETVIDEOMODE
459                 SDL_WM_GrabInput( relative ? SDL_GRAB_ON : SDL_GRAB_OFF );
460 #else
461                 SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE);
462 #endif
463 #ifdef MACOSX
464                 if(relative)
465                 {
466                         // Save the status of mouse acceleration
467                         originalMouseSpeed = -1.0; // in case of error
468                         if(apple_mouse_noaccel.integer)
469                         {
470                                 io_connect_t mouseDev = IN_GetIOHandle();
471                                 if(mouseDev != 0)
472                                 {
473                                         if(IOHIDGetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), &originalMouseSpeed) == kIOReturnSuccess)
474                                         {
475                                                 Con_DPrintf("previous mouse acceleration: %f\n", originalMouseSpeed);
476                                                 if(IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), -1.0) != kIOReturnSuccess)
477                                                 {
478                                                         Con_Print("Could not disable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n");
479                                                         Cvar_SetValueQuick(&apple_mouse_noaccel, 0);
480                                                 }
481                                         }
482                                         else
483                                         {
484                                                 Con_Print("Could not disable mouse acceleration (failed at IOHIDGetAccelerationWithKey).\n");
485                                                 Cvar_SetValueQuick(&apple_mouse_noaccel, 0);
486                                         }
487                                         IOServiceClose(mouseDev);
488                                 }
489                                 else
490                                 {
491                                         Con_Print("Could not disable mouse acceleration (failed at IO_GetIOHandle).\n");
492                                         Cvar_SetValueQuick(&apple_mouse_noaccel, 0);
493                                 }
494                         }
495
496                         vid_usingnoaccel = !!apple_mouse_noaccel.integer;
497                 }
498                 else
499                 {
500                         if(originalMouseSpeed != -1.0)
501                         {
502                                 io_connect_t mouseDev = IN_GetIOHandle();
503                                 if(mouseDev != 0)
504                                 {
505                                         Con_DPrintf("restoring mouse acceleration to: %f\n", originalMouseSpeed);
506                                         if(IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), originalMouseSpeed) != kIOReturnSuccess)
507                                                 Con_Print("Could not re-enable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n");
508                                         IOServiceClose(mouseDev);
509                                 }
510                                 else
511                                         Con_Print("Could not re-enable mouse acceleration (failed at IO_GetIOHandle).\n");
512                         }
513                 }
514 #endif
515         }
516         if (vid_usinghidecursor != hidecursor)
517         {
518                 vid_usinghidecursor = hidecursor;
519                 SDL_ShowCursor( hidecursor ? SDL_DISABLE : SDL_ENABLE);
520         }
521 #endif
522 }
523
524 static double IN_JoystickGetAxis(SDL_Joystick *joy, int axis, double sensitivity, double deadzone)
525 {
526         double value;
527         if (axis < 0 || axis >= SDL_JoystickNumAxes(joy))
528                 return 0; // no such axis on this joystick
529         value = SDL_JoystickGetAxis(joy, axis) * (1.0 / 32767.0);
530         value = bound(-1, value, 1);
531         if (fabs(value) < deadzone)
532                 return 0; // within deadzone around center
533         return value * sensitivity;
534 }
535
536 /////////////////////
537 // Joystick axis keyevents
538 // a sort of hack emulating Arrow keys for joystick axises
539 // as some drives dont send such keyevents for them
540 // additionally we should block drivers that do send arrow keyevents to prevent double events
541 ////
542
543 static void IN_JoystickKeyeventForAxis(SDL_Joystick *joy, int axis, int key_pos, int key_neg)
544 {
545         double joytime;
546
547         if (axis < 0 || axis >= SDL_JoystickNumAxes(joy))
548                 return; // no such axis on this joystick
549
550         joytime = Sys_DoubleTime();
551         // no key event, continuous keydown event
552         if (joy_axescache[axis].move == joy_axescache[axis].oldmove)
553         {
554                 if (joy_axescache[axis].move != 0 && joytime > joy_axescache[axis].keytime)
555                 {
556                         //Con_Printf("joy %s %i %f\n", Key_KeynumToString((joy_axescache[axis].move > 0) ? key_pos : key_neg), 1, cl.time);
557                         Key_Event((joy_axescache[axis].move > 0) ? key_pos : key_neg, 0, 1);
558                         joy_axescache[axis].keytime = joytime + 0.5 / 20;
559                 }
560                 return;
561         }
562         // generate key up event
563         if (joy_axescache[axis].oldmove)
564         {
565                 //Con_Printf("joy %s %i %f\n", Key_KeynumToString((joy_axescache[axis].oldmove > 0) ? key_pos : key_neg), 1, cl.time);
566                 Key_Event((joy_axescache[axis].oldmove > 0) ? key_pos : key_neg, 0, 0);
567         }
568         // generate key down event
569         if (joy_axescache[axis].move)
570         {
571                 //Con_Printf("joy %s %i %f\n", Key_KeynumToString((joy_axescache[axis].move > 0) ? key_pos : key_neg), 1, cl.time);
572                 Key_Event((joy_axescache[axis].move > 0) ? key_pos : key_neg, 0, 1);
573                 joy_axescache[axis].keytime = joytime + 0.5;
574         }
575 }
576
577 static qboolean IN_JoystickBlockDoubledKeyEvents(int keycode)
578 {
579         if (!joy_axiskeyevents.integer)
580                 return false;
581
582         // block keyevent if it's going to be provided by joystick keyevent system
583         if (vid_numjoysticks && joy_enable.integer && joy_index.integer >= 0 && joy_index.integer < vid_numjoysticks)
584         {
585                 SDL_Joystick *joy = vid_joysticks[joy_index.integer];
586
587                 if (keycode == K_UPARROW || keycode == K_DOWNARROW)
588                         if (IN_JoystickGetAxis(joy, joy_axisforward.integer, 1, joy_axiskeyevents_deadzone.value) || joy_axescache[joy_axisforward.integer].move || joy_axescache[joy_axisforward.integer].oldmove)
589                                 return true;
590                 if (keycode == K_RIGHTARROW || keycode == K_LEFTARROW)
591                         if (IN_JoystickGetAxis(joy, joy_axisside.integer, 1, joy_axiskeyevents_deadzone.value) || joy_axescache[joy_axisside.integer].move || joy_axescache[joy_axisside.integer].oldmove)
592                                 return true;
593         }
594
595         return false;
596 }
597
598 // multitouch[10][] represents the mouse pointer
599 // X and Y coordinates are 0-32767 as per SDL spec
600 #define MAXFINGERS 11
601 int multitouch[MAXFINGERS][3];
602
603 qboolean VID_TouchscreenArea(int corner, float px, float py, float pwidth, float pheight, const char *icon, float *resultmove, qboolean *resultbutton, keynum_t key)
604 {
605         int finger;
606         float fx, fy, fwidth, fheight;
607         float rel[3];
608         qboolean button = false;
609         VectorClear(rel);
610         if (pwidth > 0 && pheight > 0)
611 #ifdef __IPHONEOS__
612         if (!VID_ShowingKeyboard())
613 #endif
614         {
615                 if (corner & 1) px += vid_conwidth.value;
616                 if (corner & 2) py += vid_conheight.value;
617                 if (corner & 4) px += vid_conwidth.value * 0.5f;
618                 if (corner & 8) py += vid_conheight.value * 0.5f;
619                 if (corner & 16) {px *= vid_conwidth.value * (1.0f / 640.0f);py *= vid_conheight.value * (1.0f / 480.0f);pwidth *= vid_conwidth.value * (1.0f / 640.0f);pheight *= vid_conheight.value * (1.0f / 480.0f);}
620                 fx = px * 32768.0f / vid_conwidth.value;
621                 fy = py * 32768.0f / vid_conheight.value;
622                 fwidth = pwidth * 32768.0f / vid_conwidth.value;
623                 fheight = pheight * 32768.0f / vid_conheight.value;
624                 for (finger = 0;finger < MAXFINGERS;finger++)
625                 {
626                         if (multitouch[finger][0] && multitouch[finger][1] >= fx && multitouch[finger][2] >= fy && multitouch[finger][1] < fx + fwidth && multitouch[finger][2] < fy + fheight)
627                         {
628                                 rel[0] = (multitouch[finger][1] - (fx + 0.5f * fwidth)) * (2.0f / fwidth);
629                                 rel[1] = (multitouch[finger][2] - (fy + 0.5f * fheight)) * (2.0f / fheight);
630                                 rel[2] = 0;
631                                 button = true;
632                                 break;
633                         }
634                 }
635                 if (scr_numtouchscreenareas < 16)
636                 {
637                         scr_touchscreenareas[scr_numtouchscreenareas].pic = icon;
638                         scr_touchscreenareas[scr_numtouchscreenareas].rect[0] = px;
639                         scr_touchscreenareas[scr_numtouchscreenareas].rect[1] = py;
640                         scr_touchscreenareas[scr_numtouchscreenareas].rect[2] = pwidth;
641                         scr_touchscreenareas[scr_numtouchscreenareas].rect[3] = pheight;
642                         scr_touchscreenareas[scr_numtouchscreenareas].active = button;
643                         scr_numtouchscreenareas++;
644                 }
645         }
646         if (resultmove)
647         {
648                 if (button)
649                         VectorCopy(rel, resultmove);
650                 else
651                         VectorClear(resultmove);
652         }
653         if (resultbutton)
654         {
655                 if (*resultbutton != button && (int)key > 0)
656                         Key_Event(key, 0, button);
657                 *resultbutton = button;
658         }
659         return button;
660 }
661
662 /////////////////////
663 // Movement handling
664 ////
665
666 void IN_Move( void )
667 {
668         int j;
669         static int old_x = 0, old_y = 0;
670         static int stuck = 0;
671         int x, y, numaxes, numballs;
672
673         scr_numtouchscreenareas = 0;
674         if (vid_touchscreen.integer)
675         {
676                 vec3_t move, aim, click;
677                 static qboolean buttons[16];
678                 static keydest_t oldkeydest;
679                 keydest_t keydest = (key_consoleactive & KEY_CONSOLEACTIVE_USER) ? key_console : key_dest;
680                 multitouch[MAXFINGERS-1][0] = SDL_GetMouseState(&x, &y);
681                 multitouch[MAXFINGERS-1][1] = x * 32768 / vid.width;
682                 multitouch[MAXFINGERS-1][2] = y * 32768 / vid.height;
683                 if (oldkeydest != keydest)
684                 {
685                         switch(keydest)
686                         {
687                         case key_game: VID_ShowKeyboard(false);break;
688                         case key_console: VID_ShowKeyboard(true);break;
689                         case key_message: VID_ShowKeyboard(true);break;
690                         default: break;
691                         }
692                 }
693                 oldkeydest = keydest;
694                 // top of screen is toggleconsole and K_ESCAPE
695                 switch(keydest)
696                 {
697                 case key_console:
698 #ifdef __IPHONEOS__
699                         VID_TouchscreenArea( 0,   0,   0,  64,  64, NULL                         , NULL, &buttons[13], (keynum_t)'`');
700                         VID_TouchscreenArea( 0,  64,   0,  64,  64, "gfx/touch_menu.tga"         , NULL, &buttons[14], K_ESCAPE);
701                         if (!VID_ShowingKeyboard())
702                         {
703                                 // user entered a command, close the console now
704                                 Con_ToggleConsole_f();
705                         }
706 #endif
707                         VID_TouchscreenArea( 0,   0,   0,   0,   0, NULL                         , NULL, &buttons[15], (keynum_t)0);
708                         VID_TouchscreenArea( 0,   0,   0,   0,   0, NULL                         , move, &buttons[0], K_MOUSE4);
709                         VID_TouchscreenArea( 0,   0,   0,   0,   0, NULL                         , aim,  &buttons[1], K_MOUSE5);
710                         VID_TouchscreenArea( 0,   0,   0,   0,   0, NULL                         , click,&buttons[2], K_MOUSE1);
711                         VID_TouchscreenArea( 0,   0,   0,   0,   0, NULL                         , NULL, &buttons[3], K_SPACE);
712                         VID_TouchscreenArea( 0,   0,   0,   0,   0, NULL                         , NULL, &buttons[4], K_MOUSE2);
713                         break;
714                 case key_game:
715 #ifdef __IPHONEOS__
716                         VID_TouchscreenArea( 0,   0,   0,  64,  64, NULL                         , NULL, &buttons[13], (keynum_t)'`');
717                         VID_TouchscreenArea( 0,  64,   0,  64,  64, "gfx/touch_menu.tga"         , NULL, &buttons[14], K_ESCAPE);
718 #endif
719                         VID_TouchscreenArea( 2,   0,-128, 128, 128, "gfx/touch_movebutton.tga"   , move, &buttons[0], K_MOUSE4);
720                         VID_TouchscreenArea( 3,-128,-128, 128, 128, "gfx/touch_aimbutton.tga"    , aim,  &buttons[1], K_MOUSE5);
721                         VID_TouchscreenArea( 2,   0,-160,  64,  32, "gfx/touch_jumpbutton.tga"   , NULL, &buttons[3], K_SPACE);
722                         VID_TouchscreenArea( 3,-128,-160,  64,  32, "gfx/touch_attackbutton.tga" , NULL, &buttons[2], K_MOUSE1);
723                         VID_TouchscreenArea( 3, -64,-160,  64,  32, "gfx/touch_attack2button.tga", NULL, &buttons[4], K_MOUSE2);
724                         buttons[15] = false;
725                         break;
726                 default:
727 #ifdef __IPHONEOS__
728                         VID_TouchscreenArea( 0,   0,   0,  64,  64, NULL                         , NULL, &buttons[13], (keynum_t)'`');
729                         VID_TouchscreenArea( 0,  64,   0,  64,  64, "gfx/touch_menu.tga"         , NULL, &buttons[14], K_ESCAPE);
730                         // in menus, an icon in the corner activates keyboard
731                         VID_TouchscreenArea( 2,   0, -32,  32,  32, "gfx/touch_keyboard.tga"     , NULL, &buttons[15], (keynum_t)0);
732                         if (buttons[15])
733                                 VID_ShowKeyboard(true);
734                         VID_TouchscreenArea( 0,   0,   0,   0,   0, NULL                         , move, &buttons[0], K_MOUSE4);
735                         VID_TouchscreenArea( 0,   0,   0,   0,   0, NULL                         , aim,  &buttons[1], K_MOUSE5);
736                         VID_TouchscreenArea(16, -320,-480,640, 960, NULL                         , click,&buttons[2], K_MOUSE1);
737                         VID_TouchscreenArea( 0,   0,   0,   0,   0, NULL                         , NULL, &buttons[3], K_SPACE);
738                         VID_TouchscreenArea( 0,   0,   0,   0,   0, NULL                         , NULL, &buttons[4], K_MOUSE2);
739                         if (buttons[2])
740                         {
741                                 in_windowmouse_x = x;
742                                 in_windowmouse_y = y;
743                         }
744 #else
745                         VID_TouchscreenArea( 0,   0,   0,   0,   0, NULL                         , NULL, &buttons[15], (keynum_t)0);
746                         VID_TouchscreenArea( 0,   0,   0,   0,   0, NULL                         , move, &buttons[0], K_MOUSE4);
747                         VID_TouchscreenArea( 0,   0,   0,   0,   0, NULL                         , aim,  &buttons[1], K_MOUSE5);
748                         VID_TouchscreenArea( 0,   0,   0,   0,   0, NULL                         , click,&buttons[2], K_MOUSE1);
749                         VID_TouchscreenArea( 0,   0,   0,   0,   0, NULL                         , NULL, &buttons[3], K_SPACE);
750                         VID_TouchscreenArea( 0,   0,   0,   0,   0, NULL                         , NULL, &buttons[4], K_MOUSE2);
751 #endif
752                         break;
753                 }
754                 cl.cmd.forwardmove -= move[1] * cl_forwardspeed.value;
755                 cl.cmd.sidemove += move[0] * cl_sidespeed.value;
756                 cl.viewangles[0] += aim[1] * cl_pitchspeed.value * cl.realframetime;
757                 cl.viewangles[1] -= aim[0] * cl_yawspeed.value * cl.realframetime;
758         }
759         else
760         {
761                 if (vid_usingmouse)
762                 {
763                         if (vid_stick_mouse.integer)
764                         {
765                                 // have the mouse stuck in the middle, example use: prevent expose effect of beryl during the game when not using
766                                 // window grabbing. --blub
767         
768                                 // we need 2 frames to initialize the center position
769                                 if(!stuck)
770                                 {
771 #if SETVIDEOMODE
772                                         SDL_WarpMouse(win_half_width, win_half_height);
773 #else
774                                         SDL_WarpMouseInWindow(window, win_half_width, win_half_height);
775 #endif
776                                         SDL_GetMouseState(&x, &y);
777                                         SDL_GetRelativeMouseState(&x, &y);
778                                         ++stuck;
779                                 } else {
780                                         SDL_GetRelativeMouseState(&x, &y);
781                                         in_mouse_x = x + old_x;
782                                         in_mouse_y = y + old_y;
783                                         SDL_GetMouseState(&x, &y);
784                                         old_x = x - win_half_width;
785                                         old_y = y - win_half_height;
786 #if SETVIDEOMODE
787                                         SDL_WarpMouse(win_half_width, win_half_height);
788 #else
789                                         SDL_WarpMouseInWindow(window, win_half_width, win_half_height);
790 #endif
791                                 }
792                         } else {
793                                 SDL_GetRelativeMouseState( &x, &y );
794                                 in_mouse_x = x;
795                                 in_mouse_y = y;
796                         }
797                 }
798
799                 SDL_GetMouseState(&x, &y);
800                 in_windowmouse_x = x;
801                 in_windowmouse_y = y;
802         }
803
804         if (vid_numjoysticks && joy_enable.integer && joy_index.integer >= 0 && joy_index.integer < vid_numjoysticks)
805         {
806                 SDL_Joystick *joy = vid_joysticks[joy_index.integer];
807
808                 // balls convert to mousemove
809                 numballs = SDL_JoystickNumBalls(joy);
810                 for (j = 0;j < numballs;j++)
811                 {
812                         SDL_JoystickGetBall(joy, j, &x, &y);
813                         in_mouse_x += x;
814                         in_mouse_y += y;
815                 }
816
817                 // axes
818                 cl.cmd.forwardmove += IN_JoystickGetAxis(joy, joy_axisforward.integer, joy_sensitivityforward.value, joy_deadzoneforward.value) * cl_forwardspeed.value;
819                 cl.cmd.sidemove    += IN_JoystickGetAxis(joy, joy_axisside.integer, joy_sensitivityside.value, joy_deadzoneside.value) * cl_sidespeed.value;
820                 cl.cmd.upmove      += IN_JoystickGetAxis(joy, joy_axisup.integer, joy_sensitivityup.value, joy_deadzoneup.value) * cl_upspeed.value;
821                 cl.viewangles[0]   += IN_JoystickGetAxis(joy, joy_axispitch.integer, joy_sensitivitypitch.value, joy_deadzonepitch.value) * cl.realframetime * cl_pitchspeed.value;
822                 cl.viewangles[1]   += IN_JoystickGetAxis(joy, joy_axisyaw.integer, joy_sensitivityyaw.value, joy_deadzoneyaw.value) * cl.realframetime * cl_yawspeed.value;
823                 //cl.viewangles[2]   += IN_JoystickGetAxis(joy, joy_axisroll.integer, joy_sensitivityroll.value, joy_deadzoneroll.value) * cl.realframetime * cl_rollspeed.value;
824         
825                 // cache state of axes to emulate button events for them
826                 numaxes = min(MAX_JOYSTICK_AXES, SDL_JoystickNumAxes(joy));
827                 for (j = 0; j < numaxes; j++)
828                 {
829                         joy_axescache[j].oldmove = joy_axescache[j].move;
830                         joy_axescache[j].move = IN_JoystickGetAxis(joy, j, 1, joy_axiskeyevents_deadzone.value);
831                 }
832
833                 // run keyevents
834                 if (joy_axiskeyevents.integer)
835                 {
836                         IN_JoystickKeyeventForAxis(joy, joy_axisforward.integer, K_DOWNARROW, K_UPARROW);
837                         IN_JoystickKeyeventForAxis(joy, joy_axisside.integer, K_RIGHTARROW, K_LEFTARROW);
838                 }
839         }
840 }
841
842 /////////////////////
843 // Message Handling
844 ////
845
846 #ifdef SDL_R_RESTART
847 static qboolean sdl_needs_restart;
848 static void sdl_start(void)
849 {
850 }
851 static void sdl_shutdown(void)
852 {
853         sdl_needs_restart = false;
854 }
855 static void sdl_newmap(void)
856 {
857 }
858 #endif
859
860 #ifndef __IPHONEOS__
861 static keynum_t buttonremap[18] =
862 {
863         K_MOUSE1,
864         K_MOUSE3,
865         K_MOUSE2,
866         K_MWHEELUP,
867         K_MWHEELDOWN,
868         K_MOUSE4,
869         K_MOUSE5,
870         K_MOUSE6,
871         K_MOUSE7,
872         K_MOUSE8,
873         K_MOUSE9,
874         K_MOUSE10,
875         K_MOUSE11,
876         K_MOUSE12,
877         K_MOUSE13,
878         K_MOUSE14,
879         K_MOUSE15,
880         K_MOUSE16,
881 };
882 #endif
883
884 #if SETVIDEOMODE
885 // SDL 1.2
886 void Sys_SendKeyEvents( void )
887 {
888         static qboolean sound_active = true;
889         int keycode;
890         SDL_Event event;
891
892         while( SDL_PollEvent( &event ) )
893                 switch( event.type ) {
894                         case SDL_QUIT:
895                                 Sys_Quit(0);
896                                 break;
897                         case SDL_KEYDOWN:
898                         case SDL_KEYUP:
899                                 keycode = MapKey(event.key.keysym.sym);
900                                 if (!IN_JoystickBlockDoubledKeyEvents(keycode))
901                                         Key_Event(keycode, event.key.keysym.unicode, (event.key.state == SDL_PRESSED));
902                                 break;
903                         case SDL_ACTIVEEVENT:
904                                 if( event.active.state & SDL_APPACTIVE )
905                                 {
906                                         if( event.active.gain )
907                                                 vid_hidden = false;
908                                         else
909                                                 vid_hidden = true;
910                                 }
911                                 break;
912                         case SDL_MOUSEBUTTONDOWN:
913                         case SDL_MOUSEBUTTONUP:
914                                 if (!vid_touchscreen.integer)
915                                 if (event.button.button <= 18)
916                                         Key_Event( buttonremap[event.button.button - 1], 0, event.button.state == SDL_PRESSED );
917                                 break;
918                         case SDL_JOYBUTTONDOWN:
919                                 if (!joy_enable.integer)
920                                         break; // ignore down events if joystick has been disabled
921                         case SDL_JOYBUTTONUP:
922                                 if (event.jbutton.button < 48)
923                                         Key_Event( event.jbutton.button + (event.jbutton.button < 16 ? K_JOY1 : K_AUX1 - 16), 0, (event.jbutton.state == SDL_PRESSED) );
924                                 break;
925                         case SDL_VIDEORESIZE:
926                                 if(vid_resizable.integer < 2)
927                                 {
928                                         vid.width = event.resize.w;
929                                         vid.height = event.resize.h;
930                                         screen = SDL_SetVideoMode(vid.width, vid.height, video_bpp, video_flags);
931                                         if (vid_softsurface)
932                                         {
933                                                 SDL_FreeSurface(vid_softsurface);
934                                                 vid_softsurface = SDL_CreateRGBSurface(SDL_SWSURFACE, vid.width, vid.height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
935                                                 vid.softpixels = (unsigned int *)vid_softsurface->pixels;
936                                                 SDL_SetAlpha(vid_softsurface, 0, 255);
937                                                 if (vid.softdepthpixels)
938                                                         free(vid.softdepthpixels);
939                                                 vid.softdepthpixels = (unsigned int*)calloc(1, vid.width * vid.height * 4);
940                                         }
941 #ifdef SDL_R_RESTART
942                                         // better not call R_Modules_Restart from here directly, as this may wreak havoc...
943                                         // so, let's better queue it for next frame
944                                         if(!sdl_needs_restart)
945                                         {
946                                                 Cbuf_AddText("\nr_restart\n");
947                                                 sdl_needs_restart = true;
948                                         }
949 #endif
950                                 }
951                                 break;
952 #if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION == 2
953 #else
954                         case SDL_TEXTEDITING:
955                                 // unused when SETVIDEOMODE API is used
956                                 break;
957                         case SDL_TEXTINPUT:
958                                 // this occurs with SETVIDEOMODE but we are not using it
959                                 break;
960 #endif
961                         case SDL_MOUSEMOTION:
962                                 break;
963                         default:
964                                 Con_DPrintf("Received unrecognized SDL_Event type 0x%x\n", event.type);
965                                 break;
966                 }
967
968         // enable/disable sound on focus gain/loss
969         if ((!vid_hidden && vid_activewindow) || !snd_mutewhenidle.integer)
970         {
971                 if (!sound_active)
972                 {
973                         S_UnblockSound ();
974                         sound_active = true;
975                 }
976         }
977         else
978         {
979                 if (sound_active)
980                 {
981                         S_BlockSound ();
982                         sound_active = false;
983                 }
984         }
985 }
986
987 #else
988
989 // SDL 1.3
990 void Sys_SendKeyEvents( void )
991 {
992         static qboolean sound_active = true;
993         static qboolean missingunicodehack = true;
994         int keycode;
995         int i;
996         int j;
997         int unicode;
998         SDL_Event event;
999
1000         while( SDL_PollEvent( &event ) )
1001                 switch( event.type ) {
1002                         case SDL_QUIT:
1003                                 Sys_Quit(0);
1004                                 break;
1005                         case SDL_KEYDOWN:
1006                         case SDL_KEYUP:
1007                                 keycode = MapKey(event.key.keysym.sym);
1008                                 if (!IN_JoystickBlockDoubledKeyEvents(keycode))
1009 #ifdef __IPHONEOS__
1010                                 // the virtual keyboard seems to produce no unicode values...
1011                                 if (missingunicodehack && keycode >= ' ' && keycode < 0x7F && event.key.keysym.unicode == 0)
1012                                 {
1013                                         Con_DPrintf("SDL hack: no unicode value reported, substituting ascii value %i\n", keycode);
1014                                         Key_Event(keycode, keycode, (event.key.state == SDL_PRESSED));
1015                                 }
1016                                 else
1017 #endif
1018                                         Key_Event(keycode, 0, (event.key.state == SDL_PRESSED));
1019                                 break;
1020                         case SDL_MOUSEBUTTONDOWN:
1021                         case SDL_MOUSEBUTTONUP:
1022 #ifndef __IPHONEOS__
1023                                 if (!vid_touchscreen.integer)
1024                                 if (event.button.button <= 18)
1025                                         Key_Event( buttonremap[event.button.button - 1], 0, event.button.state == SDL_PRESSED );
1026 #endif
1027                                 break;
1028                         case SDL_JOYBUTTONDOWN:
1029                                 if (!joy_enable.integer)
1030                                         break; // ignore down events if joystick has been disabled
1031                         case SDL_JOYBUTTONUP:
1032                                 if (event.jbutton.button < 48)
1033                                         Key_Event( event.jbutton.button + (event.jbutton.button < 16 ? K_JOY1 : K_AUX1 - 16), 0, (event.jbutton.state == SDL_PRESSED) );
1034                                 break;
1035                         case SDL_WINDOWEVENT:
1036                                 //if (event.window.windowID == window) // how to compare?
1037                                 {
1038                                         switch(event.window.event)
1039                                         {
1040                                         case SDL_WINDOWEVENT_SHOWN:
1041                                                 vid_hidden = false;
1042                                                 break;
1043                                         case  SDL_WINDOWEVENT_HIDDEN:
1044                                                 vid_hidden = true;
1045                                                 break;
1046                                         case SDL_WINDOWEVENT_EXPOSED:
1047                                                 break;
1048                                         case SDL_WINDOWEVENT_MOVED:
1049                                                 break;
1050                                         case SDL_WINDOWEVENT_RESIZED:
1051                                                 if(vid_resizable.integer < 2)
1052                                                 {
1053                                                         vid.width = event.window.data1;
1054                                                         vid.height = event.window.data2;
1055                                                         if (vid_softsurface)
1056                                                         {
1057                                                                 SDL_FreeSurface(vid_softsurface);
1058                                                                 vid_softsurface = SDL_CreateRGBSurface(SDL_SWSURFACE, vid.width, vid.height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
1059                                                                 vid.softpixels = (unsigned int *)vid_softsurface->pixels;
1060                                                                 SDL_SetAlpha(vid_softsurface, 0, 255);
1061                                                                 if (vid.softdepthpixels)
1062                                                                         free(vid.softdepthpixels);
1063                                                                 vid.softdepthpixels = (unsigned int*)calloc(1, vid.width * vid.height * 4);
1064                                                         }
1065 #ifdef SDL_R_RESTART
1066                                                         // better not call R_Modules_Restart from here directly, as this may wreak havoc...
1067                                                         // so, let's better queue it for next frame
1068                                                         if(!sdl_needs_restart)
1069                                                         {
1070                                                                 Cbuf_AddText("\nr_restart\n");
1071                                                                 sdl_needs_restart = true;
1072                                                         }
1073 #endif
1074                                                 }
1075                                                 break;
1076                                         case SDL_WINDOWEVENT_MINIMIZED:
1077                                                 break;
1078                                         case SDL_WINDOWEVENT_MAXIMIZED:
1079                                                 break;
1080                                         case SDL_WINDOWEVENT_RESTORED:
1081                                                 break;
1082                                         case SDL_WINDOWEVENT_ENTER:
1083                                                 break;
1084                                         case SDL_WINDOWEVENT_LEAVE:
1085                                                 break;
1086                                         case SDL_WINDOWEVENT_FOCUS_GAINED:
1087                                                 vid_hasfocus = true;
1088                                                 break;
1089                                         case SDL_WINDOWEVENT_FOCUS_LOST:
1090                                                 vid_hasfocus = false;
1091                                                 break;
1092                                         case SDL_WINDOWEVENT_CLOSE:
1093                                                 Sys_Quit(0);
1094                                                 break;
1095                                         }
1096                                 }
1097                                 break;
1098                         case SDL_TEXTEDITING:
1099                                 // FIXME!  this is where composition gets supported
1100                                 break;
1101                         case SDL_TEXTINPUT:
1102                                 // we have some characters to parse
1103                                 missingunicodehack = false;
1104                                 {
1105                                         unicode = 0;
1106                                         for (i = 0;event.text.text[i];)
1107                                         {
1108                                                 unicode = event.text.text[i++];
1109                                                 if (unicode & 0x80)
1110                                                 {
1111                                                         // UTF-8 character
1112                                                         // strip high bits (we could count these to validate character length but we don't)
1113                                                         for (j = 0x80;unicode & j;j >>= 1)
1114                                                                 unicode ^= j;
1115                                                         for (;(event.text.text[i] & 0xC0) == 0x80;i++)
1116                                                                 unicode = (unicode << 6) | (event.text.text[i] & 0x3F);
1117                                                         // low characters are invalid and could be bad, so replace them
1118                                                         if (unicode < 0x80)
1119                                                                 unicode = '?'; // we could use 0xFFFD instead, the unicode substitute character
1120                                                 }
1121                                                 //Con_DPrintf("SDL_TEXTINPUT: K_TEXT %i \n", unicode);
1122                                                 Key_Event(K_TEXT, unicode, true);
1123                                                 Key_Event(K_TEXT, unicode, false);
1124                                         }
1125                                 }
1126                                 break;
1127                         case SDL_MOUSEMOTION:
1128                                 break;
1129                         case SDL_FINGERDOWN:
1130                                 Con_DPrintf("SDL_FINGERDOWN for finger %i\n", (int)event.tfinger.fingerId);
1131                                 for (i = 0;i < MAXFINGERS-1;i++)
1132                                 {
1133                                         if (!multitouch[i][0])
1134                                         {
1135                                                 multitouch[i][0] = event.tfinger.fingerId;
1136                                                 multitouch[i][1] = event.tfinger.x;
1137                                                 multitouch[i][2] = event.tfinger.y;
1138                                                 // TODO: use event.tfinger.pressure?
1139                                                 break;
1140                                         }
1141                                 }
1142                                 if (i == MAXFINGERS-1)
1143                                         Con_DPrintf("Too many fingers at once!\n");
1144                                 break;
1145                         case SDL_FINGERUP:
1146                                 Con_DPrintf("SDL_FINGERUP for finger %i\n", (int)event.tfinger.fingerId);
1147                                 for (i = 0;i < MAXFINGERS-1;i++)
1148                                 {
1149                                         if (multitouch[i][0] == event.tfinger.fingerId)
1150                                         {
1151                                                 multitouch[i][0] = 0;
1152                                                 break;
1153                                         }
1154                                 }
1155                                 if (i == MAXFINGERS-1)
1156                                         Con_DPrintf("No SDL_FINGERDOWN event matches this SDL_FINGERMOTION event\n");
1157                                 break;
1158                         case SDL_FINGERMOTION:
1159                                 Con_DPrintf("SDL_FINGERMOTION for finger %i\n", (int)event.tfinger.fingerId);
1160                                 for (i = 0;i < MAXFINGERS-1;i++)
1161                                 {
1162                                         if (multitouch[i][0] == event.tfinger.fingerId)
1163                                         {
1164                                                 multitouch[i][1] = event.tfinger.x;
1165                                                 multitouch[i][2] = event.tfinger.y;
1166                                                 break;
1167                                         }
1168                                 }
1169                                 if (i == MAXFINGERS-1)
1170                                         Con_DPrintf("No SDL_FINGERDOWN event matches this SDL_FINGERMOTION event\n");
1171                                 break;
1172                         case SDL_TOUCHBUTTONDOWN:
1173                                 // not sure what to do with this...
1174                                 break;
1175                         case SDL_TOUCHBUTTONUP:
1176                                 // not sure what to do with this...
1177                                 break;
1178                         case SDL_JOYAXISMOTION:
1179                                 // we poll the joystick instead
1180                                 break;
1181                         case SDL_JOYBALLMOTION:
1182                                 // we poll the joystick instead
1183                                 break;
1184                         case SDL_JOYHATMOTION:
1185                                 // we poll the joystick instead
1186                                 break;
1187                         default:
1188                                 Con_DPrintf("Received unrecognized SDL_Event type 0x%x\n", event.type);
1189                                 break;
1190                 }
1191
1192         // enable/disable sound on focus gain/loss
1193         if ((!vid_hidden && vid_activewindow) || !snd_mutewhenidle.integer)
1194         {
1195                 if (!sound_active)
1196                 {
1197                         S_UnblockSound ();
1198                         sound_active = true;
1199                 }
1200         }
1201         else
1202         {
1203                 if (sound_active)
1204                 {
1205                         S_BlockSound ();
1206                         sound_active = false;
1207                 }
1208         }
1209 }
1210 #endif
1211
1212 /////////////////
1213 // Video system
1214 ////
1215
1216 #ifdef __IPHONEOS__
1217 //#include <SDL_opengles.h>
1218 #include <OpenGLES/ES2/gl.h>
1219
1220 GLboolean wrapglIsBuffer(GLuint buffer) {return glIsBuffer(buffer);}
1221 GLboolean wrapglIsEnabled(GLenum cap) {return glIsEnabled(cap);}
1222 GLboolean wrapglIsFramebuffer(GLuint framebuffer) {return glIsFramebuffer(framebuffer);}
1223 //GLboolean wrapglIsQuery(GLuint qid) {return glIsQuery(qid);}
1224 GLboolean wrapglIsRenderbuffer(GLuint renderbuffer) {return glIsRenderbuffer(renderbuffer);}
1225 //GLboolean wrapglUnmapBuffer(GLenum target) {return glUnmapBuffer(target);}
1226 GLenum wrapglCheckFramebufferStatus(GLenum target) {return glCheckFramebufferStatus(target);}
1227 GLenum wrapglGetError(void) {return glGetError();}
1228 GLuint wrapglCreateProgram(void) {return glCreateProgram();}
1229 GLuint wrapglCreateShader(GLenum shaderType) {return glCreateShader(shaderType);}
1230 //GLuint wrapglGetHandle(GLenum pname) {return glGetHandle(pname);}
1231 GLint wrapglGetAttribLocation(GLuint programObj, const GLchar *name) {return glGetAttribLocation(programObj, name);}
1232 GLint wrapglGetUniformLocation(GLuint programObj, const GLchar *name) {return glGetUniformLocation(programObj, name);}
1233 //GLvoid* wrapglMapBuffer(GLenum target, GLenum access) {return glMapBuffer(target, access);}
1234 const GLubyte* wrapglGetString(GLenum name) {return glGetString(name);}
1235 void wrapglActiveStencilFace(GLenum e) {Con_Printf("glActiveStencilFace(e)\n");}
1236 void wrapglActiveTexture(GLenum e) {glActiveTexture(e);}
1237 void wrapglAlphaFunc(GLenum func, GLclampf ref) {Con_Printf("glAlphaFunc(func, ref)\n");}
1238 void wrapglArrayElement(GLint i) {Con_Printf("glArrayElement(i)\n");}
1239 void wrapglAttachShader(GLuint containerObj, GLuint obj) {glAttachShader(containerObj, obj);}
1240 void wrapglBegin(GLenum mode) {Con_Printf("glBegin(mode)\n");}
1241 //void wrapglBeginQuery(GLenum target, GLuint qid) {glBeginQuery(target, qid);}
1242 void wrapglBindAttribLocation(GLuint programObj, GLuint index, const GLchar *name) {glBindAttribLocation(programObj, index, name);}
1243 void wrapglBindFragDataLocation(GLuint programObj, GLuint index, const GLchar *name) {glBindFragDataLocation(programObj, index, name);}
1244 void wrapglBindBuffer(GLenum target, GLuint buffer) {glBindBuffer(target, buffer);}
1245 void wrapglBindFramebuffer(GLenum target, GLuint framebuffer) {glBindFramebuffer(target, framebuffer);}
1246 void wrapglBindRenderbuffer(GLenum target, GLuint renderbuffer) {glBindRenderbuffer(target, renderbuffer);}
1247 void wrapglBindTexture(GLenum target, GLuint texture) {glBindTexture(target, texture);}
1248 void wrapglBlendEquation(GLenum e) {glBlendEquation(e);}
1249 void wrapglBlendFunc(GLenum sfactor, GLenum dfactor) {glBlendFunc(sfactor, dfactor);}
1250 void wrapglBufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) {glBufferData(target, size, data, usage);}
1251 void wrapglBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) {glBufferSubData(target, offset, size, data);}
1252 void wrapglClear(GLbitfield mask) {glClear(mask);}
1253 void wrapglClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {glClearColor(red, green, blue, alpha);}
1254 void wrapglClearDepth(GLclampd depth) {glClearDepthf((float)depth);}
1255 void wrapglClearStencil(GLint s) {glClearStencil(s);}
1256 void wrapglClientActiveTexture(GLenum target) {Con_Printf("glClientActiveTexture(target)\n");}
1257 void wrapglColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {Con_Printf("glColor4f(red, green, blue, alpha)\n");}
1258 void wrapglColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) {Con_Printf("glColor4ub(red, green, blue, alpha)\n");}
1259 void wrapglColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {glColorMask(red, green, blue, alpha);}
1260 void wrapglColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) {Con_Printf("glColorPointer(size, type, stride, ptr)\n");}
1261 void wrapglCompileShader(GLuint shaderObj) {glCompileShader(shaderObj);}
1262 void wrapglCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border,  GLsizei imageSize, const void *data) {glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);}
1263 void wrapglCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data) {Con_Printf("glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data)\n");}
1264 void wrapglCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) {glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);}
1265 void wrapglCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data) {Con_Printf("glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data)\n");}
1266 void wrapglCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);}
1267 void wrapglCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);}
1268 void wrapglCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {Con_Printf("glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height)\n");}
1269 void wrapglCullFace(GLenum mode) {glCullFace(mode);}
1270 void wrapglDeleteBuffers(GLsizei n, const GLuint *buffers) {glDeleteBuffers(n, buffers);}
1271 void wrapglDeleteFramebuffers(GLsizei n, const GLuint *framebuffers) {glDeleteFramebuffers(n, framebuffers);}
1272 void wrapglDeleteShader(GLuint obj) {glDeleteShader(obj);}
1273 void wrapglDeleteProgram(GLuint obj) {glDeleteProgram(obj);}
1274 //void wrapglDeleteQueries(GLsizei n, const GLuint *ids) {glDeleteQueries(n, ids);}
1275 void wrapglDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) {glDeleteRenderbuffers(n, renderbuffers);}
1276 void wrapglDeleteTextures(GLsizei n, const GLuint *textures) {glDeleteTextures(n, textures);}
1277 void wrapglDepthFunc(GLenum func) {glDepthFunc(func);}
1278 void wrapglDepthMask(GLboolean flag) {glDepthMask(flag);}
1279 void wrapglDepthRange(GLclampd near_val, GLclampd far_val) {glDepthRangef((float)near_val, (float)far_val);}
1280 void wrapglDetachShader(GLuint containerObj, GLuint attachedObj) {glDetachShader(containerObj, attachedObj);}
1281 void wrapglDisable(GLenum cap) {glDisable(cap);}
1282 void wrapglDisableClientState(GLenum cap) {Con_Printf("glDisableClientState(cap)\n");}
1283 void wrapglDisableVertexAttribArray(GLuint index) {glDisableVertexAttribArray(index);}
1284 void wrapglDrawArrays(GLenum mode, GLint first, GLsizei count) {glDrawArrays(mode, first, count);}
1285 void wrapglDrawBuffer(GLenum mode) {Con_Printf("glDrawBuffer(mode)\n");}
1286 void wrapglDrawBuffers(GLsizei n, const GLenum *bufs) {Con_Printf("glDrawBuffers(n, bufs)\n");}
1287 void wrapglDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {glDrawElements(mode, count, type, indices);}
1288 //void wrapglDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) {glDrawRangeElements(mode, start, end, count, type, indices);}
1289 //void wrapglDrawRangeElementsEXT(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) {glDrawRangeElements(mode, start, end, count, type, indices);}
1290 void wrapglEnable(GLenum cap) {glEnable(cap);}
1291 void wrapglEnableClientState(GLenum cap) {Con_Printf("glEnableClientState(cap)\n");}
1292 void wrapglEnableVertexAttribArray(GLuint index) {glEnableVertexAttribArray(index);}
1293 void wrapglEnd(void) {Con_Printf("glEnd()\n");}
1294 //void wrapglEndQuery(GLenum target) {glEndQuery(target);}
1295 void wrapglFinish(void) {glFinish();}
1296 void wrapglFlush(void) {glFlush();}
1297 void wrapglFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);}
1298 void wrapglFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {glFramebufferTexture2D(target, attachment, textarget, texture, level);}
1299 void wrapglFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) {Con_Printf("glFramebufferTexture3D()\n");}
1300 void wrapglGenBuffers(GLsizei n, GLuint *buffers) {glGenBuffers(n, buffers);}
1301 void wrapglGenFramebuffers(GLsizei n, GLuint *framebuffers) {glGenFramebuffers(n, framebuffers);}
1302 //void wrapglGenQueries(GLsizei n, GLuint *ids) {glGenQueries(n, ids);}
1303 void wrapglGenRenderbuffers(GLsizei n, GLuint *renderbuffers) {glGenRenderbuffers(n, renderbuffers);}
1304 void wrapglGenTextures(GLsizei n, GLuint *textures) {glGenTextures(n, textures);}
1305 void wrapglGenerateMipmap(GLenum target) {glGenerateMipmap(target);}
1306 void wrapglGetActiveAttrib(GLuint programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLchar *name) {glGetActiveAttrib(programObj, index, maxLength, length, size, type, name);}
1307 void wrapglGetActiveUniform(GLuint programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLchar *name) {glGetActiveUniform(programObj, index, maxLength, length, size, type, name);}
1308 void wrapglGetAttachedShaders(GLuint containerObj, GLsizei maxCount, GLsizei *count, GLuint *obj) {glGetAttachedShaders(containerObj, maxCount, count, obj);}
1309 void wrapglGetBooleanv(GLenum pname, GLboolean *params) {glGetBooleanv(pname, params);}
1310 void wrapglGetCompressedTexImage(GLenum target, GLint lod, void *img) {Con_Printf("glGetCompressedTexImage(target, lod, img)\n");}
1311 void wrapglGetDoublev(GLenum pname, GLdouble *params) {Con_Printf("glGetDoublev(pname, params)\n");}
1312 void wrapglGetFloatv(GLenum pname, GLfloat *params) {glGetFloatv(pname, params);}
1313 void wrapglGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params) {glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);}
1314 void wrapglGetShaderInfoLog(GLuint obj, GLsizei maxLength, GLsizei *length, GLchar *infoLog) {glGetShaderInfoLog(obj, maxLength, length, infoLog);}
1315 void wrapglGetProgramInfoLog(GLuint obj, GLsizei maxLength, GLsizei *length, GLchar *infoLog) {glGetProgramInfoLog(obj, maxLength, length, infoLog);}
1316 void wrapglGetIntegerv(GLenum pname, GLint *params) {glGetIntegerv(pname, params);}
1317 void wrapglGetShaderiv(GLuint obj, GLenum pname, GLint *params) {glGetShaderiv(obj, pname, params);}
1318 void wrapglGetProgramiv(GLuint obj, GLenum pname, GLint *params) {glGetProgramiv(obj, pname, params);}
1319 //void wrapglGetQueryObjectiv(GLuint qid, GLenum pname, GLint *params) {glGetQueryObjectiv(qid, pname, params);}
1320 //void wrapglGetQueryObjectuiv(GLuint qid, GLenum pname, GLuint *params) {glGetQueryObjectuiv(qid, pname, params);}
1321 //void wrapglGetQueryiv(GLenum target, GLenum pname, GLint *params) {glGetQueryiv(target, pname, params);}
1322 void wrapglGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params) {glGetRenderbufferParameteriv(target, pname, params);}
1323 void wrapglGetShaderSource(GLuint obj, GLsizei maxLength, GLsizei *length, GLchar *source) {glGetShaderSource(obj, maxLength, length, source);}
1324 void wrapglGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels) {Con_Printf("glGetTexImage(target, level, format, type, pixels)\n");}
1325 void wrapglGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params) {Con_Printf("glGetTexLevelParameterfv(target, level, pname, params)\n");}
1326 void wrapglGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) {Con_Printf("glGetTexLevelParameteriv(target, level, pname, params)\n");}
1327 void wrapglGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) {glGetTexParameterfv(target, pname, params);}
1328 void wrapglGetTexParameteriv(GLenum target, GLenum pname, GLint *params) {glGetTexParameteriv(target, pname, params);}
1329 void wrapglGetUniformfv(GLuint programObj, GLint location, GLfloat *params) {glGetUniformfv(programObj, location, params);}
1330 void wrapglGetUniformiv(GLuint programObj, GLint location, GLint *params) {glGetUniformiv(programObj, location, params);}
1331 void wrapglHint(GLenum target, GLenum mode) {glHint(target, mode);}
1332 void wrapglLineWidth(GLfloat width) {glLineWidth(width);}
1333 void wrapglLinkProgram(GLuint programObj) {glLinkProgram(programObj);}
1334 void wrapglLoadIdentity(void) {Con_Printf("glLoadIdentity()\n");}
1335 void wrapglLoadMatrixf(const GLfloat *m) {Con_Printf("glLoadMatrixf(m)\n");}
1336 void wrapglMatrixMode(GLenum mode) {Con_Printf("glMatrixMode(mode)\n");}
1337 void wrapglMultiTexCoord1f(GLenum target, GLfloat s) {Con_Printf("glMultiTexCoord1f(target, s)\n");}
1338 void wrapglMultiTexCoord2f(GLenum target, GLfloat s, GLfloat t) {Con_Printf("glMultiTexCoord2f(target, s, t)\n");}
1339 void wrapglMultiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r) {Con_Printf("glMultiTexCoord3f(target, s, t, r)\n");}
1340 void wrapglMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {Con_Printf("glMultiTexCoord4f(target, s, t, r, q)\n");}
1341 void wrapglNormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr) {Con_Printf("glNormalPointer(type, stride, ptr)\n");}
1342 void wrapglPixelStorei(GLenum pname, GLint param) {glPixelStorei(pname, param);}
1343 void wrapglPointSize(GLfloat size) {Con_Printf("glPointSize(size)\n");}
1344 void wrapglPolygonMode(GLenum face, GLenum mode) {Con_Printf("glPolygonMode(face, mode)\n");}
1345 void wrapglPolygonOffset(GLfloat factor, GLfloat units) {glPolygonOffset(factor, units);}
1346 void wrapglPolygonStipple(const GLubyte *mask) {Con_Printf("glPolygonStipple(mask)\n");}
1347 void wrapglReadBuffer(GLenum mode) {Con_Printf("glReadBuffer(mode)\n");}
1348 void wrapglReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {glReadPixels(x, y, width, height, format, type, pixels);}
1349 void wrapglRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {glRenderbufferStorage(target, internalformat, width, height);}
1350 void wrapglScissor(GLint x, GLint y, GLsizei width, GLsizei height) {glScissor(x, y, width, height);}
1351 void wrapglShaderSource(GLuint shaderObj, GLsizei count, const GLchar **string, const GLint *length) {glShaderSource(shaderObj, count, string, length);}
1352 void wrapglStencilFunc(GLenum func, GLint ref, GLuint mask) {glStencilFunc(func, ref, mask);}
1353 void wrapglStencilFuncSeparate(GLenum func1, GLenum func2, GLint ref, GLuint mask) {Con_Printf("glStencilFuncSeparate(func1, func2, ref, mask)\n");}
1354 void wrapglStencilMask(GLuint mask) {glStencilMask(mask);}
1355 void wrapglStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {glStencilOp(fail, zfail, zpass);}
1356 void wrapglStencilOpSeparate(GLenum e1, GLenum e2, GLenum e3, GLenum e4) {Con_Printf("glStencilOpSeparate(e1, e2, e3, e4)\n");}
1357 void wrapglTexCoord1f(GLfloat s) {Con_Printf("glTexCoord1f(s)\n");}
1358 void wrapglTexCoord2f(GLfloat s, GLfloat t) {Con_Printf("glTexCoord2f(s, t)\n");}
1359 void wrapglTexCoord3f(GLfloat s, GLfloat t, GLfloat r) {Con_Printf("glTexCoord3f(s, t, r)\n");}
1360 void wrapglTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) {Con_Printf("glTexCoord4f(s, t, r, q)\n");}
1361 void wrapglTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) {Con_Printf("glTexCoordPointer(size, type, stride, ptr)\n");}
1362 void wrapglTexEnvf(GLenum target, GLenum pname, GLfloat param) {Con_Printf("glTexEnvf(target, pname, param)\n");}
1363 void wrapglTexEnvfv(GLenum target, GLenum pname, const GLfloat *params) {Con_Printf("glTexEnvfv(target, pname, params)\n");}
1364 void wrapglTexEnvi(GLenum target, GLenum pname, GLint param) {Con_Printf("glTexEnvi(target, pname, param)\n");}
1365 void wrapglTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);}
1366 void wrapglTexImage3D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {Con_Printf("glTexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels)\n");}
1367 void wrapglTexParameterf(GLenum target, GLenum pname, GLfloat param) {glTexParameterf(target, pname, param);}
1368 void wrapglTexParameterfv(GLenum target, GLenum pname, GLfloat *params) {glTexParameterfv(target, pname, params);}
1369 void wrapglTexParameteri(GLenum target, GLenum pname, GLint param) {glTexParameteri(target, pname, param);}
1370 void wrapglTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) {glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);}
1371 void wrapglTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) {Con_Printf("glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels)\n");}
1372 void wrapglUniform1f(GLint location, GLfloat v0) {glUniform1f(location, v0);}
1373 void wrapglUniform1fv(GLint location, GLsizei count, const GLfloat *value) {glUniform1fv(location, count, value);}
1374 void wrapglUniform1i(GLint location, GLint v0) {glUniform1i(location, v0);}
1375 void wrapglUniform1iv(GLint location, GLsizei count, const GLint *value) {glUniform1iv(location, count, value);}
1376 void wrapglUniform2f(GLint location, GLfloat v0, GLfloat v1) {glUniform2f(location, v0, v1);}
1377 void wrapglUniform2fv(GLint location, GLsizei count, const GLfloat *value) {glUniform2fv(location, count, value);}
1378 void wrapglUniform2i(GLint location, GLint v0, GLint v1) {glUniform2i(location, v0, v1);}
1379 void wrapglUniform2iv(GLint location, GLsizei count, const GLint *value) {glUniform2iv(location, count, value);}
1380 void wrapglUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {glUniform3f(location, v0, v1, v2);}
1381 void wrapglUniform3fv(GLint location, GLsizei count, const GLfloat *value) {glUniform3fv(location, count, value);}
1382 void wrapglUniform3i(GLint location, GLint v0, GLint v1, GLint v2) {glUniform3i(location, v0, v1, v2);}
1383 void wrapglUniform3iv(GLint location, GLsizei count, const GLint *value) {glUniform3iv(location, count, value);}
1384 void wrapglUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {glUniform4f(location, v0, v1, v2, v3);}
1385 void wrapglUniform4fv(GLint location, GLsizei count, const GLfloat *value) {glUniform4fv(location, count, value);}
1386 void wrapglUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {glUniform4i(location, v0, v1, v2, v3);}
1387 void wrapglUniform4iv(GLint location, GLsizei count, const GLint *value) {glUniform4iv(location, count, value);}
1388 void wrapglUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {glUniformMatrix2fv(location, count, transpose, value);}
1389 void wrapglUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {glUniformMatrix3fv(location, count, transpose, value);}
1390 void wrapglUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {glUniformMatrix4fv(location, count, transpose, value);}
1391 void wrapglUseProgram(GLuint programObj) {glUseProgram(programObj);}
1392 void wrapglValidateProgram(GLuint programObj) {glValidateProgram(programObj);}
1393 void wrapglVertex2f(GLfloat x, GLfloat y) {Con_Printf("glVertex2f(x, y)\n");}
1394 void wrapglVertex3f(GLfloat x, GLfloat y, GLfloat z) {Con_Printf("glVertex3f(x, y, z)\n");}
1395 void wrapglVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {Con_Printf("glVertex4f(x, y, z, w)\n");}
1396 void wrapglVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) {glVertexAttribPointer(index, size, type, normalized, stride, pointer);}
1397 void wrapglVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) {Con_Printf("glVertexPointer(size, type, stride, ptr)\n");}
1398 void wrapglViewport(GLint x, GLint y, GLsizei width, GLsizei height) {glViewport(x, y, width, height);}
1399 void wrapglVertexAttrib1f(GLuint index, GLfloat v0) {glVertexAttrib1f(index, v0);}
1400 //void wrapglVertexAttrib1s(GLuint index, GLshort v0) {glVertexAttrib1s(index, v0);}
1401 //void wrapglVertexAttrib1d(GLuint index, GLdouble v0) {glVertexAttrib1d(index, v0);}
1402 void wrapglVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {glVertexAttrib2f(index, v0, v1);}
1403 //void wrapglVertexAttrib2s(GLuint index, GLshort v0, GLshort v1) {glVertexAttrib2s(index, v0, v1);}
1404 //void wrapglVertexAttrib2d(GLuint index, GLdouble v0, GLdouble v1) {glVertexAttrib2d(index, v0, v1);}
1405 void wrapglVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {glVertexAttrib3f(index, v0, v1, v2);}
1406 //void wrapglVertexAttrib3s(GLuint index, GLshort v0, GLshort v1, GLshort v2) {glVertexAttrib3s(index, v0, v1, v2);}
1407 //void wrapglVertexAttrib3d(GLuint index, GLdouble v0, GLdouble v1, GLdouble v2) {glVertexAttrib3d(index, v0, v1, v2);}
1408 void wrapglVertexAttrib4f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {glVertexAttrib4f(index, v0, v1, v2, v3);}
1409 //void wrapglVertexAttrib4s(GLuint index, GLshort v0, GLshort v1, GLshort v2, GLshort v3) {glVertexAttrib4s(index, v0, v1, v2, v3);}
1410 //void wrapglVertexAttrib4d(GLuint index, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3) {glVertexAttrib4d(index, v0, v1, v2, v3);}
1411 //void wrapglVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) {glVertexAttrib4Nub(index, x, y, z, w);}
1412 void wrapglVertexAttrib1fv(GLuint index, const GLfloat *v) {glVertexAttrib1fv(index, v);}
1413 //void wrapglVertexAttrib1sv(GLuint index, const GLshort *v) {glVertexAttrib1sv(index, v);}
1414 //void wrapglVertexAttrib1dv(GLuint index, const GLdouble *v) {glVertexAttrib1dv(index, v);}
1415 void wrapglVertexAttrib2fv(GLuint index, const GLfloat *v) {glVertexAttrib2fv(index, v);}
1416 //void wrapglVertexAttrib2sv(GLuint index, const GLshort *v) {glVertexAttrib2sv(index, v);}
1417 //void wrapglVertexAttrib2dv(GLuint index, const GLdouble *v) {glVertexAttrib2dv(index, v);}
1418 void wrapglVertexAttrib3fv(GLuint index, const GLfloat *v) {glVertexAttrib3fv(index, v);}
1419 //void wrapglVertexAttrib3sv(GLuint index, const GLshort *v) {glVertexAttrib3sv(index, v);}
1420 //void wrapglVertexAttrib3dv(GLuint index, const GLdouble *v) {glVertexAttrib3dv(index, v);}
1421 void wrapglVertexAttrib4fv(GLuint index, const GLfloat *v) {glVertexAttrib4fv(index, v);}
1422 //void wrapglVertexAttrib4sv(GLuint index, const GLshort *v) {glVertexAttrib4sv(index, v);}
1423 //void wrapglVertexAttrib4dv(GLuint index, const GLdouble *v) {glVertexAttrib4dv(index, v);}
1424 //void wrapglVertexAttrib4iv(GLuint index, const GLint *v) {glVertexAttrib4iv(index, v);}
1425 //void wrapglVertexAttrib4bv(GLuint index, const GLbyte *v) {glVertexAttrib4bv(index, v);}
1426 //void wrapglVertexAttrib4ubv(GLuint index, const GLubyte *v) {glVertexAttrib4ubv(index, v);}
1427 //void wrapglVertexAttrib4usv(GLuint index, const GLushort *v) {glVertexAttrib4usv(index, GLushort v);}
1428 //void wrapglVertexAttrib4uiv(GLuint index, const GLuint *v) {glVertexAttrib4uiv(index, v);}
1429 //void wrapglVertexAttrib4Nbv(GLuint index, const GLbyte *v) {glVertexAttrib4Nbv(index, v);}
1430 //void wrapglVertexAttrib4Nsv(GLuint index, const GLshort *v) {glVertexAttrib4Nsv(index, v);}
1431 //void wrapglVertexAttrib4Niv(GLuint index, const GLint *v) {glVertexAttrib4Niv(index, v);}
1432 //void wrapglVertexAttrib4Nubv(GLuint index, const GLubyte *v) {glVertexAttrib4Nubv(index, v);}
1433 //void wrapglVertexAttrib4Nusv(GLuint index, const GLushort *v) {glVertexAttrib4Nusv(index, GLushort v);}
1434 //void wrapglVertexAttrib4Nuiv(GLuint index, const GLuint *v) {glVertexAttrib4Nuiv(index, v);}
1435 //void wrapglGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) {glGetVertexAttribdv(index, pname, params);}
1436 void wrapglGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params) {glGetVertexAttribfv(index, pname, params);}
1437 void wrapglGetVertexAttribiv(GLuint index, GLenum pname, GLint *params) {glGetVertexAttribiv(index, pname, params);}
1438 void wrapglGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer) {glGetVertexAttribPointerv(index, pname, pointer);}
1439
1440 void GLES_Init(void)
1441 {
1442         qglIsBufferARB = wrapglIsBuffer;
1443         qglIsEnabled = wrapglIsEnabled;
1444         qglIsFramebufferEXT = wrapglIsFramebuffer;
1445 //      qglIsQueryARB = wrapglIsQuery;
1446         qglIsRenderbufferEXT = wrapglIsRenderbuffer;
1447 //      qglUnmapBufferARB = wrapglUnmapBuffer;
1448         qglCheckFramebufferStatusEXT = wrapglCheckFramebufferStatus;
1449         qglGetError = wrapglGetError;
1450         qglCreateProgram = wrapglCreateProgram;
1451         qglCreateShader = wrapglCreateShader;
1452 //      qglGetHandleARB = wrapglGetHandle;
1453         qglGetAttribLocation = wrapglGetAttribLocation;
1454         qglGetUniformLocation = wrapglGetUniformLocation;
1455 //      qglMapBufferARB = wrapglMapBuffer;
1456         qglGetString = wrapglGetString;
1457 //      qglActiveStencilFaceEXT = wrapglActiveStencilFace;
1458         qglActiveTexture = wrapglActiveTexture;
1459         qglAlphaFunc = wrapglAlphaFunc;
1460         qglArrayElement = wrapglArrayElement;
1461         qglAttachShader = wrapglAttachShader;
1462         qglBegin = wrapglBegin;
1463 //      qglBeginQueryARB = wrapglBeginQuery;
1464         qglBindAttribLocation = wrapglBindAttribLocation;
1465         qglBindFragDataLocation = wrapglBindFragDataLocation;
1466         qglBindBufferARB = wrapglBindBuffer;
1467         qglBindFramebufferEXT = wrapglBindFramebuffer;
1468         qglBindRenderbufferEXT = wrapglBindRenderbuffer;
1469         qglBindTexture = wrapglBindTexture;
1470         qglBlendEquationEXT = wrapglBlendEquation;
1471         qglBlendFunc = wrapglBlendFunc;
1472         qglBufferDataARB = wrapglBufferData;
1473         qglBufferSubDataARB = wrapglBufferSubData;
1474         qglClear = wrapglClear;
1475         qglClearColor = wrapglClearColor;
1476         qglClearDepth = wrapglClearDepth;
1477         qglClearStencil = wrapglClearStencil;
1478         qglClientActiveTexture = wrapglClientActiveTexture;
1479         qglColor4f = wrapglColor4f;
1480         qglColor4ub = wrapglColor4ub;
1481         qglColorMask = wrapglColorMask;
1482         qglColorPointer = wrapglColorPointer;
1483         qglCompileShader = wrapglCompileShader;
1484         qglCompressedTexImage2DARB = wrapglCompressedTexImage2D;
1485         qglCompressedTexImage3DARB = wrapglCompressedTexImage3D;
1486         qglCompressedTexSubImage2DARB = wrapglCompressedTexSubImage2D;
1487         qglCompressedTexSubImage3DARB = wrapglCompressedTexSubImage3D;
1488         qglCopyTexImage2D = wrapglCopyTexImage2D;
1489         qglCopyTexSubImage2D = wrapglCopyTexSubImage2D;
1490         qglCopyTexSubImage3D = wrapglCopyTexSubImage3D;
1491         qglCullFace = wrapglCullFace;
1492         qglDeleteBuffersARB = wrapglDeleteBuffers;
1493         qglDeleteFramebuffersEXT = wrapglDeleteFramebuffers;
1494         qglDeleteProgram = wrapglDeleteProgram;
1495         qglDeleteShader = wrapglDeleteShader;
1496 //      qglDeleteQueriesARB = wrapglDeleteQueries;
1497         qglDeleteRenderbuffersEXT = wrapglDeleteRenderbuffers;
1498         qglDeleteTextures = wrapglDeleteTextures;
1499         qglDepthFunc = wrapglDepthFunc;
1500         qglDepthMask = wrapglDepthMask;
1501         qglDepthRange = wrapglDepthRange;
1502         qglDetachShader = wrapglDetachShader;
1503         qglDisable = wrapglDisable;
1504         qglDisableClientState = wrapglDisableClientState;
1505         qglDisableVertexAttribArray = wrapglDisableVertexAttribArray;
1506         qglDrawArrays = wrapglDrawArrays;
1507 //      qglDrawBuffer = wrapglDrawBuffer;
1508 //      qglDrawBuffersARB = wrapglDrawBuffers;
1509         qglDrawElements = wrapglDrawElements;
1510 //      qglDrawRangeElements = wrapglDrawRangeElements;
1511         qglEnable = wrapglEnable;
1512         qglEnableClientState = wrapglEnableClientState;
1513         qglEnableVertexAttribArray = wrapglEnableVertexAttribArray;
1514         qglEnd = wrapglEnd;
1515 //      qglEndQueryARB = wrapglEndQuery;
1516         qglFinish = wrapglFinish;
1517         qglFlush = wrapglFlush;
1518         qglFramebufferRenderbufferEXT = wrapglFramebufferRenderbuffer;
1519         qglFramebufferTexture2DEXT = wrapglFramebufferTexture2D;
1520         qglFramebufferTexture3DEXT = wrapglFramebufferTexture3D;
1521         qglGenBuffersARB = wrapglGenBuffers;
1522         qglGenFramebuffersEXT = wrapglGenFramebuffers;
1523 //      qglGenQueriesARB = wrapglGenQueries;
1524         qglGenRenderbuffersEXT = wrapglGenRenderbuffers;
1525         qglGenTextures = wrapglGenTextures;
1526         qglGenerateMipmapEXT = wrapglGenerateMipmap;
1527         qglGetActiveAttrib = wrapglGetActiveAttrib;
1528         qglGetActiveUniform = wrapglGetActiveUniform;
1529         qglGetAttachedShaders = wrapglGetAttachedShaders;
1530         qglGetBooleanv = wrapglGetBooleanv;
1531 //      qglGetCompressedTexImageARB = wrapglGetCompressedTexImage;
1532         qglGetDoublev = wrapglGetDoublev;
1533         qglGetFloatv = wrapglGetFloatv;
1534         qglGetFramebufferAttachmentParameterivEXT = wrapglGetFramebufferAttachmentParameteriv;
1535         qglGetProgramInfoLog = wrapglGetProgramInfoLog;
1536         qglGetShaderInfoLog = wrapglGetShaderInfoLog;
1537         qglGetIntegerv = wrapglGetIntegerv;
1538         qglGetShaderiv = wrapglGetShaderiv;
1539         qglGetProgramiv = wrapglGetProgramiv;
1540 //      qglGetQueryObjectivARB = wrapglGetQueryObjectiv;
1541 //      qglGetQueryObjectuivARB = wrapglGetQueryObjectuiv;
1542 //      qglGetQueryivARB = wrapglGetQueryiv;
1543         qglGetRenderbufferParameterivEXT = wrapglGetRenderbufferParameteriv;
1544         qglGetShaderSource = wrapglGetShaderSource;
1545         qglGetTexImage = wrapglGetTexImage;
1546         qglGetTexLevelParameterfv = wrapglGetTexLevelParameterfv;
1547         qglGetTexLevelParameteriv = wrapglGetTexLevelParameteriv;
1548         qglGetTexParameterfv = wrapglGetTexParameterfv;
1549         qglGetTexParameteriv = wrapglGetTexParameteriv;
1550         qglGetUniformfv = wrapglGetUniformfv;
1551         qglGetUniformiv = wrapglGetUniformiv;
1552         qglHint = wrapglHint;
1553         qglLineWidth = wrapglLineWidth;
1554         qglLinkProgram = wrapglLinkProgram;
1555         qglLoadIdentity = wrapglLoadIdentity;
1556         qglLoadMatrixf = wrapglLoadMatrixf;
1557         qglMatrixMode = wrapglMatrixMode;
1558         qglMultiTexCoord1f = wrapglMultiTexCoord1f;
1559         qglMultiTexCoord2f = wrapglMultiTexCoord2f;
1560         qglMultiTexCoord3f = wrapglMultiTexCoord3f;
1561         qglMultiTexCoord4f = wrapglMultiTexCoord4f;
1562         qglNormalPointer = wrapglNormalPointer;
1563         qglPixelStorei = wrapglPixelStorei;
1564         qglPointSize = wrapglPointSize;
1565         qglPolygonMode = wrapglPolygonMode;
1566         qglPolygonOffset = wrapglPolygonOffset;
1567 //      qglPolygonStipple = wrapglPolygonStipple;
1568         qglReadBuffer = wrapglReadBuffer;
1569         qglReadPixels = wrapglReadPixels;
1570         qglRenderbufferStorageEXT = wrapglRenderbufferStorage;
1571         qglScissor = wrapglScissor;
1572         qglShaderSource = wrapglShaderSource;
1573         qglStencilFunc = wrapglStencilFunc;
1574         qglStencilFuncSeparate = wrapglStencilFuncSeparate;
1575         qglStencilMask = wrapglStencilMask;
1576         qglStencilOp = wrapglStencilOp;
1577         qglStencilOpSeparate = wrapglStencilOpSeparate;
1578         qglTexCoord1f = wrapglTexCoord1f;
1579         qglTexCoord2f = wrapglTexCoord2f;
1580         qglTexCoord3f = wrapglTexCoord3f;
1581         qglTexCoord4f = wrapglTexCoord4f;
1582         qglTexCoordPointer = wrapglTexCoordPointer;
1583         qglTexEnvf = wrapglTexEnvf;
1584         qglTexEnvfv = wrapglTexEnvfv;
1585         qglTexEnvi = wrapglTexEnvi;
1586         qglTexImage2D = wrapglTexImage2D;
1587         qglTexImage3D = wrapglTexImage3D;
1588         qglTexParameterf = wrapglTexParameterf;
1589         qglTexParameterfv = wrapglTexParameterfv;
1590         qglTexParameteri = wrapglTexParameteri;
1591         qglTexSubImage2D = wrapglTexSubImage2D;
1592         qglTexSubImage3D = wrapglTexSubImage3D;
1593         qglUniform1f = wrapglUniform1f;
1594         qglUniform1fv = wrapglUniform1fv;
1595         qglUniform1i = wrapglUniform1i;
1596         qglUniform1iv = wrapglUniform1iv;
1597         qglUniform2f = wrapglUniform2f;
1598         qglUniform2fv = wrapglUniform2fv;
1599         qglUniform2i = wrapglUniform2i;
1600         qglUniform2iv = wrapglUniform2iv;
1601         qglUniform3f = wrapglUniform3f;
1602         qglUniform3fv = wrapglUniform3fv;
1603         qglUniform3i = wrapglUniform3i;
1604         qglUniform3iv = wrapglUniform3iv;
1605         qglUniform4f = wrapglUniform4f;
1606         qglUniform4fv = wrapglUniform4fv;
1607         qglUniform4i = wrapglUniform4i;
1608         qglUniform4iv = wrapglUniform4iv;
1609         qglUniformMatrix2fv = wrapglUniformMatrix2fv;
1610         qglUniformMatrix3fv = wrapglUniformMatrix3fv;
1611         qglUniformMatrix4fv = wrapglUniformMatrix4fv;
1612         qglUseProgram = wrapglUseProgram;
1613         qglValidateProgram = wrapglValidateProgram;
1614         qglVertex2f = wrapglVertex2f;
1615         qglVertex3f = wrapglVertex3f;
1616         qglVertex4f = wrapglVertex4f;
1617         qglVertexAttribPointer = wrapglVertexAttribPointer;
1618         qglVertexPointer = wrapglVertexPointer;
1619         qglViewport = wrapglViewport;
1620         qglVertexAttrib1f = wrapglVertexAttrib1f;
1621 //      qglVertexAttrib1s = wrapglVertexAttrib1s;
1622 //      qglVertexAttrib1d = wrapglVertexAttrib1d;
1623         qglVertexAttrib2f = wrapglVertexAttrib2f;
1624 //      qglVertexAttrib2s = wrapglVertexAttrib2s;
1625 //      qglVertexAttrib2d = wrapglVertexAttrib2d;
1626         qglVertexAttrib3f = wrapglVertexAttrib3f;
1627 //      qglVertexAttrib3s = wrapglVertexAttrib3s;
1628 //      qglVertexAttrib3d = wrapglVertexAttrib3d;
1629         qglVertexAttrib4f = wrapglVertexAttrib4f;
1630 //      qglVertexAttrib4s = wrapglVertexAttrib4s;
1631 //      qglVertexAttrib4d = wrapglVertexAttrib4d;
1632 //      qglVertexAttrib4Nub = wrapglVertexAttrib4Nub;
1633         qglVertexAttrib1fv = wrapglVertexAttrib1fv;
1634 //      qglVertexAttrib1sv = wrapglVertexAttrib1sv;
1635 //      qglVertexAttrib1dv = wrapglVertexAttrib1dv;
1636         qglVertexAttrib2fv = wrapglVertexAttrib2fv;
1637 //      qglVertexAttrib2sv = wrapglVertexAttrib2sv;
1638 //      qglVertexAttrib2dv = wrapglVertexAttrib2dv;
1639         qglVertexAttrib3fv = wrapglVertexAttrib3fv;
1640 //      qglVertexAttrib3sv = wrapglVertexAttrib3sv;
1641 //      qglVertexAttrib3dv = wrapglVertexAttrib3dv;
1642         qglVertexAttrib4fv = wrapglVertexAttrib4fv;
1643 //      qglVertexAttrib4sv = wrapglVertexAttrib4sv;
1644 //      qglVertexAttrib4dv = wrapglVertexAttrib4dv;
1645 //      qglVertexAttrib4iv = wrapglVertexAttrib4iv;
1646 //      qglVertexAttrib4bv = wrapglVertexAttrib4bv;
1647 //      qglVertexAttrib4ubv = wrapglVertexAttrib4ubv;
1648 //      qglVertexAttrib4usv = wrapglVertexAttrib4usv;
1649 //      qglVertexAttrib4uiv = wrapglVertexAttrib4uiv;
1650 //      qglVertexAttrib4Nbv = wrapglVertexAttrib4Nbv;
1651 //      qglVertexAttrib4Nsv = wrapglVertexAttrib4Nsv;
1652 //      qglVertexAttrib4Niv = wrapglVertexAttrib4Niv;
1653 //      qglVertexAttrib4Nubv = wrapglVertexAttrib4Nubv;
1654 //      qglVertexAttrib4Nusv = wrapglVertexAttrib4Nusv;
1655 //      qglVertexAttrib4Nuiv = wrapglVertexAttrib4Nuiv;
1656 //      qglGetVertexAttribdv = wrapglGetVertexAttribdv;
1657         qglGetVertexAttribfv = wrapglGetVertexAttribfv;
1658         qglGetVertexAttribiv = wrapglGetVertexAttribiv;
1659         qglGetVertexAttribPointerv = wrapglGetVertexAttribPointerv;
1660
1661         gl_renderer = (const char *)qglGetString(GL_RENDERER);
1662         gl_vendor = (const char *)qglGetString(GL_VENDOR);
1663         gl_version = (const char *)qglGetString(GL_VERSION);
1664         gl_extensions = (const char *)qglGetString(GL_EXTENSIONS);
1665         
1666         if (!gl_extensions)
1667                 gl_extensions = "";
1668         if (!gl_platformextensions)
1669                 gl_platformextensions = "";
1670         
1671         Con_Printf("GL_VENDOR: %s\n", gl_vendor);
1672         Con_Printf("GL_RENDERER: %s\n", gl_renderer);
1673         Con_Printf("GL_VERSION: %s\n", gl_version);
1674         Con_DPrintf("GL_EXTENSIONS: %s\n", gl_extensions);
1675         Con_DPrintf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions);
1676         
1677         // LordHavoc: report supported extensions
1678         Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions );
1679         
1680         vid.support.gl20shaders = true;
1681         vid.support.amd_texture_texture4 = false;
1682         vid.support.arb_depth_texture = false;
1683         vid.support.arb_draw_buffers = false;
1684         vid.support.arb_multitexture = false;
1685         vid.support.arb_occlusion_query = false;
1686         vid.support.arb_shadow = false;
1687         vid.support.arb_texture_compression = false; // different (vendor-specific) formats than on desktop OpenGL...
1688         vid.support.arb_texture_cube_map = true;
1689         vid.support.arb_texture_env_combine = false;
1690         vid.support.arb_texture_gather = false;
1691         vid.support.arb_texture_non_power_of_two = strstr(gl_extensions, "GL_OES_texture_npot") != NULL;
1692         vid.support.arb_vertex_buffer_object = true;
1693         vid.support.ati_separate_stencil = false;
1694         vid.support.ext_blend_minmax = false;
1695         vid.support.ext_blend_subtract = true;
1696         vid.support.ext_draw_range_elements = true;
1697         vid.support.ext_framebuffer_object = false;//true;
1698         vid.support.ext_stencil_two_side = false;
1699         vid.support.ext_texture_3d = false;//SDL_GL_ExtensionSupported("GL_OES_texture_3D"); // iPhoneOS does not support 3D textures, odd...
1700         vid.support.ext_texture_compression_s3tc = false;
1701         vid.support.ext_texture_edge_clamp = true;
1702         vid.support.ext_texture_filter_anisotropic = false; // probably don't want to use it...
1703
1704         qglGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_2d);
1705         if (vid.support.ext_texture_filter_anisotropic)
1706                 qglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, (GLint*)&vid.max_anisotropy);
1707         if (vid.support.arb_texture_cube_map)
1708                 qglGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, (GLint*)&vid.maxtexturesize_cubemap);
1709         if (vid.support.ext_texture_3d)
1710                 qglGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_3d);
1711         Con_Printf("GL_MAX_CUBE_MAP_TEXTURE_SIZE = %i\n", vid.maxtexturesize_cubemap);
1712         Con_Printf("GL_MAX_3D_TEXTURE_SIZE = %i\n", vid.maxtexturesize_3d);
1713
1714         // verify that cubemap textures are really supported
1715         if (vid.support.arb_texture_cube_map && vid.maxtexturesize_cubemap < 256)
1716                 vid.support.arb_texture_cube_map = false;
1717         
1718         // verify that 3d textures are really supported
1719         if (vid.support.ext_texture_3d && vid.maxtexturesize_3d < 32)
1720         {
1721                 vid.support.ext_texture_3d = false;
1722                 Con_Printf("GL_OES_texture_3d reported bogus GL_MAX_3D_TEXTURE_SIZE, disabled\n");
1723         }
1724
1725         vid.texunits = 4;
1726         vid.teximageunits = 8;
1727         vid.texarrayunits = 5;
1728         vid.texunits = bound(1, vid.texunits, MAX_TEXTUREUNITS);
1729         vid.teximageunits = bound(1, vid.teximageunits, MAX_TEXTUREUNITS);
1730         vid.texarrayunits = bound(1, vid.texarrayunits, MAX_TEXTUREUNITS);
1731         Con_DPrintf("Using GLES2.0 rendering path - %i texture matrix, %i texture images, %i texcoords%s\n", vid.texunits, vid.teximageunits, vid.texarrayunits, vid.support.ext_framebuffer_object ? ", shadowmapping supported" : "");
1732         vid.renderpath = RENDERPATH_GLES2;
1733         vid.useinterleavedarrays = false;
1734
1735         // VorteX: set other info (maybe place them in VID_InitMode?)
1736         extern cvar_t gl_info_vendor;
1737         extern cvar_t gl_info_renderer;
1738         extern cvar_t gl_info_version;
1739         extern cvar_t gl_info_platform;
1740         extern cvar_t gl_info_driver;
1741         Cvar_SetQuick(&gl_info_vendor, gl_vendor);
1742         Cvar_SetQuick(&gl_info_renderer, gl_renderer);
1743         Cvar_SetQuick(&gl_info_version, gl_version);
1744         Cvar_SetQuick(&gl_info_platform, gl_platform ? gl_platform : "");
1745         Cvar_SetQuick(&gl_info_driver, gl_driver);
1746 }
1747 #endif
1748
1749 void *GL_GetProcAddress(const char *name)
1750 {
1751         void *p = NULL;
1752         p = SDL_GL_GetProcAddress(name);
1753         return p;
1754 }
1755
1756 static qboolean vid_sdl_initjoysticksystem = false;
1757
1758 void VID_Init (void)
1759 {
1760 #ifndef __IPHONEOS__
1761 #ifdef MACOSX
1762         Cvar_RegisterVariable(&apple_mouse_noaccel);
1763 #endif
1764 #endif
1765         Cvar_RegisterVariable(&vid_soft);
1766         Cvar_RegisterVariable(&vid_soft_threads);
1767         Cvar_RegisterVariable(&vid_soft_interlace);
1768         Cvar_RegisterVariable(&joy_detected);
1769         Cvar_RegisterVariable(&joy_enable);
1770         Cvar_RegisterVariable(&joy_index);
1771         Cvar_RegisterVariable(&joy_axisforward);
1772         Cvar_RegisterVariable(&joy_axisside);
1773         Cvar_RegisterVariable(&joy_axisup);
1774         Cvar_RegisterVariable(&joy_axispitch);
1775         Cvar_RegisterVariable(&joy_axisyaw);
1776         //Cvar_RegisterVariable(&joy_axisroll);
1777         Cvar_RegisterVariable(&joy_deadzoneforward);
1778         Cvar_RegisterVariable(&joy_deadzoneside);
1779         Cvar_RegisterVariable(&joy_deadzoneup);
1780         Cvar_RegisterVariable(&joy_deadzonepitch);
1781         Cvar_RegisterVariable(&joy_deadzoneyaw);
1782         //Cvar_RegisterVariable(&joy_deadzoneroll);
1783         Cvar_RegisterVariable(&joy_sensitivityforward);
1784         Cvar_RegisterVariable(&joy_sensitivityside);
1785         Cvar_RegisterVariable(&joy_sensitivityup);
1786         Cvar_RegisterVariable(&joy_sensitivitypitch);
1787         Cvar_RegisterVariable(&joy_sensitivityyaw);
1788         //Cvar_RegisterVariable(&joy_sensitivityroll);
1789         Cvar_RegisterVariable(&joy_axiskeyevents);
1790         Cvar_RegisterVariable(&joy_axiskeyevents_deadzone);
1791 #ifdef __IPHONEOS__
1792         Cvar_SetValueQuick(&vid_touchscreen, 1);
1793 #endif
1794
1795 #ifdef SDL_R_RESTART
1796         R_RegisterModule("SDL", sdl_start, sdl_shutdown, sdl_newmap, NULL, NULL);
1797 #endif
1798
1799         if (SDL_Init(SDL_INIT_VIDEO) < 0)
1800                 Sys_Error ("Failed to init SDL video subsystem: %s", SDL_GetError());
1801         vid_sdl_initjoysticksystem = SDL_InitSubSystem(SDL_INIT_JOYSTICK) >= 0;
1802         if (vid_sdl_initjoysticksystem)
1803                 Con_Printf("Failed to init SDL joystick subsystem: %s\n", SDL_GetError());
1804         vid_isfullscreen = false;
1805 }
1806
1807 #if SETVIDEOMODE
1808 // set the icon (we dont use SDL here since it would be too much a PITA)
1809 #ifdef WIN32
1810 #include "resource.h"
1811 #include <SDL_syswm.h>
1812 static void VID_SetCaption(void)
1813 {
1814     SDL_SysWMinfo       info;
1815         HICON                   icon;
1816
1817         // set the caption
1818         SDL_WM_SetCaption( gamename, NULL );
1819
1820         // get the HWND handle
1821     SDL_VERSION( &info.version );
1822         if( !SDL_GetWMInfo( &info ) )
1823                 return;
1824
1825         icon = LoadIcon( GetModuleHandle( NULL ), MAKEINTRESOURCE( IDI_ICON1 ) );
1826 #ifndef _W64 //If Windows 64bit data types don't exist
1827 #ifndef SetClassLongPtr
1828 #define SetClassLongPtr SetClassLong
1829 #endif
1830 #ifndef GCLP_HICON
1831 #define GCLP_HICON GCL_HICON
1832 #endif
1833 #ifndef LONG_PTR
1834 #define LONG_PTR LONG
1835 #endif
1836 #endif
1837         SetClassLongPtr( info.window, GCLP_HICON, (LONG_PTR)icon );
1838 }
1839 static void VID_SetIcon_Pre(void)
1840 {
1841 }
1842 static void VID_SetIcon_Post(void)
1843 {
1844 }
1845 #else
1846 // Adding the OS independent XPM version --blub
1847 #include "darkplaces.xpm"
1848 #include "nexuiz.xpm"
1849 static SDL_Surface *icon = NULL;
1850 static void VID_SetIcon_Pre(void)
1851 {
1852         /*
1853          * Somewhat restricted XPM reader. Only supports XPMs saved by GIMP 2.4 at
1854          * default settings with less than 91 colors and transparency.
1855          */
1856
1857         int width, height, colors, isize, i, j;
1858         int thenone = -1;
1859         static SDL_Color palette[256];
1860         unsigned short palenc[256]; // store color id by char
1861         char *xpm;
1862         char **idata, *data;
1863         const SDL_version *version;
1864
1865         version = SDL_Linked_Version();
1866         // only use non-XPM icon support in SDL v1.3 and higher
1867         // SDL v1.2 does not support "smooth" transparency, and thus is better
1868         // off the xpm way
1869         if(version->major >= 2 || (version->major == 1 && version->minor >= 3))
1870         {
1871                 data = (char *) loadimagepixelsbgra("darkplaces-icon", false, false, false, NULL);
1872                 if(data)
1873                 {
1874                         unsigned int red = 0x00FF0000;
1875                         unsigned int green = 0x0000FF00;
1876                         unsigned int blue = 0x000000FF;
1877                         unsigned int alpha = 0xFF000000;
1878                         width = image_width;
1879                         height = image_height;
1880
1881                         // reallocate with malloc, as this is in tempmempool (do not want)
1882                         xpm = data;
1883                         data = malloc(width * height * 4);
1884                         memcpy(data, xpm, width * height * 4);
1885                         Mem_Free(xpm);
1886                         xpm = NULL;
1887
1888                         icon = SDL_CreateRGBSurface(SDL_SRCALPHA, width, height, 32, LittleLong(red), LittleLong(green), LittleLong(blue), LittleLong(alpha));
1889
1890                         if(icon == NULL) {
1891                                 Con_Printf(     "Failed to create surface for the window Icon!\n"
1892                                                 "%s\n", SDL_GetError());
1893                                 free(data);
1894                                 return;
1895                         }
1896
1897                         icon->pixels = data;
1898                 }
1899         }
1900
1901         // we only get here if non-XPM icon was missing, or SDL version is not
1902         // sufficient for transparent non-XPM icons
1903         if(!icon)
1904         {
1905                 xpm = (char *) FS_LoadFile("darkplaces-icon.xpm", tempmempool, false, NULL);
1906                 idata = NULL;
1907                 if(xpm)
1908                         idata = XPM_DecodeString(xpm);
1909                 if(!idata)
1910                         idata = ENGINE_ICON;
1911                 if(xpm)
1912                         Mem_Free(xpm);
1913
1914                 data = idata[0];
1915
1916                 if(sscanf(data, "%i %i %i %i", &width, &height, &colors, &isize) != 4)
1917                 {
1918                         // NOTE: Only 1-char colornames are supported
1919                         Con_Printf("Sorry, but this does not even look similar to an XPM.\n");
1920                         return;
1921                 }
1922
1923                 if(isize != 1)
1924                 {
1925                         // NOTE: Only 1-char colornames are supported
1926                         Con_Printf("This XPM's palette is either huge or idiotically unoptimized. It's key size is %i\n", isize);
1927                         return;
1928                 }
1929
1930                 for(i = 0; i < colors; ++i)
1931                 {
1932                         unsigned int r, g, b;
1933                         char idx;
1934
1935                         if(sscanf(idata[i+1], "%c c #%02x%02x%02x", &idx, &r, &g, &b) != 4)
1936                         {
1937                                 char foo[2];
1938                                 if(sscanf(idata[i+1], "%c c Non%1[e]", &idx, foo) != 2) // I take the DailyWTF credit for this. --div0
1939                                 {
1940                                         Con_Printf("This XPM's palette looks odd. Can't continue.\n");
1941                                         return;
1942                                 }
1943                                 else
1944                                 {
1945                                         palette[i].r = 255; // color key
1946                                         palette[i].g = 0;
1947                                         palette[i].b = 255;
1948                                         thenone = i; // weeeee
1949                                 }
1950                         }
1951                         else
1952                         {
1953                                 palette[i].r = r - (r == 255 && g == 0 && b == 255); // change 255/0/255 pink to 254/0/255 for color key
1954                                 palette[i].g = g;
1955                                 palette[i].b = b;
1956                         }
1957
1958                         palenc[(unsigned char) idx] = i;
1959                 }
1960
1961                 // allocate the image data
1962                 data = (char*) malloc(width*height);
1963
1964                 for(j = 0; j < height; ++j)
1965                 {
1966                         for(i = 0; i < width; ++i)
1967                         {
1968                                 // casting to the safest possible datatypes ^^
1969                                 data[j * width + i] = palenc[((unsigned char*)idata[colors+j+1])[i]];
1970                         }
1971                 }
1972
1973                 if(icon != NULL)
1974                 {
1975                         // SDL_FreeSurface should free the data too
1976                         // but for completeness' sake...
1977                         if(icon->flags & SDL_PREALLOC)
1978                         {
1979                                 free(icon->pixels);
1980                                 icon->pixels = NULL; // safety
1981                         }
1982                         SDL_FreeSurface(icon);
1983                 }
1984
1985                 icon = SDL_CreateRGBSurface(SDL_SRCCOLORKEY, width, height, 8, 0,0,0,0);// rmask, gmask, bmask, amask); no mask needed
1986                 // 8 bit surfaces get an empty palette allocated according to the docs
1987                 // so it's a palette image for sure :) no endian check necessary for the mask
1988
1989                 if(icon == NULL) {
1990                         Con_Printf(     "Failed to create surface for the window Icon!\n"
1991                                         "%s\n", SDL_GetError());
1992                         free(data);
1993                         return;
1994                 }
1995
1996                 icon->pixels = data;
1997                 SDL_SetPalette(icon, SDL_PHYSPAL|SDL_LOGPAL, palette, 0, colors);
1998                 SDL_SetColorKey(icon, SDL_SRCCOLORKEY, thenone);
1999         }
2000
2001         SDL_WM_SetIcon(icon, NULL);
2002 }
2003 static void VID_SetIcon_Post(void)
2004 {
2005 #if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION == 2
2006 // LordHavoc: info.info.x11.lock_func and accompanying code do not seem to compile with SDL 1.3
2007 #if SDL_VIDEO_DRIVER_X11 && !SDL_VIDEO_DRIVER_QUARTZ
2008         int j;
2009         char *data;
2010         const SDL_version *version;
2011
2012         version = SDL_Linked_Version();
2013         // only use non-XPM icon support in SDL v1.3 and higher
2014         // SDL v1.2 does not support "smooth" transparency, and thus is better
2015         // off the xpm way
2016         if(!(version->major >= 2 || (version->major == 1 && version->minor >= 3)))
2017         {
2018                 // in this case, we did not set the good icon yet
2019                 SDL_SysWMinfo info;
2020                 SDL_VERSION(&info.version);
2021                 if(SDL_GetWMInfo(&info) == 1 && info.subsystem == SDL_SYSWM_X11)
2022                 {
2023                         data = (char *) loadimagepixelsbgra("darkplaces-icon", false, false, false, NULL);
2024                         if(data)
2025                         {
2026                                 // use _NET_WM_ICON too
2027                                 static long netwm_icon[MAX_NETWM_ICON];
2028                                 int pos = 0;
2029                                 int i = 1;
2030
2031                                 while(data)
2032                                 {
2033                                         if(pos + 2 * image_width * image_height < MAX_NETWM_ICON)
2034                                         {
2035                                                 netwm_icon[pos++] = image_width;
2036                                                 netwm_icon[pos++] = image_height;
2037                                                 for(i = 0; i < image_height; ++i)
2038                                                         for(j = 0; j < image_width; ++j)
2039                                                                 netwm_icon[pos++] = BuffLittleLong((unsigned char *) &data[(i*image_width+j)*4]);
2040                                         }
2041                                         else
2042                                         {
2043                                                 Con_Printf("Skipping NETWM icon #%d because there is no space left\n", i);
2044                                         }
2045                                         ++i;
2046                                         Mem_Free(data);
2047                                         data = (char *) loadimagepixelsbgra(va("darkplaces-icon%d", i), false, false, false, NULL);
2048                                 }
2049
2050                                 info.info.x11.lock_func();
2051                                 {
2052                                         Atom net_wm_icon = XInternAtom(info.info.x11.display, "_NET_WM_ICON", false);
2053                                         XChangeProperty(info.info.x11.display, info.info.x11.wmwindow, net_wm_icon, XA_CARDINAL, 32, PropModeReplace, (const unsigned char *) netwm_icon, pos);
2054                                 }
2055                                 info.info.x11.unlock_func();
2056                         }
2057                 }
2058         }
2059 #endif
2060 #endif
2061 }
2062
2063
2064 static void VID_SetCaption(void)
2065 {
2066         SDL_WM_SetCaption( gamename, NULL );
2067 }
2068 #endif
2069 #endif
2070
2071 static void VID_OutputVersion(void)
2072 {
2073         const SDL_version *version;
2074         version = SDL_Linked_Version();
2075         Con_Printf(     "Linked against SDL version %d.%d.%d\n"
2076                                         "Using SDL library version %d.%d.%d\n",
2077                                         SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL,
2078                                         version->major, version->minor, version->patch );
2079 }
2080
2081 qboolean VID_InitModeGL(viddef_mode_t *mode)
2082 {
2083         int i;
2084 #if SETVIDEOMODE
2085         static int notfirstvideomode = false;
2086         int flags = SDL_OPENGL;
2087 #else
2088         int windowflags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL;
2089 #endif
2090         const char *drivername;
2091
2092         win_half_width = mode->width>>1;
2093         win_half_height = mode->height>>1;
2094
2095         if(vid_resizable.integer)
2096 #if SETVIDEOMODE
2097                 flags |= SDL_RESIZABLE;
2098 #else
2099                 windowflags |= SDL_WINDOW_RESIZABLE;
2100 #endif
2101
2102         VID_OutputVersion();
2103
2104 #if SETVIDEOMODE
2105         /*
2106         SDL 1.2 Hack
2107                 We cant switch from one OpenGL video mode to another.
2108                 Thus we first switch to some stupid 2D mode and then back to OpenGL.
2109         */
2110         if (notfirstvideomode)
2111                 SDL_SetVideoMode( 0, 0, 0, 0 );
2112         notfirstvideomode = true;
2113 #endif
2114
2115         // SDL usually knows best
2116         drivername = NULL;
2117
2118 // COMMANDLINEOPTION: SDL GL: -gl_driver <drivername> selects a GL driver library, default is whatever SDL recommends, useful only for 3dfxogl.dll/3dfxvgl.dll or fxmesa or similar, if you don't know what this is for, you don't need it
2119         i = COM_CheckParm("-gl_driver");
2120         if (i && i < com_argc - 1)
2121                 drivername = com_argv[i + 1];
2122         if (SDL_GL_LoadLibrary(drivername) < 0)
2123         {
2124                 Con_Printf("Unable to load GL driver \"%s\": %s\n", drivername, SDL_GetError());
2125                 return false;
2126         }
2127
2128 #ifdef __IPHONEOS__
2129         // mobile platforms are always fullscreen, we'll get the resolution after opening the window
2130         mode->fullscreen = true;
2131         // hide the menu with SDL_WINDOW_BORDERLESS
2132         windowflags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS;
2133 #else
2134         if ((qglGetString = (const GLubyte* (GLAPIENTRY *)(GLenum name))GL_GetProcAddress("glGetString")) == NULL)
2135         {
2136                 VID_Shutdown();
2137                 Con_Print("Required OpenGL function glGetString not found\n");
2138                 return false;
2139         }
2140 #endif
2141
2142         // Knghtbrd: should do platform-specific extension string function here
2143
2144         vid_isfullscreen = false;
2145         if (mode->fullscreen) {
2146 #if SETVIDEOMODE
2147                 flags |= SDL_FULLSCREEN;
2148 #else
2149                 windowflags |= SDL_WINDOW_FULLSCREEN;
2150 #endif
2151                 vid_isfullscreen = true;
2152         }
2153         //flags |= SDL_HWSURFACE;
2154
2155         SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
2156         if (mode->bitsperpixel >= 32)
2157         {
2158                 SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 8);
2159                 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 8);
2160                 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 8);
2161                 SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, 8);
2162                 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 24);
2163                 SDL_GL_SetAttribute (SDL_GL_STENCIL_SIZE, 8);
2164         }
2165         else
2166         {
2167                 SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5);
2168                 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5);
2169                 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5);
2170                 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 16);
2171         }
2172         if (mode->stereobuffer)
2173                 SDL_GL_SetAttribute (SDL_GL_STEREO, 1);
2174         if (mode->samples > 1)
2175         {
2176                 SDL_GL_SetAttribute (SDL_GL_MULTISAMPLEBUFFERS, 1);
2177                 SDL_GL_SetAttribute (SDL_GL_MULTISAMPLESAMPLES, mode->samples);
2178         }
2179 #if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION == 2
2180         if (vid_vsync.integer)
2181                 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1);
2182         else
2183                 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 0);
2184 #else
2185 #ifdef __IPHONEOS__
2186         SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
2187         SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0);
2188         SDL_GL_SetAttribute (SDL_GL_RETAINED_BACKING, 1);
2189         // FIXME: get proper resolution from OS somehow (iPad for instance...)
2190         mode->width = 320;
2191         mode->height = 480;
2192 #endif
2193 #endif
2194
2195         video_bpp = mode->bitsperpixel;
2196 #if SETVIDEOMODE
2197         video_flags = flags;
2198         VID_SetIcon_Pre();
2199         screen = SDL_SetVideoMode(mode->width, mode->height, mode->bitsperpixel, flags);
2200         VID_SetIcon_Post();
2201         if (screen == NULL)
2202         {
2203                 Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError());
2204                 VID_Shutdown();
2205                 return false;
2206         }
2207         mode->width = screen->w;
2208         mode->height = screen->h;
2209 #else
2210         window_flags = windowflags;
2211         window = SDL_CreateWindow(gamename, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, mode->width, mode->height, windowflags);
2212         if (window == NULL)
2213         {
2214                 Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError());
2215                 VID_Shutdown();
2216                 return false;
2217         }
2218         SDL_GetWindowSize(window, &mode->width, &mode->height);
2219         context = SDL_GL_CreateContext(window);
2220         if (context == NULL)
2221         {
2222                 Con_Printf("Failed to initialize OpenGL context: %s\n", SDL_GetError());
2223                 VID_Shutdown();
2224                 return false;
2225         }
2226 #endif
2227
2228         vid_softsurface = NULL;
2229         vid.softpixels = NULL;
2230
2231 #if SETVIDEOMODE
2232         // set window title
2233         VID_SetCaption();
2234 #endif
2235         // init keyboard
2236         SDL_EnableUNICODE( SDL_ENABLE );
2237         // enable key repeat since everyone expects it
2238         SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
2239
2240 #if !(SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION == 2)
2241         SDL_GL_SetSwapInterval(vid_vsync.integer != 0);
2242         vid_usingvsync = (vid_vsync.integer != 0);
2243 #endif
2244
2245         gl_platform = "SDL";
2246         gl_platformextensions = "";
2247
2248 #ifdef __IPHONEOS__
2249         GLES_Init();
2250 #else
2251         GL_Init();
2252 #endif
2253
2254         vid_numjoysticks = SDL_NumJoysticks();
2255         vid_numjoysticks = bound(0, vid_numjoysticks, MAX_JOYSTICKS);
2256         Cvar_SetValueQuick(&joy_detected, vid_numjoysticks);
2257         Con_Printf("%d SDL joystick(s) found:\n", vid_numjoysticks);
2258         memset(vid_joysticks, 0, sizeof(vid_joysticks));
2259         for (i = 0;i < vid_numjoysticks;i++)
2260         {
2261                 SDL_Joystick *joy;
2262                 joy = vid_joysticks[i] = SDL_JoystickOpen(i);
2263                 if (!joy)
2264                 {
2265                         Con_Printf("joystick #%i: open failed: %s\n", i, SDL_GetError());
2266                         continue;
2267                 }
2268                 Con_Printf("joystick #%i: opened \"%s\" with %i axes, %i buttons, %i balls\n", i, SDL_JoystickName(i), (int)SDL_JoystickNumAxes(joy), (int)SDL_JoystickNumButtons(joy), (int)SDL_JoystickNumBalls(joy));
2269         }
2270
2271         vid_hidden = false;
2272         vid_activewindow = false;
2273         vid_hasfocus = true;
2274         vid_usingmouse = false;
2275         vid_usinghidecursor = false;
2276
2277 #if SETVIDEOMODE
2278         SDL_WM_GrabInput(SDL_GRAB_OFF);
2279 #endif
2280         return true;
2281 }
2282
2283 extern cvar_t gl_info_extensions;
2284 extern cvar_t gl_info_vendor;
2285 extern cvar_t gl_info_renderer;
2286 extern cvar_t gl_info_version;
2287 extern cvar_t gl_info_platform;
2288 extern cvar_t gl_info_driver;
2289
2290 qboolean VID_InitModeSoft(viddef_mode_t *mode)
2291 {
2292         int i;
2293 #if SETVIDEOMODE
2294         int flags = SDL_HWSURFACE;
2295 #else
2296         int windowflags = SDL_WINDOW_SHOWN;
2297 #endif
2298
2299         win_half_width = mode->width>>1;
2300         win_half_height = mode->height>>1;
2301
2302         if(vid_resizable.integer)
2303 #if SETVIDEOMODE
2304                 flags |= SDL_RESIZABLE;
2305 #else
2306                 windowflags |= SDL_WINDOW_RESIZABLE;
2307 #endif
2308
2309         VID_OutputVersion();
2310
2311         vid_isfullscreen = false;
2312         if (mode->fullscreen) {
2313 #if SETVIDEOMODE
2314                 flags |= SDL_FULLSCREEN;
2315 #else
2316                 windowflags |= SDL_WINDOW_FULLSCREEN;
2317 #endif
2318                 vid_isfullscreen = true;
2319         }
2320
2321         video_bpp = mode->bitsperpixel;
2322 #if SETVIDEOMODE
2323         video_flags = flags;
2324         VID_SetIcon_Pre();
2325         screen = SDL_SetVideoMode(mode->width, mode->height, mode->bitsperpixel, flags);
2326         VID_SetIcon_Post();
2327         if (screen == NULL)
2328         {
2329                 Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError());
2330                 VID_Shutdown();
2331                 return false;
2332         }
2333         mode->width = screen->w;
2334         mode->height = screen->h;
2335 #else
2336         window_flags = windowflags;
2337         window = SDL_CreateWindow(gamename, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, mode->width, mode->height, windowflags);
2338         if (window == NULL)
2339         {
2340                 Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError());
2341                 VID_Shutdown();
2342                 return false;
2343         }
2344         SDL_GetWindowSize(window, &mode->width, &mode->height);
2345 #endif
2346
2347         // create a framebuffer using our specific color format, we let the SDL blit function convert it in VID_Finish
2348         vid_softsurface = SDL_CreateRGBSurface(SDL_SWSURFACE, mode->width, mode->height, 32, 0x00FF0000, 0x0000FF00, 0x00000000FF, 0xFF000000);
2349         if (vid_softsurface == NULL)
2350         {
2351                 Con_Printf("Failed to setup software rasterizer framebuffer %ix%ix32bpp: %s\n", mode->width, mode->height, SDL_GetError());
2352                 VID_Shutdown();
2353                 return false;
2354         }
2355         SDL_SetAlpha(vid_softsurface, 0, 255);
2356
2357         vid.softpixels = (unsigned int *)vid_softsurface->pixels;
2358         vid.softdepthpixels = (unsigned int *)calloc(1, mode->width * mode->height * 4);
2359         if (DPSOFTRAST_Init(mode->width, mode->height, vid_soft_threads.integer, vid_soft_interlace.integer, (unsigned int *)vid_softsurface->pixels, (unsigned int *)vid.softdepthpixels) < 0)
2360         {
2361                 Con_Printf("Failed to initialize software rasterizer\n");
2362                 VID_Shutdown();
2363                 return false;
2364         }
2365
2366 #if SETVIDEOMODE
2367         // set window title
2368         VID_SetCaption();
2369 #endif
2370         // init keyboard
2371         SDL_EnableUNICODE( SDL_ENABLE );
2372         // enable key repeat since everyone expects it
2373         SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
2374
2375         gl_platform = "SDLSoft";
2376         gl_platformextensions = "";
2377
2378         gl_renderer = "DarkPlaces-Soft";
2379         gl_vendor = "Forest Hale";
2380         gl_version = "0.0";
2381         gl_extensions = "";
2382
2383         // clear the extension flags
2384         memset(&vid.support, 0, sizeof(vid.support));
2385         Cvar_SetQuick(&gl_info_extensions, "");
2386
2387         vid.forcevbo = false;
2388         vid.support.arb_depth_texture = true;
2389         vid.support.arb_draw_buffers = true;
2390         vid.support.arb_occlusion_query = true;
2391         vid.support.arb_shadow = true;
2392         //vid.support.arb_texture_compression = true;
2393         vid.support.arb_texture_cube_map = true;
2394         vid.support.arb_texture_non_power_of_two = false;
2395         vid.support.arb_vertex_buffer_object = true;
2396         vid.support.ext_blend_subtract = true;
2397         vid.support.ext_draw_range_elements = true;
2398         vid.support.ext_framebuffer_object = true;
2399         vid.support.ext_texture_3d = true;
2400         //vid.support.ext_texture_compression_s3tc = true;
2401         vid.support.ext_texture_filter_anisotropic = true;
2402         vid.support.ati_separate_stencil = true;
2403
2404         vid.maxtexturesize_2d = 16384;
2405         vid.maxtexturesize_3d = 512;
2406         vid.maxtexturesize_cubemap = 16384;
2407         vid.texunits = 4;
2408         vid.teximageunits = 32;
2409         vid.texarrayunits = 8;
2410         vid.max_anisotropy = 1;
2411         vid.maxdrawbuffers = 4;
2412
2413         vid.texunits = bound(4, vid.texunits, MAX_TEXTUREUNITS);
2414         vid.teximageunits = bound(16, vid.teximageunits, MAX_TEXTUREUNITS);
2415         vid.texarrayunits = bound(8, vid.texarrayunits, MAX_TEXTUREUNITS);
2416         Con_DPrintf("Using DarkPlaces Software Rasterizer rendering path\n");
2417         vid.renderpath = RENDERPATH_SOFT;
2418         vid.useinterleavedarrays = false;
2419
2420         Cvar_SetQuick(&gl_info_vendor, gl_vendor);
2421         Cvar_SetQuick(&gl_info_renderer, gl_renderer);
2422         Cvar_SetQuick(&gl_info_version, gl_version);
2423         Cvar_SetQuick(&gl_info_platform, gl_platform ? gl_platform : "");
2424         Cvar_SetQuick(&gl_info_driver, gl_driver);
2425
2426         // LordHavoc: report supported extensions
2427         Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions );
2428
2429         // clear to black (loading plaque will be seen over this)
2430         GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 128);
2431
2432         vid_numjoysticks = SDL_NumJoysticks();
2433         vid_numjoysticks = bound(0, vid_numjoysticks, MAX_JOYSTICKS);
2434         Cvar_SetValueQuick(&joy_detected, vid_numjoysticks);
2435         Con_Printf("%d SDL joystick(s) found:\n", vid_numjoysticks);
2436         memset(vid_joysticks, 0, sizeof(vid_joysticks));
2437         for (i = 0;i < vid_numjoysticks;i++)
2438         {
2439                 SDL_Joystick *joy;
2440                 joy = vid_joysticks[i] = SDL_JoystickOpen(i);
2441                 if (!joy)
2442                 {
2443                         Con_Printf("joystick #%i: open failed: %s\n", i, SDL_GetError());
2444                         continue;
2445                 }
2446                 Con_Printf("joystick #%i: opened \"%s\" with %i axes, %i buttons, %i balls\n", i, SDL_JoystickName(i), (int)SDL_JoystickNumAxes(joy), (int)SDL_JoystickNumButtons(joy), (int)SDL_JoystickNumBalls(joy));
2447         }
2448
2449         vid_hidden = false;
2450         vid_activewindow = false;
2451         vid_hasfocus = true;
2452         vid_usingmouse = false;
2453         vid_usinghidecursor = false;
2454
2455 #if SETVIDEOMODE
2456         SDL_WM_GrabInput(SDL_GRAB_OFF);
2457 #endif
2458         return true;
2459 }
2460
2461 qboolean VID_InitMode(viddef_mode_t *mode)
2462 {
2463         if (!SDL_WasInit(SDL_INIT_VIDEO) && SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
2464                 Sys_Error ("Failed to init SDL video subsystem: %s", SDL_GetError());
2465 #ifdef SSE2_PRESENT
2466         if (vid_soft.integer)
2467                 return VID_InitModeSoft(mode);
2468         else
2469 #endif
2470                 return VID_InitModeGL(mode);
2471 }
2472
2473 void VID_Shutdown (void)
2474 {
2475         VID_SetMouse(false, false, false);
2476         VID_RestoreSystemGamma();
2477
2478 #if SETVIDEOMODE
2479 #ifndef WIN32
2480         if (icon)
2481                 SDL_FreeSurface(icon);
2482         icon = NULL;
2483 #endif
2484 #endif
2485
2486         if (vid_softsurface)
2487                 SDL_FreeSurface(vid_softsurface);
2488         vid_softsurface = NULL;
2489         vid.softpixels = NULL;
2490         if (vid.softdepthpixels)
2491                 free(vid.softdepthpixels);
2492         vid.softdepthpixels = NULL;
2493
2494 #if SETVIDEOMODE
2495 #else
2496         SDL_DestroyWindow(window);
2497         window = NULL;
2498 #endif
2499
2500         SDL_QuitSubSystem(SDL_INIT_VIDEO);
2501
2502         gl_driver[0] = 0;
2503         gl_extensions = "";
2504         gl_platform = "";
2505         gl_platformextensions = "";
2506 }
2507
2508 int VID_SetGamma (unsigned short *ramps, int rampsize)
2509 {
2510         return !SDL_SetGammaRamp (ramps, ramps + rampsize, ramps + rampsize*2);
2511 }
2512
2513 int VID_GetGamma (unsigned short *ramps, int rampsize)
2514 {
2515         return !SDL_GetGammaRamp (ramps, ramps + rampsize, ramps + rampsize*2);
2516 }
2517
2518 void VID_Finish (void)
2519 {
2520 #if SETVIDEOMODE
2521         Uint8 appstate;
2522
2523         //react on appstate changes
2524         appstate = SDL_GetAppState();
2525
2526         vid_hidden = !(appstate & SDL_APPACTIVE);
2527         vid_hasfocus = (appstate & SDL_APPMOUSEFOCUS) && (appstate & SDL_APPINPUTFOCUS);
2528 #endif
2529         vid_activewindow = !vid_hidden && vid_hasfocus;
2530
2531         VID_UpdateGamma(false, 256);
2532
2533         if (!vid_hidden)
2534         {
2535                 switch(vid.renderpath)
2536                 {
2537                 case RENDERPATH_GL11:
2538                 case RENDERPATH_GL13:
2539                 case RENDERPATH_GL20:
2540                 case RENDERPATH_GLES2:
2541                         CHECKGLERROR
2542                         if (r_speeds.integer == 2 || gl_finish.integer)
2543                         {
2544                                 qglFinish();CHECKGLERROR
2545                         }
2546 #if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION == 2
2547 #else
2548 {
2549         qboolean vid_usevsync;
2550         vid_usevsync = (vid_vsync.integer && !cls.timedemo);
2551         if (vid_usingvsync != vid_usevsync)
2552         {
2553                 if (SDL_GL_SetSwapInterval(vid_usevsync != 0) >= 0)
2554                         Con_DPrintf("Vsync %s\n", vid_usevsync ? "activated" : "deactivated");
2555                 else
2556                         Con_DPrintf("ERROR: can't %s vsync\n", vid_usevsync ? "activate" : "deactivate");
2557         }
2558 }
2559 #endif
2560 #if SETVIDEOMODE
2561                         SDL_GL_SwapBuffers();
2562 #else
2563                         SDL_GL_SwapWindow(window);
2564 #endif
2565                         break;
2566                 case RENDERPATH_SOFT:
2567                         DPSOFTRAST_Finish();
2568 #if SETVIDEOMODE
2569                         SDL_BlitSurface(vid_softsurface, NULL, screen, NULL);
2570                         SDL_Flip(screen);
2571 #else
2572                         {
2573                                 SDL_Surface *screen = SDL_GetWindowSurface(window);
2574                                 SDL_BlitSurface(vid_softsurface, NULL, screen, NULL);
2575                                 SDL_UpdateWindowSurface(window);
2576                         }
2577 #endif
2578                         break;
2579                 case RENDERPATH_D3D9:
2580                 case RENDERPATH_D3D10:
2581                 case RENDERPATH_D3D11:
2582                         break;
2583                 }
2584         }
2585 }
2586
2587 size_t VID_ListModes(vid_mode_t *modes, size_t maxcount)
2588 {
2589         size_t k;
2590         SDL_Rect **vidmodes;
2591         int bpp = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
2592
2593         k = 0;
2594         for(vidmodes = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE); *vidmodes; ++vidmodes)
2595         {
2596                 if(k >= maxcount)
2597                         break;
2598                 modes[k].width = (*vidmodes)->w;
2599                 modes[k].height = (*vidmodes)->h;
2600                 modes[k].bpp = bpp;
2601                 modes[k].refreshrate = 60; // no support for refresh rate in SDL
2602                 modes[k].pixelheight_num = 1;
2603                 modes[k].pixelheight_denom = 1; // SDL does not provide this
2604                 ++k;
2605         }
2606         return k;
2607 }