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 |