Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
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;
}