2 Copyright (C) 2003 T. Joseph Carter
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.
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.
13 See the GNU General Public License for more details.
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.
19 #undef WIN32_LEAN_AND_MEAN //hush a warning, SDL.h redefines this
25 #include "dpsoftrast.h"
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)
39 io_connect_t iohandle = MACH_PORT_NULL;
41 io_service_t iohidsystem = MACH_PORT_NULL;
42 mach_port_t masterport;
44 status = IOMasterPort(MACH_PORT_NULL, &masterport);
45 if(status != KERN_SUCCESS)
48 iohidsystem = IORegistryEntryFromPath(masterport, kIOServicePlane ":/IOResources/IOHIDSystem");
52 status = IOServiceOpen(iohidsystem, mach_task_self(), kIOHIDParamConnectType, &iohandle);
53 IOObjectRelease(iohidsystem);
64 // Tell startup code that we have a client
65 int cl_available = true;
67 qboolean vid_supportrefreshrate = false;
69 static qboolean vid_usingmouse = false;
70 static qboolean vid_usingmouse_relativeworks = false; // SDL2 workaround for unimplemented RelativeMouse mode
71 static qboolean vid_usinghidecursor = false;
72 static qboolean vid_hasfocus = false;
73 static qboolean vid_isfullscreen;
74 #if SDL_MAJOR_VERSION != 1
75 static qboolean vid_usingvsync = false;
77 static SDL_Joystick *vid_sdljoystick = NULL;
78 // GAME_STEELSTORM specific
79 static cvar_t *steelstorm_showing_map = NULL; // detect but do not create the cvar
80 static cvar_t *steelstorm_showing_mousecursor = NULL; // detect but do not create the cvar
82 static int win_half_width = 50;
83 static int win_half_height = 50;
86 #if SDL_MAJOR_VERSION == 1
87 static SDL_Surface *video_screen;
88 static int video_flags;
90 static SDL_GLContext context;
91 static SDL_Window *window;
92 static int window_flags;
94 static SDL_Surface *vid_softsurface;
95 static vid_mode_t desktop_mode;
97 /////////////////////////
100 //TODO: Add error checking
103 #define SDLK_PERCENT '%'
104 #if SDL_MAJOR_VERSION == 1
105 #define SDLK_PRINTSCREEN SDLK_PRINT
106 #define SDLK_SCROLLLOCK SDLK_SCROLLOCK
107 #define SDLK_NUMLOCKCLEAR SDLK_NUMLOCK
108 #define SDLK_KP_1 SDLK_KP1
109 #define SDLK_KP_2 SDLK_KP2
110 #define SDLK_KP_3 SDLK_KP3
111 #define SDLK_KP_4 SDLK_KP4
112 #define SDLK_KP_5 SDLK_KP5
113 #define SDLK_KP_6 SDLK_KP6
114 #define SDLK_KP_7 SDLK_KP7
115 #define SDLK_KP_8 SDLK_KP8
116 #define SDLK_KP_9 SDLK_KP9
117 #define SDLK_KP_0 SDLK_KP0
121 static int MapKey( unsigned int sdlkey )
126 // case SDLK_UNKNOWN: return K_UNKNOWN;
127 case SDLK_RETURN: return K_ENTER;
128 case SDLK_ESCAPE: return K_ESCAPE;
129 case SDLK_BACKSPACE: return K_BACKSPACE;
130 case SDLK_TAB: return K_TAB;
131 case SDLK_SPACE: return K_SPACE;
132 case SDLK_EXCLAIM: return '!';
133 case SDLK_QUOTEDBL: return '"';
134 case SDLK_HASH: return '#';
135 case SDLK_PERCENT: return '%';
136 case SDLK_DOLLAR: return '$';
137 case SDLK_AMPERSAND: return '&';
138 case SDLK_QUOTE: return '\'';
139 case SDLK_LEFTPAREN: return '(';
140 case SDLK_RIGHTPAREN: return ')';
141 case SDLK_ASTERISK: return '*';
142 case SDLK_PLUS: return '+';
143 case SDLK_COMMA: return ',';
144 case SDLK_MINUS: return '-';
145 case SDLK_PERIOD: return '.';
146 case SDLK_SLASH: return '/';
147 case SDLK_0: return '0';
148 case SDLK_1: return '1';
149 case SDLK_2: return '2';
150 case SDLK_3: return '3';
151 case SDLK_4: return '4';
152 case SDLK_5: return '5';
153 case SDLK_6: return '6';
154 case SDLK_7: return '7';
155 case SDLK_8: return '8';
156 case SDLK_9: return '9';
157 case SDLK_COLON: return ':';
158 case SDLK_SEMICOLON: return ';';
159 case SDLK_LESS: return '<';
160 case SDLK_EQUALS: return '=';
161 case SDLK_GREATER: return '>';
162 case SDLK_QUESTION: return '?';
163 case SDLK_AT: return '@';
164 case SDLK_LEFTBRACKET: return '[';
165 case SDLK_BACKSLASH: return '\\';
166 case SDLK_RIGHTBRACKET: return ']';
167 case SDLK_CARET: return '^';
168 case SDLK_UNDERSCORE: return '_';
169 case SDLK_BACKQUOTE: return '`';
170 case SDLK_a: return 'a';
171 case SDLK_b: return 'b';
172 case SDLK_c: return 'c';
173 case SDLK_d: return 'd';
174 case SDLK_e: return 'e';
175 case SDLK_f: return 'f';
176 case SDLK_g: return 'g';
177 case SDLK_h: return 'h';
178 case SDLK_i: return 'i';
179 case SDLK_j: return 'j';
180 case SDLK_k: return 'k';
181 case SDLK_l: return 'l';
182 case SDLK_m: return 'm';
183 case SDLK_n: return 'n';
184 case SDLK_o: return 'o';
185 case SDLK_p: return 'p';
186 case SDLK_q: return 'q';
187 case SDLK_r: return 'r';
188 case SDLK_s: return 's';
189 case SDLK_t: return 't';
190 case SDLK_u: return 'u';
191 case SDLK_v: return 'v';
192 case SDLK_w: return 'w';
193 case SDLK_x: return 'x';
194 case SDLK_y: return 'y';
195 case SDLK_z: return 'z';
196 case SDLK_CAPSLOCK: return K_CAPSLOCK;
197 case SDLK_F1: return K_F1;
198 case SDLK_F2: return K_F2;
199 case SDLK_F3: return K_F3;
200 case SDLK_F4: return K_F4;
201 case SDLK_F5: return K_F5;
202 case SDLK_F6: return K_F6;
203 case SDLK_F7: return K_F7;
204 case SDLK_F8: return K_F8;
205 case SDLK_F9: return K_F9;
206 case SDLK_F10: return K_F10;
207 case SDLK_F11: return K_F11;
208 case SDLK_F12: return K_F12;
209 case SDLK_PRINTSCREEN: return K_PRINTSCREEN;
210 case SDLK_SCROLLLOCK: return K_SCROLLOCK;
211 case SDLK_PAUSE: return K_PAUSE;
212 case SDLK_INSERT: return K_INS;
213 case SDLK_HOME: return K_HOME;
214 case SDLK_PAGEUP: return K_PGUP;
216 case SDLK_DELETE: return K_BACKSPACE;
218 case SDLK_DELETE: return K_DEL;
220 case SDLK_END: return K_END;
221 case SDLK_PAGEDOWN: return K_PGDN;
222 case SDLK_RIGHT: return K_RIGHTARROW;
223 case SDLK_LEFT: return K_LEFTARROW;
224 case SDLK_DOWN: return K_DOWNARROW;
225 case SDLK_UP: return K_UPARROW;
226 case SDLK_NUMLOCKCLEAR: return K_NUMLOCK;
227 case SDLK_KP_DIVIDE: return K_KP_DIVIDE;
228 case SDLK_KP_MULTIPLY: return K_KP_MULTIPLY;
229 case SDLK_KP_MINUS: return K_KP_MINUS;
230 case SDLK_KP_PLUS: return K_KP_PLUS;
231 case SDLK_KP_ENTER: return K_KP_ENTER;
232 case SDLK_KP_1: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_1 : K_END);
233 case SDLK_KP_2: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_2 : K_DOWNARROW);
234 case SDLK_KP_3: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_3 : K_PGDN);
235 case SDLK_KP_4: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_4 : K_LEFTARROW);
236 case SDLK_KP_5: return K_KP_5;
237 case SDLK_KP_6: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_6 : K_RIGHTARROW);
238 case SDLK_KP_7: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_7 : K_HOME);
239 case SDLK_KP_8: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_8 : K_UPARROW);
240 case SDLK_KP_9: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_9 : K_PGUP);
241 case SDLK_KP_0: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_0 : K_INS);
242 case SDLK_KP_PERIOD: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_PERIOD : K_DEL);
243 // case SDLK_APPLICATION: return K_APPLICATION;
244 // case SDLK_POWER: return K_POWER;
245 case SDLK_KP_EQUALS: return K_KP_EQUALS;
246 // case SDLK_F13: return K_F13;
247 // case SDLK_F14: return K_F14;
248 // case SDLK_F15: return K_F15;
249 // case SDLK_F16: return K_F16;
250 // case SDLK_F17: return K_F17;
251 // case SDLK_F18: return K_F18;
252 // case SDLK_F19: return K_F19;
253 // case SDLK_F20: return K_F20;
254 // case SDLK_F21: return K_F21;
255 // case SDLK_F22: return K_F22;
256 // case SDLK_F23: return K_F23;
257 // case SDLK_F24: return K_F24;
258 // case SDLK_EXECUTE: return K_EXECUTE;
259 // case SDLK_HELP: return K_HELP;
260 // case SDLK_MENU: return K_MENU;
261 // case SDLK_SELECT: return K_SELECT;
262 // case SDLK_STOP: return K_STOP;
263 // case SDLK_AGAIN: return K_AGAIN;
264 // case SDLK_UNDO: return K_UNDO;
265 // case SDLK_CUT: return K_CUT;
266 // case SDLK_COPY: return K_COPY;
267 // case SDLK_PASTE: return K_PASTE;
268 // case SDLK_FIND: return K_FIND;
269 // case SDLK_MUTE: return K_MUTE;
270 // case SDLK_VOLUMEUP: return K_VOLUMEUP;
271 // case SDLK_VOLUMEDOWN: return K_VOLUMEDOWN;
272 // case SDLK_KP_COMMA: return K_KP_COMMA;
273 // case SDLK_KP_EQUALSAS400: return K_KP_EQUALSAS400;
274 // case SDLK_ALTERASE: return K_ALTERASE;
275 // case SDLK_SYSREQ: return K_SYSREQ;
276 // case SDLK_CANCEL: return K_CANCEL;
277 // case SDLK_CLEAR: return K_CLEAR;
278 // case SDLK_PRIOR: return K_PRIOR;
279 // case SDLK_RETURN2: return K_RETURN2;
280 // case SDLK_SEPARATOR: return K_SEPARATOR;
281 // case SDLK_OUT: return K_OUT;
282 // case SDLK_OPER: return K_OPER;
283 // case SDLK_CLEARAGAIN: return K_CLEARAGAIN;
284 // case SDLK_CRSEL: return K_CRSEL;
285 // case SDLK_EXSEL: return K_EXSEL;
286 // case SDLK_KP_00: return K_KP_00;
287 // case SDLK_KP_000: return K_KP_000;
288 // case SDLK_THOUSANDSSEPARATOR: return K_THOUSANDSSEPARATOR;
289 // case SDLK_DECIMALSEPARATOR: return K_DECIMALSEPARATOR;
290 // case SDLK_CURRENCYUNIT: return K_CURRENCYUNIT;
291 // case SDLK_CURRENCYSUBUNIT: return K_CURRENCYSUBUNIT;
292 // case SDLK_KP_LEFTPAREN: return K_KP_LEFTPAREN;
293 // case SDLK_KP_RIGHTPAREN: return K_KP_RIGHTPAREN;
294 // case SDLK_KP_LEFTBRACE: return K_KP_LEFTBRACE;
295 // case SDLK_KP_RIGHTBRACE: return K_KP_RIGHTBRACE;
296 // case SDLK_KP_TAB: return K_KP_TAB;
297 // case SDLK_KP_BACKSPACE: return K_KP_BACKSPACE;
298 // case SDLK_KP_A: return K_KP_A;
299 // case SDLK_KP_B: return K_KP_B;
300 // case SDLK_KP_C: return K_KP_C;
301 // case SDLK_KP_D: return K_KP_D;
302 // case SDLK_KP_E: return K_KP_E;
303 // case SDLK_KP_F: return K_KP_F;
304 // case SDLK_KP_XOR: return K_KP_XOR;
305 // case SDLK_KP_POWER: return K_KP_POWER;
306 // case SDLK_KP_PERCENT: return K_KP_PERCENT;
307 // case SDLK_KP_LESS: return K_KP_LESS;
308 // case SDLK_KP_GREATER: return K_KP_GREATER;
309 // case SDLK_KP_AMPERSAND: return K_KP_AMPERSAND;
310 // case SDLK_KP_DBLAMPERSAND: return K_KP_DBLAMPERSAND;
311 // case SDLK_KP_VERTICALBAR: return K_KP_VERTICALBAR;
312 // case SDLK_KP_DBLVERTICALBAR: return K_KP_DBLVERTICALBAR;
313 // case SDLK_KP_COLON: return K_KP_COLON;
314 // case SDLK_KP_HASH: return K_KP_HASH;
315 // case SDLK_KP_SPACE: return K_KP_SPACE;
316 // case SDLK_KP_AT: return K_KP_AT;
317 // case SDLK_KP_EXCLAM: return K_KP_EXCLAM;
318 // case SDLK_KP_MEMSTORE: return K_KP_MEMSTORE;
319 // case SDLK_KP_MEMRECALL: return K_KP_MEMRECALL;
320 // case SDLK_KP_MEMCLEAR: return K_KP_MEMCLEAR;
321 // case SDLK_KP_MEMADD: return K_KP_MEMADD;
322 // case SDLK_KP_MEMSUBTRACT: return K_KP_MEMSUBTRACT;
323 // case SDLK_KP_MEMMULTIPLY: return K_KP_MEMMULTIPLY;
324 // case SDLK_KP_MEMDIVIDE: return K_KP_MEMDIVIDE;
325 // case SDLK_KP_PLUSMINUS: return K_KP_PLUSMINUS;
326 // case SDLK_KP_CLEAR: return K_KP_CLEAR;
327 // case SDLK_KP_CLEARENTRY: return K_KP_CLEARENTRY;
328 // case SDLK_KP_BINARY: return K_KP_BINARY;
329 // case SDLK_KP_OCTAL: return K_KP_OCTAL;
330 // case SDLK_KP_DECIMAL: return K_KP_DECIMAL;
331 // case SDLK_KP_HEXADECIMAL: return K_KP_HEXADECIMAL;
332 case SDLK_LCTRL: return K_CTRL;
333 case SDLK_LSHIFT: return K_SHIFT;
334 case SDLK_LALT: return K_ALT;
335 // case SDLK_LGUI: return K_LGUI;
336 case SDLK_RCTRL: return K_CTRL;
337 case SDLK_RSHIFT: return K_SHIFT;
338 case SDLK_RALT: return K_ALT;
339 // case SDLK_RGUI: return K_RGUI;
340 // case SDLK_MODE: return K_MODE;
341 #if SDL_MAJOR_VERSION != 1
342 // case SDLK_AUDIONEXT: return K_AUDIONEXT;
343 // case SDLK_AUDIOPREV: return K_AUDIOPREV;
344 // case SDLK_AUDIOSTOP: return K_AUDIOSTOP;
345 // case SDLK_AUDIOPLAY: return K_AUDIOPLAY;
346 // case SDLK_AUDIOMUTE: return K_AUDIOMUTE;
347 // case SDLK_MEDIASELECT: return K_MEDIASELECT;
348 // case SDLK_WWW: return K_WWW;
349 // case SDLK_MAIL: return K_MAIL;
350 // case SDLK_CALCULATOR: return K_CALCULATOR;
351 // case SDLK_COMPUTER: return K_COMPUTER;
352 // case SDLK_AC_SEARCH: return K_AC_SEARCH; // Android button
353 // case SDLK_AC_HOME: return K_AC_HOME; // Android button
354 case SDLK_AC_BACK: return K_ESCAPE; // Android button
355 // case SDLK_AC_FORWARD: return K_AC_FORWARD; // Android button
356 // case SDLK_AC_STOP: return K_AC_STOP; // Android button
357 // case SDLK_AC_REFRESH: return K_AC_REFRESH; // Android button
358 // case SDLK_AC_BOOKMARKS: return K_AC_BOOKMARKS; // Android button
359 // case SDLK_BRIGHTNESSDOWN: return K_BRIGHTNESSDOWN;
360 // case SDLK_BRIGHTNESSUP: return K_BRIGHTNESSUP;
361 // case SDLK_DISPLAYSWITCH: return K_DISPLAYSWITCH;
362 // case SDLK_KBDILLUMTOGGLE: return K_KBDILLUMTOGGLE;
363 // case SDLK_KBDILLUMDOWN: return K_KBDILLUMDOWN;
364 // case SDLK_KBDILLUMUP: return K_KBDILLUMUP;
365 // case SDLK_EJECT: return K_EJECT;
366 // case SDLK_SLEEP: return K_SLEEP;
371 qboolean VID_HasScreenKeyboardSupport(void)
373 #if SDL_MAJOR_VERSION != 1
374 return SDL_HasScreenKeyboardSupport() != SDL_FALSE;
380 void VID_ShowKeyboard(qboolean show)
382 #if SDL_MAJOR_VERSION != 1
383 if (!SDL_HasScreenKeyboardSupport())
388 if (!SDL_IsTextInputActive())
389 SDL_StartTextInput();
393 if (SDL_IsTextInputActive())
399 qboolean VID_ShowingKeyboard(void)
401 #if SDL_MAJOR_VERSION != 1
402 return SDL_IsTextInputActive() != 0;
408 void VID_SetMouse(qboolean fullscreengrab, qboolean relative, qboolean hidecursor)
410 #ifndef DP_MOBILETOUCH
413 if(vid_usingmouse && (vid_usingnoaccel != !!apple_mouse_noaccel.integer))
414 VID_SetMouse(false, false, false); // ungrab first!
416 if (vid_usingmouse != relative)
418 vid_usingmouse = relative;
419 cl_ignoremousemoves = 2;
420 #if SDL_MAJOR_VERSION == 1
421 SDL_WM_GrabInput( relative ? SDL_GRAB_ON : SDL_GRAB_OFF );
423 vid_usingmouse_relativeworks = SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE) == 0;
424 // Con_Printf("VID_SetMouse(%i, %i, %i) relativeworks = %i\n", (int)fullscreengrab, (int)relative, (int)hidecursor, (int)vid_usingmouse_relativeworks);
429 // Save the status of mouse acceleration
430 originalMouseSpeed = -1.0; // in case of error
431 if(apple_mouse_noaccel.integer)
433 io_connect_t mouseDev = IN_GetIOHandle();
436 if(IOHIDGetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), &originalMouseSpeed) == kIOReturnSuccess)
438 Con_DPrintf("previous mouse acceleration: %f\n", originalMouseSpeed);
439 if(IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), -1.0) != kIOReturnSuccess)
441 Con_Print("Could not disable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n");
442 Cvar_SetValueQuick(&apple_mouse_noaccel, 0);
447 Con_Print("Could not disable mouse acceleration (failed at IOHIDGetAccelerationWithKey).\n");
448 Cvar_SetValueQuick(&apple_mouse_noaccel, 0);
450 IOServiceClose(mouseDev);
454 Con_Print("Could not disable mouse acceleration (failed at IO_GetIOHandle).\n");
455 Cvar_SetValueQuick(&apple_mouse_noaccel, 0);
459 vid_usingnoaccel = !!apple_mouse_noaccel.integer;
463 if(originalMouseSpeed != -1.0)
465 io_connect_t mouseDev = IN_GetIOHandle();
468 Con_DPrintf("restoring mouse acceleration to: %f\n", originalMouseSpeed);
469 if(IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), originalMouseSpeed) != kIOReturnSuccess)
470 Con_Print("Could not re-enable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n");
471 IOServiceClose(mouseDev);
474 Con_Print("Could not re-enable mouse acceleration (failed at IO_GetIOHandle).\n");
479 if (vid_usinghidecursor != hidecursor)
481 vid_usinghidecursor = hidecursor;
482 SDL_ShowCursor( hidecursor ? SDL_DISABLE : SDL_ENABLE);
487 // multitouch[10][] represents the mouse pointer
488 // multitouch[][0]: finger active
489 // multitouch[][1]: Y
490 // multitouch[][2]: Y
491 // X and Y coordinates are 0-1.
492 #define MAXFINGERS 11
493 float multitouch[MAXFINGERS][3];
495 // this one stores how many areas this finger has touched
496 int multitouchs[MAXFINGERS];
498 // modified heavily by ELUAN
499 static qboolean VID_TouchscreenArea(int corner, float px, float py, float pwidth, float pheight, const char *icon, float textheight, const char *text, float *resultmove, qboolean *resultbutton, keynum_t key, const char *typedtext, float deadzone, float oversizepixels_x, float oversizepixels_y, qboolean iamexclusive)
502 float fx, fy, fwidth, fheight;
503 float overfx, overfy, overfwidth, overfheight;
506 qboolean button = false;
508 if (pwidth > 0 && pheight > 0)
510 if (corner & 1) px += vid_conwidth.value;
511 if (corner & 2) py += vid_conheight.value;
512 if (corner & 4) px += vid_conwidth.value * 0.5f;
513 if (corner & 8) py += vid_conheight.value * 0.5f;
514 if (corner & 16) {px *= vid_conwidth.value * (1.0f / 640.0f);py *= vid_conheight.value * (1.0f / 480.0f);pwidth *= vid_conwidth.value * (1.0f / 640.0f);pheight *= vid_conheight.value * (1.0f / 480.0f);}
515 fx = px / vid_conwidth.value;
516 fy = py / vid_conheight.value;
517 fwidth = pwidth / vid_conwidth.value;
518 fheight = pheight / vid_conheight.value;
520 // try to prevent oversizepixels_* from interfering with the iamexclusive cvar by not letting we start controlling from too far of the actual touch area (areas without resultbuttons should NEVER have the oversizepixels_* parameters set to anything other than 0)
522 if (!(*resultbutton))
524 oversizepixels_x *= 0.2;
525 oversizepixels_y *= 0.2;
528 oversizepixels_x /= vid_conwidth.value;
529 oversizepixels_y /= vid_conheight.value;
531 overfx = fx - oversizepixels_x;
532 overfy = fy - oversizepixels_y;
533 overfwidth = fwidth + 2*oversizepixels_x;
534 overfheight = fheight + 2*oversizepixels_y;
536 for (finger = 0;finger < MAXFINGERS;finger++)
538 if (multitouchs[finger] && iamexclusive) // for this to work correctly, you must call touch areas in order of highest to lowest priority
541 if (multitouch[finger][0] && multitouch[finger][1] >= overfx && multitouch[finger][2] >= overfy && multitouch[finger][1] < overfx + overfwidth && multitouch[finger][2] < overfy + overfheight)
543 multitouchs[finger]++;
545 rel[0] = bound(-1, (multitouch[finger][1] - (fx + 0.5f * fwidth)) * (2.0f / fwidth), 1);
546 rel[1] = bound(-1, (multitouch[finger][2] - (fy + 0.5f * fheight)) * (2.0f / fheight), 1);
549 sqsum = rel[0]*rel[0] + rel[1]*rel[1];
551 if (sqsum < deadzone*deadzone)
558 // ignore the third component
559 Vector2Normalize2(rel, rel);
565 if (scr_numtouchscreenareas < 128)
567 scr_touchscreenareas[scr_numtouchscreenareas].pic = icon;
568 scr_touchscreenareas[scr_numtouchscreenareas].text = text;
569 scr_touchscreenareas[scr_numtouchscreenareas].textheight = textheight;
570 scr_touchscreenareas[scr_numtouchscreenareas].rect[0] = px;
571 scr_touchscreenareas[scr_numtouchscreenareas].rect[1] = py;
572 scr_touchscreenareas[scr_numtouchscreenareas].rect[2] = pwidth;
573 scr_touchscreenareas[scr_numtouchscreenareas].rect[3] = pheight;
574 scr_touchscreenareas[scr_numtouchscreenareas].active = button;
575 // the pics may have alpha too.
576 scr_touchscreenareas[scr_numtouchscreenareas].activealpha = 1.f;
577 scr_touchscreenareas[scr_numtouchscreenareas].inactivealpha = 0.95f;
578 scr_numtouchscreenareas++;
584 VectorCopy(rel, resultmove);
586 VectorClear(resultmove);
590 if (*resultbutton != button)
593 Key_Event(key, 0, button);
594 if (typedtext && typedtext[0] && !*resultbutton)
596 // FIXME: implement UTF8 support - nothing actually specifies a UTF8 string here yet, but should support it...
598 for (i = 0;typedtext[i];i++)
600 Key_Event(K_TEXT, typedtext[i], true);
601 Key_Event(K_TEXT, typedtext[i], false);
605 *resultbutton = button;
611 // not reentrant, but we only need one mouse cursor anyway...
612 static void VID_TouchscreenCursor(float px, float py, float pwidth, float pheight, qboolean *resultbutton, keynum_t key)
615 float fx, fy, fwidth, fheight;
616 qboolean button = false;
617 static int cursorfinger = -1;
618 static int cursorfreemovement = false;
619 static int canclick = false;
620 static int clickxy[2];
621 static int relclickxy[2];
622 static double clickrealtime = 0;
624 if (steelstorm_showing_mousecursor && steelstorm_showing_mousecursor->integer)
625 if (pwidth > 0 && pheight > 0)
627 fx = px / vid_conwidth.value;
628 fy = py / vid_conheight.value;
629 fwidth = pwidth / vid_conwidth.value;
630 fheight = pheight / vid_conheight.value;
631 for (finger = 0;finger < MAXFINGERS;finger++)
633 if (multitouch[finger][0] && multitouch[finger][1] >= fx && multitouch[finger][2] >= fy && multitouch[finger][1] < fx + fwidth && multitouch[finger][2] < fy + fheight)
635 if (cursorfinger == -1)
637 clickxy[0] = multitouch[finger][1] * vid_width.value - 0.5f * pwidth;
638 clickxy[1] = multitouch[finger][2] * vid_height.value - 0.5f * pheight;
639 relclickxy[0] = (multitouch[finger][1] - fx) * vid_width.value - 0.5f * pwidth;
640 relclickxy[1] = (multitouch[finger][2] - fy) * vid_height.value - 0.5f * pheight;
642 cursorfinger = finger;
645 cursorfreemovement = false;
649 if (scr_numtouchscreenareas < 128)
651 if (clickrealtime + 1 > realtime)
653 scr_touchscreenareas[scr_numtouchscreenareas].pic = "gfx/gui/touch_puck_cur_click.tga";
657 scr_touchscreenareas[scr_numtouchscreenareas].pic = "gfx/gui/touch_puck_cur_touch.tga";
661 switch ((int)realtime * 10 % 20)
664 scr_touchscreenareas[scr_numtouchscreenareas].pic = "gfx/gui/touch_puck_cur_touch.tga";
667 scr_touchscreenareas[scr_numtouchscreenareas].pic = "gfx/gui/touch_puck_cur_idle.tga";
670 scr_touchscreenareas[scr_numtouchscreenareas].text = "";
671 scr_touchscreenareas[scr_numtouchscreenareas].textheight = 0;
672 scr_touchscreenareas[scr_numtouchscreenareas].rect[0] = px;
673 scr_touchscreenareas[scr_numtouchscreenareas].rect[1] = py;
674 scr_touchscreenareas[scr_numtouchscreenareas].rect[2] = pwidth;
675 scr_touchscreenareas[scr_numtouchscreenareas].rect[3] = pheight;
676 scr_touchscreenareas[scr_numtouchscreenareas].active = button;
677 scr_touchscreenareas[scr_numtouchscreenareas].activealpha = 1.0f;
678 scr_touchscreenareas[scr_numtouchscreenareas].inactivealpha = 1.0f;
679 scr_numtouchscreenareas++;
683 if (cursorfinger != -1)
685 if (multitouch[cursorfinger][0])
687 if (multitouch[cursorfinger][1] * vid_width.value - 0.5f * pwidth < clickxy[0] - 1 ||
688 multitouch[cursorfinger][1] * vid_width.value - 0.5f * pwidth > clickxy[0] + 1 ||
689 multitouch[cursorfinger][2] * vid_height.value - 0.5f * pheight< clickxy[1] - 1 ||
690 multitouch[cursorfinger][2] * vid_height.value - 0.5f * pheight> clickxy[1] + 1) // finger drifted more than the allowed amount
692 cursorfreemovement = true;
694 if (cursorfreemovement)
696 // in_windowmouse_x* is in screen resolution coordinates, not console resolution
697 in_windowmouse_x = multitouch[cursorfinger][1] * vid_width.value - 0.5f * pwidth - relclickxy[0];
698 in_windowmouse_y = multitouch[cursorfinger][2] * vid_height.value - 0.5f * pheight - relclickxy[1];
709 if (/**resultbutton != button && */(int)key > 0)
711 if (!button && !cursorfreemovement && canclick)
713 Key_Event(key, 0, true);
715 clickrealtime = realtime;
718 // SS:BR can't qc can't cope with presses and releases on the same frame
719 if (clickrealtime && clickrealtime + 0.1 < realtime)
721 Key_Event(key, 0, false);
726 *resultbutton = button;
730 void VID_BuildJoyState(vid_joystate_t *joystate)
732 VID_Shared_BuildJoyState_Begin(joystate);
736 SDL_Joystick *joy = vid_sdljoystick;
740 numaxes = SDL_JoystickNumAxes(joy);
741 for (j = 0;j < numaxes;j++)
742 joystate->axis[j] = SDL_JoystickGetAxis(joy, j) * (1.0f / 32767.0f);
743 numbuttons = SDL_JoystickNumButtons(joy);
744 for (j = 0;j < numbuttons;j++)
745 joystate->button[j] = SDL_JoystickGetButton(joy, j);
748 VID_Shared_BuildJoyState_Finish(joystate);
751 // clear every touch screen area, except the one with button[skip]
752 #define Vid_ClearAllTouchscreenAreas(skip) \
754 VID_TouchscreenCursor(0, 0, 0, 0, &buttons[0], K_MOUSE1); \
756 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, move, &buttons[1], K_MOUSE4, NULL, 0, 0, 0, false); \
758 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, aim, &buttons[2], K_MOUSE5, NULL, 0, 0, 0, false); \
760 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[3], K_SHIFT, NULL, 0, 0, 0, false); \
762 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[4], K_MOUSE2, NULL, 0, 0, 0, false); \
764 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[9], K_MOUSE3, NULL, 0, 0, 0, false); \
766 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[10], (keynum_t)'m', NULL, 0, 0, 0, false); \
768 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[11], (keynum_t)'b', NULL, 0, 0, 0, false); \
770 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[12], (keynum_t)'q', NULL, 0, 0, 0, false); \
772 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[13], (keynum_t)'`', NULL, 0, 0, 0, false); \
774 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[14], K_ESCAPE, NULL, 0, 0, 0, false); \
776 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[15], K_SPACE, NULL, 0, 0, 0, false); \
778 /////////////////////
782 static void IN_Move_TouchScreen_SteelStorm(void)
786 float xscale, yscale;
787 float move[3], aim[3];
788 static qboolean oldbuttons[128];
789 static qboolean buttons[128];
790 keydest_t keydest = (key_consoleactive & KEY_CONSOLEACTIVE_USER) ? key_console : key_dest;
791 memcpy(oldbuttons, buttons, sizeof(oldbuttons));
792 memset(multitouchs, 0, sizeof(multitouchs));
794 for (i = 0, numfingers = 0; i < MAXFINGERS - 1; i++)
795 if (multitouch[i][0])
799 Enable this to use a mouse as a touch device (it may conflict with the iamexclusive parameter if a finger is also reported as a mouse at the same location
802 multitouch[MAXFINGERS-1][0] = SDL_GetMouseState(&x, &y) ? 11 : 0;
803 multitouch[MAXFINGERS-1][1] = (float)x / vid.width;
804 multitouch[MAXFINGERS-1][2] = (float)y / vid.height;
808 // disable it so it doesn't get stuck, because SDL seems to stop updating it if there are more than 1 finger on screen
809 multitouch[MAXFINGERS-1][0] = 0;
812 // TODO: make touchscreen areas controlled by a config file or the VMs. THIS IS A MESS!
813 // TODO: can't just clear buttons[] when entering a new keydest, some keys would remain pressed
814 // SS:BR menuqc has many peculiarities, including that it can't accept more than one command per frame and pressing and releasing on the same frame
816 // Tuned for the SGS3, use it's value as a base. CLEAN THIS.
817 xscale = vid_touchscreen_density.value / 2.0f;
818 yscale = vid_touchscreen_density.value / 2.0f;
822 Vid_ClearAllTouchscreenAreas(14);
823 VID_TouchscreenArea( 0, 0, 160, 64, 64, "gfx/gui/touch_menu_button.tga" , 0.0f, NULL, NULL, &buttons[14], K_ESCAPE, NULL, 0, 0, 0, false);
826 if (steelstorm_showing_map && steelstorm_showing_map->integer) // FIXME: another hack to be removed when touchscreen areas go to QC
828 VID_TouchscreenArea( 0, 0, 0, vid_conwidth.value, vid_conheight.value, NULL , 0.0f, NULL, NULL, &buttons[10], (keynum_t)'m', NULL, 0, 0, 0, false);
829 Vid_ClearAllTouchscreenAreas(10);
831 else if (steelstorm_showing_mousecursor && steelstorm_showing_mousecursor->integer)
833 // in_windowmouse_x* is in screen resolution coordinates, not console resolution
834 VID_TouchscreenCursor((float)in_windowmouse_x/vid_width.value*vid_conwidth.value, (float)in_windowmouse_y/vid_height.value*vid_conheight.value, 192*xscale, 192*yscale, &buttons[0], K_MOUSE1);
835 Vid_ClearAllTouchscreenAreas(0);
839 VID_TouchscreenCursor(0, 0, 0, 0, &buttons[0], K_MOUSE1);
841 VID_TouchscreenArea( 2,16*xscale,-240*yscale, 224*xscale, 224*yscale, "gfx/gui/touch_l_thumb_dpad.tga", 0.0f, NULL, move, &buttons[1], (keynum_t)0, NULL, 0.15, 112*xscale, 112*yscale, false);
843 VID_TouchscreenArea( 3,-240*xscale,-160*yscale, 224*xscale, 128*yscale, "gfx/gui/touch_r_thumb_turn_n_shoot.tga" , 0.0f, NULL, NULL, 0, (keynum_t)0, NULL, 0, 56*xscale, 0, false);
844 VID_TouchscreenArea( 3,-240*xscale,-256*yscale, 224*xscale, 224*yscale, NULL , 0.0f, NULL, aim, &buttons[2], (keynum_t)0, NULL, 0.2, 56*xscale, 0, false);
846 VID_TouchscreenArea( 2, (vid_conwidth.value / 2) - 128,-80, 256, 80, NULL, 0.0f, NULL, NULL, &buttons[3], K_SHIFT, NULL, 0, 0, 0, true);
848 VID_TouchscreenArea( 3,-240*xscale,-256*yscale, 224*xscale, 64*yscale, "gfx/gui/touch_secondary_slide.tga", 0.0f, NULL, NULL, &buttons[4], K_MOUSE2, NULL, 0, 56*xscale, 0, false);
849 VID_TouchscreenArea( 3,-240*xscale,-256*yscale, 224*xscale, 160*yscale, NULL , 0.0f, NULL, NULL, &buttons[9], K_MOUSE3, NULL, 0.2, 56*xscale, 0, false);
851 VID_TouchscreenArea( 1,-100, 0, 100, 100, NULL , 0.0f, NULL, NULL, &buttons[10], (keynum_t)'m', NULL, 0, 0, 0, true);
852 VID_TouchscreenArea( 1,-100, 120, 100, 100, NULL , 0.0f, NULL, NULL, &buttons[11], (keynum_t)'b', NULL, 0, 0, 0, true);
853 VID_TouchscreenArea( 0, 0, 0, 64, 64, NULL , 0.0f, NULL, NULL, &buttons[12], (keynum_t)'q', NULL, 0, 0, 0, true);
854 if (developer.integer)
855 VID_TouchscreenArea( 0, 0, 96, 64, 64, NULL , 0.0f, NULL, NULL, &buttons[13], (keynum_t)'`', NULL, 0, 0, 0, true);
857 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[13], (keynum_t)'`', NULL, 0, 0, 0, false);
858 VID_TouchscreenArea( 0, 0, 160, 64, 64, "gfx/gui/touch_menu_button.tga" , 0.0f, NULL, NULL, &buttons[14], K_ESCAPE, NULL, 0, 0, 0, true);
859 switch(cl.activeweapon)
862 VID_TouchscreenArea( 2, 16*xscale,-320*yscale, 224*xscale, 64*yscale, "gfx/gui/touch_booster.tga" , 0.0f, NULL, NULL, &buttons[15], K_SPACE, NULL, 0, 0, 0, true);
865 VID_TouchscreenArea( 2, 16*xscale,-320*yscale, 224*xscale, 64*yscale, "gfx/gui/touch_shockwave.tga" , 0.0f, NULL, NULL, &buttons[15], K_SPACE, NULL, 0, 0, 0, true);
868 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[15], K_SPACE, NULL, 0, 0, 0, false);
873 if (!steelstorm_showing_mousecursor || !steelstorm_showing_mousecursor->integer)
875 Vid_ClearAllTouchscreenAreas(14);
876 // this way we can skip cutscenes
877 VID_TouchscreenArea( 0, 0, 0, vid_conwidth.value, vid_conheight.value, NULL , 0.0f, NULL, NULL, &buttons[14], K_ESCAPE, NULL, 0, 0, 0, false);
881 // in_windowmouse_x* is in screen resolution coordinates, not console resolution
882 VID_TouchscreenCursor((float)in_windowmouse_x/vid_width.value*vid_conwidth.value, (float)in_windowmouse_y/vid_height.value*vid_conheight.value, 192*xscale, 192*yscale, &buttons[0], K_MOUSE1);
883 Vid_ClearAllTouchscreenAreas(0);
888 if (VID_ShowingKeyboard() && (float)in_windowmouse_y > vid_height.value / 2 - 10)
889 in_windowmouse_y = 128;
891 cl.cmd.forwardmove -= move[1] * cl_forwardspeed.value;
892 cl.cmd.sidemove += move[0] * cl_sidespeed.value;
893 cl.viewangles[0] += aim[1] * cl_pitchspeed.value * cl.realframetime;
894 cl.viewangles[1] -= aim[0] * cl_yawspeed.value * cl.realframetime;
897 static void IN_Move_TouchScreen_Quake(void)
900 float move[3], aim[3], click[3];
901 static qboolean oldbuttons[128];
902 static qboolean buttons[128];
903 keydest_t keydest = (key_consoleactive & KEY_CONSOLEACTIVE_USER) ? key_console : key_dest;
904 memcpy(oldbuttons, buttons, sizeof(oldbuttons));
905 memset(multitouchs, 0, sizeof(multitouchs));
907 // simple quake controls
908 multitouch[MAXFINGERS-1][0] = SDL_GetMouseState(&x, &y);
909 multitouch[MAXFINGERS-1][1] = x * 32768 / vid.width;
910 multitouch[MAXFINGERS-1][2] = y * 32768 / vid.height;
912 // top of screen is toggleconsole and K_ESCAPE
916 VID_TouchscreenArea( 0, 0, 0, 64, 64, NULL , 0.0f, NULL, NULL, &buttons[13], (keynum_t)'`', NULL, 0, 0, 0, true);
917 VID_TouchscreenArea( 0, 64, 0, 64, 64, "gfx/touch_menu.tga" , 0.0f, NULL, NULL, &buttons[14], K_ESCAPE, NULL, 0, 0, 0, true);
918 if (!VID_ShowingKeyboard())
920 // user entered a command, close the console now
921 Con_ToggleConsole_f();
923 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[15], (keynum_t)0, NULL, 0, 0, 0, true);
924 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, move, &buttons[0], K_MOUSE4, NULL, 0, 0, 0, true);
925 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, aim, &buttons[1], K_MOUSE5, NULL, 0, 0, 0, true);
926 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, click,&buttons[2], K_MOUSE1, NULL, 0, 0, 0, true);
927 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[3], K_SPACE, NULL, 0, 0, 0, true);
928 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[4], K_MOUSE2, NULL, 0, 0, 0, true);
931 VID_TouchscreenArea( 0, 0, 0, 64, 64, NULL , 0.0f, NULL, NULL, &buttons[13], (keynum_t)'`', NULL, 0, 0, 0, true);
932 VID_TouchscreenArea( 0, 64, 0, 64, 64, "gfx/touch_menu.tga" , 0.0f, NULL, NULL, &buttons[14], K_ESCAPE, NULL, 0, 0, 0, true);
933 VID_TouchscreenArea( 2, 0,-128, 128, 128, "gfx/touch_movebutton.tga" , 0.0f, NULL, move, &buttons[0], K_MOUSE4, NULL, 0, 0, 0, true);
934 VID_TouchscreenArea( 3,-128,-128, 128, 128, "gfx/touch_aimbutton.tga" , 0.0f, NULL, aim, &buttons[1], K_MOUSE5, NULL, 0, 0, 0, true);
935 VID_TouchscreenArea( 2, 0,-160, 64, 32, "gfx/touch_jumpbutton.tga" , 0.0f, NULL, NULL, &buttons[3], K_SPACE, NULL, 0, 0, 0, true);
936 VID_TouchscreenArea( 3,-128,-160, 64, 32, "gfx/touch_attackbutton.tga" , 0.0f, NULL, NULL, &buttons[2], K_MOUSE1, NULL, 0, 0, 0, true);
937 VID_TouchscreenArea( 3, -64,-160, 64, 32, "gfx/touch_attack2button.tga", 0.0f, NULL, NULL, &buttons[4], K_MOUSE2, NULL, 0, 0, 0, true);
941 VID_TouchscreenArea( 0, 0, 0, 64, 64, NULL , 0.0f, NULL, NULL, &buttons[13], (keynum_t)'`', NULL, 0, 0, 0, true);
942 VID_TouchscreenArea( 0, 64, 0, 64, 64, "gfx/touch_menu.tga" , 0.0f, NULL, NULL, &buttons[14], K_ESCAPE, NULL, 0, 0, 0, true);
943 // in menus, an icon in the corner activates keyboard
944 VID_TouchscreenArea( 2, 0, -32, 32, 32, "gfx/touch_keyboard.tga" , 0.0f, NULL, NULL, &buttons[15], (keynum_t)0, NULL, 0, 0, 0, true);
946 VID_ShowKeyboard(true);
947 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, move, &buttons[0], K_MOUSE4, NULL, 0, 0, 0, true);
948 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, aim, &buttons[1], K_MOUSE5, NULL, 0, 0, 0, true);
949 VID_TouchscreenArea(16, -320,-480,640, 960, NULL , 0.0f, NULL, click,&buttons[2], K_MOUSE1, NULL, 0, 0, 0, true);
950 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[3], K_SPACE, NULL, 0, 0, 0, true);
951 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[4], K_MOUSE2, NULL, 0, 0, 0, true);
954 in_windowmouse_x = x;
955 in_windowmouse_y = y;
960 cl.cmd.forwardmove -= move[1] * cl_forwardspeed.value;
961 cl.cmd.sidemove += move[0] * cl_sidespeed.value;
962 cl.viewangles[0] += aim[1] * cl_pitchspeed.value * cl.realframetime;
963 cl.viewangles[1] -= aim[0] * cl_yawspeed.value * cl.realframetime;
968 static int old_x = 0, old_y = 0;
969 static int stuck = 0;
970 static keydest_t oldkeydest;
971 static qboolean oldshowkeyboard;
973 vid_joystate_t joystate;
974 keydest_t keydest = (key_consoleactive & KEY_CONSOLEACTIVE_USER) ? key_console : key_dest;
976 scr_numtouchscreenareas = 0;
978 // Only apply the new keyboard state if the input changes.
979 if (keydest != oldkeydest || !!vid_touchscreen_showkeyboard.integer != oldshowkeyboard)
983 case key_console: VID_ShowKeyboard(true);break;
984 case key_message: VID_ShowKeyboard(true);break;
985 default: VID_ShowKeyboard(!!vid_touchscreen_showkeyboard.integer); break;
988 oldkeydest = keydest;
989 oldshowkeyboard = !!vid_touchscreen_showkeyboard.integer;
991 if (vid_touchscreen.integer)
995 case GAME_STEELSTORM:
996 IN_Move_TouchScreen_SteelStorm();
999 IN_Move_TouchScreen_Quake();
1007 if (vid_stick_mouse.integer || !vid_usingmouse_relativeworks)
1009 // have the mouse stuck in the middle, example use: prevent expose effect of beryl during the game when not using
1010 // window grabbing. --blub
1012 // we need 2 frames to initialize the center position
1015 #if SDL_MAJOR_VERSION == 1
1016 SDL_WarpMouse(win_half_width, win_half_height);
1018 SDL_WarpMouseInWindow(window, win_half_width, win_half_height);
1020 SDL_GetMouseState(&x, &y);
1021 SDL_GetRelativeMouseState(&x, &y);
1024 SDL_GetRelativeMouseState(&x, &y);
1025 in_mouse_x = x + old_x;
1026 in_mouse_y = y + old_y;
1027 SDL_GetMouseState(&x, &y);
1028 old_x = x - win_half_width;
1029 old_y = y - win_half_height;
1030 #if SDL_MAJOR_VERSION == 1
1031 SDL_WarpMouse(win_half_width, win_half_height);
1033 SDL_WarpMouseInWindow(window, win_half_width, win_half_height);
1037 SDL_GetRelativeMouseState( &x, &y );
1043 SDL_GetMouseState(&x, &y);
1044 in_windowmouse_x = x;
1045 in_windowmouse_y = y;
1048 VID_BuildJoyState(&joystate);
1049 VID_ApplyJoyState(&joystate);
1052 /////////////////////
1056 #ifdef SDL_R_RESTART
1057 static qboolean sdl_needs_restart;
1058 static void sdl_start(void)
1061 static void sdl_shutdown(void)
1063 sdl_needs_restart = false;
1065 static void sdl_newmap(void)
1070 static keynum_t buttonremap[] =
1075 #if SDL_MAJOR_VERSION == 1
1076 // TODO Find out how SDL maps these buttons. It looks like we should
1077 // still include these for sdl2? At least the button indexes don't
1078 // differ between SDL1 and SDL2 for me, thus this array should stay the
1079 // same (in X11 button order).
1098 #if SDL_MAJOR_VERSION == 1
1100 void Sys_SendKeyEvents( void )
1102 static qboolean sound_active = true;
1106 VID_EnableJoystick(true);
1108 while( SDL_PollEvent( &event ) )
1109 switch( event.type ) {
1115 keycode = MapKey(event.key.keysym.sym);
1116 if (!VID_JoyBlockEmulatedKeys(keycode))
1118 if(keycode == K_NUMLOCK || keycode == K_CAPSLOCK)
1120 // simulate down followed by up
1121 Key_Event(keycode, event.key.keysym.unicode, true);
1122 Key_Event(keycode, event.key.keysym.unicode, false);
1125 Key_Event(keycode, event.key.keysym.unicode, (event.key.state == SDL_PRESSED));
1128 case SDL_ACTIVEEVENT:
1129 if( event.active.state & SDL_APPACTIVE )
1131 if( event.active.gain )
1137 case SDL_MOUSEBUTTONDOWN:
1138 case SDL_MOUSEBUTTONUP:
1139 if (!vid_touchscreen.integer)
1140 if (event.button.button > 0 && event.button.button <= ARRAY_SIZE(buttonremap))
1141 Key_Event( buttonremap[event.button.button - 1], 0, event.button.state == SDL_PRESSED );
1143 case SDL_JOYBUTTONDOWN:
1144 case SDL_JOYBUTTONUP:
1145 case SDL_JOYAXISMOTION:
1146 case SDL_JOYBALLMOTION:
1147 case SDL_JOYHATMOTION:
1149 case SDL_VIDEOEXPOSE:
1151 case SDL_VIDEORESIZE:
1152 if(vid_resizable.integer < 2 || vid_isfullscreen)
1154 vid.width = event.resize.w;
1155 vid.height = event.resize.h;
1156 if (!vid_isfullscreen)
1157 video_screen = SDL_SetVideoMode(vid.width, vid.height, video_bpp, video_flags);
1158 if (vid_softsurface)
1160 SDL_FreeSurface(vid_softsurface);
1161 vid_softsurface = SDL_CreateRGBSurface(SDL_SWSURFACE, vid.width, vid.height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
1162 SDL_SetAlpha(vid_softsurface, 0, 255);
1163 vid.softpixels = (unsigned int *)vid_softsurface->pixels;
1164 if (vid.softdepthpixels)
1165 free(vid.softdepthpixels);
1166 vid.softdepthpixels = (unsigned int*)calloc(1, vid.width * vid.height * 4);
1168 #ifdef SDL_R_RESTART
1169 // better not call R_Modules_Restart from here directly, as this may wreak havoc...
1170 // so, let's better queue it for next frame
1171 if(!sdl_needs_restart)
1173 Cbuf_AddText("\nr_restart\n");
1174 sdl_needs_restart = true;
1179 #if SDL_MAJOR_VERSION != 1
1180 case SDL_TEXTEDITING:
1185 case SDL_MOUSEMOTION:
1188 Con_DPrintf("Received unrecognized SDL_Event type 0x%x\n", event.type);
1192 // enable/disable sound on focus gain/loss
1193 if ((!vid_hidden && vid_activewindow) || !snd_mutewhenidle.integer)
1198 sound_active = true;
1206 sound_active = false;
1213 //#define DEBUGSDLEVENTS
1216 void Sys_SendKeyEvents( void )
1218 static qboolean sound_active = true;
1225 VID_EnableJoystick(true);
1227 while( SDL_PollEvent( &event ) )
1229 switch( event.type ) {
1231 #ifdef DEBUGSDLEVENTS
1232 Con_DPrintf("SDL_Event: SDL_QUIT\n");
1238 #ifdef DEBUGSDLEVENTS
1239 if (event.type == SDL_KEYDOWN)
1240 Con_DPrintf("SDL_Event: SDL_KEYDOWN %i\n", event.key.keysym.sym);
1242 Con_DPrintf("SDL_Event: SDL_KEYUP %i\n", event.key.keysym.sym);
1244 keycode = MapKey(event.key.keysym.sym);
1245 isdown = (event.key.state == SDL_PRESSED);
1249 if(SDL_PollEvent(&event))
1251 if(event.type == SDL_TEXTINPUT)
1253 // combine key code from SDL_KEYDOWN event and character
1254 // from SDL_TEXTINPUT event in a single Key_Event call
1255 #ifdef DEBUGSDLEVENTS
1256 Con_DPrintf("SDL_Event: SDL_TEXTINPUT - text: %s\n", event.text.text);
1258 unicode = u8_getchar_utf8_enabled(event.text.text + (int)u8_bytelen(event.text.text, 0), NULL);
1262 if (!VID_JoyBlockEmulatedKeys(keycode))
1263 Key_Event(keycode, 0, isdown);
1268 if (!VID_JoyBlockEmulatedKeys(keycode))
1269 Key_Event(keycode, unicode, isdown);
1271 case SDL_MOUSEBUTTONDOWN:
1272 case SDL_MOUSEBUTTONUP:
1273 #ifdef DEBUGSDLEVENTS
1274 if (event.type == SDL_MOUSEBUTTONDOWN)
1275 Con_DPrintf("SDL_Event: SDL_MOUSEBUTTONDOWN\n");
1277 Con_DPrintf("SDL_Event: SDL_MOUSEBUTTONUP\n");
1279 if (!vid_touchscreen.integer)
1280 if (event.button.button > 0 && event.button.button <= ARRAY_SIZE(buttonremap))
1281 Key_Event( buttonremap[event.button.button - 1], 0, event.button.state == SDL_PRESSED );
1283 case SDL_MOUSEWHEEL:
1284 // TODO support wheel x direction.
1288 Key_Event( K_MWHEELUP, 0, true );
1289 Key_Event( K_MWHEELUP, 0, false );
1293 Key_Event( K_MWHEELDOWN, 0, true );
1294 Key_Event( K_MWHEELDOWN, 0, false );
1297 case SDL_JOYBUTTONDOWN:
1298 case SDL_JOYBUTTONUP:
1299 case SDL_JOYAXISMOTION:
1300 case SDL_JOYBALLMOTION:
1301 case SDL_JOYHATMOTION:
1302 #ifdef DEBUGSDLEVENTS
1303 Con_DPrintf("SDL_Event: SDL_JOY*\n");
1306 case SDL_WINDOWEVENT:
1307 #ifdef DEBUGSDLEVENTS
1308 Con_DPrintf("SDL_Event: SDL_WINDOWEVENT %i\n", (int)event.window.event);
1310 //if (event.window.windowID == window) // how to compare?
1312 switch(event.window.event)
1314 case SDL_WINDOWEVENT_SHOWN:
1317 case SDL_WINDOWEVENT_HIDDEN:
1320 case SDL_WINDOWEVENT_EXPOSED:
1321 #ifdef DEBUGSDLEVENTS
1322 Con_DPrintf("SDL_Event: SDL_WINDOWEVENT_EXPOSED\n");
1325 case SDL_WINDOWEVENT_MOVED:
1327 case SDL_WINDOWEVENT_RESIZED:
1328 if(vid_resizable.integer < 2)
1330 vid.width = event.window.data1;
1331 vid.height = event.window.data2;
1332 if (vid_softsurface)
1334 SDL_FreeSurface(vid_softsurface);
1335 vid_softsurface = SDL_CreateRGBSurface(SDL_SWSURFACE, vid.width, vid.height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
1336 SDL_SetSurfaceBlendMode(vid_softsurface, SDL_BLENDMODE_NONE);
1337 vid.softpixels = (unsigned int *)vid_softsurface->pixels;
1338 if (vid.softdepthpixels)
1339 free(vid.softdepthpixels);
1340 vid.softdepthpixels = (unsigned int*)calloc(1, vid.width * vid.height * 4);
1342 #ifdef SDL_R_RESTART
1343 // better not call R_Modules_Restart from here directly, as this may wreak havoc...
1344 // so, let's better queue it for next frame
1345 if(!sdl_needs_restart)
1347 Cbuf_AddText("\nr_restart\n");
1348 sdl_needs_restart = true;
1353 case SDL_WINDOWEVENT_MINIMIZED:
1355 case SDL_WINDOWEVENT_MAXIMIZED:
1357 case SDL_WINDOWEVENT_RESTORED:
1359 case SDL_WINDOWEVENT_ENTER:
1361 case SDL_WINDOWEVENT_LEAVE:
1363 case SDL_WINDOWEVENT_FOCUS_GAINED:
1364 vid_hasfocus = true;
1366 case SDL_WINDOWEVENT_FOCUS_LOST:
1367 vid_hasfocus = false;
1369 case SDL_WINDOWEVENT_CLOSE:
1375 case SDL_TEXTEDITING:
1376 #ifdef DEBUGSDLEVENTS
1377 Con_DPrintf("SDL_Event: SDL_TEXTEDITING - composition = %s, cursor = %d, selection lenght = %d\n", event.edit.text, event.edit.start, event.edit.length);
1379 // FIXME! this is where composition gets supported
1382 #ifdef DEBUGSDLEVENTS
1383 Con_DPrintf("SDL_Event: SDL_TEXTINPUT - text: %s\n", event.text.text);
1385 // convert utf8 string to char
1386 // NOTE: this code is supposed to run even if utf8enable is 0
1387 unicode = u8_getchar_utf8_enabled(event.text.text + (int)u8_bytelen(event.text.text, 0), NULL);
1388 Key_Event(K_TEXT, unicode, true);
1389 Key_Event(K_TEXT, unicode, false);
1391 case SDL_MOUSEMOTION:
1393 case SDL_FINGERDOWN:
1394 #ifdef DEBUGSDLEVENTS
1395 Con_DPrintf("SDL_FINGERDOWN for finger %i\n", (int)event.tfinger.fingerId);
1397 for (i = 0;i < MAXFINGERS-1;i++)
1399 if (!multitouch[i][0])
1401 multitouch[i][0] = event.tfinger.fingerId + 1;
1402 multitouch[i][1] = event.tfinger.x;
1403 multitouch[i][2] = event.tfinger.y;
1404 // TODO: use event.tfinger.pressure?
1408 if (i == MAXFINGERS-1)
1409 Con_DPrintf("Too many fingers at once!\n");
1412 #ifdef DEBUGSDLEVENTS
1413 Con_DPrintf("SDL_FINGERUP for finger %i\n", (int)event.tfinger.fingerId);
1415 for (i = 0;i < MAXFINGERS-1;i++)
1417 if (multitouch[i][0] == event.tfinger.fingerId + 1)
1419 multitouch[i][0] = 0;
1423 if (i == MAXFINGERS-1)
1424 Con_DPrintf("No SDL_FINGERDOWN event matches this SDL_FINGERMOTION event\n");
1426 case SDL_FINGERMOTION:
1427 #ifdef DEBUGSDLEVENTS
1428 Con_DPrintf("SDL_FINGERMOTION for finger %i\n", (int)event.tfinger.fingerId);
1430 for (i = 0;i < MAXFINGERS-1;i++)
1432 if (multitouch[i][0] == event.tfinger.fingerId + 1)
1434 multitouch[i][1] = event.tfinger.x;
1435 multitouch[i][2] = event.tfinger.y;
1439 if (i == MAXFINGERS-1)
1440 Con_DPrintf("No SDL_FINGERDOWN event matches this SDL_FINGERMOTION event\n");
1443 #ifdef DEBUGSDLEVENTS
1444 Con_DPrintf("Received unrecognized SDL_Event type 0x%x\n", event.type);
1449 // enable/disable sound on focus gain/loss
1450 if ((!vid_hidden && vid_activewindow) || !snd_mutewhenidle.integer)
1455 sound_active = true;
1463 sound_active = false;
1476 #include <OpenGLES/ES2/gl.h>
1478 #include <SDL_opengles.h>
1481 //#define PRECALL //Con_Printf("GLCALL %s:%i\n", __FILE__, __LINE__)
1484 GLboolean wrapglIsBuffer(GLuint buffer) {PRECALL;return glIsBuffer(buffer);POSTCALL;}
1485 GLboolean wrapglIsEnabled(GLenum cap) {PRECALL;return glIsEnabled(cap);POSTCALL;}
1486 GLboolean wrapglIsFramebuffer(GLuint framebuffer) {PRECALL;return glIsFramebuffer(framebuffer);POSTCALL;}
1487 //GLboolean wrapglIsQuery(GLuint qid) {PRECALL;return glIsQuery(qid);POSTCALL;}
1488 GLboolean wrapglIsRenderbuffer(GLuint renderbuffer) {PRECALL;return glIsRenderbuffer(renderbuffer);POSTCALL;}
1489 //GLboolean wrapglUnmapBuffer(GLenum target) {PRECALL;return glUnmapBuffer(target);POSTCALL;}
1490 GLenum wrapglCheckFramebufferStatus(GLenum target) {PRECALL;return glCheckFramebufferStatus(target);POSTCALL;}
1491 GLenum wrapglGetError(void) {PRECALL;return glGetError();POSTCALL;}
1492 GLuint wrapglCreateProgram(void) {PRECALL;return glCreateProgram();POSTCALL;}
1493 GLuint wrapglCreateShader(GLenum shaderType) {PRECALL;return glCreateShader(shaderType);POSTCALL;}
1494 //GLuint wrapglGetHandle(GLenum pname) {PRECALL;return glGetHandle(pname);POSTCALL;}
1495 GLint wrapglGetAttribLocation(GLuint programObj, const GLchar *name) {PRECALL;return glGetAttribLocation(programObj, name);POSTCALL;}
1496 GLint wrapglGetUniformLocation(GLuint programObj, const GLchar *name) {PRECALL;return glGetUniformLocation(programObj, name);POSTCALL;}
1497 //GLvoid* wrapglMapBuffer(GLenum target, GLenum access) {PRECALL;return glMapBuffer(target, access);POSTCALL;}
1498 const GLubyte* wrapglGetString(GLenum name) {PRECALL;return (const GLubyte*)glGetString(name);POSTCALL;}
1499 void wrapglActiveStencilFace(GLenum e) {PRECALL;Con_Printf("glActiveStencilFace(e)\n");POSTCALL;}
1500 void wrapglActiveTexture(GLenum e) {PRECALL;glActiveTexture(e);POSTCALL;}
1501 void wrapglAlphaFunc(GLenum func, GLclampf ref) {PRECALL;Con_Printf("glAlphaFunc(func, ref)\n");POSTCALL;}
1502 void wrapglArrayElement(GLint i) {PRECALL;Con_Printf("glArrayElement(i)\n");POSTCALL;}
1503 void wrapglAttachShader(GLuint containerObj, GLuint obj) {PRECALL;glAttachShader(containerObj, obj);POSTCALL;}
1504 //void wrapglBegin(GLenum mode) {PRECALL;Con_Printf("glBegin(mode)\n");POSTCALL;}
1505 //void wrapglBeginQuery(GLenum target, GLuint qid) {PRECALL;glBeginQuery(target, qid);POSTCALL;}
1506 void wrapglBindAttribLocation(GLuint programObj, GLuint index, const GLchar *name) {PRECALL;glBindAttribLocation(programObj, index, name);POSTCALL;}
1507 //void wrapglBindFragDataLocation(GLuint programObj, GLuint index, const GLchar *name) {PRECALL;glBindFragDataLocation(programObj, index, name);POSTCALL;}
1508 void wrapglBindBuffer(GLenum target, GLuint buffer) {PRECALL;glBindBuffer(target, buffer);POSTCALL;}
1509 void wrapglBindFramebuffer(GLenum target, GLuint framebuffer) {PRECALL;glBindFramebuffer(target, framebuffer);POSTCALL;}
1510 void wrapglBindRenderbuffer(GLenum target, GLuint renderbuffer) {PRECALL;glBindRenderbuffer(target, renderbuffer);POSTCALL;}
1511 void wrapglBindTexture(GLenum target, GLuint texture) {PRECALL;glBindTexture(target, texture);POSTCALL;}
1512 void wrapglBlendEquation(GLenum e) {PRECALL;glBlendEquation(e);POSTCALL;}
1513 void wrapglBlendFunc(GLenum sfactor, GLenum dfactor) {PRECALL;glBlendFunc(sfactor, dfactor);POSTCALL;}
1514 void wrapglBufferData(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) {PRECALL;glBufferData(target, size, data, usage);POSTCALL;}
1515 void wrapglBufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) {PRECALL;glBufferSubData(target, offset, size, data);POSTCALL;}
1516 void wrapglClear(GLbitfield mask) {PRECALL;glClear(mask);POSTCALL;}
1517 void wrapglClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {PRECALL;glClearColor(red, green, blue, alpha);POSTCALL;}
1518 void wrapglClearDepth(GLclampd depth) {PRECALL;/*Con_Printf("glClearDepth(%f)\n", depth);glClearDepthf((float)depth);*/POSTCALL;}
1519 void wrapglClearStencil(GLint s) {PRECALL;glClearStencil(s);POSTCALL;}
1520 void wrapglClientActiveTexture(GLenum target) {PRECALL;Con_Printf("glClientActiveTexture(target)\n");POSTCALL;}
1521 void wrapglColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {PRECALL;Con_Printf("glColor4f(red, green, blue, alpha)\n");POSTCALL;}
1522 void wrapglColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) {PRECALL;Con_Printf("glColor4ub(red, green, blue, alpha)\n");POSTCALL;}
1523 void wrapglColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {PRECALL;glColorMask(red, green, blue, alpha);POSTCALL;}
1524 void wrapglColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) {PRECALL;Con_Printf("glColorPointer(size, type, stride, ptr)\n");POSTCALL;}
1525 void wrapglCompileShader(GLuint shaderObj) {PRECALL;glCompileShader(shaderObj);POSTCALL;}
1526 void wrapglCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data) {PRECALL;glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);POSTCALL;}
1527 void wrapglCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data) {PRECALL;Con_Printf("glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data)\n");POSTCALL;}
1528 void wrapglCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) {PRECALL;glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);POSTCALL;}
1529 void wrapglCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data) {PRECALL;Con_Printf("glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data)\n");POSTCALL;}
1530 void wrapglCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {PRECALL;glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);POSTCALL;}
1531 void wrapglCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {PRECALL;glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);POSTCALL;}
1532 void wrapglCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {PRECALL;Con_Printf("glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height)\n");POSTCALL;}
1533 void wrapglCullFace(GLenum mode) {PRECALL;glCullFace(mode);POSTCALL;}
1534 void wrapglDeleteBuffers(GLsizei n, const GLuint *buffers) {PRECALL;glDeleteBuffers(n, buffers);POSTCALL;}
1535 void wrapglDeleteFramebuffers(GLsizei n, const GLuint *framebuffers) {PRECALL;glDeleteFramebuffers(n, framebuffers);POSTCALL;}
1536 void wrapglDeleteShader(GLuint obj) {PRECALL;glDeleteShader(obj);POSTCALL;}
1537 void wrapglDeleteProgram(GLuint obj) {PRECALL;glDeleteProgram(obj);POSTCALL;}
1538 //void wrapglDeleteQueries(GLsizei n, const GLuint *ids) {PRECALL;glDeleteQueries(n, ids);POSTCALL;}
1539 void wrapglDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) {PRECALL;glDeleteRenderbuffers(n, renderbuffers);POSTCALL;}
1540 void wrapglDeleteTextures(GLsizei n, const GLuint *textures) {PRECALL;glDeleteTextures(n, textures);POSTCALL;}
1541 void wrapglDepthFunc(GLenum func) {PRECALL;glDepthFunc(func);POSTCALL;}
1542 void wrapglDepthMask(GLboolean flag) {PRECALL;glDepthMask(flag);POSTCALL;}
1543 //void wrapglDepthRange(GLclampd near_val, GLclampd far_val) {PRECALL;glDepthRangef((float)near_val, (float)far_val);POSTCALL;}
1544 void wrapglDepthRangef(GLclampf near_val, GLclampf far_val) {PRECALL;glDepthRangef(near_val, far_val);POSTCALL;}
1545 void wrapglDetachShader(GLuint containerObj, GLuint attachedObj) {PRECALL;glDetachShader(containerObj, attachedObj);POSTCALL;}
1546 void wrapglDisable(GLenum cap) {PRECALL;glDisable(cap);POSTCALL;}
1547 void wrapglDisableClientState(GLenum cap) {PRECALL;Con_Printf("glDisableClientState(cap)\n");POSTCALL;}
1548 void wrapglDisableVertexAttribArray(GLuint index) {PRECALL;glDisableVertexAttribArray(index);POSTCALL;}
1549 void wrapglDrawArrays(GLenum mode, GLint first, GLsizei count) {PRECALL;glDrawArrays(mode, first, count);POSTCALL;}
1550 void wrapglDrawBuffer(GLenum mode) {PRECALL;Con_Printf("glDrawBuffer(mode)\n");POSTCALL;}
1551 void wrapglDrawBuffers(GLsizei n, const GLenum *bufs) {PRECALL;Con_Printf("glDrawBuffers(n, bufs)\n");POSTCALL;}
1552 void wrapglDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {PRECALL;glDrawElements(mode, count, type, indices);POSTCALL;}
1553 //void wrapglDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) {PRECALL;glDrawRangeElements(mode, start, end, count, type, indices);POSTCALL;}
1554 //void wrapglDrawRangeElementsEXT(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) {PRECALL;glDrawRangeElements(mode, start, end, count, type, indices);POSTCALL;}
1555 void wrapglEnable(GLenum cap) {PRECALL;glEnable(cap);POSTCALL;}
1556 void wrapglEnableClientState(GLenum cap) {PRECALL;Con_Printf("glEnableClientState(cap)\n");POSTCALL;}
1557 void wrapglEnableVertexAttribArray(GLuint index) {PRECALL;glEnableVertexAttribArray(index);POSTCALL;}
1558 //void wrapglEnd(void) {PRECALL;Con_Printf("glEnd()\n");POSTCALL;}
1559 //void wrapglEndQuery(GLenum target) {PRECALL;glEndQuery(target);POSTCALL;}
1560 void wrapglFinish(void) {PRECALL;glFinish();POSTCALL;}
1561 void wrapglFlush(void) {PRECALL;glFlush();POSTCALL;}
1562 void wrapglFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {PRECALL;glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);POSTCALL;}
1563 void wrapglFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {PRECALL;glFramebufferTexture2D(target, attachment, textarget, texture, level);POSTCALL;}
1564 void wrapglFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) {PRECALL;Con_Printf("glFramebufferTexture3D()\n");POSTCALL;}
1565 void wrapglGenBuffers(GLsizei n, GLuint *buffers) {PRECALL;glGenBuffers(n, buffers);POSTCALL;}
1566 void wrapglGenFramebuffers(GLsizei n, GLuint *framebuffers) {PRECALL;glGenFramebuffers(n, framebuffers);POSTCALL;}
1567 //void wrapglGenQueries(GLsizei n, GLuint *ids) {PRECALL;glGenQueries(n, ids);POSTCALL;}
1568 void wrapglGenRenderbuffers(GLsizei n, GLuint *renderbuffers) {PRECALL;glGenRenderbuffers(n, renderbuffers);POSTCALL;}
1569 void wrapglGenTextures(GLsizei n, GLuint *textures) {PRECALL;glGenTextures(n, textures);POSTCALL;}
1570 void wrapglGenerateMipmap(GLenum target) {PRECALL;glGenerateMipmap(target);POSTCALL;}
1571 void wrapglGetActiveAttrib(GLuint programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLchar *name) {PRECALL;glGetActiveAttrib(programObj, index, maxLength, length, size, type, name);POSTCALL;}
1572 void wrapglGetActiveUniform(GLuint programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLchar *name) {PRECALL;glGetActiveUniform(programObj, index, maxLength, length, size, type, name);POSTCALL;}
1573 void wrapglGetAttachedShaders(GLuint containerObj, GLsizei maxCount, GLsizei *count, GLuint *obj) {PRECALL;glGetAttachedShaders(containerObj, maxCount, count, obj);POSTCALL;}
1574 void wrapglGetBooleanv(GLenum pname, GLboolean *params) {PRECALL;glGetBooleanv(pname, params);POSTCALL;}
1575 void wrapglGetCompressedTexImage(GLenum target, GLint lod, void *img) {PRECALL;Con_Printf("glGetCompressedTexImage(target, lod, img)\n");POSTCALL;}
1576 void wrapglGetDoublev(GLenum pname, GLdouble *params) {PRECALL;Con_Printf("glGetDoublev(pname, params)\n");POSTCALL;}
1577 void wrapglGetFloatv(GLenum pname, GLfloat *params) {PRECALL;glGetFloatv(pname, params);POSTCALL;}
1578 void wrapglGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params) {PRECALL;glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);POSTCALL;}
1579 void wrapglGetShaderInfoLog(GLuint obj, GLsizei maxLength, GLsizei *length, GLchar *infoLog) {PRECALL;glGetShaderInfoLog(obj, maxLength, length, infoLog);POSTCALL;}
1580 void wrapglGetProgramInfoLog(GLuint obj, GLsizei maxLength, GLsizei *length, GLchar *infoLog) {PRECALL;glGetProgramInfoLog(obj, maxLength, length, infoLog);POSTCALL;}
1581 void wrapglGetIntegerv(GLenum pname, GLint *params) {PRECALL;glGetIntegerv(pname, params);POSTCALL;}
1582 void wrapglGetShaderiv(GLuint obj, GLenum pname, GLint *params) {PRECALL;glGetShaderiv(obj, pname, params);POSTCALL;}
1583 void wrapglGetProgramiv(GLuint obj, GLenum pname, GLint *params) {PRECALL;glGetProgramiv(obj, pname, params);POSTCALL;}
1584 //void wrapglGetQueryObjectiv(GLuint qid, GLenum pname, GLint *params) {PRECALL;glGetQueryObjectiv(qid, pname, params);POSTCALL;}
1585 //void wrapglGetQueryObjectuiv(GLuint qid, GLenum pname, GLuint *params) {PRECALL;glGetQueryObjectuiv(qid, pname, params);POSTCALL;}
1586 //void wrapglGetQueryiv(GLenum target, GLenum pname, GLint *params) {PRECALL;glGetQueryiv(target, pname, params);POSTCALL;}
1587 void wrapglGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params) {PRECALL;glGetRenderbufferParameteriv(target, pname, params);POSTCALL;}
1588 void wrapglGetShaderSource(GLuint obj, GLsizei maxLength, GLsizei *length, GLchar *source) {PRECALL;glGetShaderSource(obj, maxLength, length, source);POSTCALL;}
1589 void wrapglGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels) {PRECALL;Con_Printf("glGetTexImage(target, level, format, type, pixels)\n");POSTCALL;}
1590 void wrapglGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params) {PRECALL;Con_Printf("glGetTexLevelParameterfv(target, level, pname, params)\n");POSTCALL;}
1591 void wrapglGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) {PRECALL;Con_Printf("glGetTexLevelParameteriv(target, level, pname, params)\n");POSTCALL;}
1592 void wrapglGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) {PRECALL;glGetTexParameterfv(target, pname, params);POSTCALL;}
1593 void wrapglGetTexParameteriv(GLenum target, GLenum pname, GLint *params) {PRECALL;glGetTexParameteriv(target, pname, params);POSTCALL;}
1594 void wrapglGetUniformfv(GLuint programObj, GLint location, GLfloat *params) {PRECALL;glGetUniformfv(programObj, location, params);POSTCALL;}
1595 void wrapglGetUniformiv(GLuint programObj, GLint location, GLint *params) {PRECALL;glGetUniformiv(programObj, location, params);POSTCALL;}
1596 void wrapglHint(GLenum target, GLenum mode) {PRECALL;glHint(target, mode);POSTCALL;}
1597 void wrapglLineWidth(GLfloat width) {PRECALL;glLineWidth(width);POSTCALL;}
1598 void wrapglLinkProgram(GLuint programObj) {PRECALL;glLinkProgram(programObj);POSTCALL;}
1599 void wrapglLoadIdentity(void) {PRECALL;Con_Printf("glLoadIdentity()\n");POSTCALL;}
1600 void wrapglLoadMatrixf(const GLfloat *m) {PRECALL;Con_Printf("glLoadMatrixf(m)\n");POSTCALL;}
1601 void wrapglMatrixMode(GLenum mode) {PRECALL;Con_Printf("glMatrixMode(mode)\n");POSTCALL;}
1602 void wrapglMultiTexCoord1f(GLenum target, GLfloat s) {PRECALL;Con_Printf("glMultiTexCoord1f(target, s)\n");POSTCALL;}
1603 void wrapglMultiTexCoord2f(GLenum target, GLfloat s, GLfloat t) {PRECALL;Con_Printf("glMultiTexCoord2f(target, s, t)\n");POSTCALL;}
1604 void wrapglMultiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r) {PRECALL;Con_Printf("glMultiTexCoord3f(target, s, t, r)\n");POSTCALL;}
1605 void wrapglMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {PRECALL;Con_Printf("glMultiTexCoord4f(target, s, t, r, q)\n");POSTCALL;}
1606 void wrapglNormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr) {PRECALL;Con_Printf("glNormalPointer(type, stride, ptr)\n");POSTCALL;}
1607 void wrapglPixelStorei(GLenum pname, GLint param) {PRECALL;glPixelStorei(pname, param);POSTCALL;}
1608 void wrapglPointSize(GLfloat size) {PRECALL;Con_Printf("glPointSize(size)\n");POSTCALL;}
1609 //void wrapglPolygonMode(GLenum face, GLenum mode) {PRECALL;Con_Printf("glPolygonMode(face, mode)\n");POSTCALL;}
1610 void wrapglPolygonOffset(GLfloat factor, GLfloat units) {PRECALL;glPolygonOffset(factor, units);POSTCALL;}
1611 void wrapglPolygonStipple(const GLubyte *mask) {PRECALL;Con_Printf("glPolygonStipple(mask)\n");POSTCALL;}
1612 void wrapglReadBuffer(GLenum mode) {PRECALL;Con_Printf("glReadBuffer(mode)\n");POSTCALL;}
1613 void wrapglReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {PRECALL;glReadPixels(x, y, width, height, format, type, pixels);POSTCALL;}
1614 void wrapglRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {PRECALL;glRenderbufferStorage(target, internalformat, width, height);POSTCALL;}
1615 void wrapglScissor(GLint x, GLint y, GLsizei width, GLsizei height) {PRECALL;glScissor(x, y, width, height);POSTCALL;}
1616 void wrapglShaderSource(GLuint shaderObj, GLsizei count, const GLchar **string, const GLint *length) {PRECALL;glShaderSource(shaderObj, count, string, length);POSTCALL;}
1617 void wrapglStencilFunc(GLenum func, GLint ref, GLuint mask) {PRECALL;glStencilFunc(func, ref, mask);POSTCALL;}
1618 void wrapglStencilFuncSeparate(GLenum func1, GLenum func2, GLint ref, GLuint mask) {PRECALL;Con_Printf("glStencilFuncSeparate(func1, func2, ref, mask)\n");POSTCALL;}
1619 void wrapglStencilMask(GLuint mask) {PRECALL;glStencilMask(mask);POSTCALL;}
1620 void wrapglStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {PRECALL;glStencilOp(fail, zfail, zpass);POSTCALL;}
1621 void wrapglStencilOpSeparate(GLenum e1, GLenum e2, GLenum e3, GLenum e4) {PRECALL;Con_Printf("glStencilOpSeparate(e1, e2, e3, e4)\n");POSTCALL;}
1622 void wrapglTexCoord1f(GLfloat s) {PRECALL;Con_Printf("glTexCoord1f(s)\n");POSTCALL;}
1623 void wrapglTexCoord2f(GLfloat s, GLfloat t) {PRECALL;Con_Printf("glTexCoord2f(s, t)\n");POSTCALL;}
1624 void wrapglTexCoord3f(GLfloat s, GLfloat t, GLfloat r) {PRECALL;Con_Printf("glTexCoord3f(s, t, r)\n");POSTCALL;}
1625 void wrapglTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) {PRECALL;Con_Printf("glTexCoord4f(s, t, r, q)\n");POSTCALL;}
1626 void wrapglTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) {PRECALL;Con_Printf("glTexCoordPointer(size, type, stride, ptr)\n");POSTCALL;}
1627 void wrapglTexEnvf(GLenum target, GLenum pname, GLfloat param) {PRECALL;Con_Printf("glTexEnvf(target, pname, param)\n");POSTCALL;}
1628 void wrapglTexEnvfv(GLenum target, GLenum pname, const GLfloat *params) {PRECALL;Con_Printf("glTexEnvfv(target, pname, params)\n");POSTCALL;}
1629 void wrapglTexEnvi(GLenum target, GLenum pname, GLint param) {PRECALL;Con_Printf("glTexEnvi(target, pname, param)\n");POSTCALL;}
1630 void wrapglTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {PRECALL;glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);POSTCALL;}
1631 void wrapglTexImage3D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {PRECALL;Con_Printf("glTexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels)\n");POSTCALL;}
1632 void wrapglTexParameterf(GLenum target, GLenum pname, GLfloat param) {PRECALL;glTexParameterf(target, pname, param);POSTCALL;}
1633 void wrapglTexParameterfv(GLenum target, GLenum pname, GLfloat *params) {PRECALL;glTexParameterfv(target, pname, params);POSTCALL;}
1634 void wrapglTexParameteri(GLenum target, GLenum pname, GLint param) {PRECALL;glTexParameteri(target, pname, param);POSTCALL;}
1635 void wrapglTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) {PRECALL;glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);POSTCALL;}
1636 void wrapglTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) {PRECALL;Con_Printf("glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels)\n");POSTCALL;}
1637 void wrapglUniform1f(GLint location, GLfloat v0) {PRECALL;glUniform1f(location, v0);POSTCALL;}
1638 void wrapglUniform1fv(GLint location, GLsizei count, const GLfloat *value) {PRECALL;glUniform1fv(location, count, value);POSTCALL;}
1639 void wrapglUniform1i(GLint location, GLint v0) {PRECALL;glUniform1i(location, v0);POSTCALL;}
1640 void wrapglUniform1iv(GLint location, GLsizei count, const GLint *value) {PRECALL;glUniform1iv(location, count, value);POSTCALL;}
1641 void wrapglUniform2f(GLint location, GLfloat v0, GLfloat v1) {PRECALL;glUniform2f(location, v0, v1);POSTCALL;}
1642 void wrapglUniform2fv(GLint location, GLsizei count, const GLfloat *value) {PRECALL;glUniform2fv(location, count, value);POSTCALL;}
1643 void wrapglUniform2i(GLint location, GLint v0, GLint v1) {PRECALL;glUniform2i(location, v0, v1);POSTCALL;}
1644 void wrapglUniform2iv(GLint location, GLsizei count, const GLint *value) {PRECALL;glUniform2iv(location, count, value);POSTCALL;}
1645 void wrapglUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {PRECALL;glUniform3f(location, v0, v1, v2);POSTCALL;}
1646 void wrapglUniform3fv(GLint location, GLsizei count, const GLfloat *value) {PRECALL;glUniform3fv(location, count, value);POSTCALL;}
1647 void wrapglUniform3i(GLint location, GLint v0, GLint v1, GLint v2) {PRECALL;glUniform3i(location, v0, v1, v2);POSTCALL;}
1648 void wrapglUniform3iv(GLint location, GLsizei count, const GLint *value) {PRECALL;glUniform3iv(location, count, value);POSTCALL;}
1649 void wrapglUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {PRECALL;glUniform4f(location, v0, v1, v2, v3);POSTCALL;}
1650 void wrapglUniform4fv(GLint location, GLsizei count, const GLfloat *value) {PRECALL;glUniform4fv(location, count, value);POSTCALL;}
1651 void wrapglUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {PRECALL;glUniform4i(location, v0, v1, v2, v3);POSTCALL;}
1652 void wrapglUniform4iv(GLint location, GLsizei count, const GLint *value) {PRECALL;glUniform4iv(location, count, value);POSTCALL;}
1653 void wrapglUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {PRECALL;glUniformMatrix2fv(location, count, transpose, value);POSTCALL;}
1654 void wrapglUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {PRECALL;glUniformMatrix3fv(location, count, transpose, value);POSTCALL;}
1655 void wrapglUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {PRECALL;glUniformMatrix4fv(location, count, transpose, value);POSTCALL;}
1656 void wrapglUseProgram(GLuint programObj) {PRECALL;glUseProgram(programObj);POSTCALL;}
1657 void wrapglValidateProgram(GLuint programObj) {PRECALL;glValidateProgram(programObj);POSTCALL;}
1658 void wrapglVertex2f(GLfloat x, GLfloat y) {PRECALL;Con_Printf("glVertex2f(x, y)\n");POSTCALL;}
1659 void wrapglVertex3f(GLfloat x, GLfloat y, GLfloat z) {PRECALL;Con_Printf("glVertex3f(x, y, z)\n");POSTCALL;}
1660 void wrapglVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {PRECALL;Con_Printf("glVertex4f(x, y, z, w)\n");POSTCALL;}
1661 void wrapglVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) {PRECALL;glVertexAttribPointer(index, size, type, normalized, stride, pointer);POSTCALL;}
1662 void wrapglVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) {PRECALL;Con_Printf("glVertexPointer(size, type, stride, ptr)\n");POSTCALL;}
1663 void wrapglViewport(GLint x, GLint y, GLsizei width, GLsizei height) {PRECALL;glViewport(x, y, width, height);POSTCALL;}
1664 void wrapglVertexAttrib1f(GLuint index, GLfloat v0) {PRECALL;glVertexAttrib1f(index, v0);POSTCALL;}
1665 //void wrapglVertexAttrib1s(GLuint index, GLshort v0) {PRECALL;glVertexAttrib1s(index, v0);POSTCALL;}
1666 //void wrapglVertexAttrib1d(GLuint index, GLdouble v0) {PRECALL;glVertexAttrib1d(index, v0);POSTCALL;}
1667 void wrapglVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {PRECALL;glVertexAttrib2f(index, v0, v1);POSTCALL;}
1668 //void wrapglVertexAttrib2s(GLuint index, GLshort v0, GLshort v1) {PRECALL;glVertexAttrib2s(index, v0, v1);POSTCALL;}
1669 //void wrapglVertexAttrib2d(GLuint index, GLdouble v0, GLdouble v1) {PRECALL;glVertexAttrib2d(index, v0, v1);POSTCALL;}
1670 void wrapglVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {PRECALL;glVertexAttrib3f(index, v0, v1, v2);POSTCALL;}
1671 //void wrapglVertexAttrib3s(GLuint index, GLshort v0, GLshort v1, GLshort v2) {PRECALL;glVertexAttrib3s(index, v0, v1, v2);POSTCALL;}
1672 //void wrapglVertexAttrib3d(GLuint index, GLdouble v0, GLdouble v1, GLdouble v2) {PRECALL;glVertexAttrib3d(index, v0, v1, v2);POSTCALL;}
1673 void wrapglVertexAttrib4f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {PRECALL;glVertexAttrib4f(index, v0, v1, v2, v3);POSTCALL;}
1674 //void wrapglVertexAttrib4s(GLuint index, GLshort v0, GLshort v1, GLshort v2, GLshort v3) {PRECALL;glVertexAttrib4s(index, v0, v1, v2, v3);POSTCALL;}
1675 //void wrapglVertexAttrib4d(GLuint index, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3) {PRECALL;glVertexAttrib4d(index, v0, v1, v2, v3);POSTCALL;}
1676 //void wrapglVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) {PRECALL;glVertexAttrib4Nub(index, x, y, z, w);POSTCALL;}
1677 void wrapglVertexAttrib1fv(GLuint index, const GLfloat *v) {PRECALL;glVertexAttrib1fv(index, v);POSTCALL;}
1678 //void wrapglVertexAttrib1sv(GLuint index, const GLshort *v) {PRECALL;glVertexAttrib1sv(index, v);POSTCALL;}
1679 //void wrapglVertexAttrib1dv(GLuint index, const GLdouble *v) {PRECALL;glVertexAttrib1dv(index, v);POSTCALL;}
1680 void wrapglVertexAttrib2fv(GLuint index, const GLfloat *v) {PRECALL;glVertexAttrib2fv(index, v);POSTCALL;}
1681 //void wrapglVertexAttrib2sv(GLuint index, const GLshort *v) {PRECALL;glVertexAttrib2sv(index, v);POSTCALL;}
1682 //void wrapglVertexAttrib2dv(GLuint index, const GLdouble *v) {PRECALL;glVertexAttrib2dv(index, v);POSTCALL;}
1683 void wrapglVertexAttrib3fv(GLuint index, const GLfloat *v) {PRECALL;glVertexAttrib3fv(index, v);POSTCALL;}
1684 //void wrapglVertexAttrib3sv(GLuint index, const GLshort *v) {PRECALL;glVertexAttrib3sv(index, v);POSTCALL;}
1685 //void wrapglVertexAttrib3dv(GLuint index, const GLdouble *v) {PRECALL;glVertexAttrib3dv(index, v);POSTCALL;}
1686 void wrapglVertexAttrib4fv(GLuint index, const GLfloat *v) {PRECALL;glVertexAttrib4fv(index, v);POSTCALL;}
1687 //void wrapglVertexAttrib4sv(GLuint index, const GLshort *v) {PRECALL;glVertexAttrib4sv(index, v);POSTCALL;}
1688 //void wrapglVertexAttrib4dv(GLuint index, const GLdouble *v) {PRECALL;glVertexAttrib4dv(index, v);POSTCALL;}
1689 //void wrapglVertexAttrib4iv(GLuint index, const GLint *v) {PRECALL;glVertexAttrib4iv(index, v);POSTCALL;}
1690 //void wrapglVertexAttrib4bv(GLuint index, const GLbyte *v) {PRECALL;glVertexAttrib4bv(index, v);POSTCALL;}
1691 //void wrapglVertexAttrib4ubv(GLuint index, const GLubyte *v) {PRECALL;glVertexAttrib4ubv(index, v);POSTCALL;}
1692 //void wrapglVertexAttrib4usv(GLuint index, const GLushort *v) {PRECALL;glVertexAttrib4usv(index, GLushort v);POSTCALL;}
1693 //void wrapglVertexAttrib4uiv(GLuint index, const GLuint *v) {PRECALL;glVertexAttrib4uiv(index, v);POSTCALL;}
1694 //void wrapglVertexAttrib4Nbv(GLuint index, const GLbyte *v) {PRECALL;glVertexAttrib4Nbv(index, v);POSTCALL;}
1695 //void wrapglVertexAttrib4Nsv(GLuint index, const GLshort *v) {PRECALL;glVertexAttrib4Nsv(index, v);POSTCALL;}
1696 //void wrapglVertexAttrib4Niv(GLuint index, const GLint *v) {PRECALL;glVertexAttrib4Niv(index, v);POSTCALL;}
1697 //void wrapglVertexAttrib4Nubv(GLuint index, const GLubyte *v) {PRECALL;glVertexAttrib4Nubv(index, v);POSTCALL;}
1698 //void wrapglVertexAttrib4Nusv(GLuint index, const GLushort *v) {PRECALL;glVertexAttrib4Nusv(index, GLushort v);POSTCALL;}
1699 //void wrapglVertexAttrib4Nuiv(GLuint index, const GLuint *v) {PRECALL;glVertexAttrib4Nuiv(index, v);POSTCALL;}
1700 //void wrapglGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) {PRECALL;glGetVertexAttribdv(index, pname, params);POSTCALL;}
1701 void wrapglGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params) {PRECALL;glGetVertexAttribfv(index, pname, params);POSTCALL;}
1702 void wrapglGetVertexAttribiv(GLuint index, GLenum pname, GLint *params) {PRECALL;glGetVertexAttribiv(index, pname, params);POSTCALL;}
1703 void wrapglGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer) {PRECALL;glGetVertexAttribPointerv(index, pname, pointer);POSTCALL;}
1706 #if SDL_MAJOR_VERSION == 1
1707 #define SDL_GL_ExtensionSupported(x) (strstr(gl_extensions, x) || strstr(gl_platformextensions, x))
1710 void GLES_Init(void)
1713 qglIsBufferARB = wrapglIsBuffer;
1714 qglIsEnabled = wrapglIsEnabled;
1715 qglIsFramebufferEXT = wrapglIsFramebuffer;
1716 // qglIsQueryARB = wrapglIsQuery;
1717 qglIsRenderbufferEXT = wrapglIsRenderbuffer;
1718 // qglUnmapBufferARB = wrapglUnmapBuffer;
1719 qglCheckFramebufferStatus = wrapglCheckFramebufferStatus;
1720 qglGetError = wrapglGetError;
1721 qglCreateProgram = wrapglCreateProgram;
1722 qglCreateShader = wrapglCreateShader;
1723 // qglGetHandleARB = wrapglGetHandle;
1724 qglGetAttribLocation = wrapglGetAttribLocation;
1725 qglGetUniformLocation = wrapglGetUniformLocation;
1726 // qglMapBufferARB = wrapglMapBuffer;
1727 qglGetString = wrapglGetString;
1728 // qglActiveStencilFaceEXT = wrapglActiveStencilFace;
1729 qglActiveTexture = wrapglActiveTexture;
1730 qglAlphaFunc = wrapglAlphaFunc;
1731 qglArrayElement = wrapglArrayElement;
1732 qglAttachShader = wrapglAttachShader;
1733 // qglBegin = wrapglBegin;
1734 // qglBeginQueryARB = wrapglBeginQuery;
1735 qglBindAttribLocation = wrapglBindAttribLocation;
1736 // qglBindFragDataLocation = wrapglBindFragDataLocation;
1737 qglBindBufferARB = wrapglBindBuffer;
1738 qglBindFramebuffer = wrapglBindFramebuffer;
1739 qglBindRenderbuffer = wrapglBindRenderbuffer;
1740 qglBindTexture = wrapglBindTexture;
1741 qglBlendEquationEXT = wrapglBlendEquation;
1742 qglBlendFunc = wrapglBlendFunc;
1743 qglBufferDataARB = wrapglBufferData;
1744 qglBufferSubDataARB = wrapglBufferSubData;
1745 qglClear = wrapglClear;
1746 qglClearColor = wrapglClearColor;
1747 qglClearDepth = wrapglClearDepth;
1748 qglClearStencil = wrapglClearStencil;
1749 qglClientActiveTexture = wrapglClientActiveTexture;
1750 qglColor4f = wrapglColor4f;
1751 qglColor4ub = wrapglColor4ub;
1752 qglColorMask = wrapglColorMask;
1753 qglColorPointer = wrapglColorPointer;
1754 qglCompileShader = wrapglCompileShader;
1755 qglCompressedTexImage2DARB = wrapglCompressedTexImage2D;
1756 qglCompressedTexImage3DARB = wrapglCompressedTexImage3D;
1757 qglCompressedTexSubImage2DARB = wrapglCompressedTexSubImage2D;
1758 qglCompressedTexSubImage3DARB = wrapglCompressedTexSubImage3D;
1759 qglCopyTexImage2D = wrapglCopyTexImage2D;
1760 qglCopyTexSubImage2D = wrapglCopyTexSubImage2D;
1761 qglCopyTexSubImage3D = wrapglCopyTexSubImage3D;
1762 qglCullFace = wrapglCullFace;
1763 qglDeleteBuffersARB = wrapglDeleteBuffers;
1764 qglDeleteFramebuffers = wrapglDeleteFramebuffers;
1765 qglDeleteProgram = wrapglDeleteProgram;
1766 qglDeleteShader = wrapglDeleteShader;
1767 // qglDeleteQueriesARB = wrapglDeleteQueries;
1768 qglDeleteRenderbuffers = wrapglDeleteRenderbuffers;
1769 qglDeleteTextures = wrapglDeleteTextures;
1770 qglDepthFunc = wrapglDepthFunc;
1771 qglDepthMask = wrapglDepthMask;
1772 qglDepthRangef = wrapglDepthRangef;
1773 qglDetachShader = wrapglDetachShader;
1774 qglDisable = wrapglDisable;
1775 qglDisableClientState = wrapglDisableClientState;
1776 qglDisableVertexAttribArray = wrapglDisableVertexAttribArray;
1777 qglDrawArrays = wrapglDrawArrays;
1778 // qglDrawBuffer = wrapglDrawBuffer;
1779 // qglDrawBuffersARB = wrapglDrawBuffers;
1780 qglDrawElements = wrapglDrawElements;
1781 // qglDrawRangeElements = wrapglDrawRangeElements;
1782 qglEnable = wrapglEnable;
1783 qglEnableClientState = wrapglEnableClientState;
1784 qglEnableVertexAttribArray = wrapglEnableVertexAttribArray;
1785 // qglEnd = wrapglEnd;
1786 // qglEndQueryARB = wrapglEndQuery;
1787 qglFinish = wrapglFinish;
1788 qglFlush = wrapglFlush;
1789 qglFramebufferRenderbufferEXT = wrapglFramebufferRenderbuffer;
1790 qglFramebufferTexture2DEXT = wrapglFramebufferTexture2D;
1791 qglFramebufferTexture3DEXT = wrapglFramebufferTexture3D;
1792 qglGenBuffersARB = wrapglGenBuffers;
1793 qglGenFramebuffers = wrapglGenFramebuffers;
1794 // qglGenQueriesARB = wrapglGenQueries;
1795 qglGenRenderbuffers = wrapglGenRenderbuffers;
1796 qglGenTextures = wrapglGenTextures;
1797 qglGenerateMipmapEXT = wrapglGenerateMipmap;
1798 qglGetActiveAttrib = wrapglGetActiveAttrib;
1799 qglGetActiveUniform = wrapglGetActiveUniform;
1800 qglGetAttachedShaders = wrapglGetAttachedShaders;
1801 qglGetBooleanv = wrapglGetBooleanv;
1802 // qglGetCompressedTexImageARB = wrapglGetCompressedTexImage;
1803 qglGetDoublev = wrapglGetDoublev;
1804 qglGetFloatv = wrapglGetFloatv;
1805 qglGetFramebufferAttachmentParameterivEXT = wrapglGetFramebufferAttachmentParameteriv;
1806 qglGetProgramInfoLog = wrapglGetProgramInfoLog;
1807 qglGetShaderInfoLog = wrapglGetShaderInfoLog;
1808 qglGetIntegerv = wrapglGetIntegerv;
1809 qglGetShaderiv = wrapglGetShaderiv;
1810 qglGetProgramiv = wrapglGetProgramiv;
1811 // qglGetQueryObjectivARB = wrapglGetQueryObjectiv;
1812 // qglGetQueryObjectuivARB = wrapglGetQueryObjectuiv;
1813 // qglGetQueryivARB = wrapglGetQueryiv;
1814 qglGetRenderbufferParameterivEXT = wrapglGetRenderbufferParameteriv;
1815 qglGetShaderSource = wrapglGetShaderSource;
1816 qglGetTexImage = wrapglGetTexImage;
1817 qglGetTexLevelParameterfv = wrapglGetTexLevelParameterfv;
1818 qglGetTexLevelParameteriv = wrapglGetTexLevelParameteriv;
1819 qglGetTexParameterfv = wrapglGetTexParameterfv;
1820 qglGetTexParameteriv = wrapglGetTexParameteriv;
1821 qglGetUniformfv = wrapglGetUniformfv;
1822 qglGetUniformiv = wrapglGetUniformiv;
1823 qglHint = wrapglHint;
1824 qglLineWidth = wrapglLineWidth;
1825 qglLinkProgram = wrapglLinkProgram;
1826 qglLoadIdentity = wrapglLoadIdentity;
1827 qglLoadMatrixf = wrapglLoadMatrixf;
1828 qglMatrixMode = wrapglMatrixMode;
1829 qglMultiTexCoord1f = wrapglMultiTexCoord1f;
1830 qglMultiTexCoord2f = wrapglMultiTexCoord2f;
1831 qglMultiTexCoord3f = wrapglMultiTexCoord3f;
1832 qglMultiTexCoord4f = wrapglMultiTexCoord4f;
1833 qglNormalPointer = wrapglNormalPointer;
1834 qglPixelStorei = wrapglPixelStorei;
1835 qglPointSize = wrapglPointSize;
1836 // qglPolygonMode = wrapglPolygonMode;
1837 qglPolygonOffset = wrapglPolygonOffset;
1838 // qglPolygonStipple = wrapglPolygonStipple;
1839 qglReadBuffer = wrapglReadBuffer;
1840 qglReadPixels = wrapglReadPixels;
1841 qglRenderbufferStorage = wrapglRenderbufferStorage;
1842 qglScissor = wrapglScissor;
1843 qglShaderSource = wrapglShaderSource;
1844 qglStencilFunc = wrapglStencilFunc;
1845 qglStencilFuncSeparate = wrapglStencilFuncSeparate;
1846 qglStencilMask = wrapglStencilMask;
1847 qglStencilOp = wrapglStencilOp;
1848 qglStencilOpSeparate = wrapglStencilOpSeparate;
1849 qglTexCoord1f = wrapglTexCoord1f;
1850 qglTexCoord2f = wrapglTexCoord2f;
1851 qglTexCoord3f = wrapglTexCoord3f;
1852 qglTexCoord4f = wrapglTexCoord4f;
1853 qglTexCoordPointer = wrapglTexCoordPointer;
1854 qglTexEnvf = wrapglTexEnvf;
1855 qglTexEnvfv = wrapglTexEnvfv;
1856 qglTexEnvi = wrapglTexEnvi;
1857 qglTexImage2D = wrapglTexImage2D;
1858 qglTexImage3D = wrapglTexImage3D;
1859 qglTexParameterf = wrapglTexParameterf;
1860 qglTexParameterfv = wrapglTexParameterfv;
1861 qglTexParameteri = wrapglTexParameteri;
1862 qglTexSubImage2D = wrapglTexSubImage2D;
1863 qglTexSubImage3D = wrapglTexSubImage3D;
1864 qglUniform1f = wrapglUniform1f;
1865 qglUniform1fv = wrapglUniform1fv;
1866 qglUniform1i = wrapglUniform1i;
1867 qglUniform1iv = wrapglUniform1iv;
1868 qglUniform2f = wrapglUniform2f;
1869 qglUniform2fv = wrapglUniform2fv;
1870 qglUniform2i = wrapglUniform2i;
1871 qglUniform2iv = wrapglUniform2iv;
1872 qglUniform3f = wrapglUniform3f;
1873 qglUniform3fv = wrapglUniform3fv;
1874 qglUniform3i = wrapglUniform3i;
1875 qglUniform3iv = wrapglUniform3iv;
1876 qglUniform4f = wrapglUniform4f;
1877 qglUniform4fv = wrapglUniform4fv;
1878 qglUniform4i = wrapglUniform4i;
1879 qglUniform4iv = wrapglUniform4iv;
1880 qglUniformMatrix2fv = wrapglUniformMatrix2fv;
1881 qglUniformMatrix3fv = wrapglUniformMatrix3fv;
1882 qglUniformMatrix4fv = wrapglUniformMatrix4fv;
1883 qglUseProgram = wrapglUseProgram;
1884 qglValidateProgram = wrapglValidateProgram;
1885 qglVertex2f = wrapglVertex2f;
1886 qglVertex3f = wrapglVertex3f;
1887 qglVertex4f = wrapglVertex4f;
1888 qglVertexAttribPointer = wrapglVertexAttribPointer;
1889 qglVertexPointer = wrapglVertexPointer;
1890 qglViewport = wrapglViewport;
1891 qglVertexAttrib1f = wrapglVertexAttrib1f;
1892 // qglVertexAttrib1s = wrapglVertexAttrib1s;
1893 // qglVertexAttrib1d = wrapglVertexAttrib1d;
1894 qglVertexAttrib2f = wrapglVertexAttrib2f;
1895 // qglVertexAttrib2s = wrapglVertexAttrib2s;
1896 // qglVertexAttrib2d = wrapglVertexAttrib2d;
1897 qglVertexAttrib3f = wrapglVertexAttrib3f;
1898 // qglVertexAttrib3s = wrapglVertexAttrib3s;
1899 // qglVertexAttrib3d = wrapglVertexAttrib3d;
1900 qglVertexAttrib4f = wrapglVertexAttrib4f;
1901 // qglVertexAttrib4s = wrapglVertexAttrib4s;
1902 // qglVertexAttrib4d = wrapglVertexAttrib4d;
1903 // qglVertexAttrib4Nub = wrapglVertexAttrib4Nub;
1904 qglVertexAttrib1fv = wrapglVertexAttrib1fv;
1905 // qglVertexAttrib1sv = wrapglVertexAttrib1sv;
1906 // qglVertexAttrib1dv = wrapglVertexAttrib1dv;
1907 qglVertexAttrib2fv = wrapglVertexAttrib2fv;
1908 // qglVertexAttrib2sv = wrapglVertexAttrib2sv;
1909 // qglVertexAttrib2dv = wrapglVertexAttrib2dv;
1910 qglVertexAttrib3fv = wrapglVertexAttrib3fv;
1911 // qglVertexAttrib3sv = wrapglVertexAttrib3sv;
1912 // qglVertexAttrib3dv = wrapglVertexAttrib3dv;
1913 qglVertexAttrib4fv = wrapglVertexAttrib4fv;
1914 // qglVertexAttrib4sv = wrapglVertexAttrib4sv;
1915 // qglVertexAttrib4dv = wrapglVertexAttrib4dv;
1916 // qglVertexAttrib4iv = wrapglVertexAttrib4iv;
1917 // qglVertexAttrib4bv = wrapglVertexAttrib4bv;
1918 // qglVertexAttrib4ubv = wrapglVertexAttrib4ubv;
1919 // qglVertexAttrib4usv = wrapglVertexAttrib4usv;
1920 // qglVertexAttrib4uiv = wrapglVertexAttrib4uiv;
1921 // qglVertexAttrib4Nbv = wrapglVertexAttrib4Nbv;
1922 // qglVertexAttrib4Nsv = wrapglVertexAttrib4Nsv;
1923 // qglVertexAttrib4Niv = wrapglVertexAttrib4Niv;
1924 // qglVertexAttrib4Nubv = wrapglVertexAttrib4Nubv;
1925 // qglVertexAttrib4Nusv = wrapglVertexAttrib4Nusv;
1926 // qglVertexAttrib4Nuiv = wrapglVertexAttrib4Nuiv;
1927 // qglGetVertexAttribdv = wrapglGetVertexAttribdv;
1928 qglGetVertexAttribfv = wrapglGetVertexAttribfv;
1929 qglGetVertexAttribiv = wrapglGetVertexAttribiv;
1930 qglGetVertexAttribPointerv = wrapglGetVertexAttribPointerv;
1933 gl_renderer = (const char *)qglGetString(GL_RENDERER);
1934 gl_vendor = (const char *)qglGetString(GL_VENDOR);
1935 gl_version = (const char *)qglGetString(GL_VERSION);
1936 gl_extensions = (const char *)qglGetString(GL_EXTENSIONS);
1940 if (!gl_platformextensions)
1941 gl_platformextensions = "";
1943 Con_Printf("GL_VENDOR: %s\n", gl_vendor);
1944 Con_Printf("GL_RENDERER: %s\n", gl_renderer);
1945 Con_Printf("GL_VERSION: %s\n", gl_version);
1946 Con_DPrintf("GL_EXTENSIONS: %s\n", gl_extensions);
1947 Con_DPrintf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions);
1949 // LordHavoc: report supported extensions
1950 Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions );
1952 // GLES devices in general do not like GL_BGRA, so use GL_RGBA
1953 vid.forcetextype = TEXTYPE_RGBA;
1955 vid.support.gl20shaders = true;
1956 vid.support.amd_texture_texture4 = false;
1957 vid.support.arb_depth_texture = SDL_GL_ExtensionSupported("GL_OES_depth_texture") != 0; // renderbuffer used anyway on gles2?
1958 vid.support.arb_draw_buffers = false;
1959 vid.support.arb_multitexture = false;
1960 vid.support.arb_occlusion_query = false;
1961 vid.support.arb_query_buffer_object = false;
1962 vid.support.arb_shadow = false;
1963 vid.support.arb_texture_compression = false; // different (vendor-specific) formats than on desktop OpenGL...
1964 vid.support.arb_texture_cube_map = SDL_GL_ExtensionSupported("GL_OES_texture_cube_map") != 0;
1965 vid.support.arb_texture_env_combine = false;
1966 vid.support.arb_texture_gather = false;
1967 vid.support.arb_texture_non_power_of_two = strstr(gl_extensions, "GL_OES_texture_npot") != NULL;
1968 vid.support.arb_vertex_buffer_object = true; // GLES2 core
1969 vid.support.ati_separate_stencil = false;
1970 vid.support.ext_blend_minmax = false;
1971 vid.support.ext_blend_subtract = true; // GLES2 core
1972 vid.support.ext_blend_func_separate = true; // GLES2 core
1973 vid.support.ext_draw_range_elements = false;
1976 Note: "In OS 2.1, the functions in GL_OES_framebuffer_object were not usable from the Java API.
1977 Calling them just threw an exception. Android developer relations confirmed that they forgot to implement these. (yeah...)
1978 It's apparently been fixed in 2.2, though I haven't tested."
1980 // LadyHavoc: Android 2.1 is way old now, enabling this again, it's going to be required soon.
1981 vid.support.ext_framebuffer_object = true;
1983 vid.support.ext_packed_depth_stencil = false;
1984 vid.support.ext_stencil_two_side = false;
1985 vid.support.ext_texture_3d = SDL_GL_ExtensionSupported("GL_OES_texture_3D") != 0;
1986 vid.support.ext_texture_compression_s3tc = SDL_GL_ExtensionSupported("GL_EXT_texture_compression_s3tc") != 0;
1987 vid.support.ext_texture_edge_clamp = true; // GLES2 core
1988 vid.support.ext_texture_filter_anisotropic = false; // probably don't want to use it...
1989 vid.support.ext_texture_srgb = false;
1990 vid.support.arb_texture_float = SDL_GL_ExtensionSupported("GL_OES_texture_float") != 0;
1991 vid.support.arb_half_float_pixel = SDL_GL_ExtensionSupported("GL_OES_texture_half_float") != 0;
1992 vid.support.arb_half_float_vertex = SDL_GL_ExtensionSupported("GL_OES_vertex_half_float") != 0;
1994 // NOTE: On some devices, a value of 512 gives better FPS than the maximum.
1995 qglGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_2d);
1997 #ifdef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
1998 if (vid.support.ext_texture_filter_anisotropic)
1999 qglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, (GLint*)&vid.max_anisotropy);
2001 if (vid.support.arb_texture_cube_map)
2002 qglGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_cubemap);
2003 #ifdef GL_MAX_3D_TEXTURE_SIZE
2004 if (vid.support.ext_texture_3d)
2005 qglGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_3d);
2007 Con_Printf("GL_MAX_CUBE_MAP_TEXTURE_SIZE = %i\n", vid.maxtexturesize_cubemap);
2008 Con_Printf("GL_MAX_3D_TEXTURE_SIZE = %i\n", vid.maxtexturesize_3d);
2010 #define GL_ALPHA_BITS 0x0D55
2011 #define GL_RED_BITS 0x0D52
2012 #define GL_GREEN_BITS 0x0D53
2013 #define GL_BLUE_BITS 0x0D54
2014 #define GL_DEPTH_BITS 0x0D56
2015 #define GL_STENCIL_BITS 0x0D57
2016 int fb_r = -1, fb_g = -1, fb_b = -1, fb_a = -1, fb_d = -1, fb_s = -1;
2017 qglGetIntegerv(GL_RED_BITS , &fb_r);
2018 qglGetIntegerv(GL_GREEN_BITS , &fb_g);
2019 qglGetIntegerv(GL_BLUE_BITS , &fb_b);
2020 qglGetIntegerv(GL_ALPHA_BITS , &fb_a);
2021 qglGetIntegerv(GL_DEPTH_BITS , &fb_d);
2022 qglGetIntegerv(GL_STENCIL_BITS, &fb_s);
2023 Con_Printf("Framebuffer depth is R%iG%iB%iA%iD%iS%i\n", fb_r, fb_g, fb_b, fb_a, fb_d, fb_s);
2026 // verify that cubemap textures are really supported
2027 if (vid.support.arb_texture_cube_map && vid.maxtexturesize_cubemap < 256)
2028 vid.support.arb_texture_cube_map = false;
2030 // verify that 3d textures are really supported
2031 if (vid.support.ext_texture_3d && vid.maxtexturesize_3d < 32)
2033 vid.support.ext_texture_3d = false;
2034 Con_Printf("GL_OES_texture_3d reported bogus GL_MAX_3D_TEXTURE_SIZE, disabled\n");
2038 vid.teximageunits = 8;
2039 vid.texarrayunits = 5;
2040 //qglGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&vid.texunits);
2041 qglGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, (GLint*)&vid.teximageunits);CHECKGLERROR
2042 //qglGetIntegerv(GL_MAX_TEXTURE_COORDS, (GLint*)&vid.texarrayunits);CHECKGLERROR
2043 vid.texunits = bound(1, vid.texunits, MAX_TEXTUREUNITS);
2044 vid.teximageunits = bound(1, vid.teximageunits, MAX_TEXTUREUNITS);
2045 vid.texarrayunits = bound(1, vid.texarrayunits, MAX_TEXTUREUNITS);
2046 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" : "");
2047 vid.renderpath = RENDERPATH_GLES2;
2048 vid.useinterleavedarrays = false;
2049 vid.sRGBcapable2D = false;
2050 vid.sRGBcapable3D = false;
2052 // VorteX: set other info (maybe place them in VID_InitMode?)
2053 extern cvar_t gl_info_vendor;
2054 extern cvar_t gl_info_renderer;
2055 extern cvar_t gl_info_version;
2056 extern cvar_t gl_info_platform;
2057 extern cvar_t gl_info_driver;
2058 Cvar_SetQuick(&gl_info_vendor, gl_vendor);
2059 Cvar_SetQuick(&gl_info_renderer, gl_renderer);
2060 Cvar_SetQuick(&gl_info_version, gl_version);
2061 Cvar_SetQuick(&gl_info_platform, gl_platform ? gl_platform : "");
2062 Cvar_SetQuick(&gl_info_driver, gl_driver);
2066 void *GL_GetProcAddress(const char *name)
2069 p = SDL_GL_GetProcAddress(name);
2073 static qboolean vid_sdl_initjoysticksystem = false;
2075 void VID_Init (void)
2077 #ifndef __IPHONEOS__
2079 Cvar_RegisterVariable(&apple_mouse_noaccel);
2082 #ifdef DP_MOBILETOUCH
2083 Cvar_SetValueQuick(&vid_touchscreen, 1);
2086 #ifdef SDL_R_RESTART
2087 R_RegisterModule("SDL", sdl_start, sdl_shutdown, sdl_newmap, NULL, NULL);
2090 if (SDL_Init(SDL_INIT_VIDEO) < 0)
2091 Sys_Error ("Failed to init SDL video subsystem: %s", SDL_GetError());
2092 vid_sdl_initjoysticksystem = SDL_InitSubSystem(SDL_INIT_JOYSTICK) >= 0;
2093 if (vid_sdl_initjoysticksystem)
2094 Con_Printf("Failed to init SDL joystick subsystem: %s\n", SDL_GetError());
2095 vid_isfullscreen = false;
2098 static int vid_sdljoystickindex = -1;
2099 void VID_EnableJoystick(qboolean enable)
2101 int index = joy_enable.integer > 0 ? joy_index.integer : -1;
2102 int numsdljoysticks;
2103 qboolean success = false;
2104 int sharedcount = 0;
2106 sharedcount = VID_Shared_SetJoystick(index);
2107 if (index >= 0 && index < sharedcount)
2109 sdlindex = index - sharedcount;
2111 numsdljoysticks = SDL_NumJoysticks();
2112 if (sdlindex < 0 || sdlindex >= numsdljoysticks)
2115 // update cvar containing count of XInput joysticks + SDL joysticks
2116 if (joy_detected.integer != sharedcount + numsdljoysticks)
2117 Cvar_SetValueQuick(&joy_detected, sharedcount + numsdljoysticks);
2119 if (vid_sdljoystickindex != sdlindex)
2121 vid_sdljoystickindex = sdlindex;
2122 // close SDL joystick if active
2123 if (vid_sdljoystick)
2124 SDL_JoystickClose(vid_sdljoystick);
2125 vid_sdljoystick = NULL;
2128 vid_sdljoystick = SDL_JoystickOpen(sdlindex);
2129 if (vid_sdljoystick)
2131 #if SDL_MAJOR_VERSION == 1
2132 const char *joystickname = SDL_JoystickName(sdlindex);
2134 const char *joystickname = SDL_JoystickName(vid_sdljoystick);
2136 Con_Printf("Joystick %i opened (SDL_Joystick %i is \"%s\" with %i axes, %i buttons, %i balls)\n", index, sdlindex, joystickname, (int)SDL_JoystickNumAxes(vid_sdljoystick), (int)SDL_JoystickNumButtons(vid_sdljoystick), (int)SDL_JoystickNumBalls(vid_sdljoystick));
2140 Con_Printf("Joystick %i failed (SDL_JoystickOpen(%i) returned: %s)\n", index, sdlindex, SDL_GetError());
2149 if (joy_active.integer != (success ? 1 : 0))
2150 Cvar_SetValueQuick(&joy_active, success ? 1 : 0);
2153 #if SDL_MAJOR_VERSION == 1
2154 // set the icon (we dont use SDL here since it would be too much a PITA)
2156 #include "resource.h"
2157 #include <SDL_syswm.h>
2158 static SDL_Surface *VID_WrapSDL_SetVideoMode(int screenwidth, int screenheight, int screenbpp, int screenflags)
2160 SDL_Surface *screen = NULL;
2163 SDL_WM_SetCaption( gamename, NULL );
2164 screen = SDL_SetVideoMode(screenwidth, screenheight, screenbpp, screenflags);
2167 // get the HWND handle
2168 SDL_VERSION( &info.version );
2169 if (SDL_GetWMInfo(&info))
2171 icon = LoadIcon( GetModuleHandle( NULL ), MAKEINTRESOURCE( IDI_ICON1 ) );
2172 #ifndef _W64 //If Windows 64bit data types don't exist
2173 #ifndef SetClassLongPtr
2174 #define SetClassLongPtr SetClassLong
2177 #define GCLP_HICON GCL_HICON
2180 #define LONG_PTR LONG
2183 SetClassLongPtr( info.window, GCLP_HICON, (LONG_PTR)icon );
2188 #elif defined(MACOSX)
2189 static SDL_Surface *VID_WrapSDL_SetVideoMode(int screenwidth, int screenheight, int screenbpp, int screenflags)
2191 SDL_Surface *screen = NULL;
2192 SDL_WM_SetCaption( gamename, NULL );
2193 screen = SDL_SetVideoMode(screenwidth, screenheight, screenbpp, screenflags);
2194 // we don't use SDL_WM_SetIcon here because the icon in the .app should be used
2198 // Adding the OS independent XPM version --blub
2199 #include "darkplaces.xpm"
2200 #include "nexuiz.xpm"
2201 #if SDL_MAJOR_VERSION == 1
2202 #if SDL_VIDEO_DRIVER_X11 && !SDL_VIDEO_DRIVER_QUARTZ
2203 #include <SDL_syswm.h>
2206 static SDL_Surface *icon = NULL;
2207 static SDL_Surface *VID_WrapSDL_SetVideoMode(int screenwidth, int screenheight, int screenbpp, int screenflags)
2210 * Somewhat restricted XPM reader. Only supports XPMs saved by GIMP 2.4 at
2211 * default settings with less than 91 colors and transparency.
2214 int width, height, colors, isize, i, j;
2216 static SDL_Color palette[256];
2217 unsigned short palenc[256]; // store color id by char
2219 char **idata, *data;
2220 const SDL_version *version;
2221 SDL_Surface *screen = NULL;
2224 SDL_FreeSurface(icon);
2226 version = SDL_Linked_Version();
2227 // only use non-XPM icon support in SDL v1.3 and higher
2228 // SDL v1.2 does not support "smooth" transparency, and thus is better
2230 if(version->major >= 2 || (version->major == 1 && version->minor >= 3))
2232 data = (char *) loadimagepixelsbgra("darkplaces-icon", false, false, false, NULL);
2235 unsigned int red = 0x00FF0000;
2236 unsigned int green = 0x0000FF00;
2237 unsigned int blue = 0x000000FF;
2238 unsigned int alpha = 0xFF000000;
2239 width = image_width;
2240 height = image_height;
2242 // reallocate with malloc, as this is in tempmempool (do not want)
2244 data = (char *) malloc(width * height * 4);
2245 memcpy(data, xpm, width * height * 4);
2249 icon = SDL_CreateRGBSurface(SDL_SRCALPHA, width, height, 32, LittleLong(red), LittleLong(green), LittleLong(blue), LittleLong(alpha));
2252 icon->pixels = data;
2255 Con_Printf( "Failed to create surface for the window Icon!\n"
2256 "%s\n", SDL_GetError());
2262 // we only get here if non-XPM icon was missing, or SDL version is not
2263 // sufficient for transparent non-XPM icons
2266 xpm = (char *) FS_LoadFile("darkplaces-icon.xpm", tempmempool, false, NULL);
2269 idata = XPM_DecodeString(xpm);
2271 idata = ENGINE_ICON;
2277 if(sscanf(data, "%i %i %i %i", &width, &height, &colors, &isize) == 4)
2281 for(i = 0; i < colors; ++i)
2283 unsigned int r, g, b;
2286 if(sscanf(idata[i+1], "%c c #%02x%02x%02x", &idx, &r, &g, &b) != 4)
2289 if(sscanf(idata[i+1], "%c c Non%1[e]", &idx, foo) != 2) // I take the DailyWTF credit for this. --div0
2293 palette[i].r = 255; // color key
2296 thenone = i; // weeeee
2297 palenc[(unsigned char) idx] = i;
2302 palette[i].r = r - (r == 255 && g == 0 && b == 255); // change 255/0/255 pink to 254/0/255 for color key
2305 palenc[(unsigned char) idx] = i;
2311 // allocate the image data
2312 data = (char*) malloc(width*height);
2314 for(j = 0; j < height; ++j)
2316 for(i = 0; i < width; ++i)
2318 // casting to the safest possible datatypes ^^
2319 data[j * width + i] = palenc[((unsigned char*)idata[colors+j+1])[i]];
2325 // SDL_FreeSurface should free the data too
2326 // but for completeness' sake...
2327 if(icon->flags & SDL_PREALLOC)
2330 icon->pixels = NULL; // safety
2332 SDL_FreeSurface(icon);
2335 icon = SDL_CreateRGBSurface(SDL_SRCCOLORKEY, width, height, 8, 0,0,0,0);// rmask, gmask, bmask, amask); no mask needed
2336 // 8 bit surfaces get an empty palette allocated according to the docs
2337 // so it's a palette image for sure :) no endian check necessary for the mask
2341 icon->pixels = data;
2342 SDL_SetPalette(icon, SDL_PHYSPAL|SDL_LOGPAL, palette, 0, colors);
2343 SDL_SetColorKey(icon, SDL_SRCCOLORKEY, thenone);
2347 Con_Printf( "Failed to create surface for the window Icon!\n"
2348 "%s\n", SDL_GetError());
2354 Con_Printf("This XPM's palette looks odd. Can't continue.\n");
2359 // NOTE: Only 1-char colornames are supported
2360 Con_Printf("This XPM's palette is either huge or idiotically unoptimized. It's key size is %i\n", isize);
2365 // NOTE: Only 1-char colornames are supported
2366 Con_Printf("Sorry, but this does not even look similar to an XPM.\n");
2371 SDL_WM_SetIcon(icon, NULL);
2373 SDL_WM_SetCaption( gamename, NULL );
2374 screen = SDL_SetVideoMode(screenwidth, screenheight, screenbpp, screenflags);
2376 #if SDL_MAJOR_VERSION == 1
2377 // LordHavoc: info.info.x11.lock_func and accompanying code do not seem to compile with SDL 1.3
2378 #if SDL_VIDEO_DRIVER_X11 && !SDL_VIDEO_DRIVER_QUARTZ
2380 version = SDL_Linked_Version();
2381 // only use non-XPM icon support in SDL v1.3 and higher
2382 // SDL v1.2 does not support "smooth" transparency, and thus is better
2384 if(screen && (!(version->major >= 2 || (version->major == 1 && version->minor >= 3))))
2386 // in this case, we did not set the good icon yet
2388 SDL_VERSION(&info.version);
2389 if(SDL_GetWMInfo(&info) == 1 && info.subsystem == SDL_SYSWM_X11)
2391 data = (char *) loadimagepixelsbgra("darkplaces-icon", false, false, false, NULL);
2394 // use _NET_WM_ICON too
2395 static long netwm_icon[MAX_NETWM_ICON];
2402 if(pos + 2 * image_width * image_height < MAX_NETWM_ICON)
2404 netwm_icon[pos++] = image_width;
2405 netwm_icon[pos++] = image_height;
2406 for(i = 0; i < image_height; ++i)
2407 for(j = 0; j < image_width; ++j)
2408 netwm_icon[pos++] = BuffLittleLong((unsigned char *) &data[(i*image_width+j)*4]);
2412 Con_Printf("Skipping NETWM icon #%d because there is no space left\n", i);
2416 data = (char *) loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "darkplaces-icon%d", i), false, false, false, NULL);
2419 info.info.x11.lock_func();
2421 Atom net_wm_icon = XInternAtom(info.info.x11.display, "_NET_WM_ICON", false);
2422 XChangeProperty(info.info.x11.display, info.info.x11.wmwindow, net_wm_icon, XA_CARDINAL, 32, PropModeReplace, (const unsigned char *) netwm_icon, pos);
2424 info.info.x11.unlock_func();
2436 static void VID_OutputVersion(void)
2438 SDL_version version;
2439 #if SDL_MAJOR_VERSION == 1
2440 version = *SDL_Linked_Version();
2442 SDL_GetVersion(&version);
2444 Con_Printf( "Linked against SDL version %d.%d.%d\n"
2445 "Using SDL library version %d.%d.%d\n",
2446 SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL,
2447 version.major, version.minor, version.patch );
2451 static void AdjustWindowBounds(viddef_mode_t *mode, RECT *rect)
2453 LONG width = mode->width; // vid_width
2454 LONG height = mode->height; // vid_height
2456 // adjust width and height for the space occupied by window decorators (title bar, borders)
2459 rect->right = width;
2460 rect->bottom = height;
2461 AdjustWindowRectEx(rect, WS_CAPTION|WS_THICKFRAME, false, 0);
2464 SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0);
2465 int workWidth = workArea.right - workArea.left;
2466 int workHeight = workArea.bottom - workArea.top;
2468 // SDL forces the window height to be <= screen height - 27px (on Win8.1 - probably intended for the title bar)
2469 // If the task bar is docked to the the left screen border and we move the window to negative y,
2470 // there would be some part of the regular desktop visible on the bottom of the screen.
2471 int titleBarPixels = 2;
2472 int screenHeight = GetSystemMetrics(SM_CYSCREEN);
2473 if (screenHeight == workHeight)
2474 titleBarPixels = -rect->top;
2476 //Con_Printf("window mode: %dx%d, workArea: %d/%d-%d/%d (%dx%d), title: %d\n", width, height, workArea.left, workArea.top, workArea.right, workArea.bottom, workArea.right - workArea.left, workArea.bottom - workArea.top, titleBarPixels);
2478 // if height and width matches the physical or previously adjusted screen height and width, adjust it to available desktop area
2479 if ((width == GetSystemMetrics(SM_CXSCREEN) || width == workWidth) && (height == screenHeight || height == workHeight - titleBarPixels))
2481 rect->left = workArea.left;
2482 mode->width = workWidth;
2483 rect->top = workArea.top + titleBarPixels;
2484 mode->height = workHeight - titleBarPixels;
2488 rect->left = workArea.left + max(0, (workWidth - width) / 2);
2489 rect->top = workArea.top + max(0, (workHeight - height) / 2);
2494 static qboolean VID_InitModeGL(viddef_mode_t *mode)
2496 #if SDL_MAJOR_VERSION == 1
2497 static int notfirstvideomode = false;
2498 int flags = SDL_OPENGL;
2500 int windowflags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL;
2501 int xPos = SDL_WINDOWPOS_UNDEFINED;
2502 int yPos = SDL_WINDOWPOS_UNDEFINED;
2506 const char *drivername;
2509 win_half_width = mode->width>>1;
2510 win_half_height = mode->height>>1;
2512 if(vid_resizable.integer)
2513 #if SDL_MAJOR_VERSION == 1
2514 flags |= SDL_RESIZABLE;
2516 windowflags |= SDL_WINDOW_RESIZABLE;
2519 VID_OutputVersion();
2521 #if SDL_MAJOR_VERSION == 1
2524 We cant switch from one OpenGL video mode to another.
2525 Thus we first switch to some stupid 2D mode and then back to OpenGL.
2527 if (notfirstvideomode)
2528 SDL_SetVideoMode( 0, 0, 0, 0 );
2529 notfirstvideomode = true;
2533 // SDL usually knows best
2536 // 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
2537 i = COM_CheckParm("-gl_driver");
2538 if (i && i < com_argc - 1)
2539 drivername = com_argv[i + 1];
2540 if (SDL_GL_LoadLibrary(drivername) < 0)
2542 Con_Printf("Unable to load GL driver \"%s\": %s\n", drivername, SDL_GetError());
2547 #ifdef DP_MOBILETOUCH
2548 // mobile platforms are always fullscreen, we'll get the resolution after opening the window
2549 mode->fullscreen = true;
2550 // hide the menu with SDL_WINDOW_BORDERLESS
2551 windowflags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS;
2554 if ((qglGetString = (const GLubyte* (GLAPIENTRY *)(GLenum name))GL_GetProcAddress("glGetString")) == NULL)
2557 Con_Print("Required OpenGL function glGetString not found\n");
2562 // Knghtbrd: should do platform-specific extension string function here
2564 vid_isfullscreen = false;
2565 #if SDL_MAJOR_VERSION == 1
2567 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2568 desktop_mode.width = vi->current_w;
2569 desktop_mode.height = vi->current_h;
2570 desktop_mode.bpp = vi->vfmt->BitsPerPixel;
2571 desktop_mode.pixelheight_num = 1;
2572 desktop_mode.pixelheight_denom = 1; // SDL does not provide this
2573 if (mode->fullscreen) {
2574 if (vid_desktopfullscreen.integer)
2576 mode->width = vi->current_w;
2577 mode->height = vi->current_h;
2578 mode->bitsperpixel = vi->vfmt->BitsPerPixel;
2580 flags |= SDL_FULLSCREEN;
2581 vid_isfullscreen = true;
2586 if (mode->fullscreen) {
2587 if (vid_desktopfullscreen.integer)
2589 vid_mode_t *m = VID_GetDesktopMode();
2590 mode->width = m->width;
2591 mode->height = m->height;
2592 windowflags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
2595 windowflags |= SDL_WINDOW_FULLSCREEN;
2596 vid_isfullscreen = true;
2601 AdjustWindowBounds(mode, &rect);
2608 //flags |= SDL_HWSURFACE;
2610 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
2611 if (mode->bitsperpixel >= 32)
2613 SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 8);
2614 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 8);
2615 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 8);
2616 SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, 8);
2617 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 24);
2618 SDL_GL_SetAttribute (SDL_GL_STENCIL_SIZE, 8);
2622 SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5);
2623 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5);
2624 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5);
2625 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 16);
2627 if (mode->stereobuffer)
2628 SDL_GL_SetAttribute (SDL_GL_STEREO, 1);
2629 if (mode->samples > 1)
2631 SDL_GL_SetAttribute (SDL_GL_MULTISAMPLEBUFFERS, 1);
2632 SDL_GL_SetAttribute (SDL_GL_MULTISAMPLESAMPLES, mode->samples);
2635 #if SDL_MAJOR_VERSION == 1
2636 if (vid_vsync.integer)
2637 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1);
2639 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 0);
2642 SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
2643 SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0);
2644 SDL_GL_SetAttribute (SDL_GL_RETAINED_BACKING, 1);
2648 video_bpp = mode->bitsperpixel;
2649 #if SDL_MAJOR_VERSION == 1
2650 video_flags = flags;
2651 video_screen = VID_WrapSDL_SetVideoMode(mode->width, mode->height, mode->bitsperpixel, flags);
2652 if (video_screen == NULL)
2654 Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError());
2658 mode->width = video_screen->w;
2659 mode->height = video_screen->h;
2661 window_flags = windowflags;
2662 window = SDL_CreateWindow(gamename, xPos, yPos, mode->width, mode->height, windowflags);
2665 Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError());
2669 SDL_GetWindowSize(window, &mode->width, &mode->height);
2670 context = SDL_GL_CreateContext(window);
2671 if (context == NULL)
2673 Con_Printf("Failed to initialize OpenGL context: %s\n", SDL_GetError());
2679 vid_softsurface = NULL;
2680 vid.softpixels = NULL;
2682 #if SDL_MAJOR_VERSION == 1
2684 SDL_EnableUNICODE( SDL_ENABLE );
2685 // enable key repeat since everyone expects it
2686 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
2689 #if SDL_MAJOR_VERSION != 1
2690 SDL_GL_SetSwapInterval(vid_vsync.integer != 0);
2691 vid_usingvsync = (vid_vsync.integer != 0);
2694 gl_platform = "SDL";
2695 gl_platformextensions = "";
2704 vid_activewindow = false;
2705 vid_hasfocus = true;
2706 vid_usingmouse = false;
2707 vid_usinghidecursor = false;
2709 #if SDL_MAJOR_VERSION == 1
2710 SDL_WM_GrabInput(SDL_GRAB_OFF);
2715 extern cvar_t gl_info_extensions;
2716 extern cvar_t gl_info_vendor;
2717 extern cvar_t gl_info_renderer;
2718 extern cvar_t gl_info_version;
2719 extern cvar_t gl_info_platform;
2720 extern cvar_t gl_info_driver;
2722 static qboolean VID_InitModeSoft(viddef_mode_t *mode)
2724 #if SDL_MAJOR_VERSION == 1
2725 int flags = SDL_HWSURFACE;
2726 if(!COM_CheckParm("-noasyncblit")) flags |= SDL_ASYNCBLIT;
2728 int windowflags = SDL_WINDOW_SHOWN;
2731 win_half_width = mode->width>>1;
2732 win_half_height = mode->height>>1;
2734 if(vid_resizable.integer)
2735 #if SDL_MAJOR_VERSION == 1
2736 flags |= SDL_RESIZABLE;
2738 windowflags |= SDL_WINDOW_RESIZABLE;
2741 VID_OutputVersion();
2743 vid_isfullscreen = false;
2744 if (mode->fullscreen) {
2745 #if SDL_MAJOR_VERSION == 1
2746 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2747 mode->width = vi->current_w;
2748 mode->height = vi->current_h;
2749 mode->bitsperpixel = vi->vfmt->BitsPerPixel;
2750 flags |= SDL_FULLSCREEN;
2752 if (vid_desktopfullscreen.integer)
2753 windowflags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
2755 windowflags |= SDL_WINDOW_FULLSCREEN;
2757 vid_isfullscreen = true;
2760 video_bpp = mode->bitsperpixel;
2761 #if SDL_MAJOR_VERSION == 1
2762 video_flags = flags;
2763 video_screen = VID_WrapSDL_SetVideoMode(mode->width, mode->height, mode->bitsperpixel, flags);
2764 if (video_screen == NULL)
2766 Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError());
2770 mode->width = video_screen->w;
2771 mode->height = video_screen->h;
2773 window_flags = windowflags;
2774 window = SDL_CreateWindow(gamename, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, mode->width, mode->height, windowflags);
2777 Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError());
2781 SDL_GetWindowSize(window, &mode->width, &mode->height);
2784 // create a framebuffer using our specific color format, we let the SDL blit function convert it in VID_Finish
2785 vid_softsurface = SDL_CreateRGBSurface(SDL_SWSURFACE, mode->width, mode->height, 32, 0x00FF0000, 0x0000FF00, 0x00000000FF, 0xFF000000);
2786 if (vid_softsurface == NULL)
2788 Con_Printf("Failed to setup software rasterizer framebuffer %ix%ix32bpp: %s\n", mode->width, mode->height, SDL_GetError());
2792 #if SDL_MAJOR_VERSION == 1
2793 SDL_SetAlpha(vid_softsurface, 0, 255);
2795 SDL_SetSurfaceBlendMode(vid_softsurface, SDL_BLENDMODE_NONE);
2798 vid.softpixels = (unsigned int *)vid_softsurface->pixels;
2799 vid.softdepthpixels = (unsigned int *)calloc(1, mode->width * mode->height * 4);
2800 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)
2802 Con_Printf("Failed to initialize software rasterizer\n");
2807 #if SDL_MAJOR_VERSION == 1
2809 SDL_EnableUNICODE( SDL_ENABLE );
2810 // enable key repeat since everyone expects it
2811 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
2814 VID_Soft_SharedSetup();
2817 vid_activewindow = false;
2818 vid_hasfocus = true;
2819 vid_usingmouse = false;
2820 vid_usinghidecursor = false;
2822 #if SDL_MAJOR_VERSION == 1
2823 SDL_WM_GrabInput(SDL_GRAB_OFF);
2828 qboolean VID_InitMode(viddef_mode_t *mode)
2830 // GAME_STEELSTORM specific
2831 steelstorm_showing_map = Cvar_FindVar("steelstorm_showing_map");
2832 steelstorm_showing_mousecursor = Cvar_FindVar("steelstorm_showing_mousecursor");
2834 if (!SDL_WasInit(SDL_INIT_VIDEO) && SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
2835 Sys_Error ("Failed to init SDL video subsystem: %s", SDL_GetError());
2837 #if SDL_MAJOR_VERSION != 1
2838 Cvar_SetValueQuick(&vid_touchscreen_supportshowkeyboard, SDL_HasScreenKeyboardSupport() ? 1 : 0);
2841 if (vid_soft.integer)
2842 return VID_InitModeSoft(mode);
2845 return VID_InitModeGL(mode);
2848 void VID_Shutdown (void)
2850 VID_EnableJoystick(false);
2851 VID_SetMouse(false, false, false);
2853 #if SDL_MAJOR_VERSION == 1
2857 SDL_FreeSurface(icon);
2863 if (vid_softsurface)
2864 SDL_FreeSurface(vid_softsurface);
2865 vid_softsurface = NULL;
2866 vid.softpixels = NULL;
2867 if (vid.softdepthpixels)
2868 free(vid.softdepthpixels);
2869 vid.softdepthpixels = NULL;
2871 #if SDL_MAJOR_VERSION != 1
2872 SDL_DestroyWindow(window);
2876 SDL_QuitSubSystem(SDL_INIT_VIDEO);
2881 gl_platformextensions = "";
2884 void VID_Finish (void)
2886 #if SDL_MAJOR_VERSION == 1
2889 //react on appstate changes
2890 appstate = SDL_GetAppState();
2892 vid_hidden = !(appstate & SDL_APPACTIVE);
2893 vid_hasfocus = (appstate & SDL_APPINPUTFOCUS) != 0;
2895 vid_activewindow = !vid_hidden && vid_hasfocus;
2901 switch(vid.renderpath)
2903 case RENDERPATH_GL11:
2904 case RENDERPATH_GL13:
2905 case RENDERPATH_GL20:
2906 case RENDERPATH_GLES1:
2907 case RENDERPATH_GLES2:
2909 if (r_speeds.integer == 2 || gl_finish.integer)
2912 #if SDL_MAJOR_VERSION != 1
2914 qboolean vid_usevsync;
2915 vid_usevsync = (vid_vsync.integer && !cls.timedemo);
2916 if (vid_usingvsync != vid_usevsync)
2918 vid_usingvsync = vid_usevsync;
2919 if (SDL_GL_SetSwapInterval(vid_usevsync != 0) >= 0)
2920 Con_DPrintf("Vsync %s\n", vid_usevsync ? "activated" : "deactivated");
2922 Con_DPrintf("ERROR: can't %s vsync\n", vid_usevsync ? "activate" : "deactivate");
2926 #if SDL_MAJOR_VERSION == 1
2927 SDL_GL_SwapBuffers();
2929 SDL_GL_SwapWindow(window);
2932 case RENDERPATH_SOFT:
2933 DPSOFTRAST_Finish();
2934 #if SDL_MAJOR_VERSION == 1
2935 // if (!r_test.integer)
2937 SDL_BlitSurface(vid_softsurface, NULL, video_screen, NULL);
2938 SDL_Flip(video_screen);
2942 SDL_Surface *screen = SDL_GetWindowSurface(window);
2943 SDL_BlitSurface(vid_softsurface, NULL, screen, NULL);
2944 SDL_UpdateWindowSurface(window);
2948 case RENDERPATH_D3D9:
2949 case RENDERPATH_D3D10:
2950 case RENDERPATH_D3D11:
2951 if (r_speeds.integer == 2 || gl_finish.integer)
2958 vid_mode_t *VID_GetDesktopMode(void)
2960 #if SDL_MAJOR_VERSION != 1
2961 SDL_DisplayMode mode;
2963 Uint32 rmask, gmask, bmask, amask;
2964 SDL_GetDesktopDisplayMode(0, &mode);
2965 SDL_PixelFormatEnumToMasks(mode.format, &bpp, &rmask, &gmask, &bmask, &amask);
2966 desktop_mode.width = mode.w;
2967 desktop_mode.height = mode.h;
2968 desktop_mode.bpp = bpp;
2969 desktop_mode.refreshrate = mode.refresh_rate;
2970 desktop_mode.pixelheight_num = 1;
2971 desktop_mode.pixelheight_denom = 1; // SDL does not provide this
2972 // TODO check whether this actually works, or whether we do still need
2973 // a read-window-size-after-entering-desktop-fullscreen hack for
2974 // multiscreen setups.
2976 return &desktop_mode;
2979 size_t VID_ListModes(vid_mode_t *modes, size_t maxcount)
2982 #if SDL_MAJOR_VERSION == 1
2983 SDL_Rect **vidmodes;
2984 int bpp = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
2986 SDL_Rect **ENDRECT = (SDL_Rect**)-1LL;
2988 SDL_Rect **ENDRECT = (SDL_Rect**)-1;
2991 for(vidmodes = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE); vidmodes && vidmodes != ENDRECT && *vidmodes; ++vidmodes)
2995 modes[k].width = (*vidmodes)->w;
2996 modes[k].height = (*vidmodes)->h;
2998 modes[k].refreshrate = 60; // no support for refresh rate in SDL
2999 modes[k].pixelheight_num = 1;
3000 modes[k].pixelheight_denom = 1; // SDL does not provide this
3005 int nummodes = SDL_GetNumDisplayModes(0);
3006 SDL_DisplayMode mode;
3007 for (modenum = 0;modenum < nummodes;modenum++)
3011 if (SDL_GetDisplayMode(0, modenum, &mode))
3013 modes[k].width = mode.w;
3014 modes[k].height = mode.h;
3016 modes[k].refreshrate = mode.refresh_rate;
3017 modes[k].pixelheight_num = 1;
3018 modes[k].pixelheight_denom = 1; // SDL does not provide this