(uxnemu) Use a separate thread for triggering redraws.

The main loop now uses SDL_WaitEvent instead of SDL_PollEvent, and the
indentation level needs to change. For clarity, this commit contains the
code changes, while the next one updates the indentation.
This commit is contained in:
Andrew Alderwick 2022-03-27 13:16:40 +01:00
parent 1f7a15d05b
commit a283264df2
1 changed files with 37 additions and 19 deletions

View File

@ -32,7 +32,6 @@ WITH REGARD TO THIS SOFTWARE.
#define WIDTH 64 * 8 #define WIDTH 64 * 8
#define HEIGHT 40 * 8 #define HEIGHT 40 * 8
#define PAD 4 #define PAD 4
#define BENCH 0
static SDL_Window *gWindow; static SDL_Window *gWindow;
static SDL_Texture *gTexture; static SDL_Texture *gTexture;
@ -44,7 +43,7 @@ static SDL_Rect gRect;
static Device *devscreen, *devmouse, *devctrl, *devaudio0, *devfile0; static Device *devscreen, *devmouse, *devctrl, *devaudio0, *devfile0;
static Uint8 zoom = 1; static Uint8 zoom = 1;
static Uint32 stdin_event, audio0_event; static Uint32 stdin_event, audio0_event, redraw_event;
static int static int
error(char *msg, const char *err) error(char *msg, const char *err)
@ -87,6 +86,20 @@ stdin_handler(void *p)
(void)p; (void)p;
} }
static int
redraw_handler(void *p)
{
SDL_Event event;
event.type = redraw_event;
for(;;) {
SDL_Delay(16);
if(SDL_HasEvent(redraw_event) == SDL_FALSE)
SDL_PushEvent(&event);
}
return 0;
(void)p;
}
static void static void
set_window_size(SDL_Window *window, int w, int h) set_window_size(SDL_Window *window, int w, int h)
{ {
@ -155,7 +168,9 @@ init(void)
error("sdl_joystick", SDL_GetError()); error("sdl_joystick", SDL_GetError());
stdin_event = SDL_RegisterEvents(1); stdin_event = SDL_RegisterEvents(1);
audio0_event = SDL_RegisterEvents(POLYPHONY); audio0_event = SDL_RegisterEvents(POLYPHONY);
redraw_event = SDL_RegisterEvents(1);
SDL_CreateThread(stdin_handler, "stdin", NULL); SDL_CreateThread(stdin_handler, "stdin", NULL);
SDL_CreateThread(redraw_handler, "redraw", NULL);
SDL_StartTextInput(); SDL_StartTextInput();
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
SDL_EventState(SDL_DROPFILE, SDL_ENABLE); SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
@ -374,14 +389,13 @@ console_input(Uxn *u, char c)
static int static int
run(Uxn *u) run(Uxn *u)
{ {
SDL_Event event;
Device *devsys = &u->dev[0]; Device *devsys = &u->dev[0];
redraw(); redraw();
while(!devsys->dat[0xf]) { while(SDL_WaitEvent(&event)) {
SDL_Event event; /* .System/halt */
double elapsed, begin; if(devsys->dat[0xf])
if(!BENCH) return error("Run", "Ended.");
begin = SDL_GetPerformanceCounter();
while(SDL_PollEvent(&event) != 0) {
/* Window */ /* Window */
if(event.type == SDL_QUIT) if(event.type == SDL_QUIT)
return error("Run", "Quit."); return error("Run", "Quit.");
@ -420,8 +434,14 @@ run(Uxn *u)
else else
do_shortcut(u, &event); do_shortcut(u, &event);
ksym = event.key.keysym.sym; ksym = event.key.keysym.sym;
if(SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_KEYUP, SDL_KEYUP) == 1 && ksym == event.key.keysym.sym) while(SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, redraw_event, redraw_event) == 0) {
break; SDL_Delay(4);
SDL_PumpEvents();
}
if(SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_KEYUP, SDL_KEYUP) == 1 && ksym == event.key.keysym.sym) {
SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_KEYUP, SDL_KEYUP);
SDL_PushEvent(&event);
}
} else if(event.type == SDL_KEYUP) } else if(event.type == SDL_KEYUP)
controller_up(devctrl, get_button(&event)); controller_up(devctrl, get_button(&event));
else if(event.type == SDL_JOYAXISMOTION) { else if(event.type == SDL_JOYAXISMOTION) {
@ -437,16 +457,14 @@ run(Uxn *u)
/* Console */ /* Console */
else if(event.type == stdin_event) else if(event.type == stdin_event)
console_input(u, event.cbutton.button); console_input(u, event.cbutton.button);
} /* .Screen/vector and redraw */
else if(event.type == redraw_event) {
uxn_eval(u, GETVECTOR(devscreen)); uxn_eval(u, GETVECTOR(devscreen));
if(uxn_screen.fg.changed || uxn_screen.bg.changed) if(uxn_screen.fg.changed || uxn_screen.bg.changed)
redraw(); redraw();
if(!BENCH) {
elapsed = (SDL_GetPerformanceCounter() - begin) / (double)SDL_GetPerformanceFrequency() * 1000.0f;
SDL_Delay(clamp(16.666f - elapsed, 0, 1000));
} }
} }
return error("Run", "Ended."); return error("SDL_WaitEvent", SDL_GetError());
} }
int int