Exemple #1
0
/*
 * Updates the input queue state. Called every
 * frame by the client and does nearly all the
 * input magic.
 */
void
IN_Update(void)
{
	qboolean want_grab;
	SDL_Event event;
	unsigned int key;

	/* Get and process an event */
	while (SDL_PollEvent(&event))
	{

		switch (event.type)
		{
#if SDL_VERSION_ATLEAST(2, 0, 0)
			case SDL_MOUSEWHEEL:
				Key_Event((event.wheel.y > 0 ? K_MWHEELUP : K_MWHEELDOWN), true, true);
				Key_Event((event.wheel.y > 0 ? K_MWHEELUP : K_MWHEELDOWN), false, true);
				break;
#endif
			case SDL_MOUSEBUTTONDOWN:
#if !SDL_VERSION_ATLEAST(2, 0, 0)
				if (event.button.button == 4)
				{
					Key_Event(K_MWHEELUP, true, true);
					Key_Event(K_MWHEELUP, false, true);
					break;
				}
				else if (event.button.button == 5)
				{
					Key_Event(K_MWHEELDOWN, true, true);
					Key_Event(K_MWHEELDOWN, false, true);
					break;
				}
#endif
				/* fall-through */
			case SDL_MOUSEBUTTONUP:
				switch (event.button.button)
				{
					case SDL_BUTTON_LEFT:
						key = K_MOUSE1;
						break;
					case SDL_BUTTON_MIDDLE:
						key = K_MOUSE3;
						break;
					case SDL_BUTTON_RIGHT:
						key = K_MOUSE2;
						break;
					case SDL_BUTTON_X1:
						key = K_MOUSE4;
						break;
					case SDL_BUTTON_X2:
						key = K_MOUSE5;
						break;
					default:
						return;
				}

				Key_Event(key, (event.type == SDL_MOUSEBUTTONDOWN), true);
				break;

			case SDL_MOUSEMOTION:
				if (cls.key_dest == key_game && (int) cl_paused->value == 0)
				{
					mouse_x += event.motion.xrel;
					mouse_y += event.motion.yrel;
				}
				break;

#if SDL_VERSION_ATLEAST(2, 0, 0)
			case SDL_TEXTINPUT:
				if ((event.text.text[0] >= ' ') &&
					(event.text.text[0] <= '~'))
				{
					Char_Event(event.text.text[0]);
				}

				break;
#endif

			case SDL_KEYDOWN:
#if !SDL_VERSION_ATLEAST(2, 0, 0)
				if ((event.key.keysym.unicode >= SDLK_SPACE) &&
					 (event.key.keysym.unicode < SDLK_DELETE))
				{
					Char_Event(event.key.keysym.unicode);
				}
#endif
				/* fall-through */
			case SDL_KEYUP:
			{
				qboolean down = (event.type == SDL_KEYDOWN);

#if SDL_VERSION_ATLEAST(2, 0, 0)
				/* workaround for AZERTY-keyboards, which don't have 1, 2, ..., 9, 0 in first row:
				 * always map those physical keys (scancodes) to those keycodes anyway
				 * see also https://bugzilla.libsdl.org/show_bug.cgi?id=3188 */
				SDL_Scancode sc = event.key.keysym.scancode;
				if (sc >= SDL_SCANCODE_1 && sc <= SDL_SCANCODE_0)
				{
					/* Note that the SDL_SCANCODEs are SDL_SCANCODE_1, _2, ..., _9, SDL_SCANCODE_0
					 * while in ASCII it's '0', '1', ..., '9' => handle 0 and 1-9 separately
					 * (quake2 uses the ASCII values for those keys) */
					int key = '0'; /* implicitly handles SDL_SCANCODE_0 */
					if (sc <= SDL_SCANCODE_9)
					{
						key = '1' + (sc - SDL_SCANCODE_1);
					}
					Key_Event(key, down, false);
				}
				else
#endif /* SDL2; (SDL1.2 doesn't have scancodes so nothing we can do there) */
				if ((event.key.keysym.sym >= SDLK_SPACE) &&
					(event.key.keysym.sym < SDLK_DELETE))
				{
					Key_Event(event.key.keysym.sym, down, false);
				}
				else
				{
					Key_Event(IN_TranslateSDLtoQ2Key(event.key.keysym.sym), down, true);
				}
			}
				break;

#if SDL_VERSION_ATLEAST(2, 0, 0)
			case SDL_WINDOWEVENT:
				if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST ||
					event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED)
				{
					Key_MarkAllUp();
				}
				else if (event.window.event == SDL_WINDOWEVENT_MOVED)
				{
					// make sure GLimp_GetRefreshRate() will query from SDL again - the window might
					// be on another display now!
					glimp_refreshRate = -1;
				}

#else /* SDL1.2 */
			case SDL_ACTIVEEVENT:
				if(event.active.gain == 0 && (event.active.state & SDL_APPINPUTFOCUS))
				{
					Key_MarkAllUp();
				}
#endif
				break;
#if SDL_VERSION_ATLEAST(2, 0, 0)
			case SDL_CONTROLLERBUTTONUP:
			case SDL_CONTROLLERBUTTONDOWN: /* Handle Controller Back button */
			{
				qboolean down = (event.type == SDL_CONTROLLERBUTTONDOWN);
				if (event.cbutton.button == SDL_CONTROLLER_BUTTON_BACK)
				{
					Key_Event(K_JOY_BACK, down, true);
				}
			}
				break;
			case SDL_CONTROLLERAXISMOTION:  /* Handle Controller Motion */
			{
				char *direction_type;
				float threshold = 0;
				float fix_value = 0;
				int axis_value = event.caxis.value;
				switch (event.caxis.axis)
				{
					/* left/right */
					case SDL_CONTROLLER_AXIS_LEFTX:
						direction_type = joy_axis_leftx->string;
						threshold = joy_axis_leftx_threshold->value;
						break;
						/* top/bottom */
					case SDL_CONTROLLER_AXIS_LEFTY:
						direction_type = joy_axis_lefty->string;
						threshold = joy_axis_lefty_threshold->value;
						break;
						/* second left/right */
					case SDL_CONTROLLER_AXIS_RIGHTX:
						direction_type = joy_axis_rightx->string;
						threshold = joy_axis_rightx_threshold->value;
						break;
						/* second top/bottom */
					case SDL_CONTROLLER_AXIS_RIGHTY:
						direction_type = joy_axis_righty->string;
						threshold = joy_axis_righty_threshold->value;
						break;
					case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
						direction_type = joy_axis_triggerleft->string;
						threshold = joy_axis_triggerleft_threshold->value;
						break;
					case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
						direction_type = joy_axis_triggerright->string;
						threshold = joy_axis_triggerright_threshold->value;
						break;
					default:
						direction_type = "none";
				}

				if (threshold > 0.9)
					threshold = 0.9;

				if (axis_value < 0 && (axis_value > (32768 * threshold)))
					axis_value = 0;
				else if (axis_value > 0 && (axis_value < (32768 * threshold)))
					axis_value = 0;

				// Smoothly ramp from dead zone to maximum value (from ioquake)
				// https://github.com/ioquake/ioq3/blob/master/code/sdl/sdl_input.c
				fix_value = ((float) abs(axis_value) / 32767.0f - threshold) / (1.0f - threshold);
				if (fix_value < 0.0f)
					fix_value = 0.0f;

				axis_value = (int) (32767 * ((axis_value < 0) ? -fix_value : fix_value));

				if (cls.key_dest == key_game && (int) cl_paused->value == 0)
				{
					if (strcmp(direction_type, "sidemove") == 0)
					{
						joystick_sidemove = axis_value * joy_sidesensitivity->value;
						// We need to be twice faster because with joystic we run...
						joystick_sidemove *= cl_sidespeed->value * 2.0f;
					}
					else if (strcmp(direction_type, "forwardmove") == 0)
					{
						joystick_forwardmove = axis_value * joy_forwardsensitivity->value;
						// We need to be twice faster because with joystic we run...
						joystick_forwardmove *= cl_forwardspeed->value * 2.0f;
					}
					else if (strcmp(direction_type, "yaw") == 0)
					{
						joystick_yaw = axis_value * joy_yawsensitivity->value;
						joystick_yaw *= cl_yawspeed->value;
					}
					else if (strcmp(direction_type, "pitch") == 0)
					{
						joystick_pitch = axis_value * joy_pitchsensitivity->value;
						joystick_pitch *= cl_pitchspeed->value;
					}
					else if (strcmp(direction_type, "updown") == 0)
					{
						joystick_up = axis_value * joy_upsensitivity->value;
						joystick_up *= cl_upspeed->value;
					}
				}

				if (strcmp(direction_type, "triggerleft") == 0)
				{
					qboolean new_left_trigger = abs(axis_value) > (32767 / 4);
					if (new_left_trigger != left_trigger)
					{
						left_trigger = new_left_trigger;
						Key_Event(K_TRIG_LEFT, left_trigger, true);
					}
				}
				else if (strcmp(direction_type, "triggerright") == 0)
				{
					qboolean new_right_trigger = abs(axis_value) > (32767 / 4);
					if (new_right_trigger != right_trigger)
					{
						right_trigger = new_right_trigger;
						Key_Event(K_TRIG_RIGHT, right_trigger, true);
					}
				}
			}
				break;
				/* Joystick can have more buttons than on general game controller
				 * so try to map not free buttons */
			case SDL_JOYBUTTONUP:
			case SDL_JOYBUTTONDOWN:
			{
				qboolean down = (event.type == SDL_JOYBUTTONDOWN);
				/* Ignore back button, we dont need event for such button */
				if (back_button_id == event.jbutton.button)
					return;
				if (event.jbutton.button <= (K_JOY32 - K_JOY1))
				{
					Key_Event(event.jbutton.button + K_JOY1, down, true);
				}
			}
				break;
			case SDL_JOYHATMOTION:
			{
				if (last_hat != event.jhat.value)
				{
					char diff = last_hat ^event.jhat.value;
					int i;
					for (i = 0; i < 4; i++)
					{
						if (diff & (1 << i))
						{
							/* check that we have button up for some bit */
							if (last_hat & (1 << i))
								Key_Event(i + K_HAT_UP, false, true);

							/* check that we have button down for some bit */
							if (event.jhat.value & (1 << i))
								Key_Event(i + K_HAT_UP, true, true);
						}
					}
					last_hat = event.jhat.value;
				}
			}
				break;
#endif
			case SDL_QUIT:
				Com_Quit();

				break;
		}
	}

	/* Grab and ungrab the mouse if the console or the menu is opened */
	if (in_grab->value == 3)
	{
		want_grab = windowed_mouse->value;
	}
	else
	{
		want_grab = (vid_fullscreen->value || in_grab->value == 1 ||
			(in_grab->value == 2 && windowed_mouse->value));
	}

	/* calling GLimp_GrabInput() each is a bit ugly but simple and should work.
	 * + the called SDL functions return after a cheap check, if there's
	 * nothing to do, anyway. */
	GLimp_GrabInput(want_grab);

	/* We need to save the frame time so other subsystems know the
	 * exact time of the last input events. */
	sys_frame_time = Sys_Milliseconds();
}
Exemple #2
0
/*
 * Updates the input queue state. Called every
 * frame by the client and does nearly all the
 * input magic.
 */
