static long ioctl_add_module(char *file) { char *buf; int64_t ret; if (g_num_files >= MAX_NUM_MODULES) { ALERT("IOCTL_ADD_MODULE: too many modules have been loaded\n"); return BF_IOCTL_FAILURE; } buf = (char *)platform_alloc(g_module_length); if (buf == NULL) { ALERT("IOCTL_ADD_MODULE: failed to allocate memory for the module\n"); return BF_IOCTL_FAILURE; } ALERT("address to copy from %p size: 0x%" PRId64 "\n", file, g_module_length); ret = copyin((user_addr_t)file, (void *)buf, g_module_length); if (ret != 0) { ALERT("IOCTL_ADD_MODULE: failed to copy memory from userspace\n"); goto failed; } ret = common_add_module(buf, g_module_length); if (ret != BF_SUCCESS) { ALERT("IOCTL_ADD_MODULE: failed to add module\n"); goto failed; } files[g_num_files] = buf; files_sizes[g_num_files] = g_module_length; g_num_files++; DEBUG("IOCTL_ADD_MODULE: succeeded\n"); return BF_IOCTL_SUCCESS; failed: platform_free(buf, g_module_length); DEBUG("IOCTL_ADD_MODULE: failed\n"); return BF_IOCTL_FAILURE; }
internal void *resize_pixel_buffer(struct pixel_buffer *buf, int height, int width) { debug(1, "Buffer was %d x %d, need %d x %d\n", buf->width, buf->height, width, height); if (buf->pixels) { platform_free(buf->pixels, buf->pixels_bytes_len); } buf->width = width; buf->height = height; buf->pixels_bytes_len = buf->height * buf->width * buf->bytes_per_pixel; buf->pitch = buf->width * buf->bytes_per_pixel; buf->pixels = platform_alloc(buf->pixels_bytes_len); if (!buf->pixels) { debug(0, "Could not alloc buf->pixels (%d)\n", buf->pixels_bytes_len); } return buf->pixels; }
internal unsigned int init_audio_ring_buffer(struct audio_ring_buffer *audio_ring_buf) { int samples_per_buffer; double seconds_per_buffer; audio_ring_buf->write_cursor = 0; audio_ring_buf->play_cursor = 0; audio_ring_buf->buf_len = HANDMAIDEN_AUDIO_BUF_SIZE; samples_per_buffer = HANDMAIDEN_AUDIO_BUF_SIZE / (HANDMAIDEN_AUDIO_BYTES_PER_SAMPLE * HANDMAIDEN_AUDIO_CHANNELS); seconds_per_buffer = (1.0 * (double)samples_per_buffer) / (1.0 * (double)HANDMAIDEN_AUDIO_SAMPLES_PER_SECOND); debug(1, "sound buffer = %d bytes (%d samples) (%f seconds)\n", HANDMAIDEN_AUDIO_BUF_SIZE, samples_per_buffer, seconds_per_buffer); audio_ring_buf->buf = platform_alloc(audio_ring_buf->buf_len); if (!audio_ring_buf->buf) { debug(0, "could not allocate sound buffer\n"); } if (DEBUG_LOG_AUDIO) { audio_ring_buf->log = fopen(debug_audio_bin_log_path(), "w"); if (!audio_ring_buf->log) { debug(0, "could not fopen %s\n", debug_audio_bin_log_path()); } } else { audio_ring_buf->log = NULL; } return audio_ring_buf->buf ? 1 : 0; }
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; }