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