11 #define TICKS_PER_FRAME (1000 / 60)
13 /* The window we'll be using */
14 static SDL_Window
*sdl_win
;
16 /* The screen surface we'll be using */
17 static SDL_Surface
*sdl_surf
;
19 /* How to limit the framerate */
20 static Uint32 frame_start_ticks
;
22 /* If conf/deny, the message onscreen */
23 static const char *conf_deny_text
;
25 /* Buffer for event queue */
26 static struct ui_event
*eq_buf
;
28 /* Current max length of event queue */
31 /* Current head of queue */
32 static size_t eq_head
;
34 /* Current tail of queue */
35 static size_t eq_tail
;
38 static void eq_pop(struct ui_event
*out
)
40 if (eq_head
== eq_tail
) {
41 *out
= (struct ui_event
) { 0 };
46 memcpy(out
, eq_buf
+ eq_head
, sizeof *out
);
47 eq_buf
[eq_head
] = (struct ui_event
) { 0 };
48 eq_head
= (eq_head
+ 1) % eq_len
;
52 static int eq_push(struct ui_event
*in
)
57 if (((eq_tail
+ 1) % eq_len
) == eq_head
) {
58 if ((eq_len
* sizeof *in
) >= ((size_t) -1) / 2) {
60 "eq_push: Impossibly large buffer\n"));
65 if (!(newmem
= realloc(eq_buf
, (eq_len
* 2) *
73 eq_buf
= (struct ui_event
*) newmem
;
77 memcpy(eq_buf
+ eq_tail
, in
, sizeof *in
);
78 eq_tail
= (eq_tail
+ 1) % eq_len
;
88 if (SDL_Init(SDL_INIT_VIDEO
) < 0) {
89 fprintf(stderr
, L("SDL_Init(): %s\n"), SDL_GetError());
94 sdl_win
= SDL_CreateWindow("Cluster Algebra Visualizer",
95 SDL_WINDOWPOS_UNDEFINED
,
96 SDL_WINDOWPOS_UNDEFINED
, 800, 600,
100 fprintf(stderr
, L("SDL_CreateWindow(): %s\n"), SDL_GetError());
105 sdl_surf
= SDL_GetWindowSurface(sdl_win
);
108 fprintf(stderr
, L("SDL_GetWindowSurface(): %s\n"),
114 SDL_FillRect(sdl_surf
, 0, SDL_MapRGB(sdl_surf
->format
, 0xe2, 0xe2,
116 SDL_UpdateWindowSurface(sdl_win
);
118 /* Set up queue for returning data */
119 if (!(eq_buf
= calloc(2, sizeof *eq_buf
))) {
134 int ui_teardown(void)
137 SDL_DestroyWindow(sdl_win
);
145 /* Record that a frame has been started */
146 int ui_start_frame(void)
148 frame_start_ticks
= SDL_GetTicks();
153 /* Draw a frame, possibly sleeping for framelimit */
154 int ui_finish_frame(void)
157 Uint32 elapsed_time
= 0;
158 SDL_Event sdl_e
= { 0 };
159 struct ui_event ui_e
= { 0 };
161 /* Draw the damn thing */
167 /* Handle user input */
168 while (SDL_PollEvent(&sdl_e
) != 0) {
169 switch (sdl_e
.type
) {
171 ui_e
= (struct ui_event
) { .type
= ET_FORCE_QUIT
};
180 now
= SDL_GetTicks();
182 if (frame_start_ticks
< now
) {
183 elapsed_time
= now
- frame_start_ticks
;
185 if (elapsed_time
< TICKS_PER_FRAME
) {
186 SDL_Delay(TICKS_PER_FRAME
- elapsed_time
);
193 /* Return an event to the main loop */
194 int ui_get_event(struct ui_event
*e
, uint_fast8_t *more
)
197 *more
= eq_head
!= eq_tail
;
202 /* Be told to display a confirm dialog */
203 int ui_confirm_deny(const char *s
)