void PollJoystick(JoystickDevice <LinuxJoyDetails> js) { JoystickEvent e; unsafe { while ((long)Libc.read(js.Details.FileDescriptor, (void *)&e, (UIntPtr)sizeof(JoystickEvent)) > 0) { e.Type &= ~JoystickEventType.Init; switch (e.Type) { case JoystickEventType.Axis: // Flip vertical axes so that +1 point up. if (e.Number % 2 == 0) { js.Details.State.SetAxis((JoystickAxis)e.Number, e.Value); } else { js.Details.State.SetAxis((JoystickAxis)e.Number, unchecked ((short)-e.Value)); } break; case JoystickEventType.Button: js.Details.State.SetButton((JoystickButton)e.Number, e.Value != 0); break; } js.Details.State.SetPacketNumber(unchecked ((int)e.Time)); } } }
void ProcessEvents() { state.SetIsConnected(true); while (Interlocked.Read(ref exit) == 0) { byte scancode; short extended; while (Libc.read(stdin, out scancode) > 0) { bool pressed = (scancode & 0x80) == 0; int key = scancode & ~0x80; KeyModifiers mods; Debug.Print("{0}:{1} is {2}", key, (int)TranslateKey(key, out mods), pressed); if (key == 0) { // This is an extended scancode, ignore Libc.read(stdin, out extended); } else { lock (sync) { state[(Key)key] = pressed; } } } } input_thread = null; }
private void PollJoystick(LinuxJoystickDetails js) { unsafe { const int EventCount = 32; InputEvent *events = stackalloc InputEvent[EventCount]; long length = 0; while (true) { length = (long)Libc.read(js.FileDescriptor, (void *)events, (UIntPtr)(sizeof(InputEvent) * EventCount)); if (length <= 0) { break; } //As we've received an event, this must be connected! js.Caps.SetIsConnected(true); js.State.SetIsConnected(true); length /= sizeof(InputEvent); for (int i = 0; i < length; i++) { InputEvent *e = events + i; switch (e->Type) { case EvdevType.ABS: { AxisInfo axis; if (js.AxisMap.TryGetValue((EvdevAxis)e->Code, out axis)) { if (axis.Info.Maximum > axis.Info.Minimum) { if (e->Code >= (int)EvdevAxis.HAT0X && e->Code <= (int)EvdevAxis.HAT3Y) { // We currently treat analogue hats as digital hats // to maintain compatibility with SDL2. We can do // better than this, however. int hat = (e->Code - (int)EvdevAxis.HAT0X) / 2; int xy_axis = (int)axis.Axis & 0x1; int value = e->Value.CompareTo(0) + 1; switch (xy_axis) { case 0: // X-axis js.hatStates[hat, 1] = value; break; case 1: // Y-axis js.hatStates[hat, 0] = value; break; } js.State.SetHat((JoystickHat)hat, TranslateHat(js.hatStates[hat, 0], js.hatStates[hat, 1])); } else { // This axis represents a regular axis or trigger js.State.SetAxis( axis.Axis, (short)Common.HidHelper.ScaleValue(e->Value, axis.Info.Minimum, axis.Info.Maximum, short.MinValue, short.MaxValue)); } } } break; } case EvdevType.KEY: { int button; if (js.ButtonMap.TryGetValue((EvdevButton)e->Code, out button)) { js.State.SetButton(button, e->Value != 0); } break; } } // Create a serial number (total seconds in 24.8 fixed point format) int sec = (int)((long)e->Time.Seconds & 0xffffffff); int msec = (int)e->Time.MicroSeconds / 1000; int packet = ((sec & 0x00ffffff) << 24) | Common.HidHelper.ScaleValue(msec, 0, 1000, 0, 255); js.State.SetPacketNumber(packet); } } } }
void PollJoystick(LinuxJoystickDetails js) { unsafe { const int EventCount = 32; InputEvent *events = stackalloc InputEvent[EventCount]; long length = 0; while (true) { length = (long)Libc.read(js.FileDescriptor, (void *)events, (UIntPtr)(sizeof(InputEvent) * EventCount)); if (length <= 0) { break; } // Only mark the joystick as connected when we actually start receiving events. // Otherwise, the Xbox wireless receiver will register 4 joysticks even if no // actual joystick is connected to the receiver. js.Caps.SetIsConnected(true); js.State.SetIsConnected(true); length /= sizeof(InputEvent); for (int i = 0; i < length; i++) { InputEvent *e = events + i; switch (e->Type) { case EvdevType.ABS: { AxisInfo axis; if (js.AxisMap.TryGetValue((EvdevAxis)e->Code, out axis)) { if (axis.Info.Maximum > axis.Info.Minimum) { if (e->Code >= (int)EvdevAxis.HAT0X && e->Code <= (int)EvdevAxis.HAT3Y) { // We currently treat analogue hats as digital hats // to maintain compatibility with SDL2. We can do // better than this, however. JoystickHat hat = JoystickHat.Hat0 + (e->Code - (int)EvdevAxis.HAT0X) / 2; JoystickHatState pos = js.State.GetHat(hat); int xy_axis = (int)axis.Axis & 0x1; switch (xy_axis) { case 0: // X-axis pos = TranslateHat( e->Value.CompareTo(0) + 1, pos.IsUp ? 0 : pos.IsDown ? 2 : 1); break; case 1: // Y-axis pos = TranslateHat( pos.IsLeft ? 0 : pos.IsRight ? 2 : 1, e->Value.CompareTo(0) + 1); break; } js.State.SetHat(hat, pos); } else { // This axis represents a regular axis or trigger js.State.SetAxis( axis.Axis, (short)Common.HidHelper.ScaleValue(e->Value, axis.Info.Minimum, axis.Info.Maximum, short.MinValue, short.MaxValue)); } } } break; } case EvdevType.KEY: { JoystickButton button; if (js.ButtonMap.TryGetValue((EvdevButton)e->Code, out button)) { js.State.SetButton(button, e->Value != 0); } break; } } // Create a serial number (total seconds in 24.8 fixed point format) int sec = (int)((long)e->Time.Seconds & 0xffffffff); int msec = (int)e->Time.MicroSeconds / 1000; int packet = ((sec & 0x00ffffff) << 24) | Common.HidHelper.ScaleValue(msec, 0, 1000, 0, 255); js.State.SetPacketNumber(packet); } } } }