Browse Source

device: Implement correct sign extension for Windows raw devices

Hopefully, fix for #1218
rdb 4 years ago
parent
commit
0e9ea67066
2 changed files with 27 additions and 9 deletions
  1. 24 6
      panda/src/device/winRawInputDevice.cxx
  2. 3 3
      panda/src/device/winRawInputDevice.h

+ 24 - 6
panda/src/device/winRawInputDevice.cxx

@@ -405,7 +405,8 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
           << ", UsagePage=0x" << hex << cap.UsagePage
           << ", UsagePage=0x" << hex << cap.UsagePage
           << ", Usage=0x" << cap.Range.UsageMin << "..0x" << cap.Range.UsageMax
           << ", Usage=0x" << cap.Range.UsageMin << "..0x" << cap.Range.UsageMax
           << dec << ", LogicalMin=" << cap.LogicalMin
           << dec << ", LogicalMin=" << cap.LogicalMin
-          << ", LogicalMax=" << cap.LogicalMax << "\n";
+          << ", LogicalMax=" << cap.LogicalMax
+          << ", BitSize=" << cap.BitSize << "\n";
       }
       }
     } else {
     } else {
       if (device_cat.is_debug()) {
       if (device_cat.is_debug()) {
@@ -415,7 +416,8 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
           << ", UsagePage=0x" << hex << cap.UsagePage
           << ", UsagePage=0x" << hex << cap.UsagePage
           << ", Usage=0x" << cap.NotRange.Usage
           << ", Usage=0x" << cap.NotRange.Usage
           << dec << ", LogicalMin=" << cap.LogicalMin
           << dec << ", LogicalMin=" << cap.LogicalMin
-          << ", LogicalMax=" << cap.LogicalMax << "\n";
+          << ", LogicalMax=" << cap.LogicalMax
+          << ", BitSize=" << cap.BitSize << "\n";
       }
       }
     }
     }
 
 
@@ -428,7 +430,7 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
 
 
       // My gamepads give this odd invalid range.
       // My gamepads give this odd invalid range.
       if (cap.LogicalMin == 0 && cap.LogicalMax == -1) {
       if (cap.LogicalMin == 0 && cap.LogicalMax == -1) {
-        cap.LogicalMax = 65535;
+        cap.LogicalMax = (1 << cap.BitSize) - 1;
         is_signed = false;
         is_signed = false;
       }
       }
 
 
@@ -562,6 +564,17 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
         }
         }
       }
       }
 
 
+      int sign_bit = 0;
+      if (cap.BitSize < 32) {
+        if (cap.LogicalMin < 0) {
+          sign_bit = 1 << (cap.BitSize - 1);
+        }
+        else if (is_signed) {
+          //XXX is this still necessary?
+          sign_bit = (1 << 15);
+        }
+      }
+
       int axis_index;
       int axis_index;
       if (!is_signed) {
       if (!is_signed) {
         // All axes on the weird XInput-style mappings go from -1 to 1
         // All axes on the weird XInput-style mappings go from -1 to 1
@@ -569,7 +582,7 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
       } else {
       } else {
         axis_index = add_axis(axis, cap.LogicalMin, cap.LogicalMax);
         axis_index = add_axis(axis, cap.LogicalMin, cap.LogicalMax);
       }
       }
-      _indices[data_index] = Index::axis(axis_index, is_signed);
+      _indices[data_index] = Index::axis(axis_index, sign_bit);
     }
     }
   }
   }
 
 
@@ -685,8 +698,13 @@ process_report(PCHAR ptr, size_t size) {
 
 
         const Index &idx = _indices[data[di].DataIndex];
         const Index &idx = _indices[data[di].DataIndex];
         if (idx._axis >= 0) {
         if (idx._axis >= 0) {
-          if (idx._signed) {
-            axis_changed(idx._axis, (SHORT)data[di].RawValue);
+          if (idx._sign_bit != 0) {
+            // Sign extend.
+            int value = data[di].RawValue;
+            if (value & idx._sign_bit) {
+              value = -(value & ~idx._sign_bit);
+            }
+            axis_changed(idx._axis, value);
           } else {
           } else {
             axis_changed(idx._axis, data[di].RawValue);
             axis_changed(idx._axis, data[di].RawValue);
           }
           }

+ 3 - 3
panda/src/device/winRawInputDevice.h

@@ -59,16 +59,16 @@ private:
       idx._button = index;
       idx._button = index;
       return idx;
       return idx;
     }
     }
-    static Index axis(int index, bool is_signed=true) {
+    static Index axis(int index, int sign_bit = 0) {
       Index idx;
       Index idx;
       idx._axis = index;
       idx._axis = index;
-      idx._signed = is_signed;
+      idx._sign_bit = sign_bit;
       return idx;
       return idx;
     }
     }
 
 
     int _button;
     int _button;
     int _axis;
     int _axis;
-    bool _signed;
+    int _sign_bit;
   };
   };
 
 
   // Maps a "data index" to either button index or axis index.
   // Maps a "data index" to either button index or axis index.