Exemplo n.º 1
0
/* Check time elapsed after one frame, hold up
 * the program if not enough tim has elapsed */
void adjust_to_framerate() {
// EMSCRIPTEN had its own ways to run frames at certain FPS
#ifndef EMSCRIPTEN 

    char title_buf[100];

    current_ticks = get_timestamp_micro();
    uint64_t ticks_elapsed = current_ticks - last_ticks;
    uint64_t estimated_ticks = last_ticks + (uint64_t)(1000 * (1000/framerate));
    uint64_t framerate_ticks = ticks_elapsed * framerate;
    
    // If too fast we sleep for a certain amount of time
    // sleep might go over the time we want to wait
    // so attempt to come out of sleep early and use 
    // cpu cycles to wait for the rest of the time
    if (limiter && framerate_ticks < 1000000) {        
	    uint64_t delay_time = 1000000/framerate - ticks_elapsed;
	    if (delay_time >= 5000) {
		    //casting uint64_t into uint32_t, not really safe
		    // but we will never be delaying for more than 1000ms which is well in range
 		    SDL_Delay( (uint32_t) ((delay_time - 200)/1000));        
	    }	
        while(get_timestamp_micro() < estimated_ticks)
  		    ;;
        }   

    current_ticks = get_timestamp_micro();
    count = (count + 1) % 60;
    if (count == 0) {
	//printf("speed %u\n", current_ticks - last_ticks);
        float fps = 1000000.0 / (current_ticks - last_ticks);
        //printf("Gameboy fps:%.2f\n",fps);
        SDL_WM_SetCaption(title_buf,"");
        
        #ifdef THREE_DS
        int fps_i = (int)fps;
        if (fps_i > 35) {
            show_fps(fps);
            forgiveness_frame = 1;
        } else if (forgiveness_frame) { // Benefit of the doubt
            forgiveness_frame = 0;
        } else { // Beyond the forgiveness threshold, framerate is low
            show_fps(fps);
        }

        show_battery();
        show_fps_limiter();
        #endif
    }
    last_ticks = current_ticks;
#endif
}
Exemplo n.º 2
0
int run_emu(const char *path)
{
	SceCtrlData pad;
	unsigned int joypad1, joypad2;
	
	setup_audio();

	emu->set_sample_rate(44100);
	emu->set_equalizer(Nes_Emu::nes_eq);
	emu->set_palette_range(0);

	vita2d_texture *tex = vita2d_create_empty_texture(Nes_Emu::image_width, Nes_Emu::image_height);
	void *tex_data = vita2d_texture_get_datap(tex);

	static uint32_t video_buffer[Nes_Emu::image_width * Nes_Emu::image_height];
	emu->set_pixels(video_buffer, Nes_Emu::image_width);

	Auto_File_Reader freader(path);
	emu->load_ines(freader);

	int scale = 2;
	int pos_x = SCREEN_W/2 - (Nes_Emu::image_width/2)*scale;
	int pos_y = SCREEN_H/2 - (Nes_Emu::image_height/2)*scale;

	while (1) {
		sceCtrlPeekBufferPositive(0, &pad, 1);
		if ((pad.buttons & CHANGE_GAME_MASK) == CHANGE_GAME_MASK) break;

		joypad1 = joypad2 = update_input(&pad);

		emu->emulate_frame(joypad1, joypad2);
		const Nes_Emu::frame_t &frame = emu->frame();

		const uint8_t *in_pixels = frame.pixels;
		uint32_t *out_pixels = (uint32_t *)tex_data;

		for (unsigned h = 0; h < Nes_Emu::image_height;
			h++, in_pixels += frame.pitch, out_pixels += Nes_Emu::image_width) {
			for (unsigned w = 0; w < Nes_Emu::image_width; w++) {
				unsigned col = frame.palette[in_pixels[w]];
				const Nes_Emu::rgb_t& rgb = emu->nes_colors[col];
				unsigned r = rgb.red;
				unsigned g = rgb.green;
				unsigned b = rgb.blue;
				out_pixels[w] = 0xFF000000 | (r << 0) | (g << 8) | (b << 16);
			}
		}

		vita2d_start_drawing();
		vita2d_clear_screen();

		vita2d_draw_texture_scale(tex, pos_x, pos_y, scale, scale);
		show_fps();

		vita2d_end_drawing();
		vita2d_swap_buffers();
	}

	return 0;
}
Exemplo n.º 3
0
Arquivo: lsc.c Projeto: wcheswick/ex
void
do_idle(void) {
	int i;
	struct timeval now;

	if (refresh_screen) {
		draw_screen();
		refresh_screen = 0;
		gettimeofday(&last_busy, 0);
	}

	switch (state) {
	case AttractLoop:
		if (over_fps(2))
			return;
		grab_video_in();
		write_video_frame_zoom(video_r.min, video_in, VIDEO_ZOOM);
		break;
	case Live:
		if (over_fps(30))
			return;
		grab_video_in();
		memcpy(frames[0], video_in, sizeof(frames[0]));
		/* FALLTHROUGH */
	case Frozen:
		for (i=0; i<nhist; i++)
			transform(history[i], frames[i], frames[i+1]);
		write_video_frame_zoom(video_r.min, &frames[nhist], VIDEO_ZOOM);
		gettimeofday(&now, 0);
		if (idletime > 0 && elapsed_time(last_busy, now) > idletime) {
			nhist = 0;
			unfreeze();
			draw_screen();
			state = AttractLoop;
		}
		if (fps_flag)
			show_fps();
		break;
	}
}
Exemplo n.º 4
0
/***
 * Callback for when a new frame is generated that we need to render.
 */
