Half-Life Re-imagined competition results on their way...
Check out Skewing textures in Hammer, our newest tutorial!
Say hello to thatguymalone, our newest member!

logo

Site Stuff

Reference

Maps

Community

ShoutBOX

Poll

Feeling Blue

What's your favourite shade of blue?

Azure

9

Cobalt

20

Turquoise

5

Cyan

8

Royal

3

Teal

3

Onliners

7 mins

Admer456

9 mins

Dr. Orange

23 mins

Solokiller

24 mins

DocRock

42 mins

Windawz

43 mins

zeeba-G

1 hours

Jessie

Affiliates

A gaming and technology blog by TWHL admins Penguinboy and Ant. A music blog by TWHL users Ant and Hugh.

User Input Processing System

By Valve Software

HL SDK 2.2
This article was originally made available as part of version 2.2 of the Half-Life SDK. As such, all limitations, restrictions, license agreements, copyrights and trademarks from the original document apply here.

In this SDK release, the user input processing system has been moved to the client.dll. The user input system handles all mouse, keyboard, and controller ( joystick ) inputs and creates the appropriate movement commands based on the input data.

A. Keyboard Handlers

Handled keyboard actions are defined in InitInput(), and certain input related cvars are also registered there.

Handlers for toggleable keys can be found in input.cpp. A typical handler takes the form:

    void IN_UpDown(void) { KeyDown(&in_up); }
    void IN_UpUp(void) { KeyUp(&in_up); }

The functions IN_UpDown and IN_UpUp are mapped to +moveup and -moveup in InitInput().

    ?
    gEngfuncs.pfnAddCommand ("+moveup",IN_UpDown);
    gEngfuncs.pfnAddCommand ("-moveup",IN_UpUp);
    ?

Thus, when the key bound to +moveup is pressed, the function IN_UpDown ( i.e., the "Up" key has been pressed down ) is called. This function, in turn, invokes the KeyDown utility function and passes in the address of the &in_up key structure.

Based on the above, to add a new key to the input system is simple:

  1. First define the appropriate key structure: kbutton_t in_mykey;
  2. Then define the handlers for the up and down events for that key:

      void IN_MyKeyDown(void) {KeyDown(&in_mykey);}
      void IN_MyKeyUp(void) {KeyUp(&in_mykey);}

  3. Then link the handlers to actual bindable key commands in InitInput:

      gEngfuncs.pfnAddCommand ("+mykey",IN_MyKeyDown);
      gEngfuncs.pfnAddCommand ("-mykey",IN_MyKeyUp);

B. Constructing a Movement Command based on User Inputs

The Half-Life engine constructs movement commands by filling in a usercmd_t structure ( see usercmd.h ).

The new input system processes user inputs in CL_CreateMove in input.cpp. This function is the core of creating a movement for the user. The current view angles are sampled and adjusted by calling in to CL_AdjustAngles(). The final view angles are placed into the usercmd_t structure when the movement is complete. After the view angles are sampled, keyboard influences such as strafing and other movements are added to the movement command. The effects of the keyboard look and the speed key are factored in next. The client caps the maximum requested velocity to the current player maxspeed to avoid prediction glitches on the client. Next, the mouse and joystick are allowed to contribute to the usercmd_t in IN_Move() ( inputw32.cpp ). Afterward, any impulse command is set and the underlying impulse flag is cleared, and the button bit fields are set.

As for IN_Move(), it simply calls in to IN_MouseMove() which accumulates vertical and horizontal offsets for the mouse and converts those into angle changes or movements depending on the user's control settings. Similar sampling code exists for the joystick/controller as well, and that code can be found by tracing into IN_JoyMove().

C. The Third Person Camera

The third person camera, when active, takes over mouse sampling and camera positioning. The bulk of the work is done in CAM_Think, which is called by the engine once per frame. The results of CAM_Think influence the view setup functions discussed elsewhere.