X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=vid_sdl.c;h=4fb37539e4a4117ae4c95e8e0a69a6d93e61e2e7;hb=94a5be97432b0a538c0200cd0c837253b65633bf;hp=e7b770d6400252a8ac909be69eaddc14dd207c05;hpb=7553655597e4e22766b9ed2394896a2a6905fc32;p=xonotic%2Fdarkplaces.git diff --git a/vid_sdl.c b/vid_sdl.c index e7b770d6..4fb37539 100644 --- a/vid_sdl.c +++ b/vid_sdl.c @@ -66,34 +66,7 @@ int cl_available = true; qboolean vid_supportrefreshrate = false; -cvar_t vid_soft = {CVAR_SAVE, "vid_soft", "0", "enables use of the DarkPlaces Software Rasterizer rather than OpenGL or Direct3D"}; -cvar_t vid_soft_threads = {CVAR_SAVE, "vid_soft_threads", "2", "the number of threads the DarkPlaces Software Rasterizer should use"}; -cvar_t vid_soft_interlace = {CVAR_SAVE, "vid_soft_interlace", "1", "whether the DarkPlaces Software Rasterizer should interlace the screen bands occupied by each thread"}; -cvar_t joy_detected = {CVAR_READONLY, "joy_detected", "0", "number of joysticks detected by engine"}; -cvar_t joy_enable = {CVAR_SAVE, "joy_enable", "0", "enables joystick support"}; -cvar_t joy_index = {0, "joy_index", "0", "selects which joystick to use if you have multiple"}; -cvar_t joy_axisforward = {0, "joy_axisforward", "1", "which joystick axis to query for forward/backward movement"}; -cvar_t joy_axisside = {0, "joy_axisside", "0", "which joystick axis to query for right/left movement"}; -cvar_t joy_axisup = {0, "joy_axisup", "-1", "which joystick axis to query for up/down movement"}; -cvar_t joy_axispitch = {0, "joy_axispitch", "3", "which joystick axis to query for looking up/down"}; -cvar_t joy_axisyaw = {0, "joy_axisyaw", "2", "which joystick axis to query for looking right/left"}; -cvar_t joy_axisroll = {0, "joy_axisroll", "-1", "which joystick axis to query for tilting head right/left"}; -cvar_t joy_deadzoneforward = {0, "joy_deadzoneforward", "0", "deadzone tolerance, suggested values are in the range 0 to 0.01"}; -cvar_t joy_deadzoneside = {0, "joy_deadzoneside", "0", "deadzone tolerance, suggested values are in the range 0 to 0.01"}; -cvar_t joy_deadzoneup = {0, "joy_deadzoneup", "0", "deadzone tolerance, suggested values are in the range 0 to 0.01"}; -cvar_t joy_deadzonepitch = {0, "joy_deadzonepitch", "0", "deadzone tolerance, suggested values are in the range 0 to 0.01"}; -cvar_t joy_deadzoneyaw = {0, "joy_deadzoneyaw", "0", "deadzone tolerance, suggested values are in the range 0 to 0.01"}; -cvar_t joy_deadzoneroll = {0, "joy_deadzoneroll", "0", "deadzone tolerance, suggested values are in the range 0 to 0.01"}; -cvar_t joy_sensitivityforward = {0, "joy_sensitivityforward", "-1", "movement multiplier"}; -cvar_t joy_sensitivityside = {0, "joy_sensitivityside", "1", "movement multiplier"}; -cvar_t joy_sensitivityup = {0, "joy_sensitivityup", "1", "movement multiplier"}; -cvar_t joy_sensitivitypitch = {0, "joy_sensitivitypitch", "1", "movement multiplier"}; -cvar_t joy_sensitivityyaw = {0, "joy_sensitivityyaw", "-1", "movement multiplier"}; -cvar_t joy_sensitivityroll = {0, "joy_sensitivityroll", "1", "movement multiplier"}; -cvar_t joy_axiskeyevents = {CVAR_SAVE, "joy_axiskeyevents", "0", "generate uparrow/leftarrow etc. keyevents for joystick axes, use if your joystick driver is not generating them"}; -cvar_t joy_axiskeyevents_deadzone = {CVAR_SAVE, "joy_axiskeyevents_deadzone", "0.5", "deadzone value for axes"}; - -#ifdef __IPHONEOS__ +#ifdef USE_GLES2 # define SETVIDEOMODE 0 #else # if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION == 2 @@ -114,9 +87,7 @@ static qboolean vid_isfullscreen; #else static qboolean vid_usingvsync = false; #endif -static int vid_numjoysticks = 0; -#define MAX_JOYSTICKS 8 -static SDL_Joystick *vid_joysticks[MAX_JOYSTICKS]; +static SDL_Joystick *vid_sdljoystick = NULL; static int win_half_width = 50; static int win_half_height = 50; @@ -132,20 +103,9 @@ static int window_flags; #endif static SDL_Surface *vid_softsurface; -// joystick axes state -#define MAX_JOYSTICK_AXES 16 -typedef struct -{ - float oldmove; - float move; - double keytime; -}joy_axiscache_t; -static joy_axiscache_t joy_axescache[MAX_JOYSTICK_AXES]; - ///////////////////////// // Input handling //// -//TODO: Add joystick support //TODO: Add error checking #ifndef SDLK_PERCENT @@ -521,80 +481,6 @@ void VID_SetMouse(qboolean fullscreengrab, qboolean relative, qboolean hidecurso #endif } -static double IN_JoystickGetAxis(SDL_Joystick *joy, int axis, double sensitivity, double deadzone) -{ - double value; - if (axis < 0 || axis >= SDL_JoystickNumAxes(joy)) - return 0; // no such axis on this joystick - value = SDL_JoystickGetAxis(joy, axis) * (1.0 / 32767.0); - value = bound(-1, value, 1); - if (fabs(value) < deadzone) - return 0; // within deadzone around center - return value * sensitivity; -} - -///////////////////// -// Joystick axis keyevents -// a sort of hack emulating Arrow keys for joystick axises -// as some drives dont send such keyevents for them -// additionally we should block drivers that do send arrow keyevents to prevent double events -//// - -static void IN_JoystickKeyeventForAxis(SDL_Joystick *joy, int axis, int key_pos, int key_neg) -{ - double joytime; - - if (axis < 0 || axis >= SDL_JoystickNumAxes(joy)) - return; // no such axis on this joystick - - joytime = Sys_DoubleTime(); - // no key event, continuous keydown event - if (joy_axescache[axis].move == joy_axescache[axis].oldmove) - { - if (joy_axescache[axis].move != 0 && joytime > joy_axescache[axis].keytime) - { - //Con_Printf("joy %s %i %f\n", Key_KeynumToString((joy_axescache[axis].move > 0) ? key_pos : key_neg), 1, cl.time); - Key_Event((joy_axescache[axis].move > 0) ? key_pos : key_neg, 0, 1); - joy_axescache[axis].keytime = joytime + 0.5 / 20; - } - return; - } - // generate key up event - if (joy_axescache[axis].oldmove) - { - //Con_Printf("joy %s %i %f\n", Key_KeynumToString((joy_axescache[axis].oldmove > 0) ? key_pos : key_neg), 1, cl.time); - Key_Event((joy_axescache[axis].oldmove > 0) ? key_pos : key_neg, 0, 0); - } - // generate key down event - if (joy_axescache[axis].move) - { - //Con_Printf("joy %s %i %f\n", Key_KeynumToString((joy_axescache[axis].move > 0) ? key_pos : key_neg), 1, cl.time); - Key_Event((joy_axescache[axis].move > 0) ? key_pos : key_neg, 0, 1); - joy_axescache[axis].keytime = joytime + 0.5; - } -} - -static qboolean IN_JoystickBlockDoubledKeyEvents(int keycode) -{ - if (!joy_axiskeyevents.integer) - return false; - - // block keyevent if it's going to be provided by joystick keyevent system - if (vid_numjoysticks && joy_enable.integer && joy_index.integer >= 0 && joy_index.integer < vid_numjoysticks) - { - SDL_Joystick *joy = vid_joysticks[joy_index.integer]; - - if (keycode == K_UPARROW || keycode == K_DOWNARROW) - if (IN_JoystickGetAxis(joy, joy_axisforward.integer, 1, joy_axiskeyevents_deadzone.value) || joy_axescache[joy_axisforward.integer].move || joy_axescache[joy_axisforward.integer].oldmove) - return true; - if (keycode == K_RIGHTARROW || keycode == K_LEFTARROW) - if (IN_JoystickGetAxis(joy, joy_axisside.integer, 1, joy_axiskeyevents_deadzone.value) || joy_axescache[joy_axisside.integer].move || joy_axescache[joy_axisside.integer].oldmove) - return true; - } - - return false; -} - // multitouch[10][] represents the mouse pointer // X and Y coordinates are 0-32767 as per SDL spec #define MAXFINGERS 11 @@ -659,16 +545,37 @@ qboolean VID_TouchscreenArea(int corner, float px, float py, float pwidth, float return button; } +void VID_BuildJoyState(vid_joystate_t *joystate) +{ + VID_Shared_BuildJoyState_Begin(joystate); + + if (vid_sdljoystick) + { + SDL_Joystick *joy = vid_sdljoystick; + int j; + int numaxes; + int numbuttons; + numaxes = SDL_JoystickNumAxes(joy); + for (j = 0;j < numaxes;j++) + joystate->axis[j] = SDL_JoystickGetAxis(joy, j) * (1.0f / 32767.0f); + numbuttons = SDL_JoystickNumButtons(joy); + for (j = 0;j < numbuttons;j++) + joystate->button[j] = SDL_JoystickGetButton(joy, j); + } + + VID_Shared_BuildJoyState_Finish(joystate); +} + ///////////////////// // Movement handling //// void IN_Move( void ) { - int j; static int old_x = 0, old_y = 0; static int stuck = 0; - int x, y, numaxes, numballs; + int x, y; + vid_joystate_t joystate; scr_numtouchscreenareas = 0; if (vid_touchscreen.integer) @@ -801,42 +708,8 @@ void IN_Move( void ) in_windowmouse_y = y; } - if (vid_numjoysticks && joy_enable.integer && joy_index.integer >= 0 && joy_index.integer < vid_numjoysticks) - { - SDL_Joystick *joy = vid_joysticks[joy_index.integer]; - - // balls convert to mousemove - numballs = SDL_JoystickNumBalls(joy); - for (j = 0;j < numballs;j++) - { - SDL_JoystickGetBall(joy, j, &x, &y); - in_mouse_x += x; - in_mouse_y += y; - } - - // axes - cl.cmd.forwardmove += IN_JoystickGetAxis(joy, joy_axisforward.integer, joy_sensitivityforward.value, joy_deadzoneforward.value) * cl_forwardspeed.value; - cl.cmd.sidemove += IN_JoystickGetAxis(joy, joy_axisside.integer, joy_sensitivityside.value, joy_deadzoneside.value) * cl_sidespeed.value; - cl.cmd.upmove += IN_JoystickGetAxis(joy, joy_axisup.integer, joy_sensitivityup.value, joy_deadzoneup.value) * cl_upspeed.value; - cl.viewangles[0] += IN_JoystickGetAxis(joy, joy_axispitch.integer, joy_sensitivitypitch.value, joy_deadzonepitch.value) * cl.realframetime * cl_pitchspeed.value; - cl.viewangles[1] += IN_JoystickGetAxis(joy, joy_axisyaw.integer, joy_sensitivityyaw.value, joy_deadzoneyaw.value) * cl.realframetime * cl_yawspeed.value; - //cl.viewangles[2] += IN_JoystickGetAxis(joy, joy_axisroll.integer, joy_sensitivityroll.value, joy_deadzoneroll.value) * cl.realframetime * cl_rollspeed.value; - - // cache state of axes to emulate button events for them - numaxes = min(MAX_JOYSTICK_AXES, SDL_JoystickNumAxes(joy)); - for (j = 0; j < numaxes; j++) - { - joy_axescache[j].oldmove = joy_axescache[j].move; - joy_axescache[j].move = IN_JoystickGetAxis(joy, j, 1, joy_axiskeyevents_deadzone.value); - } - - // run keyevents - if (joy_axiskeyevents.integer) - { - IN_JoystickKeyeventForAxis(joy, joy_axisforward.integer, K_DOWNARROW, K_UPARROW); - IN_JoystickKeyeventForAxis(joy, joy_axisside.integer, K_RIGHTARROW, K_LEFTARROW); - } - } + VID_BuildJoyState(&joystate); + VID_ApplyJoyState(&joystate); } ///////////////////// @@ -889,6 +762,8 @@ void Sys_SendKeyEvents( void ) int keycode; SDL_Event event; + VID_EnableJoystick(true); + while( SDL_PollEvent( &event ) ) switch( event.type ) { case SDL_QUIT: @@ -897,7 +772,7 @@ void Sys_SendKeyEvents( void ) case SDL_KEYDOWN: case SDL_KEYUP: keycode = MapKey(event.key.keysym.sym); - if (!IN_JoystickBlockDoubledKeyEvents(keycode)) + if (!VID_JoyBlockEmulatedKeys(keycode)) Key_Event(keycode, event.key.keysym.unicode, (event.key.state == SDL_PRESSED)); break; case SDL_ACTIVEEVENT: @@ -916,12 +791,7 @@ void Sys_SendKeyEvents( void ) Key_Event( buttonremap[event.button.button - 1], 0, event.button.state == SDL_PRESSED ); break; case SDL_JOYBUTTONDOWN: - if (!joy_enable.integer) - break; // ignore down events if joystick has been disabled case SDL_JOYBUTTONUP: - if (event.jbutton.button < 48) - Key_Event( event.jbutton.button + (event.jbutton.button < 16 ? K_JOY1 : K_AUX1 - 16), 0, (event.jbutton.state == SDL_PRESSED) ); - break; case SDL_JOYAXISMOTION: case SDL_JOYBALLMOTION: case SDL_JOYHATMOTION: @@ -1003,6 +873,8 @@ void Sys_SendKeyEvents( void ) int unicode; SDL_Event event; + VID_EnableJoystick(true); + while( SDL_PollEvent( &event ) ) switch( event.type ) { case SDL_QUIT: @@ -1011,33 +883,17 @@ void Sys_SendKeyEvents( void ) case SDL_KEYDOWN: case SDL_KEYUP: keycode = MapKey(event.key.keysym.sym); - if (!IN_JoystickBlockDoubledKeyEvents(keycode)) -#ifdef __IPHONEOS__ - // the virtual keyboard seems to produce no unicode values... - if (missingunicodehack && keycode >= ' ' && keycode < 0x7F && event.key.keysym.unicode == 0) - { - Con_DPrintf("SDL hack: no unicode value reported, substituting ascii value %i\n", keycode); - Key_Event(keycode, keycode, (event.key.state == SDL_PRESSED)); - } - else -#endif + if (!VID_JoyBlockEmulatedKeys(keycode)) Key_Event(keycode, 0, (event.key.state == SDL_PRESSED)); break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: -#ifndef __IPHONEOS__ if (!vid_touchscreen.integer) if (event.button.button <= 18) Key_Event( buttonremap[event.button.button - 1], 0, event.button.state == SDL_PRESSED ); -#endif break; case SDL_JOYBUTTONDOWN: - if (!joy_enable.integer) - break; // ignore down events if joystick has been disabled case SDL_JOYBUTTONUP: - if (event.jbutton.button < 48) - Key_Event( event.jbutton.button + (event.jbutton.button < 16 ? K_JOY1 : K_AUX1 - 16), 0, (event.jbutton.state == SDL_PRESSED) ); - break; case SDL_JOYAXISMOTION: case SDL_JOYBALLMOTION: case SDL_JOYHATMOTION: @@ -1187,15 +1043,6 @@ void Sys_SendKeyEvents( void ) case SDL_TOUCHBUTTONUP: // not sure what to do with this... break; - case SDL_JOYAXISMOTION: - // we poll the joystick instead - break; - case SDL_JOYBALLMOTION: - // we poll the joystick instead - break; - case SDL_JOYHATMOTION: - // we poll the joystick instead - break; default: Con_DPrintf("Received unrecognized SDL_Event type 0x%x\n", event.type); break; @@ -1225,9 +1072,12 @@ void Sys_SendKeyEvents( void ) // Video system //// +#ifdef USE_GLES2 #ifdef __IPHONEOS__ -//#include #include +#else +#include +#endif GLboolean wrapglIsBuffer(GLuint buffer) {return glIsBuffer(buffer);} GLboolean wrapglIsEnabled(GLenum cap) {return glIsEnabled(cap);} @@ -1249,7 +1099,7 @@ void wrapglActiveTexture(GLenum e) {glActiveTexture(e);} void wrapglAlphaFunc(GLenum func, GLclampf ref) {Con_Printf("glAlphaFunc(func, ref)\n");} void wrapglArrayElement(GLint i) {Con_Printf("glArrayElement(i)\n");} void wrapglAttachShader(GLuint containerObj, GLuint obj) {glAttachShader(containerObj, obj);} -void wrapglBegin(GLenum mode) {Con_Printf("glBegin(mode)\n");} +//void wrapglBegin(GLenum mode) {Con_Printf("glBegin(mode)\n");} //void wrapglBeginQuery(GLenum target, GLuint qid) {glBeginQuery(target, qid);} void wrapglBindAttribLocation(GLuint programObj, GLuint index, const GLchar *name) {glBindAttribLocation(programObj, index, name);} void wrapglBindFragDataLocation(GLuint programObj, GLuint index, const GLchar *name) {glBindFragDataLocation(programObj, index, name);} @@ -1302,7 +1152,7 @@ void wrapglDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *i void wrapglEnable(GLenum cap) {glEnable(cap);} void wrapglEnableClientState(GLenum cap) {Con_Printf("glEnableClientState(cap)\n");} void wrapglEnableVertexAttribArray(GLuint index) {glEnableVertexAttribArray(index);} -void wrapglEnd(void) {Con_Printf("glEnd()\n");} +//void wrapglEnd(void) {Con_Printf("glEnd()\n");} //void wrapglEndQuery(GLenum target) {glEndQuery(target);} void wrapglFinish(void) {glFinish();} void wrapglFlush(void) {glFlush();} @@ -1353,7 +1203,7 @@ void wrapglMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLflo void wrapglNormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr) {Con_Printf("glNormalPointer(type, stride, ptr)\n");} void wrapglPixelStorei(GLenum pname, GLint param) {glPixelStorei(pname, param);} void wrapglPointSize(GLfloat size) {Con_Printf("glPointSize(size)\n");} -void wrapglPolygonMode(GLenum face, GLenum mode) {Con_Printf("glPolygonMode(face, mode)\n");} +//void wrapglPolygonMode(GLenum face, GLenum mode) {Con_Printf("glPolygonMode(face, mode)\n");} void wrapglPolygonOffset(GLfloat factor, GLfloat units) {glPolygonOffset(factor, units);} void wrapglPolygonStipple(const GLubyte *mask) {Con_Printf("glPolygonStipple(mask)\n");} void wrapglReadBuffer(GLenum mode) {Con_Printf("glReadBuffer(mode)\n");} @@ -1471,7 +1321,7 @@ void GLES_Init(void) qglAlphaFunc = wrapglAlphaFunc; qglArrayElement = wrapglArrayElement; qglAttachShader = wrapglAttachShader; - qglBegin = wrapglBegin; +// qglBegin = wrapglBegin; // qglBeginQueryARB = wrapglBeginQuery; qglBindAttribLocation = wrapglBindAttribLocation; qglBindFragDataLocation = wrapglBindFragDataLocation; @@ -1523,7 +1373,7 @@ void GLES_Init(void) qglEnable = wrapglEnable; qglEnableClientState = wrapglEnableClientState; qglEnableVertexAttribArray = wrapglEnableVertexAttribArray; - qglEnd = wrapglEnd; +// qglEnd = wrapglEnd; // qglEndQueryARB = wrapglEndQuery; qglFinish = wrapglFinish; qglFlush = wrapglFlush; @@ -1574,7 +1424,7 @@ void GLES_Init(void) qglNormalPointer = wrapglNormalPointer; qglPixelStorei = wrapglPixelStorei; qglPointSize = wrapglPointSize; - qglPolygonMode = wrapglPolygonMode; +// qglPolygonMode = wrapglPolygonMode; qglPolygonOffset = wrapglPolygonOffset; // qglPolygonStipple = wrapglPolygonStipple; qglReadBuffer = wrapglReadBuffer; @@ -1688,6 +1538,9 @@ void GLES_Init(void) // LordHavoc: report supported extensions Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions ); + + // GLES devices in general do not like GL_BGRA, so use GL_RGBA + vid.forcetextype = TEXTYPE_RGBA; vid.support.gl20shaders = true; vid.support.amd_texture_texture4 = false; @@ -1712,6 +1565,7 @@ void GLES_Init(void) vid.support.ext_texture_compression_s3tc = false; vid.support.ext_texture_edge_clamp = true; vid.support.ext_texture_filter_anisotropic = false; // probably don't want to use it... + vid.support.ext_texture_srgb = false; qglGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_2d); if (vid.support.ext_texture_filter_anisotropic) @@ -1743,6 +1597,8 @@ void GLES_Init(void) 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" : ""); vid.renderpath = RENDERPATH_GLES2; vid.useinterleavedarrays = false; + vid.sRGBcapable2D = false; + vid.sRGBcapable3D = false; // VorteX: set other info (maybe place them in VID_InitMode?) extern cvar_t gl_info_vendor; @@ -1774,32 +1630,6 @@ void VID_Init (void) Cvar_RegisterVariable(&apple_mouse_noaccel); #endif #endif - Cvar_RegisterVariable(&vid_soft); - Cvar_RegisterVariable(&vid_soft_threads); - Cvar_RegisterVariable(&vid_soft_interlace); - Cvar_RegisterVariable(&joy_detected); - Cvar_RegisterVariable(&joy_enable); - Cvar_RegisterVariable(&joy_index); - Cvar_RegisterVariable(&joy_axisforward); - Cvar_RegisterVariable(&joy_axisside); - Cvar_RegisterVariable(&joy_axisup); - Cvar_RegisterVariable(&joy_axispitch); - Cvar_RegisterVariable(&joy_axisyaw); - //Cvar_RegisterVariable(&joy_axisroll); - Cvar_RegisterVariable(&joy_deadzoneforward); - Cvar_RegisterVariable(&joy_deadzoneside); - Cvar_RegisterVariable(&joy_deadzoneup); - Cvar_RegisterVariable(&joy_deadzonepitch); - Cvar_RegisterVariable(&joy_deadzoneyaw); - //Cvar_RegisterVariable(&joy_deadzoneroll); - Cvar_RegisterVariable(&joy_sensitivityforward); - Cvar_RegisterVariable(&joy_sensitivityside); - Cvar_RegisterVariable(&joy_sensitivityup); - Cvar_RegisterVariable(&joy_sensitivitypitch); - Cvar_RegisterVariable(&joy_sensitivityyaw); - //Cvar_RegisterVariable(&joy_sensitivityroll); - Cvar_RegisterVariable(&joy_axiskeyevents); - Cvar_RegisterVariable(&joy_axiskeyevents_deadzone); #ifdef __IPHONEOS__ Cvar_SetValueQuick(&vid_touchscreen, 1); #endif @@ -1816,25 +1646,72 @@ void VID_Init (void) vid_isfullscreen = false; } +static int vid_sdljoystickindex = -1; +void VID_EnableJoystick(qboolean enable) +{ + int index = joy_enable.integer > 0 ? joy_index.integer : -1; + int numsdljoysticks; + qboolean success = false; + int sharedcount = 0; + int sdlindex = -1; + sharedcount = VID_Shared_SetJoystick(index); + if (index >= 0 && index < sharedcount) + success = true; + sdlindex = index - sharedcount; + + numsdljoysticks = SDL_NumJoysticks(); + if (sdlindex < 0 || sdlindex >= numsdljoysticks) + sdlindex = -1; + + // update cvar containing count of XInput joysticks + SDL joysticks + if (joy_detected.integer != sharedcount + numsdljoysticks) + Cvar_SetValueQuick(&joy_detected, sharedcount + numsdljoysticks); + + if (vid_sdljoystickindex != sdlindex) + { + vid_sdljoystickindex = sdlindex; + // close SDL joystick if active + if (vid_sdljoystick) + SDL_JoystickClose(vid_sdljoystick); + vid_sdljoystick = NULL; + if (sdlindex >= 0) + { + vid_sdljoystick = SDL_JoystickOpen(sdlindex); + if (vid_sdljoystick) + Con_Printf("Joystick %i opened (SDL_Joystick %i is \"%s\" with %i axes, %i buttons, %i balls)\n", index, sdlindex, SDL_JoystickName(sdlindex), (int)SDL_JoystickNumAxes(vid_sdljoystick), (int)SDL_JoystickNumButtons(vid_sdljoystick), (int)SDL_JoystickNumBalls(vid_sdljoystick)); + else + { + Con_Printf("Joystick %i failed (SDL_JoystickOpen(%i) returned: %s)\n", index, sdlindex, SDL_GetError()); + sdlindex = -1; + } + } + } + + if (sdlindex >= 0) + success = true; + + Cvar_SetValueQuick(&joy_active, success ? 1 : 0); +} + #if SETVIDEOMODE // set the icon (we dont use SDL here since it would be too much a PITA) #ifdef WIN32 #include "resource.h" #include -static void VID_SetCaption(void) +static SDL_Surface *VID_WrapSDL_SetVideoMode(int screenwidth, int screenheight, int screenbpp, int screenflags) { - SDL_SysWMinfo info; - HICON icon; - - // set the caption + SDL_Surface *screen = NULL; + SDL_SysWMinfo info; + HICON icon; SDL_WM_SetCaption( gamename, NULL ); - - // get the HWND handle - SDL_VERSION( &info.version ); - if( !SDL_GetWMInfo( &info ) ) - return; - - icon = LoadIcon( GetModuleHandle( NULL ), MAKEINTRESOURCE( IDI_ICON1 ) ); + screen = SDL_SetVideoMode(screenwidth, screenheight, screenbpp, screenflags); + if (screen) + { + // get the HWND handle + SDL_VERSION( &info.version ); + if (SDL_GetWMInfo(&info)) + { + icon = LoadIcon( GetModuleHandle( NULL ), MAKEINTRESOURCE( IDI_ICON1 ) ); #ifndef _W64 //If Windows 64bit data types don't exist #ifndef SetClassLongPtr #define SetClassLongPtr SetClassLong @@ -1846,20 +1723,26 @@ static void VID_SetCaption(void) #define LONG_PTR LONG #endif #endif - SetClassLongPtr( info.window, GCLP_HICON, (LONG_PTR)icon ); -} -static void VID_SetIcon_Pre(void) -{ + SetClassLongPtr( info.window, GCLP_HICON, (LONG_PTR)icon ); + } + } + return screen; } -static void VID_SetIcon_Post(void) +#elif defined(MACOSX) +static SDL_Surface *VID_WrapSDL_SetVideoMode(int screenwidth, int screenheight, int screenbpp, int screenflags) { + SDL_Surface *screen = NULL; + SDL_WM_SetCaption( gamename, NULL ); + screen = SDL_SetVideoMode(screenwidth, screenheight, screenbpp, screenflags); + // we don't use SDL_WM_SetIcon here because the icon in the .app should be used + return screen; } #else // Adding the OS independent XPM version --blub #include "darkplaces.xpm" #include "nexuiz.xpm" static SDL_Surface *icon = NULL; -static void VID_SetIcon_Pre(void) +static SDL_Surface *VID_WrapSDL_SetVideoMode(int screenwidth, int screenheight, int screenbpp, int screenflags) { /* * Somewhat restricted XPM reader. Only supports XPMs saved by GIMP 2.4 at @@ -1873,7 +1756,11 @@ static void VID_SetIcon_Pre(void) char *xpm; char **idata, *data; const SDL_version *version; + SDL_Surface *screen = NULL; + if (icon) + SDL_FreeSurface(icon); + icon = NULL; version = SDL_Linked_Version(); // only use non-XPM icon support in SDL v1.3 and higher // SDL v1.2 does not support "smooth" transparency, and thus is better @@ -1899,14 +1786,14 @@ static void VID_SetIcon_Pre(void) icon = SDL_CreateRGBSurface(SDL_SRCALPHA, width, height, 32, LittleLong(red), LittleLong(green), LittleLong(blue), LittleLong(alpha)); - if(icon == NULL) { + if (icon) + icon->pixels = data; + else + { Con_Printf( "Failed to create surface for the window Icon!\n" "%s\n", SDL_GetError()); free(data); - return; } - - icon->pixels = data; } } @@ -1925,107 +1812,114 @@ static void VID_SetIcon_Pre(void) data = idata[0]; - if(sscanf(data, "%i %i %i %i", &width, &height, &colors, &isize) != 4) + if(sscanf(data, "%i %i %i %i", &width, &height, &colors, &isize) == 4) { - // NOTE: Only 1-char colornames are supported - Con_Printf("Sorry, but this does not even look similar to an XPM.\n"); - return; - } - - if(isize != 1) - { - // NOTE: Only 1-char colornames are supported - Con_Printf("This XPM's palette is either huge or idiotically unoptimized. It's key size is %i\n", isize); - return; - } + if(isize == 1) + { + for(i = 0; i < colors; ++i) + { + unsigned int r, g, b; + char idx; - for(i = 0; i < colors; ++i) - { - unsigned int r, g, b; - char idx; + if(sscanf(idata[i+1], "%c c #%02x%02x%02x", &idx, &r, &g, &b) != 4) + { + char foo[2]; + if(sscanf(idata[i+1], "%c c Non%1[e]", &idx, foo) != 2) // I take the DailyWTF credit for this. --div0 + break; + else + { + palette[i].r = 255; // color key + palette[i].g = 0; + palette[i].b = 255; + thenone = i; // weeeee + palenc[(unsigned char) idx] = i; + } + } + else + { + palette[i].r = r - (r == 255 && g == 0 && b == 255); // change 255/0/255 pink to 254/0/255 for color key + palette[i].g = g; + palette[i].b = b; + palenc[(unsigned char) idx] = i; + } + } - if(sscanf(idata[i+1], "%c c #%02x%02x%02x", &idx, &r, &g, &b) != 4) - { - char foo[2]; - if(sscanf(idata[i+1], "%c c Non%1[e]", &idx, foo) != 2) // I take the DailyWTF credit for this. --div0 + if (i == colors) { - Con_Printf("This XPM's palette looks odd. Can't continue.\n"); - return; + // allocate the image data + data = (char*) malloc(width*height); + + for(j = 0; j < height; ++j) + { + for(i = 0; i < width; ++i) + { + // casting to the safest possible datatypes ^^ + data[j * width + i] = palenc[((unsigned char*)idata[colors+j+1])[i]]; + } + } + + if(icon != NULL) + { + // SDL_FreeSurface should free the data too + // but for completeness' sake... + if(icon->flags & SDL_PREALLOC) + { + free(icon->pixels); + icon->pixels = NULL; // safety + } + SDL_FreeSurface(icon); + } + + icon = SDL_CreateRGBSurface(SDL_SRCCOLORKEY, width, height, 8, 0,0,0,0);// rmask, gmask, bmask, amask); no mask needed + // 8 bit surfaces get an empty palette allocated according to the docs + // so it's a palette image for sure :) no endian check necessary for the mask + + if(icon) + { + icon->pixels = data; + SDL_SetPalette(icon, SDL_PHYSPAL|SDL_LOGPAL, palette, 0, colors); + SDL_SetColorKey(icon, SDL_SRCCOLORKEY, thenone); + } + else + { + Con_Printf( "Failed to create surface for the window Icon!\n" + "%s\n", SDL_GetError()); + free(data); + } } else { - palette[i].r = 255; // color key - palette[i].g = 0; - palette[i].b = 255; - thenone = i; // weeeee + Con_Printf("This XPM's palette looks odd. Can't continue.\n"); } } else { - palette[i].r = r - (r == 255 && g == 0 && b == 255); // change 255/0/255 pink to 254/0/255 for color key - palette[i].g = g; - palette[i].b = b; - } - - palenc[(unsigned char) idx] = i; - } - - // allocate the image data - data = (char*) malloc(width*height); - - for(j = 0; j < height; ++j) - { - for(i = 0; i < width; ++i) - { - // casting to the safest possible datatypes ^^ - data[j * width + i] = palenc[((unsigned char*)idata[colors+j+1])[i]]; + // NOTE: Only 1-char colornames are supported + Con_Printf("This XPM's palette is either huge or idiotically unoptimized. It's key size is %i\n", isize); } } - - if(icon != NULL) + else { - // SDL_FreeSurface should free the data too - // but for completeness' sake... - if(icon->flags & SDL_PREALLOC) - { - free(icon->pixels); - icon->pixels = NULL; // safety - } - SDL_FreeSurface(icon); + // NOTE: Only 1-char colornames are supported + Con_Printf("Sorry, but this does not even look similar to an XPM.\n"); } + } - icon = SDL_CreateRGBSurface(SDL_SRCCOLORKEY, width, height, 8, 0,0,0,0);// rmask, gmask, bmask, amask); no mask needed - // 8 bit surfaces get an empty palette allocated according to the docs - // so it's a palette image for sure :) no endian check necessary for the mask - - if(icon == NULL) { - Con_Printf( "Failed to create surface for the window Icon!\n" - "%s\n", SDL_GetError()); - free(data); - return; - } + if (icon) + SDL_WM_SetIcon(icon, NULL); - icon->pixels = data; - SDL_SetPalette(icon, SDL_PHYSPAL|SDL_LOGPAL, palette, 0, colors); - SDL_SetColorKey(icon, SDL_SRCCOLORKEY, thenone); - } + SDL_WM_SetCaption( gamename, NULL ); + screen = SDL_SetVideoMode(screenwidth, screenheight, screenbpp, screenflags); - SDL_WM_SetIcon(icon, NULL); -} -static void VID_SetIcon_Post(void) -{ #if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION == 2 // LordHavoc: info.info.x11.lock_func and accompanying code do not seem to compile with SDL 1.3 #if SDL_VIDEO_DRIVER_X11 && !SDL_VIDEO_DRIVER_QUARTZ - int j; - char *data; - const SDL_version *version; version = SDL_Linked_Version(); // only use non-XPM icon support in SDL v1.3 and higher // SDL v1.2 does not support "smooth" transparency, and thus is better // off the xpm way - if(!(version->major >= 2 || (version->major == 1 && version->minor >= 3))) + if(screen && (!(version->major >= 2 || (version->major == 1 && version->minor >= 3)))) { // in this case, we did not set the good icon yet SDL_SysWMinfo info; @@ -2070,13 +1964,9 @@ static void VID_SetIcon_Post(void) } #endif #endif + return screen; } - -static void VID_SetCaption(void) -{ - SDL_WM_SetCaption( gamename, NULL ); -} #endif #endif @@ -2142,7 +2032,8 @@ qboolean VID_InitModeGL(viddef_mode_t *mode) mode->fullscreen = true; // hide the menu with SDL_WINDOW_BORDERLESS windowflags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS; -#else +#endif +#ifndef USE_GLES2 if ((qglGetString = (const GLubyte* (GLAPIENTRY *)(GLenum name))GL_GetProcAddress("glGetString")) == NULL) { VID_Shutdown(); @@ -2188,28 +2079,24 @@ qboolean VID_InitModeGL(viddef_mode_t *mode) SDL_GL_SetAttribute (SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute (SDL_GL_MULTISAMPLESAMPLES, mode->samples); } + #if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION == 2 if (vid_vsync.integer) SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1); else SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 0); #else -#ifdef __IPHONEOS__ +#ifdef USE_GLES2 SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0); SDL_GL_SetAttribute (SDL_GL_RETAINED_BACKING, 1); - // FIXME: get proper resolution from OS somehow (iPad for instance...) - mode->width = 320; - mode->height = 480; #endif #endif video_bpp = mode->bitsperpixel; #if SETVIDEOMODE video_flags = flags; - VID_SetIcon_Pre(); - screen = SDL_SetVideoMode(mode->width, mode->height, mode->bitsperpixel, flags); - VID_SetIcon_Post(); + screen = VID_WrapSDL_SetVideoMode(mode->width, mode->height, mode->bitsperpixel, flags); if (screen == NULL) { Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError()); @@ -2240,10 +2127,6 @@ qboolean VID_InitModeGL(viddef_mode_t *mode) vid_softsurface = NULL; vid.softpixels = NULL; -#if SETVIDEOMODE - // set window title - VID_SetCaption(); -#endif // init keyboard SDL_EnableUNICODE( SDL_ENABLE ); // enable key repeat since everyone expects it @@ -2257,35 +2140,18 @@ qboolean VID_InitModeGL(viddef_mode_t *mode) gl_platform = "SDL"; gl_platformextensions = ""; -#ifdef __IPHONEOS__ +#ifdef USE_GLES2 GLES_Init(); #else GL_Init(); #endif - vid_numjoysticks = SDL_NumJoysticks(); - vid_numjoysticks = bound(0, vid_numjoysticks, MAX_JOYSTICKS); - Cvar_SetValueQuick(&joy_detected, vid_numjoysticks); - Con_Printf("%d SDL joystick(s) found:\n", vid_numjoysticks); - memset(vid_joysticks, 0, sizeof(vid_joysticks)); - for (i = 0;i < vid_numjoysticks;i++) - { - SDL_Joystick *joy; - joy = vid_joysticks[i] = SDL_JoystickOpen(i); - if (!joy) - { - Con_Printf("joystick #%i: open failed: %s\n", i, SDL_GetError()); - continue; - } - Con_Printf("joystick #%i: opened \"%s\" with %i axes, %i buttons, %i balls\n", i, SDL_JoystickName(i), (int)SDL_JoystickNumAxes(joy), (int)SDL_JoystickNumButtons(joy), (int)SDL_JoystickNumBalls(joy)); - } - vid_hidden = false; vid_activewindow = false; vid_hasfocus = true; vid_usingmouse = false; vid_usinghidecursor = false; - + #if SETVIDEOMODE SDL_WM_GrabInput(SDL_GRAB_OFF); #endif @@ -2301,9 +2167,9 @@ extern cvar_t gl_info_driver; qboolean VID_InitModeSoft(viddef_mode_t *mode) { - int i; #if SETVIDEOMODE int flags = SDL_HWSURFACE; + if(!COM_CheckParm("-noasyncblit")) flags |= SDL_ASYNCBLIT; #else int windowflags = SDL_WINDOW_SHOWN; #endif @@ -2333,9 +2199,7 @@ qboolean VID_InitModeSoft(viddef_mode_t *mode) video_bpp = mode->bitsperpixel; #if SETVIDEOMODE video_flags = flags; - VID_SetIcon_Pre(); - screen = SDL_SetVideoMode(mode->width, mode->height, mode->bitsperpixel, flags); - VID_SetIcon_Post(); + screen = VID_WrapSDL_SetVideoMode(mode->width, mode->height, mode->bitsperpixel, flags); if (screen == NULL) { Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError()); @@ -2375,88 +2239,12 @@ qboolean VID_InitModeSoft(viddef_mode_t *mode) return false; } -#if SETVIDEOMODE - // set window title - VID_SetCaption(); -#endif // init keyboard SDL_EnableUNICODE( SDL_ENABLE ); // enable key repeat since everyone expects it SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); - gl_platform = "SDLSoft"; - gl_platformextensions = ""; - - gl_renderer = "DarkPlaces-Soft"; - gl_vendor = "Forest Hale"; - gl_version = "0.0"; - gl_extensions = ""; - - // clear the extension flags - memset(&vid.support, 0, sizeof(vid.support)); - Cvar_SetQuick(&gl_info_extensions, ""); - - vid.forcevbo = false; - vid.support.arb_depth_texture = true; - vid.support.arb_draw_buffers = true; - vid.support.arb_occlusion_query = true; - vid.support.arb_shadow = true; - //vid.support.arb_texture_compression = true; - vid.support.arb_texture_cube_map = true; - vid.support.arb_texture_non_power_of_two = false; - vid.support.arb_vertex_buffer_object = true; - vid.support.ext_blend_subtract = true; - vid.support.ext_draw_range_elements = true; - vid.support.ext_framebuffer_object = true; - vid.support.ext_texture_3d = true; - //vid.support.ext_texture_compression_s3tc = true; - vid.support.ext_texture_filter_anisotropic = true; - vid.support.ati_separate_stencil = true; - - vid.maxtexturesize_2d = 16384; - vid.maxtexturesize_3d = 512; - vid.maxtexturesize_cubemap = 16384; - vid.texunits = 4; - vid.teximageunits = 32; - vid.texarrayunits = 8; - vid.max_anisotropy = 1; - vid.maxdrawbuffers = 4; - - vid.texunits = bound(4, vid.texunits, MAX_TEXTUREUNITS); - vid.teximageunits = bound(16, vid.teximageunits, MAX_TEXTUREUNITS); - vid.texarrayunits = bound(8, vid.texarrayunits, MAX_TEXTUREUNITS); - Con_DPrintf("Using DarkPlaces Software Rasterizer rendering path\n"); - vid.renderpath = RENDERPATH_SOFT; - vid.useinterleavedarrays = false; - - Cvar_SetQuick(&gl_info_vendor, gl_vendor); - Cvar_SetQuick(&gl_info_renderer, gl_renderer); - Cvar_SetQuick(&gl_info_version, gl_version); - Cvar_SetQuick(&gl_info_platform, gl_platform ? gl_platform : ""); - Cvar_SetQuick(&gl_info_driver, gl_driver); - - // LordHavoc: report supported extensions - Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions ); - - // clear to black (loading plaque will be seen over this) - GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 128); - - vid_numjoysticks = SDL_NumJoysticks(); - vid_numjoysticks = bound(0, vid_numjoysticks, MAX_JOYSTICKS); - Cvar_SetValueQuick(&joy_detected, vid_numjoysticks); - Con_Printf("%d SDL joystick(s) found:\n", vid_numjoysticks); - memset(vid_joysticks, 0, sizeof(vid_joysticks)); - for (i = 0;i < vid_numjoysticks;i++) - { - SDL_Joystick *joy; - joy = vid_joysticks[i] = SDL_JoystickOpen(i); - if (!joy) - { - Con_Printf("joystick #%i: open failed: %s\n", i, SDL_GetError()); - continue; - } - Con_Printf("joystick #%i: opened \"%s\" with %i axes, %i buttons, %i balls\n", i, SDL_JoystickName(i), (int)SDL_JoystickNumAxes(joy), (int)SDL_JoystickNumButtons(joy), (int)SDL_JoystickNumBalls(joy)); - } + VID_Soft_SharedSetup(); vid_hidden = false; vid_activewindow = false; @@ -2474,7 +2262,7 @@ qboolean VID_InitMode(viddef_mode_t *mode) { if (!SDL_WasInit(SDL_INIT_VIDEO) && SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) Sys_Error ("Failed to init SDL video subsystem: %s", SDL_GetError()); -#ifdef SSE2_PRESENT +#ifdef SSE_POSSIBLE if (vid_soft.integer) return VID_InitModeSoft(mode); else @@ -2484,15 +2272,18 @@ qboolean VID_InitMode(viddef_mode_t *mode) void VID_Shutdown (void) { + VID_EnableJoystick(false); VID_SetMouse(false, false, false); VID_RestoreSystemGamma(); #if SETVIDEOMODE #ifndef WIN32 +#ifndef MACOSX if (icon) SDL_FreeSurface(icon); icon = NULL; #endif +#endif #endif if (vid_softsurface) @@ -2536,7 +2327,7 @@ void VID_Finish (void) appstate = SDL_GetAppState(); vid_hidden = !(appstate & SDL_APPACTIVE); - vid_hasfocus = (appstate & SDL_APPMOUSEFOCUS) && (appstate & SDL_APPINPUTFOCUS); + vid_hasfocus = (appstate & SDL_APPINPUTFOCUS) != 0; #endif vid_activewindow = !vid_hidden && vid_hasfocus; @@ -2549,6 +2340,7 @@ void VID_Finish (void) case RENDERPATH_GL11: case RENDERPATH_GL13: case RENDERPATH_GL20: + case RENDERPATH_GLES1: case RENDERPATH_GLES2: CHECKGLERROR if (r_speeds.integer == 2 || gl_finish.integer) @@ -2576,8 +2368,11 @@ void VID_Finish (void) case RENDERPATH_SOFT: DPSOFTRAST_Finish(); #if SETVIDEOMODE +// if (!r_test.integer) + { SDL_BlitSurface(vid_softsurface, NULL, screen, NULL); SDL_Flip(screen); + } #else { SDL_Surface *screen = SDL_GetWindowSurface(window);