예제 #1
0
void updatescreen(void)
{
	/* update sound */
	sound_frame_update();

	/* if we're not skipping this frame, draw the screen */
	if (!osd_skip_this_frame())
	{
		profiler_mark(PROFILER_VIDEO);
		draw_screen();
		profiler_mark(PROFILER_END);
	}

	/* the user interface must be called between vh_update() and osd_update_video_and_audio(), */
	/* to allow it to overlay things on the game display. We must call it even */
	/* if the frame is skipped, to keep a consistent timing. */
	ui_update_and_render(artwork_get_ui_bitmap());

	/* update our movie recording state */
	if (!mame_is_paused())
		record_movie_frame(scrbitmap[0]);

	/* blit to the screen */
	update_video_and_audio();

	/* call the end-of-frame callback */
	if (Machine->drv->video_eof && !mame_is_paused())
	{
		profiler_mark(PROFILER_VIDEO);
		(*Machine->drv->video_eof)();
		profiler_mark(PROFILER_END);
	}
}
예제 #2
0
const char *osd_get_fps_text(const performance_info *performance)
{
	static char buffer[1024];
	char *dest = buffer;

	// if we're paused, display less info
	if (mame_is_paused(Machine))
		dest += sprintf(dest, "Paused");
	else
	{
		dest += sprintf(dest, "%s%2d%4d%%%4d/%d fps",
				effective_autoframeskip() ? "auto" : "fskp", effective_frameskip(),
				(int)(performance->game_speed_percent + 0.5),
				(int)(performance->frames_per_second + 0.5),
				(int)(Machine->screen[0].refresh + 0.5));

		/* for vector games, add the number of vector updates */
		if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR)
			dest += sprintf(dest, "\n %d vector updates", performance->vector_updates_last_second);
		else if (performance->partial_updates_this_frame > 1)
			dest += sprintf(dest, "\n %d partial updates", performance->partial_updates_this_frame);
	}

	/* return a pointer to the static buffer */
	return buffer;
}
예제 #3
0
static void update_autoframeskip(void)
{
	// skip if paused
	if (mame_is_paused(Machine))
		return;

	// don't adjust frameskip if we're paused or if the debugger was
	// visible this cycle or if we haven't run yet
	if (cpu_getcurrentframe() > 2 * FRAMESKIP_LEVELS)
	{
		const performance_info *performance = mame_get_performance_info();

		// if we're too fast, attempt to increase the frameskip
		if (performance->game_speed_percent >= 99.5)
		{
			frameskipadjust++;

			// but only after 3 consecutive frames where we are too fast
			if (frameskipadjust >= 3)
			{
				frameskipadjust = 0;
				if (video_config.frameskip > 0) video_config.frameskip--;
			}
		}

		// if we're too slow, attempt to increase the frameskip
		else
		{
			// if below 80% speed, be more aggressive
			if (performance->game_speed_percent < 80)
				frameskipadjust -= (90 - performance->game_speed_percent) / 5;

			// if we're close, only force it up to frameskip 8
			else if (video_config.frameskip < 8)
				frameskipadjust--;

			// perform the adjustment
			while (frameskipadjust <= -2)
			{
				frameskipadjust += 2;
				if (video_config.frameskip < FRAMESKIP_LEVELS - 1)
					video_config.frameskip++;
			}
		}
	}
}
예제 #4
0
파일: window.c 프로젝트: broftkd/mess-cvs
void winwindow_ui_pause_from_main_thread(int pause)
{
	int old_temp_pause = ui_temp_pause;

	assert(GetCurrentThreadId() == main_threadid);

	// if we're pausing, increment the pause counter
	if (pause)
	{
		// if we're the first to pause, we have to actually initiate it
		if (ui_temp_pause++ == 0)
		{
			// only call mame_pause if we weren't already paused due to some external reason
			ui_temp_was_paused = mame_is_paused(Machine);
			if (!ui_temp_was_paused)
			{
				mame_pause(Machine, TRUE);
				SetEvent(ui_pause_event);
			}
		}
	}

	// if we're resuming, decrement the pause counter
	else
	{
		// if we're the last to resume, unpause MAME
		if (--ui_temp_pause == 0)
		{
			// but only do it if we were the ones who initiated it
			if (!ui_temp_was_paused)
			{
				mame_pause(Machine, FALSE);
				ResetEvent(ui_pause_event);
			}
		}
	}

	if (LOG_TEMP_PAUSE)
		logerror("winwindow_ui_pause_from_main_thread(): %d --> %d\n", old_temp_pause, ui_temp_pause);
}
예제 #5
0
UINT32 ui_gfx_ui_handler(running_machine *machine, UINT32 uistate)
{
	ui_gfx_state *state = &ui_gfx;

	/* if we have nothing, implicitly cancel */
	if (machine->config->total_colors == 0 && machine->colortable == NULL && machine->gfx[0] == NULL && tilemap_count(machine) == 0)
		goto cancel;

	/* if we're not paused, mark the bitmap dirty */
	if (!mame_is_paused(machine))
		state->bitmap_dirty = TRUE;

	/* switch off the state to display something */
again:
	switch (state->mode)
	{
		case 0:
			/* if we have a palette, display it */
			if (machine->config->total_colors > 0)
			{
				palette_handler(machine, state);
				break;
			}

			/* fall through...*/
			state->mode++;

		case 1:
			/* if we have graphics sets, display them */
			if (machine->gfx[0] != NULL)
			{
				gfxset_handler(machine, state);
				break;
			}

			/* fall through...*/
			state->mode++;

		case 2:
			/* if we have tilemaps, display them */
			if (tilemap_count(machine) > 0)
			{
				tilemap_handler(machine, state);
				break;
			}

			state->mode = 0;
			goto again;
	}

	/* handle keys */
	if (ui_input_pressed(machine, IPT_UI_SELECT))
	{
		state->mode = (state->mode + 1) % 3;
		state->bitmap_dirty = TRUE;
	}

	if (ui_input_pressed(machine, IPT_UI_PAUSE))
		mame_pause(machine, !mame_is_paused(machine));

	if (ui_input_pressed(machine, IPT_UI_CANCEL) || ui_input_pressed(machine, IPT_UI_SHOW_GFX))
		goto cancel;

	return uistate;

cancel:
	if (!uistate)
		mame_pause(machine, FALSE);
	state->bitmap_dirty = TRUE;
	return UI_HANDLER_CANCEL;
}
예제 #6
0
파일: window.c 프로젝트: broftkd/mess-cvs
int winwindow_ui_is_paused(void)
{
	return mame_is_paused(Machine) && ui_temp_was_paused;
}
예제 #7
0
void video_frame_update(void)
{
	int skipped_it = video_skip_this_frame();
	int paused = mame_is_paused(Machine);
	int phase = mame_get_phase(Machine);
	int livemask;
	int scrnum;

	/* only render sound and video if we're in the running phase */
	if (phase == MAME_PHASE_RUNNING)
	{
		/* update sound */
		sound_frame_update();

		/* finish updating the screens */
		for (scrnum = 0; scrnum < MAX_SCREENS; scrnum++)
			if (Machine->drv->screen[scrnum].tag != NULL)
				video_screen_update_partial(scrnum, Machine->screen[scrnum].visarea.max_y);

		/* now add the quads for all the screens */
		livemask = render_get_live_screens_mask();
		for (scrnum = 0; scrnum < MAX_SCREENS; scrnum++) {
			if (livemask & (1 << scrnum))
			{
				internal_screen_info *screen = &scrinfo[scrnum];

				/* only update if empty and not a vector game; otherwise assume the driver did it directly */
				if (render_container_is_empty(render_container_get_screen(scrnum)) && !(Machine->drv->video_attributes & VIDEO_TYPE_VECTOR))
				{
					mame_bitmap *bitmap = screen->bitmap[screen->curbitmap];
					if (!skipping_this_frame && screen->changed)
					{
						rectangle fixedvis = Machine->screen[scrnum].visarea;
						fixedvis.max_x++;
						fixedvis.max_y++;
						render_texture_set_bitmap(screen->texture, bitmap, &fixedvis, Machine->drv->screen[scrnum].palette_base, screen->format);
						screen->curbitmap = 1 - screen->curbitmap;
					}
					render_screen_add_quad(scrnum, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), screen->texture, PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1));
				}
			}
        }

		/* update our movie recording state */
		if (!paused)
			movie_record_frame(0);

		/* reset the screen changed flags */
		for (scrnum = 0; scrnum < MAX_SCREENS; scrnum++)
			scrinfo[scrnum].changed = 0;
	}

	/* draw any crosshairs */
	crosshair_render();

	/* draw the user interface */
	ui_update_and_render();

	/* call the OSD to update */
	skipping_this_frame = osd_update(mame_timer_get_time());

	/* empty the containers */
	for (scrnum = 0; scrnum < MAX_SCREENS; scrnum++)
		if (Machine->drv->screen[scrnum].tag != NULL)
			render_container_empty(render_container_get_screen(scrnum));

	/* update FPS */
	recompute_fps(skipped_it);

	/* call the end-of-frame callback */
	if (phase == MAME_PHASE_RUNNING)
	{
		/* reset partial updates if we're paused or if the debugger is active */
		if (paused || mame_debug_is_active())
			video_reset_partial_updates();

		/* otherwise, call the video EOF callback */
		else if (Machine->drv->video_eof != NULL)
		{
			profiler_mark(PROFILER_VIDEO);
			(*Machine->drv->video_eof)(Machine);
			profiler_mark(PROFILER_END);
		}
	}
}
예제 #8
0
static void update_throttle(mame_time emutime)
{
	static double ticks_per_sleep_msec = 0;
	osd_ticks_t target, curr, cps, diffticks;
	int allowed_to_sleep;
	subseconds_t subsecs_per_cycle;
	int paused = mame_is_paused(Machine);

	// if we're only syncing to the refresh, bail now
	if (video_config.syncrefresh)
		return;

	// if we're paused, emutime will not advance; explicitly resync and set us backwards
	// 1/60th of a second
	if (paused)
		throttle_realtime = throttle_emutime = sub_subseconds_from_mame_time(emutime, MAX_SUBSECONDS / PAUSED_REFRESH_RATE);

	// if time moved backwards (reset), or if it's been more than 1 second in emulated time, resync
	if (compare_mame_times(emutime, throttle_emutime) < 0 || sub_mame_times(emutime, throttle_emutime).seconds > 0)
		goto resync;

	// get the current realtime; if it's been more than 1 second realtime, just resync
	cps = osd_ticks_per_second();
	diffticks = osd_ticks() - throttle_last_ticks;
	throttle_last_ticks += diffticks;
	if (diffticks >= cps)
		goto resync;

	// add the time that has passed to the real time
	subsecs_per_cycle = MAX_SUBSECONDS / cps;
	throttle_realtime = add_subseconds_to_mame_time(throttle_realtime, diffticks * subsecs_per_cycle);

	// update the emulated time
	throttle_emutime = emutime;

	// if we're behind, just sync
	if (compare_mame_times(throttle_emutime, throttle_realtime) <= 0)
		goto resync;

	// determine our target ticks value
	target = throttle_last_ticks + sub_mame_times(throttle_emutime, throttle_realtime).subseconds / subsecs_per_cycle;

	// initialize the ticks per sleep
	if (ticks_per_sleep_msec == 0)
		ticks_per_sleep_msec = (double)(cps / 1000);

	// this counts as idle time
	profiler_mark(PROFILER_IDLE);

	// determine whether or not we are allowed to sleep
	allowed_to_sleep = video_config.sleep && (!effective_autoframeskip() || effective_frameskip() == 0);

	// sync
	for (curr = osd_ticks(); curr - target < 0; curr = osd_ticks())
	{
		// if we have enough time to sleep, do it
		// ...but not if we're autoframeskipping and we're behind
		if (paused || (allowed_to_sleep && (target - curr) > (osd_ticks_t)(ticks_per_sleep_msec * 1.1)))
		{
			osd_ticks_t next;

			// keep track of how long we actually slept
			Sleep(1);
			next = osd_ticks();
			ticks_per_sleep_msec = (ticks_per_sleep_msec * 0.90) + ((double)(next - curr) * 0.10);
		}
	}

	// idle time done
	profiler_mark(PROFILER_END);

	// update realtime
	diffticks = osd_ticks() - throttle_last_ticks;
	throttle_last_ticks += diffticks;
	throttle_realtime = add_subseconds_to_mame_time(throttle_realtime, diffticks * subsecs_per_cycle);
	return;

resync:
	// reset realtime and emutime to the same value
	throttle_realtime = throttle_emutime = emutime;
}
예제 #9
0
INLINE int effective_throttle(void)
{
	return !video_config.fastforward && (video_config.throttle || mame_is_paused(Machine) || ui_is_menu_active() || ui_is_slider_active());
}
예제 #10
0
void sound_frame_update(void)
{
	int sample, spknum;

	VPRINTF(("sound_frame_update\n"));

	profiler_mark(PROFILER_SOUND);

	/* reset the mixing streams */
	memset(leftmix, 0, samples_this_frame * sizeof(*leftmix));
	memset(rightmix, 0, samples_this_frame * sizeof(*rightmix));

	/* if we're not paused, keep the sounds going */
	if (!mame_is_paused(Machine))
	{
		/* force all the speaker streams to generate the proper number of samples */
		for (spknum = 0; spknum < totalspeakers; spknum++)
		{
			speaker_info *spk = &speaker[spknum];
			stream_sample_t *stream_buf;

			/* get the output buffer */
			if (spk->mixer_stream)
			{
				stream_buf = stream_consume_output(spk->mixer_stream, 0, samples_this_frame);

#ifdef MAME_DEBUG
				/* debug version: keep track of the maximum sample */
				for (sample = 0; sample < samples_this_frame; sample++)
				{
					if (stream_buf[sample] > spk->max_sample)
						spk->max_sample = stream_buf[sample];
					else if (-stream_buf[sample] > spk->max_sample)
						spk->max_sample = -stream_buf[sample];
					if (stream_buf[sample] > 32767 || stream_buf[sample] < -32768)
						spk->clipped_samples++;
					spk->total_samples++;
				}
#endif

				/* mix if sound is enabled */
				if (global_sound_enabled && !nosound_mode)
				{
					/* if the speaker is centered, send to both left and right */
					if (spk->speaker->x == 0)
						for (sample = 0; sample < samples_this_frame; sample++)
						{
							leftmix[sample] += stream_buf[sample];
							rightmix[sample] += stream_buf[sample];
						}

					/* if the speaker is to the left, send only to the left */
					else if (spk->speaker->x < 0)
						for (sample = 0; sample < samples_this_frame; sample++)
							leftmix[sample] += stream_buf[sample];

					/* if the speaker is to the right, send only to the right */
					else
						for (sample = 0; sample < samples_this_frame; sample++)
							rightmix[sample] += stream_buf[sample];
				}
			}
		}
	}

	/* now downmix the final result */
	for (sample = 0; sample < samples_this_frame; sample++)
	{
		INT32 samp;

		/* clamp the left side */
		samp = leftmix[sample];
		if (samp < -32768)
			samp = -32768;
		else if (samp > 32767)
			samp = 32767;
		finalmix[sample*2+0] = samp;

		/* clamp the right side */
		samp = rightmix[sample];
		if (samp < -32768)
			samp = -32768;
		else if (samp > 32767)
			samp = 32767;
		finalmix[sample*2+1] = samp;
	}

	if (wavfile && !mame_is_paused(Machine))
		wav_add_data_16(wavfile, finalmix, samples_this_frame * 2);

	/* play the result */
	samples_this_frame = osd_update_audio_stream(finalmix);

	/* update the streamer */
	streams_frame_update();

	/* reset the timer to resync for this frame */
	mame_timer_adjust(sound_update_timer, time_never, 0, time_never);

	profiler_mark(PROFILER_END);
}