예제 #1
0
파일: events.cpp 프로젝트: svdijk/dhewm3
/*
================
Sys_GetEvent
================
*/
sysEvent_t Sys_GetEvent() {
	SDL_Event ev;
	sysEvent_t res = { };
	byte key;

	static const sysEvent_t res_none = { SE_NONE, 0, 0, 0, NULL };

#if SDL_VERSION_ATLEAST(2, 0, 0)
	static char s[SDL_TEXTINPUTEVENT_TEXT_SIZE] = {0};
	static size_t s_pos = 0;

	if (s[0] != '\0') {
		res.evType = SE_CHAR;
		res.evValue = s[s_pos];

		++s_pos;

		if (!s[s_pos] || s_pos == SDL_TEXTINPUTEVENT_TEXT_SIZE) {
			memset(s, 0, sizeof(s));
			s_pos = 0;
		}

		return res;
	}
#endif

	static byte c = 0;

	if (c) {
		res.evType = SE_CHAR;
		res.evValue = c;

		c = 0;

		return res;
	}

	// loop until there is an event we care about (will return then) or no more events
	while(SDL_PollEvent(&ev)) {
		switch (ev.type) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
		case SDL_WINDOWEVENT:
			switch (ev.window.event) {
				case SDL_WINDOWEVENT_FOCUS_GAINED: {
						// unset modifier, in case alt-tab was used to leave window and ALT is still set
						// as that can cause fullscreen-toggling when pressing enter...
						SDL_Keymod currentmod = SDL_GetModState();
					
						int newmod = KMOD_NONE;
						if (currentmod & KMOD_CAPS) // preserve capslock
							newmod |= KMOD_CAPS;

						SDL_SetModState((SDL_Keymod)newmod);
					} // new context because visual studio complains about newmod and currentmod not initialized because of the case SDL_WINDOWEVENT_FOCUS_LOST

					GLimp_GrabInput(GRAB_ENABLE | GRAB_REENABLE | GRAB_HIDECURSOR);
					break;
				case SDL_WINDOWEVENT_FOCUS_LOST:
					GLimp_GrabInput(0);
					break;
			}

			continue; // handle next event
#else
		case SDL_ACTIVEEVENT:
			{
				int flags = 0;

				if (ev.active.gain) {
					flags = GRAB_ENABLE | GRAB_REENABLE | GRAB_HIDECURSOR;

					// unset modifier, in case alt-tab was used to leave window and ALT is still set
					// as that can cause fullscreen-toggling when pressing enter...
					SDLMod currentmod = SDL_GetModState();
					int newmod = KMOD_NONE;
					if (currentmod & KMOD_CAPS) // preserve capslock
						newmod |= KMOD_CAPS;

					SDL_SetModState((SDLMod)newmod);
				}

				GLimp_GrabInput(flags);
			}

			continue; // handle next event

		case SDL_VIDEOEXPOSE:
			continue; // handle next event
#endif

		case SDL_KEYDOWN:
			if (ev.key.keysym.sym == SDLK_RETURN && (ev.key.keysym.mod & KMOD_ALT) > 0) {
				cvarSystem->SetCVarBool("r_fullscreen", !renderSystem->IsFullScreen());
				PushConsoleEvent("vid_restart");
				return res_none;
			}

			// fall through
		case SDL_KEYUP:
			key = mapkey(ev.key.keysym.sym);
#if !SDL_VERSION_ATLEAST(2, 0, 0)
			if (!key) {
				unsigned char c;
				// check if its an unmapped console key
				if (ev.key.keysym.unicode == (c = Sys_GetConsoleKey(false))) {
					key = c;
				} else if (ev.key.keysym.unicode == (c = Sys_GetConsoleKey(true))) {
					key = c;
				} else {
					if (ev.type == SDL_KEYDOWN)
						common->Warning("unmapped SDL key %d (0x%x)", ev.key.keysym.sym, ev.key.keysym.unicode);
					continue; // handle next event
				}
			}
#else
			if(!key) {
				if (ev.key.keysym.scancode == SDL_SCANCODE_GRAVE) { // TODO: always do this check?
					key = Sys_GetConsoleKey(true);
				} else {
					if (ev.type == SDL_KEYDOWN) {
						common->Warning("unmapped SDL key %d", ev.key.keysym.sym);
					}
					continue; // handle next event
				}
			}

#endif

			res.evType = SE_KEY;
			res.evValue = key;
			res.evValue2 = ev.key.state == SDL_PRESSED ? 1 : 0;

			kbd_polls.Append(kbd_poll_t(key, ev.key.state == SDL_PRESSED));

#if SDL_VERSION_ATLEAST(2, 0, 0)
			if (key == K_BACKSPACE && ev.key.state == SDL_PRESSED)
				c = key;
#else
			if (ev.key.state == SDL_PRESSED && (ev.key.keysym.unicode & 0xff00) == 0)
				c = ev.key.keysym.unicode & 0xff;
#endif

			return res;

#if SDL_VERSION_ATLEAST(2, 0, 0)
		case SDL_TEXTINPUT:
			if (ev.text.text[0]) {
				res.evType = SE_CHAR;
				res.evValue = ev.text.text[0];

				if (ev.text.text[1] != '\0')
				{
					memcpy(s, ev.text.text, SDL_TEXTINPUTEVENT_TEXT_SIZE);
					s_pos = 1; // pos 0 is returned
				}
				return res;
			}

			continue; // handle next event
#endif

		case SDL_MOUSEMOTION:
			res.evType = SE_MOUSE;
			res.evValue = ev.motion.xrel;
			res.evValue2 = ev.motion.yrel;

			mouse_polls.Append(mouse_poll_t(M_DELTAX, ev.motion.xrel));
			mouse_polls.Append(mouse_poll_t(M_DELTAY, ev.motion.yrel));

			return res;

#if SDL_VERSION_ATLEAST(2, 0, 0)
		case SDL_MOUSEWHEEL:
			res.evType = SE_KEY;

			if (ev.wheel.y > 0) {
				res.evValue = K_MWHEELUP;
				mouse_polls.Append(mouse_poll_t(M_DELTAZ, 1));
			} else {
				res.evValue = K_MWHEELDOWN;
				mouse_polls.Append(mouse_poll_t(M_DELTAZ, -1));
			}

			res.evValue2 = 1;

			return res;
#endif

		case SDL_MOUSEBUTTONDOWN:
		case SDL_MOUSEBUTTONUP:
			res.evType = SE_KEY;

			switch (ev.button.button) {
			case SDL_BUTTON_LEFT:
				res.evValue = K_MOUSE1;
				mouse_polls.Append(mouse_poll_t(M_ACTION1, ev.button.state == SDL_PRESSED ? 1 : 0));
				break;
			case SDL_BUTTON_MIDDLE:
				res.evValue = K_MOUSE3;
				mouse_polls.Append(mouse_poll_t(M_ACTION3, ev.button.state == SDL_PRESSED ? 1 : 0));
				break;
			case SDL_BUTTON_RIGHT:
				res.evValue = K_MOUSE2;
				mouse_polls.Append(mouse_poll_t(M_ACTION2, ev.button.state == SDL_PRESSED ? 1 : 0));
				break;

#if !SDL_VERSION_ATLEAST(2, 0, 0)
			case SDL_BUTTON_WHEELUP:
				res.evValue = K_MWHEELUP;
				if (ev.button.state == SDL_PRESSED)
					mouse_polls.Append(mouse_poll_t(M_DELTAZ, 1));
				break;
			case SDL_BUTTON_WHEELDOWN:
				res.evValue = K_MWHEELDOWN;
				if (ev.button.state == SDL_PRESSED)
					mouse_polls.Append(mouse_poll_t(M_DELTAZ, -1));
				break;
#endif
			}

			res.evValue2 = ev.button.state == SDL_PRESSED ? 1 : 0;

			return res;

		case SDL_QUIT:
			PushConsoleEvent("quit");
			return res_none;

		case SDL_USEREVENT:
			switch (ev.user.code) {
			case SE_CONSOLE:
				res.evType = SE_CONSOLE;
				res.evPtrLength = (intptr_t)ev.user.data1;
				res.evPtr = ev.user.data2;
				return res;
			default:
				common->Warning("unknown user event %u", ev.user.code);
				continue; // handle next event
			}
		default:
			common->Warning("unknown event %u", ev.type);
			continue; // handle next event
		}
	}

	return res_none;
}
예제 #2
0
파일: events.cpp 프로젝트: Edgarins29/Doom3
/*
================
Sys_GetEvent
================
*/
sysEvent_t Sys_GetEvent() {
	SDL_Event ev;
	sysEvent_t res = { };
	byte key;

	static const sysEvent_t res_none = { SE_NONE, 0, 0, 0, NULL };
	static byte c = 0;

	if (c) {
		res.evType = SE_CHAR;
		res.evValue = c;

		c = 0;

		return res;
	}

	if (SDL_PollEvent(&ev)) {
		switch (ev.type) {
		case SDL_ACTIVEEVENT:
			GrabInput(grabbed && ev.active.gain == 1, ev.active.gain == 1, false);
			return res_none;

		case SDL_VIDEOEXPOSE:
			return res_none;

		case SDL_KEYDOWN:
			if (ev.key.keysym.sym == SDLK_RETURN && (ev.key.keysym.mod & KMOD_ALT) > 0) {
				cvarSystem->SetCVarBool("r_fullscreen", !renderSystem->IsFullScreen());
				PushConsoleEvent("vid_restart");
				return res_none;
			}

			// fall through
		case SDL_KEYUP:
			key = mapkey(ev.key.keysym.sym);

			if (!key) {
				unsigned char c;

				// check if its an unmapped console key
				if (ev.key.keysym.unicode == (c = Sys_GetConsoleKey(false))) {
					key = c;
				} else if (ev.key.keysym.unicode == (c = Sys_GetConsoleKey(true))) {
					key = c;
				} else {
					if (ev.type == SDL_KEYDOWN)
						common->Warning("unmapped SDL key %d (0x%x)", ev.key.keysym.sym, ev.key.keysym.unicode);
					return res_none;
				}
			}

			res.evType = SE_KEY;
			res.evValue = key;
			res.evValue2 = ev.key.state == SDL_PRESSED ? 1 : 0;

			kbd_polls.Append(kbd_poll_t(key, ev.key.state == SDL_PRESSED));

			if (ev.key.state == SDL_PRESSED && (ev.key.keysym.unicode & 0xff00) == 0)
				c = ev.key.keysym.unicode & 0xff;

			return res;

		case SDL_MOUSEMOTION:
			res.evType = SE_MOUSE;
			res.evValue = ev.motion.xrel;
			res.evValue2 = ev.motion.yrel;

			mouse_polls.Append(mouse_poll_t(M_DELTAX, ev.motion.xrel));
			mouse_polls.Append(mouse_poll_t(M_DELTAY, ev.motion.yrel));

			return res;

		case SDL_MOUSEBUTTONDOWN:
		case SDL_MOUSEBUTTONUP:
			res.evType = SE_KEY;

			switch (ev.button.button) {
			case SDL_BUTTON_LEFT:
				res.evValue = K_MOUSE1;
				mouse_polls.Append(mouse_poll_t(M_ACTION1, ev.button.state == SDL_PRESSED ? 1 : 0));
				break;
			case SDL_BUTTON_MIDDLE:
				res.evValue = K_MOUSE3;
				mouse_polls.Append(mouse_poll_t(M_ACTION3, ev.button.state == SDL_PRESSED ? 1 : 0));
				break;
			case SDL_BUTTON_RIGHT:
				res.evValue = K_MOUSE2;
				mouse_polls.Append(mouse_poll_t(M_ACTION2, ev.button.state == SDL_PRESSED ? 1 : 0));
				break;
			case SDL_BUTTON_WHEELUP:
				res.evValue = K_MWHEELUP;
				if (ev.button.state == SDL_PRESSED)
					mouse_polls.Append(mouse_poll_t(M_DELTAZ, 1));
				break;
			case SDL_BUTTON_WHEELDOWN:
				res.evValue = K_MWHEELDOWN;
				if (ev.button.state == SDL_PRESSED)
					mouse_polls.Append(mouse_poll_t(M_DELTAZ, -1));
				break;
			}

			res.evValue2 = ev.button.state == SDL_PRESSED ? 1 : 0;

			return res;

		case SDL_QUIT:
			PushConsoleEvent("quit");
			return res_none;

		case SDL_USEREVENT:
			switch (ev.user.code) {
			case SE_CONSOLE:
				res.evType = SE_CONSOLE;
				res.evPtrLength = (intptr_t)ev.user.data1;
				res.evPtr = ev.user.data2;
				return res;
			default:
				common->Warning("unknown user event %u", ev.user.code);
				return res_none;
			}
		default:
			common->Warning("unknown event %u", ev.type);
			return res_none;
		}
	}

	return res_none;
}
예제 #3
0
/*
================
Sys_GetEvent
================
*/
sysEvent_t Sys_GetEvent() {
	SDL_Event ev;
	sysEvent_t res = { };
	byte key;

	static const sysEvent_t res_none = { SE_NONE, 0, 0, 0, NULL };

	// process any overflow.
	if (event_overflow.Num() > 0)
	{
		res = event_overflow[0];
		event_overflow.RemoveIndex(0);
		return res;
	}

	// overflow text input.
	static char *s = NULL;
	static size_t s_pos = 0;

	if (s) {
		res.evType = SE_CHAR;
		res.evValue = s[s_pos];

		s_pos++;
		if (!s[s_pos]) {
			free(s);
			s = NULL;
			s_pos = 0;
		}

		return res;
	}

	static byte c = 0;

	if (c) {
		res.evType = SE_CHAR;
		res.evValue = c;

		c = 0;

		return res;
	}

    bool getNext = true;
	while (SDL_PollEvent(&ev) && getNext) {
        getNext = false;
		switch (ev.type) {
#ifdef __WINDOWS__ // on windows we need to grab the hwnd.
		case SDL_SYSWMEVENT:
			if (win32.hWnd == NULL)
			{
				win32.hWnd = ev.syswm.msg->msg.win.hwnd;
			}
			getNext = true; // try to get a decent event.
			break;
#endif
		case SDL_WINDOWEVENT:
			switch (ev.window.event) {
				case SDL_WINDOWEVENT_FOCUS_GAINED: {
						// unset modifier, in case alt-tab was used to leave window and ALT is still set
						// as that can cause fullscreen-toggling when pressing enter...
						SDL_Keymod currentmod = SDL_GetModState();
					
						int newmod = KMOD_NONE;
						if (currentmod & KMOD_CAPS) // preserve capslock
							newmod |= KMOD_CAPS;

						SDL_SetModState((SDL_Keymod)newmod);
					} // new context because visual studio complains about newmod and currentmod not initialized because of the case SDL_WINDOWEVENT_FOCUS_LOST

					GLimp_GrabInput(GRAB_ENABLE | GRAB_REENABLE | GRAB_HIDECURSOR);
					break;
				case SDL_WINDOWEVENT_FOCUS_LOST:
					GLimp_GrabInput(0);
					break;
			}

			return res_none;

		case SDL_KEYDOWN:
			if (ev.key.keysym.sym == SDLK_RETURN && (ev.key.keysym.mod & KMOD_ALT) > 0) {
				cvarSystem->SetCVarBool("r_fullscreen", !renderSystem->IsFullScreen());
				PushConsoleEvent("vid_restart");
				return res_none;
			}

			// fall through
		case SDL_KEYUP:
			key = mapkey(ev.key.keysym.sym);
			if(!key) {
				if (ev.key.keysym.scancode == SDL_SCANCODE_GRAVE) {
					key = Sys_GetConsoleKey(true);
				} else {
					if (ev.type == SDL_KEYDOWN) {
						common->Warning("unmapped SDL key %d", ev.key.keysym.sym);
            			getNext = true; // try to get a decent event.
						break;
					}

				}
			}

			res.evType = SE_KEY;
			res.evValue = key;
			res.evValue2 = ev.key.state == SDL_PRESSED ? 1 : 0;

			kbd_polls.Append(kbd_poll_t(key, ev.key.state == SDL_PRESSED));

			if ( (key == K_BACKSPACE && ev.key.state == SDL_PRESSED)
				|| SDL_GetEventState(SDL_TEXTINPUT) == SDL_DISABLE)
				c = key;

			return res;

		case SDL_TEXTINPUT:
			if (ev.text.text && *ev.text.text) {

				res.evType = SE_CHAR;
				res.evValue = *ev.text.text;
				
				// if there are more characters hold onto them for later events.
				if (ev.text.text[1] != 0)
					s = strdup(ev.text.text+1);

				return res;
			}

			getNext = true; // try to get a decent event.
			break;

		case SDL_MOUSEMOTION:
			if (g_inputGrabbed)
			{
				res.evType = SE_MOUSE;

				res.evValue = ev.motion.xrel;
				res.evValue2 = ev.motion.yrel;

				mouse_polls.Append(mouse_poll_t(M_DELTAX, ev.motion.xrel));
				mouse_polls.Append(mouse_poll_t(M_DELTAY, ev.motion.yrel));
			
				return res;
			}

			getNext = true;
			break;

		case SDL_MOUSEWHEEL:
			if (g_inputGrabbed)
			{
				res.evType = SE_KEY;

				if (ev.wheel.y > 0) {
					res.evValue = K_MWHEELUP;
					mouse_polls.Append(mouse_poll_t(M_DELTAZ, 1));
				} else {
					res.evValue = K_MWHEELDOWN;
					mouse_polls.Append(mouse_poll_t(M_DELTAZ, -1));
				}

				res.evValue2 = 1;

				return res;
			}

			getNext = true;
			break;

		case SDL_MOUSEBUTTONDOWN:
		case SDL_MOUSEBUTTONUP:
			if (g_inputGrabbed)
			{
				res.evType = SE_KEY;

				switch (ev.button.button) {
				case SDL_BUTTON_LEFT:
					res.evValue = K_MOUSE1;
					mouse_polls.Append(mouse_poll_t(M_ACTION1, ev.button.state == SDL_PRESSED ? 1 : 0));
					break;
				case SDL_BUTTON_MIDDLE:
					res.evValue = K_MOUSE3;
					mouse_polls.Append(mouse_poll_t(M_ACTION3, ev.button.state == SDL_PRESSED ? 1 : 0));
					break;
				case SDL_BUTTON_RIGHT:
					res.evValue = K_MOUSE2;
					mouse_polls.Append(mouse_poll_t(M_ACTION2, ev.button.state == SDL_PRESSED ? 1 : 0));
					break;
				}

				res.evValue2 = ev.button.state == SDL_PRESSED ? 1 : 0;

				return res;
			}

			getNext = true;
			break;

		case SDL_CONTROLLERBUTTONDOWN:
		case SDL_CONTROLLERBUTTONUP:
			{
				sys_jEvents jEvent =  mapjoybutton( (SDL_GameControllerButton)ev.cbutton.button);
				joystick_polls.Append(joystick_poll_t(	jEvent,
														ev.cbutton.state == SDL_PRESSED ? 1 : 0) );

				res.evType = SE_KEY;
				res.evValue2 = ev.cbutton.state == SDL_PRESSED ? 1 : 0;
				if ( ( jEvent >= J_ACTION1 ) && ( jEvent <= J_ACTION_MAX ) ) {
					res.evValue = K_JOY1 + ( jEvent - J_ACTION1 );
					return res;
				} else if ( ( jEvent >= J_DPAD_UP ) && ( jEvent <= J_DPAD_RIGHT ) ) {
					res.evValue = K_JOY_DPAD_UP + ( jEvent - J_DPAD_UP );
					return res;
				}

				getNext = true; // try to get a decent event.
			}
			break;

		case SDL_CONTROLLERAXISMOTION:
			{
				const int range = 16384;

				sys_jEvents jEvent = mapjoyaxis( (SDL_GameControllerAxis)ev.caxis.axis);
				joystick_polls.Append(joystick_poll_t(	jEvent, ev.caxis.value) );

				if ( jEvent == J_AXIS_LEFT_X ) {
					PushButton( K_JOY_STICK1_LEFT, ( ev.caxis.value < -range ) );
					PushButton( K_JOY_STICK1_RIGHT, ( ev.caxis.value > range ) );
				} else if ( jEvent == J_AXIS_LEFT_Y ) {
					PushButton( K_JOY_STICK1_UP, ( ev.caxis.value < -range ) );
					PushButton( K_JOY_STICK1_DOWN, ( ev.caxis.value > range ) );
				} else if ( jEvent == J_AXIS_RIGHT_X ) {
					PushButton( K_JOY_STICK2_LEFT, ( ev.caxis.value < -range ) );
					PushButton( K_JOY_STICK2_RIGHT, ( ev.caxis.value > range ) );
				} else if ( jEvent == J_AXIS_RIGHT_Y ) {
					PushButton( K_JOY_STICK2_UP, ( ev.caxis.value < -range ) );
					PushButton( K_JOY_STICK2_DOWN, ( ev.caxis.value > range ) );
				} else if ( jEvent == J_AXIS_LEFT_TRIG ) {
					PushButton( K_JOY_TRIGGER1, ( ev.caxis.value > range ) );
				} else if ( jEvent == J_AXIS_RIGHT_TRIG ) {
					PushButton( K_JOY_TRIGGER2, ( ev.caxis.value > range ) );
				}
				if ( jEvent >= J_AXIS_MIN && jEvent <= J_AXIS_MAX ) {
					int axis = jEvent - J_AXIS_MIN;
					int percent = ( ev.caxis.value * 16 ) / range;
					if ( joyAxis[axis] != percent ) {
						joyAxis[axis] = percent;
						res.evType = SE_JOYSTICK;
						res.evValue = axis;
						res.evValue2 = percent;
						return res;
					}
				}

				getNext = true; // try to get a decent event.
			}
			break;

		case SDL_JOYDEVICEADDED:
			SDL_GameControllerOpen( ev.jdevice.which );
			// TODO: hot swapping maybe.
			//lbOnControllerPlugIn(event.jdevice.which);
			break;

		case SDL_JOYDEVICEREMOVED:
			// TODO: hot swapping maybe.
			//lbOnControllerUnPlug(event.jdevice.which);
			break;

		case SDL_QUIT:
			PushConsoleEvent("quit");
			return res_none;

		case SDL_USEREVENT:
			switch (ev.user.code) {
			case SE_CONSOLE:
				res.evType = SE_CONSOLE;
				res.evPtrLength = (intptr_t)ev.user.data1;
				res.evPtr = ev.user.data2;
				return res;
			default:
				common->Warning("unknown user event %u", ev.user.code);
            	getNext = true; // try to get a decent event.
            	break;
			}
		default:
            getNext = true; // try to get a decent event.
            break;
		}
	}

	return res_none;
}
예제 #4
0
/*
================
Sys_GetEvent
================
*/
sysEvent_t Sys_GetEvent() {
	SDL_Event ev;
	sysEvent_t res = { };
	byte key;

	static const sysEvent_t res_none = { SE_NONE, 0, 0, 0, NULL };

	static char *s = NULL;
	static size_t s_pos = 0;

	if (s) {
		res.evType = SE_CHAR;
		res.evValue = s[s_pos];

		s_pos++;
		if (!s[s_pos]) {
			free(s);
			s = NULL;
			s_pos = 0;
		}

		return res;
	}

	static byte c = 0;

	if (c) {
		res.evType = SE_CHAR;
		res.evValue = c;

		c = 0;

		return res;
	}

	if (SDL_PollEvent(&ev)) {
		switch (ev.type) {
		case SDL_WINDOWEVENT:
			switch (ev.window.event) {
			        case SDL_WINDOWEVENT_SHOWN:
					SDL_Log("Window %d shown", ev.window.windowID);
					break;
				case SDL_WINDOWEVENT_HIDDEN:
					SDL_Log("Window %d hidden", ev.window.windowID);
					break;
				case SDL_WINDOWEVENT_EXPOSED:
					SDL_Log("Window %d exposed", ev.window.windowID);
					break;
				case SDL_WINDOWEVENT_MOVED:
					SDL_Log("Window %d moved to %d,%d",
							ev.window.windowID, ev.window.data1,
							ev.window.data2);
					break;
				case SDL_WINDOWEVENT_RESIZED:
					SDL_Log("Window %d resized to %dx%d",
							ev.window.windowID, ev.window.data1,
							ev.window.data2);
					break;
				case SDL_WINDOWEVENT_MINIMIZED:
					SDL_Log("Window %d minimized", ev.window.windowID);
					break;
				case SDL_WINDOWEVENT_MAXIMIZED:
					SDL_Log("Window %d maximized", ev.window.windowID);
					break;
				case SDL_WINDOWEVENT_RESTORED:
					SDL_Log("Window %d restored", ev.window.windowID);
					break;
				case SDL_WINDOWEVENT_ENTER:
					SDL_Log("Mouse entered window %d",
							ev.window.windowID);
					break;
				case SDL_WINDOWEVENT_LEAVE:
					SDL_Log("Mouse left window %d", ev.window.windowID);
					break;
				case SDL_WINDOWEVENT_FOCUS_GAINED:
					SDL_Log("Window %d gained keyboard focus",
							ev.window.windowID);
					cvarSystem->SetCVarBool( "com_pause", false );
					GLimp_GrabInput(GRAB_ENABLE | GRAB_REENABLE | GRAB_HIDECURSOR);
					break;
				case SDL_WINDOWEVENT_FOCUS_LOST:
					SDL_Log("Window %d lost keyboard focus",
							ev.window.windowID);
					cvarSystem->SetCVarBool( "com_pause", true );
					GLimp_GrabInput(0);
					break;
				case SDL_WINDOWEVENT_CLOSE:
					SDL_Log("Window %d closed", ev.window.windowID);
					break;
				default:
					SDL_Log("Window %d got unknown event %d",
							ev.window.windowID, ev.window.event);
					break;
			}

			return res_none;

		case SDL_KEYDOWN:
			if (ev.key.keysym.sym == SDLK_RETURN && (ev.key.keysym.mod & KMOD_ALT) > 0) {
				cvarSystem->SetCVarBool("r_fullscreen", !renderSystem->IsFullScreen());
				PushConsoleEvent("vid_restart");
				/*
				 * FIXME vid_restart
				 */

				return res_none;
			}

			// fall through
		case SDL_KEYUP:
			key = mapkey(ev.key.keysym.sym);
			if(!key) {
				if (ev.key.keysym.scancode == SDL_SCANCODE_GRAVE) {
					key = Sys_GetConsoleKey(true);
				} else {
					if (ev.type == SDL_KEYDOWN) {
						common->Warning("unmapped SDL key %d", ev.key.keysym.sym);
					return res_none;
					}

				}
			}

			res.evType = SE_KEY;
			res.evValue = key;
			res.evValue2 = ev.key.state == SDL_PRESSED ? 1 : 0;

			kbd_polls.Append(kbd_poll_t(key, ev.key.state == SDL_PRESSED));

			if (key == K_BACKSPACE && ev.key.state == SDL_PRESSED)
				c = key;

			return res;

		case SDL_TEXTINPUT:
			if (ev.text.text && *ev.text.text) {
				if (!ev.text.text[1])
					c = *ev.text.text;
				else
					s = strdup(ev.text.text);
			}

			return res_none;
		case SDL_TEXTEDITING:
		  SDL_StartTextInput();
		  SDL_Log("SDL_TextEditingEvent");
		  //SDL_StopTextInput();
		  break;
		case SDL_SYSWMEVENT:
		  SDL_Log("SDL_SYSWMEVENT");
		  break;
		case SDL_CLIPBOARDUPDATE:
		  SDL_Log("SDL_CLIPBOARDUPDATE");
		  break;

		case SDL_MOUSEMOTION:
			res.evType = SE_MOUSE;
			res.evValue = ev.motion.xrel;
			res.evValue2 = ev.motion.yrel;

			mouse_polls.Append(mouse_poll_t(M_DELTAX, ev.motion.xrel));
			mouse_polls.Append(mouse_poll_t(M_DELTAY, ev.motion.yrel));

			return res;

		case SDL_MOUSEWHEEL:
			res.evType = SE_KEY;

			if (ev.wheel.y > 0) {
				res.evValue = K_MWHEELUP;
				mouse_polls.Append(mouse_poll_t(M_DELTAZ, 1));
			} else {
				res.evValue = K_MWHEELDOWN;
				mouse_polls.Append(mouse_poll_t(M_DELTAZ, -1));
			}

			res.evValue2 = 1;

			return res;

		case SDL_MOUSEBUTTONDOWN:
		case SDL_MOUSEBUTTONUP:
			res.evType = SE_KEY;

			switch (ev.button.button) {
			case SDL_BUTTON_LEFT:
				res.evValue = K_MOUSE1;
				mouse_polls.Append(mouse_poll_t(M_ACTION1, ev.button.state == SDL_PRESSED ? 1 : 0));
				break;
			case SDL_BUTTON_MIDDLE:
				res.evValue = K_MOUSE3;
				mouse_polls.Append(mouse_poll_t(M_ACTION3, ev.button.state == SDL_PRESSED ? 1 : 0));
				break;
			case SDL_BUTTON_RIGHT:
				res.evValue = K_MOUSE2;
				mouse_polls.Append(mouse_poll_t(M_ACTION2, ev.button.state == SDL_PRESSED ? 1 : 0));
				break;

			}

			res.evValue2 = ev.button.state == SDL_PRESSED ? 1 : 0;

			return res;

		case SDL_QUIT:
			PushConsoleEvent("quit");
			SDL_Quit();
			return res_none;

		case SDL_USEREVENT:
			switch (ev.user.code) {
			case SE_CONSOLE:
				res.evType = SE_CONSOLE;
				res.evPtrLength = (intptr_t)ev.user.data1;
				res.evPtr = ev.user.data2;
				return res;
			default:
				common->Warning("unknown user event %u", ev.user.code);
				return res_none;
			}
		default:
			common->Warning("unknown event %u", ev.type);
			return res_none;
		}
	}

	return res_none;
}
예제 #5
0
/*
================
Sys_GetEvent
================
*/
sysEvent_t Sys_GetEvent() {
	SDL_Event ev;
	sysEvent_t res = { };
	byte key;

	static const sysEvent_t res_none = { SE_NONE, 0, 0, 0, NULL };

	static char *s = NULL;
	static size_t s_pos = 0;

	if (s) {
		res.evType = SE_CHAR;
		res.evValue = s[s_pos];

		s_pos++;
		if (!s[s_pos]) {
			free(s);
			s = NULL;
			s_pos = 0;
		}

		return res;
	}

	static byte c = 0;

	if (c) {
		res.evType = SE_CHAR;
		res.evValue = c;

		c = 0;

		return res;
	}

	if (SDL_PollEvent(&ev)) {
		switch (ev.type) {
		case SDL_WINDOWEVENT:
			switch (ev.window.event) {
				case SDL_WINDOWEVENT_FOCUS_GAINED:
					{
						// unset modifier, in case alt-tab was used to leave window and ALT is still set
						// as that can cause fullscreen-toggling when pressing enter...
						SDL_Keymod currentmod = SDL_GetModState();
						int newmod = KMOD_NONE;
						if (currentmod & KMOD_CAPS) // preserve capslock
							newmod |= KMOD_CAPS;

						SDL_SetModState((SDL_Keymod)newmod);

						GLimp_GrabInput(GRAB_ENABLE | GRAB_REENABLE | GRAB_HIDECURSOR);
						break;
					}
				case SDL_WINDOWEVENT_FOCUS_LOST:
					GLimp_GrabInput(0);
					break;
			}

			return res_none;

		case SDL_KEYDOWN:
			if (ev.key.keysym.sym == SDLK_RETURN && (ev.key.keysym.mod & KMOD_ALT) > 0) {
				cvarSystem->SetCVarBool("r_fullscreen", !renderSystem->IsFullScreen());
				PushConsoleEvent("vid_restart");
				return res_none;
			}

			// fall through
		case SDL_KEYUP:
			key = mapkey(ev.key.keysym.sym);

			if (!key) {
				unsigned char c;

				// check if its an unmapped console key
				if (ev.key.keysym.unicode == (c = Sys_GetConsoleKey(false))) {
					key = c;
				} else if (ev.key.keysym.unicode == (c = Sys_GetConsoleKey(true))) {
					key = c;
				} else {
					if (ev.type == SDL_KEYDOWN)
						common->Warning("unmapped SDL key %d (0x%x)", ev.key.keysym.sym, ev.key.keysym.unicode);
					return res_none;
				}
			}

			res.evType = SE_KEY;
			res.evValue = key;
			res.evValue2 = ev.key.state == SDL_PRESSED ? 1 : 0;

			kbd_polls.Append(kbd_poll_t(key, ev.key.state == SDL_PRESSED));

			if (key == K_BACKSPACE && ev.key.state == SDL_PRESSED)
				c = key;

			return res;

		case SDL_TEXTINPUT:
			if (ev.text.text && *ev.text.text) {
				if (!ev.text.text[1])
					c = *ev.text.text;
				else
					s = strdup(ev.text.text);
			}

			return res_none;

		case SDL_MOUSEMOTION:
			res.evType = SE_MOUSE;
			res.evValue = ev.motion.xrel;
			res.evValue2 = ev.motion.yrel;

			mouse_polls.Append(mouse_poll_t(M_DELTAX, ev.motion.xrel));
			mouse_polls.Append(mouse_poll_t(M_DELTAY, ev.motion.yrel));

			return res;

		case SDL_MOUSEWHEEL:
			res.evType = SE_KEY;

			if (ev.wheel.y > 0) {
				res.evValue = K_MWHEELUP;
				mouse_polls.Append(mouse_poll_t(M_DELTAZ, 1));
			} else {
				res.evValue = K_MWHEELDOWN;
				mouse_polls.Append(mouse_poll_t(M_DELTAZ, -1));
			}

			res.evValue2 = 1;

			return res;

		case SDL_MOUSEBUTTONDOWN:
		case SDL_MOUSEBUTTONUP:
			res.evType = SE_KEY;

			switch (ev.button.button) {
			case SDL_BUTTON_LEFT:
				res.evValue = K_MOUSE1;
				mouse_polls.Append(mouse_poll_t(M_ACTION1, ev.button.state == SDL_PRESSED ? 1 : 0));
				break;
			case SDL_BUTTON_MIDDLE:
				res.evValue = K_MOUSE3;
				mouse_polls.Append(mouse_poll_t(M_ACTION3, ev.button.state == SDL_PRESSED ? 1 : 0));
				break;
			case SDL_BUTTON_RIGHT:
				res.evValue = K_MOUSE2;
				mouse_polls.Append(mouse_poll_t(M_ACTION2, ev.button.state == SDL_PRESSED ? 1 : 0));
				break;

			}

			res.evValue2 = ev.button.state == SDL_PRESSED ? 1 : 0;

			return res;

		case SDL_QUIT:
			PushConsoleEvent("quit");
			return res_none;

		case SDL_USEREVENT:
			switch (ev.user.code) {
			case SE_CONSOLE:
				res.evType = SE_CONSOLE;
				res.evPtrLength = (intptr_t)ev.user.data1;
				res.evPtr = ev.user.data2;
				return res;
			default:
				common->Warning("unknown user event %u", ev.user.code);
				return res_none;
			}
		default:
			common->Warning("unknown event %u", ev.type);
			return res_none;
		}
	}

	return res_none;
}