bool retro_video_refresh_callback(const void *data, unsigned width, unsigned height, size_t pitch)
{
	curr_frame++;

    // initialize our main render texture once we get the dimensions for the first time
    if (!tex)
    {
        tex = vita2d_create_empty_texture_format(width, height, SCE_GXM_TEXTURE_FORMAT_R5G6B5);
        tex_data = vita2d_texture_get_datap(tex);

        // initialize PSPImage
        if (Screen)
            free(Screen);
        int size = width * height * 2;

        Screen = (PspImage*)malloc(sizeof(PspImage));

        Screen->TextureFormat = SCE_GXM_TEXTURE_FORMAT_R5G6B5;
        Screen->PalSize = (unsigned short)0;
        memset(tex_data, 0, size);

        Screen->Width = width;
        Screen->Height = height;
        Screen->Pixels = tex_data;
        Screen->Texture = tex;

        Screen->Viewport.X = 0;
        Screen->Viewport.Y = 0;
        Screen->Viewport.Width = width;
        Screen->Viewport.Height = height;

        int i;
        for (i = 1; i < width; i *= 2);
            Screen->PowerOfTwo = (i == width);
        Screen->BytesPerPixel = 2;
        Screen->FreeBuffer = 0;
        Screen->Depth = 16;
    }

    // initialize our render variables if they're uninitalized, or
    // if they've changed due to user action
	if(OptionsChanged)
	{
        OptionsChanged = false;

		// handle changes to scale from the options
        switch (Options.DisplayMode)
        {
        case DISPLAY_MODE_UNSCALED:
            scale_x = 1.0f;
            scale_y = 1.0f;
            break;
        case DISPLAY_MODE_2X:
            scale_x = 2.0f;
            scale_y = 2.0f;
            break;
        case DISPLAY_MODE_FIT_HEIGHT:
            scale_y = (float)SCREEN_H / (float)height;
            scale_x = scale_y;
            break;
        case DISPLAY_MODE_FILL_SCREEN:
            scale_x = (float)SCREEN_W / (float)width;
            scale_y = (float)SCREEN_H / (float)height;
            break;
        }

		curr_frame = 0;
        curr_fps = 0.0f;
		pos_x = (SCREEN_W / 2) - (width / 2) * scale_x;
		pos_y = (SCREEN_H / 2) - (height / 2) * scale_y;

        // handle texture filtering options
        tex_filter = Options.TextureFilter ? SCE_GXM_TEXTURE_FILTER_LINEAR : SCE_GXM_TEXTURE_FILTER_POINT;

        sceGxmTextureSetMinFilter(&(tex->gxm_tex), tex_filter);
        sceGxmTextureSetMagFilter(&(tex->gxm_tex), tex_filter);
	}

	// copy the input pixels into the output buffer
	const uint16_t* in_pixels = (const uint16_t*)data;
	uint16_t *out_pixels = (uint16_t *)tex_data;

	for (h = 0; h < height; h++, in_pixels += pitch / 2, out_pixels += width) 
	{
		memcpy(out_pixels, in_pixels, width * sizeof(uint16_t));
	}

    // draw the screen
	vita2d_start_drawing();

	vita2d_draw_texture_scale(tex, pos_x, pos_y, scale_x, scale_y);

    if(Options.ShowFps)
        show_fps();

	vita2d_end_drawing();
	vita2d_swap_buffers();

	return true;
}
Exemplo n.º 5
0
void update_screen(void)
{
	UINT8 skipped_it = skiptable[frameskip][frameskip_counter];

	if (!skipped_it)
	{
		if (option_showfps) show_fps();
		draw_volume_status(1);
		show_battery_warning();
		ui_show_popup(1);
	}
	else
	{
		draw_volume_status(0);
		ui_show_popup(0);
	}

	if (warming_up)
	{
		sceDisplayWaitVblankStart();
		last_skipcount0_time = ticker() - (int)((float)FRAMESKIP_LEVELS * PSP_TICKS_PER_FRAME);
		warming_up = 0;
	}

	if (frameskip_counter == 0)
		this_frame_base = last_skipcount0_time + (int)((float)FRAMESKIP_LEVELS * PSP_TICKS_PER_FRAME);

	frames_displayed++;
	frames_since_last_fps++;

	if (!skipped_it)
	{
		TICKER curr = ticker();
		int flip = 0;

		if (option_speedlimit)
		{
			TICKER target = this_frame_base + (int)((float)frameskip_counter * PSP_TICKS_PER_FRAME);

			if (option_vsync)
			{
				if (curr < target - 100)
				{
					video_flip_screen(1);
					flip = 1;
				}
			}

			while (curr < target)
				curr = ticker();
		}
		if (!flip) video_flip_screen(0);

		rendered_frames_since_last_fps++;

		if (frameskip_counter == 0)
		{
			float seconds_elapsed = (float)(curr - last_skipcount0_time) * (1.0 / 1000000.0);
			float frames_per_sec = (float)frames_since_last_fps / seconds_elapsed;

			game_speed_percent = (int)(100.0 * frames_per_sec / PSP_REFRESH_RATE + 0.5);
			frames_per_second = (int)((float)rendered_frames_since_last_fps / seconds_elapsed + 0.5);

			last_skipcount0_time = curr;
			frames_since_last_fps = 0;
			rendered_frames_since_last_fps = 0;

			if (option_autoframeskip)
			{
				if (option_speedlimit && frames_displayed > 2 * FRAMESKIP_LEVELS)
				{
					if (game_speed_percent >= 99)
					{
						frameskipadjust++;

						if (frameskipadjust >= 3)
						{
							frameskipadjust = 0;
							if (frameskip > 0) frameskip--;
						}
					}
					else
					{
						if (game_speed_percent < 80)
						{
							frameskipadjust -= (90 - game_speed_percent) / 5;
						}
						else if (frameskip < 8)
						{
							frameskipadjust--;
						}

						while (frameskipadjust <= -2)
						{
							frameskipadjust += 2;
							if (frameskip < FRAMESKIP_LEVELS - 1)
								frameskip++;
						}
					}
				}
			}
		}
	}

	frameskip_counter = (frameskip_counter + 1) % FRAMESKIP_LEVELS;
}