Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
InputBridge.cs
浏览该文件的文档.
1using System.Runtime.InteropServices;
2using Engine.Input;
3
4namespace Engine.Browser {
5 public static unsafe class InputBridge {
8
9 public static Point2 CanvasSize = Point2.One;
10 public static bool IsFullscreen = false;
11
12 public static IntPtr Initialize() {
13 // 分配对齐的非托管内存
14 void* ptr = NativeMemory.AlignedAlloc((nuint)sizeof(SharedInputMemory), 16);
15 NativeMemory.Clear(ptr, (nuint)sizeof(SharedInputMemory));
17 return (IntPtr)ptr;
18 }
19
20 public static void BeforeFrame() {
21 if (_sharedPtr == null) {
22 return;
23 }
24 // 1. 原子翻转 Buffer
25 int currentIndex = _sharedPtr->ActiveIndex;
26 int nextIndex = (currentIndex + 1) % 2;
27 Interlocked.Exchange(ref _sharedPtr->ActiveIndex, nextIndex);
28 // 2. 获取刚才 JS 写入的 Buffer
29 _currentReadBuffer = currentIndex == 0 ? &_sharedPtr->Buffer0 : &_sharedPtr->Buffer1;
30 // 3. 处理状态数据
32 // 4. 处理事件流
34 // 5. 重置事件计数 (状态数据不需要清零,会覆盖)
35 _currentReadBuffer->UsedBytes = 0;
36 }
37
38 static void ProcessStates() {
39 float newCanvasWidth = _currentReadBuffer->CanvasWidth;
40 float newCanvasHeight = _currentReadBuffer->CanvasHeight;
41 if (CanvasSize.X != newCanvasWidth || CanvasSize.Y != newCanvasHeight) {
42 CanvasSize = new Point2((int)newCanvasWidth, (int)newCanvasHeight);
43 Window.ResizeHandler(default);
44 }
45 float mousePositionX = _currentReadBuffer->MousePositionX;
46 float mousePositionY = _currentReadBuffer->MousePositionY;
47 Mouse.m_currentMousePosition = new Point2((int)mousePositionX, (int)mousePositionY);
48 for (int gamepadIndex = 0; gamepadIndex < 4; gamepadIndex++) {
49 GamePad.State state = GamePad.m_states[gamepadIndex];
50 if (!state.IsConnected) {
51 continue;
52 }
53 state.Sticks[0] = new Vector2(_currentReadBuffer->GamepadAxes[gamepadIndex * 4], -_currentReadBuffer->GamepadAxes[gamepadIndex * 4 + 1]);
54 state.Sticks[1] = new Vector2(_currentReadBuffer->GamepadAxes[gamepadIndex * 4 + 2], -_currentReadBuffer->GamepadAxes[gamepadIndex * 4 + 3]);
55 state.Triggers[0] = _currentReadBuffer->GamepadTriggers[gamepadIndex * 2];
56 state.Triggers[1] = _currentReadBuffer->GamepadTriggers[gamepadIndex * 2 + 1];
57 }
58 }
59
60 static void ProcessEvents() {
61 byte* ptr = _currentReadBuffer->EventData;
62 byte* end = ptr + _currentReadBuffer->UsedBytes;
63
64 while (ptr < end) {
65 InputEventType type = (InputEventType)(*ptr);
66 if (type == InputEventType.None) {
67 return;
68 }
69 if (((byte)type & 128) == 128) {
70 // 读取 12 字节
71 LargeEvent* e = (LargeEvent*)ptr;
73 ptr += 12;
74 }
75 else {
76 // 读取 4 字节
77 SmallEvent* e = (SmallEvent*)ptr;
79 ptr += 4;
80 }
81 }
82 }
83
84 static void HandleSmallEvent(SmallEvent* e) {
85 switch (e->Type) {
86 case InputEventType.KeyDown:
88 char c = (char)e->Payload;
89 if (c != 0) {
91 }
92 break;
93 case InputEventType.KeyUp:
95 break;
96 case InputEventType.GamepadButtonDown:
97 GamePad.m_states[e->Payload].Buttons[e->Param] = true;
98 break;
99 case InputEventType.GamepadButtonUp:
100 GamePad.m_states[e->Payload].Buttons[e->Param] = false;
101 break;
102 case InputEventType.GamepadDisconnected:
103 GamePad.GamepadDisconnectedHandler(e->Payload);
104 break;
105 case InputEventType.FocusChange:
107 break;
108 case InputEventType.FullscreenChange:
109 IsFullscreen = e->Param == 1;
110 break;
111 }
112 }
113
114 static void HandleLargeEvent(LargeEvent* e) {
115 switch (e->Header.Type) {
116 case InputEventType.MouseDown:
117 Mouse.ProcessMouseDown((MouseButton)e->Header.Param, new Point2((int)e->X, (int)e->Y));
118 break;
119 case InputEventType.MouseUp:
120 Mouse.ProcessMouseUp((MouseButton)e->Header.Param, new Point2((int)e->X, (int)e->Y));
121 break;
122 case InputEventType.MouseMove:
123 Mouse.m_queuedMouseMovement += new Vector2(e->X, e->Y);
124 break;
125 case InputEventType.MouseWheel:
126 Mouse.m_queuedMouseWheelMovement -= (e->Y);
127 break;
128 case InputEventType.TouchDown:
129 Touch.ProcessTouchPressed(e->Header.Param, new Point2((int)e->X, (int)e->Y));
130 break;
131 case InputEventType.TouchUp:
132 Touch.ProcessTouchReleased(e->Header.Param, new Point2((int)e->X, (int)e->Y));
133 break;
134 case InputEventType.TouchMove:
135 Touch.ProcessTouchMoved(e->Header.Param, new Point2((int)e->X, (int)e->Y));
136 break;
137 }
138 }
139 }
140}
unsafe
定义 Main.cs:15
static SharedInputMemory * _sharedPtr
static InputBuffer * _currentReadBuffer
static void HandleSmallEvent(SmallEvent *e)
static void HandleLargeEvent(LargeEvent *e)
static State[] m_states
static bool ProcessKeyDown(Key key)
static bool ProcessCharacterEntered(char ch)
static bool ProcessKeyUp(Key key)
static void ProcessMouseDown(MouseButton mouseButton, Point2 position)
static void ProcessMouseUp(MouseButton mouseButton, Point2 position)
static void ProcessTouchMoved(int id, Vector2 position)
static void ProcessTouchReleased(int id, Vector2 position)
static void ProcessTouchPressed(int id, Vector2 position)
static void FocusedChangedHandler(bool focused)
static void ResizeHandler(Vector2D< int > _)
static readonly Point2 One