Search Tips Advanced Search |
| Delphi Graphics and Game Programming Exposed with DirectX 7.0 by John Ayres Wordware Publishing, Inc. ISBN: 1556226373 Pub Date: 12/01/99
Search this book:
Previous | Table of Contents | Next
Listing 7-15: Retrieving immediate game controller input data
    procedure TfrmJoyTestBed.tmrJoyPollTimer(Sender: TObject);

    var

      DevState: TDIJoystate2;

      iCount: Integer;

    begin

      {more often than not, game controllers do not generate hardware

       interrupts. thus, we have to poll the device driver in order to

       get the current state of the device.}

      FDirectInputDevice.Poll;

      {retrieve the state of all objects on the device}

      DXCheck( FDirectInputDevice.GetDeviceState(SizeOf(DevState), @DevState) );

      {we’re assuming here that the game controller has an X and Y axis

       (as joysticks and gamepads do), so draw a crosshair}

      DrawCrossHair((DevState.lX + 1000) div 20, (DevState.lY + 1000) div 20);

      {draw slider bars for any other axes}

      for iCount := 2 to NumAxes-1 do

        case FAxisList[iCount] of

          DIJOFS_Z  : shpZBarPos.Width  := (DevState.lZ + 1000) div 20;

          DIJOFS_RX : shpRXBarPos.Width := (DevState.lRx + 1000) div 20;

          DIJOFS_RY : shpRYBarPos.Width := (DevState.lRy + 1000) div 20;

          DIJOFS_RZ : shpRZBarPos.Width := (DevState.lRz + 1000) div 20;

        end;

      {if a POV is available (availability of which should probably be placed

       in a global variable as opposed to checking the enabled state of a

       label), then draw a crosshair}

      if Label9.Enabled then

        DrawPov(DevState.rgdwPOV[0]);

      {test the joystick buttons}

      for iCount := 0 to 127 do

      if ButtonLights[iCount] <> nil then

        if (DevState.rgbButtons[iCount] and $80) = $80 then

          ButtonLights[iCount].Brush.Color := clRed

        else

          ButtonLights[iCount].Brush.Color := clMaroon;

    end;
### Summary In this chapter, we discussed several techniques for retrieving user input data from various input devices. We examined both common Win32 API functions and their DirectInput counterparts for reading the state of keyboard, mice, and game controller devices. We also covered various techniques for retrieving this data, including immediate and buffered data as well as polling and event notification. When coding user input data routines using DirectInput or Win32 API functions, it is important to keep these points in mind: • Input is one of the three fundamental parts of a game, and as such is important to overall game enjoyment. Exactly how user input will be translated into game element manipulation is dependent on the game itself. Flight simulators need input that affects the direction of flight, or perhaps even the selection and use of a weapon. Strategy games, by contrast, need input that determines which token is selected and its direction of movement or combat. • Input devices go beyond the standard mouse and keyboard. There are now a wide variety of peripheral game controllers in all shapes and sizes. Rudder pedals, steering wheels, gamepads, throttles, and all manner of sundry and arcane input devices are now available, making some games much more enjoyable to play. Even the standard joystick has become incredibly complex, with many sporting impressive arrays of buttons, switches, sliders, and even tactile responses known as force feedback. • An important user input consideration is support for user configurable controls. Even though the developer has determined which input devices will be supported and how they interact with game elements, individual users may find this structure somewhat restrictive based on their particular preferences. • DirectInput is the DirectX component responsible for providing user input from all manner of input devices, such as keyboards, mice, and game controllers. DirectInput offers many features above and beyond what is available through the Win32 API. As with all DirectX components, DirectInput gives the developer more control over user input than the Windows API, while also providing an improvement in performance. • Similar to DirectDraw, DirectInput programming consists of creating a DirectInput object and several DirectInputDevice objects. The DirectInput object itself acts as a liaison between the application and input device drivers. Individual DirectInputDevice objects represent the application’s interface directly to input hardware, or more specifically, that hardware’s device driver. • Where DirectInput is concerned, a button is considered to be any switch that has an on and off position. There is no distinction made between buttons on a mouse, keyboard, or joystick. An axis has a range of positions where its value is affected by the physical movement of a device in some particular direction. Some axes can move an infinite distance in a particular direction, and are measured in relative values. Other axes can physically move only a specific distance, and are measured in absolute values. • Buffered data retrieval simulates the mechanism by which Windows reports input. Individual input events are stored in a buffer, which takes the form of an array of data structures containing the various axis movement values or button clicks. Immediate data retrieval does not report a stream of singular events, but returns the current state of the device at the time of the function call. • Polling involves checking the state of the input device at the time that the input is needed. Typically, this is performed in the game loop. Event notification, on the other hand, is very similar to event-driven programming. This is a mechanism by which DirectInput will notify the application when new input data is available, and is best paired with buffered data retrieval. • As discussed in the DirectDraw tutorial, a cooperative level determines how the application works with other applications. As with other DirectX components, DirectInput gives the developer a choice as to how the application will share input devices with other applications, in terms of who can gain access to the device and if input can be retrieved based on application focus. Bear in mind that Windows requires exclusive access to the keyboard at all times, so that functions such as Alt+Tab and Ctrl+Alt+Delete are always available. Thus, an application can only obtain non-exclusive access to the keyboard. • Once a device is set up, the application cannot receive input data until it instructs DirectInput that it is ready to do so. This process is known as acquiring the device. Bear in mind that a device can be forcibly unacquired by the application. This may happen when another application receives focus or acquires the device in exclusive mode. • Several steps are required in order to set up DirectInput and begin interfacing with user input devices. In general you must create the DirectInput object, enumerate input devices, create the input device, set the data format, set the cooperative level, set device properties, and then acquire the device. • While the steps required for initializing and setting up DirectInput and DirectInputDevices are similar for every device, exactly how the input data is retrieved and extracted varies from device to device. This will also depend on whether you will be using immediate data retrieval or buffered data retrieval. This leads to subtle nuances in which initialization steps are required, and how the data returned from certain methods is interpreted. • Retrieving keyboard data is the easiest. The GetAsyncKeyState Win32 API function could potentially be used if the full power of DirectInput was not needed. However, you would not be able to differentiate between left and right versions of certain keys, such as Shift or Ctrl. • Mouse data is best retrieved using a buffer coupled with event notification. This requires setting up a secondary thread and using critical sections to synchronize variable access. The Win32 API function GetCursorPos function could potentially be used instead, but this function reports absolute values relative to the screen. • Game controller data input retrieval is very complex. We must set up a custom data format, but this complexity results in support for a wider range of devices. We must also set up the range, deadzone, and saturation properties for each axis. We could use the joyGetPosEx function, but this function only supports up to six axes and 32 buttons, and has no support for force feedback.
Previous | Table of Contents | Next

Products | Contact Us | About Us | Privacy | Ad Info | Home Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.