void
IN_Update(void)
{
	qboolean want_grab;
	SDL_Event event;
 	unsigned int key;

	/* Get and process an event */
	while (SDL_PollEvent(&event))
	{

		switch (event.type)
		{
#if SDL_VERSION_ATLEAST(2, 0, 0)
			case SDL_MOUSEWHEEL:
				Key_Event((event.wheel.y > 0 ? K_MWHEELUP : K_MWHEELDOWN), true, true);
				Key_Event((event.wheel.y > 0 ? K_MWHEELUP : K_MWHEELDOWN), false, true);
				break;
#endif
			case SDL_MOUSEBUTTONDOWN:
#if !SDL_VERSION_ATLEAST(2, 0, 0)
				if (event.button.button == 4)
				{
					Key_Event(K_MWHEELUP, true, true);
					Key_Event(K_MWHEELUP, false, true);
					break;
				}
				else if (event.button.button == 5)
				{
					Key_Event(K_MWHEELDOWN, true, true);
					Key_Event(K_MWHEELDOWN, false, true);
					break;
				}
#endif
				/* fall-through */
			case SDL_MOUSEBUTTONUP:
				switch( event.button.button )
				{
					case SDL_BUTTON_LEFT:
						key = K_MOUSE1;
						break;
					case SDL_BUTTON_MIDDLE:
						key = K_MOUSE3;
						break;
					case SDL_BUTTON_RIGHT:
						key = K_MOUSE2;
						break;
					case SDL_BUTTON_X1:
						key = K_MOUSE4;
						break;
					case SDL_BUTTON_X2:
						key = K_MOUSE5;
						break;
					default:
						return;
				}

				Key_Event(key, (event.type == SDL_MOUSEBUTTONDOWN), true);
				break;

			case SDL_MOUSEMOTION:
                if (cls.key_dest == key_game && (int)cl_paused->value == 0) {
                    mouse_x += event.motion.xrel;
                    mouse_y += event.motion.yrel;
                }
				break;

#if SDL_VERSION_ATLEAST(2, 0, 0)
			case SDL_TEXTINPUT:
				if((event.text.text[0] >= ' ') &&
				   (event.text.text[0] <= '~'))
				{
					Char_Event(event.text.text[0]);
				}

				break;
#endif

			case SDL_KEYDOWN:
#if !SDL_VERSION_ATLEAST(2, 0, 0)
				if ((event.key.keysym.unicode >= SDLK_SPACE) &&
					 (event.key.keysym.unicode < SDLK_DELETE))
				{
					Char_Event(event.key.keysym.unicode);
				}
#endif
				/* fall-through */
			case SDL_KEYUP:
			{
				qboolean down = (event.type == SDL_KEYDOWN);

#if SDL_VERSION_ATLEAST(2, 0, 0)
				/* workaround for AZERTY-keyboards, which don't have 1, 2, ..., 9, 0 in first row:
				 * always map those physical keys (scancodes) to those keycodes anyway
				 * see also https://bugzilla.libsdl.org/show_bug.cgi?id=3188 */
				SDL_Scancode sc = event.key.keysym.scancode;
				if(sc >= SDL_SCANCODE_1 && sc <= SDL_SCANCODE_0)
				{
					/* Note that the SDL_SCANCODEs are SDL_SCANCODE_1, _2, ..., _9, SDL_SCANCODE_0
					 * while in ASCII it's '0', '1', ..., '9' => handle 0 and 1-9 separately
					 * (quake2 uses the ASCII values for those keys) */
					int key = '0'; /* implicitly handles SDL_SCANCODE_0 */
					if(sc <= SDL_SCANCODE_9)
					{
						key = '1' + (sc - SDL_SCANCODE_1);
					}
					Key_Event(key, down, false);
				}
				else
#endif /* SDL2; (SDL1.2 doesn't have scancodes so nothing we can do there) */
				   if((event.key.keysym.sym >= SDLK_SPACE) &&
				      (event.key.keysym.sym < SDLK_DELETE))
				{
					Key_Event(event.key.keysym.sym, down, false);
				}
				else
				{
					Key_Event(IN_TranslateSDLtoQ2Key(event.key.keysym.sym), down, true);
				}
			}
				break;

#if SDL_VERSION_ATLEAST(2, 0, 0)
			case SDL_WINDOWEVENT:
				if(event.window.event == SDL_WINDOWEVENT_FOCUS_LOST)
				{
					Key_MarkAllUp();
				}

#else /* SDL1.2 */
			case SDL_ACTIVEEVENT:
				if(event.active.gain == 0 && (event.active.state & SDL_APPINPUTFOCUS))
				{
					Key_MarkAllUp();
				}
#endif
				break;
		}
	}

	/* Grab and ungrab the mouse if the* console or the menu is opened */
	want_grab = (vid_fullscreen->value || in_grab->value == 1 ||
			(in_grab->value == 2 && windowed_mouse->value));
	/* calling GLimp_GrabInput() each is a but ugly but simple and should work.
	 * + the called SDL functions return after a cheap check, if there's
	 * nothing to do, anyway
	 */
	GLimp_GrabInput(want_grab);
}
Exemple #3
0
/*
 * Updates the input queue state. Called every
 * frame by the client and does nearly all the
 * input magic.
 */
