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