sd-test.cpp

Go to the documentation of this file.
00001 /*
00002  * sd-test.cpp
00003  *
00004  * Copyright (C) 2009,2010  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  * Routines to test a provided SourceDeviceFactory object
00008  */
00009 
00010 // includes --------------------------------------------------------------------
00011 #include "sd-test.h"            // always include our own header first!
00012 
00013 #include <time.h>
00014 #include <iostream>
00015 
00016 #include "perf/perf.h"
00017 #include "threadsafe/threadsafe.h"
00018 
00019 
00020 namespace gamepad {
00021 
00022 
00023 ////////////////////////////////////////////////////////////////////////////////
00024 //
00025 //      static helper methods
00026 //
00027 ////////////////////////////////////////////////////////////////////////////////
00028 
00029 static int
00030 getIntDigits
00031 (
00032 IN int x
00033 )
00034 throw()
00035 {
00036         if (x <= 9)
00037                 return 1;
00038 
00039         int nDigits = 1;
00040         while (x > 10) {
00041                 x /= 10;
00042                 nDigits++;
00043         }
00044 
00045         return nDigits;
00046 }
00047 
00048 
00049 
00050 static int
00051 getPotDigits
00052 (
00053 IN int min,
00054 IN int max
00055 )
00056 throw()
00057 {
00058         int minDigits = 0;
00059         if (min < 0) {
00060                 minDigits = getIntDigits(-min) + 1;
00061         }
00062         int maxDigits = getIntDigits(max);
00063 
00064         if (minDigits > maxDigits) {
00065                 return minDigits;
00066         }
00067         return maxDigits;
00068 }
00069 
00070 
00071 static void
00072 printPot
00073 (
00074 IN int idx,
00075 IN const gamepad::pot_value_t& pv
00076 )
00077 throw()
00078 {
00079         int valDigits = getPotDigits(pv.minSeen, pv.maxSeen);
00080 
00081 //      DPRINTF("Pot min=%d, max=%d", pv.minSeen, pv.maxSeen);
00082 
00083         const int bufsize = 64;
00084         char format[bufsize];
00085 
00086 //      snprintf(format, bufsize, "%%d:%%%dd ", valDigits);
00087         snprintf(format, bufsize, "%%%dd ", valDigits);
00088 //      DPRINTF("  format string: '%s'", format);
00089 
00090 //      printf(format, idx, pv.value);
00091         printf(format, pv.value);
00092 /*      if (phase & 1) {
00093                 // show min
00094                 if (gamepad::pot_value_t::eStartMin == pv.minSeen) {
00095                         printf("X");
00096                 } else {
00097                         printf("%d", pv.minSeen);
00098                 }
00099         } else {
00100                 // show max
00101                 if (gamepad::pot_value_t::eStartMax == pv.maxSeen) {
00102                         printf("X");
00103                 } else {
00104                         printf("%d", pv.maxSeen);
00105                 }
00106         }
00107         printf(" "); */
00108 }
00109 
00110 
00111 
00112 ////////////////////////////////////////////////////////////////////////////////
00113 //
00114 //      public API
00115 //
00116 ////////////////////////////////////////////////////////////////////////////////
00117 
00118 void
00119 testSourceDeviceFactory
00120 (
00121 IN SourceDeviceFactory * factory
00122 )
00123 {
00124         perf::Timer timer("testFactory");
00125         ASSERT(factory, "null");
00126 
00127         DPRINTF("Testing factory: name='%s'", factory->getName());
00128 
00129         // see if there are any devices
00130         int nDevices = factory->getCount();
00131         DPRINTF("Found %d source devices", nDevices);
00132         ASSERT_THROW(nDevices > 0, "Bad or no source devices found?");
00133 
00134         // loop through all devices and get info!
00135         for (int i = 0; i < nDevices; ++i) {
00136                 smart_ptr<gamepad::SourceDevice> device =
00137                     factory->getSourceDevice(i);
00138                 ASSERT_THROW(device, "Should have a device here");
00139 
00140                 // dump the names
00141                 DPRINTF("Device %d: '%s'", i, device->getPublicName());
00142                 DPRINTF("  unique ID: '%s'", device->getUniqueId());
00143 
00144                 DPRINTF("  state: %d", device->getState());
00145                 DPRINTF("  total potentiometers: %d", device->getNumPots());
00146                 DPRINTF("  total buttons: %d", device->getNumButtons());
00147         }
00148 
00149         // okay, get the first device
00150         smart_ptr<gamepad::SourceDevice> device = factory->getSourceDevice(0);
00151         ASSERT_THROW(device, "should have a device");
00152 
00153         // set up sleep interval
00154         const int desiredHz = 100;
00155         long msPoll = 1000 / desiredHz;
00156         DPRINTF("Want sampling at %d Hz, so polling every %ld ms",
00157             desiredHz, msPoll);
00158         ASSERT_THROW(desiredHz > 1, "Need a higher sampling frequency!");
00159 
00160         // how often do we see if the device is still connected?
00161         const int connectedHz = 5;
00162         int checkCounter = desiredHz / connectedHz;
00163         DPRINTF("Checking connection status every %d iterations",
00164             checkCounter);
00165         int counter = 0;
00166 
00167 /*
00168         // Jan 2011: removing all force feedback support for now
00169         // default rumble values
00170         uint16_t loFreq = 0x5000;
00171         uint16_t hiFreq = 0x5000;
00172         int nRumble = device->getNumRumblers();
00173         DPRINTF("Found %d rumblers", nRumble);
00174         if (device->getNumButtons() < nRumble) {
00175                 nRumble = device->getNumButtons();
00176         }
00177  */
00178 
00179         int nCols = 100;                // assume 100 columns for display
00180         ASSERT_THROW(device->getNumPots() > 0,
00181             "Device contains no potentiometers?");
00182         int nCharsPerPot = (nCols / device->getNumPots()) - 1;
00183         if (nCharsPerPot > 6) {
00184                 nCharsPerPot = 6;
00185         }
00186         if (nCharsPerPot < 2) {
00187                 nCharsPerPot = 2;
00188         }
00189 //      char potFormat[64];
00190 //      sprintf(potFormat, "%%d:%%d:%%d ");
00191 //      DPRINTF("Potentiometer format: '%s'", potFormat);
00192 
00193         // now loop and read
00194         DPRINTF("\n\nDetach the device to stop the program!\n");
00195         while (gamepad::eDevice_Detached != device->getState()) {
00196                 sleepMilliseconds(msPoll);
00197 
00198                 counter++;
00199                 if (counter >= checkCounter) {
00200                         counter = 0;
00201                         factory->getCount();
00202                 }
00203 
00204                 device->poll();
00205                 printf("\r");
00206                 for (int i = 0; i < device->getNumPots(); ++i) {
00207                         const gamepad::pot_value_t& pv = device->getPotValue(i);
00208                         printPot(i, pv);
00209 //                      printf(potFormat, pv.minSeen, pv.value, pv.maxSeen);
00210                 }
00211 
00212                 printf(" pressed:");
00213                 bool needLinefeed = false;
00214                 for (int i = 0; i < device->getNumButtons(); ++i) {
00215                         if (gamepad::eButtonWasPushed & device->getButtonValue(i)) {
00216                                 printf(" b%d", i);
00217                                 needLinefeed = true;
00218                         }
00219                 }
00220                 if (needLinefeed) {
00221                         printf("\n");
00222                 }
00223 
00224 /*
00225                 for (int i = 0; i < nRumble; ++i) {
00226                         int duration = -1;
00227                         if (gamepad::eButtonWasPushed & device->getButtonValue(i))
00228                                 duration = 2000;
00229                         if (gamepad::eButtonWasReleased & device->getButtonValue(i))
00230                                 duration = 0;
00231                         if (duration < 0)
00232                                 continue;       // skip button
00233 
00234                         uint16_t hi = (i % 2) ? hiFreq : 0;
00235                         uint16_t lo = (hi) ? 0 : loFreq;
00236                         device->playRumble(i, hi, lo, duration);
00237                 }
00238  */
00239         }
00240         printf("\n");
00241         DPRINTF("Device appears to be detached--exiting!");
00242 }
00243 
00244 
00245 };      // gamepad namespace