File: rawinput.cpp

package info (click to toggle)
higan 094-5
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 9,780 kB
  • ctags: 15,643
  • sloc: cpp: 103,963; ansic: 659; makefile: 531; sh: 25
file content (123 lines) | stat: -rwxr-xr-x 3,590 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#ifndef RUBY_INPUT_MOUSE_RAWINPUT
#define RUBY_INPUT_MOUSE_RAWINPUT

namespace ruby {

struct InputMouseRawInput {
  uintptr_t handle = 0;
  bool mouseAcquired = false;

  struct Mouse {
    HID::Mouse hid;

    signed relativeX = 0;
    signed relativeY = 0;
    signed relativeZ = 0;
    bool buttons[5] = {0};
  } ms;

  bool acquire() {
    if(mouseAcquired == false) {
      mouseAcquired = true;
      ShowCursor(false);
    }
    return true;
  }

  bool unacquire() {
    if(mouseAcquired == true) {
      mouseAcquired = false;
      ReleaseCapture();
      ClipCursor(NULL);
      ShowCursor(true);
    }
    return true;
  }

  bool acquired() {
    if(mouseAcquired == true) {
      SetFocus((HWND)handle);
      SetCapture((HWND)handle);
      RECT rc;
      GetWindowRect((HWND)handle, &rc);
      ClipCursor(&rc);
    }
    return GetCapture() == (HWND)handle;
  }

  void update(RAWINPUT* input) {
    if((input->data.mouse.usFlags & 1) == MOUSE_MOVE_RELATIVE) {
      ms.relativeX += input->data.mouse.lLastX;
      ms.relativeY += input->data.mouse.lLastY;
    }

    if(input->data.mouse.usButtonFlags & RI_MOUSE_WHEEL) {
      ms.relativeZ += (int16_t)input->data.mouse.usButtonData;
    }

    if(input->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) ms.buttons[0] = 1;
    if(input->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_UP  ) ms.buttons[0] = 0;
    if(input->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_DOWN) ms.buttons[1] = 1;
    if(input->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_UP  ) ms.buttons[1] = 0;
    if(input->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_DOWN) ms.buttons[2] = 1;
    if(input->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_UP  ) ms.buttons[2] = 0;
    if(input->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) ms.buttons[3] = 1;
    if(input->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_UP  ) ms.buttons[3] = 0;
    if(input->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) ms.buttons[4] = 1;
    if(input->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_UP  ) ms.buttons[4] = 0;
  }

  void assign(unsigned groupID, unsigned inputID, int16_t value) {
    auto& group = ms.hid.group[groupID];
    if(group.input[inputID].value == value) return;
    if(input.onChange) input.onChange(ms.hid, groupID, inputID, group.input[inputID].value, value);
    group.input[inputID].value = value;
  }

  void poll(vector<HID::Device*>& devices) {
    assign(HID::Mouse::GroupID::Axis, 0, ms.relativeX);
    assign(HID::Mouse::GroupID::Axis, 1, ms.relativeY);
    assign(HID::Mouse::GroupID::Axis, 2, ms.relativeZ);

    //keys are intentionally reordered below:
    //in ruby, button order is {left, middle, right, up, down}
    assign(HID::Mouse::GroupID::Button, 0, ms.buttons[0]);
    assign(HID::Mouse::GroupID::Button, 2, ms.buttons[1]);
    assign(HID::Mouse::GroupID::Button, 1, ms.buttons[2]);
    assign(HID::Mouse::GroupID::Button, 4, ms.buttons[3]);
    assign(HID::Mouse::GroupID::Button, 3, ms.buttons[4]);

    ms.relativeX = 0;
    ms.relativeY = 0;
    ms.relativeZ = 0;

    devices.append(&ms.hid);
  }

  bool init(uintptr_t handle) {
    this->handle = handle;

    ms.hid.id = 2;

    ms.hid.axis().append({"X"});
    ms.hid.axis().append({"Y"});
    ms.hid.axis().append({"Z"});

    ms.hid.button().append({"Left"});
    ms.hid.button().append({"Middle"});
    ms.hid.button().append({"Right"});
    ms.hid.button().append({"Up"});
    ms.hid.button().append({"Down"});

    rawinput.updateMouse = {&InputMouseRawInput::update, this};
    return true;
  }

  void term() {
    unacquire();
  }
};

}

#endif