Пример #1
0
/*
===================
Key_Event

Called by the system between frames for both key up and key down events
Should NOT be called during an interrupt!
===================
*/
void Key_Event(unsigned key, qboolean down, unsigned time)
{
    char    *kb;
    char    cmd[MAX_STRING_CHARS];

    if (key >= 256) {
        Com_Error(ERR_FATAL, "%s: bad key", __func__);
    }

    Com_DDDPrintf("%u: %c%s\n", time,
                  down ? '+' : '-', Key_KeynumToString(key));

    // hack for menu key binding
    if (key_wait_cb && down && !key_wait_cb(key_wait_arg, key)) {
        return;
    }

    // update key down and auto-repeat status
    if (down) {
        if (keydown[key] < 255)
            keydown[key]++;
    } else {
        keydown[key] = 0;
    }

    // console key is hardcoded, so the user can never unbind it
    if (!Key_IsDown(K_SHIFT) && (key == '`' || key == '~')) {
        if (keydown[key] == 1) {
            Con_ToggleConsole_f();
        }
        return;
    }

    // Alt+Enter is hardcoded for all systems
    if (Key_IsDown(K_ALT) && key == K_ENTER) {
        if (keydown[key] == 1) {
            VID_ToggleFullscreen();
        }
        return;
    }

    // menu key is hardcoded, so the user can never unbind it
    if (key == K_ESCAPE) {
        if (!down) {
            return;
        }

        if (cls.key_dest == KEY_GAME &&
            cl.frame.ps.stats[STAT_LAYOUTS] &&
            cls.demo.playback == qfalse) {
            if (keydown[key] == 2) {
                // force main menu if escape is held
                UI_OpenMenu(UIMENU_GAME);
            } else if (keydown[key] == 1) {
                // put away help computer / inventory
                CL_ClientCommand("putaway");
            }
            return;
        }

        // ignore autorepeats
        if (keydown[key] > 1) {
            return;
        }

        if (cls.key_dest & KEY_CONSOLE) {
            if (cls.state < ca_active && !(cls.key_dest & KEY_MENU)) {
                UI_OpenMenu(UIMENU_MAIN);
            } else {
                Con_Close(qtrue);
            }
        } else if (cls.key_dest & KEY_MENU) {
            UI_Keydown(key);
        } else if (cls.key_dest & KEY_MESSAGE) {
            Key_Message(key);
        } else if (cls.state == ca_active) {
            UI_OpenMenu(UIMENU_GAME);
        } else {
            UI_OpenMenu(UIMENU_MAIN);
        }
        return;
    }

    // track if any key is down for BUTTON_ANY
    if (down) {
        if (keydown[key] == 1)
            anykeydown++;
    } else {
        anykeydown--;
        if (anykeydown < 0)
            anykeydown = 0;
    }

    // hack for demo freelook in windowed mode
    if (cls.key_dest == KEY_GAME && cls.demo.playback && key == K_SHIFT && keydown[key] <= 1) {
        IN_Activate();
    }

//
// if not a consolekey, send to the interpreter no matter what mode is
//
    if ((cls.key_dest == KEY_GAME) ||
        ((cls.key_dest & KEY_CONSOLE) && !Q_IsBitSet(consolekeys, key)) ||
        ((cls.key_dest & KEY_MENU) && (key >= K_F1 && key <= K_F12)) ||
        (!down && Q_IsBitSet(buttondown, key))) {
//
// Key up events only generate commands if the game key binding is a button
// command (leading + sign). These will occur even in console mode, to keep the
// character from continuing an action started before a console switch. Button
// commands include the kenum as a parameter, so multiple downs can be matched
// with ups.
//
        if (!down) {
            kb = keybindings[key];
            if (kb && kb[0] == '+') {
                Q_snprintf(cmd, sizeof(cmd), "-%s %i %i\n",
                           kb + 1, key, time);
                Cbuf_AddText(&cmd_buffer, cmd);
            }
            Q_ClearBit(buttondown, key);
            return;
        }

        // ignore autorepeats
        if (keydown[key] > 1) {
            return;
        }

        // generate button up command when released
        Q_SetBit(buttondown, key);

        kb = keybindings[key];
        if (kb) {
            if (kb[0] == '+') {
                // button commands add keynum and time as a parm
                Q_snprintf(cmd, sizeof(cmd), "%s %i %i\n", kb, key, time);
                Cbuf_AddText(&cmd_buffer, cmd);
            } else {
                Cbuf_AddText(&cmd_buffer, kb);
                Cbuf_AddText(&cmd_buffer, "\n");
            }
        }
        return;
    }

    if (cls.key_dest == KEY_GAME)
        return;

    if (!down)
        return;     // other subsystems only care about key down events

    if (cls.key_dest & KEY_CONSOLE) {
        Key_Console(key);
    } else if (cls.key_dest & KEY_MENU) {
        UI_Keydown(key);
    } else if (cls.key_dest & KEY_MESSAGE) {
        Key_Message(key);
    }

    if (Key_IsDown(K_CTRL) || Key_IsDown(K_ALT)) {
        return;
    }

    switch (key) {
    case K_KP_SLASH:
        key = '/';
        break;
    case K_KP_MULTIPLY:
        key = '*';
        break;
    case K_KP_MINUS:
        key = '-';
        break;
    case K_KP_PLUS:
        key = '+';
        break;
    case K_KP_HOME:
        key = '7';
        break;
    case K_KP_UPARROW:
        key = '8';
        break;
    case K_KP_PGUP:
        key = '9';
        break;
    case K_KP_LEFTARROW:
        key = '4';
        break;
    case K_KP_5:
        key = '5';
        break;
    case K_KP_RIGHTARROW:
        key = '6';
        break;
    case K_KP_END:
        key = '1';
        break;
    case K_KP_DOWNARROW:
        key = '2';
        break;
    case K_KP_PGDN:
        key = '3';
        break;
    case K_KP_INS:
        key = '0';
        break;
    case K_KP_DEL:
        key = '.';
        break;
    }

    // if key is printable, generate char events
    if (key < 32 || key >= 127) {
        return;
    }

    if (Key_IsDown(K_SHIFT)) {
        key = keyshift[key];
    }

    if (cls.key_dest & KEY_CONSOLE) {
        Char_Console(key);
    } else if (cls.key_dest & KEY_MENU) {
        UI_CharEvent(key);
    } else if (cls.key_dest & KEY_MESSAGE) {
        Char_Message(key);
    }
}
Пример #2
0
// main window procedure
STATIC LONG WINAPI Win_MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
    switch( uMsg ) {
    case WM_MOUSEWHEEL:
        if( win.mouse.initialized == WIN_MOUSE_LEGACY ) {
            mouse_wheel_event( ( short )HIWORD( wParam ) );
        }
        break;
    case WM_MOUSEHWHEEL:
        if( win.mouse.initialized == WIN_MOUSE_LEGACY ) {
            mouse_hwheel_event( ( short )HIWORD( wParam ) );
        }
        break;

    case WM_NCMOUSEMOVE:
        if( win.mouse.initialized ) {
            // don't hide cursor
            IN_MouseEvent( -1, -1 );
        }
        break;

    case WM_MOUSEMOVE:
        if( win.mouse.initialized ) {
            int x = ( short )LOWORD( lParam );
            int y = ( short )HIWORD( lParam );

            IN_MouseEvent( x, y );
        }
        // fall through

    case WM_LBUTTONDOWN:
    case WM_LBUTTONUP:
    case WM_RBUTTONDOWN:
    case WM_RBUTTONUP:
    case WM_MBUTTONDOWN:
    case WM_MBUTTONUP:
    case WM_XBUTTONDOWN:
    case WM_XBUTTONUP:
        if( win.mouse.initialized == WIN_MOUSE_LEGACY ) {
            legacy_mouse_event( wParam );
        }
        break;

    case WM_HOTKEY:
        return FALSE;

    case WM_INPUT:
        if( wParam == RIM_INPUT && win.mouse.initialized == WIN_MOUSE_RAW ) {
            raw_input_event( ( HANDLE )lParam );
        }
        break;

    case WM_CLOSE:
        PostQuitMessage( 0 );
        return FALSE;

    case WM_ACTIVATE:
        Win_Activate( wParam );
        break;

    case WM_WINDOWPOSCHANGING:
        if( !( win.flags & QVF_FULLSCREEN ) ) {
            WINDOWPOS *pos = ( WINDOWPOS * )lParam;
            if( !( pos->flags & SWP_NOSIZE ) ) {
                resizing_event( hWnd, pos );
            }
        }
        break;

    case WM_SIZE:
        if( wParam == SIZE_RESTORED && !( win.flags & QVF_FULLSCREEN ) ) {
            int w = ( short )LOWORD( lParam );
            int h = ( short )HIWORD( lParam );

            win.rc.width = w;
            win.rc.height = h;

            win.mode_changed |= MODE_SIZE;
        }
        break;

    case WM_MOVE: 
        if( !( win.flags & QVF_FULLSCREEN ) ) {
            int x = ( short )LOWORD( lParam );
            int y = ( short )HIWORD( lParam );
            RECT r;

            // adjust for non-client area
            get_nc_area_size( hWnd, &r );
            win.rc.x = x + r.left;
            win.rc.y = y + r.top;

            win.mode_changed |= MODE_POS;
        }
        break;

    case WM_SYSCOMMAND:
        switch( wParam & 0xFFF0 ) {
        case SC_SCREENSAVE:
            return FALSE;
        case SC_MAXIMIZE:
            if( !vid_fullscreen->integer ) {
                VID_ToggleFullscreen();
            }
            return FALSE;
        }
        break;

    case WM_KEYDOWN:
    case WM_SYSKEYDOWN:
        legacy_key_event( wParam, lParam, qtrue );
        return FALSE;

    case WM_KEYUP:
    case WM_SYSKEYUP:
        legacy_key_event( wParam, lParam, qfalse );
        return FALSE;

    case WM_SYSCHAR:
    case WM_CHAR:
#if USE_CHAR_EVENTS
        Key_CharEvent( wParam );
#endif
        return FALSE;

    default:    
        break;
    }

    // pass all unhandled messages to DefWindowProc
    return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
