void OS_X11::run() { force_quit = false; if (!main_loop) return; main_loop->init(); // uint64_t last_ticks=get_ticks_usec(); // int frames=0; // uint64_t frame=0; while (!force_quit) { process_xevents(); // get rid of pending events process_joysticks(); if (Main::iteration()==true) break; }; main_loop->finish(); }
int main(int argc, char *argv[]) { char *title; SDL_Window *window; Uint32 flags; int x, y, width, height, shutdown; SDL_Renderer *renderer; SDL_Event event; SDL_AudioDeviceID sdl_audio_dev; struct timespec start, last_print, now, elapsed; unsigned long total_elapsed_seconds; double fps; unsigned long int frame_count, frames_since_print; struct game_memory mem; struct pixel_buffer *virtual_win; struct pixel_buffer blit_buf; struct human_input input[2]; struct human_input *tmp_input; struct human_input *new_input; struct human_input *old_input; struct sdl_texture_buffer texture_buf; struct sdl_event_context event_ctx; struct audio_ring_buffer audio_ring_buf; struct audio_buffer audio_buf; pixel_buffer_init(&blit_buf); texture_buf.texture = NULL; texture_buf.pixel_buf = &blit_buf; flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC; if (SDL_Init(flags) != 0) { return 1; } height = 480; width = 640; mem.is_initialized = 0; mem.fixed_memory_size = 4 * 1024 * 1024; mem.transient_memory_size = 1 * 1024 * 1024; mem.fixed_memory = platform_alloc(mem.fixed_memory_size + mem.transient_memory_size); if (mem.fixed_memory == 0) { debug(0, "did not alloc game memory\n"); return 1; } mem.transient_memory = mem.fixed_memory + mem.fixed_memory_size; init_game(&mem, HANDMAIDEN_AUDIO_DEFAULT_VOLUME, HANDMAIDEN_AUDIO_START_VOLUME); virtual_win = NULL; update_pixel_buffer(&mem, &virtual_win); if (!virtual_win) { debug(0, "did not assign virtual_win\n"); } sdl_init_joysticks(&event_ctx); title = (argc > 1) ? argv[1] : "Handmaiden Hero"; x = SDL_WINDOWPOS_UNDEFINED; y = SDL_WINDOWPOS_UNDEFINED; flags = SDL_WINDOW_RESIZABLE; window = SDL_CreateWindow(title, x, y, width, height, flags); if (!window) { debug(0, "Could not SDL_CreateWindow\n"); return 2; } renderer = SDL_CreateRenderer(window, FIRST_SUPPORTING, NONE); if (!renderer) { return 3; } sdl_resize_texture_buf(window, renderer, &texture_buf); if (init_audio_ring_buffer(&audio_ring_buf)) { sdl_audio_dev = sdl_init_audio(&audio_ring_buf); } else { sdl_audio_dev = 0; } if (sdl_audio_dev && audio_ring_buf.buf_len) { audio_buf.stream_pos = 0; audio_buf.num_samples = 0; audio_buf.samples = (int *)platform_alloc(audio_ring_buf.buf_len); if (!audio_buf.samples) { debug(0, "could not allocate audio_buf.samples[%u]\n", audio_ring_buf.buf_len); audio_buf.buf_len = 0; } else { audio_buf.buf_len = audio_ring_buf.buf_len; } } /* start audio playing by setting "pause" to zero */ if (sdl_audio_dev && audio_buf.samples) { SDL_PauseAudioDevice(sdl_audio_dev, 0); } event_ctx.event = &event; event_ctx.texture_buf = &texture_buf; event_ctx.renderer = renderer; event_ctx.window = window; event_ctx.win_id = SDL_GetWindowID(window); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); last_print.tv_sec = start.tv_sec; last_print.tv_nsec = start.tv_nsec; total_elapsed_seconds = 0; frames_since_print = 0; frame_count = 0; shutdown = 0; old_input = &input[0]; new_input = &input[1]; init_input(old_input); init_input(new_input); while (!shutdown) { tmp_input = new_input; new_input = old_input; old_input = tmp_input; init_input(new_input); while (SDL_PollEvent(&event)) { if ((shutdown = process_event(&event_ctx, new_input))) { break; } } process_joysticks(&event_ctx, old_input, new_input); if (shutdown || (shutdown = process_input(&mem, new_input))) { break; } update_pixel_buffer(&mem, &virtual_win); stretch_buffer(virtual_win, &blit_buf); sdl_blit_texture(renderer, &texture_buf); if (sdl_audio_dev && audio_buf.samples) { if ((audio_ring_buf.write_cursor - audio_ring_buf.play_cursor) < audio_ring_buf.buf_len) { SDL_LockAudio(); if (fill_ring_buf (&audio_ring_buf, &mem, &audio_buf) < 0) { shutdown = 1; } SDL_UnlockAudio(); } } frame_count++; frames_since_print++; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &now); diff_timespecs(last_print, now, &elapsed); if (((elapsed.tv_sec * 1000000000) + elapsed.tv_nsec) > 100000000) { fps = ((double)frames_since_print) / (((double)elapsed.tv_sec) * 1000000000.0 + ((double)elapsed.tv_nsec) / 1000000000.0); frames_since_print = 0; last_print.tv_sec = now.tv_sec; last_print.tv_nsec = now.tv_nsec; diff_timespecs(start, now, &elapsed); total_elapsed_seconds = elapsed.tv_sec + 1; if (FPS_PRINTER) { debug(0, "fps: %.02f (avg fps: %.f) %u, %u%s", fps, (double)frame_count / (double)total_elapsed_seconds, audio_ring_buf.play_cursor, audio_ring_buf.write_cursor, ERIC_DEBUG ? "\n" : "\r"); } } } debug(0, "\n"); if (sdl_audio_dev) { SDL_CloseAudioDevice(sdl_audio_dev); } close_audio_debug_logging(&audio_ring_buf); sdl_close_joysticks(&event_ctx); /* we probably do not need to do these next steps */ if (HANDMAIDEN_TRY_TO_MAKE_VALGRIND_HAPPY) { /* first cleanup SDL stuff */ if (texture_buf.texture) { SDL_DestroyTexture(texture_buf.texture); } SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); /* then collect our own garbage */ if (blit_buf.pixels) { platform_free(blit_buf.pixels, blit_buf.pixels_bytes_len); } if (audio_ring_buf.buf) { platform_free(audio_ring_buf.buf, audio_ring_buf.buf_len); } if (audio_buf.samples) { platform_free(audio_buf.samples, audio_buf.buf_len); } if (mem.fixed_memory) { platform_free(mem.fixed_memory, mem.fixed_memory_size + mem.transient_memory_size); } } return 0; }