]> de.git.xonotic.org Git - xonotic/darkplaces.git/blob - vid_sdl.c
26c49f1ed0967798c4f024e95ceb33f6de29eca6
[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 shoud 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 qboolean VID_ShowingKeyboard(void)
439 {
440 #ifdef __IPHONEOS__
441         return SDL_iPhoneKeyboardIsShown(window);
442 #endif
443 }
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(float x, float y, float width, float height, const char *icon, float *resultmove, qboolean *resultbutton, keynum_t key)
603 {
604         int finger;
605         float rel[3];
606         qboolean button = false;
607         VectorClear(rel);
608         if (width > 0 && height > 0 && (key == '`' || key == K_ESCAPE || !VID_ShowingKeyboard()))
609         {
610                 x *= 32768.0f / 320.0f;
611                 y *= 32768.0f / 480.0f;
612                 width *= 32768.0f / 320.0f;
613                 height *= 32768.0f / 480.0f;
614                 for (finger = 0;finger < MAXFINGERS;finger++)
615                 {
616                         if (multitouch[finger][0] && multitouch[finger][1] >= x && multitouch[finger][2] >= y && multitouch[finger][1] < x + width && multitouch[finger][2] < y + height)
617                         {
618                                 rel[0] = (multitouch[finger][1] - (x + 0.5f * width)) * (2.0f / width);
619                                 rel[1] = (multitouch[finger][2] - (y + 0.5f * height)) * (2.0f / height);
620                                 rel[2] = 0;
621                                 button = true;
622                                 break;
623                         }
624                 }
625                 if (scr_numtouchscreenareas < 16)
626                 {
627                         scr_touchscreenareas[scr_numtouchscreenareas].pic = icon;
628                         scr_touchscreenareas[scr_numtouchscreenareas].rect[0] = x * vid_conwidth.value / 32768.0f;
629                         scr_touchscreenareas[scr_numtouchscreenareas].rect[1] = y * vid_conheight.value / 32768.0f;
630                         scr_touchscreenareas[scr_numtouchscreenareas].rect[2] = width * vid_conwidth.value / 32768.0f;
631                         scr_touchscreenareas[scr_numtouchscreenareas].rect[3] = height * vid_conheight.value / 32768.0f;
632                         scr_touchscreenareas[scr_numtouchscreenareas].active = button;
633                         scr_numtouchscreenareas++;
634                 }
635         }
636         if (resultmove)
637         {
638                 if (button)
639                         VectorCopy(rel, resultmove);
640                 else
641                         VectorClear(resultmove);
642         }
643         if (resultbutton)
644         {
645                 if (*resultbutton != button && (int)key > 0)
646                         Key_Event(key, 0, button);
647                 *resultbutton = button;
648         }
649         return button;
650 }
651
652 /////////////////////
653 // Movement handling
654 ////
655
656 void IN_Move( void )
657 {
658         int j;
659         static int old_x = 0, old_y = 0;
660         static int stuck = 0;
661         int x, y, numaxes, numballs;
662
663         scr_numtouchscreenareas = 0;
664         if (vid_touchscreen.integer)
665         {
666                 vec3_t move, aim, click;
667                 static qboolean buttons[16];
668                 static int oldkeydest;
669                 keydest_t keydest = (key_consoleactive & KEY_CONSOLEACTIVE_USER) ? key_console : key_dest;
670                 multitouch[MAXFINGERS-1][0] = SDL_GetMouseState(&x, &y);
671                 multitouch[MAXFINGERS-1][1] = x * 32768 / vid.width;
672                 multitouch[MAXFINGERS-1][2] = y * 32768 / vid.height;
673                 if (oldkeydest != keydest)
674                 {
675                         switch(keydest)
676                         {
677                         case key_game: VID_ShowKeyboard(false);break;
678                         case key_console: VID_ShowKeyboard(true);break;
679                         case key_message: VID_ShowKeyboard(true);break;
680                         default: break;
681                         }
682                 }
683                 oldkeydest = keydest;
684                 // top of screen is toggleconsole and K_ESCAPE
685                         VID_TouchscreenArea(  0,   0,  50,  50, NULL                         , NULL, &buttons[13], '`');
686                         VID_TouchscreenArea( 50,   0, 270,  50, "gfx/touch_menu.tga"         , NULL, &buttons[14], K_ESCAPE);
687                 switch(keydest)
688                 {
689                 case key_console:
690                         if (!VID_ShowingKeyboard())
691                         {
692                                 // user entered a command, close the console now
693                                 Con_ToggleConsole_f();
694                         }
695                         break;
696                 case key_game:
697                         VID_TouchscreenArea(  0, 380, 100, 100, "gfx/touch_movebutton.tga"   , move, &buttons[0], K_MOUSE4);
698                         VID_TouchscreenArea(220, 380, 100, 100, "gfx/touch_aimbutton.tga"    , aim,  &buttons[1], K_MOUSE5);
699                         VID_TouchscreenArea(110, 380, 100, 100, "gfx/touch_attackbutton.tga" , NULL, &buttons[2], K_MOUSE1);
700                         VID_TouchscreenArea(  0, 330, 100,  50, "gfx/touch_jumpbutton.tga"   , NULL, &buttons[3], K_SPACE);
701                         VID_TouchscreenArea(220, 330, 100,  50, "gfx/touch_attack2button.tga", NULL, &buttons[4], K_MOUSE2);
702                         buttons[15] = false;
703                         break;
704                 default:
705                         // in menus, an icon in the corner activates keyboard
706                         VID_TouchscreenArea(  0, 430,  50,  50, "gfx/touch_keyboard.tga"     , NULL, &buttons[15], 0);
707                         if (buttons[15])
708                                 VID_ShowKeyboard(true);
709                         VID_TouchscreenArea(  0,   0,   0,   0, NULL                         , move, &buttons[0], K_MOUSE4);
710                         VID_TouchscreenArea(  0,   0,   0,   0, NULL                         , aim,  &buttons[1], K_MOUSE5);
711                         VID_TouchscreenArea(-320,-480,640, 960, NULL                         , click,&buttons[2], K_MOUSE1);
712                         VID_TouchscreenArea(  0,   0,   0,   0, NULL                         , NULL, &buttons[3], K_SPACE);
713                         VID_TouchscreenArea(  0,   0,   0,   0, NULL                         , NULL, &buttons[4], K_MOUSE2);
714                         if (buttons[2])
715                         {
716                                 in_windowmouse_x = x;
717                                 in_windowmouse_y = y;
718                         }
719                         break;
720                 }
721                 cl.cmd.forwardmove -= move[1] * cl_forwardspeed.value;
722                 cl.cmd.sidemove += move[0] * cl_sidespeed.value;
723                 cl.viewangles[0] += aim[1] * cl_pitchspeed.value * cl.realframetime;
724                 cl.viewangles[1] -= aim[0] * cl_yawspeed.value * cl.realframetime;
725         }
726         else
727         {
728                 if (vid_usingmouse)
729                 {
730                         if (vid_stick_mouse.integer)
731                         {
732                                 // have the mouse stuck in the middle, example use: prevent expose effect of beryl during the game when not using
733                                 // window grabbing. --blub
734         
735                                 // we need 2 frames to initialize the center position
736                                 if(!stuck)
737                                 {
738 #if SETVIDEOMODE
739                                         SDL_WarpMouse(win_half_width, win_half_height);
740 #else
741                                         SDL_WarpMouseInWindow(window, win_half_width, win_half_height);
742 #endif
743                                         SDL_GetMouseState(&x, &y);
744                                         SDL_GetRelativeMouseState(&x, &y);
745                                         ++stuck;
746                                 } else {
747                                         SDL_GetRelativeMouseState(&x, &y);
748                                         in_mouse_x = x + old_x;
749                                         in_mouse_y = y + old_y;
750                                         SDL_GetMouseState(&x, &y);
751                                         old_x = x - win_half_width;
752                                         old_y = y - win_half_height;
753 #if SETVIDEOMODE
754                                         SDL_WarpMouse(win_half_width, win_half_height);
755 #else
756                                         SDL_WarpMouseInWindow(window, win_half_width, win_half_height);
757 #endif
758                                 }
759                         } else {
760                                 SDL_GetRelativeMouseState( &x, &y );
761                                 in_mouse_x = x;
762                                 in_mouse_y = y;
763                         }
764                 }
765
766                 SDL_GetMouseState(&x, &y);
767                 in_windowmouse_x = x;
768                 in_windowmouse_y = y;
769         }
770
771         if (vid_numjoysticks && joy_enable.integer && joy_index.integer >= 0 && joy_index.integer < vid_numjoysticks)
772         {
773                 SDL_Joystick *joy = vid_joysticks[joy_index.integer];
774
775                 // balls convert to mousemove
776                 numballs = SDL_JoystickNumBalls(joy);
777                 for (j = 0;j < numballs;j++)
778                 {
779                         SDL_JoystickGetBall(joy, j, &x, &y);
780                         in_mouse_x += x;
781                         in_mouse_y += y;
782                 }
783
784                 // axes
785                 cl.cmd.forwardmove += IN_JoystickGetAxis(joy, joy_axisforward.integer, joy_sensitivityforward.value, joy_deadzoneforward.value) * cl_forwardspeed.value;
786                 cl.cmd.sidemove    += IN_JoystickGetAxis(joy, joy_axisside.integer, joy_sensitivityside.value, joy_deadzoneside.value) * cl_sidespeed.value;
787                 cl.cmd.upmove      += IN_JoystickGetAxis(joy, joy_axisup.integer, joy_sensitivityup.value, joy_deadzoneup.value) * cl_upspeed.value;
788                 cl.viewangles[0]   += IN_JoystickGetAxis(joy, joy_axispitch.integer, joy_sensitivitypitch.value, joy_deadzonepitch.value) * cl.realframetime * cl_pitchspeed.value;
789                 cl.viewangles[1]   += IN_JoystickGetAxis(joy, joy_axisyaw.integer, joy_sensitivityyaw.value, joy_deadzoneyaw.value) * cl.realframetime * cl_yawspeed.value;
790                 //cl.viewangles[2]   += IN_JoystickGetAxis(joy, joy_axisroll.integer, joy_sensitivityroll.value, joy_deadzoneroll.value) * cl.realframetime * cl_rollspeed.value;
791         
792                 // cache state of axes to emulate button events for them
793                 numaxes = min(MAX_JOYSTICK_AXES, SDL_JoystickNumAxes(joy));
794                 for (j = 0; j < numaxes; j++)
795                 {
796                         joy_axescache[j].oldmove = joy_axescache[j].move;
797                         joy_axescache[j].move = IN_JoystickGetAxis(joy, j, 1, 0.01);
798                 }
799
800                 // run keyevents
801                 if (joy_axiskeyevents.integer)
802                 {
803                         IN_JoystickKeyeventForAxis(joy, joy_axisforward.integer, K_DOWNARROW, K_UPARROW);
804                         IN_JoystickKeyeventForAxis(joy, joy_axisside.integer, K_RIGHTARROW, K_LEFTARROW);
805                 }
806         }
807 }
808
809 /////////////////////
810 // Message Handling
811 ////
812
813 #ifdef SDL_R_RESTART
814 static qboolean sdl_needs_restart;
815 static void sdl_start(void)
816 {
817 }
818 static void sdl_shutdown(void)
819 {
820         sdl_needs_restart = false;
821 }
822 static void sdl_newmap(void)
823 {
824 }
825 #endif
826
827 static keynum_t buttonremap[18] =
828 {
829         K_MOUSE1,
830         K_MOUSE3,
831         K_MOUSE2,
832         K_MWHEELUP,
833         K_MWHEELDOWN,
834         K_MOUSE4,
835         K_MOUSE5,
836         K_MOUSE6,
837         K_MOUSE7,
838         K_MOUSE8,
839         K_MOUSE9,
840         K_MOUSE10,
841         K_MOUSE11,
842         K_MOUSE12,
843         K_MOUSE13,
844         K_MOUSE14,
845         K_MOUSE15,
846         K_MOUSE16,
847 };
848
849 #if SETVIDEOMODE
850 // SDL 1.2
851 void Sys_SendKeyEvents( void )
852 {
853         static qboolean sound_active = true;
854         int keycode;
855         SDL_Event event;
856
857         while( SDL_PollEvent( &event ) )
858                 switch( event.type ) {
859                         case SDL_QUIT:
860                                 Sys_Quit(0);
861                                 break;
862                         case SDL_KEYDOWN:
863                         case SDL_KEYUP:
864                                 keycode = MapKey(event.key.keysym.sym);
865                                 if (!IN_JoystickBlockDoubledKeyEvents(keycode))
866                                         Key_Event(keycode, event.key.keysym.unicode, (event.key.state == SDL_PRESSED));
867                                 break;
868                         case SDL_ACTIVEEVENT:
869                                 if( event.active.state & SDL_APPACTIVE )
870                                 {
871                                         if( event.active.gain )
872                                                 vid_hidden = false;
873                                         else
874                                                 vid_hidden = true;
875                                 }
876                                 break;
877                         case SDL_MOUSEBUTTONDOWN:
878                         case SDL_MOUSEBUTTONUP:
879                                 if (event.button.button <= 18)
880                                         Key_Event( buttonremap[event.button.button - 1], 0, event.button.state == SDL_PRESSED );
881                                 break;
882                         case SDL_JOYBUTTONDOWN:
883                                 if (!joy_enable.integer)
884                                         break; // ignore down events if joystick has been disabled
885                         case SDL_JOYBUTTONUP:
886                                 if (event.jbutton.button < 48)
887                                         Key_Event( event.jbutton.button + (event.jbutton.button < 16 ? K_JOY1 : K_AUX1 - 16), 0, (event.jbutton.state == SDL_PRESSED) );
888                                 break;
889                         case SDL_VIDEORESIZE:
890                                 if(vid_resizable.integer < 2)
891                                 {
892                                         vid.width = event.resize.w;
893                                         vid.height = event.resize.h;
894                                         screen = SDL_SetVideoMode(vid.width, vid.height, video_bpp, video_flags);
895                                         if (vid_softsurface)
896                                         {
897                                                 SDL_FreeSurface(vid_softsurface);
898                                                 vid_softsurface = SDL_CreateRGBSurface(SDL_SWSURFACE, vid.width, vid.height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
899                                                 vid.softpixels = (unsigned int *)vid_softsurface->pixels;
900                                                 SDL_SetAlpha(vid_softsurface, 0, 255);
901                                                 if (vid.softdepthpixels)
902                                                         free(vid.softdepthpixels);
903                                                 vid.softdepthpixels = (unsigned int*)calloc(1, vid.width * vid.height * 4);
904                                         }
905 #ifdef SDL_R_RESTART
906                                         // better not call R_Modules_Restart from here directly, as this may wreak havoc...
907                                         // so, let's better queue it for next frame
908                                         if(!sdl_needs_restart)
909                                         {
910                                                 Cbuf_AddText("\nr_restart\n");
911                                                 sdl_needs_restart = true;
912                                         }
913 #endif
914                                 }
915                                 break;
916                         case SDL_TEXTEDITING:
917                                 // unused when SETVIDEOMODE API is used
918                                 break;
919                         case SDL_TEXTINPUT:
920                                 // this occurs with SETVIDEOMODE but we are not using it
921                                 break;
922                         case SDL_MOUSEMOTION:
923                                 break;
924                         default:
925                                 Con_DPrintf("Received unrecognized SDL_Event type 0x%x\n", event.type);
926                                 break;
927                 }
928
929         // enable/disable sound on focus gain/loss
930         if ((!vid_hidden && vid_activewindow) || !snd_mutewhenidle.integer)
931         {
932                 if (!sound_active)
933                 {
934                         S_UnblockSound ();
935                         sound_active = true;
936                 }
937         }
938         else
939         {
940                 if (sound_active)
941                 {
942                         S_BlockSound ();
943                         sound_active = false;
944                 }
945         }
946 }
947
948 #else
949
950 // SDL 1.3
951 void Sys_SendKeyEvents( void )
952 {
953         static qboolean sound_active = true;
954         static qboolean missingunicodehack = true;
955         int keycode;
956         int i;
957         int j;
958         int unicode;
959         SDL_Event event;
960
961         while( SDL_PollEvent( &event ) )
962                 switch( event.type ) {
963                         case SDL_QUIT:
964                                 Sys_Quit(0);
965                                 break;
966                         case SDL_KEYDOWN:
967                         case SDL_KEYUP:
968                                 keycode = MapKey(event.key.keysym.sym);
969                                 if (!IN_JoystickBlockDoubledKeyEvents(keycode))
970 #ifdef __IPHONEOS__
971                                 // the virtual keyboard seems to produce no unicode values...
972                                 if (missingunicodehack && keycode >= ' ' && keycode < 0x7F && event.key.keysym.unicode == 0)
973                                 {
974                                         Con_DPrintf("SDL hack: no unicode value reported, substituting ascii value %i\n", keycode);
975                                         Key_Event(keycode, keycode, (event.key.state == SDL_PRESSED));
976                                 }
977                                 else
978 #endif
979                                         Key_Event(keycode, 0, (event.key.state == SDL_PRESSED));
980                                 break;
981                         case SDL_MOUSEBUTTONDOWN:
982                         case SDL_MOUSEBUTTONUP:
983 #ifndef __IPHONEOS__
984                                 if (event.button.button <= 18)
985                                         Key_Event( buttonremap[event.button.button - 1], 0, event.button.state == SDL_PRESSED );
986 #endif
987                                 break;
988                         case SDL_JOYBUTTONDOWN:
989                                 if (!joy_enable.integer)
990                                         break; // ignore down events if joystick has been disabled
991                         case SDL_JOYBUTTONUP:
992                                 if (event.jbutton.button < 48)
993                                         Key_Event( event.jbutton.button + (event.jbutton.button < 16 ? K_JOY1 : K_AUX1 - 16), 0, (event.jbutton.state == SDL_PRESSED) );
994                                 break;
995                         case SDL_WINDOWEVENT:
996                                 //if (event.window.windowID == window) // how to compare?
997                                 {
998                                         switch(event.window.event)
999                                         {
1000                                         case SDL_WINDOWEVENT_SHOWN:
1001                                                 vid_hidden = false;
1002                                                 break;
1003                                         case  SDL_WINDOWEVENT_HIDDEN:
1004                                                 vid_hidden = true;
1005                                                 break;
1006                                         case SDL_WINDOWEVENT_EXPOSED:
1007                                                 break;
1008                                         case SDL_WINDOWEVENT_MOVED:
1009                                                 break;
1010                                         case SDL_WINDOWEVENT_RESIZED:
1011                                                 if(vid_resizable.integer < 2)
1012                                                 {
1013                                                         vid.width = event.window.data1;
1014                                                         vid.height = event.window.data2;
1015                                                         if (vid_softsurface)
1016                                                         {
1017                                                                 SDL_FreeSurface(vid_softsurface);
1018                                                                 vid_softsurface = SDL_CreateRGBSurface(SDL_SWSURFACE, vid.width, vid.height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
1019                                                                 vid.softpixels = (unsigned int *)vid_softsurface->pixels;
1020                                                                 SDL_SetAlpha(vid_softsurface, 0, 255);
1021                                                                 if (vid.softdepthpixels)
1022                                                                         free(vid.softdepthpixels);
1023                                                                 vid.softdepthpixels = (unsigned int*)calloc(1, vid.width * vid.height * 4);
1024                                                         }
1025 #ifdef SDL_R_RESTART
1026                                                         // better not call R_Modules_Restart from here directly, as this may wreak havoc...
1027                                                         // so, let's better queue it for next frame
1028                                                         if(!sdl_needs_restart)
1029                                                         {
1030                                                                 Cbuf_AddText("\nr_restart\n");
1031                                                                 sdl_needs_restart = true;
1032                                                         }
1033 #endif
1034                                                 }
1035                                                 break;
1036                                         case SDL_WINDOWEVENT_MINIMIZED:
1037                                                 break;
1038                                         case SDL_WINDOWEVENT_MAXIMIZED:
1039                                                 break;
1040                                         case SDL_WINDOWEVENT_RESTORED:
1041                                                 break;
1042                                         case SDL_WINDOWEVENT_ENTER:
1043                                                 break;
1044                                         case SDL_WINDOWEVENT_LEAVE:
1045                                                 break;
1046                                         case SDL_WINDOWEVENT_FOCUS_GAINED:
1047                                                 vid_hasfocus = true;
1048                                                 break;
1049                                         case SDL_WINDOWEVENT_FOCUS_LOST:
1050                                                 vid_hasfocus = false;
1051                                                 break;
1052                                         case SDL_WINDOWEVENT_CLOSE:
1053                                                 Sys_Quit(0);
1054                                                 break;
1055                                         }
1056                                 }
1057                                 break;
1058                         case SDL_TEXTEDITING:
1059                                 // FIXME!  this is where composition gets supported
1060                                 break;
1061                         case SDL_TEXTINPUT:
1062                                 // we have some characters to parse
1063                                 missingunicodehack = false;
1064                                 {
1065                                         unicode = 0;
1066                                         for (i = 0;event.text.text[i];)
1067                                         {
1068                                                 unicode = event.text.text[i++];
1069                                                 if (unicode & 0x80)
1070                                                 {
1071                                                         // UTF-8 character
1072                                                         // strip high bits (we could count these to validate character length but we don't)
1073                                                         for (j = 0x80;unicode & j;j >>= 1)
1074                                                                 unicode ^= j;
1075                                                         for (;(event.text.text[i] & 0xC0) == 0x80;i++)
1076                                                                 unicode = (unicode << 6) | (event.text.text[i] & 0x3F);
1077                                                         // low characters are invalid and could be bad, so replace them
1078                                                         if (unicode < 0x80)
1079                                                                 unicode = '?'; // we could use 0xFFFD instead, the unicode substitute character
1080                                                 }
1081                                                 //Con_DPrintf("SDL_TEXTINPUT: K_TEXT %i \n", unicode);
1082                                                 Key_Event(K_TEXT, unicode, true);
1083                                                 Key_Event(K_TEXT, unicode, false);
1084                                         }
1085                                 }
1086                                 break;
1087                         case SDL_MOUSEMOTION:
1088                                 break;
1089                         case SDL_FINGERDOWN:
1090                                 Con_DPrintf("SDL_FINGERDOWN for finger %i\n", (int)event.tfinger.fingerId);
1091                                 for (i = 0;i < MAXFINGERS-1;i++)
1092                                 {
1093                                         if (!multitouch[i][0])
1094                                         {
1095                                                 multitouch[i][0] = event.tfinger.fingerId;
1096                                                 multitouch[i][1] = event.tfinger.x;
1097                                                 multitouch[i][2] = event.tfinger.y;
1098                                                 // TODO: use event.tfinger.pressure?
1099                                                 break;
1100                                         }
1101                                 }
1102                                 if (i == MAXFINGERS-1)
1103                                         Con_DPrintf("Too many fingers at once!\n");
1104                                 break;
1105                         case SDL_FINGERUP:
1106                                 Con_DPrintf("SDL_FINGERUP for finger %i\n", (int)event.tfinger.fingerId);
1107                                 for (i = 0;i < MAXFINGERS-1;i++)
1108                                 {
1109                                         if (multitouch[i][0] == event.tfinger.fingerId)
1110                                         {
1111                                                 multitouch[i][0] = 0;
1112                                                 break;
1113                                         }
1114                                 }
1115                                 if (i == MAXFINGERS-1)
1116                                         Con_DPrintf("No SDL_FINGERDOWN event matches this SDL_FINGERMOTION event\n");
1117                                 break;
1118                         case SDL_FINGERMOTION:
1119                                 Con_DPrintf("SDL_FINGERMOTION for finger %i\n", (int)event.tfinger.fingerId);
1120                                 for (i = 0;i < MAXFINGERS-1;i++)
1121                                 {
1122                                         if (multitouch[i][0] == event.tfinger.fingerId)
1123                                         {
1124                                                 multitouch[i][1] = event.tfinger.x;
1125                                                 multitouch[i][2] = event.tfinger.y;
1126                                                 break;
1127                                         }
1128                                 }
1129                                 if (i == MAXFINGERS-1)
1130                                         Con_DPrintf("No SDL_FINGERDOWN event matches this SDL_FINGERMOTION event\n");
1131                                 break;
1132                         case SDL_TOUCHBUTTONDOWN:
1133                                 // not sure what to do with this...
1134                                 break;
1135                         case SDL_TOUCHBUTTONUP:
1136                                 // not sure what to do with this...
1137                                 break;
1138                         case SDL_JOYAXISMOTION:
1139                                 // we poll the joystick instead
1140                                 break;
1141                         case SDL_JOYBALLMOTION:
1142                                 // we poll the joystick instead
1143                                 break;
1144                         case SDL_JOYHATMOTION:
1145                                 // we poll the joystick instead
1146                                 break;
1147                         default:
1148                                 Con_DPrintf("Received unrecognized SDL_Event type 0x%x\n", event.type);
1149                                 break;
1150                 }
1151
1152         // enable/disable sound on focus gain/loss
1153         if ((!vid_hidden && vid_activewindow) || !snd_mutewhenidle.integer)
1154         {
1155                 if (!sound_active)
1156                 {
1157                         S_UnblockSound ();
1158                         sound_active = true;
1159                 }
1160         }
1161         else
1162         {
1163                 if (sound_active)
1164                 {
1165                         S_BlockSound ();
1166                         sound_active = false;
1167                 }
1168         }
1169 }
1170 #endif
1171
1172 /////////////////
1173 // Video system
1174 ////
1175
1176 #ifdef __IPHONEOS__
1177 //#include <SDL_opengles.h>
1178 #include <OpenGLES/ES2/gl.h>
1179
1180 GLboolean wrapglIsBuffer(GLuint buffer) {return glIsBuffer(buffer);}
1181 GLboolean wrapglIsEnabled(GLenum cap) {return glIsEnabled(cap);}
1182 GLboolean wrapglIsFramebuffer(GLuint framebuffer) {return glIsFramebuffer(framebuffer);}
1183 //GLboolean wrapglIsQuery(GLuint qid) {return glIsQuery(qid);}
1184 GLboolean wrapglIsRenderbuffer(GLuint renderbuffer) {return glIsRenderbuffer(renderbuffer);}
1185 //GLboolean wrapglUnmapBuffer(GLenum target) {return glUnmapBuffer(target);}
1186 GLenum wrapglCheckFramebufferStatus(GLenum target) {return glCheckFramebufferStatus(target);}
1187 GLenum wrapglGetError(void) {return glGetError();}
1188 GLuint wrapglCreateProgram(void) {return glCreateProgram();}
1189 GLuint wrapglCreateShader(GLenum shaderType) {return glCreateShader(shaderType);}
1190 //GLuint wrapglGetHandle(GLenum pname) {return glGetHandle(pname);}
1191 GLint wrapglGetAttribLocation(GLuint programObj, const GLchar *name) {return glGetAttribLocation(programObj, name);}
1192 GLint wrapglGetUniformLocation(GLuint programObj, const GLchar *name) {return glGetUniformLocation(programObj, name);}
1193 //GLvoid* wrapglMapBuffer(GLenum target, GLenum access) {return glMapBuffer(target, access);}
1194 const GLubyte* wrapglGetString(GLenum name) {return glGetString(name);}
1195 void wrapglActiveStencilFace(GLenum e) {Con_Printf("glActiveStencilFace(e)\n");}
1196 void wrapglActiveTexture(GLenum e) {glActiveTexture(e);}
1197 void wrapglAlphaFunc(GLenum func, GLclampf ref) {Con_Printf("glAlphaFunc(func, ref)\n");}
1198 void wrapglArrayElement(GLint i) {Con_Printf("glArrayElement(i)\n");}
1199 void wrapglAttachShader(GLuint containerObj, GLuint obj) {glAttachShader(containerObj, obj);}
1200 void wrapglBegin(GLenum mode) {Con_Printf("glBegin(mode)\n");}
1201 //void wrapglBeginQuery(GLenum target, GLuint qid) {glBeginQuery(target, qid);}
1202 void wrapglBindAttribLocation(GLuint programObj, GLuint index, const GLchar *name) {glBindAttribLocation(programObj, index, name);}
1203 void wrapglBindBuffer(GLenum target, GLuint buffer) {glBindBuffer(target, buffer);}
1204 void wrapglBindFramebuffer(GLenum target, GLuint framebuffer) {glBindFramebuffer(target, framebuffer);}
1205 void wrapglBindRenderbuffer(GLenum target, GLuint renderbuffer) {glBindRenderbuffer(target, renderbuffer);}
1206 void wrapglBindTexture(GLenum target, GLuint texture) {glBindTexture(target, texture);}
1207 void wrapglBlendEquation(GLenum e) {glBlendEquation(e);}
1208 void wrapglBlendFunc(GLenum sfactor, GLenum dfactor) {glBlendFunc(sfactor, dfactor);}
1209 void wrapglBufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) {glBufferData(target, size, data, usage);}
1210 void wrapglBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) {glBufferSubData(target, offset, size, data);}
1211 void wrapglClear(GLbitfield mask) {glClear(mask);}
1212 void wrapglClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {glClearColor(red, green, blue, alpha);}
1213 void wrapglClearDepth(GLclampd depth) {glClearDepthf((float)depth);}
1214 void wrapglClearStencil(GLint s) {glClearStencil(s);}
1215 void wrapglClientActiveTexture(GLenum target) {Con_Printf("glClientActiveTexture(target)\n");}
1216 void wrapglColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {Con_Printf("glColor4f(red, green, blue, alpha)\n");}
1217 void wrapglColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) {Con_Printf("glColor4ub(red, green, blue, alpha)\n");}
1218 void wrapglColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {glColorMask(red, green, blue, alpha);}
1219 void wrapglColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) {Con_Printf("glColorPointer(size, type, stride, ptr)\n");}
1220 void wrapglCompileShader(GLuint shaderObj) {glCompileShader(shaderObj);}
1221 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);}
1222 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");}
1223 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);}
1224 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");}
1225 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);}
1226 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);}
1227 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");}
1228 void wrapglCullFace(GLenum mode) {glCullFace(mode);}
1229 void wrapglDeleteBuffers(GLsizei n, const GLuint *buffers) {glDeleteBuffers(n, buffers);}
1230 void wrapglDeleteFramebuffers(GLsizei n, const GLuint *framebuffers) {glDeleteFramebuffers(n, framebuffers);}
1231 void wrapglDeleteShader(GLuint obj) {glDeleteShader(obj);}
1232 void wrapglDeleteProgram(GLuint obj) {glDeleteProgram(obj);}
1233 //void wrapglDeleteQueries(GLsizei n, const GLuint *ids) {glDeleteQueries(n, ids);}
1234 void wrapglDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) {glDeleteRenderbuffers(n, renderbuffers);}
1235 void wrapglDeleteTextures(GLsizei n, const GLuint *textures) {glDeleteTextures(n, textures);}
1236 void wrapglDepthFunc(GLenum func) {glDepthFunc(func);}
1237 void wrapglDepthMask(GLboolean flag) {glDepthMask(flag);}
1238 void wrapglDepthRange(GLclampd near_val, GLclampd far_val) {glDepthRangef((float)near_val, (float)far_val);}
1239 void wrapglDetachShader(GLuint containerObj, GLuint attachedObj) {glDetachShader(containerObj, attachedObj);}
1240 void wrapglDisable(GLenum cap) {glDisable(cap);}
1241 void wrapglDisableClientState(GLenum cap) {Con_Printf("glDisableClientState(cap)\n");}
1242 void wrapglDisableVertexAttribArray(GLuint index) {glDisableVertexAttribArray(index);}
1243 void wrapglDrawArrays(GLenum mode, GLint first, GLsizei count) {glDrawArrays(mode, first, count);}
1244 void wrapglDrawBuffer(GLenum mode) {Con_Printf("glDrawBuffer(mode)\n");}
1245 void wrapglDrawBuffers(GLsizei n, const GLenum *bufs) {Con_Printf("glDrawBuffers(n, bufs)\n");}
1246 void wrapglDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {glDrawElements(mode, count, type, indices);}
1247 //void wrapglDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) {glDrawRangeElements(mode, start, end, count, type, indices);}
1248 //void wrapglDrawRangeElementsEXT(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) {glDrawRangeElements(mode, start, end, count, type, indices);}
1249 void wrapglEnable(GLenum cap) {glEnable(cap);}
1250 void wrapglEnableClientState(GLenum cap) {Con_Printf("glEnableClientState(cap)\n");}
1251 void wrapglEnableVertexAttribArray(GLuint index) {glEnableVertexAttribArray(index);}
1252 void wrapglEnd(void) {Con_Printf("glEnd()\n");}
1253 //void wrapglEndQuery(GLenum target) {glEndQuery(target);}
1254 void wrapglFinish(void) {glFinish();}
1255 void wrapglFlush(void) {glFlush();}
1256 void wrapglFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);}
1257 void wrapglFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {glFramebufferTexture2D(target, attachment, textarget, texture, level);}
1258 void wrapglFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) {Con_Printf("glFramebufferTexture3D()\n");}
1259 void wrapglGenBuffers(GLsizei n, GLuint *buffers) {glGenBuffers(n, buffers);}
1260 void wrapglGenFramebuffers(GLsizei n, GLuint *framebuffers) {glGenFramebuffers(n, framebuffers);}
1261 //void wrapglGenQueries(GLsizei n, GLuint *ids) {glGenQueries(n, ids);}
1262 void wrapglGenRenderbuffers(GLsizei n, GLuint *renderbuffers) {glGenRenderbuffers(n, renderbuffers);}
1263 void wrapglGenTextures(GLsizei n, GLuint *textures) {glGenTextures(n, textures);}
1264 void wrapglGenerateMipmap(GLenum target) {glGenerateMipmap(target);}
1265 void wrapglGetActiveAttrib(GLuint programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLchar *name) {glGetActiveAttrib(programObj, index, maxLength, length, size, type, name);}
1266 void wrapglGetActiveUniform(GLuint programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLchar *name) {glGetActiveUniform(programObj, index, maxLength, length, size, type, name);}
1267 void wrapglGetAttachedShaders(GLuint containerObj, GLsizei maxCount, GLsizei *count, GLuint *obj) {glGetAttachedShaders(containerObj, maxCount, count, obj);}
1268 void wrapglGetBooleanv(GLenum pname, GLboolean *params) {glGetBooleanv(pname, params);}
1269 void wrapglGetCompressedTexImage(GLenum target, GLint lod, void *img) {Con_Printf("glGetCompressedTexImage(target, lod, img)\n");}
1270 void wrapglGetDoublev(GLenum pname, GLdouble *params) {Con_Printf("glGetDoublev(pname, params)\n");}
1271 void wrapglGetFloatv(GLenum pname, GLfloat *params) {glGetFloatv(pname, params);}
1272 void wrapglGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params) {glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);}
1273 void wrapglGetShaderInfoLog(GLuint obj, GLsizei maxLength, GLsizei *length, GLchar *infoLog) {glGetShaderInfoLog(obj, maxLength, length, infoLog);}
1274 void wrapglGetProgramInfoLog(GLuint obj, GLsizei maxLength, GLsizei *length, GLchar *infoLog) {glGetProgramInfoLog(obj, maxLength, length, infoLog);}
1275 void wrapglGetIntegerv(GLenum pname, GLint *params) {glGetIntegerv(pname, params);}
1276 void wrapglGetShaderiv(GLuint obj, GLenum pname, GLint *params) {glGetShaderiv(obj, pname, params);}
1277 void wrapglGetProgramiv(GLuint obj, GLenum pname, GLint *params) {glGetProgramiv(obj, pname, params);}
1278 //void wrapglGetQueryObjectiv(GLuint qid, GLenum pname, GLint *params) {glGetQueryObjectiv(qid, pname, params);}
1279 //void wrapglGetQueryObjectuiv(GLuint qid, GLenum pname, GLuint *params) {glGetQueryObjectuiv(qid, pname, params);}
1280 //void wrapglGetQueryiv(GLenum target, GLenum pname, GLint *params) {glGetQueryiv(target, pname, params);}
1281 void wrapglGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params) {glGetRenderbufferParameteriv(target, pname, params);}
1282 void wrapglGetShaderSource(GLuint obj, GLsizei maxLength, GLsizei *length, GLchar *source) {glGetShaderSource(obj, maxLength, length, source);}
1283 void wrapglGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels) {Con_Printf("glGetTexImage(target, level, format, type, pixels)\n");}
1284 void wrapglGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params) {Con_Printf("glGetTexLevelParameterfv(target, level, pname, params)\n");}
1285 void wrapglGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) {Con_Printf("glGetTexLevelParameteriv(target, level, pname, params)\n");}
1286 void wrapglGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) {glGetTexParameterfv(target, pname, params);}
1287 void wrapglGetTexParameteriv(GLenum target, GLenum pname, GLint *params) {glGetTexParameteriv(target, pname, params);}
1288 void wrapglGetUniformfv(GLuint programObj, GLint location, GLfloat *params) {glGetUniformfv(programObj, location, params);}
1289 void wrapglGetUniformiv(GLuint programObj, GLint location, GLint *params) {glGetUniformiv(programObj, location, params);}
1290 void wrapglHint(GLenum target, GLenum mode) {glHint(target, mode);}
1291 void wrapglLineWidth(GLfloat width) {glLineWidth(width);}
1292 void wrapglLinkProgram(GLuint programObj) {glLinkProgram(programObj);}
1293 void wrapglLoadIdentity(void) {Con_Printf("glLoadIdentity()\n");}
1294 void wrapglLoadMatrixf(const GLfloat *m) {Con_Printf("glLoadMatrixf(m)\n");}
1295 void wrapglMatrixMode(GLenum mode) {Con_Printf("glMatrixMode(mode)\n");}
1296 void wrapglMultiTexCoord1f(GLenum target, GLfloat s) {Con_Printf("glMultiTexCoord1f(target, s)\n");}
1297 void wrapglMultiTexCoord2f(GLenum target, GLfloat s, GLfloat t) {Con_Printf("glMultiTexCoord2f(target, s, t)\n");}
1298 void wrapglMultiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r) {Con_Printf("glMultiTexCoord3f(target, s, t, r)\n");}
1299 void wrapglMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {Con_Printf("glMultiTexCoord4f(target, s, t, r, q)\n");}
1300 void wrapglNormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr) {Con_Printf("glNormalPointer(type, stride, ptr)\n");}
1301 void wrapglPixelStorei(GLenum pname, GLint param) {glPixelStorei(pname, param);}
1302 void wrapglPointSize(GLfloat size) {Con_Printf("glPointSize(size)\n");}
1303 void wrapglPolygonMode(GLenum face, GLenum mode) {Con_Printf("glPolygonMode(face, mode)\n");}
1304 void wrapglPolygonOffset(GLfloat factor, GLfloat units) {glPolygonOffset(factor, units);}
1305 void wrapglPolygonStipple(const GLubyte *mask) {Con_Printf("glPolygonStipple(mask)\n");}
1306 void wrapglReadBuffer(GLenum mode) {Con_Printf("glReadBuffer(mode)\n");}
1307 void wrapglReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {glReadPixels(x, y, width, height, format, type, pixels);}
1308 void wrapglRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {glRenderbufferStorage(target, internalformat, width, height);}
1309 void wrapglScissor(GLint x, GLint y, GLsizei width, GLsizei height) {glScissor(x, y, width, height);}
1310 void wrapglShaderSource(GLuint shaderObj, GLsizei count, const GLchar **string, const GLint *length) {glShaderSource(shaderObj, count, string, length);}
1311 void wrapglStencilFunc(GLenum func, GLint ref, GLuint mask) {glStencilFunc(func, ref, mask);}
1312 void wrapglStencilFuncSeparate(GLenum func1, GLenum func2, GLint ref, GLuint mask) {Con_Printf("glStencilFuncSeparate(func1, func2, ref, mask)\n");}
1313 void wrapglStencilMask(GLuint mask) {glStencilMask(mask);}
1314 void wrapglStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {glStencilOp(fail, zfail, zpass);}
1315 void wrapglStencilOpSeparate(GLenum e1, GLenum e2, GLenum e3, GLenum e4) {Con_Printf("glStencilOpSeparate(e1, e2, e3, e4)\n");}
1316 void wrapglTexCoord1f(GLfloat s) {Con_Printf("glTexCoord1f(s)\n");}
1317 void wrapglTexCoord2f(GLfloat s, GLfloat t) {Con_Printf("glTexCoord2f(s, t)\n");}
1318 void wrapglTexCoord3f(GLfloat s, GLfloat t, GLfloat r) {Con_Printf("glTexCoord3f(s, t, r)\n");}
1319 void wrapglTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) {Con_Printf("glTexCoord4f(s, t, r, q)\n");}
1320 void wrapglTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) {Con_Printf("glTexCoordPointer(size, type, stride, ptr)\n");}
1321 void wrapglTexEnvf(GLenum target, GLenum pname, GLfloat param) {Con_Printf("glTexEnvf(target, pname, param)\n");}
1322 void wrapglTexEnvfv(GLenum target, GLenum pname, const GLfloat *params) {Con_Printf("glTexEnvfv(target, pname, params)\n");}
1323 void wrapglTexEnvi(GLenum target, GLenum pname, GLint param) {Con_Printf("glTexEnvi(target, pname, param)\n");}
1324 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);}
1325 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");}
1326 void wrapglTexParameterf(GLenum target, GLenum pname, GLfloat param) {glTexParameterf(target, pname, param);}
1327 void wrapglTexParameterfv(GLenum target, GLenum pname, GLfloat *params) {glTexParameterfv(target, pname, params);}
1328 void wrapglTexParameteri(GLenum target, GLenum pname, GLint param) {glTexParameteri(target, pname, param);}
1329 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);}
1330 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");}
1331 void wrapglUniform1f(GLint location, GLfloat v0) {glUniform1f(location, v0);}
1332 void wrapglUniform1fv(GLint location, GLsizei count, const GLfloat *value) {glUniform1fv(location, count, value);}
1333 void wrapglUniform1i(GLint location, GLint v0) {glUniform1i(location, v0);}
1334 void wrapglUniform1iv(GLint location, GLsizei count, const GLint *value) {glUniform1iv(location, count, value);}
1335 void wrapglUniform2f(GLint location, GLfloat v0, GLfloat v1) {glUniform2f(location, v0, v1);}
1336 void wrapglUniform2fv(GLint location, GLsizei count, const GLfloat *value) {glUniform2fv(location, count, value);}
1337 void wrapglUniform2i(GLint location, GLint v0, GLint v1) {glUniform2i(location, v0, v1);}
1338 void wrapglUniform2iv(GLint location, GLsizei count, const GLint *value) {glUniform2iv(location, count, value);}
1339 void wrapglUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {glUniform3f(location, v0, v1, v2);}
1340 void wrapglUniform3fv(GLint location, GLsizei count, const GLfloat *value) {glUniform3fv(location, count, value);}
1341 void wrapglUniform3i(GLint location, GLint v0, GLint v1, GLint v2) {glUniform3i(location, v0, v1, v2);}
1342 void wrapglUniform3iv(GLint location, GLsizei count, const GLint *value) {glUniform3iv(location, count, value);}
1343 void wrapglUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {glUniform4f(location, v0, v1, v2, v3);}
1344 void wrapglUniform4fv(GLint location, GLsizei count, const GLfloat *value) {glUniform4fv(location, count, value);}
1345 void wrapglUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {glUniform4i(location, v0, v1, v2, v3);}
1346 void wrapglUniform4iv(GLint location, GLsizei count, const GLint *value) {glUniform4iv(location, count, value);}
1347 void wrapglUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {glUniformMatrix2fv(location, count, transpose, value);}
1348 void wrapglUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {glUniformMatrix3fv(location, count, transpose, value);}
1349 void wrapglUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {glUniformMatrix4fv(location, count, transpose, value);}
1350 void wrapglUseProgram(GLuint programObj) {glUseProgram(programObj);}
1351 void wrapglValidateProgram(GLuint programObj) {glValidateProgram(programObj);}
1352 void wrapglVertex2f(GLfloat x, GLfloat y) {Con_Printf("glVertex2f(x, y)\n");}
1353 void wrapglVertex3f(GLfloat x, GLfloat y, GLfloat z) {Con_Printf("glVertex3f(x, y, z)\n");}
1354 void wrapglVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {Con_Printf("glVertex4f(x, y, z, w)\n");}
1355 void wrapglVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) {glVertexAttribPointer(index, size, type, normalized, stride, pointer);}
1356 void wrapglVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) {Con_Printf("glVertexPointer(size, type, stride, ptr)\n");}
1357 void wrapglViewport(GLint x, GLint y, GLsizei width, GLsizei height) {glViewport(x, y, width, height);}
1358 void wrapglVertexAttrib1f(GLuint index, GLfloat v0) {glVertexAttrib1f(index, v0);}
1359 //void wrapglVertexAttrib1s(GLuint index, GLshort v0) {glVertexAttrib1s(index, v0);}
1360 //void wrapglVertexAttrib1d(GLuint index, GLdouble v0) {glVertexAttrib1d(index, v0);}
1361 void wrapglVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {glVertexAttrib2f(index, v0, v1);}
1362 //void wrapglVertexAttrib2s(GLuint index, GLshort v0, GLshort v1) {glVertexAttrib2s(index, v0, v1);}
1363 //void wrapglVertexAttrib2d(GLuint index, GLdouble v0, GLdouble v1) {glVertexAttrib2d(index, v0, v1);}
1364 void wrapglVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {glVertexAttrib3f(index, v0, v1, v2);}
1365 //void wrapglVertexAttrib3s(GLuint index, GLshort v0, GLshort v1, GLshort v2) {glVertexAttrib3s(index, v0, v1, v2);}
1366 //void wrapglVertexAttrib3d(GLuint index, GLdouble v0, GLdouble v1, GLdouble v2) {glVertexAttrib3d(index, v0, v1, v2);}
1367 void wrapglVertexAttrib4f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {glVertexAttrib4f(index, v0, v1, v2, v3);}
1368 //void wrapglVertexAttrib4s(GLuint index, GLshort v0, GLshort v1, GLshort v2, GLshort v3) {glVertexAttrib4s(index, v0, v1, v2, v3);}
1369 //void wrapglVertexAttrib4d(GLuint index, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3) {glVertexAttrib4d(index, v0, v1, v2, v3);}
1370 //void wrapglVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) {glVertexAttrib4Nub(index, x, y, z, w);}
1371 void wrapglVertexAttrib1fv(GLuint index, const GLfloat *v) {glVertexAttrib1fv(index, v);}
1372 //void wrapglVertexAttrib1sv(GLuint index, const GLshort *v) {glVertexAttrib1sv(index, v);}
1373 //void wrapglVertexAttrib1dv(GLuint index, const GLdouble *v) {glVertexAttrib1dv(index, v);}
1374 void wrapglVertexAttrib2fv(GLuint index, const GLfloat *v) {glVertexAttrib2fv(index, v);}
1375 //void wrapglVertexAttrib2sv(GLuint index, const GLshort *v) {glVertexAttrib2sv(index, v);}
1376 //void wrapglVertexAttrib2dv(GLuint index, const GLdouble *v) {glVertexAttrib2dv(index, v);}
1377 void wrapglVertexAttrib3fv(GLuint index, const GLfloat *v) {glVertexAttrib3fv(index, v);}
1378 //void wrapglVertexAttrib3sv(GLuint index, const GLshort *v) {glVertexAttrib3sv(index, v);}
1379 //void wrapglVertexAttrib3dv(GLuint index, const GLdouble *v) {glVertexAttrib3dv(index, v);}
1380 void wrapglVertexAttrib4fv(GLuint index, const GLfloat *v) {glVertexAttrib4fv(index, v);}
1381 //void wrapglVertexAttrib4sv(GLuint index, const GLshort *v) {glVertexAttrib4sv(index, v);}
1382 //void wrapglVertexAttrib4dv(GLuint index, const GLdouble *v) {glVertexAttrib4dv(index, v);}
1383 //void wrapglVertexAttrib4iv(GLuint index, const GLint *v) {glVertexAttrib4iv(index, v);}
1384 //void wrapglVertexAttrib4bv(GLuint index, const GLbyte *v) {glVertexAttrib4bv(index, v);}
1385 //void wrapglVertexAttrib4ubv(GLuint index, const GLubyte *v) {glVertexAttrib4ubv(index, v);}
1386 //void wrapglVertexAttrib4usv(GLuint index, const GLushort *v) {glVertexAttrib4usv(index, GLushort v);}
1387 //void wrapglVertexAttrib4uiv(GLuint index, const GLuint *v) {glVertexAttrib4uiv(index, v);}
1388 //void wrapglVertexAttrib4Nbv(GLuint index, const GLbyte *v) {glVertexAttrib4Nbv(index, v);}
1389 //void wrapglVertexAttrib4Nsv(GLuint index, const GLshort *v) {glVertexAttrib4Nsv(index, v);}
1390 //void wrapglVertexAttrib4Niv(GLuint index, const GLint *v) {glVertexAttrib4Niv(index, v);}
1391 //void wrapglVertexAttrib4Nubv(GLuint index, const GLubyte *v) {glVertexAttrib4Nubv(index, v);}
1392 //void wrapglVertexAttrib4Nusv(GLuint index, const GLushort *v) {glVertexAttrib4Nusv(index, GLushort v);}
1393 //void wrapglVertexAttrib4Nuiv(GLuint index, const GLuint *v) {glVertexAttrib4Nuiv(index, v);}
1394 //void wrapglGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) {glGetVertexAttribdv(index, pname, params);}
1395 void wrapglGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params) {glGetVertexAttribfv(index, pname, params);}
1396 void wrapglGetVertexAttribiv(GLuint index, GLenum pname, GLint *params) {glGetVertexAttribiv(index, pname, params);}
1397 void wrapglGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer) {glGetVertexAttribPointerv(index, pname, pointer);}
1398
1399 void GLES_Init(void)
1400 {
1401         qglIsBufferARB = wrapglIsBuffer;
1402         qglIsEnabled = wrapglIsEnabled;
1403         qglIsFramebufferEXT = wrapglIsFramebuffer;
1404 //      qglIsQueryARB = wrapglIsQuery;
1405         qglIsRenderbufferEXT = wrapglIsRenderbuffer;
1406 //      qglUnmapBufferARB = wrapglUnmapBuffer;
1407         qglCheckFramebufferStatusEXT = wrapglCheckFramebufferStatus;
1408         qglGetError = wrapglGetError;
1409         qglCreateProgram = wrapglCreateProgram;
1410         qglCreateShader = wrapglCreateShader;
1411 //      qglGetHandleARB = wrapglGetHandle;
1412         qglGetAttribLocation = wrapglGetAttribLocation;
1413         qglGetUniformLocation = wrapglGetUniformLocation;
1414 //      qglMapBufferARB = wrapglMapBuffer;
1415         qglGetString = wrapglGetString;
1416 //      qglActiveStencilFaceEXT = wrapglActiveStencilFace;
1417         qglActiveTexture = wrapglActiveTexture;
1418         qglAlphaFunc = wrapglAlphaFunc;
1419         qglArrayElement = wrapglArrayElement;
1420         qglAttachShader = wrapglAttachShader;
1421         qglBegin = wrapglBegin;
1422 //      qglBeginQueryARB = wrapglBeginQuery;
1423         qglBindAttribLocation = wrapglBindAttribLocation;
1424         qglBindBufferARB = wrapglBindBuffer;
1425         qglBindFramebufferEXT = wrapglBindFramebuffer;
1426         qglBindRenderbufferEXT = wrapglBindRenderbuffer;
1427         qglBindTexture = wrapglBindTexture;
1428         qglBlendEquationEXT = wrapglBlendEquation;
1429         qglBlendFunc = wrapglBlendFunc;
1430         qglBufferDataARB = wrapglBufferData;
1431         qglBufferSubDataARB = wrapglBufferSubData;
1432         qglClear = wrapglClear;
1433         qglClearColor = wrapglClearColor;
1434         qglClearDepth = wrapglClearDepth;
1435         qglClearStencil = wrapglClearStencil;
1436         qglClientActiveTexture = wrapglClientActiveTexture;
1437         qglColor4f = wrapglColor4f;
1438         qglColor4ub = wrapglColor4ub;
1439         qglColorMask = wrapglColorMask;
1440         qglColorPointer = wrapglColorPointer;
1441         qglCompileShader = wrapglCompileShader;
1442         qglCompressedTexImage2DARB = wrapglCompressedTexImage2D;
1443         qglCompressedTexImage3DARB = wrapglCompressedTexImage3D;
1444         qglCompressedTexSubImage2DARB = wrapglCompressedTexSubImage2D;
1445         qglCompressedTexSubImage3DARB = wrapglCompressedTexSubImage3D;
1446         qglCopyTexImage2D = wrapglCopyTexImage2D;
1447         qglCopyTexSubImage2D = wrapglCopyTexSubImage2D;
1448         qglCopyTexSubImage3D = wrapglCopyTexSubImage3D;
1449         qglCullFace = wrapglCullFace;
1450         qglDeleteBuffersARB = wrapglDeleteBuffers;
1451         qglDeleteFramebuffersEXT = wrapglDeleteFramebuffers;
1452         qglDeleteProgram = wrapglDeleteProgram;
1453         qglDeleteShader = wrapglDeleteShader;
1454 //      qglDeleteQueriesARB = wrapglDeleteQueries;
1455         qglDeleteRenderbuffersEXT = wrapglDeleteRenderbuffers;
1456         qglDeleteTextures = wrapglDeleteTextures;
1457         qglDepthFunc = wrapglDepthFunc;
1458         qglDepthMask = wrapglDepthMask;
1459         qglDepthRange = wrapglDepthRange;
1460         qglDetachShader = wrapglDetachShader;
1461         qglDisable = wrapglDisable;
1462         qglDisableClientState = wrapglDisableClientState;
1463         qglDisableVertexAttribArray = wrapglDisableVertexAttribArray;
1464         qglDrawArrays = wrapglDrawArrays;
1465 //      qglDrawBuffer = wrapglDrawBuffer;
1466 //      qglDrawBuffersARB = wrapglDrawBuffers;
1467         qglDrawElements = wrapglDrawElements;
1468 //      qglDrawRangeElements = wrapglDrawRangeElements;
1469         qglEnable = wrapglEnable;
1470         qglEnableClientState = wrapglEnableClientState;
1471         qglEnableVertexAttribArray = wrapglEnableVertexAttribArray;
1472         qglEnd = wrapglEnd;
1473 //      qglEndQueryARB = wrapglEndQuery;
1474         qglFinish = wrapglFinish;
1475         qglFlush = wrapglFlush;
1476         qglFramebufferRenderbufferEXT = wrapglFramebufferRenderbuffer;
1477         qglFramebufferTexture2DEXT = wrapglFramebufferTexture2D;
1478         qglFramebufferTexture3DEXT = wrapglFramebufferTexture3D;
1479         qglGenBuffersARB = wrapglGenBuffers;
1480         qglGenFramebuffersEXT = wrapglGenFramebuffers;
1481 //      qglGenQueriesARB = wrapglGenQueries;
1482         qglGenRenderbuffersEXT = wrapglGenRenderbuffers;
1483         qglGenTextures = wrapglGenTextures;
1484         qglGenerateMipmapEXT = wrapglGenerateMipmap;
1485         qglGetActiveAttrib = wrapglGetActiveAttrib;
1486         qglGetActiveUniform = wrapglGetActiveUniform;
1487         qglGetAttachedShaders = wrapglGetAttachedShaders;
1488         qglGetBooleanv = wrapglGetBooleanv;
1489 //      qglGetCompressedTexImageARB = wrapglGetCompressedTexImage;
1490         qglGetDoublev = wrapglGetDoublev;
1491         qglGetFloatv = wrapglGetFloatv;
1492         qglGetFramebufferAttachmentParameterivEXT = wrapglGetFramebufferAttachmentParameteriv;
1493         qglGetProgramInfoLog = wrapglGetProgramInfoLog;
1494         qglGetShaderInfoLog = wrapglGetShaderInfoLog;
1495         qglGetIntegerv = wrapglGetIntegerv;
1496         qglGetShaderiv = wrapglGetShaderiv;
1497         qglGetProgramiv = wrapglGetProgramiv;
1498 //      qglGetQueryObjectivARB = wrapglGetQueryObjectiv;
1499 //      qglGetQueryObjectuivARB = wrapglGetQueryObjectuiv;
1500 //      qglGetQueryivARB = wrapglGetQueryiv;
1501         qglGetRenderbufferParameterivEXT = wrapglGetRenderbufferParameteriv;
1502         qglGetShaderSource = wrapglGetShaderSource;
1503         qglGetTexImage = wrapglGetTexImage;
1504         qglGetTexLevelParameterfv = wrapglGetTexLevelParameterfv;
1505         qglGetTexLevelParameteriv = wrapglGetTexLevelParameteriv;
1506         qglGetTexParameterfv = wrapglGetTexParameterfv;
1507         qglGetTexParameteriv = wrapglGetTexParameteriv;
1508         qglGetUniformfv = wrapglGetUniformfv;
1509         qglGetUniformiv = wrapglGetUniformiv;
1510         qglHint = wrapglHint;
1511         qglLineWidth = wrapglLineWidth;
1512         qglLinkProgram = wrapglLinkProgram;
1513         qglLoadIdentity = wrapglLoadIdentity;
1514         qglLoadMatrixf = wrapglLoadMatrixf;
1515         qglMatrixMode = wrapglMatrixMode;
1516         qglMultiTexCoord1f = wrapglMultiTexCoord1f;
1517         qglMultiTexCoord2f = wrapglMultiTexCoord2f;
1518         qglMultiTexCoord3f = wrapglMultiTexCoord3f;
1519         qglMultiTexCoord4f = wrapglMultiTexCoord4f;
1520         qglNormalPointer = wrapglNormalPointer;
1521         qglPixelStorei = wrapglPixelStorei;
1522         qglPointSize = wrapglPointSize;
1523         qglPolygonMode = wrapglPolygonMode;
1524         qglPolygonOffset = wrapglPolygonOffset;
1525 //      qglPolygonStipple = wrapglPolygonStipple;
1526         qglReadBuffer = wrapglReadBuffer;
1527         qglReadPixels = wrapglReadPixels;
1528         qglRenderbufferStorageEXT = wrapglRenderbufferStorage;
1529         qglScissor = wrapglScissor;
1530         qglShaderSource = wrapglShaderSource;
1531         qglStencilFunc = wrapglStencilFunc;
1532         qglStencilFuncSeparate = wrapglStencilFuncSeparate;
1533         qglStencilMask = wrapglStencilMask;
1534         qglStencilOp = wrapglStencilOp;
1535         qglStencilOpSeparate = wrapglStencilOpSeparate;
1536         qglTexCoord1f = wrapglTexCoord1f;
1537         qglTexCoord2f = wrapglTexCoord2f;
1538         qglTexCoord3f = wrapglTexCoord3f;
1539         qglTexCoord4f = wrapglTexCoord4f;
1540         qglTexCoordPointer = wrapglTexCoordPointer;
1541         qglTexEnvf = wrapglTexEnvf;
1542         qglTexEnvfv = wrapglTexEnvfv;
1543         qglTexEnvi = wrapglTexEnvi;
1544         qglTexImage2D = wrapglTexImage2D;
1545         qglTexImage3D = wrapglTexImage3D;
1546         qglTexParameterf = wrapglTexParameterf;
1547         qglTexParameterfv = wrapglTexParameterfv;
1548         qglTexParameteri = wrapglTexParameteri;
1549         qglTexSubImage2D = wrapglTexSubImage2D;
1550         qglTexSubImage3D = wrapglTexSubImage3D;
1551         qglUniform1f = wrapglUniform1f;
1552         qglUniform1fv = wrapglUniform1fv;
1553         qglUniform1i = wrapglUniform1i;
1554         qglUniform1iv = wrapglUniform1iv;
1555         qglUniform2f = wrapglUniform2f;
1556         qglUniform2fv = wrapglUniform2fv;
1557         qglUniform2i = wrapglUniform2i;
1558         qglUniform2iv = wrapglUniform2iv;
1559         qglUniform3f = wrapglUniform3f;
1560         qglUniform3fv = wrapglUniform3fv;
1561         qglUniform3i = wrapglUniform3i;
1562         qglUniform3iv = wrapglUniform3iv;
1563         qglUniform4f = wrapglUniform4f;
1564         qglUniform4fv = wrapglUniform4fv;
1565         qglUniform4i = wrapglUniform4i;
1566         qglUniform4iv = wrapglUniform4iv;
1567         qglUniformMatrix2fv = wrapglUniformMatrix2fv;
1568         qglUniformMatrix3fv = wrapglUniformMatrix3fv;
1569         qglUniformMatrix4fv = wrapglUniformMatrix4fv;
1570         qglUseProgram = wrapglUseProgram;
1571         qglValidateProgram = wrapglValidateProgram;
1572         qglVertex2f = wrapglVertex2f;
1573         qglVertex3f = wrapglVertex3f;
1574         qglVertex4f = wrapglVertex4f;
1575         qglVertexAttribPointer = wrapglVertexAttribPointer;
1576         qglVertexPointer = wrapglVertexPointer;
1577         qglViewport = wrapglViewport;
1578         qglVertexAttrib1f = wrapglVertexAttrib1f;
1579 //      qglVertexAttrib1s = wrapglVertexAttrib1s;
1580 //      qglVertexAttrib1d = wrapglVertexAttrib1d;
1581         qglVertexAttrib2f = wrapglVertexAttrib2f;
1582 //      qglVertexAttrib2s = wrapglVertexAttrib2s;
1583 //      qglVertexAttrib2d = wrapglVertexAttrib2d;
1584         qglVertexAttrib3f = wrapglVertexAttrib3f;
1585 //      qglVertexAttrib3s = wrapglVertexAttrib3s;
1586 //      qglVertexAttrib3d = wrapglVertexAttrib3d;
1587         qglVertexAttrib4f = wrapglVertexAttrib4f;
1588 //      qglVertexAttrib4s = wrapglVertexAttrib4s;
1589 //      qglVertexAttrib4d = wrapglVertexAttrib4d;
1590 //      qglVertexAttrib4Nub = wrapglVertexAttrib4Nub;
1591         qglVertexAttrib1fv = wrapglVertexAttrib1fv;
1592 //      qglVertexAttrib1sv = wrapglVertexAttrib1sv;
1593 //      qglVertexAttrib1dv = wrapglVertexAttrib1dv;
1594         qglVertexAttrib2fv = wrapglVertexAttrib2fv;
1595 //      qglVertexAttrib2sv = wrapglVertexAttrib2sv;
1596 //      qglVertexAttrib2dv = wrapglVertexAttrib2dv;
1597         qglVertexAttrib3fv = wrapglVertexAttrib3fv;
1598 //      qglVertexAttrib3sv = wrapglVertexAttrib3sv;
1599 //      qglVertexAttrib3dv = wrapglVertexAttrib3dv;
1600         qglVertexAttrib4fv = wrapglVertexAttrib4fv;
1601 //      qglVertexAttrib4sv = wrapglVertexAttrib4sv;
1602 //      qglVertexAttrib4dv = wrapglVertexAttrib4dv;
1603 //      qglVertexAttrib4iv = wrapglVertexAttrib4iv;
1604 //      qglVertexAttrib4bv = wrapglVertexAttrib4bv;
1605 //      qglVertexAttrib4ubv = wrapglVertexAttrib4ubv;
1606 //      qglVertexAttrib4usv = wrapglVertexAttrib4usv;
1607 //      qglVertexAttrib4uiv = wrapglVertexAttrib4uiv;
1608 //      qglVertexAttrib4Nbv = wrapglVertexAttrib4Nbv;
1609 //      qglVertexAttrib4Nsv = wrapglVertexAttrib4Nsv;
1610 //      qglVertexAttrib4Niv = wrapglVertexAttrib4Niv;
1611 //      qglVertexAttrib4Nubv = wrapglVertexAttrib4Nubv;
1612 //      qglVertexAttrib4Nusv = wrapglVertexAttrib4Nusv;
1613 //      qglVertexAttrib4Nuiv = wrapglVertexAttrib4Nuiv;
1614 //      qglGetVertexAttribdv = wrapglGetVertexAttribdv;
1615         qglGetVertexAttribfv = wrapglGetVertexAttribfv;
1616         qglGetVertexAttribiv = wrapglGetVertexAttribiv;
1617         qglGetVertexAttribPointerv = wrapglGetVertexAttribPointerv;
1618
1619         gl_renderer = (const char *)qglGetString(GL_RENDERER);
1620         gl_vendor = (const char *)qglGetString(GL_VENDOR);
1621         gl_version = (const char *)qglGetString(GL_VERSION);
1622         gl_extensions = (const char *)qglGetString(GL_EXTENSIONS);
1623         
1624         if (!gl_extensions)
1625                 gl_extensions = "";
1626         if (!gl_platformextensions)
1627                 gl_platformextensions = "";
1628         
1629         Con_Printf("GL_VENDOR: %s\n", gl_vendor);
1630         Con_Printf("GL_RENDERER: %s\n", gl_renderer);
1631         Con_Printf("GL_VERSION: %s\n", gl_version);
1632         Con_DPrintf("GL_EXTENSIONS: %s\n", gl_extensions);
1633         Con_DPrintf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions);
1634         
1635         // LordHavoc: report supported extensions
1636         Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions );
1637         
1638         vid.support.gl20shaders = true;
1639         vid.support.amd_texture_texture4 = false;
1640         vid.support.arb_depth_texture = false;
1641         vid.support.arb_draw_buffers = false;
1642         vid.support.arb_multitexture = false;
1643         vid.support.arb_occlusion_query = false;
1644         vid.support.arb_shadow = false;
1645         vid.support.arb_texture_compression = false; // different (vendor-specific) formats than on desktop OpenGL...
1646         vid.support.arb_texture_cube_map = true;
1647         vid.support.arb_texture_env_combine = false;
1648         vid.support.arb_texture_gather = false;
1649         vid.support.arb_texture_non_power_of_two = strstr(gl_extensions, "GL_OES_texture_npot") != NULL;
1650         vid.support.arb_vertex_buffer_object = true;
1651         vid.support.ati_separate_stencil = false;
1652         vid.support.ext_blend_minmax = false;
1653         vid.support.ext_blend_subtract = true;
1654         vid.support.ext_draw_range_elements = true;
1655         vid.support.ext_framebuffer_object = false;//true;
1656         vid.support.ext_stencil_two_side = false;
1657         vid.support.ext_texture_3d = false;//SDL_GL_ExtensionSupported("GL_OES_texture_3D"); // iPhoneOS does not support 3D textures, odd...
1658         vid.support.ext_texture_compression_s3tc = false;
1659         vid.support.ext_texture_edge_clamp = true;
1660         vid.support.ext_texture_filter_anisotropic = false; // probably don't want to use it...
1661
1662         qglGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_2d);
1663         if (vid.support.ext_texture_filter_anisotropic)
1664                 qglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, (GLint*)&vid.max_anisotropy);
1665         if (vid.support.arb_texture_cube_map)
1666                 qglGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, (GLint*)&vid.maxtexturesize_cubemap);
1667         if (vid.support.ext_texture_3d)
1668                 qglGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_3d);
1669         Con_Printf("GL_MAX_CUBE_MAP_TEXTURE_SIZE = %i\n", vid.maxtexturesize_cubemap);
1670         Con_Printf("GL_MAX_3D_TEXTURE_SIZE = %i\n", vid.maxtexturesize_3d);
1671
1672         // verify that cubemap textures are really supported
1673         if (vid.support.arb_texture_cube_map && vid.maxtexturesize_cubemap < 256)
1674                 vid.support.arb_texture_cube_map = false;
1675         
1676         // verify that 3d textures are really supported
1677         if (vid.support.ext_texture_3d && vid.maxtexturesize_3d < 32)
1678         {
1679                 vid.support.ext_texture_3d = false;
1680                 Con_Printf("GL_OES_texture_3d reported bogus GL_MAX_3D_TEXTURE_SIZE, disabled\n");
1681         }
1682
1683         vid.texunits = 4;
1684         vid.teximageunits = 8;
1685         vid.texarrayunits = 5;
1686         vid.texunits = bound(1, vid.texunits, MAX_TEXTUREUNITS);
1687         vid.teximageunits = bound(1, vid.teximageunits, MAX_TEXTUREUNITS);
1688         vid.texarrayunits = bound(1, vid.texarrayunits, MAX_TEXTUREUNITS);
1689         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" : "");
1690         vid.renderpath = RENDERPATH_GLES2;
1691         vid.useinterleavedarrays = false;
1692
1693         // VorteX: set other info (maybe place them in VID_InitMode?)
1694         extern cvar_t gl_info_vendor;
1695         extern cvar_t gl_info_renderer;
1696         extern cvar_t gl_info_version;
1697         extern cvar_t gl_info_platform;
1698         extern cvar_t gl_info_driver;
1699         Cvar_SetQuick(&gl_info_vendor, gl_vendor);
1700         Cvar_SetQuick(&gl_info_renderer, gl_renderer);
1701         Cvar_SetQuick(&gl_info_version, gl_version);
1702         Cvar_SetQuick(&gl_info_platform, gl_platform ? gl_platform : "");
1703         Cvar_SetQuick(&gl_info_driver, gl_driver);
1704 }
1705 #endif
1706
1707 void *GL_GetProcAddress(const char *name)
1708 {
1709         void *p = NULL;
1710         p = SDL_GL_GetProcAddress(name);
1711         return p;
1712 }
1713
1714 static qboolean vid_sdl_initjoysticksystem = false;
1715
1716 void VID_Init (void)
1717 {
1718 #ifndef __IPHONEOS__
1719 #ifdef MACOSX
1720         Cvar_RegisterVariable(&apple_mouse_noaccel);
1721 #endif
1722 #endif
1723         Cvar_RegisterVariable(&vid_soft);
1724         Cvar_RegisterVariable(&vid_soft_threads);
1725         Cvar_RegisterVariable(&vid_soft_interlace);
1726         Cvar_RegisterVariable(&joy_detected);
1727         Cvar_RegisterVariable(&joy_enable);
1728         Cvar_RegisterVariable(&joy_index);
1729         Cvar_RegisterVariable(&joy_axisforward);
1730         Cvar_RegisterVariable(&joy_axisside);
1731         Cvar_RegisterVariable(&joy_axisup);
1732         Cvar_RegisterVariable(&joy_axispitch);
1733         Cvar_RegisterVariable(&joy_axisyaw);
1734         //Cvar_RegisterVariable(&joy_axisroll);
1735         Cvar_RegisterVariable(&joy_deadzoneforward);
1736         Cvar_RegisterVariable(&joy_deadzoneside);
1737         Cvar_RegisterVariable(&joy_deadzoneup);
1738         Cvar_RegisterVariable(&joy_deadzonepitch);
1739         Cvar_RegisterVariable(&joy_deadzoneyaw);
1740         //Cvar_RegisterVariable(&joy_deadzoneroll);
1741         Cvar_RegisterVariable(&joy_sensitivityforward);
1742         Cvar_RegisterVariable(&joy_sensitivityside);
1743         Cvar_RegisterVariable(&joy_sensitivityup);
1744         Cvar_RegisterVariable(&joy_sensitivitypitch);
1745         Cvar_RegisterVariable(&joy_sensitivityyaw);
1746         //Cvar_RegisterVariable(&joy_sensitivityroll);
1747         Cvar_RegisterVariable(&joy_axiskeyevents);
1748 #ifdef __IPHONEOS__
1749         Cvar_SetValueQuick(&vid_touchscreen, 1);
1750 #endif
1751
1752 #ifdef SDL_R_RESTART
1753         R_RegisterModule("SDL", sdl_start, sdl_shutdown, sdl_newmap, NULL, NULL);
1754 #endif
1755
1756         if (SDL_Init(SDL_INIT_VIDEO) < 0)
1757                 Sys_Error ("Failed to init SDL video subsystem: %s", SDL_GetError());
1758         vid_sdl_initjoysticksystem = SDL_InitSubSystem(SDL_INIT_JOYSTICK) >= 0;
1759         if (vid_sdl_initjoysticksystem)
1760                 Con_Printf("Failed to init SDL joystick subsystem: %s\n", SDL_GetError());
1761         vid_isfullscreen = false;
1762 }
1763
1764 #if SETVIDEOMODE
1765 // set the icon (we dont use SDL here since it would be too much a PITA)
1766 #ifdef WIN32
1767 #include "resource.h"
1768 #include <SDL_syswm.h>
1769 static void VID_SetCaption(void)
1770 {
1771     SDL_SysWMinfo       info;
1772         HICON                   icon;
1773
1774         // set the caption
1775         SDL_WM_SetCaption( gamename, NULL );
1776
1777         // get the HWND handle
1778     SDL_VERSION( &info.version );
1779         if( !SDL_GetWMInfo( &info ) )
1780                 return;
1781
1782         icon = LoadIcon( GetModuleHandle( NULL ), MAKEINTRESOURCE( IDI_ICON1 ) );
1783 #ifndef _W64 //If Windows 64bit data types don't exist
1784 #ifndef SetClassLongPtr
1785 #define SetClassLongPtr SetClassLong
1786 #endif
1787 #ifndef GCLP_HICON
1788 #define GCLP_HICON GCL_HICON
1789 #endif
1790 #ifndef LONG_PTR
1791 #define LONG_PTR LONG
1792 #endif
1793 #endif
1794         SetClassLongPtr( info.window, GCLP_HICON, (LONG_PTR)icon );
1795 }
1796 static void VID_SetIcon_Pre(void)
1797 {
1798 }
1799 static void VID_SetIcon_Post(void)
1800 {
1801 }
1802 #else
1803 // Adding the OS independent XPM version --blub
1804 #include "darkplaces.xpm"
1805 #include "nexuiz.xpm"
1806 static SDL_Surface *icon = NULL;
1807 static void VID_SetIcon_Pre(void)
1808 {
1809         /*
1810          * Somewhat restricted XPM reader. Only supports XPMs saved by GIMP 2.4 at
1811          * default settings with less than 91 colors and transparency.
1812          */
1813
1814         int width, height, colors, isize, i, j;
1815         int thenone = -1;
1816         static SDL_Color palette[256];
1817         unsigned short palenc[256]; // store color id by char
1818         char *xpm;
1819         char **idata, *data;
1820         const SDL_version *version;
1821
1822         version = SDL_Linked_Version();
1823         // only use non-XPM icon support in SDL v1.3 and higher
1824         // SDL v1.2 does not support "smooth" transparency, and thus is better
1825         // off the xpm way
1826         if(version->major >= 2 || (version->major == 1 && version->minor >= 3))
1827         {
1828                 data = (char *) loadimagepixelsbgra("darkplaces-icon", false, false, false, NULL);
1829                 if(data)
1830                 {
1831                         unsigned int red = 0x00FF0000;
1832                         unsigned int green = 0x0000FF00;
1833                         unsigned int blue = 0x000000FF;
1834                         unsigned int alpha = 0xFF000000;
1835                         width = image_width;
1836                         height = image_height;
1837
1838                         // reallocate with malloc, as this is in tempmempool (do not want)
1839                         xpm = data;
1840                         data = malloc(width * height * 4);
1841                         memcpy(data, xpm, width * height * 4);
1842                         Mem_Free(xpm);
1843                         xpm = NULL;
1844
1845                         icon = SDL_CreateRGBSurface(SDL_SRCALPHA, width, height, 32, LittleLong(red), LittleLong(green), LittleLong(blue), LittleLong(alpha));
1846
1847                         if(icon == NULL) {
1848                                 Con_Printf(     "Failed to create surface for the window Icon!\n"
1849                                                 "%s\n", SDL_GetError());
1850                                 free(data);
1851                                 return;
1852                         }
1853
1854                         icon->pixels = data;
1855                 }
1856         }
1857
1858         // we only get here if non-XPM icon was missing, or SDL version is not
1859         // sufficient for transparent non-XPM icons
1860         if(!icon)
1861         {
1862                 xpm = (char *) FS_LoadFile("darkplaces-icon.xpm", tempmempool, false, NULL);
1863                 idata = NULL;
1864                 if(xpm)
1865                         idata = XPM_DecodeString(xpm);
1866                 if(!idata)
1867                         idata = ENGINE_ICON;
1868                 if(xpm)
1869                         Mem_Free(xpm);
1870
1871                 data = idata[0];
1872
1873                 if(sscanf(data, "%i %i %i %i", &width, &height, &colors, &isize) != 4)
1874                 {
1875                         // NOTE: Only 1-char colornames are supported
1876                         Con_Printf("Sorry, but this does not even look similar to an XPM.\n");
1877                         return;
1878                 }
1879
1880                 if(isize != 1)
1881                 {
1882                         // NOTE: Only 1-char colornames are supported
1883                         Con_Printf("This XPM's palette is either huge or idiotically unoptimized. It's key size is %i\n", isize);
1884                         return;
1885                 }
1886
1887                 for(i = 0; i < colors; ++i)
1888                 {
1889                         unsigned int r, g, b;
1890                         char idx;
1891
1892                         if(sscanf(idata[i+1], "%c c #%02x%02x%02x", &idx, &r, &g, &b) != 4)
1893                         {
1894                                 char foo[2];
1895                                 if(sscanf(idata[i+1], "%c c Non%1[e]", &idx, foo) != 2) // I take the DailyWTF credit for this. --div0
1896                                 {
1897                                         Con_Printf("This XPM's palette looks odd. Can't continue.\n");
1898                                         return;
1899                                 }
1900                                 else
1901                                 {
1902                                         palette[i].r = 255; // color key
1903                                         palette[i].g = 0;
1904                                         palette[i].b = 255;
1905                                         thenone = i; // weeeee
1906                                 }
1907                         }
1908                         else
1909                         {
1910                                 palette[i].r = r - (r == 255 && g == 0 && b == 255); // change 255/0/255 pink to 254/0/255 for color key
1911                                 palette[i].g = g;
1912                                 palette[i].b = b;
1913                         }
1914
1915                         palenc[(unsigned char) idx] = i;
1916                 }
1917
1918                 // allocate the image data
1919                 data = (char*) malloc(width*height);
1920
1921                 for(j = 0; j < height; ++j)
1922                 {
1923                         for(i = 0; i < width; ++i)
1924                         {
1925                                 // casting to the safest possible datatypes ^^
1926                                 data[j * width + i] = palenc[((unsigned char*)idata[colors+j+1])[i]];
1927                         }
1928                 }
1929
1930                 if(icon != NULL)
1931                 {
1932                         // SDL_FreeSurface should free the data too
1933                         // but for completeness' sake...
1934                         if(icon->flags & SDL_PREALLOC)
1935                         {
1936                                 free(icon->pixels);
1937                                 icon->pixels = NULL; // safety
1938                         }
1939                         SDL_FreeSurface(icon);
1940                 }
1941
1942                 icon = SDL_CreateRGBSurface(SDL_SRCCOLORKEY, width, height, 8, 0,0,0,0);// rmask, gmask, bmask, amask); no mask needed
1943                 // 8 bit surfaces get an empty palette allocated according to the docs
1944                 // so it's a palette image for sure :) no endian check necessary for the mask
1945
1946                 if(icon == NULL) {
1947                         Con_Printf(     "Failed to create surface for the window Icon!\n"
1948                                         "%s\n", SDL_GetError());
1949                         free(data);
1950                         return;
1951                 }
1952
1953                 icon->pixels = data;
1954                 SDL_SetPalette(icon, SDL_PHYSPAL|SDL_LOGPAL, palette, 0, colors);
1955                 SDL_SetColorKey(icon, SDL_SRCCOLORKEY, thenone);
1956         }
1957
1958         SDL_WM_SetIcon(icon, NULL);
1959 }
1960 static void VID_SetIcon_Post(void)
1961 {
1962 #if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION == 2
1963 // LordHavoc: info.info.x11.lock_func and accompanying code do not seem to compile with SDL 1.3
1964 #if SDL_VIDEO_DRIVER_X11 && !SDL_VIDEO_DRIVER_QUARTZ
1965         int j;
1966         char *data;
1967         const SDL_version *version;
1968
1969         version = SDL_Linked_Version();
1970         // only use non-XPM icon support in SDL v1.3 and higher
1971         // SDL v1.2 does not support "smooth" transparency, and thus is better
1972         // off the xpm way
1973         if(!(version->major >= 2 || (version->major == 1 && version->minor >= 3)))
1974         {
1975                 // in this case, we did not set the good icon yet
1976                 SDL_SysWMinfo info;
1977                 SDL_VERSION(&info.version);
1978                 if(SDL_GetWMInfo(&info) == 1 && info.subsystem == SDL_SYSWM_X11)
1979                 {
1980                         data = (char *) loadimagepixelsbgra("darkplaces-icon", false, false, false, NULL);
1981                         if(data)
1982                         {
1983                                 // use _NET_WM_ICON too
1984                                 static long netwm_icon[MAX_NETWM_ICON];
1985                                 int pos = 0;
1986                                 int i = 1;
1987
1988                                 while(data)
1989                                 {
1990                                         if(pos + 2 * image_width * image_height < MAX_NETWM_ICON)
1991                                         {
1992                                                 netwm_icon[pos++] = image_width;
1993                                                 netwm_icon[pos++] = image_height;
1994                                                 for(i = 0; i < image_height; ++i)
1995                                                         for(j = 0; j < image_width; ++j)
1996                                                                 netwm_icon[pos++] = BuffLittleLong((unsigned char *) &data[(i*image_width+j)*4]);
1997                                         }
1998                                         else
1999                                         {
2000                                                 Con_Printf("Skipping NETWM icon #%d because there is no space left\n", i);
2001                                         }
2002                                         ++i;
2003                                         Mem_Free(data);
2004                                         data = (char *) loadimagepixelsbgra(va("darkplaces-icon%d", i), false, false, false, NULL);
2005                                 }
2006
2007                                 info.info.x11.lock_func();
2008                                 {
2009                                         Atom net_wm_icon = XInternAtom(info.info.x11.display, "_NET_WM_ICON", false);
2010                                         XChangeProperty(info.info.x11.display, info.info.x11.wmwindow, net_wm_icon, XA_CARDINAL, 32, PropModeReplace, (const unsigned char *) netwm_icon, pos);
2011                                 }
2012                                 info.info.x11.unlock_func();
2013                         }
2014                 }
2015         }
2016 #endif
2017 #endif
2018 }
2019
2020
2021 static void VID_SetCaption(void)
2022 {
2023         SDL_WM_SetCaption( gamename, NULL );
2024 }
2025 #endif
2026 #endif
2027
2028 static void VID_OutputVersion(void)
2029 {
2030         const SDL_version *version;
2031         version = SDL_Linked_Version();
2032         Con_Printf(     "Linked against SDL version %d.%d.%d\n"
2033                                         "Using SDL library version %d.%d.%d\n",
2034                                         SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL,
2035                                         version->major, version->minor, version->patch );
2036 }
2037
2038 qboolean VID_InitModeGL(viddef_mode_t *mode)
2039 {
2040         int i;
2041 #if SETVIDEOMODE
2042         static int notfirstvideomode = false;
2043         int flags = SDL_OPENGL;
2044 #else
2045         int windowflags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL;
2046 #endif
2047         const char *drivername;
2048
2049         win_half_width = mode->width>>1;
2050         win_half_height = mode->height>>1;
2051
2052         if(vid_resizable.integer)
2053 #if SETVIDEOMODE
2054                 flags |= SDL_RESIZABLE;
2055 #else
2056                 windowflags |= SDL_WINDOW_RESIZABLE;
2057 #endif
2058
2059         VID_OutputVersion();
2060
2061 #if SETVIDEOMODE
2062         /*
2063         SDL 1.2 Hack
2064                 We cant switch from one OpenGL video mode to another.
2065                 Thus we first switch to some stupid 2D mode and then back to OpenGL.
2066         */
2067         if (notfirstvideomode)
2068                 SDL_SetVideoMode( 0, 0, 0, 0 );
2069         notfirstvideomode = true;
2070 #endif
2071
2072         // SDL usually knows best
2073         drivername = NULL;
2074
2075 // 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
2076         i = COM_CheckParm("-gl_driver");
2077         if (i && i < com_argc - 1)
2078                 drivername = com_argv[i + 1];
2079         if (SDL_GL_LoadLibrary(drivername) < 0)
2080         {
2081                 Con_Printf("Unable to load GL driver \"%s\": %s\n", drivername, SDL_GetError());
2082                 return false;
2083         }
2084
2085 #ifdef __IPHONEOS__
2086         // mobile platforms are always fullscreen, we'll get the resolution after opening the window
2087         mode->fullscreen = true;
2088         // hide the menu with SDL_WINDOW_BORDERLESS
2089         windowflags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS;
2090 #else
2091         if ((qglGetString = (const GLubyte* (GLAPIENTRY *)(GLenum name))GL_GetProcAddress("glGetString")) == NULL)
2092         {
2093                 VID_Shutdown();
2094                 Con_Print("Required OpenGL function glGetString not found\n");
2095                 return false;
2096         }
2097 #endif
2098
2099         // Knghtbrd: should do platform-specific extension string function here
2100
2101         vid_isfullscreen = false;
2102         if (mode->fullscreen) {
2103 #if SETVIDEOMODE
2104                 flags |= SDL_FULLSCREEN;
2105 #else
2106                 windowflags |= SDL_WINDOW_FULLSCREEN;
2107 #endif
2108                 vid_isfullscreen = true;
2109         }
2110         //flags |= SDL_HWSURFACE;
2111
2112         SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
2113         if (mode->bitsperpixel >= 32)
2114         {
2115                 SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 8);
2116                 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 8);
2117                 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 8);
2118                 SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, 8);
2119                 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 24);
2120                 SDL_GL_SetAttribute (SDL_GL_STENCIL_SIZE, 8);
2121         }
2122         else
2123         {
2124                 SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5);
2125                 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5);
2126                 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5);
2127                 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 16);
2128         }
2129         if (mode->stereobuffer)
2130                 SDL_GL_SetAttribute (SDL_GL_STEREO, 1);
2131         if (mode->samples > 1)
2132         {
2133                 SDL_GL_SetAttribute (SDL_GL_MULTISAMPLEBUFFERS, 1);
2134                 SDL_GL_SetAttribute (SDL_GL_MULTISAMPLESAMPLES, mode->samples);
2135         }
2136 #if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION == 2
2137         if (vid_vsync.integer)
2138                 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1);
2139         else
2140                 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 0);
2141 #else
2142 #ifdef __IPHONEOS__
2143         SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
2144         SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0);
2145         SDL_GL_SetAttribute (SDL_GL_RETAINED_BACKING, 1);
2146         // FIXME: get proper resolution from OS somehow (iPad for instance...)
2147         mode->width = 320;
2148         mode->height = 480;
2149 #endif
2150 #endif
2151
2152         video_bpp = mode->bitsperpixel;
2153 #if SETVIDEOMODE
2154         video_flags = flags;
2155         VID_SetIcon_Pre();
2156         screen = SDL_SetVideoMode(mode->width, mode->height, mode->bitsperpixel, flags);
2157         VID_SetIcon_Post();
2158         if (screen == NULL)
2159         {
2160                 Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError());
2161                 VID_Shutdown();
2162                 return false;
2163         }
2164         mode->width = screen->w;
2165         mode->height = screen->h;
2166 #else
2167         window_flags = windowflags;
2168         window = SDL_CreateWindow(gamename, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, mode->width, mode->height, windowflags);
2169         if (window == NULL)
2170         {
2171                 Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError());
2172                 VID_Shutdown();
2173                 return false;
2174         }
2175         SDL_GetWindowSize(window, &mode->width, &mode->height);
2176         context = SDL_GL_CreateContext(window);
2177         if (context == NULL)
2178         {
2179                 Con_Printf("Failed to initialize OpenGL context: %s\n", SDL_GetError());
2180                 VID_Shutdown();
2181                 return false;
2182         }
2183 #endif
2184
2185         vid_softsurface = NULL;
2186         vid.softpixels = NULL;
2187
2188 #if SETVIDEOMODE
2189         // set window title
2190         VID_SetCaption();
2191 #endif
2192         // init keyboard
2193         SDL_EnableUNICODE( SDL_ENABLE );
2194         // enable key repeat since everyone expects it
2195         SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
2196
2197 #if !(SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION == 2)
2198         SDL_GL_SetSwapInterval(vid_vsync.integer != 0);
2199         vid_usingvsync = (vid_vsync.integer != 0);
2200 #endif
2201
2202         gl_platform = "SDL";
2203         gl_platformextensions = "";
2204
2205 #ifdef __IPHONEOS__
2206         GLES_Init();
2207 #else
2208         GL_Init();
2209 #endif
2210
2211         vid_numjoysticks = SDL_NumJoysticks();
2212         vid_numjoysticks = bound(0, vid_numjoysticks, MAX_JOYSTICKS);
2213         Cvar_SetValueQuick(&joy_detected, vid_numjoysticks);
2214         Con_Printf("%d SDL joystick(s) found:\n", vid_numjoysticks);
2215         memset(vid_joysticks, 0, sizeof(vid_joysticks));
2216         for (i = 0;i < vid_numjoysticks;i++)
2217         {
2218                 SDL_Joystick *joy;
2219                 joy = vid_joysticks[i] = SDL_JoystickOpen(i);
2220                 if (!joy)
2221                 {
2222                         Con_Printf("joystick #%i: open failed: %s\n", i, SDL_GetError());
2223                         continue;
2224                 }
2225                 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));
2226         }
2227
2228         vid_hidden = false;
2229         vid_activewindow = false;
2230         vid_hasfocus = true;
2231         vid_usingmouse = false;
2232         vid_usinghidecursor = false;
2233
2234 #if SETVIDEOMODE
2235         SDL_WM_GrabInput(SDL_GRAB_OFF);
2236 #endif
2237         return true;
2238 }
2239
2240 extern cvar_t gl_info_extensions;
2241 extern cvar_t gl_info_vendor;
2242 extern cvar_t gl_info_renderer;
2243 extern cvar_t gl_info_version;
2244 extern cvar_t gl_info_platform;
2245 extern cvar_t gl_info_driver;
2246
2247 qboolean VID_InitModeSoft(viddef_mode_t *mode)
2248 {
2249         int i;
2250 #if SETVIDEOMODE
2251         int flags = SDL_HWSURFACE;
2252 #else
2253         int windowflags = SDL_WINDOW_SHOWN;
2254 #endif
2255
2256         win_half_width = mode->width>>1;
2257         win_half_height = mode->height>>1;
2258
2259         if(vid_resizable.integer)
2260 #if SETVIDEOMODE
2261                 flags |= SDL_RESIZABLE;
2262 #else
2263                 windowflags |= SDL_WINDOW_RESIZABLE;
2264 #endif
2265
2266         VID_OutputVersion();
2267
2268         vid_isfullscreen = false;
2269         if (mode->fullscreen) {
2270 #if SETVIDEOMODE
2271                 flags |= SDL_FULLSCREEN;
2272 #else
2273                 windowflags |= SDL_WINDOW_FULLSCREEN;
2274 #endif
2275                 vid_isfullscreen = true;
2276         }
2277
2278         video_bpp = mode->bitsperpixel;
2279 #if SETVIDEOMODE
2280         video_flags = flags;
2281         VID_SetIcon_Pre();
2282         screen = SDL_SetVideoMode(mode->width, mode->height, mode->bitsperpixel, flags);
2283         VID_SetIcon_Post();
2284         if (screen == NULL)
2285         {
2286                 Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError());
2287                 VID_Shutdown();
2288                 return false;
2289         }
2290         mode->width = screen->w;
2291         mode->height = screen->h;
2292 #else
2293         window_flags = windowflags;
2294         window = SDL_CreateWindow(gamename, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, mode->width, mode->height, windowflags);
2295         if (window == NULL)
2296         {
2297                 Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError());
2298                 VID_Shutdown();
2299                 return false;
2300         }
2301         SDL_GetWindowSize(window, &mode->width, &mode->height);
2302 #endif
2303
2304         // create a framebuffer using our specific color format, we let the SDL blit function convert it in VID_Finish
2305         vid_softsurface = SDL_CreateRGBSurface(SDL_SWSURFACE, mode->width, mode->height, 32, 0x00FF0000, 0x0000FF00, 0x00000000FF, 0xFF000000);
2306         if (vid_softsurface == NULL)
2307         {
2308                 Con_Printf("Failed to setup software rasterizer framebuffer %ix%ix32bpp: %s\n", mode->width, mode->height, SDL_GetError());
2309                 VID_Shutdown();
2310                 return false;
2311         }
2312         SDL_SetAlpha(vid_softsurface, 0, 255);
2313
2314         vid.softpixels = (unsigned int *)vid_softsurface->pixels;
2315         vid.softdepthpixels = (unsigned int *)calloc(1, mode->width * mode->height * 4);
2316         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)
2317         {
2318                 Con_Printf("Failed to initialize software rasterizer\n");
2319                 VID_Shutdown();
2320                 return false;
2321         }
2322
2323 #if SETVIDEOMODE
2324         // set window title
2325         VID_SetCaption();
2326 #endif
2327         // init keyboard
2328         SDL_EnableUNICODE( SDL_ENABLE );
2329         // enable key repeat since everyone expects it
2330         SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
2331
2332         gl_platform = "SDLSoft";
2333         gl_platformextensions = "";
2334
2335         gl_renderer = "DarkPlaces-Soft";
2336         gl_vendor = "Forest Hale";
2337         gl_version = "0.0";
2338         gl_extensions = "";
2339
2340         // clear the extension flags
2341         memset(&vid.support, 0, sizeof(vid.support));
2342         Cvar_SetQuick(&gl_info_extensions, "");
2343
2344         vid.forcevbo = false;
2345         vid.support.arb_depth_texture = true;
2346         vid.support.arb_draw_buffers = true;
2347         vid.support.arb_occlusion_query = true;
2348         vid.support.arb_shadow = true;
2349         //vid.support.arb_texture_compression = true;
2350         vid.support.arb_texture_cube_map = true;
2351         vid.support.arb_texture_non_power_of_two = false;
2352         vid.support.arb_vertex_buffer_object = true;
2353         vid.support.ext_blend_subtract = true;
2354         vid.support.ext_draw_range_elements = true;
2355         vid.support.ext_framebuffer_object = true;
2356         vid.support.ext_texture_3d = true;
2357         //vid.support.ext_texture_compression_s3tc = true;
2358         vid.support.ext_texture_filter_anisotropic = true;
2359         vid.support.ati_separate_stencil = true;
2360
2361         vid.maxtexturesize_2d = 16384;
2362         vid.maxtexturesize_3d = 512;
2363         vid.maxtexturesize_cubemap = 16384;
2364         vid.texunits = 4;
2365         vid.teximageunits = 32;
2366         vid.texarrayunits = 8;
2367         vid.max_anisotropy = 1;
2368         vid.maxdrawbuffers = 4;
2369
2370         vid.texunits = bound(4, vid.texunits, MAX_TEXTUREUNITS);
2371         vid.teximageunits = bound(16, vid.teximageunits, MAX_TEXTUREUNITS);
2372         vid.texarrayunits = bound(8, vid.texarrayunits, MAX_TEXTUREUNITS);
2373         Con_DPrintf("Using DarkPlaces Software Rasterizer rendering path\n");
2374         vid.renderpath = RENDERPATH_SOFT;
2375         vid.useinterleavedarrays = false;
2376
2377         Cvar_SetQuick(&gl_info_vendor, gl_vendor);
2378         Cvar_SetQuick(&gl_info_renderer, gl_renderer);
2379         Cvar_SetQuick(&gl_info_version, gl_version);
2380         Cvar_SetQuick(&gl_info_platform, gl_platform ? gl_platform : "");
2381         Cvar_SetQuick(&gl_info_driver, gl_driver);
2382
2383         // LordHavoc: report supported extensions
2384         Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions );
2385
2386         // clear to black (loading plaque will be seen over this)
2387         GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 128);
2388
2389         vid_numjoysticks = SDL_NumJoysticks();
2390         vid_numjoysticks = bound(0, vid_numjoysticks, MAX_JOYSTICKS);
2391         Cvar_SetValueQuick(&joy_detected, vid_numjoysticks);
2392         Con_Printf("%d SDL joystick(s) found:\n", vid_numjoysticks);
2393         memset(vid_joysticks, 0, sizeof(vid_joysticks));
2394         for (i = 0;i < vid_numjoysticks;i++)
2395         {
2396                 SDL_Joystick *joy;
2397                 joy = vid_joysticks[i] = SDL_JoystickOpen(i);
2398                 if (!joy)
2399                 {
2400                         Con_Printf("joystick #%i: open failed: %s\n", i, SDL_GetError());
2401                         continue;
2402                 }
2403                 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));
2404         }
2405
2406         vid_hidden = false;
2407         vid_activewindow = false;
2408         vid_hasfocus = true;
2409         vid_usingmouse = false;
2410         vid_usinghidecursor = false;
2411
2412 #if SETVIDEOMODE
2413         SDL_WM_GrabInput(SDL_GRAB_OFF);
2414 #endif
2415         return true;
2416 }
2417
2418 qboolean VID_InitMode(viddef_mode_t *mode)
2419 {
2420         if (!SDL_WasInit(SDL_INIT_VIDEO) && SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
2421                 Sys_Error ("Failed to init SDL video subsystem: %s", SDL_GetError());
2422 #ifdef SSE2_PRESENT
2423         if (vid_soft.integer)
2424                 return VID_InitModeSoft(mode);
2425         else
2426 #endif
2427                 return VID_InitModeGL(mode);
2428 }
2429
2430 void VID_Shutdown (void)
2431 {
2432         VID_SetMouse(false, false, false);
2433         VID_RestoreSystemGamma();
2434
2435 #if SETVIDEOMODE
2436 #ifndef WIN32
2437         if (icon)
2438                 SDL_FreeSurface(icon);
2439         icon = NULL;
2440 #endif
2441 #endif
2442
2443         if (vid_softsurface)
2444                 SDL_FreeSurface(vid_softsurface);
2445         vid_softsurface = NULL;
2446         vid.softpixels = NULL;
2447         if (vid.softdepthpixels)
2448                 free(vid.softdepthpixels);
2449         vid.softdepthpixels = NULL;
2450
2451 #if SETVIDEOMODE
2452 #else
2453         SDL_DestroyWindow(window);
2454         window = NULL;
2455 #endif
2456
2457         SDL_QuitSubSystem(SDL_INIT_VIDEO);
2458
2459         gl_driver[0] = 0;
2460         gl_extensions = "";
2461         gl_platform = "";
2462         gl_platformextensions = "";
2463 }
2464
2465 int VID_SetGamma (unsigned short *ramps, int rampsize)
2466 {
2467         return !SDL_SetGammaRamp (ramps, ramps + rampsize, ramps + rampsize*2);
2468 }
2469
2470 int VID_GetGamma (unsigned short *ramps, int rampsize)
2471 {
2472         return !SDL_GetGammaRamp (ramps, ramps + rampsize, ramps + rampsize*2);
2473 }
2474
2475 void VID_Finish (void)
2476 {
2477 #if SETVIDEOMODE
2478         Uint8 appstate;
2479
2480         //react on appstate changes
2481         appstate = SDL_GetAppState();
2482
2483         vid_hidden = !(appstate & SDL_APPACTIVE);
2484         vid_hasfocus = (appstate & SDL_APPMOUSEFOCUS) && (appstate & SDL_APPINPUTFOCUS);
2485 #endif
2486         vid_activewindow = !vid_hidden && vid_hasfocus;
2487
2488         VID_UpdateGamma(false, 256);
2489
2490         if (!vid_hidden)
2491         {
2492                 switch(vid.renderpath)
2493                 {
2494                 case RENDERPATH_GL11:
2495                 case RENDERPATH_GL13:
2496                 case RENDERPATH_GL20:
2497                 case RENDERPATH_GLES2:
2498                         CHECKGLERROR
2499                         if (r_speeds.integer == 2 || gl_finish.integer)
2500                         {
2501                                 qglFinish();CHECKGLERROR
2502                         }
2503 #if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION == 2
2504 #else
2505 {
2506         qboolean vid_usevsync;
2507         vid_usevsync = (vid_vsync.integer && !cls.timedemo);
2508         if (vid_usingvsync != vid_usevsync)
2509         {
2510                 if (SDL_GL_SetSwapInterval(vid_usevsync != 0) >= 0)
2511                         Con_DPrintf("Vsync %s\n", vid_usevsync ? "activated" : "deactivated");
2512                 else
2513                         Con_DPrintf("ERROR: can't %s vsync\n", vid_usevsync ? "activate" : "deactivate");
2514         }
2515 }
2516 #endif
2517 #if SETVIDEOMODE
2518                         SDL_GL_SwapBuffers();
2519 #else
2520                         SDL_GL_SwapWindow(window);
2521 #endif
2522                         break;
2523                 case RENDERPATH_SOFT:
2524                         DPSOFTRAST_Finish();
2525 #if SETVIDEOMODE
2526                         SDL_BlitSurface(vid_softsurface, NULL, screen, NULL);
2527                         SDL_Flip(screen);
2528 #else
2529                         {
2530                                 SDL_Surface *screen = SDL_GetWindowSurface(window);
2531                                 SDL_BlitSurface(vid_softsurface, NULL, screen, NULL);
2532                                 SDL_UpdateWindowSurface(window);
2533                         }
2534 #endif
2535                         break;
2536                 case RENDERPATH_D3D9:
2537                 case RENDERPATH_D3D10:
2538                 case RENDERPATH_D3D11:
2539                         break;
2540                 }
2541         }
2542 }
2543
2544 size_t VID_ListModes(vid_mode_t *modes, size_t maxcount)
2545 {
2546         size_t k;
2547         SDL_Rect **vidmodes;
2548         int bpp = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
2549
2550         k = 0;
2551         for(vidmodes = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE); *vidmodes; ++vidmodes)
2552         {
2553                 if(k >= maxcount)
2554                         break;
2555                 modes[k].width = (*vidmodes)->w;
2556                 modes[k].height = (*vidmodes)->h;
2557                 modes[k].bpp = bpp;
2558                 modes[k].refreshrate = 60; // no support for refresh rate in SDL
2559                 modes[k].pixelheight_num = 1;
2560                 modes[k].pixelheight_denom = 1; // SDL does not provide this
2561                 ++k;
2562         }
2563         return k;
2564 }