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
29 #include <Carbon/Carbon.h>
30 #include <IOKit/hidsystem/IOHIDLib.h>
31 #include <IOKit/hidsystem/IOHIDParameter.h>
32 #include <IOKit/hidsystem/event_status_driver.h>
33 static cvar_t apple_mouse_noaccel = {CVAR_SAVE, "apple_mouse_noaccel", "1", "disables mouse acceleration while DarkPlaces is active"};
34 static qboolean vid_usingnoaccel;
35 static double originalMouseSpeed = -1.0;
36 io_connect_t IN_GetIOHandle(void)
38 io_connect_t iohandle = MACH_PORT_NULL;
40 io_service_t iohidsystem = MACH_PORT_NULL;
41 mach_port_t masterport;
43 status = IOMasterPort(MACH_PORT_NULL, &masterport);
44 if(status != KERN_SUCCESS)
47 iohidsystem = IORegistryEntryFromPath(masterport, kIOServicePlane ":/IOResources/IOHIDSystem");
51 status = IOServiceOpen(iohidsystem, mach_task_self(), kIOHIDParamConnectType, &iohandle);
52 IOObjectRelease(iohidsystem);
63 // Tell startup code that we have a client
64 int cl_available = true;
66 qboolean vid_supportrefreshrate = false;
68 static qboolean vid_usingmouse = false;
69 static qboolean vid_usingmouse_relativeworks = false; // SDL2 workaround for unimplemented RelativeMouse mode
70 static qboolean vid_usinghidecursor = false;
71 static qboolean vid_hasfocus = false;
72 static qboolean vid_isfullscreen;
73 static qboolean vid_usingvsync = false;
74 static SDL_Joystick *vid_sdljoystick = NULL;
75 // GAME_STEELSTORM specific
76 static cvar_t *steelstorm_showing_map = NULL; // detect but do not create the cvar
77 static cvar_t *steelstorm_showing_mousecursor = NULL; // detect but do not create the cvar
79 static int win_half_width = 50;
80 static int win_half_height = 50;
83 static SDL_GLContext context;
84 static SDL_Window *window;
85 static int window_flags;
86 static vid_mode_t desktop_mode;
91 #define SDLK_PERCENT '%'
94 static int MapKey( unsigned int sdlkey )
99 // case SDLK_UNKNOWN: return K_UNKNOWN;
100 case SDLK_RETURN: return K_ENTER;
101 case SDLK_ESCAPE: return K_ESCAPE;
102 case SDLK_BACKSPACE: return K_BACKSPACE;
103 case SDLK_TAB: return K_TAB;
104 case SDLK_SPACE: return K_SPACE;
105 case SDLK_EXCLAIM: return '!';
106 case SDLK_QUOTEDBL: return '"';
107 case SDLK_HASH: return '#';
108 case SDLK_PERCENT: return '%';
109 case SDLK_DOLLAR: return '$';
110 case SDLK_AMPERSAND: return '&';
111 case SDLK_QUOTE: return '\'';
112 case SDLK_LEFTPAREN: return '(';
113 case SDLK_RIGHTPAREN: return ')';
114 case SDLK_ASTERISK: return '*';
115 case SDLK_PLUS: return '+';
116 case SDLK_COMMA: return ',';
117 case SDLK_MINUS: return '-';
118 case SDLK_PERIOD: return '.';
119 case SDLK_SLASH: return '/';
120 case SDLK_0: return '0';
121 case SDLK_1: return '1';
122 case SDLK_2: return '2';
123 case SDLK_3: return '3';
124 case SDLK_4: return '4';
125 case SDLK_5: return '5';
126 case SDLK_6: return '6';
127 case SDLK_7: return '7';
128 case SDLK_8: return '8';
129 case SDLK_9: return '9';
130 case SDLK_COLON: return ':';
131 case SDLK_SEMICOLON: return ';';
132 case SDLK_LESS: return '<';
133 case SDLK_EQUALS: return '=';
134 case SDLK_GREATER: return '>';
135 case SDLK_QUESTION: return '?';
136 case SDLK_AT: return '@';
137 case SDLK_LEFTBRACKET: return '[';
138 case SDLK_BACKSLASH: return '\\';
139 case SDLK_RIGHTBRACKET: return ']';
140 case SDLK_CARET: return '^';
141 case SDLK_UNDERSCORE: return '_';
142 case SDLK_BACKQUOTE: return '`';
143 case SDLK_a: return 'a';
144 case SDLK_b: return 'b';
145 case SDLK_c: return 'c';
146 case SDLK_d: return 'd';
147 case SDLK_e: return 'e';
148 case SDLK_f: return 'f';
149 case SDLK_g: return 'g';
150 case SDLK_h: return 'h';
151 case SDLK_i: return 'i';
152 case SDLK_j: return 'j';
153 case SDLK_k: return 'k';
154 case SDLK_l: return 'l';
155 case SDLK_m: return 'm';
156 case SDLK_n: return 'n';
157 case SDLK_o: return 'o';
158 case SDLK_p: return 'p';
159 case SDLK_q: return 'q';
160 case SDLK_r: return 'r';
161 case SDLK_s: return 's';
162 case SDLK_t: return 't';
163 case SDLK_u: return 'u';
164 case SDLK_v: return 'v';
165 case SDLK_w: return 'w';
166 case SDLK_x: return 'x';
167 case SDLK_y: return 'y';
168 case SDLK_z: return 'z';
169 case SDLK_CAPSLOCK: return K_CAPSLOCK;
170 case SDLK_F1: return K_F1;
171 case SDLK_F2: return K_F2;
172 case SDLK_F3: return K_F3;
173 case SDLK_F4: return K_F4;
174 case SDLK_F5: return K_F5;
175 case SDLK_F6: return K_F6;
176 case SDLK_F7: return K_F7;
177 case SDLK_F8: return K_F8;
178 case SDLK_F9: return K_F9;
179 case SDLK_F10: return K_F10;
180 case SDLK_F11: return K_F11;
181 case SDLK_F12: return K_F12;
182 case SDLK_PRINTSCREEN: return K_PRINTSCREEN;
183 case SDLK_SCROLLLOCK: return K_SCROLLOCK;
184 case SDLK_PAUSE: return K_PAUSE;
185 case SDLK_INSERT: return K_INS;
186 case SDLK_HOME: return K_HOME;
187 case SDLK_PAGEUP: return K_PGUP;
189 case SDLK_DELETE: return K_BACKSPACE;
191 case SDLK_DELETE: return K_DEL;
193 case SDLK_END: return K_END;
194 case SDLK_PAGEDOWN: return K_PGDN;
195 case SDLK_RIGHT: return K_RIGHTARROW;
196 case SDLK_LEFT: return K_LEFTARROW;
197 case SDLK_DOWN: return K_DOWNARROW;
198 case SDLK_UP: return K_UPARROW;
199 case SDLK_NUMLOCKCLEAR: return K_NUMLOCK;
200 case SDLK_KP_DIVIDE: return K_KP_DIVIDE;
201 case SDLK_KP_MULTIPLY: return K_KP_MULTIPLY;
202 case SDLK_KP_MINUS: return K_KP_MINUS;
203 case SDLK_KP_PLUS: return K_KP_PLUS;
204 case SDLK_KP_ENTER: return K_KP_ENTER;
205 case SDLK_KP_1: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_1 : K_END);
206 case SDLK_KP_2: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_2 : K_DOWNARROW);
207 case SDLK_KP_3: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_3 : K_PGDN);
208 case SDLK_KP_4: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_4 : K_LEFTARROW);
209 case SDLK_KP_5: return K_KP_5;
210 case SDLK_KP_6: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_6 : K_RIGHTARROW);
211 case SDLK_KP_7: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_7 : K_HOME);
212 case SDLK_KP_8: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_8 : K_UPARROW);
213 case SDLK_KP_9: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_9 : K_PGUP);
214 case SDLK_KP_0: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_0 : K_INS);
215 case SDLK_KP_PERIOD: return ((SDL_GetModState() & KMOD_NUM) ? K_KP_PERIOD : K_DEL);
216 // case SDLK_APPLICATION: return K_APPLICATION;
217 // case SDLK_POWER: return K_POWER;
218 case SDLK_KP_EQUALS: return K_KP_EQUALS;
219 // case SDLK_F13: return K_F13;
220 // case SDLK_F14: return K_F14;
221 // case SDLK_F15: return K_F15;
222 // case SDLK_F16: return K_F16;
223 // case SDLK_F17: return K_F17;
224 // case SDLK_F18: return K_F18;
225 // case SDLK_F19: return K_F19;
226 // case SDLK_F20: return K_F20;
227 // case SDLK_F21: return K_F21;
228 // case SDLK_F22: return K_F22;
229 // case SDLK_F23: return K_F23;
230 // case SDLK_F24: return K_F24;
231 // case SDLK_EXECUTE: return K_EXECUTE;
232 // case SDLK_HELP: return K_HELP;
233 // case SDLK_MENU: return K_MENU;
234 // case SDLK_SELECT: return K_SELECT;
235 // case SDLK_STOP: return K_STOP;
236 // case SDLK_AGAIN: return K_AGAIN;
237 // case SDLK_UNDO: return K_UNDO;
238 // case SDLK_CUT: return K_CUT;
239 // case SDLK_COPY: return K_COPY;
240 // case SDLK_PASTE: return K_PASTE;
241 // case SDLK_FIND: return K_FIND;
242 // case SDLK_MUTE: return K_MUTE;
243 // case SDLK_VOLUMEUP: return K_VOLUMEUP;
244 // case SDLK_VOLUMEDOWN: return K_VOLUMEDOWN;
245 // case SDLK_KP_COMMA: return K_KP_COMMA;
246 // case SDLK_KP_EQUALSAS400: return K_KP_EQUALSAS400;
247 // case SDLK_ALTERASE: return K_ALTERASE;
248 // case SDLK_SYSREQ: return K_SYSREQ;
249 // case SDLK_CANCEL: return K_CANCEL;
250 // case SDLK_CLEAR: return K_CLEAR;
251 // case SDLK_PRIOR: return K_PRIOR;
252 // case SDLK_RETURN2: return K_RETURN2;
253 // case SDLK_SEPARATOR: return K_SEPARATOR;
254 // case SDLK_OUT: return K_OUT;
255 // case SDLK_OPER: return K_OPER;
256 // case SDLK_CLEARAGAIN: return K_CLEARAGAIN;
257 // case SDLK_CRSEL: return K_CRSEL;
258 // case SDLK_EXSEL: return K_EXSEL;
259 // case SDLK_KP_00: return K_KP_00;
260 // case SDLK_KP_000: return K_KP_000;
261 // case SDLK_THOUSANDSSEPARATOR: return K_THOUSANDSSEPARATOR;
262 // case SDLK_DECIMALSEPARATOR: return K_DECIMALSEPARATOR;
263 // case SDLK_CURRENCYUNIT: return K_CURRENCYUNIT;
264 // case SDLK_CURRENCYSUBUNIT: return K_CURRENCYSUBUNIT;
265 // case SDLK_KP_LEFTPAREN: return K_KP_LEFTPAREN;
266 // case SDLK_KP_RIGHTPAREN: return K_KP_RIGHTPAREN;
267 // case SDLK_KP_LEFTBRACE: return K_KP_LEFTBRACE;
268 // case SDLK_KP_RIGHTBRACE: return K_KP_RIGHTBRACE;
269 // case SDLK_KP_TAB: return K_KP_TAB;
270 // case SDLK_KP_BACKSPACE: return K_KP_BACKSPACE;
271 // case SDLK_KP_A: return K_KP_A;
272 // case SDLK_KP_B: return K_KP_B;
273 // case SDLK_KP_C: return K_KP_C;
274 // case SDLK_KP_D: return K_KP_D;
275 // case SDLK_KP_E: return K_KP_E;
276 // case SDLK_KP_F: return K_KP_F;
277 // case SDLK_KP_XOR: return K_KP_XOR;
278 // case SDLK_KP_POWER: return K_KP_POWER;
279 // case SDLK_KP_PERCENT: return K_KP_PERCENT;
280 // case SDLK_KP_LESS: return K_KP_LESS;
281 // case SDLK_KP_GREATER: return K_KP_GREATER;
282 // case SDLK_KP_AMPERSAND: return K_KP_AMPERSAND;
283 // case SDLK_KP_DBLAMPERSAND: return K_KP_DBLAMPERSAND;
284 // case SDLK_KP_VERTICALBAR: return K_KP_VERTICALBAR;
285 // case SDLK_KP_DBLVERTICALBAR: return K_KP_DBLVERTICALBAR;
286 // case SDLK_KP_COLON: return K_KP_COLON;
287 // case SDLK_KP_HASH: return K_KP_HASH;
288 // case SDLK_KP_SPACE: return K_KP_SPACE;
289 // case SDLK_KP_AT: return K_KP_AT;
290 // case SDLK_KP_EXCLAM: return K_KP_EXCLAM;
291 // case SDLK_KP_MEMSTORE: return K_KP_MEMSTORE;
292 // case SDLK_KP_MEMRECALL: return K_KP_MEMRECALL;
293 // case SDLK_KP_MEMCLEAR: return K_KP_MEMCLEAR;
294 // case SDLK_KP_MEMADD: return K_KP_MEMADD;
295 // case SDLK_KP_MEMSUBTRACT: return K_KP_MEMSUBTRACT;
296 // case SDLK_KP_MEMMULTIPLY: return K_KP_MEMMULTIPLY;
297 // case SDLK_KP_MEMDIVIDE: return K_KP_MEMDIVIDE;
298 // case SDLK_KP_PLUSMINUS: return K_KP_PLUSMINUS;
299 // case SDLK_KP_CLEAR: return K_KP_CLEAR;
300 // case SDLK_KP_CLEARENTRY: return K_KP_CLEARENTRY;
301 // case SDLK_KP_BINARY: return K_KP_BINARY;
302 // case SDLK_KP_OCTAL: return K_KP_OCTAL;
303 // case SDLK_KP_DECIMAL: return K_KP_DECIMAL;
304 // case SDLK_KP_HEXADECIMAL: return K_KP_HEXADECIMAL;
305 case SDLK_LCTRL: return K_CTRL;
306 case SDLK_LSHIFT: return K_SHIFT;
307 case SDLK_LALT: return K_ALT;
308 // case SDLK_LGUI: return K_LGUI;
309 case SDLK_RCTRL: return K_CTRL;
310 case SDLK_RSHIFT: return K_SHIFT;
311 case SDLK_RALT: return K_ALT;
312 // case SDLK_RGUI: return K_RGUI;
313 // case SDLK_MODE: return K_MODE;
314 // case SDLK_AUDIONEXT: return K_AUDIONEXT;
315 // case SDLK_AUDIOPREV: return K_AUDIOPREV;
316 // case SDLK_AUDIOSTOP: return K_AUDIOSTOP;
317 // case SDLK_AUDIOPLAY: return K_AUDIOPLAY;
318 // case SDLK_AUDIOMUTE: return K_AUDIOMUTE;
319 // case SDLK_MEDIASELECT: return K_MEDIASELECT;
320 // case SDLK_WWW: return K_WWW;
321 // case SDLK_MAIL: return K_MAIL;
322 // case SDLK_CALCULATOR: return K_CALCULATOR;
323 // case SDLK_COMPUTER: return K_COMPUTER;
324 // case SDLK_AC_SEARCH: return K_AC_SEARCH; // Android button
325 // case SDLK_AC_HOME: return K_AC_HOME; // Android button
326 case SDLK_AC_BACK: return K_ESCAPE; // Android button
327 // case SDLK_AC_FORWARD: return K_AC_FORWARD; // Android button
328 // case SDLK_AC_STOP: return K_AC_STOP; // Android button
329 // case SDLK_AC_REFRESH: return K_AC_REFRESH; // Android button
330 // case SDLK_AC_BOOKMARKS: return K_AC_BOOKMARKS; // Android button
331 // case SDLK_BRIGHTNESSDOWN: return K_BRIGHTNESSDOWN;
332 // case SDLK_BRIGHTNESSUP: return K_BRIGHTNESSUP;
333 // case SDLK_DISPLAYSWITCH: return K_DISPLAYSWITCH;
334 // case SDLK_KBDILLUMTOGGLE: return K_KBDILLUMTOGGLE;
335 // case SDLK_KBDILLUMDOWN: return K_KBDILLUMDOWN;
336 // case SDLK_KBDILLUMUP: return K_KBDILLUMUP;
337 // case SDLK_EJECT: return K_EJECT;
338 // case SDLK_SLEEP: return K_SLEEP;
342 qboolean VID_HasScreenKeyboardSupport(void)
344 return SDL_HasScreenKeyboardSupport() != SDL_FALSE;
347 void VID_ShowKeyboard(qboolean show)
349 if (!SDL_HasScreenKeyboardSupport())
354 if (!SDL_IsTextInputActive())
355 SDL_StartTextInput();
359 if (SDL_IsTextInputActive())
364 qboolean VID_ShowingKeyboard(void)
366 return SDL_IsTextInputActive() != 0;
369 void VID_SetMouse(qboolean fullscreengrab, qboolean relative, qboolean hidecursor)
371 #ifndef DP_MOBILETOUCH
374 if(vid_usingmouse && (vid_usingnoaccel != !!apple_mouse_noaccel.integer))
375 VID_SetMouse(false, false, false); // ungrab first!
377 if (vid_usingmouse != relative)
379 vid_usingmouse = relative;
380 cl_ignoremousemoves = 2;
381 vid_usingmouse_relativeworks = SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE) == 0;
382 // Con_Printf("VID_SetMouse(%i, %i, %i) relativeworks = %i\n", (int)fullscreengrab, (int)relative, (int)hidecursor, (int)vid_usingmouse_relativeworks);
386 // Save the status of mouse acceleration
387 originalMouseSpeed = -1.0; // in case of error
388 if(apple_mouse_noaccel.integer)
390 io_connect_t mouseDev = IN_GetIOHandle();
393 if(IOHIDGetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), &originalMouseSpeed) == kIOReturnSuccess)
395 Con_DPrintf("previous mouse acceleration: %f\n", originalMouseSpeed);
396 if(IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), -1.0) != kIOReturnSuccess)
398 Con_Print("Could not disable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n");
399 Cvar_SetValueQuick(&apple_mouse_noaccel, 0);
404 Con_Print("Could not disable mouse acceleration (failed at IOHIDGetAccelerationWithKey).\n");
405 Cvar_SetValueQuick(&apple_mouse_noaccel, 0);
407 IOServiceClose(mouseDev);
411 Con_Print("Could not disable mouse acceleration (failed at IO_GetIOHandle).\n");
412 Cvar_SetValueQuick(&apple_mouse_noaccel, 0);
416 vid_usingnoaccel = !!apple_mouse_noaccel.integer;
420 if(originalMouseSpeed != -1.0)
422 io_connect_t mouseDev = IN_GetIOHandle();
425 Con_DPrintf("restoring mouse acceleration to: %f\n", originalMouseSpeed);
426 if(IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), originalMouseSpeed) != kIOReturnSuccess)
427 Con_Print("Could not re-enable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n");
428 IOServiceClose(mouseDev);
431 Con_Print("Could not re-enable mouse acceleration (failed at IO_GetIOHandle).\n");
436 if (vid_usinghidecursor != hidecursor)
438 vid_usinghidecursor = hidecursor;
439 SDL_ShowCursor( hidecursor ? SDL_DISABLE : SDL_ENABLE);
444 // multitouch[10][] represents the mouse pointer
445 // multitouch[][0]: finger active
446 // multitouch[][1]: Y
447 // multitouch[][2]: Y
448 // X and Y coordinates are 0-1.
449 #define MAXFINGERS 11
450 float multitouch[MAXFINGERS][3];
452 // this one stores how many areas this finger has touched
453 int multitouchs[MAXFINGERS];
455 // modified heavily by ELUAN
456 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)
459 float fx, fy, fwidth, fheight;
460 float overfx, overfy, overfwidth, overfheight;
463 qboolean button = false;
465 if (pwidth > 0 && pheight > 0)
467 if (corner & 1) px += vid_conwidth.value;
468 if (corner & 2) py += vid_conheight.value;
469 if (corner & 4) px += vid_conwidth.value * 0.5f;
470 if (corner & 8) py += vid_conheight.value * 0.5f;
471 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);}
472 fx = px / vid_conwidth.value;
473 fy = py / vid_conheight.value;
474 fwidth = pwidth / vid_conwidth.value;
475 fheight = pheight / vid_conheight.value;
477 // 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)
479 if (!(*resultbutton))
481 oversizepixels_x *= 0.2;
482 oversizepixels_y *= 0.2;
485 oversizepixels_x /= vid_conwidth.value;
486 oversizepixels_y /= vid_conheight.value;
488 overfx = fx - oversizepixels_x;
489 overfy = fy - oversizepixels_y;
490 overfwidth = fwidth + 2*oversizepixels_x;
491 overfheight = fheight + 2*oversizepixels_y;
493 for (finger = 0;finger < MAXFINGERS;finger++)
495 if (multitouchs[finger] && iamexclusive) // for this to work correctly, you must call touch areas in order of highest to lowest priority
498 if (multitouch[finger][0] && multitouch[finger][1] >= overfx && multitouch[finger][2] >= overfy && multitouch[finger][1] < overfx + overfwidth && multitouch[finger][2] < overfy + overfheight)
500 multitouchs[finger]++;
502 rel[0] = bound(-1, (multitouch[finger][1] - (fx + 0.5f * fwidth)) * (2.0f / fwidth), 1);
503 rel[1] = bound(-1, (multitouch[finger][2] - (fy + 0.5f * fheight)) * (2.0f / fheight), 1);
506 sqsum = rel[0]*rel[0] + rel[1]*rel[1];
508 if (sqsum < deadzone*deadzone)
515 // ignore the third component
516 Vector2Normalize2(rel, rel);
522 if (scr_numtouchscreenareas < 128)
524 scr_touchscreenareas[scr_numtouchscreenareas].pic = icon;
525 scr_touchscreenareas[scr_numtouchscreenareas].text = text;
526 scr_touchscreenareas[scr_numtouchscreenareas].textheight = textheight;
527 scr_touchscreenareas[scr_numtouchscreenareas].rect[0] = px;
528 scr_touchscreenareas[scr_numtouchscreenareas].rect[1] = py;
529 scr_touchscreenareas[scr_numtouchscreenareas].rect[2] = pwidth;
530 scr_touchscreenareas[scr_numtouchscreenareas].rect[3] = pheight;
531 scr_touchscreenareas[scr_numtouchscreenareas].active = button;
532 // the pics may have alpha too.
533 scr_touchscreenareas[scr_numtouchscreenareas].activealpha = 1.f;
534 scr_touchscreenareas[scr_numtouchscreenareas].inactivealpha = 0.95f;
535 scr_numtouchscreenareas++;
541 VectorCopy(rel, resultmove);
543 VectorClear(resultmove);
547 if (*resultbutton != button)
550 Key_Event(key, 0, button);
551 if (typedtext && typedtext[0] && !*resultbutton)
553 // FIXME: implement UTF8 support - nothing actually specifies a UTF8 string here yet, but should support it...
555 for (i = 0;typedtext[i];i++)
557 Key_Event(K_TEXT, typedtext[i], true);
558 Key_Event(K_TEXT, typedtext[i], false);
562 *resultbutton = button;
568 // not reentrant, but we only need one mouse cursor anyway...
569 static void VID_TouchscreenCursor(float px, float py, float pwidth, float pheight, qboolean *resultbutton, keynum_t key)
572 float fx, fy, fwidth, fheight;
573 qboolean button = false;
574 static int cursorfinger = -1;
575 static int cursorfreemovement = false;
576 static int canclick = false;
577 static int clickxy[2];
578 static int relclickxy[2];
579 static double clickrealtime = 0;
581 if (steelstorm_showing_mousecursor && steelstorm_showing_mousecursor->integer)
582 if (pwidth > 0 && pheight > 0)
584 fx = px / vid_conwidth.value;
585 fy = py / vid_conheight.value;
586 fwidth = pwidth / vid_conwidth.value;
587 fheight = pheight / vid_conheight.value;
588 for (finger = 0;finger < MAXFINGERS;finger++)
590 if (multitouch[finger][0] && multitouch[finger][1] >= fx && multitouch[finger][2] >= fy && multitouch[finger][1] < fx + fwidth && multitouch[finger][2] < fy + fheight)
592 if (cursorfinger == -1)
594 clickxy[0] = multitouch[finger][1] * vid_width.value - 0.5f * pwidth;
595 clickxy[1] = multitouch[finger][2] * vid_height.value - 0.5f * pheight;
596 relclickxy[0] = (multitouch[finger][1] - fx) * vid_width.value - 0.5f * pwidth;
597 relclickxy[1] = (multitouch[finger][2] - fy) * vid_height.value - 0.5f * pheight;
599 cursorfinger = finger;
602 cursorfreemovement = false;
606 if (scr_numtouchscreenareas < 128)
608 if (clickrealtime + 1 > realtime)
610 scr_touchscreenareas[scr_numtouchscreenareas].pic = "gfx/gui/touch_puck_cur_click.tga";
614 scr_touchscreenareas[scr_numtouchscreenareas].pic = "gfx/gui/touch_puck_cur_touch.tga";
618 switch ((int)realtime * 10 % 20)
621 scr_touchscreenareas[scr_numtouchscreenareas].pic = "gfx/gui/touch_puck_cur_touch.tga";
624 scr_touchscreenareas[scr_numtouchscreenareas].pic = "gfx/gui/touch_puck_cur_idle.tga";
627 scr_touchscreenareas[scr_numtouchscreenareas].text = "";
628 scr_touchscreenareas[scr_numtouchscreenareas].textheight = 0;
629 scr_touchscreenareas[scr_numtouchscreenareas].rect[0] = px;
630 scr_touchscreenareas[scr_numtouchscreenareas].rect[1] = py;
631 scr_touchscreenareas[scr_numtouchscreenareas].rect[2] = pwidth;
632 scr_touchscreenareas[scr_numtouchscreenareas].rect[3] = pheight;
633 scr_touchscreenareas[scr_numtouchscreenareas].active = button;
634 scr_touchscreenareas[scr_numtouchscreenareas].activealpha = 1.0f;
635 scr_touchscreenareas[scr_numtouchscreenareas].inactivealpha = 1.0f;
636 scr_numtouchscreenareas++;
640 if (cursorfinger != -1)
642 if (multitouch[cursorfinger][0])
644 if (multitouch[cursorfinger][1] * vid_width.value - 0.5f * pwidth < clickxy[0] - 1 ||
645 multitouch[cursorfinger][1] * vid_width.value - 0.5f * pwidth > clickxy[0] + 1 ||
646 multitouch[cursorfinger][2] * vid_height.value - 0.5f * pheight< clickxy[1] - 1 ||
647 multitouch[cursorfinger][2] * vid_height.value - 0.5f * pheight> clickxy[1] + 1) // finger drifted more than the allowed amount
649 cursorfreemovement = true;
651 if (cursorfreemovement)
653 // in_windowmouse_x* is in screen resolution coordinates, not console resolution
654 in_windowmouse_x = multitouch[cursorfinger][1] * vid_width.value - 0.5f * pwidth - relclickxy[0];
655 in_windowmouse_y = multitouch[cursorfinger][2] * vid_height.value - 0.5f * pheight - relclickxy[1];
666 if (/**resultbutton != button && */(int)key > 0)
668 if (!button && !cursorfreemovement && canclick)
670 Key_Event(key, 0, true);
672 clickrealtime = realtime;
675 // SS:BR can't qc can't cope with presses and releases on the same frame
676 if (clickrealtime && clickrealtime + 0.1 < realtime)
678 Key_Event(key, 0, false);
683 *resultbutton = button;
687 void VID_BuildJoyState(vid_joystate_t *joystate)
689 VID_Shared_BuildJoyState_Begin(joystate);
693 SDL_Joystick *joy = vid_sdljoystick;
697 numaxes = SDL_JoystickNumAxes(joy);
698 for (j = 0;j < numaxes;j++)
699 joystate->axis[j] = SDL_JoystickGetAxis(joy, j) * (1.0f / 32767.0f);
700 numbuttons = SDL_JoystickNumButtons(joy);
701 for (j = 0;j < numbuttons;j++)
702 joystate->button[j] = SDL_JoystickGetButton(joy, j);
705 VID_Shared_BuildJoyState_Finish(joystate);
708 // clear every touch screen area, except the one with button[skip]
709 #define Vid_ClearAllTouchscreenAreas(skip) \
711 VID_TouchscreenCursor(0, 0, 0, 0, &buttons[0], K_MOUSE1); \
713 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, move, &buttons[1], K_MOUSE4, NULL, 0, 0, 0, false); \
715 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, aim, &buttons[2], K_MOUSE5, NULL, 0, 0, 0, false); \
717 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[3], K_SHIFT, NULL, 0, 0, 0, false); \
719 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[4], K_MOUSE2, NULL, 0, 0, 0, false); \
721 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[9], K_MOUSE3, NULL, 0, 0, 0, false); \
723 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[10], (keynum_t)'m', NULL, 0, 0, 0, false); \
725 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[11], (keynum_t)'b', NULL, 0, 0, 0, false); \
727 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[12], (keynum_t)'q', NULL, 0, 0, 0, false); \
729 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[13], (keynum_t)'`', NULL, 0, 0, 0, false); \
731 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[14], K_ESCAPE, NULL, 0, 0, 0, false); \
733 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[15], K_SPACE, NULL, 0, 0, 0, false); \
735 /////////////////////
739 static void IN_Move_TouchScreen_SteelStorm(void)
743 float xscale, yscale;
744 float move[3], aim[3];
745 static qboolean oldbuttons[128];
746 static qboolean buttons[128];
747 keydest_t keydest = (key_consoleactive & KEY_CONSOLEACTIVE_USER) ? key_console : key_dest;
748 memcpy(oldbuttons, buttons, sizeof(oldbuttons));
749 memset(multitouchs, 0, sizeof(multitouchs));
751 for (i = 0, numfingers = 0; i < MAXFINGERS - 1; i++)
752 if (multitouch[i][0])
756 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
759 multitouch[MAXFINGERS-1][0] = SDL_GetMouseState(&x, &y) ? 11 : 0;
760 multitouch[MAXFINGERS-1][1] = (float)x / vid.width;
761 multitouch[MAXFINGERS-1][2] = (float)y / vid.height;
765 // disable it so it doesn't get stuck, because SDL seems to stop updating it if there are more than 1 finger on screen
766 multitouch[MAXFINGERS-1][0] = 0;
769 // TODO: make touchscreen areas controlled by a config file or the VMs. THIS IS A MESS!
770 // TODO: can't just clear buttons[] when entering a new keydest, some keys would remain pressed
771 // 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
773 // Tuned for the SGS3, use it's value as a base. CLEAN THIS.
774 xscale = vid_touchscreen_density.value / 2.0f;
775 yscale = vid_touchscreen_density.value / 2.0f;
779 Vid_ClearAllTouchscreenAreas(14);
780 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);
783 if (steelstorm_showing_map && steelstorm_showing_map->integer) // FIXME: another hack to be removed when touchscreen areas go to QC
785 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);
786 Vid_ClearAllTouchscreenAreas(10);
788 else if (steelstorm_showing_mousecursor && steelstorm_showing_mousecursor->integer)
790 // in_windowmouse_x* is in screen resolution coordinates, not console resolution
791 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);
792 Vid_ClearAllTouchscreenAreas(0);
796 VID_TouchscreenCursor(0, 0, 0, 0, &buttons[0], K_MOUSE1);
798 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);
800 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);
801 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);
803 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);
805 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);
806 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);
808 VID_TouchscreenArea( 1,-100, 0, 100, 100, NULL , 0.0f, NULL, NULL, &buttons[10], (keynum_t)'m', NULL, 0, 0, 0, true);
809 VID_TouchscreenArea( 1,-100, 120, 100, 100, NULL , 0.0f, NULL, NULL, &buttons[11], (keynum_t)'b', NULL, 0, 0, 0, true);
810 VID_TouchscreenArea( 0, 0, 0, 64, 64, NULL , 0.0f, NULL, NULL, &buttons[12], (keynum_t)'q', NULL, 0, 0, 0, true);
811 if (developer.integer)
812 VID_TouchscreenArea( 0, 0, 96, 64, 64, NULL , 0.0f, NULL, NULL, &buttons[13], (keynum_t)'`', NULL, 0, 0, 0, true);
814 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[13], (keynum_t)'`', NULL, 0, 0, 0, false);
815 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);
816 switch(cl.activeweapon)
819 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);
822 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);
825 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[15], K_SPACE, NULL, 0, 0, 0, false);
830 if (!steelstorm_showing_mousecursor || !steelstorm_showing_mousecursor->integer)
832 Vid_ClearAllTouchscreenAreas(14);
833 // this way we can skip cutscenes
834 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);
838 // in_windowmouse_x* is in screen resolution coordinates, not console resolution
839 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);
840 Vid_ClearAllTouchscreenAreas(0);
845 if (VID_ShowingKeyboard() && (float)in_windowmouse_y > vid_height.value / 2 - 10)
846 in_windowmouse_y = 128;
848 cl.cmd.forwardmove -= move[1] * cl_forwardspeed.value;
849 cl.cmd.sidemove += move[0] * cl_sidespeed.value;
850 cl.viewangles[0] += aim[1] * cl_pitchspeed.value * cl.realframetime;
851 cl.viewangles[1] -= aim[0] * cl_yawspeed.value * cl.realframetime;
854 static void IN_Move_TouchScreen_Quake(void)
857 float move[3], aim[3], click[3];
858 static qboolean oldbuttons[128];
859 static qboolean buttons[128];
860 keydest_t keydest = (key_consoleactive & KEY_CONSOLEACTIVE_USER) ? key_console : key_dest;
861 memcpy(oldbuttons, buttons, sizeof(oldbuttons));
862 memset(multitouchs, 0, sizeof(multitouchs));
864 // simple quake controls
865 multitouch[MAXFINGERS-1][0] = SDL_GetMouseState(&x, &y);
866 multitouch[MAXFINGERS-1][1] = x * 32768 / vid.width;
867 multitouch[MAXFINGERS-1][2] = y * 32768 / vid.height;
869 // top of screen is toggleconsole and K_ESCAPE
873 VID_TouchscreenArea( 0, 0, 0, 64, 64, NULL , 0.0f, NULL, NULL, &buttons[13], (keynum_t)'`', NULL, 0, 0, 0, true);
874 VID_TouchscreenArea( 0, 64, 0, 64, 64, "gfx/touch_menu.tga" , 0.0f, NULL, NULL, &buttons[14], K_ESCAPE, NULL, 0, 0, 0, true);
875 if (!VID_ShowingKeyboard())
877 // user entered a command, close the console now
878 Con_ToggleConsole_f();
880 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[15], (keynum_t)0, NULL, 0, 0, 0, true);
881 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, move, &buttons[0], K_MOUSE4, NULL, 0, 0, 0, true);
882 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, aim, &buttons[1], K_MOUSE5, NULL, 0, 0, 0, true);
883 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, click,&buttons[2], K_MOUSE1, NULL, 0, 0, 0, true);
884 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[3], K_SPACE, NULL, 0, 0, 0, true);
885 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[4], K_MOUSE2, NULL, 0, 0, 0, true);
888 VID_TouchscreenArea( 0, 0, 0, 64, 64, NULL , 0.0f, NULL, NULL, &buttons[13], (keynum_t)'`', NULL, 0, 0, 0, true);
889 VID_TouchscreenArea( 0, 64, 0, 64, 64, "gfx/touch_menu.tga" , 0.0f, NULL, NULL, &buttons[14], K_ESCAPE, NULL, 0, 0, 0, true);
890 VID_TouchscreenArea( 2, 0,-128, 128, 128, "gfx/touch_movebutton.tga" , 0.0f, NULL, move, &buttons[0], K_MOUSE4, NULL, 0, 0, 0, true);
891 VID_TouchscreenArea( 3,-128,-128, 128, 128, "gfx/touch_aimbutton.tga" , 0.0f, NULL, aim, &buttons[1], K_MOUSE5, NULL, 0, 0, 0, true);
892 VID_TouchscreenArea( 2, 0,-160, 64, 32, "gfx/touch_jumpbutton.tga" , 0.0f, NULL, NULL, &buttons[3], K_SPACE, NULL, 0, 0, 0, true);
893 VID_TouchscreenArea( 3,-128,-160, 64, 32, "gfx/touch_attackbutton.tga" , 0.0f, NULL, NULL, &buttons[2], K_MOUSE1, NULL, 0, 0, 0, true);
894 VID_TouchscreenArea( 3, -64,-160, 64, 32, "gfx/touch_attack2button.tga", 0.0f, NULL, NULL, &buttons[4], K_MOUSE2, NULL, 0, 0, 0, true);
898 VID_TouchscreenArea( 0, 0, 0, 64, 64, NULL , 0.0f, NULL, NULL, &buttons[13], (keynum_t)'`', NULL, 0, 0, 0, true);
899 VID_TouchscreenArea( 0, 64, 0, 64, 64, "gfx/touch_menu.tga" , 0.0f, NULL, NULL, &buttons[14], K_ESCAPE, NULL, 0, 0, 0, true);
900 // in menus, an icon in the corner activates keyboard
901 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);
903 VID_ShowKeyboard(true);
904 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, move, &buttons[0], K_MOUSE4, NULL, 0, 0, 0, true);
905 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, aim, &buttons[1], K_MOUSE5, NULL, 0, 0, 0, true);
906 VID_TouchscreenArea(16, -320,-480,640, 960, NULL , 0.0f, NULL, click,&buttons[2], K_MOUSE1, NULL, 0, 0, 0, true);
907 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[3], K_SPACE, NULL, 0, 0, 0, true);
908 VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[4], K_MOUSE2, NULL, 0, 0, 0, true);
911 in_windowmouse_x = x;
912 in_windowmouse_y = y;
917 cl.cmd.forwardmove -= move[1] * cl_forwardspeed.value;
918 cl.cmd.sidemove += move[0] * cl_sidespeed.value;
919 cl.viewangles[0] += aim[1] * cl_pitchspeed.value * cl.realframetime;
920 cl.viewangles[1] -= aim[0] * cl_yawspeed.value * cl.realframetime;
925 static int old_x = 0, old_y = 0;
926 static int stuck = 0;
927 static keydest_t oldkeydest;
928 static qboolean oldshowkeyboard;
930 vid_joystate_t joystate;
931 keydest_t keydest = (key_consoleactive & KEY_CONSOLEACTIVE_USER) ? key_console : key_dest;
933 scr_numtouchscreenareas = 0;
935 // Only apply the new keyboard state if the input changes.
936 if (keydest != oldkeydest || !!vid_touchscreen_showkeyboard.integer != oldshowkeyboard)
940 case key_console: VID_ShowKeyboard(true);break;
941 case key_message: VID_ShowKeyboard(true);break;
942 default: VID_ShowKeyboard(!!vid_touchscreen_showkeyboard.integer); break;
945 oldkeydest = keydest;
946 oldshowkeyboard = !!vid_touchscreen_showkeyboard.integer;
948 if (vid_touchscreen.integer)
952 case GAME_STEELSTORM:
953 IN_Move_TouchScreen_SteelStorm();
956 IN_Move_TouchScreen_Quake();
964 if (vid_stick_mouse.integer || !vid_usingmouse_relativeworks)
966 // have the mouse stuck in the middle, example use: prevent expose effect of beryl during the game when not using
967 // window grabbing. --blub
969 // we need 2 frames to initialize the center position
972 SDL_WarpMouseInWindow(window, win_half_width, win_half_height);
973 SDL_GetMouseState(&x, &y);
974 SDL_GetRelativeMouseState(&x, &y);
977 SDL_GetRelativeMouseState(&x, &y);
978 in_mouse_x = x + old_x;
979 in_mouse_y = y + old_y;
980 SDL_GetMouseState(&x, &y);
981 old_x = x - win_half_width;
982 old_y = y - win_half_height;
983 SDL_WarpMouseInWindow(window, win_half_width, win_half_height);
986 SDL_GetRelativeMouseState( &x, &y );
992 SDL_GetMouseState(&x, &y);
993 in_windowmouse_x = x;
994 in_windowmouse_y = y;
997 VID_BuildJoyState(&joystate);
998 VID_ApplyJoyState(&joystate);
1001 /////////////////////
1005 #ifdef SDL_R_RESTART
1006 static qboolean sdl_needs_restart;
1007 static void sdl_start(void)
1010 static void sdl_shutdown(void)
1012 sdl_needs_restart = false;
1014 static void sdl_newmap(void)
1019 static keynum_t buttonremap[] =
1039 //#define DEBUGSDLEVENTS
1042 void Sys_SendKeyEvents( void )
1044 static qboolean sound_active = true;
1051 VID_EnableJoystick(true);
1053 while( SDL_PollEvent( &event ) )
1055 switch( event.type ) {
1057 #ifdef DEBUGSDLEVENTS
1058 Con_DPrintf("SDL_Event: SDL_QUIT\n");
1064 #ifdef DEBUGSDLEVENTS
1065 if (event.type == SDL_KEYDOWN)
1066 Con_DPrintf("SDL_Event: SDL_KEYDOWN %i\n", event.key.keysym.sym);
1068 Con_DPrintf("SDL_Event: SDL_KEYUP %i\n", event.key.keysym.sym);
1070 keycode = MapKey(event.key.keysym.sym);
1071 isdown = (event.key.state == SDL_PRESSED);
1075 if(SDL_PollEvent(&event))
1077 if(event.type == SDL_TEXTINPUT)
1079 // combine key code from SDL_KEYDOWN event and character
1080 // from SDL_TEXTINPUT event in a single Key_Event call
1081 #ifdef DEBUGSDLEVENTS
1082 Con_DPrintf("SDL_Event: SDL_TEXTINPUT - text: %s\n", event.text.text);
1084 unicode = u8_getchar_utf8_enabled(event.text.text + (int)u8_bytelen(event.text.text, 0), NULL);
1088 if (!VID_JoyBlockEmulatedKeys(keycode))
1089 Key_Event(keycode, 0, isdown);
1094 if (!VID_JoyBlockEmulatedKeys(keycode))
1095 Key_Event(keycode, unicode, isdown);
1097 case SDL_MOUSEBUTTONDOWN:
1098 case SDL_MOUSEBUTTONUP:
1099 #ifdef DEBUGSDLEVENTS
1100 if (event.type == SDL_MOUSEBUTTONDOWN)
1101 Con_DPrintf("SDL_Event: SDL_MOUSEBUTTONDOWN\n");
1103 Con_DPrintf("SDL_Event: SDL_MOUSEBUTTONUP\n");
1105 if (!vid_touchscreen.integer)
1106 if (event.button.button > 0 && event.button.button <= ARRAY_SIZE(buttonremap))
1107 Key_Event( buttonremap[event.button.button - 1], 0, event.button.state == SDL_PRESSED );
1109 case SDL_MOUSEWHEEL:
1110 // TODO support wheel x direction.
1114 Key_Event( K_MWHEELUP, 0, true );
1115 Key_Event( K_MWHEELUP, 0, false );
1119 Key_Event( K_MWHEELDOWN, 0, true );
1120 Key_Event( K_MWHEELDOWN, 0, false );
1123 case SDL_JOYBUTTONDOWN:
1124 case SDL_JOYBUTTONUP:
1125 case SDL_JOYAXISMOTION:
1126 case SDL_JOYBALLMOTION:
1127 case SDL_JOYHATMOTION:
1128 #ifdef DEBUGSDLEVENTS
1129 Con_DPrintf("SDL_Event: SDL_JOY*\n");
1132 case SDL_WINDOWEVENT:
1133 #ifdef DEBUGSDLEVENTS
1134 Con_DPrintf("SDL_Event: SDL_WINDOWEVENT %i\n", (int)event.window.event);
1136 //if (event.window.windowID == window) // how to compare?
1138 switch(event.window.event)
1140 case SDL_WINDOWEVENT_SHOWN:
1143 case SDL_WINDOWEVENT_HIDDEN:
1146 case SDL_WINDOWEVENT_EXPOSED:
1147 #ifdef DEBUGSDLEVENTS
1148 Con_DPrintf("SDL_Event: SDL_WINDOWEVENT_EXPOSED\n");
1151 case SDL_WINDOWEVENT_MOVED:
1153 case SDL_WINDOWEVENT_RESIZED:
1154 if(vid_resizable.integer < 2)
1156 vid.width = event.window.data1;
1157 vid.height = event.window.data2;
1158 #ifdef SDL_R_RESTART
1159 // better not call R_Modules_Restart from here directly, as this may wreak havoc...
1160 // so, let's better queue it for next frame
1161 if(!sdl_needs_restart)
1163 Cbuf_AddText("\nr_restart\n");
1164 sdl_needs_restart = true;
1169 case SDL_WINDOWEVENT_MINIMIZED:
1171 case SDL_WINDOWEVENT_MAXIMIZED:
1173 case SDL_WINDOWEVENT_RESTORED:
1175 case SDL_WINDOWEVENT_ENTER:
1177 case SDL_WINDOWEVENT_LEAVE:
1179 case SDL_WINDOWEVENT_FOCUS_GAINED:
1180 vid_hasfocus = true;
1182 case SDL_WINDOWEVENT_FOCUS_LOST:
1183 vid_hasfocus = false;
1185 case SDL_WINDOWEVENT_CLOSE:
1191 case SDL_TEXTEDITING:
1192 #ifdef DEBUGSDLEVENTS
1193 Con_DPrintf("SDL_Event: SDL_TEXTEDITING - composition = %s, cursor = %d, selection lenght = %d\n", event.edit.text, event.edit.start, event.edit.length);
1195 // FIXME! this is where composition gets supported
1198 #ifdef DEBUGSDLEVENTS
1199 Con_DPrintf("SDL_Event: SDL_TEXTINPUT - text: %s\n", event.text.text);
1201 // convert utf8 string to char
1202 // NOTE: this code is supposed to run even if utf8enable is 0
1203 unicode = u8_getchar_utf8_enabled(event.text.text + (int)u8_bytelen(event.text.text, 0), NULL);
1204 Key_Event(K_TEXT, unicode, true);
1205 Key_Event(K_TEXT, unicode, false);
1207 case SDL_MOUSEMOTION:
1209 case SDL_FINGERDOWN:
1210 #ifdef DEBUGSDLEVENTS
1211 Con_DPrintf("SDL_FINGERDOWN for finger %i\n", (int)event.tfinger.fingerId);
1213 for (i = 0;i < MAXFINGERS-1;i++)
1215 if (!multitouch[i][0])
1217 multitouch[i][0] = event.tfinger.fingerId + 1;
1218 multitouch[i][1] = event.tfinger.x;
1219 multitouch[i][2] = event.tfinger.y;
1220 // TODO: use event.tfinger.pressure?
1224 if (i == MAXFINGERS-1)
1225 Con_DPrintf("Too many fingers at once!\n");
1228 #ifdef DEBUGSDLEVENTS
1229 Con_DPrintf("SDL_FINGERUP for finger %i\n", (int)event.tfinger.fingerId);
1231 for (i = 0;i < MAXFINGERS-1;i++)
1233 if (multitouch[i][0] == event.tfinger.fingerId + 1)
1235 multitouch[i][0] = 0;
1239 if (i == MAXFINGERS-1)
1240 Con_DPrintf("No SDL_FINGERDOWN event matches this SDL_FINGERMOTION event\n");
1242 case SDL_FINGERMOTION:
1243 #ifdef DEBUGSDLEVENTS
1244 Con_DPrintf("SDL_FINGERMOTION for finger %i\n", (int)event.tfinger.fingerId);
1246 for (i = 0;i < MAXFINGERS-1;i++)
1248 if (multitouch[i][0] == event.tfinger.fingerId + 1)
1250 multitouch[i][1] = event.tfinger.x;
1251 multitouch[i][2] = event.tfinger.y;
1255 if (i == MAXFINGERS-1)
1256 Con_DPrintf("No SDL_FINGERDOWN event matches this SDL_FINGERMOTION event\n");
1259 #ifdef DEBUGSDLEVENTS
1260 Con_DPrintf("Received unrecognized SDL_Event type 0x%x\n", event.type);
1265 // enable/disable sound on focus gain/loss
1266 if ((!vid_hidden && vid_activewindow) || !snd_mutewhenidle.integer)
1271 sound_active = true;
1279 sound_active = false;
1291 #include <OpenGLES/ES2/gl.h>
1293 #include <SDL_opengles.h>
1296 //#define PRECALL //Con_Printf("GLCALL %s:%i\n", __FILE__, __LINE__)
1299 GLboolean wrapglIsBuffer(GLuint buffer) {PRECALL;return glIsBuffer(buffer);POSTCALL;}
1300 GLboolean wrapglIsEnabled(GLenum cap) {PRECALL;return glIsEnabled(cap);POSTCALL;}
1301 GLboolean wrapglIsFramebuffer(GLuint framebuffer) {PRECALL;return glIsFramebuffer(framebuffer);POSTCALL;}
1302 //GLboolean wrapglIsQuery(GLuint qid) {PRECALL;return glIsQuery(qid);POSTCALL;}
1303 GLboolean wrapglIsRenderbuffer(GLuint renderbuffer) {PRECALL;return glIsRenderbuffer(renderbuffer);POSTCALL;}
1304 //GLboolean wrapglUnmapBuffer(GLenum target) {PRECALL;return glUnmapBuffer(target);POSTCALL;}
1305 GLenum wrapglCheckFramebufferStatus(GLenum target) {PRECALL;return glCheckFramebufferStatus(target);POSTCALL;}
1306 GLenum wrapglGetError(void) {PRECALL;return glGetError();POSTCALL;}
1307 GLuint wrapglCreateProgram(void) {PRECALL;return glCreateProgram();POSTCALL;}
1308 GLuint wrapglCreateShader(GLenum shaderType) {PRECALL;return glCreateShader(shaderType);POSTCALL;}
1309 //GLuint wrapglGetHandle(GLenum pname) {PRECALL;return glGetHandle(pname);POSTCALL;}
1310 GLint wrapglGetAttribLocation(GLuint programObj, const GLchar *name) {PRECALL;return glGetAttribLocation(programObj, name);POSTCALL;}
1311 GLint wrapglGetUniformLocation(GLuint programObj, const GLchar *name) {PRECALL;return glGetUniformLocation(programObj, name);POSTCALL;}
1312 //GLvoid* wrapglMapBuffer(GLenum target, GLenum access) {PRECALL;return glMapBuffer(target, access);POSTCALL;}
1313 const GLubyte* wrapglGetString(GLenum name) {PRECALL;return (const GLubyte*)glGetString(name);POSTCALL;}
1314 void wrapglActiveStencilFace(GLenum e) {PRECALL;Con_Printf("glActiveStencilFace(e)\n");POSTCALL;}
1315 void wrapglActiveTexture(GLenum e) {PRECALL;glActiveTexture(e);POSTCALL;}
1316 void wrapglArrayElement(GLint i) {PRECALL;Con_Printf("glArrayElement(i)\n");POSTCALL;}
1317 void wrapglAttachShader(GLuint containerObj, GLuint obj) {PRECALL;glAttachShader(containerObj, obj);POSTCALL;}
1318 //void wrapglBeginQuery(GLenum target, GLuint qid) {PRECALL;glBeginQuery(target, qid);POSTCALL;}
1319 void wrapglBindAttribLocation(GLuint programObj, GLuint index, const GLchar *name) {PRECALL;glBindAttribLocation(programObj, index, name);POSTCALL;}
1320 //void wrapglBindFragDataLocation(GLuint programObj, GLuint index, const GLchar *name) {PRECALL;glBindFragDataLocation(programObj, index, name);POSTCALL;}
1321 void wrapglBindBuffer(GLenum target, GLuint buffer) {PRECALL;glBindBuffer(target, buffer);POSTCALL;}
1322 void wrapglBindFramebuffer(GLenum target, GLuint framebuffer) {PRECALL;glBindFramebuffer(target, framebuffer);POSTCALL;}
1323 void wrapglBindRenderbuffer(GLenum target, GLuint renderbuffer) {PRECALL;glBindRenderbuffer(target, renderbuffer);POSTCALL;}
1324 void wrapglBindTexture(GLenum target, GLuint texture) {PRECALL;glBindTexture(target, texture);POSTCALL;}
1325 void wrapglBlendEquation(GLenum e) {PRECALL;glBlendEquation(e);POSTCALL;}
1326 void wrapglBlendFunc(GLenum sfactor, GLenum dfactor) {PRECALL;glBlendFunc(sfactor, dfactor);POSTCALL;}
1327 void wrapglBufferData(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) {PRECALL;glBufferData(target, size, data, usage);POSTCALL;}
1328 void wrapglBufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) {PRECALL;glBufferSubData(target, offset, size, data);POSTCALL;}
1329 void wrapglClear(GLbitfield mask) {PRECALL;glClear(mask);POSTCALL;}
1330 void wrapglClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {PRECALL;glClearColor(red, green, blue, alpha);POSTCALL;}
1331 void wrapglClearDepth(GLclampd depth) {PRECALL;/*Con_Printf("glClearDepth(%f)\n", depth);glClearDepthf((float)depth);*/POSTCALL;}
1332 void wrapglClearStencil(GLint s) {PRECALL;glClearStencil(s);POSTCALL;}
1333 void wrapglColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {PRECALL;glColorMask(red, green, blue, alpha);POSTCALL;}
1334 void wrapglCompileShader(GLuint shaderObj) {PRECALL;glCompileShader(shaderObj);POSTCALL;}
1335 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;}
1336 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;}
1337 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;}
1338 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;}
1339 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;}
1340 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;}
1341 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;}
1342 void wrapglCullFace(GLenum mode) {PRECALL;glCullFace(mode);POSTCALL;}
1343 void wrapglDeleteBuffers(GLsizei n, const GLuint *buffers) {PRECALL;glDeleteBuffers(n, buffers);POSTCALL;}
1344 void wrapglDeleteFramebuffers(GLsizei n, const GLuint *framebuffers) {PRECALL;glDeleteFramebuffers(n, framebuffers);POSTCALL;}
1345 void wrapglDeleteShader(GLuint obj) {PRECALL;glDeleteShader(obj);POSTCALL;}
1346 void wrapglDeleteProgram(GLuint obj) {PRECALL;glDeleteProgram(obj);POSTCALL;}
1347 //void wrapglDeleteQueries(GLsizei n, const GLuint *ids) {PRECALL;glDeleteQueries(n, ids);POSTCALL;}
1348 void wrapglDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) {PRECALL;glDeleteRenderbuffers(n, renderbuffers);POSTCALL;}
1349 void wrapglDeleteTextures(GLsizei n, const GLuint *textures) {PRECALL;glDeleteTextures(n, textures);POSTCALL;}
1350 void wrapglDepthFunc(GLenum func) {PRECALL;glDepthFunc(func);POSTCALL;}
1351 void wrapglDepthMask(GLboolean flag) {PRECALL;glDepthMask(flag);POSTCALL;}
1352 //void wrapglDepthRange(GLclampd near_val, GLclampd far_val) {PRECALL;glDepthRangef((float)near_val, (float)far_val);POSTCALL;}
1353 void wrapglDepthRangef(GLclampf near_val, GLclampf far_val) {PRECALL;glDepthRangef(near_val, far_val);POSTCALL;}
1354 void wrapglDetachShader(GLuint containerObj, GLuint attachedObj) {PRECALL;glDetachShader(containerObj, attachedObj);POSTCALL;}
1355 void wrapglDisable(GLenum cap) {PRECALL;glDisable(cap);POSTCALL;}
1356 void wrapglDisableVertexAttribArray(GLuint index) {PRECALL;glDisableVertexAttribArray(index);POSTCALL;}
1357 void wrapglDrawArrays(GLenum mode, GLint first, GLsizei count) {PRECALL;glDrawArrays(mode, first, count);POSTCALL;}
1358 void wrapglDrawBuffer(GLenum mode) {PRECALL;Con_Printf("glDrawBuffer(mode)\n");POSTCALL;}
1359 void wrapglDrawBuffers(GLsizei n, const GLenum *bufs) {PRECALL;Con_Printf("glDrawBuffers(n, bufs)\n");POSTCALL;}
1360 void wrapglDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {PRECALL;glDrawElements(mode, count, type, indices);POSTCALL;}
1361 //void wrapglDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) {PRECALL;glDrawRangeElements(mode, start, end, count, type, indices);POSTCALL;}
1362 //void wrapglDrawRangeElementsEXT(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) {PRECALL;glDrawRangeElements(mode, start, end, count, type, indices);POSTCALL;}
1363 void wrapglEnable(GLenum cap) {PRECALL;glEnable(cap);POSTCALL;}
1364 void wrapglEnableVertexAttribArray(GLuint index) {PRECALL;glEnableVertexAttribArray(index);POSTCALL;}
1365 //void wrapglEndQuery(GLenum target) {PRECALL;glEndQuery(target);POSTCALL;}
1366 void wrapglFinish(void) {PRECALL;glFinish();POSTCALL;}
1367 void wrapglFlush(void) {PRECALL;glFlush();POSTCALL;}
1368 void wrapglFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {PRECALL;glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);POSTCALL;}
1369 void wrapglFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {PRECALL;glFramebufferTexture2D(target, attachment, textarget, texture, level);POSTCALL;}
1370 void wrapglFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) {PRECALL;Con_Printf("glFramebufferTexture3D()\n");POSTCALL;}
1371 void wrapglGenBuffers(GLsizei n, GLuint *buffers) {PRECALL;glGenBuffers(n, buffers);POSTCALL;}
1372 void wrapglGenFramebuffers(GLsizei n, GLuint *framebuffers) {PRECALL;glGenFramebuffers(n, framebuffers);POSTCALL;}
1373 //void wrapglGenQueries(GLsizei n, GLuint *ids) {PRECALL;glGenQueries(n, ids);POSTCALL;}
1374 void wrapglGenRenderbuffers(GLsizei n, GLuint *renderbuffers) {PRECALL;glGenRenderbuffers(n, renderbuffers);POSTCALL;}
1375 void wrapglGenTextures(GLsizei n, GLuint *textures) {PRECALL;glGenTextures(n, textures);POSTCALL;}
1376 void wrapglGenerateMipmap(GLenum target) {PRECALL;glGenerateMipmap(target);POSTCALL;}
1377 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;}
1378 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;}
1379 void wrapglGetAttachedShaders(GLuint containerObj, GLsizei maxCount, GLsizei *count, GLuint *obj) {PRECALL;glGetAttachedShaders(containerObj, maxCount, count, obj);POSTCALL;}
1380 void wrapglGetBooleanv(GLenum pname, GLboolean *params) {PRECALL;glGetBooleanv(pname, params);POSTCALL;}
1381 void wrapglGetCompressedTexImage(GLenum target, GLint lod, void *img) {PRECALL;Con_Printf("glGetCompressedTexImage(target, lod, img)\n");POSTCALL;}
1382 void wrapglGetDoublev(GLenum pname, GLdouble *params) {PRECALL;Con_Printf("glGetDoublev(pname, params)\n");POSTCALL;}
1383 void wrapglGetFloatv(GLenum pname, GLfloat *params) {PRECALL;glGetFloatv(pname, params);POSTCALL;}
1384 void wrapglGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params) {PRECALL;glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);POSTCALL;}
1385 void wrapglGetShaderInfoLog(GLuint obj, GLsizei maxLength, GLsizei *length, GLchar *infoLog) {PRECALL;glGetShaderInfoLog(obj, maxLength, length, infoLog);POSTCALL;}
1386 void wrapglGetProgramInfoLog(GLuint obj, GLsizei maxLength, GLsizei *length, GLchar *infoLog) {PRECALL;glGetProgramInfoLog(obj, maxLength, length, infoLog);POSTCALL;}
1387 void wrapglGetIntegerv(GLenum pname, GLint *params) {PRECALL;glGetIntegerv(pname, params);POSTCALL;}
1388 void wrapglGetShaderiv(GLuint obj, GLenum pname, GLint *params) {PRECALL;glGetShaderiv(obj, pname, params);POSTCALL;}
1389 void wrapglGetProgramiv(GLuint obj, GLenum pname, GLint *params) {PRECALL;glGetProgramiv(obj, pname, params);POSTCALL;}
1390 //void wrapglGetQueryObjectiv(GLuint qid, GLenum pname, GLint *params) {PRECALL;glGetQueryObjectiv(qid, pname, params);POSTCALL;}
1391 //void wrapglGetQueryObjectuiv(GLuint qid, GLenum pname, GLuint *params) {PRECALL;glGetQueryObjectuiv(qid, pname, params);POSTCALL;}
1392 //void wrapglGetQueryiv(GLenum target, GLenum pname, GLint *params) {PRECALL;glGetQueryiv(target, pname, params);POSTCALL;}
1393 void wrapglGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params) {PRECALL;glGetRenderbufferParameteriv(target, pname, params);POSTCALL;}
1394 void wrapglGetShaderSource(GLuint obj, GLsizei maxLength, GLsizei *length, GLchar *source) {PRECALL;glGetShaderSource(obj, maxLength, length, source);POSTCALL;}
1395 void wrapglGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels) {PRECALL;Con_Printf("glGetTexImage(target, level, format, type, pixels)\n");POSTCALL;}
1396 void wrapglGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params) {PRECALL;Con_Printf("glGetTexLevelParameterfv(target, level, pname, params)\n");POSTCALL;}
1397 void wrapglGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) {PRECALL;Con_Printf("glGetTexLevelParameteriv(target, level, pname, params)\n");POSTCALL;}
1398 void wrapglGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) {PRECALL;glGetTexParameterfv(target, pname, params);POSTCALL;}
1399 void wrapglGetTexParameteriv(GLenum target, GLenum pname, GLint *params) {PRECALL;glGetTexParameteriv(target, pname, params);POSTCALL;}
1400 void wrapglGetUniformfv(GLuint programObj, GLint location, GLfloat *params) {PRECALL;glGetUniformfv(programObj, location, params);POSTCALL;}
1401 void wrapglGetUniformiv(GLuint programObj, GLint location, GLint *params) {PRECALL;glGetUniformiv(programObj, location, params);POSTCALL;}
1402 void wrapglHint(GLenum target, GLenum mode) {PRECALL;glHint(target, mode);POSTCALL;}
1403 void wrapglLinkProgram(GLuint programObj) {PRECALL;glLinkProgram(programObj);POSTCALL;}
1404 void wrapglPixelStorei(GLenum pname, GLint param) {PRECALL;glPixelStorei(pname, param);POSTCALL;}
1405 void wrapglPointSize(GLfloat size) {PRECALL;Con_Printf("glPointSize(size)\n");POSTCALL;}
1406 //void wrapglPolygonMode(GLenum face, GLenum mode) {PRECALL;Con_Printf("glPolygonMode(face, mode)\n");POSTCALL;}
1407 void wrapglPolygonOffset(GLfloat factor, GLfloat units) {PRECALL;glPolygonOffset(factor, units);POSTCALL;}
1408 void wrapglPolygonStipple(const GLubyte *mask) {PRECALL;Con_Printf("glPolygonStipple(mask)\n");POSTCALL;}
1409 void wrapglReadBuffer(GLenum mode) {PRECALL;Con_Printf("glReadBuffer(mode)\n");POSTCALL;}
1410 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;}
1411 void wrapglRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {PRECALL;glRenderbufferStorage(target, internalformat, width, height);POSTCALL;}
1412 void wrapglScissor(GLint x, GLint y, GLsizei width, GLsizei height) {PRECALL;glScissor(x, y, width, height);POSTCALL;}
1413 void wrapglShaderSource(GLuint shaderObj, GLsizei count, const GLchar **string, const GLint *length) {PRECALL;glShaderSource(shaderObj, count, string, length);POSTCALL;}
1414 void wrapglStencilFunc(GLenum func, GLint ref, GLuint mask) {PRECALL;glStencilFunc(func, ref, mask);POSTCALL;}
1415 void wrapglStencilFuncSeparate(GLenum func1, GLenum func2, GLint ref, GLuint mask) {PRECALL;Con_Printf("glStencilFuncSeparate(func1, func2, ref, mask)\n");POSTCALL;}
1416 void wrapglStencilMask(GLuint mask) {PRECALL;glStencilMask(mask);POSTCALL;}
1417 void wrapglStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {PRECALL;glStencilOp(fail, zfail, zpass);POSTCALL;}
1418 void wrapglStencilOpSeparate(GLenum e1, GLenum e2, GLenum e3, GLenum e4) {PRECALL;Con_Printf("glStencilOpSeparate(e1, e2, e3, e4)\n");POSTCALL;}
1419 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;}
1420 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;}
1421 void wrapglTexParameterf(GLenum target, GLenum pname, GLfloat param) {PRECALL;glTexParameterf(target, pname, param);POSTCALL;}
1422 void wrapglTexParameterfv(GLenum target, GLenum pname, GLfloat *params) {PRECALL;glTexParameterfv(target, pname, params);POSTCALL;}
1423 void wrapglTexParameteri(GLenum target, GLenum pname, GLint param) {PRECALL;glTexParameteri(target, pname, param);POSTCALL;}
1424 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;}
1425 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;}
1426 void wrapglUniform1f(GLint location, GLfloat v0) {PRECALL;glUniform1f(location, v0);POSTCALL;}
1427 void wrapglUniform1fv(GLint location, GLsizei count, const GLfloat *value) {PRECALL;glUniform1fv(location, count, value);POSTCALL;}
1428 void wrapglUniform1i(GLint location, GLint v0) {PRECALL;glUniform1i(location, v0);POSTCALL;}
1429 void wrapglUniform1iv(GLint location, GLsizei count, const GLint *value) {PRECALL;glUniform1iv(location, count, value);POSTCALL;}
1430 void wrapglUniform2f(GLint location, GLfloat v0, GLfloat v1) {PRECALL;glUniform2f(location, v0, v1);POSTCALL;}
1431 void wrapglUniform2fv(GLint location, GLsizei count, const GLfloat *value) {PRECALL;glUniform2fv(location, count, value);POSTCALL;}
1432 void wrapglUniform2i(GLint location, GLint v0, GLint v1) {PRECALL;glUniform2i(location, v0, v1);POSTCALL;}
1433 void wrapglUniform2iv(GLint location, GLsizei count, const GLint *value) {PRECALL;glUniform2iv(location, count, value);POSTCALL;}
1434 void wrapglUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {PRECALL;glUniform3f(location, v0, v1, v2);POSTCALL;}
1435 void wrapglUniform3fv(GLint location, GLsizei count, const GLfloat *value) {PRECALL;glUniform3fv(location, count, value);POSTCALL;}
1436 void wrapglUniform3i(GLint location, GLint v0, GLint v1, GLint v2) {PRECALL;glUniform3i(location, v0, v1, v2);POSTCALL;}
1437 void wrapglUniform3iv(GLint location, GLsizei count, const GLint *value) {PRECALL;glUniform3iv(location, count, value);POSTCALL;}
1438 void wrapglUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {PRECALL;glUniform4f(location, v0, v1, v2, v3);POSTCALL;}
1439 void wrapglUniform4fv(GLint location, GLsizei count, const GLfloat *value) {PRECALL;glUniform4fv(location, count, value);POSTCALL;}
1440 void wrapglUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {PRECALL;glUniform4i(location, v0, v1, v2, v3);POSTCALL;}
1441 void wrapglUniform4iv(GLint location, GLsizei count, const GLint *value) {PRECALL;glUniform4iv(location, count, value);POSTCALL;}
1442 void wrapglUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {PRECALL;glUniformMatrix2fv(location, count, transpose, value);POSTCALL;}
1443 void wrapglUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {PRECALL;glUniformMatrix3fv(location, count, transpose, value);POSTCALL;}
1444 void wrapglUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {PRECALL;glUniformMatrix4fv(location, count, transpose, value);POSTCALL;}
1445 void wrapglUseProgram(GLuint programObj) {PRECALL;glUseProgram(programObj);POSTCALL;}
1446 void wrapglValidateProgram(GLuint programObj) {PRECALL;glValidateProgram(programObj);POSTCALL;}
1447 void wrapglVertex2f(GLfloat x, GLfloat y) {PRECALL;Con_Printf("glVertex2f(x, y)\n");POSTCALL;}
1448 void wrapglVertex3f(GLfloat x, GLfloat y, GLfloat z) {PRECALL;Con_Printf("glVertex3f(x, y, z)\n");POSTCALL;}
1449 void wrapglVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {PRECALL;Con_Printf("glVertex4f(x, y, z, w)\n");POSTCALL;}
1450 void wrapglVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) {PRECALL;glVertexAttribPointer(index, size, type, normalized, stride, pointer);POSTCALL;}
1451 void wrapglVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) {PRECALL;Con_Printf("glVertexPointer(size, type, stride, ptr)\n");POSTCALL;}
1452 void wrapglViewport(GLint x, GLint y, GLsizei width, GLsizei height) {PRECALL;glViewport(x, y, width, height);POSTCALL;}
1453 void wrapglVertexAttrib1f(GLuint index, GLfloat v0) {PRECALL;glVertexAttrib1f(index, v0);POSTCALL;}
1454 //void wrapglVertexAttrib1s(GLuint index, GLshort v0) {PRECALL;glVertexAttrib1s(index, v0);POSTCALL;}
1455 //void wrapglVertexAttrib1d(GLuint index, GLdouble v0) {PRECALL;glVertexAttrib1d(index, v0);POSTCALL;}
1456 void wrapglVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {PRECALL;glVertexAttrib2f(index, v0, v1);POSTCALL;}
1457 //void wrapglVertexAttrib2s(GLuint index, GLshort v0, GLshort v1) {PRECALL;glVertexAttrib2s(index, v0, v1);POSTCALL;}
1458 //void wrapglVertexAttrib2d(GLuint index, GLdouble v0, GLdouble v1) {PRECALL;glVertexAttrib2d(index, v0, v1);POSTCALL;}
1459 void wrapglVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {PRECALL;glVertexAttrib3f(index, v0, v1, v2);POSTCALL;}
1460 //void wrapglVertexAttrib3s(GLuint index, GLshort v0, GLshort v1, GLshort v2) {PRECALL;glVertexAttrib3s(index, v0, v1, v2);POSTCALL;}
1461 //void wrapglVertexAttrib3d(GLuint index, GLdouble v0, GLdouble v1, GLdouble v2) {PRECALL;glVertexAttrib3d(index, v0, v1, v2);POSTCALL;}
1462 void wrapglVertexAttrib4f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {PRECALL;glVertexAttrib4f(index, v0, v1, v2, v3);POSTCALL;}
1463 //void wrapglVertexAttrib4s(GLuint index, GLshort v0, GLshort v1, GLshort v2, GLshort v3) {PRECALL;glVertexAttrib4s(index, v0, v1, v2, v3);POSTCALL;}
1464 //void wrapglVertexAttrib4d(GLuint index, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3) {PRECALL;glVertexAttrib4d(index, v0, v1, v2, v3);POSTCALL;}
1465 //void wrapglVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) {PRECALL;glVertexAttrib4Nub(index, x, y, z, w);POSTCALL;}
1466 void wrapglVertexAttrib1fv(GLuint index, const GLfloat *v) {PRECALL;glVertexAttrib1fv(index, v);POSTCALL;}
1467 //void wrapglVertexAttrib1sv(GLuint index, const GLshort *v) {PRECALL;glVertexAttrib1sv(index, v);POSTCALL;}
1468 //void wrapglVertexAttrib1dv(GLuint index, const GLdouble *v) {PRECALL;glVertexAttrib1dv(index, v);POSTCALL;}
1469 void wrapglVertexAttrib2fv(GLuint index, const GLfloat *v) {PRECALL;glVertexAttrib2fv(index, v);POSTCALL;}
1470 //void wrapglVertexAttrib2sv(GLuint index, const GLshort *v) {PRECALL;glVertexAttrib2sv(index, v);POSTCALL;}
1471 //void wrapglVertexAttrib2dv(GLuint index, const GLdouble *v) {PRECALL;glVertexAttrib2dv(index, v);POSTCALL;}
1472 void wrapglVertexAttrib3fv(GLuint index, const GLfloat *v) {PRECALL;glVertexAttrib3fv(index, v);POSTCALL;}
1473 //void wrapglVertexAttrib3sv(GLuint index, const GLshort *v) {PRECALL;glVertexAttrib3sv(index, v);POSTCALL;}
1474 //void wrapglVertexAttrib3dv(GLuint index, const GLdouble *v) {PRECALL;glVertexAttrib3dv(index, v);POSTCALL;}
1475 void wrapglVertexAttrib4fv(GLuint index, const GLfloat *v) {PRECALL;glVertexAttrib4fv(index, v);POSTCALL;}
1476 //void wrapglVertexAttrib4sv(GLuint index, const GLshort *v) {PRECALL;glVertexAttrib4sv(index, v);POSTCALL;}
1477 //void wrapglVertexAttrib4dv(GLuint index, const GLdouble *v) {PRECALL;glVertexAttrib4dv(index, v);POSTCALL;}
1478 //void wrapglVertexAttrib4iv(GLuint index, const GLint *v) {PRECALL;glVertexAttrib4iv(index, v);POSTCALL;}
1479 //void wrapglVertexAttrib4bv(GLuint index, const GLbyte *v) {PRECALL;glVertexAttrib4bv(index, v);POSTCALL;}
1480 //void wrapglVertexAttrib4ubv(GLuint index, const GLubyte *v) {PRECALL;glVertexAttrib4ubv(index, v);POSTCALL;}
1481 //void wrapglVertexAttrib4usv(GLuint index, const GLushort *v) {PRECALL;glVertexAttrib4usv(index, GLushort v);POSTCALL;}
1482 //void wrapglVertexAttrib4uiv(GLuint index, const GLuint *v) {PRECALL;glVertexAttrib4uiv(index, v);POSTCALL;}
1483 //void wrapglVertexAttrib4Nbv(GLuint index, const GLbyte *v) {PRECALL;glVertexAttrib4Nbv(index, v);POSTCALL;}
1484 //void wrapglVertexAttrib4Nsv(GLuint index, const GLshort *v) {PRECALL;glVertexAttrib4Nsv(index, v);POSTCALL;}
1485 //void wrapglVertexAttrib4Niv(GLuint index, const GLint *v) {PRECALL;glVertexAttrib4Niv(index, v);POSTCALL;}
1486 //void wrapglVertexAttrib4Nubv(GLuint index, const GLubyte *v) {PRECALL;glVertexAttrib4Nubv(index, v);POSTCALL;}
1487 //void wrapglVertexAttrib4Nusv(GLuint index, const GLushort *v) {PRECALL;glVertexAttrib4Nusv(index, GLushort v);POSTCALL;}
1488 //void wrapglVertexAttrib4Nuiv(GLuint index, const GLuint *v) {PRECALL;glVertexAttrib4Nuiv(index, v);POSTCALL;}
1489 //void wrapglGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) {PRECALL;glGetVertexAttribdv(index, pname, params);POSTCALL;}
1490 void wrapglGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params) {PRECALL;glGetVertexAttribfv(index, pname, params);POSTCALL;}
1491 void wrapglGetVertexAttribiv(GLuint index, GLenum pname, GLint *params) {PRECALL;glGetVertexAttribiv(index, pname, params);POSTCALL;}
1492 void wrapglGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer) {PRECALL;glGetVertexAttribPointerv(index, pname, pointer);POSTCALL;}
1495 void GLES_Init(void)
1498 qglIsBufferARB = wrapglIsBuffer;
1499 qglIsEnabled = wrapglIsEnabled;
1500 qglIsFramebufferEXT = wrapglIsFramebuffer;
1501 // qglIsQueryARB = wrapglIsQuery;
1502 qglIsRenderbufferEXT = wrapglIsRenderbuffer;
1503 // qglUnmapBufferARB = wrapglUnmapBuffer;
1504 qglCheckFramebufferStatus = wrapglCheckFramebufferStatus;
1505 qglGetError = wrapglGetError;
1506 qglCreateProgram = wrapglCreateProgram;
1507 qglCreateShader = wrapglCreateShader;
1508 // qglGetHandleARB = wrapglGetHandle;
1509 qglGetAttribLocation = wrapglGetAttribLocation;
1510 qglGetUniformLocation = wrapglGetUniformLocation;
1511 // qglMapBufferARB = wrapglMapBuffer;
1512 qglGetString = wrapglGetString;
1513 // qglActiveStencilFaceEXT = wrapglActiveStencilFace;
1514 qglActiveTexture = wrapglActiveTexture;
1515 qglArrayElement = wrapglArrayElement;
1516 qglAttachShader = wrapglAttachShader;
1517 // qglBeginQueryARB = wrapglBeginQuery;
1518 qglBindAttribLocation = wrapglBindAttribLocation;
1519 // qglBindFragDataLocation = wrapglBindFragDataLocation;
1520 qglBindBufferARB = wrapglBindBuffer;
1521 qglBindFramebuffer = wrapglBindFramebuffer;
1522 qglBindRenderbuffer = wrapglBindRenderbuffer;
1523 qglBindTexture = wrapglBindTexture;
1524 qglBlendEquationEXT = wrapglBlendEquation;
1525 qglBlendFunc = wrapglBlendFunc;
1526 qglBufferDataARB = wrapglBufferData;
1527 qglBufferSubDataARB = wrapglBufferSubData;
1528 qglClear = wrapglClear;
1529 qglClearColor = wrapglClearColor;
1530 qglClearDepth = wrapglClearDepth;
1531 qglClearStencil = wrapglClearStencil;
1532 qglColorMask = wrapglColorMask;
1533 qglCompileShader = wrapglCompileShader;
1534 qglCompressedTexImage2DARB = wrapglCompressedTexImage2D;
1535 qglCompressedTexImage3DARB = wrapglCompressedTexImage3D;
1536 qglCompressedTexSubImage2DARB = wrapglCompressedTexSubImage2D;
1537 qglCompressedTexSubImage3DARB = wrapglCompressedTexSubImage3D;
1538 qglCopyTexImage2D = wrapglCopyTexImage2D;
1539 qglCopyTexSubImage2D = wrapglCopyTexSubImage2D;
1540 qglCopyTexSubImage3D = wrapglCopyTexSubImage3D;
1541 qglCullFace = wrapglCullFace;
1542 qglDeleteBuffersARB = wrapglDeleteBuffers;
1543 qglDeleteFramebuffers = wrapglDeleteFramebuffers;
1544 qglDeleteProgram = wrapglDeleteProgram;
1545 qglDeleteShader = wrapglDeleteShader;
1546 // qglDeleteQueriesARB = wrapglDeleteQueries;
1547 qglDeleteRenderbuffers = wrapglDeleteRenderbuffers;
1548 qglDeleteTextures = wrapglDeleteTextures;
1549 qglDepthFunc = wrapglDepthFunc;
1550 qglDepthMask = wrapglDepthMask;
1551 qglDepthRangef = wrapglDepthRangef;
1552 qglDetachShader = wrapglDetachShader;
1553 qglDisable = wrapglDisable;
1554 qglDisableVertexAttribArray = wrapglDisableVertexAttribArray;
1555 qglDrawArrays = wrapglDrawArrays;
1556 // qglDrawBuffer = wrapglDrawBuffer;
1557 // qglDrawBuffersARB = wrapglDrawBuffers;
1558 qglDrawElements = wrapglDrawElements;
1559 // qglDrawRangeElements = wrapglDrawRangeElements;
1560 qglEnable = wrapglEnable;
1561 qglEnableVertexAttribArray = wrapglEnableVertexAttribArray;
1562 // qglEndQueryARB = wrapglEndQuery;
1563 qglFinish = wrapglFinish;
1564 qglFlush = wrapglFlush;
1565 qglFramebufferRenderbufferEXT = wrapglFramebufferRenderbuffer;
1566 qglFramebufferTexture2DEXT = wrapglFramebufferTexture2D;
1567 qglFramebufferTexture3DEXT = wrapglFramebufferTexture3D;
1568 qglGenBuffersARB = wrapglGenBuffers;
1569 qglGenFramebuffers = wrapglGenFramebuffers;
1570 // qglGenQueriesARB = wrapglGenQueries;
1571 qglGenRenderbuffers = wrapglGenRenderbuffers;
1572 qglGenTextures = wrapglGenTextures;
1573 qglGenerateMipmapEXT = wrapglGenerateMipmap;
1574 qglGetActiveAttrib = wrapglGetActiveAttrib;
1575 qglGetActiveUniform = wrapglGetActiveUniform;
1576 qglGetAttachedShaders = wrapglGetAttachedShaders;
1577 qglGetBooleanv = wrapglGetBooleanv;
1578 // qglGetCompressedTexImageARB = wrapglGetCompressedTexImage;
1579 qglGetDoublev = wrapglGetDoublev;
1580 qglGetFloatv = wrapglGetFloatv;
1581 qglGetFramebufferAttachmentParameterivEXT = wrapglGetFramebufferAttachmentParameteriv;
1582 qglGetProgramInfoLog = wrapglGetProgramInfoLog;
1583 qglGetShaderInfoLog = wrapglGetShaderInfoLog;
1584 qglGetIntegerv = wrapglGetIntegerv;
1585 qglGetShaderiv = wrapglGetShaderiv;
1586 qglGetProgramiv = wrapglGetProgramiv;
1587 // qglGetQueryObjectivARB = wrapglGetQueryObjectiv;
1588 // qglGetQueryObjectuivARB = wrapglGetQueryObjectuiv;
1589 // qglGetQueryivARB = wrapglGetQueryiv;
1590 qglGetRenderbufferParameterivEXT = wrapglGetRenderbufferParameteriv;
1591 qglGetShaderSource = wrapglGetShaderSource;
1592 qglGetTexImage = wrapglGetTexImage;
1593 qglGetTexLevelParameterfv = wrapglGetTexLevelParameterfv;
1594 qglGetTexLevelParameteriv = wrapglGetTexLevelParameteriv;
1595 qglGetTexParameterfv = wrapglGetTexParameterfv;
1596 qglGetTexParameteriv = wrapglGetTexParameteriv;
1597 qglGetUniformfv = wrapglGetUniformfv;
1598 qglGetUniformiv = wrapglGetUniformiv;
1599 qglHint = wrapglHint;
1600 qglLinkProgram = wrapglLinkProgram;
1601 qglPixelStorei = wrapglPixelStorei;
1602 qglPointSize = wrapglPointSize;
1603 // qglPolygonMode = wrapglPolygonMode;
1604 qglPolygonOffset = wrapglPolygonOffset;
1605 // qglPolygonStipple = wrapglPolygonStipple;
1606 qglReadBuffer = wrapglReadBuffer;
1607 qglReadPixels = wrapglReadPixels;
1608 qglRenderbufferStorage = wrapglRenderbufferStorage;
1609 qglScissor = wrapglScissor;
1610 qglShaderSource = wrapglShaderSource;
1611 qglStencilFunc = wrapglStencilFunc;
1612 qglStencilFuncSeparate = wrapglStencilFuncSeparate;
1613 qglStencilMask = wrapglStencilMask;
1614 qglStencilOp = wrapglStencilOp;
1615 qglStencilOpSeparate = wrapglStencilOpSeparate;
1616 qglTexImage2D = wrapglTexImage2D;
1617 qglTexImage3D = wrapglTexImage3D;
1618 qglTexParameterf = wrapglTexParameterf;
1619 qglTexParameterfv = wrapglTexParameterfv;
1620 qglTexParameteri = wrapglTexParameteri;
1621 qglTexSubImage2D = wrapglTexSubImage2D;
1622 qglTexSubImage3D = wrapglTexSubImage3D;
1623 qglUniform1f = wrapglUniform1f;
1624 qglUniform1fv = wrapglUniform1fv;
1625 qglUniform1i = wrapglUniform1i;
1626 qglUniform1iv = wrapglUniform1iv;
1627 qglUniform2f = wrapglUniform2f;
1628 qglUniform2fv = wrapglUniform2fv;
1629 qglUniform2i = wrapglUniform2i;
1630 qglUniform2iv = wrapglUniform2iv;
1631 qglUniform3f = wrapglUniform3f;
1632 qglUniform3fv = wrapglUniform3fv;
1633 qglUniform3i = wrapglUniform3i;
1634 qglUniform3iv = wrapglUniform3iv;
1635 qglUniform4f = wrapglUniform4f;
1636 qglUniform4fv = wrapglUniform4fv;
1637 qglUniform4i = wrapglUniform4i;
1638 qglUniform4iv = wrapglUniform4iv;
1639 qglUniformMatrix2fv = wrapglUniformMatrix2fv;
1640 qglUniformMatrix3fv = wrapglUniformMatrix3fv;
1641 qglUniformMatrix4fv = wrapglUniformMatrix4fv;
1642 qglUseProgram = wrapglUseProgram;
1643 qglValidateProgram = wrapglValidateProgram;
1644 qglVertex2f = wrapglVertex2f;
1645 qglVertex3f = wrapglVertex3f;
1646 qglVertex4f = wrapglVertex4f;
1647 qglVertexAttribPointer = wrapglVertexAttribPointer;
1648 qglVertexPointer = wrapglVertexPointer;
1649 qglViewport = wrapglViewport;
1650 qglVertexAttrib1f = wrapglVertexAttrib1f;
1651 // qglVertexAttrib1s = wrapglVertexAttrib1s;
1652 // qglVertexAttrib1d = wrapglVertexAttrib1d;
1653 qglVertexAttrib2f = wrapglVertexAttrib2f;
1654 // qglVertexAttrib2s = wrapglVertexAttrib2s;
1655 // qglVertexAttrib2d = wrapglVertexAttrib2d;
1656 qglVertexAttrib3f = wrapglVertexAttrib3f;
1657 // qglVertexAttrib3s = wrapglVertexAttrib3s;
1658 // qglVertexAttrib3d = wrapglVertexAttrib3d;
1659 qglVertexAttrib4f = wrapglVertexAttrib4f;
1660 // qglVertexAttrib4s = wrapglVertexAttrib4s;
1661 // qglVertexAttrib4d = wrapglVertexAttrib4d;
1662 // qglVertexAttrib4Nub = wrapglVertexAttrib4Nub;
1663 qglVertexAttrib1fv = wrapglVertexAttrib1fv;
1664 // qglVertexAttrib1sv = wrapglVertexAttrib1sv;
1665 // qglVertexAttrib1dv = wrapglVertexAttrib1dv;
1666 qglVertexAttrib2fv = wrapglVertexAttrib2fv;
1667 // qglVertexAttrib2sv = wrapglVertexAttrib2sv;
1668 // qglVertexAttrib2dv = wrapglVertexAttrib2dv;
1669 qglVertexAttrib3fv = wrapglVertexAttrib3fv;
1670 // qglVertexAttrib3sv = wrapglVertexAttrib3sv;
1671 // qglVertexAttrib3dv = wrapglVertexAttrib3dv;
1672 qglVertexAttrib4fv = wrapglVertexAttrib4fv;
1673 // qglVertexAttrib4sv = wrapglVertexAttrib4sv;
1674 // qglVertexAttrib4dv = wrapglVertexAttrib4dv;
1675 // qglVertexAttrib4iv = wrapglVertexAttrib4iv;
1676 // qglVertexAttrib4bv = wrapglVertexAttrib4bv;
1677 // qglVertexAttrib4ubv = wrapglVertexAttrib4ubv;
1678 // qglVertexAttrib4usv = wrapglVertexAttrib4usv;
1679 // qglVertexAttrib4uiv = wrapglVertexAttrib4uiv;
1680 // qglVertexAttrib4Nbv = wrapglVertexAttrib4Nbv;
1681 // qglVertexAttrib4Nsv = wrapglVertexAttrib4Nsv;
1682 // qglVertexAttrib4Niv = wrapglVertexAttrib4Niv;
1683 // qglVertexAttrib4Nubv = wrapglVertexAttrib4Nubv;
1684 // qglVertexAttrib4Nusv = wrapglVertexAttrib4Nusv;
1685 // qglVertexAttrib4Nuiv = wrapglVertexAttrib4Nuiv;
1686 // qglGetVertexAttribdv = wrapglGetVertexAttribdv;
1687 qglGetVertexAttribfv = wrapglGetVertexAttribfv;
1688 qglGetVertexAttribiv = wrapglGetVertexAttribiv;
1689 qglGetVertexAttribPointerv = wrapglGetVertexAttribPointerv;
1692 gl_renderer = (const char *)qglGetString(GL_RENDERER);
1693 gl_vendor = (const char *)qglGetString(GL_VENDOR);
1694 gl_version = (const char *)qglGetString(GL_VERSION);
1695 gl_extensions = (const char *)qglGetString(GL_EXTENSIONS);
1699 if (!gl_platformextensions)
1700 gl_platformextensions = "";
1702 Con_Printf("GL_VENDOR: %s\n", gl_vendor);
1703 Con_Printf("GL_RENDERER: %s\n", gl_renderer);
1704 Con_Printf("GL_VERSION: %s\n", gl_version);
1705 Con_DPrintf("GL_EXTENSIONS: %s\n", gl_extensions);
1706 Con_DPrintf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions);
1708 // LordHavoc: report supported extensions
1709 Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions );
1711 // GLES devices in general do not like GL_BGRA, so use GL_RGBA
1712 vid.forcetextype = TEXTYPE_RGBA;
1714 vid.support.gl20shaders = true;
1715 vid.support.amd_texture_texture4 = false;
1716 vid.support.arb_depth_texture = SDL_GL_ExtensionSupported("GL_OES_depth_texture") != 0; // renderbuffer used anyway on gles2?
1717 vid.support.arb_draw_buffers = false;
1718 vid.support.arb_multitexture = false;
1719 vid.support.arb_occlusion_query = false;
1720 vid.support.arb_query_buffer_object = false;
1721 vid.support.arb_shadow = false;
1722 vid.support.arb_texture_compression = false; // different (vendor-specific) formats than on desktop OpenGL...
1723 vid.support.arb_texture_cube_map = SDL_GL_ExtensionSupported("GL_OES_texture_cube_map") != 0;
1724 vid.support.arb_texture_env_combine = false;
1725 vid.support.arb_texture_gather = false;
1726 vid.support.arb_texture_non_power_of_two = strstr(gl_extensions, "GL_OES_texture_npot") != NULL;
1727 vid.support.arb_vertex_buffer_object = true; // GLES2 core
1728 vid.support.ext_blend_minmax = false;
1729 vid.support.ext_blend_subtract = true; // GLES2 core
1730 vid.support.ext_blend_func_separate = true; // GLES2 core
1731 vid.support.ext_draw_range_elements = false;
1734 Note: "In OS 2.1, the functions in GL_OES_framebuffer_object were not usable from the Java API.
1735 Calling them just threw an exception. Android developer relations confirmed that they forgot to implement these. (yeah...)
1736 It's apparently been fixed in 2.2, though I haven't tested."
1738 // LadyHavoc: Android 2.1 is way old now, enabling this again, it's going to be required soon.
1739 vid.support.ext_framebuffer_object = true;
1741 vid.support.ext_packed_depth_stencil = false;
1742 vid.support.ext_texture_3d = SDL_GL_ExtensionSupported("GL_OES_texture_3D") != 0;
1743 vid.support.ext_texture_compression_s3tc = SDL_GL_ExtensionSupported("GL_EXT_texture_compression_s3tc") != 0;
1744 vid.support.ext_texture_edge_clamp = true; // GLES2 core
1745 vid.support.ext_texture_filter_anisotropic = false; // probably don't want to use it...
1746 vid.support.ext_texture_srgb = false;
1747 vid.support.arb_texture_float = SDL_GL_ExtensionSupported("GL_OES_texture_float") != 0;
1748 vid.support.arb_half_float_pixel = SDL_GL_ExtensionSupported("GL_OES_texture_half_float") != 0;
1749 vid.support.arb_half_float_vertex = SDL_GL_ExtensionSupported("GL_OES_vertex_half_float") != 0;
1751 // NOTE: On some devices, a value of 512 gives better FPS than the maximum.
1752 qglGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_2d);
1754 #ifdef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
1755 if (vid.support.ext_texture_filter_anisotropic)
1756 qglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, (GLint*)&vid.max_anisotropy);
1758 if (vid.support.arb_texture_cube_map)
1759 qglGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_cubemap);
1760 #ifdef GL_MAX_3D_TEXTURE_SIZE
1761 if (vid.support.ext_texture_3d)
1762 qglGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_3d);
1764 Con_Printf("GL_MAX_CUBE_MAP_TEXTURE_SIZE = %i\n", vid.maxtexturesize_cubemap);
1765 Con_Printf("GL_MAX_3D_TEXTURE_SIZE = %i\n", vid.maxtexturesize_3d);
1767 #define GL_ALPHA_BITS 0x0D55
1768 #define GL_RED_BITS 0x0D52
1769 #define GL_GREEN_BITS 0x0D53
1770 #define GL_BLUE_BITS 0x0D54
1771 #define GL_DEPTH_BITS 0x0D56
1772 #define GL_STENCIL_BITS 0x0D57
1773 int fb_r = -1, fb_g = -1, fb_b = -1, fb_a = -1, fb_d = -1, fb_s = -1;
1774 qglGetIntegerv(GL_RED_BITS , &fb_r);
1775 qglGetIntegerv(GL_GREEN_BITS , &fb_g);
1776 qglGetIntegerv(GL_BLUE_BITS , &fb_b);
1777 qglGetIntegerv(GL_ALPHA_BITS , &fb_a);
1778 qglGetIntegerv(GL_DEPTH_BITS , &fb_d);
1779 qglGetIntegerv(GL_STENCIL_BITS, &fb_s);
1780 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);
1783 // verify that cubemap textures are really supported
1784 if (vid.support.arb_texture_cube_map && vid.maxtexturesize_cubemap < 256)
1785 vid.support.arb_texture_cube_map = false;
1787 // verify that 3d textures are really supported
1788 if (vid.support.ext_texture_3d && vid.maxtexturesize_3d < 32)
1790 vid.support.ext_texture_3d = false;
1791 Con_Printf("GL_OES_texture_3d reported bogus GL_MAX_3D_TEXTURE_SIZE, disabled\n");
1795 vid.teximageunits = 8;
1796 vid.texarrayunits = 5;
1797 //qglGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&vid.texunits);
1798 qglGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, (GLint*)&vid.teximageunits);CHECKGLERROR
1799 //qglGetIntegerv(GL_MAX_TEXTURE_COORDS, (GLint*)&vid.texarrayunits);CHECKGLERROR
1800 vid.texunits = bound(1, vid.texunits, MAX_TEXTUREUNITS);
1801 vid.teximageunits = bound(1, vid.teximageunits, MAX_TEXTUREUNITS);
1802 vid.texarrayunits = bound(1, vid.texarrayunits, MAX_TEXTUREUNITS);
1803 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" : "");
1804 vid.renderpath = RENDERPATH_GLES2;
1805 vid.sRGBcapable2D = false;
1806 vid.sRGBcapable3D = false;
1808 // VorteX: set other info (maybe place them in VID_InitMode?)
1809 extern cvar_t gl_info_vendor;
1810 extern cvar_t gl_info_renderer;
1811 extern cvar_t gl_info_version;
1812 extern cvar_t gl_info_platform;
1813 extern cvar_t gl_info_driver;
1814 Cvar_SetQuick(&gl_info_vendor, gl_vendor);
1815 Cvar_SetQuick(&gl_info_renderer, gl_renderer);
1816 Cvar_SetQuick(&gl_info_version, gl_version);
1817 Cvar_SetQuick(&gl_info_platform, gl_platform ? gl_platform : "");
1818 Cvar_SetQuick(&gl_info_driver, gl_driver);
1822 void *GL_GetProcAddress(const char *name)
1825 p = SDL_GL_GetProcAddress(name);
1829 static qboolean vid_sdl_initjoysticksystem = false;
1831 void VID_Init (void)
1833 #ifndef __IPHONEOS__
1835 Cvar_RegisterVariable(&apple_mouse_noaccel);
1838 #ifdef DP_MOBILETOUCH
1839 Cvar_SetValueQuick(&vid_touchscreen, 1);
1842 #ifdef SDL_R_RESTART
1843 R_RegisterModule("SDL", sdl_start, sdl_shutdown, sdl_newmap, NULL, NULL);
1846 if (SDL_Init(SDL_INIT_VIDEO) < 0)
1847 Sys_Error ("Failed to init SDL video subsystem: %s", SDL_GetError());
1848 vid_sdl_initjoysticksystem = SDL_InitSubSystem(SDL_INIT_JOYSTICK) >= 0;
1849 if (vid_sdl_initjoysticksystem)
1850 Con_Printf("Failed to init SDL joystick subsystem: %s\n", SDL_GetError());
1851 vid_isfullscreen = false;
1854 static int vid_sdljoystickindex = -1;
1855 void VID_EnableJoystick(qboolean enable)
1857 int index = joy_enable.integer > 0 ? joy_index.integer : -1;
1858 int numsdljoysticks;
1859 qboolean success = false;
1860 int sharedcount = 0;
1862 sharedcount = VID_Shared_SetJoystick(index);
1863 if (index >= 0 && index < sharedcount)
1865 sdlindex = index - sharedcount;
1867 numsdljoysticks = SDL_NumJoysticks();
1868 if (sdlindex < 0 || sdlindex >= numsdljoysticks)
1871 // update cvar containing count of XInput joysticks + SDL joysticks
1872 if (joy_detected.integer != sharedcount + numsdljoysticks)
1873 Cvar_SetValueQuick(&joy_detected, sharedcount + numsdljoysticks);
1875 if (vid_sdljoystickindex != sdlindex)
1877 vid_sdljoystickindex = sdlindex;
1878 // close SDL joystick if active
1879 if (vid_sdljoystick)
1880 SDL_JoystickClose(vid_sdljoystick);
1881 vid_sdljoystick = NULL;
1884 vid_sdljoystick = SDL_JoystickOpen(sdlindex);
1885 if (vid_sdljoystick)
1887 const char *joystickname = SDL_JoystickName(vid_sdljoystick);
1888 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));
1892 Con_Printf("Joystick %i failed (SDL_JoystickOpen(%i) returned: %s)\n", index, sdlindex, SDL_GetError());
1901 if (joy_active.integer != (success ? 1 : 0))
1902 Cvar_SetValueQuick(&joy_active, success ? 1 : 0);
1905 static void VID_OutputVersion(void)
1907 SDL_version version;
1908 SDL_GetVersion(&version);
1909 Con_Printf( "Linked against SDL version %d.%d.%d\n"
1910 "Using SDL library version %d.%d.%d\n",
1911 SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL,
1912 version.major, version.minor, version.patch );
1916 static void AdjustWindowBounds(viddef_mode_t *mode, RECT *rect)
1918 LONG width = mode->width; // vid_width
1919 LONG height = mode->height; // vid_height
1921 // adjust width and height for the space occupied by window decorators (title bar, borders)
1924 rect->right = width;
1925 rect->bottom = height;
1926 AdjustWindowRectEx(rect, WS_CAPTION|WS_THICKFRAME, false, 0);
1929 SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0);
1930 int workWidth = workArea.right - workArea.left;
1931 int workHeight = workArea.bottom - workArea.top;
1933 // SDL forces the window height to be <= screen height - 27px (on Win8.1 - probably intended for the title bar)
1934 // If the task bar is docked to the the left screen border and we move the window to negative y,
1935 // there would be some part of the regular desktop visible on the bottom of the screen.
1936 int titleBarPixels = 2;
1937 int screenHeight = GetSystemMetrics(SM_CYSCREEN);
1938 if (screenHeight == workHeight)
1939 titleBarPixels = -rect->top;
1941 //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);
1943 // if height and width matches the physical or previously adjusted screen height and width, adjust it to available desktop area
1944 if ((width == GetSystemMetrics(SM_CXSCREEN) || width == workWidth) && (height == screenHeight || height == workHeight - titleBarPixels))
1946 rect->left = workArea.left;
1947 mode->width = workWidth;
1948 rect->top = workArea.top + titleBarPixels;
1949 mode->height = workHeight - titleBarPixels;
1953 rect->left = workArea.left + max(0, (workWidth - width) / 2);
1954 rect->top = workArea.top + max(0, (workHeight - height) / 2);
1959 static qboolean VID_InitModeGL(viddef_mode_t *mode)
1961 int windowflags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL;
1962 int xPos = SDL_WINDOWPOS_UNDEFINED;
1963 int yPos = SDL_WINDOWPOS_UNDEFINED;
1966 const char *drivername;
1969 win_half_width = mode->width>>1;
1970 win_half_height = mode->height>>1;
1972 if(vid_resizable.integer)
1973 windowflags |= SDL_WINDOW_RESIZABLE;
1975 VID_OutputVersion();
1978 // SDL usually knows best
1981 // 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
1982 i = COM_CheckParm("-gl_driver");
1983 if (i && i < com_argc - 1)
1984 drivername = com_argv[i + 1];
1985 if (SDL_GL_LoadLibrary(drivername) < 0)
1987 Con_Printf("Unable to load GL driver \"%s\": %s\n", drivername, SDL_GetError());
1992 #ifdef DP_MOBILETOUCH
1993 // mobile platforms are always fullscreen, we'll get the resolution after opening the window
1994 mode->fullscreen = true;
1995 // hide the menu with SDL_WINDOW_BORDERLESS
1996 windowflags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS;
1999 if ((qglGetString = (const GLubyte* (GLAPIENTRY *)(GLenum name))GL_GetProcAddress("glGetString")) == NULL)
2002 Con_Print("Required OpenGL function glGetString not found\n");
2007 // Knghtbrd: should do platform-specific extension string function here
2009 vid_isfullscreen = false;
2011 if (mode->fullscreen) {
2012 if (vid_desktopfullscreen.integer)
2014 vid_mode_t *m = VID_GetDesktopMode();
2015 mode->width = m->width;
2016 mode->height = m->height;
2017 windowflags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
2020 windowflags |= SDL_WINDOW_FULLSCREEN;
2021 vid_isfullscreen = true;
2026 AdjustWindowBounds(mode, &rect);
2032 //flags |= SDL_HWSURFACE;
2034 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
2035 SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 8);
2036 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 8);
2037 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 8);
2038 SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, 8);
2039 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 24);
2040 SDL_GL_SetAttribute (SDL_GL_STENCIL_SIZE, 8);
2041 if (mode->stereobuffer)
2042 SDL_GL_SetAttribute (SDL_GL_STEREO, 1);
2043 if (mode->samples > 1)
2045 SDL_GL_SetAttribute (SDL_GL_MULTISAMPLEBUFFERS, 1);
2046 SDL_GL_SetAttribute (SDL_GL_MULTISAMPLESAMPLES, mode->samples);
2050 SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
2051 SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0);
2052 SDL_GL_SetAttribute (SDL_GL_RETAINED_BACKING, 1);
2054 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
2055 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
2058 video_bpp = mode->bitsperpixel;
2059 window_flags = windowflags;
2060 window = SDL_CreateWindow(gamename, xPos, yPos, mode->width, mode->height, windowflags);
2063 Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError());
2067 SDL_GetWindowSize(window, &mode->width, &mode->height);
2068 context = SDL_GL_CreateContext(window);
2069 if (context == NULL)
2071 Con_Printf("Failed to initialize OpenGL context: %s\n", SDL_GetError());
2076 SDL_GL_SetSwapInterval(bound(-1, vid_vsync.integer, 1));
2077 vid_usingvsync = (vid_vsync.integer != 0);
2079 gl_platform = "SDL";
2080 gl_platformextensions = "";
2089 vid_activewindow = false;
2090 vid_hasfocus = true;
2091 vid_usingmouse = false;
2092 vid_usinghidecursor = false;
2097 extern cvar_t gl_info_extensions;
2098 extern cvar_t gl_info_vendor;
2099 extern cvar_t gl_info_renderer;
2100 extern cvar_t gl_info_version;
2101 extern cvar_t gl_info_platform;
2102 extern cvar_t gl_info_driver;
2104 qboolean VID_InitMode(viddef_mode_t *mode)
2106 // GAME_STEELSTORM specific
2107 steelstorm_showing_map = Cvar_FindVar("steelstorm_showing_map");
2108 steelstorm_showing_mousecursor = Cvar_FindVar("steelstorm_showing_mousecursor");
2110 if (!SDL_WasInit(SDL_INIT_VIDEO) && SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
2111 Sys_Error ("Failed to init SDL video subsystem: %s", SDL_GetError());
2113 Cvar_SetValueQuick(&vid_touchscreen_supportshowkeyboard, SDL_HasScreenKeyboardSupport() ? 1 : 0);
2114 return VID_InitModeGL(mode);
2117 void VID_Shutdown (void)
2119 VID_EnableJoystick(false);
2120 VID_SetMouse(false, false, false);
2122 SDL_DestroyWindow(window);
2125 SDL_QuitSubSystem(SDL_INIT_VIDEO);
2130 gl_platformextensions = "";
2133 void VID_Finish (void)
2135 qboolean vid_usevsync;
2136 vid_activewindow = !vid_hidden && vid_hasfocus;
2142 switch(vid.renderpath)
2144 case RENDERPATH_GL20:
2145 case RENDERPATH_GLES2:
2147 if (r_speeds.integer == 2 || gl_finish.integer)
2150 vid_usevsync = (vid_vsync.integer && !cls.timedemo);
2151 if (vid_usingvsync != vid_usevsync)
2153 vid_usingvsync = vid_usevsync;
2154 if (SDL_GL_SetSwapInterval(vid_usevsync != 0) >= 0)
2155 Con_DPrintf("Vsync %s\n", vid_usevsync ? "activated" : "deactivated");
2157 Con_DPrintf("ERROR: can't %s vsync\n", vid_usevsync ? "activate" : "deactivate");
2159 SDL_GL_SwapWindow(window);
2165 vid_mode_t *VID_GetDesktopMode(void)
2167 SDL_DisplayMode mode;
2169 Uint32 rmask, gmask, bmask, amask;
2170 SDL_GetDesktopDisplayMode(0, &mode);
2171 SDL_PixelFormatEnumToMasks(mode.format, &bpp, &rmask, &gmask, &bmask, &amask);
2172 desktop_mode.width = mode.w;
2173 desktop_mode.height = mode.h;
2174 desktop_mode.bpp = bpp;
2175 desktop_mode.refreshrate = mode.refresh_rate;
2176 desktop_mode.pixelheight_num = 1;
2177 desktop_mode.pixelheight_denom = 1; // SDL does not provide this
2178 // TODO check whether this actually works, or whether we do still need
2179 // a read-window-size-after-entering-desktop-fullscreen hack for
2180 // multiscreen setups.
2181 return &desktop_mode;
2184 size_t VID_ListModes(vid_mode_t *modes, size_t maxcount)
2188 int nummodes = SDL_GetNumDisplayModes(0);
2189 SDL_DisplayMode mode;
2190 for (modenum = 0;modenum < nummodes;modenum++)
2194 if (SDL_GetDisplayMode(0, modenum, &mode))
2196 modes[k].width = mode.w;
2197 modes[k].height = mode.h;
2199 modes[k].refreshrate = mode.refresh_rate;
2200 modes[k].pixelheight_num = 1;
2201 modes[k].pixelheight_denom = 1; // SDL does not provide this