]> de.git.xonotic.org Git - xonotic/darkplaces.git/blob - vid_sdl.c
Revert "Revert "Build in subdirs"", as the issues seem to be ironed out now.
[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)
1136                                 {
1137                                         vid.width = event.resize.w;
1138                                         vid.height = event.resize.h;
1139                                         screen = SDL_SetVideoMode(vid.width, vid.height, video_bpp, video_flags);
1140                                         if (vid_softsurface)
1141                                         {
1142                                                 SDL_FreeSurface(vid_softsurface);
1143                                                 vid_softsurface = SDL_CreateRGBSurface(SDL_SWSURFACE, vid.width, vid.height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
1144                                                 vid.softpixels = (unsigned int *)vid_softsurface->pixels;
1145                                                 SDL_SetAlpha(vid_softsurface, 0, 255);
1146                                                 if (vid.softdepthpixels)
1147                                                         free(vid.softdepthpixels);
1148                                                 vid.softdepthpixels = (unsigned int*)calloc(1, vid.width * vid.height * 4);
1149                                         }
1150 #ifdef SDL_R_RESTART
1151                                         // better not call R_Modules_Restart from here directly, as this may wreak havoc...
1152                                         // so, let's better queue it for next frame
1153                                         if(!sdl_needs_restart)
1154                                         {
1155                                                 Cbuf_AddText("\nr_restart\n");
1156                                                 sdl_needs_restart = true;
1157                                         }
1158 #endif
1159                                 }
1160                                 break;
1161 #if SDL_MAJOR_VERSION != 1
1162                         case SDL_TEXTEDITING:
1163                                 break;
1164                         case SDL_TEXTINPUT:
1165                                 break;
1166 #endif
1167                         case SDL_MOUSEMOTION:
1168                                 break;
1169                         default:
1170                                 Con_DPrintf("Received unrecognized SDL_Event type 0x%x\n", event.type);
1171                                 break;
1172                 }
1173
1174         // enable/disable sound on focus gain/loss
1175         if ((!vid_hidden && vid_activewindow) || !snd_mutewhenidle.integer)
1176         {
1177                 if (!sound_active)
1178                 {
1179                         S_UnblockSound ();
1180                         sound_active = true;
1181                 }
1182         }
1183         else
1184         {
1185                 if (sound_active)
1186                 {
1187                         S_BlockSound ();
1188                         sound_active = false;
1189                 }
1190         }
1191 }
1192
1193 #else
1194
1195 //#define DEBUGSDLEVENTS
1196
1197 // SDL2
1198 void Sys_SendKeyEvents( void )
1199 {
1200         static qboolean sound_active = true;
1201         int keycode;
1202         int i;
1203         int j;
1204         int unicode;
1205         SDL_Event event;
1206
1207         VID_EnableJoystick(true);
1208
1209         while( SDL_PollEvent( &event ) )
1210                 switch( event.type ) {
1211                         case SDL_QUIT:
1212 #ifdef DEBUGSDLEVENTS
1213                                 Con_DPrintf("SDL_Event: SDL_QUIT\n");
1214 #endif
1215                                 Sys_Quit(0);
1216                                 break;
1217                         case SDL_KEYDOWN:
1218                         case SDL_KEYUP:
1219 #ifdef DEBUGSDLEVENTS
1220                                 if (event.type == SDL_KEYDOWN)
1221                                         Con_DPrintf("SDL_Event: SDL_KEYDOWN %i unicode %i\n", event.key.keysym.sym, event.key.keysym.unicode);
1222                                 else
1223                                         Con_DPrintf("SDL_Event: SDL_KEYUP %i unicode %i\n", event.key.keysym.sym, event.key.keysym.unicode);
1224 #endif
1225                                 keycode = MapKey(event.key.keysym.sym);
1226                                 if (!VID_JoyBlockEmulatedKeys(keycode))
1227                                         Key_Event(keycode, 0, (event.key.state == SDL_PRESSED));
1228                                 break;
1229                         case SDL_MOUSEBUTTONDOWN:
1230                         case SDL_MOUSEBUTTONUP:
1231 #ifdef DEBUGSDLEVENTS
1232                                 if (event.type == SDL_MOUSEBUTTONDOWN)
1233                                         Con_DPrintf("SDL_Event: SDL_MOUSEBUTTONDOWN\n");
1234                                 else
1235                                         Con_DPrintf("SDL_Event: SDL_MOUSEBUTTONUP\n");
1236 #endif
1237                                 if (!vid_touchscreen.integer)
1238                                 if (event.button.button <= 18)
1239                                         Key_Event( buttonremap[event.button.button - 1], 0, event.button.state == SDL_PRESSED );
1240                                 break;
1241                         case SDL_JOYBUTTONDOWN:
1242                         case SDL_JOYBUTTONUP:
1243                         case SDL_JOYAXISMOTION:
1244                         case SDL_JOYBALLMOTION:
1245                         case SDL_JOYHATMOTION:
1246 #ifdef DEBUGSDLEVENTS
1247                                 Con_DPrintf("SDL_Event: SDL_JOY*\n");
1248 #endif
1249                                 break;
1250                         case SDL_WINDOWEVENT:
1251 #ifdef DEBUGSDLEVENTS
1252                                 Con_DPrintf("SDL_Event: SDL_WINDOWEVENT %i\n", (int)event.window.event);
1253 #endif
1254                                 //if (event.window.windowID == window) // how to compare?
1255                                 {
1256                                         switch(event.window.event)
1257                                         {
1258                                         case SDL_WINDOWEVENT_SHOWN:
1259                                                 vid_hidden = false;
1260                                                 break;
1261                                         case  SDL_WINDOWEVENT_HIDDEN:
1262                                                 vid_hidden = true;
1263                                                 break;
1264                                         case SDL_WINDOWEVENT_EXPOSED:
1265 #ifdef DEBUGSDLEVENTS
1266                                                 Con_DPrintf("SDL_Event: SDL_WINDOWEVENT_EXPOSED\n");
1267 #endif
1268                                                 break;
1269                                         case SDL_WINDOWEVENT_MOVED:
1270                                                 break;
1271                                         case SDL_WINDOWEVENT_RESIZED:
1272                                                 if(vid_resizable.integer < 2)
1273                                                 {
1274                                                         vid.width = event.window.data1;
1275                                                         vid.height = event.window.data2;
1276                                                         if (vid_softsurface)
1277                                                         {
1278                                                                 SDL_FreeSurface(vid_softsurface);
1279                                                                 vid_softsurface = SDL_CreateRGBSurface(SDL_SWSURFACE, vid.width, vid.height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
1280                                                                 vid.softpixels = (unsigned int *)vid_softsurface->pixels;
1281                                                                 if (vid.softdepthpixels)
1282                                                                         free(vid.softdepthpixels);
1283                                                                 vid.softdepthpixels = (unsigned int*)calloc(1, vid.width * vid.height * 4);
1284                                                         }
1285 #ifdef SDL_R_RESTART
1286                                                         // better not call R_Modules_Restart from here directly, as this may wreak havoc...
1287                                                         // so, let's better queue it for next frame
1288                                                         if(!sdl_needs_restart)
1289                                                         {
1290                                                                 Cbuf_AddText("\nr_restart\n");
1291                                                                 sdl_needs_restart = true;
1292                                                         }
1293 #endif
1294                                                 }
1295                                                 break;
1296                                         case SDL_WINDOWEVENT_MINIMIZED:
1297                                                 break;
1298                                         case SDL_WINDOWEVENT_MAXIMIZED:
1299                                                 break;
1300                                         case SDL_WINDOWEVENT_RESTORED:
1301                                                 break;
1302                                         case SDL_WINDOWEVENT_ENTER:
1303                                                 break;
1304                                         case SDL_WINDOWEVENT_LEAVE:
1305                                                 break;
1306                                         case SDL_WINDOWEVENT_FOCUS_GAINED:
1307                                                 vid_hasfocus = true;
1308                                                 break;
1309                                         case SDL_WINDOWEVENT_FOCUS_LOST:
1310                                                 vid_hasfocus = false;
1311                                                 break;
1312                                         case SDL_WINDOWEVENT_CLOSE:
1313                                                 Sys_Quit(0);
1314                                                 break;
1315                                         }
1316                                 }
1317                                 break;
1318                         case SDL_TEXTEDITING:
1319 #ifdef DEBUGSDLEVENTS
1320                                 Con_DPrintf("SDL_Event: SDL_TEXTEDITING - composition = %s, cursor = %d, selection lenght = %d\n", event.edit.text, event.edit.start, event.edit.length);
1321 #endif
1322                                 // FIXME!  this is where composition gets supported
1323                                 break;
1324                         case SDL_TEXTINPUT:
1325 #ifdef DEBUGSDLEVENTS
1326                                 Con_DPrintf("SDL_Event: SDL_TEXTINPUT - text: %s\n", event.text.text);
1327 #endif
1328                                 // we have some characters to parse
1329                                 {
1330                                         unicode = 0;
1331                                         for (i = 0;event.text.text[i];)
1332                                         {
1333                                                 unicode = event.text.text[i++];
1334                                                 if (unicode & 0x80)
1335                                                 {
1336                                                         // UTF-8 character
1337                                                         // strip high bits (we could count these to validate character length but we don't)
1338                                                         for (j = 0x80;unicode & j;j >>= 1)
1339                                                                 unicode ^= j;
1340                                                         for (;(event.text.text[i] & 0xC0) == 0x80;i++)
1341                                                                 unicode = (unicode << 6) | (event.text.text[i] & 0x3F);
1342                                                         // low characters are invalid and could be bad, so replace them
1343                                                         if (unicode < 0x80)
1344                                                                 unicode = '?'; // we could use 0xFFFD instead, the unicode substitute character
1345                                                 }
1346                                                 //Con_DPrintf("SDL_TEXTINPUT: K_TEXT %i \n", unicode);
1347
1348                                                 Key_Event(K_TEXT, unicode, true);
1349                                                 Key_Event(K_TEXT, unicode, false);
1350                                         }
1351                                 }
1352                                 break;
1353                         case SDL_MOUSEMOTION:
1354                                 break;
1355                         case SDL_FINGERDOWN:
1356 #ifdef DEBUGSDLEVENTS
1357                                 Con_DPrintf("SDL_FINGERDOWN for finger %i\n", (int)event.tfinger.fingerId);
1358 #endif
1359                                 for (i = 0;i < MAXFINGERS-1;i++)
1360                                 {
1361                                         if (!multitouch[i][0])
1362                                         {
1363                                                 multitouch[i][0] = event.tfinger.fingerId + 1;
1364                                                 multitouch[i][1] = event.tfinger.x;
1365                                                 multitouch[i][2] = event.tfinger.y;
1366                                                 // TODO: use event.tfinger.pressure?
1367                                                 break;
1368                                         }
1369                                 }
1370                                 if (i == MAXFINGERS-1)
1371                                         Con_DPrintf("Too many fingers at once!\n");
1372                                 break;
1373                         case SDL_FINGERUP:
1374 #ifdef DEBUGSDLEVENTS
1375                                 Con_DPrintf("SDL_FINGERUP for finger %i\n", (int)event.tfinger.fingerId);
1376 #endif
1377                                 for (i = 0;i < MAXFINGERS-1;i++)
1378                                 {
1379                                         if (multitouch[i][0] == event.tfinger.fingerId + 1)
1380                                         {
1381                                                 multitouch[i][0] = 0;
1382                                                 break;
1383                                         }
1384                                 }
1385                                 if (i == MAXFINGERS-1)
1386                                         Con_DPrintf("No SDL_FINGERDOWN event matches this SDL_FINGERMOTION event\n");
1387                                 break;
1388                         case SDL_FINGERMOTION:
1389 #ifdef DEBUGSDLEVENTS
1390                                 Con_DPrintf("SDL_FINGERMOTION for finger %i\n", (int)event.tfinger.fingerId);
1391 #endif
1392                                 for (i = 0;i < MAXFINGERS-1;i++)
1393                                 {
1394                                         if (multitouch[i][0] == event.tfinger.fingerId + 1)
1395                                         {
1396                                                 multitouch[i][1] = event.tfinger.x;
1397                                                 multitouch[i][2] = event.tfinger.y;
1398                                                 break;
1399                                         }
1400                                 }
1401                                 if (i == MAXFINGERS-1)
1402                                         Con_DPrintf("No SDL_FINGERDOWN event matches this SDL_FINGERMOTION event\n");
1403                                 break;
1404                         default:
1405 #ifdef DEBUGSDLEVENTS
1406                                 Con_DPrintf("Received unrecognized SDL_Event type 0x%x\n", event.type);
1407 #endif
1408                                 break;
1409                 }
1410
1411         // enable/disable sound on focus gain/loss
1412         if ((!vid_hidden && vid_activewindow) || !snd_mutewhenidle.integer)
1413         {
1414                 if (!sound_active)
1415                 {
1416                         S_UnblockSound ();
1417                         sound_active = true;
1418                 }
1419         }
1420         else
1421         {
1422                 if (sound_active)
1423                 {
1424                         S_BlockSound ();
1425                         sound_active = false;
1426                 }
1427         }
1428 }
1429 #endif
1430
1431 /////////////////
1432 // Video system
1433 ////
1434
1435 #ifdef USE_GLES2
1436 #ifndef qglClear
1437 #ifdef __IPHONEOS__
1438 #include <OpenGLES/ES2/gl.h>
1439 #else
1440 #include <SDL_opengles.h>
1441 #endif
1442
1443 //#define PRECALL //Con_Printf("GLCALL %s:%i\n", __FILE__, __LINE__)
1444 #define PRECALL
1445 #define POSTCALL
1446 GLboolean wrapglIsBuffer(GLuint buffer) {PRECALL;return glIsBuffer(buffer);POSTCALL;}
1447 GLboolean wrapglIsEnabled(GLenum cap) {PRECALL;return glIsEnabled(cap);POSTCALL;}
1448 GLboolean wrapglIsFramebuffer(GLuint framebuffer) {PRECALL;return glIsFramebuffer(framebuffer);POSTCALL;}
1449 //GLboolean wrapglIsQuery(GLuint qid) {PRECALL;return glIsQuery(qid);POSTCALL;}
1450 GLboolean wrapglIsRenderbuffer(GLuint renderbuffer) {PRECALL;return glIsRenderbuffer(renderbuffer);POSTCALL;}
1451 //GLboolean wrapglUnmapBuffer(GLenum target) {PRECALL;return glUnmapBuffer(target);POSTCALL;}
1452 GLenum wrapglCheckFramebufferStatus(GLenum target) {PRECALL;return glCheckFramebufferStatus(target);POSTCALL;}
1453 GLenum wrapglGetError(void) {PRECALL;return glGetError();POSTCALL;}
1454 GLuint wrapglCreateProgram(void) {PRECALL;return glCreateProgram();POSTCALL;}
1455 GLuint wrapglCreateShader(GLenum shaderType) {PRECALL;return glCreateShader(shaderType);POSTCALL;}
1456 //GLuint wrapglGetHandle(GLenum pname) {PRECALL;return glGetHandle(pname);POSTCALL;}
1457 GLint wrapglGetAttribLocation(GLuint programObj, const GLchar *name) {PRECALL;return glGetAttribLocation(programObj, name);POSTCALL;}
1458 GLint wrapglGetUniformLocation(GLuint programObj, const GLchar *name) {PRECALL;return glGetUniformLocation(programObj, name);POSTCALL;}
1459 //GLvoid* wrapglMapBuffer(GLenum target, GLenum access) {PRECALL;return glMapBuffer(target, access);POSTCALL;}
1460 const GLubyte* wrapglGetString(GLenum name) {PRECALL;return (const GLubyte*)glGetString(name);POSTCALL;}
1461 void wrapglActiveStencilFace(GLenum e) {PRECALL;Con_Printf("glActiveStencilFace(e)\n");POSTCALL;}
1462 void wrapglActiveTexture(GLenum e) {PRECALL;glActiveTexture(e);POSTCALL;}
1463 void wrapglAlphaFunc(GLenum func, GLclampf ref) {PRECALL;Con_Printf("glAlphaFunc(func, ref)\n");POSTCALL;}
1464 void wrapglArrayElement(GLint i) {PRECALL;Con_Printf("glArrayElement(i)\n");POSTCALL;}
1465 void wrapglAttachShader(GLuint containerObj, GLuint obj) {PRECALL;glAttachShader(containerObj, obj);POSTCALL;}
1466 //void wrapglBegin(GLenum mode) {PRECALL;Con_Printf("glBegin(mode)\n");POSTCALL;}
1467 //void wrapglBeginQuery(GLenum target, GLuint qid) {PRECALL;glBeginQuery(target, qid);POSTCALL;}
1468 void wrapglBindAttribLocation(GLuint programObj, GLuint index, const GLchar *name) {PRECALL;glBindAttribLocation(programObj, index, name);POSTCALL;}
1469 //void wrapglBindFragDataLocation(GLuint programObj, GLuint index, const GLchar *name) {PRECALL;glBindFragDataLocation(programObj, index, name);POSTCALL;}
1470 void wrapglBindBuffer(GLenum target, GLuint buffer) {PRECALL;glBindBuffer(target, buffer);POSTCALL;}
1471 void wrapglBindFramebuffer(GLenum target, GLuint framebuffer) {PRECALL;glBindFramebuffer(target, framebuffer);POSTCALL;}
1472 void wrapglBindRenderbuffer(GLenum target, GLuint renderbuffer) {PRECALL;glBindRenderbuffer(target, renderbuffer);POSTCALL;}
1473 void wrapglBindTexture(GLenum target, GLuint texture) {PRECALL;glBindTexture(target, texture);POSTCALL;}
1474 void wrapglBlendEquation(GLenum e) {PRECALL;glBlendEquation(e);POSTCALL;}
1475 void wrapglBlendFunc(GLenum sfactor, GLenum dfactor) {PRECALL;glBlendFunc(sfactor, dfactor);POSTCALL;}
1476 void wrapglBufferData(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) {PRECALL;glBufferData(target, size, data, usage);POSTCALL;}
1477 void wrapglBufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) {PRECALL;glBufferSubData(target, offset, size, data);POSTCALL;}
1478 void wrapglClear(GLbitfield mask) {PRECALL;glClear(mask);POSTCALL;}
1479 void wrapglClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {PRECALL;glClearColor(red, green, blue, alpha);POSTCALL;}
1480 void wrapglClearDepth(GLclampd depth) {PRECALL;/*Con_Printf("glClearDepth(%f)\n", depth);glClearDepthf((float)depth);*/POSTCALL;}
1481 void wrapglClearStencil(GLint s) {PRECALL;glClearStencil(s);POSTCALL;}
1482 void wrapglClientActiveTexture(GLenum target) {PRECALL;Con_Printf("glClientActiveTexture(target)\n");POSTCALL;}
1483 void wrapglColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {PRECALL;Con_Printf("glColor4f(red, green, blue, alpha)\n");POSTCALL;}
1484 void wrapglColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) {PRECALL;Con_Printf("glColor4ub(red, green, blue, alpha)\n");POSTCALL;}
1485 void wrapglColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {PRECALL;glColorMask(red, green, blue, alpha);POSTCALL;}
1486 void wrapglColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) {PRECALL;Con_Printf("glColorPointer(size, type, stride, ptr)\n");POSTCALL;}
1487 void wrapglCompileShader(GLuint shaderObj) {PRECALL;glCompileShader(shaderObj);POSTCALL;}
1488 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;}
1489 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;}
1490 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;}
1491 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;}
1492 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;}
1493 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;}
1494 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;}
1495 void wrapglCullFace(GLenum mode) {PRECALL;glCullFace(mode);POSTCALL;}
1496 void wrapglDeleteBuffers(GLsizei n, const GLuint *buffers) {PRECALL;glDeleteBuffers(n, buffers);POSTCALL;}
1497 void wrapglDeleteFramebuffers(GLsizei n, const GLuint *framebuffers) {PRECALL;glDeleteFramebuffers(n, framebuffers);POSTCALL;}
1498 void wrapglDeleteShader(GLuint obj) {PRECALL;glDeleteShader(obj);POSTCALL;}
1499 void wrapglDeleteProgram(GLuint obj) {PRECALL;glDeleteProgram(obj);POSTCALL;}
1500 //void wrapglDeleteQueries(GLsizei n, const GLuint *ids) {PRECALL;glDeleteQueries(n, ids);POSTCALL;}
1501 void wrapglDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) {PRECALL;glDeleteRenderbuffers(n, renderbuffers);POSTCALL;}
1502 void wrapglDeleteTextures(GLsizei n, const GLuint *textures) {PRECALL;glDeleteTextures(n, textures);POSTCALL;}
1503 void wrapglDepthFunc(GLenum func) {PRECALL;glDepthFunc(func);POSTCALL;}
1504 void wrapglDepthMask(GLboolean flag) {PRECALL;glDepthMask(flag);POSTCALL;}
1505 //void wrapglDepthRange(GLclampd near_val, GLclampd far_val) {PRECALL;glDepthRangef((float)near_val, (float)far_val);POSTCALL;}
1506 void wrapglDepthRangef(GLclampf near_val, GLclampf far_val) {PRECALL;glDepthRangef(near_val, far_val);POSTCALL;}
1507 void wrapglDetachShader(GLuint containerObj, GLuint attachedObj) {PRECALL;glDetachShader(containerObj, attachedObj);POSTCALL;}
1508 void wrapglDisable(GLenum cap) {PRECALL;glDisable(cap);POSTCALL;}
1509 void wrapglDisableClientState(GLenum cap) {PRECALL;Con_Printf("glDisableClientState(cap)\n");POSTCALL;}
1510 void wrapglDisableVertexAttribArray(GLuint index) {PRECALL;glDisableVertexAttribArray(index);POSTCALL;}
1511 void wrapglDrawArrays(GLenum mode, GLint first, GLsizei count) {PRECALL;glDrawArrays(mode, first, count);POSTCALL;}
1512 void wrapglDrawBuffer(GLenum mode) {PRECALL;Con_Printf("glDrawBuffer(mode)\n");POSTCALL;}
1513 void wrapglDrawBuffers(GLsizei n, const GLenum *bufs) {PRECALL;Con_Printf("glDrawBuffers(n, bufs)\n");POSTCALL;}
1514 void wrapglDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {PRECALL;glDrawElements(mode, count, type, indices);POSTCALL;}
1515 //void wrapglDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) {PRECALL;glDrawRangeElements(mode, start, end, count, type, indices);POSTCALL;}
1516 //void wrapglDrawRangeElementsEXT(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) {PRECALL;glDrawRangeElements(mode, start, end, count, type, indices);POSTCALL;}
1517 void wrapglEnable(GLenum cap) {PRECALL;glEnable(cap);POSTCALL;}
1518 void wrapglEnableClientState(GLenum cap) {PRECALL;Con_Printf("glEnableClientState(cap)\n");POSTCALL;}
1519 void wrapglEnableVertexAttribArray(GLuint index) {PRECALL;glEnableVertexAttribArray(index);POSTCALL;}
1520 //void wrapglEnd(void) {PRECALL;Con_Printf("glEnd()\n");POSTCALL;}
1521 //void wrapglEndQuery(GLenum target) {PRECALL;glEndQuery(target);POSTCALL;}
1522 void wrapglFinish(void) {PRECALL;glFinish();POSTCALL;}
1523 void wrapglFlush(void) {PRECALL;glFlush();POSTCALL;}
1524 void wrapglFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {PRECALL;glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);POSTCALL;}
1525 void wrapglFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {PRECALL;glFramebufferTexture2D(target, attachment, textarget, texture, level);POSTCALL;}
1526 void wrapglFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) {PRECALL;Con_Printf("glFramebufferTexture3D()\n");POSTCALL;}
1527 void wrapglGenBuffers(GLsizei n, GLuint *buffers) {PRECALL;glGenBuffers(n, buffers);POSTCALL;}
1528 void wrapglGenFramebuffers(GLsizei n, GLuint *framebuffers) {PRECALL;glGenFramebuffers(n, framebuffers);POSTCALL;}
1529 //void wrapglGenQueries(GLsizei n, GLuint *ids) {PRECALL;glGenQueries(n, ids);POSTCALL;}
1530 void wrapglGenRenderbuffers(GLsizei n, GLuint *renderbuffers) {PRECALL;glGenRenderbuffers(n, renderbuffers);POSTCALL;}
1531 void wrapglGenTextures(GLsizei n, GLuint *textures) {PRECALL;glGenTextures(n, textures);POSTCALL;}
1532 void wrapglGenerateMipmap(GLenum target) {PRECALL;glGenerateMipmap(target);POSTCALL;}
1533 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;}
1534 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;}
1535 void wrapglGetAttachedShaders(GLuint containerObj, GLsizei maxCount, GLsizei *count, GLuint *obj) {PRECALL;glGetAttachedShaders(containerObj, maxCount, count, obj);POSTCALL;}
1536 void wrapglGetBooleanv(GLenum pname, GLboolean *params) {PRECALL;glGetBooleanv(pname, params);POSTCALL;}
1537 void wrapglGetCompressedTexImage(GLenum target, GLint lod, void *img) {PRECALL;Con_Printf("glGetCompressedTexImage(target, lod, img)\n");POSTCALL;}
1538 void wrapglGetDoublev(GLenum pname, GLdouble *params) {PRECALL;Con_Printf("glGetDoublev(pname, params)\n");POSTCALL;}
1539 void wrapglGetFloatv(GLenum pname, GLfloat *params) {PRECALL;glGetFloatv(pname, params);POSTCALL;}
1540 void wrapglGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params) {PRECALL;glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);POSTCALL;}
1541 void wrapglGetShaderInfoLog(GLuint obj, GLsizei maxLength, GLsizei *length, GLchar *infoLog) {PRECALL;glGetShaderInfoLog(obj, maxLength, length, infoLog);POSTCALL;}
1542 void wrapglGetProgramInfoLog(GLuint obj, GLsizei maxLength, GLsizei *length, GLchar *infoLog) {PRECALL;glGetProgramInfoLog(obj, maxLength, length, infoLog);POSTCALL;}
1543 void wrapglGetIntegerv(GLenum pname, GLint *params) {PRECALL;glGetIntegerv(pname, params);POSTCALL;}
1544 void wrapglGetShaderiv(GLuint obj, GLenum pname, GLint *params) {PRECALL;glGetShaderiv(obj, pname, params);POSTCALL;}
1545 void wrapglGetProgramiv(GLuint obj, GLenum pname, GLint *params) {PRECALL;glGetProgramiv(obj, pname, params);POSTCALL;}
1546 //void wrapglGetQueryObjectiv(GLuint qid, GLenum pname, GLint *params) {PRECALL;glGetQueryObjectiv(qid, pname, params);POSTCALL;}
1547 //void wrapglGetQueryObjectuiv(GLuint qid, GLenum pname, GLuint *params) {PRECALL;glGetQueryObjectuiv(qid, pname, params);POSTCALL;}
1548 //void wrapglGetQueryiv(GLenum target, GLenum pname, GLint *params) {PRECALL;glGetQueryiv(target, pname, params);POSTCALL;}
1549 void wrapglGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params) {PRECALL;glGetRenderbufferParameteriv(target, pname, params);POSTCALL;}
1550 void wrapglGetShaderSource(GLuint obj, GLsizei maxLength, GLsizei *length, GLchar *source) {PRECALL;glGetShaderSource(obj, maxLength, length, source);POSTCALL;}
1551 void wrapglGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels) {PRECALL;Con_Printf("glGetTexImage(target, level, format, type, pixels)\n");POSTCALL;}
1552 void wrapglGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params) {PRECALL;Con_Printf("glGetTexLevelParameterfv(target, level, pname, params)\n");POSTCALL;}
1553 void wrapglGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) {PRECALL;Con_Printf("glGetTexLevelParameteriv(target, level, pname, params)\n");POSTCALL;}
1554 void wrapglGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) {PRECALL;glGetTexParameterfv(target, pname, params);POSTCALL;}
1555 void wrapglGetTexParameteriv(GLenum target, GLenum pname, GLint *params) {PRECALL;glGetTexParameteriv(target, pname, params);POSTCALL;}
1556 void wrapglGetUniformfv(GLuint programObj, GLint location, GLfloat *params) {PRECALL;glGetUniformfv(programObj, location, params);POSTCALL;}
1557 void wrapglGetUniformiv(GLuint programObj, GLint location, GLint *params) {PRECALL;glGetUniformiv(programObj, location, params);POSTCALL;}
1558 void wrapglHint(GLenum target, GLenum mode) {PRECALL;glHint(target, mode);POSTCALL;}
1559 void wrapglLineWidth(GLfloat width) {PRECALL;glLineWidth(width);POSTCALL;}
1560 void wrapglLinkProgram(GLuint programObj) {PRECALL;glLinkProgram(programObj);POSTCALL;}
1561 void wrapglLoadIdentity(void) {PRECALL;Con_Printf("glLoadIdentity()\n");POSTCALL;}
1562 void wrapglLoadMatrixf(const GLfloat *m) {PRECALL;Con_Printf("glLoadMatrixf(m)\n");POSTCALL;}
1563 void wrapglMatrixMode(GLenum mode) {PRECALL;Con_Printf("glMatrixMode(mode)\n");POSTCALL;}
1564 void wrapglMultiTexCoord1f(GLenum target, GLfloat s) {PRECALL;Con_Printf("glMultiTexCoord1f(target, s)\n");POSTCALL;}
1565 void wrapglMultiTexCoord2f(GLenum target, GLfloat s, GLfloat t) {PRECALL;Con_Printf("glMultiTexCoord2f(target, s, t)\n");POSTCALL;}
1566 void wrapglMultiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r) {PRECALL;Con_Printf("glMultiTexCoord3f(target, s, t, r)\n");POSTCALL;}
1567 void wrapglMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {PRECALL;Con_Printf("glMultiTexCoord4f(target, s, t, r, q)\n");POSTCALL;}
1568 void wrapglNormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr) {PRECALL;Con_Printf("glNormalPointer(type, stride, ptr)\n");POSTCALL;}
1569 void wrapglPixelStorei(GLenum pname, GLint param) {PRECALL;glPixelStorei(pname, param);POSTCALL;}
1570 void wrapglPointSize(GLfloat size) {PRECALL;Con_Printf("glPointSize(size)\n");POSTCALL;}
1571 //void wrapglPolygonMode(GLenum face, GLenum mode) {PRECALL;Con_Printf("glPolygonMode(face, mode)\n");POSTCALL;}
1572 void wrapglPolygonOffset(GLfloat factor, GLfloat units) {PRECALL;glPolygonOffset(factor, units);POSTCALL;}
1573 void wrapglPolygonStipple(const GLubyte *mask) {PRECALL;Con_Printf("glPolygonStipple(mask)\n");POSTCALL;}
1574 void wrapglReadBuffer(GLenum mode) {PRECALL;Con_Printf("glReadBuffer(mode)\n");POSTCALL;}
1575 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;}
1576 void wrapglRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {PRECALL;glRenderbufferStorage(target, internalformat, width, height);POSTCALL;}
1577 void wrapglScissor(GLint x, GLint y, GLsizei width, GLsizei height) {PRECALL;glScissor(x, y, width, height);POSTCALL;}
1578 void wrapglShaderSource(GLuint shaderObj, GLsizei count, const GLchar **string, const GLint *length) {PRECALL;glShaderSource(shaderObj, count, string, length);POSTCALL;}
1579 void wrapglStencilFunc(GLenum func, GLint ref, GLuint mask) {PRECALL;glStencilFunc(func, ref, mask);POSTCALL;}
1580 void wrapglStencilFuncSeparate(GLenum func1, GLenum func2, GLint ref, GLuint mask) {PRECALL;Con_Printf("glStencilFuncSeparate(func1, func2, ref, mask)\n");POSTCALL;}
1581 void wrapglStencilMask(GLuint mask) {PRECALL;glStencilMask(mask);POSTCALL;}
1582 void wrapglStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {PRECALL;glStencilOp(fail, zfail, zpass);POSTCALL;}
1583 void wrapglStencilOpSeparate(GLenum e1, GLenum e2, GLenum e3, GLenum e4) {PRECALL;Con_Printf("glStencilOpSeparate(e1, e2, e3, e4)\n");POSTCALL;}
1584 void wrapglTexCoord1f(GLfloat s) {PRECALL;Con_Printf("glTexCoord1f(s)\n");POSTCALL;}
1585 void wrapglTexCoord2f(GLfloat s, GLfloat t) {PRECALL;Con_Printf("glTexCoord2f(s, t)\n");POSTCALL;}
1586 void wrapglTexCoord3f(GLfloat s, GLfloat t, GLfloat r) {PRECALL;Con_Printf("glTexCoord3f(s, t, r)\n");POSTCALL;}
1587 void wrapglTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) {PRECALL;Con_Printf("glTexCoord4f(s, t, r, q)\n");POSTCALL;}
1588 void wrapglTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) {PRECALL;Con_Printf("glTexCoordPointer(size, type, stride, ptr)\n");POSTCALL;}
1589 void wrapglTexEnvf(GLenum target, GLenum pname, GLfloat param) {PRECALL;Con_Printf("glTexEnvf(target, pname, param)\n");POSTCALL;}
1590 void wrapglTexEnvfv(GLenum target, GLenum pname, const GLfloat *params) {PRECALL;Con_Printf("glTexEnvfv(target, pname, params)\n");POSTCALL;}
1591 void wrapglTexEnvi(GLenum target, GLenum pname, GLint param) {PRECALL;Con_Printf("glTexEnvi(target, pname, param)\n");POSTCALL;}
1592 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;}
1593 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;}
1594 void wrapglTexParameterf(GLenum target, GLenum pname, GLfloat param) {PRECALL;glTexParameterf(target, pname, param);POSTCALL;}
1595 void wrapglTexParameterfv(GLenum target, GLenum pname, GLfloat *params) {PRECALL;glTexParameterfv(target, pname, params);POSTCALL;}
1596 void wrapglTexParameteri(GLenum target, GLenum pname, GLint param) {PRECALL;glTexParameteri(target, pname, param);POSTCALL;}
1597 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;}
1598 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;}
1599 void wrapglUniform1f(GLint location, GLfloat v0) {PRECALL;glUniform1f(location, v0);POSTCALL;}
1600 void wrapglUniform1fv(GLint location, GLsizei count, const GLfloat *value) {PRECALL;glUniform1fv(location, count, value);POSTCALL;}
1601 void wrapglUniform1i(GLint location, GLint v0) {PRECALL;glUniform1i(location, v0);POSTCALL;}
1602 void wrapglUniform1iv(GLint location, GLsizei count, const GLint *value) {PRECALL;glUniform1iv(location, count, value);POSTCALL;}
1603 void wrapglUniform2f(GLint location, GLfloat v0, GLfloat v1) {PRECALL;glUniform2f(location, v0, v1);POSTCALL;}
1604 void wrapglUniform2fv(GLint location, GLsizei count, const GLfloat *value) {PRECALL;glUniform2fv(location, count, value);POSTCALL;}
1605 void wrapglUniform2i(GLint location, GLint v0, GLint v1) {PRECALL;glUniform2i(location, v0, v1);POSTCALL;}
1606 void wrapglUniform2iv(GLint location, GLsizei count, const GLint *value) {PRECALL;glUniform2iv(location, count, value);POSTCALL;}
1607 void wrapglUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {PRECALL;glUniform3f(location, v0, v1, v2);POSTCALL;}
1608 void wrapglUniform3fv(GLint location, GLsizei count, const GLfloat *value) {PRECALL;glUniform3fv(location, count, value);POSTCALL;}
1609 void wrapglUniform3i(GLint location, GLint v0, GLint v1, GLint v2) {PRECALL;glUniform3i(location, v0, v1, v2);POSTCALL;}
1610 void wrapglUniform3iv(GLint location, GLsizei count, const GLint *value) {PRECALL;glUniform3iv(location, count, value);POSTCALL;}
1611 void wrapglUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {PRECALL;glUniform4f(location, v0, v1, v2, v3);POSTCALL;}
1612 void wrapglUniform4fv(GLint location, GLsizei count, const GLfloat *value) {PRECALL;glUniform4fv(location, count, value);POSTCALL;}
1613 void wrapglUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {PRECALL;glUniform4i(location, v0, v1, v2, v3);POSTCALL;}
1614 void wrapglUniform4iv(GLint location, GLsizei count, const GLint *value) {PRECALL;glUniform4iv(location, count, value);POSTCALL;}
1615 void wrapglUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {PRECALL;glUniformMatrix2fv(location, count, transpose, value);POSTCALL;}
1616 void wrapglUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {PRECALL;glUniformMatrix3fv(location, count, transpose, value);POSTCALL;}
1617 void wrapglUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {PRECALL;glUniformMatrix4fv(location, count, transpose, value);POSTCALL;}
1618 void wrapglUseProgram(GLuint programObj) {PRECALL;glUseProgram(programObj);POSTCALL;}
1619 void wrapglValidateProgram(GLuint programObj) {PRECALL;glValidateProgram(programObj);POSTCALL;}
1620 void wrapglVertex2f(GLfloat x, GLfloat y) {PRECALL;Con_Printf("glVertex2f(x, y)\n");POSTCALL;}
1621 void wrapglVertex3f(GLfloat x, GLfloat y, GLfloat z) {PRECALL;Con_Printf("glVertex3f(x, y, z)\n");POSTCALL;}
1622 void wrapglVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {PRECALL;Con_Printf("glVertex4f(x, y, z, w)\n");POSTCALL;}
1623 void wrapglVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) {PRECALL;glVertexAttribPointer(index, size, type, normalized, stride, pointer);POSTCALL;}
1624 void wrapglVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) {PRECALL;Con_Printf("glVertexPointer(size, type, stride, ptr)\n");POSTCALL;}
1625 void wrapglViewport(GLint x, GLint y, GLsizei width, GLsizei height) {PRECALL;glViewport(x, y, width, height);POSTCALL;}
1626 void wrapglVertexAttrib1f(GLuint index, GLfloat v0) {PRECALL;glVertexAttrib1f(index, v0);POSTCALL;}
1627 //void wrapglVertexAttrib1s(GLuint index, GLshort v0) {PRECALL;glVertexAttrib1s(index, v0);POSTCALL;}
1628 //void wrapglVertexAttrib1d(GLuint index, GLdouble v0) {PRECALL;glVertexAttrib1d(index, v0);POSTCALL;}
1629 void wrapglVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {PRECALL;glVertexAttrib2f(index, v0, v1);POSTCALL;}
1630 //void wrapglVertexAttrib2s(GLuint index, GLshort v0, GLshort v1) {PRECALL;glVertexAttrib2s(index, v0, v1);POSTCALL;}
1631 //void wrapglVertexAttrib2d(GLuint index, GLdouble v0, GLdouble v1) {PRECALL;glVertexAttrib2d(index, v0, v1);POSTCALL;}
1632 void wrapglVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {PRECALL;glVertexAttrib3f(index, v0, v1, v2);POSTCALL;}
1633 //void wrapglVertexAttrib3s(GLuint index, GLshort v0, GLshort v1, GLshort v2) {PRECALL;glVertexAttrib3s(index, v0, v1, v2);POSTCALL;}
1634 //void wrapglVertexAttrib3d(GLuint index, GLdouble v0, GLdouble v1, GLdouble v2) {PRECALL;glVertexAttrib3d(index, v0, v1, v2);POSTCALL;}
1635 void wrapglVertexAttrib4f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {PRECALL;glVertexAttrib4f(index, v0, v1, v2, v3);POSTCALL;}
1636 //void wrapglVertexAttrib4s(GLuint index, GLshort v0, GLshort v1, GLshort v2, GLshort v3) {PRECALL;glVertexAttrib4s(index, v0, v1, v2, v3);POSTCALL;}
1637 //void wrapglVertexAttrib4d(GLuint index, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3) {PRECALL;glVertexAttrib4d(index, v0, v1, v2, v3);POSTCALL;}
1638 //void wrapglVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) {PRECALL;glVertexAttrib4Nub(index, x, y, z, w);POSTCALL;}
1639 void wrapglVertexAttrib1fv(GLuint index, const GLfloat *v) {PRECALL;glVertexAttrib1fv(index, v);POSTCALL;}
1640 //void wrapglVertexAttrib1sv(GLuint index, const GLshort *v) {PRECALL;glVertexAttrib1sv(index, v);POSTCALL;}
1641 //void wrapglVertexAttrib1dv(GLuint index, const GLdouble *v) {PRECALL;glVertexAttrib1dv(index, v);POSTCALL;}
1642 void wrapglVertexAttrib2fv(GLuint index, const GLfloat *v) {PRECALL;glVertexAttrib2fv(index, v);POSTCALL;}
1643 //void wrapglVertexAttrib2sv(GLuint index, const GLshort *v) {PRECALL;glVertexAttrib2sv(index, v);POSTCALL;}
1644 //void wrapglVertexAttrib2dv(GLuint index, const GLdouble *v) {PRECALL;glVertexAttrib2dv(index, v);POSTCALL;}
1645 void wrapglVertexAttrib3fv(GLuint index, const GLfloat *v) {PRECALL;glVertexAttrib3fv(index, v);POSTCALL;}
1646 //void wrapglVertexAttrib3sv(GLuint index, const GLshort *v) {PRECALL;glVertexAttrib3sv(index, v);POSTCALL;}
1647 //void wrapglVertexAttrib3dv(GLuint index, const GLdouble *v) {PRECALL;glVertexAttrib3dv(index, v);POSTCALL;}
1648 void wrapglVertexAttrib4fv(GLuint index, const GLfloat *v) {PRECALL;glVertexAttrib4fv(index, v);POSTCALL;}
1649 //void wrapglVertexAttrib4sv(GLuint index, const GLshort *v) {PRECALL;glVertexAttrib4sv(index, v);POSTCALL;}
1650 //void wrapglVertexAttrib4dv(GLuint index, const GLdouble *v) {PRECALL;glVertexAttrib4dv(index, v);POSTCALL;}
1651 //void wrapglVertexAttrib4iv(GLuint index, const GLint *v) {PRECALL;glVertexAttrib4iv(index, v);POSTCALL;}
1652 //void wrapglVertexAttrib4bv(GLuint index, const GLbyte *v) {PRECALL;glVertexAttrib4bv(index, v);POSTCALL;}
1653 //void wrapglVertexAttrib4ubv(GLuint index, const GLubyte *v) {PRECALL;glVertexAttrib4ubv(index, v);POSTCALL;}
1654 //void wrapglVertexAttrib4usv(GLuint index, const GLushort *v) {PRECALL;glVertexAttrib4usv(index, GLushort v);POSTCALL;}
1655 //void wrapglVertexAttrib4uiv(GLuint index, const GLuint *v) {PRECALL;glVertexAttrib4uiv(index, v);POSTCALL;}
1656 //void wrapglVertexAttrib4Nbv(GLuint index, const GLbyte *v) {PRECALL;glVertexAttrib4Nbv(index, v);POSTCALL;}
1657 //void wrapglVertexAttrib4Nsv(GLuint index, const GLshort *v) {PRECALL;glVertexAttrib4Nsv(index, v);POSTCALL;}
1658 //void wrapglVertexAttrib4Niv(GLuint index, const GLint *v) {PRECALL;glVertexAttrib4Niv(index, v);POSTCALL;}
1659 //void wrapglVertexAttrib4Nubv(GLuint index, const GLubyte *v) {PRECALL;glVertexAttrib4Nubv(index, v);POSTCALL;}
1660 //void wrapglVertexAttrib4Nusv(GLuint index, const GLushort *v) {PRECALL;glVertexAttrib4Nusv(index, GLushort v);POSTCALL;}
1661 //void wrapglVertexAttrib4Nuiv(GLuint index, const GLuint *v) {PRECALL;glVertexAttrib4Nuiv(index, v);POSTCALL;}
1662 //void wrapglGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) {PRECALL;glGetVertexAttribdv(index, pname, params);POSTCALL;}
1663 void wrapglGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params) {PRECALL;glGetVertexAttribfv(index, pname, params);POSTCALL;}
1664 void wrapglGetVertexAttribiv(GLuint index, GLenum pname, GLint *params) {PRECALL;glGetVertexAttribiv(index, pname, params);POSTCALL;}
1665 void wrapglGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer) {PRECALL;glGetVertexAttribPointerv(index, pname, pointer);POSTCALL;}
1666 #endif
1667
1668 #if SDL_MAJOR_VERSION == 1
1669 #define SDL_GL_ExtensionSupported(x) (strstr(gl_extensions, x) || strstr(gl_platformextensions, x))
1670 #endif
1671
1672 void GLES_Init(void)
1673 {
1674 #ifndef qglClear
1675         qglIsBufferARB = wrapglIsBuffer;
1676         qglIsEnabled = wrapglIsEnabled;
1677         qglIsFramebufferEXT = wrapglIsFramebuffer;
1678 //      qglIsQueryARB = wrapglIsQuery;
1679         qglIsRenderbufferEXT = wrapglIsRenderbuffer;
1680 //      qglUnmapBufferARB = wrapglUnmapBuffer;
1681         qglCheckFramebufferStatus = wrapglCheckFramebufferStatus;
1682         qglGetError = wrapglGetError;
1683         qglCreateProgram = wrapglCreateProgram;
1684         qglCreateShader = wrapglCreateShader;
1685 //      qglGetHandleARB = wrapglGetHandle;
1686         qglGetAttribLocation = wrapglGetAttribLocation;
1687         qglGetUniformLocation = wrapglGetUniformLocation;
1688 //      qglMapBufferARB = wrapglMapBuffer;
1689         qglGetString = wrapglGetString;
1690 //      qglActiveStencilFaceEXT = wrapglActiveStencilFace;
1691         qglActiveTexture = wrapglActiveTexture;
1692         qglAlphaFunc = wrapglAlphaFunc;
1693         qglArrayElement = wrapglArrayElement;
1694         qglAttachShader = wrapglAttachShader;
1695 //      qglBegin = wrapglBegin;
1696 //      qglBeginQueryARB = wrapglBeginQuery;
1697         qglBindAttribLocation = wrapglBindAttribLocation;
1698 //      qglBindFragDataLocation = wrapglBindFragDataLocation;
1699         qglBindBufferARB = wrapglBindBuffer;
1700         qglBindFramebuffer = wrapglBindFramebuffer;
1701         qglBindRenderbuffer = wrapglBindRenderbuffer;
1702         qglBindTexture = wrapglBindTexture;
1703         qglBlendEquationEXT = wrapglBlendEquation;
1704         qglBlendFunc = wrapglBlendFunc;
1705         qglBufferDataARB = wrapglBufferData;
1706         qglBufferSubDataARB = wrapglBufferSubData;
1707         qglClear = wrapglClear;
1708         qglClearColor = wrapglClearColor;
1709         qglClearDepth = wrapglClearDepth;
1710         qglClearStencil = wrapglClearStencil;
1711         qglClientActiveTexture = wrapglClientActiveTexture;
1712         qglColor4f = wrapglColor4f;
1713         qglColor4ub = wrapglColor4ub;
1714         qglColorMask = wrapglColorMask;
1715         qglColorPointer = wrapglColorPointer;
1716         qglCompileShader = wrapglCompileShader;
1717         qglCompressedTexImage2DARB = wrapglCompressedTexImage2D;
1718         qglCompressedTexImage3DARB = wrapglCompressedTexImage3D;
1719         qglCompressedTexSubImage2DARB = wrapglCompressedTexSubImage2D;
1720         qglCompressedTexSubImage3DARB = wrapglCompressedTexSubImage3D;
1721         qglCopyTexImage2D = wrapglCopyTexImage2D;
1722         qglCopyTexSubImage2D = wrapglCopyTexSubImage2D;
1723         qglCopyTexSubImage3D = wrapglCopyTexSubImage3D;
1724         qglCullFace = wrapglCullFace;
1725         qglDeleteBuffersARB = wrapglDeleteBuffers;
1726         qglDeleteFramebuffers = wrapglDeleteFramebuffers;
1727         qglDeleteProgram = wrapglDeleteProgram;
1728         qglDeleteShader = wrapglDeleteShader;
1729 //      qglDeleteQueriesARB = wrapglDeleteQueries;
1730         qglDeleteRenderbuffers = wrapglDeleteRenderbuffers;
1731         qglDeleteTextures = wrapglDeleteTextures;
1732         qglDepthFunc = wrapglDepthFunc;
1733         qglDepthMask = wrapglDepthMask;
1734         qglDepthRangef = wrapglDepthRangef;
1735         qglDetachShader = wrapglDetachShader;
1736         qglDisable = wrapglDisable;
1737         qglDisableClientState = wrapglDisableClientState;
1738         qglDisableVertexAttribArray = wrapglDisableVertexAttribArray;
1739         qglDrawArrays = wrapglDrawArrays;
1740 //      qglDrawBuffer = wrapglDrawBuffer;
1741 //      qglDrawBuffersARB = wrapglDrawBuffers;
1742         qglDrawElements = wrapglDrawElements;
1743 //      qglDrawRangeElements = wrapglDrawRangeElements;
1744         qglEnable = wrapglEnable;
1745         qglEnableClientState = wrapglEnableClientState;
1746         qglEnableVertexAttribArray = wrapglEnableVertexAttribArray;
1747 //      qglEnd = wrapglEnd;
1748 //      qglEndQueryARB = wrapglEndQuery;
1749         qglFinish = wrapglFinish;
1750         qglFlush = wrapglFlush;
1751         qglFramebufferRenderbufferEXT = wrapglFramebufferRenderbuffer;
1752         qglFramebufferTexture2DEXT = wrapglFramebufferTexture2D;
1753         qglFramebufferTexture3DEXT = wrapglFramebufferTexture3D;
1754         qglGenBuffersARB = wrapglGenBuffers;
1755         qglGenFramebuffers = wrapglGenFramebuffers;
1756 //      qglGenQueriesARB = wrapglGenQueries;
1757         qglGenRenderbuffers = wrapglGenRenderbuffers;
1758         qglGenTextures = wrapglGenTextures;
1759         qglGenerateMipmapEXT = wrapglGenerateMipmap;
1760         qglGetActiveAttrib = wrapglGetActiveAttrib;
1761         qglGetActiveUniform = wrapglGetActiveUniform;
1762         qglGetAttachedShaders = wrapglGetAttachedShaders;
1763         qglGetBooleanv = wrapglGetBooleanv;
1764 //      qglGetCompressedTexImageARB = wrapglGetCompressedTexImage;
1765         qglGetDoublev = wrapglGetDoublev;
1766         qglGetFloatv = wrapglGetFloatv;
1767         qglGetFramebufferAttachmentParameterivEXT = wrapglGetFramebufferAttachmentParameteriv;
1768         qglGetProgramInfoLog = wrapglGetProgramInfoLog;
1769         qglGetShaderInfoLog = wrapglGetShaderInfoLog;
1770         qglGetIntegerv = wrapglGetIntegerv;
1771         qglGetShaderiv = wrapglGetShaderiv;
1772         qglGetProgramiv = wrapglGetProgramiv;
1773 //      qglGetQueryObjectivARB = wrapglGetQueryObjectiv;
1774 //      qglGetQueryObjectuivARB = wrapglGetQueryObjectuiv;
1775 //      qglGetQueryivARB = wrapglGetQueryiv;
1776         qglGetRenderbufferParameterivEXT = wrapglGetRenderbufferParameteriv;
1777         qglGetShaderSource = wrapglGetShaderSource;
1778         qglGetTexImage = wrapglGetTexImage;
1779         qglGetTexLevelParameterfv = wrapglGetTexLevelParameterfv;
1780         qglGetTexLevelParameteriv = wrapglGetTexLevelParameteriv;
1781         qglGetTexParameterfv = wrapglGetTexParameterfv;
1782         qglGetTexParameteriv = wrapglGetTexParameteriv;
1783         qglGetUniformfv = wrapglGetUniformfv;
1784         qglGetUniformiv = wrapglGetUniformiv;
1785         qglHint = wrapglHint;
1786         qglLineWidth = wrapglLineWidth;
1787         qglLinkProgram = wrapglLinkProgram;
1788         qglLoadIdentity = wrapglLoadIdentity;
1789         qglLoadMatrixf = wrapglLoadMatrixf;
1790         qglMatrixMode = wrapglMatrixMode;
1791         qglMultiTexCoord1f = wrapglMultiTexCoord1f;
1792         qglMultiTexCoord2f = wrapglMultiTexCoord2f;
1793         qglMultiTexCoord3f = wrapglMultiTexCoord3f;
1794         qglMultiTexCoord4f = wrapglMultiTexCoord4f;
1795         qglNormalPointer = wrapglNormalPointer;
1796         qglPixelStorei = wrapglPixelStorei;
1797         qglPointSize = wrapglPointSize;
1798 //      qglPolygonMode = wrapglPolygonMode;
1799         qglPolygonOffset = wrapglPolygonOffset;
1800 //      qglPolygonStipple = wrapglPolygonStipple;
1801         qglReadBuffer = wrapglReadBuffer;
1802         qglReadPixels = wrapglReadPixels;
1803         qglRenderbufferStorage = wrapglRenderbufferStorage;
1804         qglScissor = wrapglScissor;
1805         qglShaderSource = wrapglShaderSource;
1806         qglStencilFunc = wrapglStencilFunc;
1807         qglStencilFuncSeparate = wrapglStencilFuncSeparate;
1808         qglStencilMask = wrapglStencilMask;
1809         qglStencilOp = wrapglStencilOp;
1810         qglStencilOpSeparate = wrapglStencilOpSeparate;
1811         qglTexCoord1f = wrapglTexCoord1f;
1812         qglTexCoord2f = wrapglTexCoord2f;
1813         qglTexCoord3f = wrapglTexCoord3f;
1814         qglTexCoord4f = wrapglTexCoord4f;
1815         qglTexCoordPointer = wrapglTexCoordPointer;
1816         qglTexEnvf = wrapglTexEnvf;
1817         qglTexEnvfv = wrapglTexEnvfv;
1818         qglTexEnvi = wrapglTexEnvi;
1819         qglTexImage2D = wrapglTexImage2D;
1820         qglTexImage3D = wrapglTexImage3D;
1821         qglTexParameterf = wrapglTexParameterf;
1822         qglTexParameterfv = wrapglTexParameterfv;
1823         qglTexParameteri = wrapglTexParameteri;
1824         qglTexSubImage2D = wrapglTexSubImage2D;
1825         qglTexSubImage3D = wrapglTexSubImage3D;
1826         qglUniform1f = wrapglUniform1f;
1827         qglUniform1fv = wrapglUniform1fv;
1828         qglUniform1i = wrapglUniform1i;
1829         qglUniform1iv = wrapglUniform1iv;
1830         qglUniform2f = wrapglUniform2f;
1831         qglUniform2fv = wrapglUniform2fv;
1832         qglUniform2i = wrapglUniform2i;
1833         qglUniform2iv = wrapglUniform2iv;
1834         qglUniform3f = wrapglUniform3f;
1835         qglUniform3fv = wrapglUniform3fv;
1836         qglUniform3i = wrapglUniform3i;
1837         qglUniform3iv = wrapglUniform3iv;
1838         qglUniform4f = wrapglUniform4f;
1839         qglUniform4fv = wrapglUniform4fv;
1840         qglUniform4i = wrapglUniform4i;
1841         qglUniform4iv = wrapglUniform4iv;
1842         qglUniformMatrix2fv = wrapglUniformMatrix2fv;
1843         qglUniformMatrix3fv = wrapglUniformMatrix3fv;
1844         qglUniformMatrix4fv = wrapglUniformMatrix4fv;
1845         qglUseProgram = wrapglUseProgram;
1846         qglValidateProgram = wrapglValidateProgram;
1847         qglVertex2f = wrapglVertex2f;
1848         qglVertex3f = wrapglVertex3f;
1849         qglVertex4f = wrapglVertex4f;
1850         qglVertexAttribPointer = wrapglVertexAttribPointer;
1851         qglVertexPointer = wrapglVertexPointer;
1852         qglViewport = wrapglViewport;
1853         qglVertexAttrib1f = wrapglVertexAttrib1f;
1854 //      qglVertexAttrib1s = wrapglVertexAttrib1s;
1855 //      qglVertexAttrib1d = wrapglVertexAttrib1d;
1856         qglVertexAttrib2f = wrapglVertexAttrib2f;
1857 //      qglVertexAttrib2s = wrapglVertexAttrib2s;
1858 //      qglVertexAttrib2d = wrapglVertexAttrib2d;
1859         qglVertexAttrib3f = wrapglVertexAttrib3f;
1860 //      qglVertexAttrib3s = wrapglVertexAttrib3s;
1861 //      qglVertexAttrib3d = wrapglVertexAttrib3d;
1862         qglVertexAttrib4f = wrapglVertexAttrib4f;
1863 //      qglVertexAttrib4s = wrapglVertexAttrib4s;
1864 //      qglVertexAttrib4d = wrapglVertexAttrib4d;
1865 //      qglVertexAttrib4Nub = wrapglVertexAttrib4Nub;
1866         qglVertexAttrib1fv = wrapglVertexAttrib1fv;
1867 //      qglVertexAttrib1sv = wrapglVertexAttrib1sv;
1868 //      qglVertexAttrib1dv = wrapglVertexAttrib1dv;
1869         qglVertexAttrib2fv = wrapglVertexAttrib2fv;
1870 //      qglVertexAttrib2sv = wrapglVertexAttrib2sv;
1871 //      qglVertexAttrib2dv = wrapglVertexAttrib2dv;
1872         qglVertexAttrib3fv = wrapglVertexAttrib3fv;
1873 //      qglVertexAttrib3sv = wrapglVertexAttrib3sv;
1874 //      qglVertexAttrib3dv = wrapglVertexAttrib3dv;
1875         qglVertexAttrib4fv = wrapglVertexAttrib4fv;
1876 //      qglVertexAttrib4sv = wrapglVertexAttrib4sv;
1877 //      qglVertexAttrib4dv = wrapglVertexAttrib4dv;
1878 //      qglVertexAttrib4iv = wrapglVertexAttrib4iv;
1879 //      qglVertexAttrib4bv = wrapglVertexAttrib4bv;
1880 //      qglVertexAttrib4ubv = wrapglVertexAttrib4ubv;
1881 //      qglVertexAttrib4usv = wrapglVertexAttrib4usv;
1882 //      qglVertexAttrib4uiv = wrapglVertexAttrib4uiv;
1883 //      qglVertexAttrib4Nbv = wrapglVertexAttrib4Nbv;
1884 //      qglVertexAttrib4Nsv = wrapglVertexAttrib4Nsv;
1885 //      qglVertexAttrib4Niv = wrapglVertexAttrib4Niv;
1886 //      qglVertexAttrib4Nubv = wrapglVertexAttrib4Nubv;
1887 //      qglVertexAttrib4Nusv = wrapglVertexAttrib4Nusv;
1888 //      qglVertexAttrib4Nuiv = wrapglVertexAttrib4Nuiv;
1889 //      qglGetVertexAttribdv = wrapglGetVertexAttribdv;
1890         qglGetVertexAttribfv = wrapglGetVertexAttribfv;
1891         qglGetVertexAttribiv = wrapglGetVertexAttribiv;
1892         qglGetVertexAttribPointerv = wrapglGetVertexAttribPointerv;
1893 #endif
1894
1895         gl_renderer = (const char *)qglGetString(GL_RENDERER);
1896         gl_vendor = (const char *)qglGetString(GL_VENDOR);
1897         gl_version = (const char *)qglGetString(GL_VERSION);
1898         gl_extensions = (const char *)qglGetString(GL_EXTENSIONS);
1899         
1900         if (!gl_extensions)
1901                 gl_extensions = "";
1902         if (!gl_platformextensions)
1903                 gl_platformextensions = "";
1904         
1905         Con_Printf("GL_VENDOR: %s\n", gl_vendor);
1906         Con_Printf("GL_RENDERER: %s\n", gl_renderer);
1907         Con_Printf("GL_VERSION: %s\n", gl_version);
1908         Con_DPrintf("GL_EXTENSIONS: %s\n", gl_extensions);
1909         Con_DPrintf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions);
1910         
1911         // LordHavoc: report supported extensions
1912         Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions );
1913
1914         // GLES devices in general do not like GL_BGRA, so use GL_RGBA
1915         vid.forcetextype = TEXTYPE_RGBA;
1916         
1917         vid.support.gl20shaders = true;
1918         vid.support.amd_texture_texture4 = false;
1919         vid.support.arb_depth_texture = SDL_GL_ExtensionSupported("GL_OES_depth_texture") != 0; // renderbuffer used anyway on gles2?
1920         vid.support.arb_draw_buffers = false;
1921         vid.support.arb_multitexture = false;
1922         vid.support.arb_occlusion_query = false;
1923         vid.support.arb_shadow = false;
1924         vid.support.arb_texture_compression = false; // different (vendor-specific) formats than on desktop OpenGL...
1925         vid.support.arb_texture_cube_map = SDL_GL_ExtensionSupported("GL_OES_texture_cube_map") != 0;
1926         vid.support.arb_texture_env_combine = false;
1927         vid.support.arb_texture_gather = false;
1928         vid.support.arb_texture_non_power_of_two = strstr(gl_extensions, "GL_OES_texture_npot") != NULL;
1929         vid.support.arb_vertex_buffer_object = true; // GLES2 core
1930         vid.support.ati_separate_stencil = false;
1931         vid.support.ext_blend_minmax = false;
1932         vid.support.ext_blend_subtract = true; // GLES2 core
1933         vid.support.ext_blend_func_separate = true; // GLES2 core
1934         vid.support.ext_draw_range_elements = false;
1935
1936         /*      ELUAN:
1937                 Note: "In OS 2.1, the functions in GL_OES_framebuffer_object were not usable from the Java API.
1938                 Calling them just threw an exception. Android developer relations confirmed that they forgot to implement these. (yeah...)
1939                 It's apparently been fixed in 2.2, though I haven't tested."
1940         */
1941         vid.support.ext_framebuffer_object = false;//true;
1942
1943         vid.support.ext_packed_depth_stencil = false;
1944         vid.support.ext_stencil_two_side = false;
1945         vid.support.ext_texture_3d = SDL_GL_ExtensionSupported("GL_OES_texture_3D") != 0;
1946         vid.support.ext_texture_compression_s3tc = SDL_GL_ExtensionSupported("GL_EXT_texture_compression_s3tc") != 0;
1947         vid.support.ext_texture_edge_clamp = true; // GLES2 core
1948         vid.support.ext_texture_filter_anisotropic = false; // probably don't want to use it...
1949         vid.support.ext_texture_srgb = false;
1950
1951         // NOTE: On some devices, a value of 512 gives better FPS than the maximum.
1952         qglGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_2d);
1953
1954 #ifdef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
1955         if (vid.support.ext_texture_filter_anisotropic)
1956                 qglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, (GLint*)&vid.max_anisotropy);
1957 #endif
1958         if (vid.support.arb_texture_cube_map)
1959                 qglGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_cubemap);
1960 #ifdef GL_MAX_3D_TEXTURE_SIZE
1961         if (vid.support.ext_texture_3d)
1962                 qglGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_3d);
1963 #endif
1964         Con_Printf("GL_MAX_CUBE_MAP_TEXTURE_SIZE = %i\n", vid.maxtexturesize_cubemap);
1965         Con_Printf("GL_MAX_3D_TEXTURE_SIZE = %i\n", vid.maxtexturesize_3d);
1966         {
1967 #define GL_ALPHA_BITS                           0x0D55
1968 #define GL_RED_BITS                             0x0D52
1969 #define GL_GREEN_BITS                           0x0D53
1970 #define GL_BLUE_BITS                            0x0D54
1971 #define GL_DEPTH_BITS                           0x0D56
1972 #define GL_STENCIL_BITS                         0x0D57
1973                 int fb_r = -1, fb_g = -1, fb_b = -1, fb_a = -1, fb_d = -1, fb_s = -1;
1974                 qglGetIntegerv(GL_RED_BITS    , &fb_r);
1975                 qglGetIntegerv(GL_GREEN_BITS  , &fb_g);
1976                 qglGetIntegerv(GL_BLUE_BITS   , &fb_b);
1977                 qglGetIntegerv(GL_ALPHA_BITS  , &fb_a);
1978                 qglGetIntegerv(GL_DEPTH_BITS  , &fb_d);
1979                 qglGetIntegerv(GL_STENCIL_BITS, &fb_s);
1980                 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);
1981         }
1982
1983         // verify that cubemap textures are really supported
1984         if (vid.support.arb_texture_cube_map && vid.maxtexturesize_cubemap < 256)
1985                 vid.support.arb_texture_cube_map = false;
1986         
1987         // verify that 3d textures are really supported
1988         if (vid.support.ext_texture_3d && vid.maxtexturesize_3d < 32)
1989         {
1990                 vid.support.ext_texture_3d = false;
1991                 Con_Printf("GL_OES_texture_3d reported bogus GL_MAX_3D_TEXTURE_SIZE, disabled\n");
1992         }
1993
1994         vid.texunits = 4;
1995         vid.teximageunits = 8;
1996         vid.texarrayunits = 5;
1997         //qglGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&vid.texunits);
1998         qglGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, (GLint*)&vid.teximageunits);CHECKGLERROR
1999         //qglGetIntegerv(GL_MAX_TEXTURE_COORDS, (GLint*)&vid.texarrayunits);CHECKGLERROR
2000         vid.texunits = bound(1, vid.texunits, MAX_TEXTUREUNITS);
2001         vid.teximageunits = bound(1, vid.teximageunits, MAX_TEXTUREUNITS);
2002         vid.texarrayunits = bound(1, vid.texarrayunits, MAX_TEXTUREUNITS);
2003         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" : "");
2004         vid.renderpath = RENDERPATH_GLES2;
2005         vid.useinterleavedarrays = false;
2006         vid.sRGBcapable2D = false;
2007         vid.sRGBcapable3D = false;
2008
2009         // VorteX: set other info (maybe place them in VID_InitMode?)
2010         extern cvar_t gl_info_vendor;
2011         extern cvar_t gl_info_renderer;
2012         extern cvar_t gl_info_version;
2013         extern cvar_t gl_info_platform;
2014         extern cvar_t gl_info_driver;
2015         Cvar_SetQuick(&gl_info_vendor, gl_vendor);
2016         Cvar_SetQuick(&gl_info_renderer, gl_renderer);
2017         Cvar_SetQuick(&gl_info_version, gl_version);
2018         Cvar_SetQuick(&gl_info_platform, gl_platform ? gl_platform : "");
2019         Cvar_SetQuick(&gl_info_driver, gl_driver);
2020 }
2021 #endif
2022
2023 void *GL_GetProcAddress(const char *name)
2024 {
2025         void *p = NULL;
2026         p = SDL_GL_GetProcAddress(name);
2027         return p;
2028 }
2029
2030 static qboolean vid_sdl_initjoysticksystem = false;
2031
2032 void VID_Init (void)
2033 {
2034 #ifndef __IPHONEOS__
2035 #ifdef MACOSX
2036         Cvar_RegisterVariable(&apple_mouse_noaccel);
2037 #endif
2038 #endif
2039 #ifdef DP_MOBILETOUCH
2040         Cvar_SetValueQuick(&vid_touchscreen, 1);
2041 #endif
2042
2043 #ifdef SDL_R_RESTART
2044         R_RegisterModule("SDL", sdl_start, sdl_shutdown, sdl_newmap, NULL, NULL);
2045 #endif
2046
2047         if (SDL_Init(SDL_INIT_VIDEO) < 0)
2048                 Sys_Error ("Failed to init SDL video subsystem: %s", SDL_GetError());
2049         vid_sdl_initjoysticksystem = SDL_InitSubSystem(SDL_INIT_JOYSTICK) >= 0;
2050         if (vid_sdl_initjoysticksystem)
2051                 Con_Printf("Failed to init SDL joystick subsystem: %s\n", SDL_GetError());
2052         vid_isfullscreen = false;
2053 }
2054
2055 static int vid_sdljoystickindex = -1;
2056 void VID_EnableJoystick(qboolean enable)
2057 {
2058         int index = joy_enable.integer > 0 ? joy_index.integer : -1;
2059         int numsdljoysticks;
2060         qboolean success = false;
2061         int sharedcount = 0;
2062         int sdlindex = -1;
2063         sharedcount = VID_Shared_SetJoystick(index);
2064         if (index >= 0 && index < sharedcount)
2065                 success = true;
2066         sdlindex = index - sharedcount;
2067
2068         numsdljoysticks = SDL_NumJoysticks();
2069         if (sdlindex < 0 || sdlindex >= numsdljoysticks)
2070                 sdlindex = -1;
2071
2072         // update cvar containing count of XInput joysticks + SDL joysticks
2073         if (joy_detected.integer != sharedcount + numsdljoysticks)
2074                 Cvar_SetValueQuick(&joy_detected, sharedcount + numsdljoysticks);
2075
2076         if (vid_sdljoystickindex != sdlindex)
2077         {
2078                 vid_sdljoystickindex = sdlindex;
2079                 // close SDL joystick if active
2080                 if (vid_sdljoystick)
2081                         SDL_JoystickClose(vid_sdljoystick);
2082                 vid_sdljoystick = NULL;
2083                 if (sdlindex >= 0)
2084                 {
2085                         vid_sdljoystick = SDL_JoystickOpen(sdlindex);
2086                         if (vid_sdljoystick)
2087                         {
2088 #if SDL_MAJOR_VERSION == 1
2089                                 const char *joystickname = SDL_JoystickName(sdlindex);
2090 #else
2091                                 const char *joystickname = SDL_JoystickName(vid_sdljoystick);
2092 #endif
2093                                 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));
2094                         }
2095                         else
2096                         {
2097                                 Con_Printf("Joystick %i failed (SDL_JoystickOpen(%i) returned: %s)\n", index, sdlindex, SDL_GetError());
2098                                 sdlindex = -1;
2099                         }
2100                 }
2101         }
2102
2103         if (sdlindex >= 0)
2104                 success = true;
2105
2106         if (joy_active.integer != (success ? 1 : 0))
2107                 Cvar_SetValueQuick(&joy_active, success ? 1 : 0);
2108 }
2109
2110 #if SDL_MAJOR_VERSION == 1
2111 // set the icon (we dont use SDL here since it would be too much a PITA)
2112 #ifdef WIN32
2113 #include "resource.h"
2114 #include <SDL_syswm.h>
2115 static SDL_Surface *VID_WrapSDL_SetVideoMode(int screenwidth, int screenheight, int screenbpp, int screenflags)
2116 {
2117         SDL_Surface *screen = NULL;
2118         SDL_SysWMinfo info;
2119         HICON icon;
2120         SDL_WM_SetCaption( gamename, NULL );
2121         screen = SDL_SetVideoMode(screenwidth, screenheight, screenbpp, screenflags);
2122         if (screen)
2123         {
2124                 // get the HWND handle
2125                 SDL_VERSION( &info.version );
2126                 if (SDL_GetWMInfo(&info))
2127                 {
2128                         icon = LoadIcon( GetModuleHandle( NULL ), MAKEINTRESOURCE( IDI_ICON1 ) );
2129 #ifndef _W64 //If Windows 64bit data types don't exist
2130 #ifndef SetClassLongPtr
2131 #define SetClassLongPtr SetClassLong
2132 #endif
2133 #ifndef GCLP_HICON
2134 #define GCLP_HICON GCL_HICON
2135 #endif
2136 #ifndef LONG_PTR
2137 #define LONG_PTR LONG
2138 #endif
2139 #endif
2140                         SetClassLongPtr( info.window, GCLP_HICON, (LONG_PTR)icon );
2141                 }
2142         }
2143         return screen;
2144 }
2145 #elif defined(MACOSX)
2146 static SDL_Surface *VID_WrapSDL_SetVideoMode(int screenwidth, int screenheight, int screenbpp, int screenflags)
2147 {
2148         SDL_Surface *screen = NULL;
2149         SDL_WM_SetCaption( gamename, NULL );
2150         screen = SDL_SetVideoMode(screenwidth, screenheight, screenbpp, screenflags);
2151         // we don't use SDL_WM_SetIcon here because the icon in the .app should be used
2152         return screen;
2153 }
2154 #else
2155 // Adding the OS independent XPM version --blub
2156 #include "darkplaces.xpm"
2157 #include "nexuiz.xpm"
2158 #if SDL_MAJOR_VERSION == 1
2159 #if SDL_VIDEO_DRIVER_X11 && !SDL_VIDEO_DRIVER_QUARTZ
2160 #include <SDL_syswm.h>
2161 #endif
2162 #endif
2163 static SDL_Surface *icon = NULL;
2164 static SDL_Surface *VID_WrapSDL_SetVideoMode(int screenwidth, int screenheight, int screenbpp, int screenflags)
2165 {
2166         /*
2167          * Somewhat restricted XPM reader. Only supports XPMs saved by GIMP 2.4 at
2168          * default settings with less than 91 colors and transparency.
2169          */
2170
2171         int width, height, colors, isize, i, j;
2172         int thenone = -1;
2173         static SDL_Color palette[256];
2174         unsigned short palenc[256]; // store color id by char
2175         char *xpm;
2176         char **idata, *data;
2177         const SDL_version *version;
2178         SDL_Surface *screen = NULL;
2179
2180         if (icon)
2181                 SDL_FreeSurface(icon);
2182         icon = NULL;
2183         version = SDL_Linked_Version();
2184         // only use non-XPM icon support in SDL v1.3 and higher
2185         // SDL v1.2 does not support "smooth" transparency, and thus is better
2186         // off the xpm way
2187         if(version->major >= 2 || (version->major == 1 && version->minor >= 3))
2188         {
2189                 data = (char *) loadimagepixelsbgra("darkplaces-icon", false, false, false, NULL);
2190                 if(data)
2191                 {
2192                         unsigned int red = 0x00FF0000;
2193                         unsigned int green = 0x0000FF00;
2194                         unsigned int blue = 0x000000FF;
2195                         unsigned int alpha = 0xFF000000;
2196                         width = image_width;
2197                         height = image_height;
2198
2199                         // reallocate with malloc, as this is in tempmempool (do not want)
2200                         xpm = data;
2201                         data = (char *) malloc(width * height * 4);
2202                         memcpy(data, xpm, width * height * 4);
2203                         Mem_Free(xpm);
2204                         xpm = NULL;
2205
2206                         icon = SDL_CreateRGBSurface(SDL_SRCALPHA, width, height, 32, LittleLong(red), LittleLong(green), LittleLong(blue), LittleLong(alpha));
2207
2208                         if (icon)
2209                                 icon->pixels = data;
2210                         else
2211                         {
2212                                 Con_Printf(     "Failed to create surface for the window Icon!\n"
2213                                                 "%s\n", SDL_GetError());
2214                                 free(data);
2215                         }
2216                 }
2217         }
2218
2219         // we only get here if non-XPM icon was missing, or SDL version is not
2220         // sufficient for transparent non-XPM icons
2221         if(!icon)
2222         {
2223                 xpm = (char *) FS_LoadFile("darkplaces-icon.xpm", tempmempool, false, NULL);
2224                 idata = NULL;
2225                 if(xpm)
2226                         idata = XPM_DecodeString(xpm);
2227                 if(!idata)
2228                         idata = ENGINE_ICON;
2229                 if(xpm)
2230                         Mem_Free(xpm);
2231
2232                 data = idata[0];
2233
2234                 if(sscanf(data, "%i %i %i %i", &width, &height, &colors, &isize) == 4)
2235                 {
2236                         if(isize == 1)
2237                         {
2238                                 for(i = 0; i < colors; ++i)
2239                                 {
2240                                         unsigned int r, g, b;
2241                                         char idx;
2242
2243                                         if(sscanf(idata[i+1], "%c c #%02x%02x%02x", &idx, &r, &g, &b) != 4)
2244                                         {
2245                                                 char foo[2];
2246                                                 if(sscanf(idata[i+1], "%c c Non%1[e]", &idx, foo) != 2) // I take the DailyWTF credit for this. --div0
2247                                                         break;
2248                                                 else
2249                                                 {
2250                                                         palette[i].r = 255; // color key
2251                                                         palette[i].g = 0;
2252                                                         palette[i].b = 255;
2253                                                         thenone = i; // weeeee
2254                                                         palenc[(unsigned char) idx] = i;
2255                                                 }
2256                                         }
2257                                         else
2258                                         {
2259                                                 palette[i].r = r - (r == 255 && g == 0 && b == 255); // change 255/0/255 pink to 254/0/255 for color key
2260                                                 palette[i].g = g;
2261                                                 palette[i].b = b;
2262                                                 palenc[(unsigned char) idx] = i;
2263                                         }
2264                                 }
2265
2266                                 if (i == colors)
2267                                 {
2268                                         // allocate the image data
2269                                         data = (char*) malloc(width*height);
2270
2271                                         for(j = 0; j < height; ++j)
2272                                         {
2273                                                 for(i = 0; i < width; ++i)
2274                                                 {
2275                                                         // casting to the safest possible datatypes ^^
2276                                                         data[j * width + i] = palenc[((unsigned char*)idata[colors+j+1])[i]];
2277                                                 }
2278                                         }
2279
2280                                         if(icon != NULL)
2281                                         {
2282                                                 // SDL_FreeSurface should free the data too
2283                                                 // but for completeness' sake...
2284                                                 if(icon->flags & SDL_PREALLOC)
2285                                                 {
2286                                                         free(icon->pixels);
2287                                                         icon->pixels = NULL; // safety
2288                                                 }
2289                                                 SDL_FreeSurface(icon);
2290                                         }
2291
2292                                         icon = SDL_CreateRGBSurface(SDL_SRCCOLORKEY, width, height, 8, 0,0,0,0);// rmask, gmask, bmask, amask); no mask needed
2293                                         // 8 bit surfaces get an empty palette allocated according to the docs
2294                                         // so it's a palette image for sure :) no endian check necessary for the mask
2295
2296                                         if(icon)
2297                                         {
2298                                                 icon->pixels = data;
2299                                                 SDL_SetPalette(icon, SDL_PHYSPAL|SDL_LOGPAL, palette, 0, colors);
2300                                                 SDL_SetColorKey(icon, SDL_SRCCOLORKEY, thenone);
2301                                         }
2302                                         else
2303                                         {
2304                                                 Con_Printf(     "Failed to create surface for the window Icon!\n"
2305                                                                 "%s\n", SDL_GetError());
2306                                                 free(data);
2307                                         }
2308                                 }
2309                                 else
2310                                 {
2311                                         Con_Printf("This XPM's palette looks odd. Can't continue.\n");
2312                                 }
2313                         }
2314                         else
2315                         {
2316                                 // NOTE: Only 1-char colornames are supported
2317                                 Con_Printf("This XPM's palette is either huge or idiotically unoptimized. It's key size is %i\n", isize);
2318                         }
2319                 }
2320                 else
2321                 {
2322                         // NOTE: Only 1-char colornames are supported
2323                         Con_Printf("Sorry, but this does not even look similar to an XPM.\n");
2324                 }
2325         }
2326
2327         if (icon)
2328                 SDL_WM_SetIcon(icon, NULL);
2329
2330         SDL_WM_SetCaption( gamename, NULL );
2331         screen = SDL_SetVideoMode(screenwidth, screenheight, screenbpp, screenflags);
2332
2333 #if SDL_MAJOR_VERSION == 1
2334 // LordHavoc: info.info.x11.lock_func and accompanying code do not seem to compile with SDL 1.3
2335 #if SDL_VIDEO_DRIVER_X11 && !SDL_VIDEO_DRIVER_QUARTZ
2336
2337         version = SDL_Linked_Version();
2338         // only use non-XPM icon support in SDL v1.3 and higher
2339         // SDL v1.2 does not support "smooth" transparency, and thus is better
2340         // off the xpm way
2341         if(screen && (!(version->major >= 2 || (version->major == 1 && version->minor >= 3))))
2342         {
2343                 // in this case, we did not set the good icon yet
2344                 SDL_SysWMinfo info;
2345                 SDL_VERSION(&info.version);
2346                 if(SDL_GetWMInfo(&info) == 1 && info.subsystem == SDL_SYSWM_X11)
2347                 {
2348                         data = (char *) loadimagepixelsbgra("darkplaces-icon", false, false, false, NULL);
2349                         if(data)
2350                         {
2351                                 // use _NET_WM_ICON too
2352                                 static long netwm_icon[MAX_NETWM_ICON];
2353                                 int pos = 0;
2354                                 int i = 1;
2355                                 char vabuf[1024];
2356
2357                                 while(data)
2358                                 {
2359                                         if(pos + 2 * image_width * image_height < MAX_NETWM_ICON)
2360                                         {
2361                                                 netwm_icon[pos++] = image_width;
2362                                                 netwm_icon[pos++] = image_height;
2363                                                 for(i = 0; i < image_height; ++i)
2364                                                         for(j = 0; j < image_width; ++j)
2365                                                                 netwm_icon[pos++] = BuffLittleLong((unsigned char *) &data[(i*image_width+j)*4]);
2366                                         }
2367                                         else
2368                                         {
2369                                                 Con_Printf("Skipping NETWM icon #%d because there is no space left\n", i);
2370                                         }
2371                                         ++i;
2372                                         Mem_Free(data);
2373                                         data = (char *) loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "darkplaces-icon%d", i), false, false, false, NULL);
2374                                 }
2375
2376                                 info.info.x11.lock_func();
2377                                 {
2378                                         Atom net_wm_icon = XInternAtom(info.info.x11.display, "_NET_WM_ICON", false);
2379                                         XChangeProperty(info.info.x11.display, info.info.x11.wmwindow, net_wm_icon, XA_CARDINAL, 32, PropModeReplace, (const unsigned char *) netwm_icon, pos);
2380                                 }
2381                                 info.info.x11.unlock_func();
2382                         }
2383                 }
2384         }
2385 #endif
2386 #endif
2387         return screen;
2388 }
2389
2390 #endif
2391 #endif
2392
2393 static void VID_OutputVersion(void)
2394 {
2395         SDL_version version;
2396 #if SDL_MAJOR_VERSION == 1
2397         version = *SDL_Linked_Version();
2398 #else
2399         SDL_GetVersion(&version);
2400 #endif
2401         Con_Printf(     "Linked against SDL version %d.%d.%d\n"
2402                                         "Using SDL library version %d.%d.%d\n",
2403                                         SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL,
2404                                         version.major, version.minor, version.patch );
2405 }
2406
2407 static qboolean VID_InitModeGL(viddef_mode_t *mode)
2408 {
2409 #if SDL_MAJOR_VERSION == 1
2410         static int notfirstvideomode = false;
2411         int flags = SDL_OPENGL;
2412 #else
2413         int windowflags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL;
2414 #endif
2415 #ifndef USE_GLES2
2416         int i;
2417         const char *drivername;
2418 #endif
2419
2420         win_half_width = mode->width>>1;
2421         win_half_height = mode->height>>1;
2422
2423         if(vid_resizable.integer)
2424 #if SDL_MAJOR_VERSION == 1
2425                 flags |= SDL_RESIZABLE;
2426 #else
2427                 windowflags |= SDL_WINDOW_RESIZABLE;
2428 #endif
2429
2430         VID_OutputVersion();
2431
2432 #if SDL_MAJOR_VERSION == 1
2433         /*
2434         SDL 1.2 Hack
2435                 We cant switch from one OpenGL video mode to another.
2436                 Thus we first switch to some stupid 2D mode and then back to OpenGL.
2437         */
2438         if (notfirstvideomode)
2439                 SDL_SetVideoMode( 0, 0, 0, 0 );
2440         notfirstvideomode = true;
2441 #endif
2442
2443 #ifndef USE_GLES2
2444         // SDL usually knows best
2445         drivername = NULL;
2446
2447 // 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
2448         i = COM_CheckParm("-gl_driver");
2449         if (i && i < com_argc - 1)
2450                 drivername = com_argv[i + 1];
2451         if (SDL_GL_LoadLibrary(drivername) < 0)
2452         {
2453                 Con_Printf("Unable to load GL driver \"%s\": %s\n", drivername, SDL_GetError());
2454                 return false;
2455         }
2456 #endif
2457
2458 #ifdef DP_MOBILETOUCH
2459         // mobile platforms are always fullscreen, we'll get the resolution after opening the window
2460         mode->fullscreen = true;
2461         // hide the menu with SDL_WINDOW_BORDERLESS
2462         windowflags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS;
2463 #endif
2464 #ifndef USE_GLES2
2465         if ((qglGetString = (const GLubyte* (GLAPIENTRY *)(GLenum name))GL_GetProcAddress("glGetString")) == NULL)
2466         {
2467                 VID_Shutdown();
2468                 Con_Print("Required OpenGL function glGetString not found\n");
2469                 return false;
2470         }
2471 #endif
2472
2473         // Knghtbrd: should do platform-specific extension string function here
2474
2475         vid_isfullscreen = false;
2476         if (mode->fullscreen) {
2477 #if SDL_MAJOR_VERSION == 1
2478                 flags |= SDL_FULLSCREEN;
2479 #else
2480                 windowflags |= SDL_WINDOW_FULLSCREEN;
2481 #endif
2482                 vid_isfullscreen = true;
2483         }
2484         //flags |= SDL_HWSURFACE;
2485
2486         SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
2487         if (mode->bitsperpixel >= 32)
2488         {
2489                 SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 8);
2490                 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 8);
2491                 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 8);
2492                 SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, 8);
2493                 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 24);
2494                 SDL_GL_SetAttribute (SDL_GL_STENCIL_SIZE, 8);
2495         }
2496         else
2497         {
2498                 SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5);
2499                 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5);
2500                 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5);
2501                 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 16);
2502         }
2503         if (mode->stereobuffer)
2504                 SDL_GL_SetAttribute (SDL_GL_STEREO, 1);
2505         if (mode->samples > 1)
2506         {
2507                 SDL_GL_SetAttribute (SDL_GL_MULTISAMPLEBUFFERS, 1);
2508                 SDL_GL_SetAttribute (SDL_GL_MULTISAMPLESAMPLES, mode->samples);
2509         }
2510
2511 #if SDL_MAJOR_VERSION == 1
2512         if (vid_vsync.integer)
2513                 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1);
2514         else
2515                 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 0);
2516 #else
2517 #ifdef USE_GLES2
2518         SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
2519         SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0);
2520         SDL_GL_SetAttribute (SDL_GL_RETAINED_BACKING, 1);
2521 #endif
2522 #endif
2523
2524         video_bpp = mode->bitsperpixel;
2525 #if SDL_MAJOR_VERSION == 1
2526         video_flags = flags;
2527         screen = VID_WrapSDL_SetVideoMode(mode->width, mode->height, mode->bitsperpixel, flags);
2528         if (screen == NULL)
2529         {
2530                 Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError());
2531                 VID_Shutdown();
2532                 return false;
2533         }
2534         mode->width = screen->w;
2535         mode->height = screen->h;
2536 #else
2537         window_flags = windowflags;
2538         window = SDL_CreateWindow(gamename, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, mode->width, mode->height, windowflags);
2539         if (window == NULL)
2540         {
2541                 Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError());
2542                 VID_Shutdown();
2543                 return false;
2544         }
2545         SDL_GetWindowSize(window, &mode->width, &mode->height);
2546         context = SDL_GL_CreateContext(window);
2547         if (context == NULL)
2548         {
2549                 Con_Printf("Failed to initialize OpenGL context: %s\n", SDL_GetError());
2550                 VID_Shutdown();
2551                 return false;
2552         }
2553 #endif
2554
2555         vid_softsurface = NULL;
2556         vid.softpixels = NULL;
2557
2558 #if SDL_MAJOR_VERSION == 1
2559         // init keyboard
2560         SDL_EnableUNICODE( SDL_ENABLE );
2561         // enable key repeat since everyone expects it
2562         SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
2563 #endif
2564
2565 #if SDL_MAJOR_VERSION != 1
2566         SDL_GL_SetSwapInterval(vid_vsync.integer != 0);
2567         vid_usingvsync = (vid_vsync.integer != 0);
2568 #endif
2569
2570         gl_platform = "SDL";
2571         gl_platformextensions = "";
2572
2573 #ifdef USE_GLES2
2574         GLES_Init();
2575 #else
2576         GL_Init();
2577 #endif
2578
2579         vid_hidden = false;
2580         vid_activewindow = false;
2581         vid_hasfocus = true;
2582         vid_usingmouse = false;
2583         vid_usinghidecursor = false;
2584                 
2585 #if SDL_MAJOR_VERSION == 1
2586         SDL_WM_GrabInput(SDL_GRAB_OFF);
2587 #endif
2588         return true;
2589 }
2590
2591 extern cvar_t gl_info_extensions;
2592 extern cvar_t gl_info_vendor;
2593 extern cvar_t gl_info_renderer;
2594 extern cvar_t gl_info_version;
2595 extern cvar_t gl_info_platform;
2596 extern cvar_t gl_info_driver;
2597
2598 static qboolean VID_InitModeSoft(viddef_mode_t *mode)
2599 {
2600 #if SDL_MAJOR_VERSION == 1
2601         int flags = SDL_HWSURFACE;
2602         if(!COM_CheckParm("-noasyncblit")) flags |= SDL_ASYNCBLIT;
2603 #else
2604         int windowflags = SDL_WINDOW_SHOWN;
2605 #endif
2606
2607         win_half_width = mode->width>>1;
2608         win_half_height = mode->height>>1;
2609
2610         if(vid_resizable.integer)
2611 #if SDL_MAJOR_VERSION == 1
2612                 flags |= SDL_RESIZABLE;
2613 #else
2614                 windowflags |= SDL_WINDOW_RESIZABLE;
2615 #endif
2616
2617         VID_OutputVersion();
2618
2619         vid_isfullscreen = false;
2620         if (mode->fullscreen) {
2621 #if SDL_MAJOR_VERSION == 1
2622                 flags |= SDL_FULLSCREEN;
2623 #else
2624                 windowflags |= SDL_WINDOW_FULLSCREEN;
2625 #endif
2626                 vid_isfullscreen = true;
2627         }
2628
2629         video_bpp = mode->bitsperpixel;
2630 #if SDL_MAJOR_VERSION == 1
2631         video_flags = flags;
2632         screen = VID_WrapSDL_SetVideoMode(mode->width, mode->height, mode->bitsperpixel, flags);
2633         if (screen == NULL)
2634         {
2635                 Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError());
2636                 VID_Shutdown();
2637                 return false;
2638         }
2639         mode->width = screen->w;
2640         mode->height = screen->h;
2641 #else
2642         window_flags = windowflags;
2643         window = SDL_CreateWindow(gamename, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, mode->width, mode->height, windowflags);
2644         if (window == NULL)
2645         {
2646                 Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError());
2647                 VID_Shutdown();
2648                 return false;
2649         }
2650         SDL_GetWindowSize(window, &mode->width, &mode->height);
2651 #endif
2652
2653         // create a framebuffer using our specific color format, we let the SDL blit function convert it in VID_Finish
2654         vid_softsurface = SDL_CreateRGBSurface(SDL_SWSURFACE, mode->width, mode->height, 32, 0x00FF0000, 0x0000FF00, 0x00000000FF, 0xFF000000);
2655         if (vid_softsurface == NULL)
2656         {
2657                 Con_Printf("Failed to setup software rasterizer framebuffer %ix%ix32bpp: %s\n", mode->width, mode->height, SDL_GetError());
2658                 VID_Shutdown();
2659                 return false;
2660         }
2661 #if SDL_MAJOR_VERSION == 1
2662         SDL_SetAlpha(vid_softsurface, 0, 255);
2663 #endif
2664
2665         vid.softpixels = (unsigned int *)vid_softsurface->pixels;
2666         vid.softdepthpixels = (unsigned int *)calloc(1, mode->width * mode->height * 4);
2667         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)
2668         {
2669                 Con_Printf("Failed to initialize software rasterizer\n");
2670                 VID_Shutdown();
2671                 return false;
2672         }
2673
2674 #if SDL_MAJOR_VERSION == 1
2675         // init keyboard
2676         SDL_EnableUNICODE( SDL_ENABLE );
2677         // enable key repeat since everyone expects it
2678         SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
2679 #endif
2680
2681         VID_Soft_SharedSetup();
2682
2683         vid_hidden = false;
2684         vid_activewindow = false;
2685         vid_hasfocus = true;
2686         vid_usingmouse = false;
2687         vid_usinghidecursor = false;
2688
2689 #if SDL_MAJOR_VERSION == 1
2690         SDL_WM_GrabInput(SDL_GRAB_OFF);
2691 #endif
2692         return true;
2693 }
2694
2695 qboolean VID_InitMode(viddef_mode_t *mode)
2696 {
2697         // GAME_STEELSTORM specific
2698         steelstorm_showing_map = Cvar_FindVar("steelstorm_showing_map");
2699         steelstorm_showing_mousecursor = Cvar_FindVar("steelstorm_showing_mousecursor");
2700
2701         if (!SDL_WasInit(SDL_INIT_VIDEO) && SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
2702                 Sys_Error ("Failed to init SDL video subsystem: %s", SDL_GetError());
2703
2704 #if SDL_MAJOR_VERSION != 1
2705         Cvar_SetValueQuick(&vid_touchscreen_supportshowkeyboard, SDL_HasScreenKeyboardSupport() ? 1 : 0);
2706 #endif
2707 #ifdef SSE_POSSIBLE
2708         if (vid_soft.integer)
2709                 return VID_InitModeSoft(mode);
2710         else
2711 #endif
2712                 return VID_InitModeGL(mode);
2713 }
2714
2715 void VID_Shutdown (void)
2716 {
2717         VID_EnableJoystick(false);
2718         VID_SetMouse(false, false, false);
2719         VID_RestoreSystemGamma();
2720
2721 #if SDL_MAJOR_VERSION == 1
2722 #ifndef WIN32
2723 #ifndef MACOSX
2724         if (icon)
2725                 SDL_FreeSurface(icon);
2726         icon = NULL;
2727 #endif
2728 #endif
2729 #endif
2730
2731         if (vid_softsurface)
2732                 SDL_FreeSurface(vid_softsurface);
2733         vid_softsurface = NULL;
2734         vid.softpixels = NULL;
2735         if (vid.softdepthpixels)
2736                 free(vid.softdepthpixels);
2737         vid.softdepthpixels = NULL;
2738
2739 #if SDL_MAJOR_VERSION != 1
2740         SDL_DestroyWindow(window);
2741         window = NULL;
2742 #endif
2743
2744         SDL_QuitSubSystem(SDL_INIT_VIDEO);
2745
2746         gl_driver[0] = 0;
2747         gl_extensions = "";
2748         gl_platform = "";
2749         gl_platformextensions = "";
2750 }
2751
2752 int VID_SetGamma (unsigned short *ramps, int rampsize)
2753 {
2754 #if SDL_MAJOR_VERSION == 1
2755         return !SDL_SetGammaRamp (ramps, ramps + rampsize, ramps + rampsize*2);
2756 #else
2757         return !SDL_SetWindowGammaRamp (window, ramps, ramps + rampsize, ramps + rampsize*2);
2758 #endif
2759 }
2760
2761 int VID_GetGamma (unsigned short *ramps, int rampsize)
2762 {
2763 #if SDL_MAJOR_VERSION == 1
2764         return !SDL_GetGammaRamp (ramps, ramps + rampsize, ramps + rampsize*2);
2765 #else
2766         return !SDL_GetWindowGammaRamp (window, ramps, ramps + rampsize, ramps + rampsize*2);
2767 #endif
2768 }
2769
2770 void VID_Finish (void)
2771 {
2772 #if SDL_MAJOR_VERSION == 1
2773         Uint8 appstate;
2774
2775         //react on appstate changes
2776         appstate = SDL_GetAppState();
2777
2778         vid_hidden = !(appstate & SDL_APPACTIVE);
2779         vid_hasfocus = (appstate & SDL_APPINPUTFOCUS) != 0;
2780 #endif
2781         vid_activewindow = !vid_hidden && vid_hasfocus;
2782
2783         VID_UpdateGamma(false, 256);
2784
2785         if (!vid_hidden)
2786         {
2787                 switch(vid.renderpath)
2788                 {
2789                 case RENDERPATH_GL11:
2790                 case RENDERPATH_GL13:
2791                 case RENDERPATH_GL20:
2792                 case RENDERPATH_GLES1:
2793                 case RENDERPATH_GLES2:
2794                         CHECKGLERROR
2795                         if (r_speeds.integer == 2 || gl_finish.integer)
2796                                 GL_Finish();
2797
2798 #if SDL_MAJOR_VERSION != 1
2799 {
2800         qboolean vid_usevsync;
2801         vid_usevsync = (vid_vsync.integer && !cls.timedemo);
2802         if (vid_usingvsync != vid_usevsync)
2803         {
2804                 if (SDL_GL_SetSwapInterval(vid_usevsync != 0) >= 0)
2805                         Con_DPrintf("Vsync %s\n", vid_usevsync ? "activated" : "deactivated");
2806                 else
2807                         Con_DPrintf("ERROR: can't %s vsync\n", vid_usevsync ? "activate" : "deactivate");
2808         }
2809 }
2810 #endif
2811 #if SDL_MAJOR_VERSION == 1
2812                         SDL_GL_SwapBuffers();
2813 #else
2814                         SDL_GL_SwapWindow(window);
2815 #endif
2816                         break;
2817                 case RENDERPATH_SOFT:
2818                         DPSOFTRAST_Finish();
2819 #if SDL_MAJOR_VERSION == 1
2820 //              if (!r_test.integer)
2821                 {
2822                         SDL_BlitSurface(vid_softsurface, NULL, screen, NULL);
2823                         SDL_Flip(screen);
2824                 }
2825 #else
2826                         {
2827                                 SDL_Surface *screen = SDL_GetWindowSurface(window);
2828                                 SDL_BlitSurface(vid_softsurface, NULL, screen, NULL);
2829                                 SDL_UpdateWindowSurface(window);
2830                         }
2831 #endif
2832                         break;
2833                 case RENDERPATH_D3D9:
2834                 case RENDERPATH_D3D10:
2835                 case RENDERPATH_D3D11:
2836                         if (r_speeds.integer == 2 || gl_finish.integer)
2837                                 GL_Finish();
2838                         break;
2839                 }
2840         }
2841 }
2842
2843 size_t VID_ListModes(vid_mode_t *modes, size_t maxcount)
2844 {
2845         size_t k = 0;
2846 #if SDL_MAJOR_VERSION == 1
2847         SDL_Rect **vidmodes;
2848         int bpp = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
2849
2850         for(vidmodes = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE); vidmodes && vidmodes != (SDL_Rect**)(-1) && *vidmodes; ++vidmodes)
2851         {
2852                 if(k >= maxcount)
2853                         break;
2854                 modes[k].width = (*vidmodes)->w;
2855                 modes[k].height = (*vidmodes)->h;
2856                 modes[k].bpp = bpp;
2857                 modes[k].refreshrate = 60; // no support for refresh rate in SDL
2858                 modes[k].pixelheight_num = 1;
2859                 modes[k].pixelheight_denom = 1; // SDL does not provide this
2860                 ++k;
2861         }
2862 #else
2863         int modenum;
2864         int nummodes = SDL_GetNumDisplayModes(0);
2865         SDL_DisplayMode mode;
2866         for (modenum = 0;modenum < nummodes;modenum++)
2867         {
2868                 if (k >= maxcount)
2869                         break;
2870                 if (SDL_GetDisplayMode(0, modenum, &mode))
2871                         continue;
2872                 modes[k].width = mode.w;
2873                 modes[k].height = mode.h;
2874                 modes[k].refreshrate = mode.refresh_rate;
2875                 modes[k].pixelheight_num = 1;
2876                 modes[k].pixelheight_num = 1;
2877                 modes[k].pixelheight_denom = 1; // SDL does not provide this
2878                 k++;
2879         }
2880 #endif
2881         return k;
2882 }