void
IN_Update(void)
{
	qboolean want_grab;
	SDL_Event event;
 	unsigned int key;

	/* Get and process an event */
	while (SDL_PollEvent(&event))
	{

		switch (event.type)
		{
#if SDL_VERSION_ATLEAST(2, 0, 0)
			case SDL_MOUSEWHEEL:
				Key_Event((event.wheel.y > 0 ? K_MWHEELUP : K_MWHEELDOWN), true, true);
				Key_Event((event.wheel.y > 0 ? K_MWHEELUP : K_MWHEELDOWN), false, true);
				break;
#endif
			case SDL_MOUSEBUTTONDOWN:
#if !SDL_VERSION_ATLEAST(2, 0, 0)
				if (event.button.button == 4)
				{
					Key_Event(K_MWHEELUP, true, true);
					Key_Event(K_MWHEELUP, false, true);
					break;
				}
				else if (event.button.button == 5)
				{
					Key_Event(K_MWHEELDOWN, true, true);
					Key_Event(K_MWHEELDOWN, false, true);
					break;
				}
#endif
			case SDL_MOUSEBUTTONUP:
				switch( event.button.button )
				{
					case SDL_BUTTON_LEFT:
						key = K_MOUSE1;
						break;
					case SDL_BUTTON_MIDDLE:
						key = K_MOUSE3;
						break;
					case SDL_BUTTON_RIGHT:
						key = K_MOUSE2;
						break;
					case SDL_BUTTON_X1:
						key = K_MOUSE4;
						break;
					case SDL_BUTTON_X2:
						key = K_MOUSE5;
						break;
					default:
						return;
				}

				Key_Event(key, (event.type == SDL_MOUSEBUTTONDOWN), true);
				break;

			case SDL_MOUSEMOTION:
                if (cls.key_dest == key_game && (int)cl_paused->value == 0) {
                    mouse_x += event.motion.xrel;
                    mouse_y += event.motion.yrel;
                }
				break;

#if SDL_VERSION_ATLEAST(2, 0, 0)
			case SDL_TEXTINPUT:
				if ((event.text.text[0] >= SDLK_SPACE) &&
					 (event.text.text[0] < SDLK_DELETE))
				{
					Char_Event(event.text.text[0]);
				}

				break;
#endif

			case SDL_KEYDOWN:
#if !SDL_VERSION_ATLEAST(2, 0, 0)
				if ((event.key.keysym.unicode >= SDLK_SPACE) &&
					 (event.key.keysym.unicode < SDLK_DELETE))
				{
					Char_Event(event.key.keysym.unicode);
				}
#endif

				if ((event.key.keysym.sym >= SDLK_SPACE) &&
					 (event.key.keysym.sym < SDLK_DELETE))
				{
					Key_Event(event.key.keysym.sym, true, false);
				}
				else
				{
					Key_Event(IN_TranslateSDLtoQ2Key(event.key.keysym.sym), true, true);
				}

				break;

			case SDL_KEYUP:

				if ((event.key.keysym.sym >= SDLK_SPACE) &&
					 (event.key.keysym.sym < SDLK_DELETE))
				{
					Key_Event(event.key.keysym.sym, false, false);
				}
				else
				{
					Key_Event(IN_TranslateSDLtoQ2Key(event.key.keysym.sym), false, true);
				}

				break;

#if SDL_VERSION_ATLEAST(2, 0, 0)
			case SDL_WINDOWEVENT:
				if(event.window.event == SDL_WINDOWEVENT_FOCUS_LOST)
				{
					Key_MarkAllUp();
				}

#else // SDL1.2
			case SDL_ACTIVEEVENT:
				if(event.active.gain == 0 && (event.active.state & SDL_APPINPUTFOCUS))
				{
					Key_MarkAllUp();
				}
#endif
				break;
		}
	}

	/* Grab and ungrab the mouse if the* console or the menu is opened */
	want_grab = (vid_fullscreen->value || in_grab->value == 1 ||
			(in_grab->value == 2 && windowed_mouse->value));
	/* calling GLimp_GrabInput() each is a but ugly but simple and should work.
	 * + the called SDL functions return after a cheap check, if there's
	 * nothing to do, anyway
	 */
	GLimp_GrabInput(want_grab);
}
Exemple #4
0
void IN_SendKeyEvents (void)
{
	SDL_Event event;
	int key;
	qboolean down;

	while (SDL_PollEvent(&event))
	{
		switch (event.type)
		{
		case SDL_WINDOWEVENT:
			if (event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED)
				S_UnblockSound();
			else if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST)
				S_BlockSound();
			break;
		case SDL_TEXTINPUT:
			if (in_debugkeys.value)
				IN_DebugTextEvent(&event);

		// SDL2: We use SDL_TEXTINPUT for typing in the console / chat.
		// SDL2 uses the local keyboard layout and handles modifiers
		// (shift for uppercase, etc.) for us.
			{
				unsigned char *ch;
				for (ch = (unsigned char *)event.text.text; *ch; ch++)
					if ((*ch & ~0x7F) == 0)
						Char_Event (*ch);
			}
			break;
		case SDL_KEYDOWN:
		case SDL_KEYUP:
			down = (event.key.state == SDL_PRESSED);

			if (in_debugkeys.value)
				IN_DebugKeyEvent(&event);

		// SDL2: we interpret the keyboard as the US layout, so keybindings
		// are based on key position, not the label on the key cap.
			key = IN_SDL2_ScancodeToQuakeKey(event.key.keysym.scancode);

			Key_Event (key, down);
			break;

		case SDL_MOUSEBUTTONDOWN:
		case SDL_MOUSEBUTTONUP:
			if (event.button.button < 1 ||
			    event.button.button > sizeof(buttonremap) / sizeof(buttonremap[0]))
			{
				Con_Printf ("Ignored event for mouse button %d\n",
							event.button.button);
				break;
			}
			Key_Event(buttonremap[event.button.button - 1], event.button.state == SDL_PRESSED);
			break;

		case SDL_MOUSEWHEEL:
			if (event.wheel.y > 0)
			{
				Key_Event(K_MWHEELUP, true);
				Key_Event(K_MWHEELUP, false);
			}
			else if (event.wheel.y < 0)
			{
				Key_Event(K_MWHEELDOWN, true);
				Key_Event(K_MWHEELDOWN, false);
			}
			break;

		case SDL_MOUSEMOTION:
			IN_MouseMotion(event.motion.xrel, event.motion.yrel);
			break;

		case SDL_CONTROLLERDEVICEADDED:
			if (joy_active_instaceid == -1)
			{
				joy_active_controller = SDL_GameControllerOpen(event.cdevice.which);
				if (joy_active_controller == NULL)
					Con_DPrintf("Couldn't open game controller\n");
				else
				{
					SDL_Joystick *joy;
					joy = SDL_GameControllerGetJoystick(joy_active_controller);
					joy_active_instaceid = SDL_JoystickInstanceID(joy);
				}
			}
			else
				Con_DPrintf("Ignoring SDL_CONTROLLERDEVICEADDED\n");
			break;
		case SDL_CONTROLLERDEVICEREMOVED:
			if (joy_active_instaceid != -1 && event.cdevice.which == joy_active_instaceid)
			{
				SDL_GameControllerClose(joy_active_controller);
				joy_active_controller = NULL;
				joy_active_instaceid = -1;
			}
			else
				Con_DPrintf("Ignoring SDL_CONTROLLERDEVICEREMOVED\n");
			break;
		case SDL_CONTROLLERDEVICEREMAPPED:
			Con_DPrintf("Ignoring SDL_CONTROLLERDEVICEREMAPPED\n");
			break;

		case SDL_QUIT:
			CL_Disconnect ();
			Sys_Quit ();
			break;

		default:
			break;
		}
	}
}