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