9
9
10
10
#include "state.h"
11
11
12
+ #define MAX_EVENT_QUEUE_SIZE 128
13
+
14
+ enum {
15
+ KEY_EVENT = 0 ,
16
+ MOUSE_MOTION_EVENT = 1 ,
17
+ MOUSE_BUTTON_EVENT = 2 ,
18
+ };
19
+
20
+ typedef struct {
21
+ uint32_t keycode ;
22
+ uint8_t state ;
23
+ } key_event_t ;
24
+
25
+ typedef struct {
26
+ int32_t xrel , yrel ;
27
+ } mouse_motion_t ;
28
+
29
+ typedef struct {
30
+ uint8_t button ;
31
+ uint8_t state ;
32
+ } mouse_button_t ;
33
+
34
+ typedef struct {
35
+ uint32_t type ;
36
+ union {
37
+ key_event_t key_event ;
38
+ mouse_motion_t mouse_motion ;
39
+ mouse_button_t mouse_button ;
40
+ };
41
+ } event_t ;
42
+
43
+ typedef struct {
44
+ event_t events [MAX_EVENT_QUEUE_SIZE ];
45
+ size_t start , end ;
46
+ bool full ;
47
+ } event_queue_t ;
48
+
12
49
static SDL_Window * window = NULL ;
13
50
static SDL_Renderer * renderer ;
14
51
static SDL_Texture * texture ;
52
+ static event_queue_t event_queue = {
53
+ .events = {},
54
+ .start = 0 ,
55
+ .end = 0 ,
56
+ .full = false,
57
+ };
58
+
59
+ static bool event_pop (event_t * event )
60
+ {
61
+ if (event_queue .start == event_queue .end )
62
+ return false;
63
+ * event = event_queue .events [event_queue .start ++ ];
64
+ event_queue .start &= MAX_EVENT_QUEUE_SIZE - 1 ;
65
+ event_queue .full = false;
66
+ return true;
67
+ }
68
+
69
+ static void event_push (event_t event )
70
+ {
71
+ if (event_queue .full )
72
+ return ;
73
+ event_queue .events [event_queue .end ++ ] = event ;
74
+ event_queue .end &= MAX_EVENT_QUEUE_SIZE - 1 ;
75
+ event_queue .full = (event_queue .start == event_queue .end );
76
+ }
15
77
16
78
/* check if we need to setup SDL and run event loop */
17
79
static bool check_sdl (struct riscv_t * rv , uint32_t width , uint32_t height )
@@ -43,10 +105,55 @@ static bool check_sdl(struct riscv_t *rv, uint32_t width, uint32_t height)
43
105
rv_halt (rv );
44
106
return false;
45
107
case SDL_KEYDOWN :
46
- if (event .key .keysym .sym == SDLK_ESCAPE ) {
47
- rv_halt (rv );
48
- return false;
108
+ if (event .key .keysym .sym == SDLK_ESCAPE &&
109
+ SDL_GetRelativeMouseMode () == SDL_TRUE ) {
110
+ SDL_SetRelativeMouseMode (SDL_FALSE );
111
+ break ;
49
112
}
113
+ /* fall through */
114
+ case SDL_KEYUP : {
115
+ if (event .key .repeat )
116
+ break ;
117
+ event_t new_event = {
118
+ .type = KEY_EVENT ,
119
+ .key_event =
120
+ {
121
+ .keycode = event .key .keysym .sym ,
122
+ .state = (bool ) (event .key .state == SDL_PRESSED ),
123
+ },
124
+ };
125
+ event_push (new_event );
126
+ break ;
127
+ }
128
+ case SDL_MOUSEMOTION : {
129
+ event_t new_event = {
130
+ .type = MOUSE_MOTION_EVENT ,
131
+ .mouse_motion =
132
+ {
133
+ .xrel = event .motion .xrel ,
134
+ .yrel = event .motion .yrel ,
135
+ },
136
+ };
137
+ event_push (new_event );
138
+ break ;
139
+ }
140
+ case SDL_MOUSEBUTTONDOWN :
141
+ if (event .button .button == SDL_BUTTON_LEFT &&
142
+ SDL_GetRelativeMouseMode () == SDL_FALSE ) {
143
+ SDL_SetRelativeMouseMode (SDL_TRUE );
144
+ break ;
145
+ }
146
+ /* fall through */
147
+ case SDL_MOUSEBUTTONUP : {
148
+ event_t new_event = {
149
+ .type = MOUSE_BUTTON_EVENT ,
150
+ .mouse_button = {
151
+ .button = event .button .button ,
152
+ .state = (bool ) (event .button .state == SDL_PRESSED ),
153
+ }};
154
+ event_push (new_event );
155
+ break ;
156
+ }
50
157
}
51
158
}
52
159
return true;
@@ -118,3 +225,35 @@ void syscall_draw_frame_pal(struct riscv_t *rv)
118
225
free (i );
119
226
free (j );
120
227
}
228
+
229
+ void syscall_poll_event (struct riscv_t * rv )
230
+ {
231
+ state_t * s = rv_userdata (rv ); /* access userdata */
232
+
233
+ /* poll_event(base) */
234
+ const uint32_t base = rv_get_reg (rv , rv_reg_a0 );
235
+
236
+ event_t event ;
237
+ if (!event_pop (& event )) {
238
+ rv_set_reg (rv , rv_reg_a0 , 0 );
239
+ return ;
240
+ }
241
+
242
+ memory_write (s -> mem , base + 0 , (const uint8_t * ) & event .type , 4 );
243
+ switch (event .type ) {
244
+ case KEY_EVENT :
245
+ memory_write (s -> mem , base + 4 , (const uint8_t * ) & event .key_event ,
246
+ sizeof (key_event_t ));
247
+ break ;
248
+ case MOUSE_MOTION_EVENT :
249
+ memory_write (s -> mem , base + 4 , (const uint8_t * ) & event .mouse_motion ,
250
+ sizeof (mouse_motion_t ));
251
+ break ;
252
+ case MOUSE_BUTTON_EVENT :
253
+ memory_write (s -> mem , base + 4 , (const uint8_t * ) & event .mouse_button ,
254
+ sizeof (mouse_button_t ));
255
+ break ;
256
+ }
257
+
258
+ rv_set_reg (rv , rv_reg_a0 , 1 );
259
+ }
0 commit comments