Beispiel #1
0
int video_screen_get_vpos(int scrnum)
{
	mame_time delta = sub_mame_times(mame_timer_get_time(), scrinfo[scrnum].vblank_time);
	int vpos;

	assert(delta.seconds == 0);
	vpos = delta.subseconds / scrinfo[scrnum].scantime;
	return (Machine->screen[scrnum].visarea.max_y + 1 + vpos) % Machine->screen[scrnum].height;
}
Beispiel #2
0
int video_screen_get_hpos(int scrnum)
{
	mame_time delta = sub_mame_times(mame_timer_get_time(), scrinfo[scrnum].vblank_time);
	int vpos, hpos;

	assert(delta.seconds == 0);
	vpos = delta.subseconds / scrinfo[scrnum].scantime;
	hpos = (delta.subseconds - (vpos * scrinfo[scrnum].scantime)) / scrinfo[scrnum].pixeltime;
	return hpos;
}
Beispiel #3
0
void video_vblank_start(void)
{
	mame_time curtime = mame_timer_get_time();
	int scrnum;

	/* kludge: we get called at time 0 to reset, but at that point,
       the time of last VBLANK is actually -vblank_duration */
	if (curtime.seconds == 0 && curtime.subseconds == 0)
		curtime = sub_mame_times(time_zero, double_to_mame_time(Machine->screen[0].vblank));

	/* reset VBLANK timers for each screen -- fix me */
	for (scrnum = 0; scrnum < MAX_SCREENS; scrnum++)
		scrinfo[scrnum].vblank_time = curtime;
}
Beispiel #4
0
mame_time video_screen_get_time_until_pos(int scrnum, int vpos, int hpos)
{
	mame_time curdelta = sub_mame_times(mame_timer_get_time(), scrinfo[scrnum].vblank_time);
	subseconds_t targetdelta;

	assert(curdelta.seconds == 0);

	/* since we measure time relative to VBLANK, compute the scanline offset from VBLANK */
	vpos += Machine->screen[scrnum].height - (Machine->screen[scrnum].visarea.max_y + 1);
	vpos %= Machine->screen[scrnum].height;

	/* compute the delta for the given X,Y position */
	targetdelta = (subseconds_t)vpos * scrinfo[scrnum].scantime + (subseconds_t)hpos * scrinfo[scrnum].pixeltime;

	/* if we're past that time, head to the next frame */
	if (targetdelta <= curdelta.subseconds)
		targetdelta += DOUBLE_TO_SUBSECONDS(TIME_IN_HZ(Machine->screen[scrnum].refresh));

	/* return the difference */
	return make_mame_time(0, targetdelta - curdelta.subseconds);
}
Beispiel #5
0
int video_init(running_machine *machine)
{
	int scrnum;

	add_exit_callback(machine, video_exit);

	/* reset globals */
	memset(scrinfo, 0, sizeof(scrinfo));

	/* configure all of the screens */
	for (scrnum = 0; scrnum < MAX_SCREENS; scrnum++)
		if (machine->drv->screen[scrnum].tag != NULL)
		{
			internal_screen_info *info = &scrinfo[scrnum];
			screen_state *state = &machine->screen[scrnum];

			/* configure the screen with the default parameters */
			video_screen_configure(scrnum, state->width, state->height, &state->visarea, state->refresh);

			/* reset VBLANK timing */
			info->vblank_time = sub_mame_times(time_zero, double_to_mame_time(Machine->screen[0].vblank));

			/* register for save states */
			state_save_register_item("video", scrnum, info->vblank_time.seconds);
			state_save_register_item("video", scrnum, info->vblank_time.subseconds);
		}

	/* create spriteram buffers if necessary */
	if (machine->drv->video_attributes & VIDEO_BUFFERS_SPRITERAM)
		init_buffered_spriteram();

	/* convert the gfx ROMs into character sets. This is done BEFORE calling the driver's */
	/* palette_init() routine because it might need to check the machine->gfx[] data */
	if (machine->drv->gfxdecodeinfo != NULL)
		allocate_graphics(machine->drv->gfxdecodeinfo);

	/* configure the palette */
	palette_config(machine);

	/* actually decode the graphics */
	if (machine->drv->gfxdecodeinfo != NULL)
		decode_graphics(machine->drv->gfxdecodeinfo);

	/* reset performance data */
	last_fps_time = osd_ticks();
	rendered_frames_since_last_fps = frames_since_last_fps = 0;
	performance.game_speed_percent = 100;
	performance.frames_per_second = machine->screen[0].refresh;
	performance.vector_updates_last_second = 0;

	/* reset video statics and get out of here */
	pdrawgfx_shadow_lowpri = 0;
	leds_status = 0;

	/* initialize tilemaps */
	if (tilemap_init(machine) != 0)
		fatalerror("tilemap_init failed");

	/* create a render target for snapshots */
	if (Machine->drv->screen[0].tag != NULL)
	{
		snap_bitmap = NULL;
		snap_target = render_target_alloc(layout_snap, RENDER_CREATE_SINGLE_FILE | RENDER_CREATE_HIDDEN);
		assert(snap_target != NULL);
		if (snap_target == NULL)
			return 1;
		render_target_set_layer_config(snap_target, 0);
	}

	/* create crosshairs */
	crosshair_init();

	return 0;
}
Beispiel #6
0
static void handle_load(running_machine *machine)
{
	mame_private *mame = machine->mame_data;
	mame_file_error filerr;
	mame_file *file;

	/* if no name, bail */
	if (mame->saveload_pending_file == NULL)
	{
		mame->saveload_schedule_callback = NULL;
		return;
	}

	/* if there are anonymous timers, we can't load just yet because the timers might */
	/* overwrite data we have loaded */
	if (timer_count_anonymous() > 0)
	{
		/* if more than a second has passed, we're probably screwed */
		if (sub_mame_times(mame_timer_get_time(), mame->saveload_schedule_time).seconds > 0)
		{
			popmessage("Unable to load due to pending anonymous timers. See error.log for details.");
			goto cancel;
		}
		return;
	}

	/* open the file */
	filerr = mame_fopen(SEARCHPATH_STATE, mame->saveload_pending_file, OPEN_FLAG_READ, &file);
	if (filerr == FILERR_NONE)
	{
		/* start loading */
		if (state_save_load_begin(file) == 0)
		{
			int cpunum;

			/* read tag 0 */
			state_save_push_tag(0);
			state_save_load_continue();
			state_save_pop_tag();

			/* loop over CPUs */
			for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
			{
				cpuintrf_push_context(cpunum);

				/* make sure banking is set */
				activecpu_reset_banking();

				/* load the CPU data */
				state_save_push_tag(cpunum + 1);
				state_save_load_continue();
				state_save_pop_tag();

				/* make sure banking is set */
				activecpu_reset_banking();

				cpuintrf_pop_context();
			}

			/* finish and close */
			state_save_load_finish();
			popmessage("State successfully loaded.");
		}
		else
			popmessage("Error: Failed to load state");
		mame_fclose(file);
	}
	else
		popmessage("Error: Failed to load state");

cancel:
	/* unschedule the load */
	free(mame->saveload_pending_file);
	mame->saveload_pending_file = NULL;
	mame->saveload_schedule_callback = NULL;
}
Beispiel #7
0
static void handle_save(running_machine *machine)
{
	mame_private *mame = machine->mame_data;
	mame_file_error filerr;
	mame_file *file;

	/* if no name, bail */
	if (mame->saveload_pending_file == NULL)
	{
		mame->saveload_schedule_callback = NULL;
		return;
	}

	/* if there are anonymous timers, we can't save just yet */
	if (timer_count_anonymous() > 0)
	{
		/* if more than a second has passed, we're probably screwed */
		if (sub_mame_times(mame_timer_get_time(), mame->saveload_schedule_time).seconds > 0)
		{
			popmessage("Unable to save due to pending anonymous timers. See error.log for details.");
			goto cancel;
		}
		return;
	}

	/* open the file */
	filerr = mame_fopen(SEARCHPATH_STATE, mame->saveload_pending_file, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &file);
	if (filerr == FILERR_NONE)
	{
		int cpunum;

		/* write the save state */
		if (state_save_save_begin(file) != 0)
		{
			popmessage("Error: Unable to save state due to illegal registrations. See error.log for details.");
			mame_fclose(file);
			goto cancel;
		}

		/* write the default tag */
		state_save_push_tag(0);
		state_save_save_continue();
		state_save_pop_tag();

		/* loop over CPUs */
		for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
		{
			cpuintrf_push_context(cpunum);

			/* make sure banking is set */
			activecpu_reset_banking();

			/* save the CPU data */
			state_save_push_tag(cpunum + 1);
			state_save_save_continue();
			state_save_pop_tag();

			cpuintrf_pop_context();
		}

		/* finish and close */
		state_save_save_finish();
		mame_fclose(file);

		/* pop a warning if the game doesn't support saves */
		if (!(machine->gamedrv->flags & GAME_SUPPORTS_SAVE))
			popmessage("State successfully saved.\nWarning: Save states are not officially supported for this game.");
		else
			popmessage("State successfully saved.");
	}
	else
		popmessage("Error: Failed to save state");

cancel:
	/* unschedule the save */
	free(mame->saveload_pending_file);
	mame->saveload_pending_file = NULL;
	mame->saveload_schedule_callback = NULL;
}
Beispiel #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;
}
Beispiel #9
0
mame_time mame_timer_timeleft(mame_timer *which)
{
	return sub_mame_times(which->expire, get_current_time());
}
Beispiel #10
0
mame_time mame_timer_timeelapsed(mame_timer *which)
{
	return sub_mame_times(get_current_time(), which->start);
}