Пример #3
0
/*
================
VID_MenuKey
================
*/
static void VID_MenuKey (int key)
{
	switch (key)
	{
	case K_ESCAPE:
		vid_cursor = (num_fmodes) ? 0 : VID_RESOLUTION;
		M_Menu_Options_f ();
		return;

	case K_ENTER:
		switch (vid_cursor)
		{
		case VID_RESET:
			vid_menu_fs = (modestate != MS_WINDOWED);
			vid_menunum = vid_modenum;
			vid_cursor = (num_fmodes) ? 0 : VID_RESOLUTION;
			break;
		case VID_APPLY:
			if (need_apply)
			{
				Cvar_SetValue("vid_mode", vid_menunum);
				Cvar_SetValue("vid_config_fscr", vid_menu_fs);
				VID_Restart_f();
			}
			vid_cursor = (num_fmodes) ? 0 : VID_RESOLUTION;
			break;
		}
		return;

	case K_LEFTARROW:
		switch (vid_cursor)
		{
		case VID_FULLSCREEN:
			vid_menu_fs = !vid_menu_fs;
			if (fs_toggle_works)
				VID_ToggleFullscreen();
			break;
		case VID_RESOLUTION:
			S_LocalSound ("raven/menu1.wav");
			vid_menunum--;
			if (vid_menunum < 0)
				vid_menunum = 0;
			break;
		}
		return;

	case K_RIGHTARROW:
		switch (vid_cursor)
		{
		case VID_FULLSCREEN:
			vid_menu_fs = !vid_menu_fs;
			if (fs_toggle_works)
				VID_ToggleFullscreen();
			break;
		case VID_RESOLUTION:
			S_LocalSound ("raven/menu1.wav");
			vid_menunum++;
			if (vid_menunum >= *nummodes)
				vid_menunum = *nummodes - 1;
			break;
		}
		return;

	case K_UPARROW:
		S_LocalSound ("raven/menu1.wav");
		vid_cursor--;
		if (vid_cursor < 0)
		{
			vid_cursor = (need_apply) ? VID_ITEMS-1 : VID_BLANKLINE-1;
		}
		else if (vid_cursor == VID_BLANKLINE)
		{
			vid_cursor--;
		}
		break;

	case K_DOWNARROW:
		S_LocalSound ("raven/menu1.wav");
		vid_cursor++;
		if (vid_cursor >= VID_ITEMS)
		{
			vid_cursor = (num_fmodes) ? 0 : VID_RESOLUTION;
			break;
		}
		if (vid_cursor >= VID_BLANKLINE)
		{
			if (need_apply)
			{
				if (vid_cursor == VID_BLANKLINE)
					vid_cursor++;
			}
			else
			{
				vid_cursor = (num_fmodes) ? 0 : VID_RESOLUTION;
			}
		}
		break;

	default:
		return;
	}
}
Пример #4
0
void IN_SendKeyEvents (void)
{
	SDL_Event event;
	int sym, state;
	int modstate;

	while (SDL_PollEvent(&event))
	{
		switch (event.type)
		{
		case SDL_ACTIVEEVENT:
			if (event.active.state & (SDL_APPINPUTFOCUS|SDL_APPACTIVE))
			{
				if (event.active.gain)
				{
				//	Sys_Printf("FOCUS GAIN\n");
					S_UnblockSound();
				}
				else
				{
				//	Sys_Printf("FOCUS LOSS\n");
					S_BlockSound();
				}
			}
			break;

		case SDL_KEYDOWN:
			if ((event.key.keysym.sym == SDLK_RETURN) &&
			    (event.key.keysym.mod & KMOD_ALT))
			{
				VID_ToggleFullscreen();
				break;
			}
			else if ((event.key.keysym.sym == SDLK_ESCAPE) &&
				 (event.key.keysym.mod & KMOD_SHIFT))
			{
				Con_ToggleConsole_f();
				break;
			}
			else if ((event.key.keysym.sym == SDLK_g) &&
				 (event.key.keysym.mod & KMOD_CTRL))
			{
				SDL_WM_GrabInput( (SDL_WM_GrabInput (SDL_GRAB_QUERY) == SDL_GRAB_ON) ? SDL_GRAB_OFF : SDL_GRAB_ON );
				break;
			}

		case SDL_KEYUP:
			sym = event.key.keysym.sym;
			state = event.key.state;
			modstate = SDL_GetModState();

			switch (key_dest)
			{
			case key_game:
				if ((event.key.keysym.unicode != 0) || (modstate & KMOD_SHIFT))
				{	/* only use unicode for ~ and ` in game mode */
					if ((event.key.keysym.unicode & 0xFF80) == 0)
					{
						if (((event.key.keysym.unicode & 0x7F) == '`') ||
						    ((event.key.keysym.unicode & 0x7F) == '~') )
							sym = event.key.keysym.unicode & 0x7F;
					}
				}
				break;
			case key_message:
			case key_console:
				if ((event.key.keysym.unicode != 0) || (modstate & KMOD_SHIFT))
				{
#if defined(__QNX__)
					if ((sym == SDLK_BACKSPACE) || (sym == SDLK_RETURN))
						break;	// S.A: fixes QNX weirdness
#endif	/* __QNX__ */
					if ((event.key.keysym.unicode & 0xFF80) == 0)
						sym = event.key.keysym.unicode & 0x7F;
					/* else: it's an international character */
				}
			//	printf("You pressed %s (%d) (%c)\n", SDL_GetKeyName(sym), sym, sym);
				break;
			default:
				break;
			}

			switch (sym)
			{
			case SDLK_DELETE:
				sym = K_DEL;
				break;
			case SDLK_BACKSPACE:
				sym = K_BACKSPACE;
				break;
			case SDLK_F1:
				sym = K_F1;
				break;
			case SDLK_F2:
				sym = K_F2;
				break;
			case SDLK_F3:
				sym = K_F3;
				break;
			case SDLK_F4:
				sym = K_F4;
				break;
			case SDLK_F5:
				sym = K_F5;
				break;
			case SDLK_F6:
				sym = K_F6;
				break;
			case SDLK_F7:
				sym = K_F7;
				break;
			case SDLK_F8:
				sym = K_F8;
				break;
			case SDLK_F9:
				sym = K_F9;
				break;
			case SDLK_F10:
				sym = K_F10;
				break;
			case SDLK_F11:
				sym = K_F11;
				break;
			case SDLK_F12:
				sym = K_F12;
				break;
			case SDLK_BREAK:
			case SDLK_PAUSE:
				sym = K_PAUSE;
				break;
			case SDLK_UP:
				sym = K_UPARROW;
				break;
			case SDLK_DOWN:
				sym = K_DOWNARROW;
				break;
			case SDLK_RIGHT:
				sym = K_RIGHTARROW;
				break;
			case SDLK_LEFT:
				sym = K_LEFTARROW;
				break;
			case SDLK_INSERT:
				sym = K_INS;
				break;
			case SDLK_HOME:
				sym = K_HOME;
				break;
			case SDLK_END:
				sym = K_END;
				break;
			case SDLK_PAGEUP:
				sym = K_PGUP;
				break;
			case SDLK_PAGEDOWN:
				sym = K_PGDN;
				break;
			case SDLK_RSHIFT:
			case SDLK_LSHIFT:
				sym = K_SHIFT;
				break;
			case SDLK_RCTRL:
			case SDLK_LCTRL:
				sym = K_CTRL;
				break;
			case SDLK_RALT:
			case SDLK_LALT:
				sym = K_ALT;
				break;
			case SDLK_KP0:
				if (modstate & KMOD_NUM)
					sym = K_INS;
				else
					sym = SDLK_0;
				break;
			case SDLK_KP1:
				if (modstate & KMOD_NUM)
					sym = K_END;
				else
					sym = SDLK_1;
				break;
			case SDLK_KP2:
				if (modstate & KMOD_NUM)
					sym = K_DOWNARROW;
				else
					sym = SDLK_2;
				break;
			case SDLK_KP3:
				if (modstate & KMOD_NUM)
					sym = K_PGDN;
				else
					sym = SDLK_3;
				break;
			case SDLK_KP4:
				if (modstate & KMOD_NUM)
					sym = K_LEFTARROW;
				else
					sym = SDLK_4;
				break;
			case SDLK_KP5:
				sym = SDLK_5;
				break;
			case SDLK_KP6:
				if (modstate & KMOD_NUM)
					sym = K_RIGHTARROW;
				else
					sym = SDLK_6;
				break;
			case SDLK_KP7:
				if (modstate & KMOD_NUM)
					sym = K_HOME;
				else
					sym = SDLK_7;
				break;
			case SDLK_KP8:
				if (modstate & KMOD_NUM)
					sym = K_UPARROW;
				else
					sym = SDLK_8;
				break;
			case SDLK_KP9:
				if (modstate & KMOD_NUM)
					sym = K_PGUP;
				else
					sym = SDLK_9;
				break;
			case SDLK_KP_PERIOD:
				if (modstate & KMOD_NUM)
					sym = K_DEL;
				else
					sym = SDLK_PERIOD;
				break;
			case SDLK_KP_DIVIDE:
				sym = SDLK_SLASH;
				break;
			case SDLK_KP_MULTIPLY:
				sym = SDLK_ASTERISK;
				break;
			case SDLK_KP_MINUS:
				sym = SDLK_MINUS;
				break;
			case SDLK_KP_PLUS:
				sym = SDLK_PLUS;
				break;
			case SDLK_KP_ENTER:
				sym = SDLK_RETURN;
				break;
			case SDLK_KP_EQUALS:
				sym = SDLK_EQUALS;
				break;
			case 178: /* the '²' key */
				sym = '~';
				break;
			}
			// If we're not directly handled and still
			// above 255, just force it to 0
			if (sym > 255)
				sym = 0;
			Key_Event (sym, state);
			break;

		case SDL_MOUSEBUTTONDOWN:
		case SDL_MOUSEBUTTONUP:
			if (!mouseactive || in_mode_set)
				break;
			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_MOUSEMOTION:
		//	SDL_GetMouseState (NULL, NULL);
			break;

#if USE_JOYSTICK
		case SDL_JOYBUTTONDOWN:
		case SDL_JOYBUTTONUP:
			if (!in_joystick.value)
				break;
			if (event.jbutton.button > K_AUX32 - K_JOY1)
			{
				Con_Printf ("Ignored event for joystick button %d\n",
							event.jbutton.button);
				break;
			}
			Key_Event(K_JOY1 + event.jbutton.button, event.jbutton.state == SDL_PRESSED);
			break;

		case SDL_JOYAXISMOTION:
		case SDL_JOYHATMOTION:
		case SDL_JOYBALLMOTION:
		/* to be coded.. */
			break;
#endif	/* USE_JOYSTICK */

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

		default:
			break;
		}
	}
}