di-diagnostics.h

Go to the documentation of this file.
00001 /*
00002  * di-diagnostics.h
00003  *
00004  * Copyright (C) 2010  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *     * Redistributions of source code must retain the above copyright
00011  *       notice, this list of conditions and the following disclaimer.
00012  *     * Redistributions in binary form must reproduce the above copyright
00013  *       notice, this list of conditions and the following disclaimer in the
00014  *       documentation and/or other materials provided with the distribution.
00015  *     * Neither the name of the <organization> nor the
00016  *       names of its contributors may be used to endorse or promote products
00017  *       derived from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY
00020  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY
00023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00026  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  *
00031  * Diagnostic routines for DirectInput.  Meant for internal use of this library
00032  * only.  Clients of the library should just use the SourceDevice interface.
00033  */
00034 
00035 #ifndef GAMEPAD_DI_DIAGNOSTICS_H__
00036 #define GAMEPAD_DI_DIAGNOSTICS_H__
00037 
00038 // includes --------------------------------------------------------------------
00039 #include "wave-windows/wave-windows.h"
00040 
00041 #include <dinput.h>     // Microsoft DirectInput headers
00042 
00043 
00044 namespace gamepad {
00045 
00046 
00047 // NOTE: what follows are helper methods for dealing with DirectInput APIs.
00048 //   These are mostly diagnostics and clients of this library shouldn't need
00049 //   to use these directly.  They are exposed so test code can use them.
00050 
00051 /// helper method to inspect Windows DirectInput error codes
00052 void checkDIError(IN HRESULT hr) throw();
00053 
00054 #define DI_VERIFY(exp, hr, msg)                                         \
00055         if (!(exp)) {                                                   \
00056                 DPRINTF("DirectInput API call failed!");                \
00057                 gamepad::checkDIError(hr);                              \
00058                 ASSERT_THROW(false && (exp), msg);                      \
00059         }
00060 
00061 
00062 void writeDevCaps(IO std::ostream& stream,
00063                         IN const DIDEVCAPS& dc);
00064 
00065 void writeDevInstance(IO std::ostream& stream,
00066                         IN const DIDEVICEINSTANCEA& di);
00067 
00068 
00069 void writeDataFormat(IO std::ostream& stream,
00070                         IN const DIDATAFORMAT& df);
00071 
00072 void writeObjectDataFormat(IO std::ostream& stream,
00073                         IN const DIOBJECTDATAFORMAT& odf);
00074 
00075 void writeStateDebug(IO std::ostream& stream,
00076                         IN const DIDATAFORMAT& df,
00077                         IN const byte_t * buffer);
00078 
00079 void writeState(IO std::ostream& stream,
00080                         IN const DIDATAFORMAT& df,
00081                         IN const byte_t * buffer);
00082 
00083 
00084 /// information about a device, as determined from enumeration of objects
00085 struct device_caps_t {
00086         // constructor, manipulators
00087         device_caps_t(void) throw() { this->clear(); }
00088         void clear(void) throw() {
00089                         nAxes = nPOVs = nButtons = 0;
00090                         dataBytes = 0;
00091                 }
00092         void dump(IN const char * title) const throw();
00093 
00094         // data fields
00095         int             nAxes;
00096         int             nPOVs;
00097         int             nButtons;
00098         int             dataBytes;
00099 };
00100 
00101 
00102 /// This routine will inspect a given device, and then construct a custom
00103 ///     DIDATAFORMAT struct to specify how data should be retrieved.  Data
00104 ///     will be packed with axes first, then POVs, then buttons, all data
00105 ///     dword-aligned.
00106 /// need to free this memory by calling delete[]
00107 byte_t * getDataFormatForDevice(IN IDirectInputDevice8 * device,
00108                         OUT device_caps_t& dc);
00109 
00110 int32_t getAxisValue(IN const byte_t * data,
00111                         IN const device_caps_t& dc,
00112                         IN int axisIndex);
00113 
00114 int32_t getPOVValue(IN const byte_t * data,
00115                         IN const device_caps_t& dc,
00116                         IN int povIndex);
00117 
00118 dword_t getButtonValue(IN const byte_t * data,
00119                         IN const device_caps_t& dc,
00120                         IN int buttonIndex);
00121 
00122 };      // gamepad namespace
00123 
00124 
00125 // global diagnostics
00126 
00127 inline std::ostream& operator << (IO std::ostream& stream,
00128                                   IN const DIDEVCAPS& dc) {
00129         gamepad::writeDevCaps(stream, dc);
00130         return stream;
00131 }
00132 
00133 inline std::ostream& operator << (IO std::ostream& stream,
00134                                   IN const DIDEVICEINSTANCEA& di) {
00135         gamepad::writeDevInstance(stream, di);
00136         return stream;
00137 }
00138 
00139 inline std::ostream& operator << (IO std::ostream& stream,
00140                                   IN const DIOBJECTDATAFORMAT& odf) {
00141         gamepad::writeObjectDataFormat(stream, odf);
00142         return stream;
00143 }
00144 
00145 inline std::ostream& operator << (IO std::ostream& stream,
00146                                   IN const DIDATAFORMAT& df) {
00147         gamepad::writeDataFormat(stream, df);
00148         return stream;
00149 }
00150 
00151 #endif  // GAMEPAD_DI_DIAGNOSTICS_H__
00152