This reverts commit a283264df27c2a886de41d23841dfe3e92b4b2c1 while
keeping the enhancements made later on (detection of overlong
execution).
This change fixes compatibility for learn-uxn and current npe.
... | ... |
@@ -36,7 +36,8 @@ WITH REGARD TO THIS SOFTWARE. |
36 | 36 |
#define WIDTH 64 * 8 |
37 | 37 |
#define HEIGHT 40 * 8 |
38 | 38 |
#define PAD 4 |
39 |
-#define TIMEOUT_FRAMES 20 |
|
39 |
+#define TIMEOUT_MS 334 |
|
40 |
+#define BENCH 0 |
|
40 | 41 |
|
41 | 42 |
static SDL_Window *gWindow; |
42 | 43 |
static SDL_Texture *gTexture; |
... | ... |
@@ -49,7 +50,8 @@ static SDL_Thread *stdin_thread; |
49 | 50 |
|
50 | 51 |
static Device *devscreen, *devmouse, *devctrl, *devaudio0; |
51 | 52 |
static Uint8 zoom = 1; |
52 |
-static Uint32 stdin_event, audio0_event, redraw_event, interrupt_event; |
|
53 |
+static Uint32 stdin_event, audio0_event; |
|
54 |
+static Uint64 exec_deadline, deadline_interval, ms_interval; |
|
53 | 55 |
|
54 | 56 |
static int |
55 | 57 |
error(char *msg, const char *err) |
... | ... |
@@ -93,26 +95,6 @@ stdin_handler(void *p) |
93 | 95 |
(void)p; |
94 | 96 |
} |
95 | 97 |
|
96 |
-static int |
|
97 |
-redraw_handler(void *p) |
|
98 |
-{ |
|
99 |
- int dropped_frames = 0, stop = 0; |
|
100 |
- SDL_Event event, interrupt; |
|
101 |
- event.type = redraw_event; |
|
102 |
- interrupt.type = interrupt_event; |
|
103 |
- while(!stop) { |
|
104 |
- SDL_Delay(16); |
|
105 |
- if(SDL_HasEvent(redraw_event) == SDL_FALSE) { |
|
106 |
- stop = SDL_PushEvent(&event) < 0; |
|
107 |
- dropped_frames = 0; |
|
108 |
- } else if(++dropped_frames == TIMEOUT_FRAMES) { |
|
109 |
- stop = SDL_PushEvent(&interrupt) < 0; |
|
110 |
- } |
|
111 |
- } |
|
112 |
- return 0; |
|
113 |
- (void)p; |
|
114 |
-} |
|
115 |
- |
|
116 | 98 |
static void |
117 | 99 |
set_window_size(SDL_Window *window, int w, int h) |
118 | 100 |
{ |
... | ... |
@@ -181,13 +163,12 @@ init(void) |
181 | 163 |
error("sdl_joystick", SDL_GetError()); |
182 | 164 |
stdin_event = SDL_RegisterEvents(1); |
183 | 165 |
audio0_event = SDL_RegisterEvents(POLYPHONY); |
184 |
- redraw_event = SDL_RegisterEvents(1); |
|
185 |
- interrupt_event = SDL_RegisterEvents(1); |
|
186 | 166 |
SDL_DetachThread(stdin_thread = SDL_CreateThread(stdin_handler, "stdin", NULL)); |
187 |
- SDL_DetachThread(SDL_CreateThread(redraw_handler, "redraw", NULL)); |
|
188 | 167 |
SDL_StartTextInput(); |
189 | 168 |
SDL_ShowCursor(SDL_DISABLE); |
190 | 169 |
SDL_EventState(SDL_DROPFILE, SDL_ENABLE); |
170 |
+ ms_interval = SDL_GetPerformanceFrequency() / 1000; |
|
171 |
+ deadline_interval = ms_interval * TIMEOUT_MS; |
|
191 | 172 |
return 1; |
192 | 173 |
} |
193 | 174 |
|
... | ... |
@@ -290,6 +271,7 @@ start(Uxn *u, char *rom) |
290 | 271 |
/* unused */ uxn_port(u, 0xd, nil_dei, nil_deo); |
291 | 272 |
/* unused */ uxn_port(u, 0xe, nil_dei, nil_deo); |
292 | 273 |
/* unused */ uxn_port(u, 0xf, nil_dei, nil_deo); |
274 |
+ exec_deadline = SDL_GetPerformanceCounter() + deadline_interval; |
|
293 | 275 |
if(!uxn_eval(u, PAGE_PROGRAM)) |
294 | 276 |
return error("Boot", "Failed to start rom."); |
295 | 277 |
return 1; |
... | ... |
@@ -392,15 +374,10 @@ console_input(Uxn *u, char c) |
392 | 374 |
} |
393 | 375 |
|
394 | 376 |
static int |
395 |
-run(Uxn *u) |
|
377 |
+handle_events(Uxn *u) |
|
396 | 378 |
{ |
397 | 379 |
SDL_Event event; |
398 |
- Device *devsys = &u->dev[0]; |
|
399 |
- redraw(); |
|
400 |
- while(SDL_WaitEvent(&event)) { |
|
401 |
- /* .System/halt */ |
|
402 |
- if(devsys->dat[0xf]) |
|
403 |
- return error("Run", "Ended."); |
|
380 |
+ while(SDL_PollEvent(&event)) { |
|
404 | 381 |
/* Window */ |
405 | 382 |
if(event.type == SDL_QUIT) |
406 | 383 |
return error("Run", "Quit."); |
... | ... |
@@ -439,13 +416,8 @@ run(Uxn *u) |
439 | 416 |
else |
440 | 417 |
do_shortcut(u, &event); |
441 | 418 |
ksym = event.key.keysym.sym; |
442 |
- while(SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, redraw_event, redraw_event) == 0) { |
|
443 |
- SDL_Delay(4); |
|
444 |
- SDL_PumpEvents(); |
|
445 |
- } |
|
446 | 419 |
if(SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_KEYUP, SDL_KEYUP) == 1 && ksym == event.key.keysym.sym) { |
447 |
- SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_KEYUP, SDL_KEYUP); |
|
448 |
- SDL_PushEvent(&event); |
|
420 |
+ return 1; |
|
449 | 421 |
} |
450 | 422 |
} else if(event.type == SDL_KEYUP) |
451 | 423 |
controller_up(devctrl, get_button(&event)); |
... | ... |
@@ -462,11 +434,30 @@ run(Uxn *u) |
462 | 434 |
/* Console */ |
463 | 435 |
else if(event.type == stdin_event) |
464 | 436 |
console_input(u, event.cbutton.button); |
465 |
- /* .Screen/vector and redraw */ |
|
466 |
- else if(event.type == redraw_event) { |
|
467 |
- uxn_eval(u, GETVECTOR(devscreen)); |
|
468 |
- if(uxn_screen.fg.changed || uxn_screen.bg.changed) |
|
469 |
- redraw(); |
|
437 |
+ } |
|
438 |
+ return 1; |
|
439 |
+} |
|
440 |
+ |
|
441 |
+static int |
|
442 |
+run(Uxn *u) |
|
443 |
+{ |
|
444 |
+ Device *devsys = &u->dev[0]; |
|
445 |
+ Uint64 now = SDL_GetPerformanceCounter(), frame_end, frame_interval = SDL_GetPerformanceFrequency() / 60; |
|
446 |
+ for(;;) { |
|
447 |
+ /* .System/halt */ |
|
448 |
+ if(devsys->dat[0xf]) |
|
449 |
+ return error("Run", "Ended."); |
|
450 |
+ frame_end = now + frame_interval; |
|
451 |
+ exec_deadline = now + deadline_interval; |
|
452 |
+ if(!handle_events(u)) |
|
453 |
+ return 0; |
|
454 |
+ uxn_eval(u, GETVECTOR(devscreen)); |
|
455 |
+ if(uxn_screen.fg.changed || uxn_screen.bg.changed) |
|
456 |
+ redraw(); |
|
457 |
+ now = SDL_GetPerformanceCounter(); |
|
458 |
+ if(!BENCH && ((Sint64)(frame_end - now)) > 0) { |
|
459 |
+ SDL_Delay((frame_end - now) / ms_interval); |
|
460 |
+ now = frame_end; |
|
470 | 461 |
} |
471 | 462 |
} |
472 | 463 |
return error("SDL_WaitEvent", SDL_GetError()); |
... | ... |
@@ -475,7 +466,7 @@ run(Uxn *u) |
475 | 466 |
int |
476 | 467 |
uxn_interrupt(void) |
477 | 468 |
{ |
478 |
- return SDL_PeepEvents(NULL, 1, SDL_GETEVENT, interrupt_event, interrupt_event) < 1; |
|
469 |
+ return ((Sint64)(exec_deadline - SDL_GetPerformanceCounter())) > 0; |
|
479 | 470 |
} |
480 | 471 |
|
481 | 472 |
int |