void iter() { printf("frame: %d\n", ++counter); emscripten_async_call(acall, 0, counter % 2); // 0 or 1 millis, try to execute this *before* the sync callback finishes, which would be bad // ensure we don't 'recurse' with the main loop sending is back in before the synchronous operation callback finishes the rest of this trace assert(nesting == 0); nesting++; emscripten_sleep(500); assert(nesting == 1); nesting = 2; if (counter % 3 == 2) { // second sleep every 3rd frame, to test sleep when returning from a sleep printf(" (second sleep)\n"); assert(nesting == 2); nesting = 3; emscripten_sleep(1000); assert(nesting == 3); }; nesting = 0; if (counter == 10) { assert(acall_counter == 9 /* the tenth is about to execute, but not yet! */ ); finish(121); // if we got here without hitting any assertions, all is well emscripten_cancel_main_loop(); } }
static bool sleepWithTimeout(int duration, int * timeout) { if (*timeout >= duration) { emscripten_sleep(duration); *timeout -= duration; return false; } else { emscripten_sleep(*timeout); *timeout = 0; return true; } }
int main(void) { printf("No yield:\n"); emscripten_sleep(500); printf("With yield:\n"); emscripten_sleep_with_yield(500); printf("Again no yield:\n"); emscripten_sleep(500); printf("Done!\n"); REPORT_RESULT(1); return 0; }
int main(int argc, char **argv) { SDL_Init(SDL_INIT_VIDEO); SDL_Surface *screen = SDL_SetVideoMode(600, 450, 32, SDL_HWSURFACE); #ifdef TEST_EMSCRIPTEN_SDL_SETEVENTHANDLER emscripten_SDL_SetEventHandler(EventHandler, 0); #endif emscripten_set_main_loop(one, 0, 0); emscripten_run_script("keydown(1250);keydown(38);keyup(38);keyup(1250);"); // alt, up emscripten_run_script("keydown(1248);keydown(1249);keydown(40);keyup(40);keyup(1249);keyup(1248);"); // ctrl, shift, down emscripten_run_script("keydown(37);keyup(37);"); // left emscripten_run_script("keydown(39);keyup(39);"); // right #ifdef TEST_SLEEP printf("sleep...\n"); emscripten_sleep(2000); //emscripten_sleep_with_yield(1); printf("rise!\n"); #endif emscripten_run_script("keydown(65);keyup(65);"); // a emscripten_run_script("keydown(66);keyup(66);"); // b emscripten_run_script("keydown(100);keyup(100);"); // trigger the end return 0; }
int Web_nh_poskey(int * x, int * y, int * mod) { while(Web_keybuffer_empty() && Web_mousebuffer_empty()) emscripten_sleep(10); if(!Web_keybuffer_empty()) return Web_getch(); Web_save_mouse(x, y, mod); return 0; }
void one(char *data, int size) { int *x = (int*)data; int num = size/sizeof(int); for (int i = 0; i < num; i++) { x[i] += 1234; } emscripten_sleep(1000); emscripten_worker_respond(data, size); }
void loop(void) { emscripten_sleep(1); loops++; printf("loop: mains, inners, nevers, loops: %d, %d, %d, %d\n", mains, inners, nevers, loops); if (loops > 5) { printf("done looping\n"); emscripten_cancel_main_loop(); assert(mains == 1); // never re-enter main assert(inners == 1); // never re-enter inner assert(nevers == 0); // never reach never int result = 1; REPORT_RESULT(); return; } }
static void morphdraw() { int s = STATE > 0 ? (STATE < MTIME ? STATE : MTIME) : 0; int mul = s * 256 / MTIME; int mul1 = 256 - mul; int i; int size = aa_imgwidth(context) * (aa_imgheight(context) - YSTART * 2); char *c = context->imagebuffer + aa_imgwidth(context) * 2 * YSTART; for (i = 0; i < size; i++, c++) { *c = (source[i] * mul1 + target[i] * mul) >> 8; } aa_fastrender(context, 0, YSTART, aa_scrwidth(context), aa_scrheight(context)); aa_flush(context); emscripten_sleep(1); }
static void toblack1() { int x, y, mul1, mul2 = 0, pos; int minpos = 0; unsigned char *b1 = bckup, *b2 = bckup1; pos = STAGE * (aa_imgheight(context) + aa_imgheight(context)) / (endtime - starttime) - aa_imgheight(context); for (y = 0; y < aa_imgheight(context); y++) { mul1 = (y - pos); if (mul1 < 0) mul1 = 0; else mul1 = mul1 * 256 * 4 / aa_imgheight(context); if (mul1 > 256) mul1 = 256; mul2 = (y - pos - aa_imgheight(context)); if (mul2 < 0) mul2 = 0; else mul2 = mul2 * 256 * 8 / aa_imgheight(context); if (mul2 > 256) mul2 = 256; if (mul2 == 0) minpos = y; mul1 -= mul2; for (x = 0; x < aa_imgwidth(context); x++) { aa_putpixel(context, x, y, (mul1 * (int) (*b1) + mul2 * (int) (*b2)) / 256); b1++; b2++; } } minpos = pos + 3 * aa_imgheight(context) / 4; if (minpos < 0) minpos = 0; if (minpos > aa_imgheight(context)) minpos = aa_imgheight(context); aa_render(context, params, 0, 0, aa_imgwidth(context), minpos); aa_flush(context); emscripten_sleep(1); }
int BatchFile::ReadLine(char * line) { printf("Sleep-->\n"); emscripten_sleep(300); printf("<--Sleep\n"); return 1; }
void sleeper() { emscripten_sleep(100); }
void tl_sleep(int time) { emscripten_sleep(time / 1000); }
void Web_get_nh_event() { emscripten_sleep(1); }
void Web_display_nhwindow(winid window, BOOLEAN_P blocking) { emscripten_sleep(1); }
void Web_delay_output() { emscripten_sleep(50); }
int Web_nhgetch() { while(Web_keybuffer_empty()) emscripten_sleep(10); return Web_getch(); }
void Web_wait_synch() { emscripten_sleep(1); }
void Web_mark_synch() { emscripten_sleep(1); }
static inline void HandleEvent(struct Game* game, ALLEGRO_EVENT* ev) { switch (ev->type) { case ALLEGRO_EVENT_DISPLAY_HALT_DRAWING: PauseExecution(game); al_acknowledge_drawing_halt(game->display); break; case ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING: al_acknowledge_drawing_resume(game->display); ReloadGamestates(game); ResumeExecution(game); break; case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT: if (game->config.autopause) { PrintConsole(game, "Focus lost, autopausing..."); PauseExecution(game); } break; case ALLEGRO_EVENT_DISPLAY_SWITCH_IN: if (game->config.autopause) { if (game->config.debug.enabled && game->config.debug.livereload) { ReloadCode(game); } ResumeExecution(game); } break; case ALLEGRO_EVENT_DISPLAY_RESIZE: PrintConsole(game, "Resize event: %dx%d", ev->display.width, ev->display.height); #ifdef LIBSUPERDERPY_IMGUI ImGui_ImplAllegro5_InvalidateDeviceObjects(); #endif al_acknowledge_resize(game->display); #ifdef LIBSUPERDERPY_IMGUI ImGui_ImplAllegro5_CreateDeviceObjects(); #endif // SetupViewport can be expensive, so don't do it when the resize event is already outdated or doesn't change anything if (((ev->display.width != game->_priv.window_width) || (ev->display.height != game->_priv.window_height)) && (ev->display.width == al_get_display_width(game->display)) && (ev->display.height == al_get_display_height(game->display))) { SetupViewport(game); } break; case ALLEGRO_EVENT_KEY_DOWN: #ifdef ALLEGRO_ANDROID if ((ev->keyboard.keycode == ALLEGRO_KEY_MENU) || (ev->keyboard.keycode == ALLEGRO_KEY_TILDE) || (ev->keyboard.keycode == ALLEGRO_KEY_BACKQUOTE)) { #else if ((ev->keyboard.keycode == ALLEGRO_KEY_TILDE) || (ev->keyboard.keycode == ALLEGRO_KEY_BACKQUOTE)) { #endif game->_priv.showconsole = !game->_priv.showconsole; if ((ev->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL) && (game->config.debug.enabled)) { game->_priv.showtimeline = game->_priv.showconsole; } } if (ev->keyboard.keycode == ALLEGRO_KEY_F12) { DrawGamestates(game); int flags = al_get_new_bitmap_flags(); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); ALLEGRO_BITMAP* bitmap = al_create_bitmap(al_get_display_width(game->display), al_get_display_height(game->display)); al_set_new_bitmap_flags(flags); ALLEGRO_BITMAP* target = al_get_target_bitmap(); al_set_target_bitmap(bitmap); al_draw_bitmap(al_get_backbuffer(game->display), 0, 0, 0); al_set_target_bitmap(target); PrintConsole(game, "Screenshot made! Storing..."); struct ScreenshotThreadData* data = malloc(sizeof(struct ScreenshotThreadData)); data->game = game; data->bitmap = bitmap; #ifndef LIBSUPERDERPY_SINGLE_THREAD al_run_detached_thread(ScreenshotThread, data); #else ScreenshotThread(data); #endif } break; default: break; } #ifdef MAEMO5 // on Maemo we get mouse events instead of touch ones, so we'll rewrite them by ourselves if ((ev->type == ALLEGRO_EVENT_MOUSE_AXES) || (ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) || (ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_UP)) { switch (ev->type) { case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: ev->type = ALLEGRO_EVENT_TOUCH_BEGIN; break; case ALLEGRO_EVENT_MOUSE_BUTTON_UP: ev->type = ALLEGRO_EVENT_TOUCH_END; break; case ALLEGRO_EVENT_MOUSE_AXES: ev->type = ALLEGRO_EVENT_TOUCH_MOVE; break; default: break; } ALLEGRO_DISPLAY* display = ev->mouse.display; float dx = ev->mouse.dx; float dy = ev->mouse.dy; float x = ev->mouse.x; float y = ev->mouse.y; double timestamp = ev->mouse.timestamp; ev->touch.display = display; ev->touch.dx = dx; ev->touch.dy = dy; ev->touch.id = 0; ev->touch.primary = true; ev->touch.source = (ALLEGRO_TOUCH_INPUT*)al_get_touch_input_event_source(); ev->touch.timestamp = timestamp; ev->touch.x = x; ev->touch.y = y; } #endif } static inline void HandleDebugEvent(struct Game* game, ALLEGRO_EVENT* ev) { switch (ev->type) { case ALLEGRO_EVENT_KEY_DOWN: switch (ev->keyboard.keycode) { case ALLEGRO_KEY_F1: if (!game->_priv.paused) { PauseExecution(game); } else { ReloadCode(game); ResumeExecution(game); } break; case ALLEGRO_KEY_F9: game->_priv.speed = ALLEGRO_BPS_TO_SECS(60.0); game->_priv.showconsole = true; PrintConsole(game, "DEBUG: Gameplay speed: 1.00x"); break; case ALLEGRO_KEY_F10: { double speed = ALLEGRO_BPS_TO_SECS(game->_priv.speed); // inverting speed -= 10; if (speed < 10) { speed = 10; } game->_priv.speed = ALLEGRO_BPS_TO_SECS(speed); game->_priv.showconsole = true; PrintConsole(game, "DEBUG: Gameplay speed: %.2fx", speed / 60.0); } break; case ALLEGRO_KEY_F11: { double speed = ALLEGRO_BPS_TO_SECS(game->_priv.speed); // inverting speed += 10; if (speed > 600) { speed = 600; } game->_priv.speed = ALLEGRO_BPS_TO_SECS(speed); game->_priv.showconsole = true; PrintConsole(game, "DEBUG: Gameplay speed: %.2fx", speed / 60.0); } break; } break; default: break; } } static inline bool MainloopEvents(struct Game* game) { do { ALLEGRO_EVENT ev; if (game->_priv.paused && !IS_EMSCRIPTEN) { // there's no frame flipping when paused, so avoid pointless busylooping al_wait_for_event(game->_priv.event_queue, &ev); } else if (!al_get_next_event(game->_priv.event_queue, &ev)) { break; } #ifdef LIBSUPERDERPY_IMGUI ImGui_ImplAllegro5_ProcessEvent(&ev); switch (ev.type) { case ALLEGRO_EVENT_KEY_CHAR: case ALLEGRO_EVENT_KEY_DOWN: case ALLEGRO_EVENT_KEY_UP: if (igGetIO()->WantCaptureKeyboard) { continue; } break; case ALLEGRO_EVENT_MOUSE_AXES: case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: case ALLEGRO_EVENT_MOUSE_BUTTON_UP: case ALLEGRO_EVENT_TOUCH_BEGIN: case ALLEGRO_EVENT_TOUCH_CANCEL: case ALLEGRO_EVENT_TOUCH_END: case ALLEGRO_EVENT_TOUCH_MOVE: if (igGetIO()->WantCaptureMouse) { continue; } break; default: break; } #endif if (game->_priv.params.handlers.event) { if ((*game->_priv.params.handlers.event)(game, &ev)) { continue; } } if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { EventGamestates(game, &ev); return false; } HandleEvent(game, &ev); if (game->config.debug.enabled) { HandleDebugEvent(game, &ev); } EventGamestates(game, &ev); } while (!al_is_event_queue_empty(game->_priv.event_queue)); return true; } static inline bool MainloopTick(struct Game* game) { if (game->_priv.paused) { return true; } struct Gamestate* tmp = game->_priv.gamestates; #ifdef __EMSCRIPTEN__ emscripten_pause_main_loop(); #endif game->_priv.loading.to_load = 0; game->_priv.loading.loaded = 0; game->_priv.loading.lock = true; game->loading.progress = 0; // TODO: support gamestate dependences/ordering while (tmp) { if (tmp->pending_stop) { PrintConsole(game, "Stopping gamestate \"%s\"...", tmp->name); game->_priv.current_gamestate = tmp; (*tmp->api->stop)(game, tmp->data); tmp->started = false; tmp->pending_stop = false; PrintConsole(game, "Gamestate \"%s\" stopped successfully.", tmp->name); } if (tmp->pending_load) { game->_priv.loading.to_load++; } tmp = tmp->next; } tmp = game->_priv.gamestates; while (tmp) { if (tmp->pending_unload) { #ifdef __EMSCRIPTEN__ al_detach_voice(game->audio.v); #endif PrintConsole(game, "Unloading gamestate \"%s\"...", tmp->name); tmp->loaded = false; tmp->pending_unload = false; game->_priv.current_gamestate = tmp; (*tmp->api->unload)(game, tmp->data); PrintConsole(game, "Gamestate \"%s\" unloaded successfully.", tmp->name); #ifdef __EMSCRIPTEN__ al_attach_mixer_to_voice(game->audio.mixer, game->audio.v); #endif } if (tmp->pending_load) { #ifdef __EMSCRIPTEN__ al_detach_voice(game->audio.v); #endif if (tmp->show_loading && game->_priv.loading.gamestate->open) { (*game->_priv.loading.gamestate->api->start)(game, game->_priv.loading.gamestate->data); } if (!tmp->api) { if (!OpenGamestate(game, tmp, true) || !LinkGamestate(game, tmp)) { tmp->pending_load = false; tmp->pending_start = false; continue; } } if (tmp->api) { PrintConsole(game, "Loading gamestate \"%s\"...", tmp->name); game->_priv.loading.progress = 0; game->_priv.loading.current = tmp; game->_priv.current_gamestate = tmp; struct GamestateLoadingThreadData data = {.game = game, .gamestate = tmp, .bitmap_flags = al_get_new_bitmap_flags()}; game->_priv.loading.in_progress = true; double time = al_get_time(); game->_priv.loading.time = time; CalculateProgress(game); if (tmp->show_loading) { game->loading.shown = true; DrawGamestates(game); DrawConsole(game); al_flip_display(); #ifdef __EMSCRIPTEN__ emscripten_sleep(0); #endif } #ifndef LIBSUPERDERPY_SINGLE_THREAD al_run_detached_thread(GamestateLoadingThread, &data); while (game->_priv.loading.in_progress) { double delta = al_get_time() - game->_priv.loading.time; game->time += delta; // TODO: ability to disable passing time during loading game->_priv.loading.time += delta; if (game->loading.shown && game->_priv.loading.gamestate->open) { (*game->_priv.loading.gamestate->api->logic)(game, game->_priv.loading.gamestate->data, delta); } DrawGamestates(game); if (game->_priv.texture_sync) { al_convert_memory_bitmaps(); game->_priv.texture_sync = false; al_signal_cond(game->_priv.texture_sync_cond); game->_priv.loading.time = al_get_time(); // TODO: rethink time management during loading } DrawConsole(game); al_flip_display(); if (game->_priv.bsod_sync) { al_set_target_bitmap(NULL); game->_priv.bsod_sync = false; al_signal_cond(game->_priv.bsod_cond); } al_lock_mutex(game->_priv.bsod_mutex); while (game->_priv.in_bsod) { al_wait_cond(game->_priv.bsod_cond, game->_priv.bsod_mutex); } al_unlock_mutex(game->_priv.bsod_mutex); } #else GamestateLoadingThread(&data); DrawGamestates(game); DrawConsole(game); al_flip_display(); #ifdef __EMSCRIPTEN__ emscripten_sleep(0); #endif al_convert_memory_bitmaps(); #endif al_set_new_bitmap_flags(data.bitmap_flags); ReloadShaders(game, false); if (tmp->api->post_load) { PrintConsole(game, "[%s] Post-loading...", tmp->name); tmp->api->post_load(game, tmp->data); } game->_priv.loading.progress++; CalculateProgress(game); PrintConsole(game, "Gamestate \"%s\" loaded successfully in %f seconds.", tmp->name, al_get_time() - time); game->_priv.loading.loaded++; DrawGamestates(game); DrawConsole(game); al_flip_display(); #ifdef __EMSCRIPTEN__ emscripten_sleep(0); #endif tmp->loaded = true; tmp->pending_load = false; } if (tmp->show_loading && game->_priv.loading.gamestate->open) { (*game->_priv.loading.gamestate->api->stop)(game, game->_priv.loading.gamestate->data); } tmp->show_loading = true; game->loading.shown = false; game->_priv.timestamp = al_get_time(); #ifdef __EMSCRIPTEN__ al_attach_mixer_to_voice(game->audio.mixer, game->audio.v); #endif } tmp = tmp->next; }
void credits2(void) { int i, ch; int p; int plast = -1; clrscr(); centerprint(aa_imgwidth(context) / 2, aa_imgheight(context) / 3, 3, 128, "The", 0); centerprint(aa_imgwidth(context) / 2, 2 * aa_imgheight(context) / 3, 3, 128, "END", 0); drawptr = decrand; params->randomval = 50; timestuff(0, NULL, draw, 5000000); drawptr = NULL; params->randomval = 0; drawptr = pryc; timestuff(0, NULL, draw, MAXTIME); drawptr = NULL; clrscr(); draw(); load_song("bb3.s3m"); bbupdate(); starttime = endtime = TIME; play(); bbwait(1); for (i = 0; i < LOGOHEIGHT; i++) { aa_puts(context, aa_scrwidth(context) / 2 - 2, LOGOY + i, AA_BOLD, "8 8"); if (i) aa_puts(context, aa_scrwidth(context) / 2 - 2, LOGOY + i - 1, AA_NORMAL, "8 8"); bbflushwait(100000); } aa_puts(context, aa_scrwidth(context) / 2 - 2, LOGOY + i - 1, AA_NORMAL, "8 8"); #define LWIDTH for (i = aa_scrwidth(context) / 2; i; i--) { display8(); displaya(i); bbflushwait(10000); } for (; i < 100; i++) { textclrscr(); displaya(10 * sin(i * M_PI / 100)); display8(); bbflushwait(10000); } aa_puts(context, aa_scrwidth(context) / 2 - 9, LOGOY + 3, AA_DIM, "<PROJECT><PROJECT>"); bbflushwait(100000); aa_puts(context, aa_scrwidth(context) / 2 - 9, LOGOY + 3, AA_NORMAL, "<PROJECT><PROJECT>"); bbflushwait(100000); aa_puts(context, aa_scrwidth(context) / 2 - 9, LOGOY + 3, AA_BOLD, "<PROJECT><PROJECT>"); bbflushwait(100000); aa_puts(context, aa_scrwidth(context) / 2 - 9, LOGOY + 3, AA_NORMAL, "<PROJECT><PROJECT>"); bbflushwait(100000); bbwait(1000000); for (i = LOGOY; i > 1; i--) { textclrscr(); displogo(i); bbflushwait(30000); } source = malloc(aa_imgwidth(context) * (aa_imgheight(context))); target = malloc(aa_imgwidth(context) * (aa_imgheight(context))); params->dither = AA_NONE; format(dual ? aa_scrwidth(context) / 2 : aa_scrwidth(context)); p = 0; while (1) { if (p != plast) { getsource(); displaytext(p); gettarget(); morph(); displaytext(p); aa_flush(context); emscripten_sleep(1); plast = p; } again: emscripten_sleep(100); #ifndef __DJGPP__ //ch = aa_getkey(context, 100); ch = AA_NONE; #else while ((ch = bbupdate()) == AA_NONE) ; #endif switch (ch) { case '1': load_song("bb.s3m"); bbupdate(); play(); break; case '2': load_song("bb2.s3m"); bbupdate(); play(); break; case '3': load_song("bb3.s3m"); bbupdate(); play(); break; case 'b': case 'k': case 'B': case 'K': case AA_BACKSPACE: case AA_UP: p -= (aa_scrheight(context) - YSTART) / 2 * (dual + 1); if (p < 0) p = 0; break; case AA_DOWN: case AA_LEFT: case 'f': case 'F': case ' ': case 'j': case 'J': p += (aa_scrheight(context) - YSTART) / 2 * (dual + 1); if (p > textsize) p = textsize; break; case 'q': case 'Q': case AA_ESC: finish_stuff = 0; backconvert(0, 0, aa_scrwidth(context), aa_scrheight(context)); bbupdate(); starttime = endtime = TIME; drawptr = decbright; timestuff(0, NULL, draw, 1000000); textclrscr(); drawptr = NULL; aa_flush(context); emscripten_sleep(1); free(source); free(target); return; default: goto again; } bbupdate(); starttime = endtime = TIME; } }