Exemplo n.º 1
0
static void pastelg_gfxdraw(running_machine &machine)
{
	pastelg_state *state = machine.driver_data<pastelg_state>();
	UINT8 *GFX = machine.region("gfx1")->base();
	int width = machine.primary_screen->width();

	int x, y;
	int dx, dy;
	int startx, starty;
	int sizex, sizey;
	int incx, incy;
	int ctrx, ctry;
	int readflag;
	int gfxaddr, gfxlen;
	int count;
	UINT8 color;

	nb1413m3_busyctr = 0;

	startx = state->m_blitter_destx + state->m_blitter_sizex;
	starty = state->m_blitter_desty + state->m_blitter_sizey;


	if (state->m_blitter_direction_x)
	{
		if (state->m_blitter_sizex&0x80) sizex = 0xff-state->m_blitter_sizex;
		else sizex=state->m_blitter_sizex;
		incx = 1;
	}
	else
	{
		sizex = state->m_blitter_sizex;
		incx = -1;
	}

	if (state->m_blitter_direction_y)
	{
		if (state->m_blitter_sizey&0x80) sizey = 0xff-state->m_blitter_sizey;
		else sizey=state->m_blitter_sizey;
		incy = 1;
	}
	else
	{
		sizey = state->m_blitter_sizey;
		incy = -1;
	}

	gfxlen = machine.region("gfx1")->bytes();
	gfxaddr = (state->m_gfxrom << 16) + state->m_blitter_src_addr;

	readflag = 0;

	count = 0;
	y = starty;

	for (ctry = sizey; ctry >= 0; ctry--)
	{
		x = startx;

		for (ctrx = sizex; ctrx >= 0; ctrx--)
		{
			gfxaddr = (state->m_gfxrom << 16) + ((state->m_blitter_src_addr + count));

			if ((gfxaddr > (gfxlen - 1)))
			{
#ifdef MAME_DEBUG
				popmessage("GFXROM ADDRESS OVER!!");
#endif
				gfxaddr = 0;
			}

			color = GFX[gfxaddr];

			dx = x & 0xff;
			dy = y & 0xff;

			if (state->m_flipscreen)
			{
				dx ^= 0xff;
				dy ^= 0xff;
			}

			if (!readflag)
			{
				// 1st, 3rd, 5th, ... read
				color = (color & 0x0f);
			}
			else
			{
				// 2nd, 4th, 6th, ... read
				color = (color & 0xf0) >> 4;
				count++;
			}

			readflag ^= 1;

			if (state->m_clut[color] & 0xf0)
			{
				if (color)
				{
					color = ((state->m_palbank * 0x10) + color);
					state->m_videoram[(dy * width) + dx] = color;
				}
			}
			else
			{
				if(state->m_clut[color] != 0)
				{
					color = ((state->m_palbank * 0x10) + state->m_clut[color]);
					state->m_videoram[(dy * width) + dx] = color;
				}
			}

			nb1413m3_busyctr++;
			x += incx;
		}

		y += incy;
	}

	nb1413m3_busyflag = 0;
	machine.scheduler().timer_set(attotime::from_hz(400000) * nb1413m3_busyctr, FUNC(blitter_timer_callback));
}
Exemplo n.º 2
0
Arquivo: smpc.c Projeto: j4y4r/j4ymame
static void stv_select_game(running_machine &machine, int gameno)
{
	machine.scheduler().timer_set(attotime::zero, FUNC(stv_bankswitch_state), gameno);
}
Exemplo n.º 3
0
video_manager::video_manager(running_machine &machine)
	: m_machine(machine),
		m_screenless_frame_timer(nullptr),
		m_output_changed(false),
		m_throttle_last_ticks(0),
		m_throttle_realtime(attotime::zero),
		m_throttle_emutime(attotime::zero),
		m_throttle_history(0),
		m_speed_last_realtime(0),
		m_speed_last_emutime(attotime::zero),
		m_speed_percent(1.0),
		m_overall_real_seconds(0),
		m_overall_real_ticks(0),
		m_overall_emutime(attotime::zero),
		m_overall_valid_counter(0),
		m_throttled(machine.options().throttle()),
		m_throttle_rate(1.0f),
		m_fastforward(false),
		m_seconds_to_run(machine.options().seconds_to_run()),
		m_auto_frameskip(machine.options().auto_frameskip()),
		m_speed(original_speed_setting()),
		m_empty_skip_count(0),
		m_frameskip_level(machine.options().frameskip()),
		m_frameskip_counter(0),
		m_frameskip_adjust(0),
		m_skipping_this_frame(false),
		m_average_oversleep(0),
		m_snap_target(nullptr),
		m_snap_native(true),
		m_snap_width(0),
		m_snap_height(0),
		m_mng_frame_period(attotime::zero),
		m_mng_next_frame_time(attotime::zero),
		m_mng_frame(0),
		m_avi_file(nullptr),
		m_avi_frame_period(attotime::zero),
		m_avi_next_frame_time(attotime::zero),
		m_avi_frame(0),
		m_dummy_recording(false),
		m_timecode_enabled(false),
		m_timecode_write(false),
		m_timecode_text(""),
		m_timecode_start(attotime::zero),
		m_timecode_total(attotime::zero)

{
	// request a callback upon exiting
	machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(video_manager::exit), this));
	machine.save().register_postload(save_prepost_delegate(FUNC(video_manager::postload), this));

	// extract initial execution state from global configuration settings
	update_refresh_speed();

	// create a render target for snapshots
	const char *viewname = machine.options().snap_view();
	m_snap_native = (machine.first_screen() != nullptr && (viewname[0] == 0 || strcmp(viewname, "native") == 0));

	// the native target is hard-coded to our internal layout and has all options disabled
	if (m_snap_native)
	{
		m_snap_target = machine.render().target_alloc(layout_snap, RENDER_CREATE_SINGLE_FILE | RENDER_CREATE_HIDDEN);
		m_snap_target->set_backdrops_enabled(false);
		m_snap_target->set_overlays_enabled(false);
		m_snap_target->set_bezels_enabled(false);
		m_snap_target->set_cpanels_enabled(false);
		m_snap_target->set_marquees_enabled(false);
		m_snap_target->set_screen_overlay_enabled(false);
		m_snap_target->set_zoom_to_screen(false);
	}

	// other targets select the specified view and turn off effects
	else
	{
		m_snap_target = machine.render().target_alloc(nullptr, RENDER_CREATE_HIDDEN);
		m_snap_target->set_view(m_snap_target->configured_view(viewname, 0, 1));
		m_snap_target->set_screen_overlay_enabled(false);
	}

	// extract snap resolution if present
	if (sscanf(machine.options().snap_size(), "%dx%d", &m_snap_width, &m_snap_height) != 2)
		m_snap_width = m_snap_height = 0;

	// start recording movie if specified
	const char *filename = machine.options().mng_write();
	if (filename[0] != 0)
		begin_recording(filename, MF_MNG);

	filename = machine.options().avi_write();
	if (filename[0] != 0)
		begin_recording(filename, MF_AVI);

#ifdef MAME_DEBUG
	m_dummy_recording = machine.options().dummy_write();
#endif

	// if no screens, create a periodic timer to drive updates
	if (machine.first_screen() == nullptr)
	{
		m_screenless_frame_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(video_manager::screenless_update_callback), this));
		m_screenless_frame_timer->adjust(screen_device::DEFAULT_FRAME_PERIOD, 0, screen_device::DEFAULT_FRAME_PERIOD);
		machine.output().set_notifier(nullptr, video_notifier_callback, this);
	}
}
Exemplo n.º 4
0
void hector_disc2_init( running_machine &machine)
{
	hec2hrp_state *state = machine.driver_data<hec2hrp_state>();
	state->m_DMA_timer = machine.scheduler().timer_alloc(FUNC(Callback_DMA_irq));
	state->m_INT_timer = machine.scheduler().timer_alloc(FUNC(Callback_INT_irq));
}
Exemplo n.º 5
0
static void draw_sprites(running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	triplhnt_state *state = machine.driver_data<triplhnt_state>();
	int i;

	int hit_line = 999;
	int hit_code = 999;

	for (i = 0; i < 16; i++)
	{
		rectangle rect;

		int j = (state->m_orga_ram[i] & 15) ^ 15;

		/* software sorts sprites by x and stores order in orga RAM */

		int hpos = state->m_hpos_ram[j] ^ 255;
		int vpos = state->m_vpos_ram[j] ^ 255;
		int code = state->m_code_ram[j] ^ 255;

		if (hpos == 255)
			continue;

		/* sprite placement might be wrong */

		if (state->m_sprite_zoom)
		{
			rect.set(hpos - 16, hpos - 16 + 63, 196 - vpos, 196 - vpos + 63);
		}
		else
		{
			rect.set(hpos - 16, hpos - 16 + 31, 224 - vpos, 224 - vpos + 31);
		}

		/* render sprite to auxiliary bitmap */

		drawgfx_opaque(state->m_helper, cliprect, machine.gfx[state->m_sprite_zoom],
			2 * code + state->m_sprite_bank, 0, code & 8, 0,
			rect.min_x, rect.min_y);

		rect &= cliprect;

		/* check for collisions and copy sprite */

		{
			int x;
			int y;

			for (x = rect.min_x; x <= rect.max_x; x++)
			{
				for (y = rect.min_y; y <= rect.max_y; y++)
				{
					pen_t a = state->m_helper.pix16(y, x);
					pen_t b = bitmap.pix16(y, x);

					if (a == 2 && b == 7)
					{
						hit_code = j;
						hit_line = y;
					}

					if (a != 1)
						bitmap.pix16(y, x) = a;
				}
			}
		}
	}

	if (hit_line != 999 && hit_code != 999)
		machine.scheduler().timer_set(machine.primary_screen->time_until_pos(hit_line), FUNC(triplhnt_hit_callback), hit_code);
}
Exemplo n.º 6
0
static void snes_input_read( running_machine &machine )
{
	snes_state *state = machine.driver_data<snes_state>();
	UINT8 ctrl1 = input_port_read(machine, "CTRLSEL") & 0x0f;
	UINT8 ctrl2 = (input_port_read(machine, "CTRLSEL") & 0xf0) >> 4;

	/* Check if lightgun has been chosen as input: if so, enable crosshair */
	machine.scheduler().timer_set(attotime::zero, FUNC(lightgun_tick));

	switch (ctrl1)
	{
	case 1:	/* SNES joypad */
		snes_input_read_joy(machine, 0);
		break;
	case 2:	/* SNES Mouse */
		snes_input_read_mouse(machine, 0);
		break;
	case 3:	/* SNES Superscope */
		snes_input_read_superscope(machine, 0);
		break;
	case 0:	/* no controller in port1 */
	default:
		state->m_data1[0] = 0;
		state->m_data2[0] = 0;
		break;
	}

	switch (ctrl2)
	{
	case 1:	/* SNES joypad */
		snes_input_read_joy(machine, 1);
		break;
	case 2:	/* SNES Mouse */
		snes_input_read_mouse(machine, 1);
		break;
	case 3:	/* SNES Superscope */
		snes_input_read_superscope(machine, 1);
		break;
	case 0:	/* no controller in port2 */
	default:
		state->m_data1[1] = 0;
		state->m_data2[1] = 0;
		break;
	}

	// is automatic reading on? if so, copy port data1/data2 to joy1l->joy4h
	// this actually works like reading the first 16bits from oldjoy1/2 in reverse order
	if (snes_ram[NMITIMEN] & 1)
	{
		state->m_joy1l = (state->m_data1[0] & 0x00ff) >> 0;
		state->m_joy1h = (state->m_data1[0] & 0xff00) >> 8;
		state->m_joy2l = (state->m_data1[1] & 0x00ff) >> 0;
		state->m_joy2h = (state->m_data1[1] & 0xff00) >> 8;
		state->m_joy3l = (state->m_data2[0] & 0x00ff) >> 0;
		state->m_joy3h = (state->m_data2[0] & 0xff00) >> 8;
		state->m_joy4l = (state->m_data2[1] & 0x00ff) >> 0;
		state->m_joy4h = (state->m_data2[1] & 0xff00) >> 8;

		// make sure read_idx starts returning all 1s because the auto-read reads it :-)
		state->m_read_idx[0] = 16;
		state->m_read_idx[1] = 16;
	}
Exemplo n.º 7
0
static void create_interrupt_timer( running_machine &machine )
{
	beaminv_state *state = machine.driver_data<beaminv_state>();
	state->m_interrupt_timer = machine.scheduler().timer_alloc(FUNC(interrupt_callback));
}
Exemplo n.º 8
0
static void create_interrupt_timer( running_machine &machine )
{
	beaminv_state *state = machine.driver_data<beaminv_state>();
	state->m_interrupt_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(beaminv_state::interrupt_callback),state));
}
Exemplo n.º 9
0
Arquivo: sgi.c Projeto: cdenix/psmame
void sgi_mc_timer_init(running_machine &machine)
{
	tMC_UpdateTimer = machine.scheduler().timer_alloc(FUNC(mc_update_callback));
	tMC_UpdateTimer->adjust(attotime::from_hz(10000), 0, attotime::from_hz(10000));
}
Exemplo n.º 10
0
/* call hiscore_open once after loading a game */
void hiscore_init (running_machine &machine)
{
	memory_range *mem_range = state.mem_range;
	address_space *initspace;
	file_error filerr;
  	const char *name = machine.system().name;
	state.hiscores_have_been_loaded = 0;

	while (mem_range)
	{
		if (strstr(machine.system().source_file,"cinemat.cpp") > 0)
		{
			initspace = &machine.cpu[mem_range->cpu]->memory().space(AS_DATA);
			initspace->write_byte(mem_range->addr, ~mem_range->start_value);
			initspace->write_byte(mem_range->addr + mem_range->num_bytes-1, ~mem_range->end_value);
			mem_range = mem_range->next;
		}
		else
		{
			initspace = &machine.cpu[mem_range->cpu]->memory().space(AS_PROGRAM);
			initspace->write_byte(mem_range->addr, ~mem_range->start_value);
		  	initspace->write_byte(mem_range->addr + mem_range->num_bytes-1, ~mem_range->end_value);
			mem_range = mem_range->next;
		}
	}

	state.mem_range = NULL;
	emu_file f(OPEN_FLAG_READ);
  	filerr = f.open("hiscore", ".dat");

	if(filerr == FILERR_NONE)
	{
		char buffer[MAX_CONFIG_LINE_SIZE];
		enum { FIND_NAME, FIND_DATA, FETCH_DATA } mode;
		mode = FIND_NAME;

		while (f.gets(buffer, MAX_CONFIG_LINE_SIZE))
		{
			if (mode == FIND_NAME)
			{
				if (matching_game_name (buffer, name))
				{
					mode = FIND_DATA;
				}
			}
			else if (is_mem_range (buffer))
			{
				const char *pBuf = buffer;
				mem_range = (memory_range *)malloc(sizeof(memory_range));

				if (mem_range)
				{
					mem_range->cpu = hexstr2num (&pBuf);
					mem_range->addr = hexstr2num (&pBuf);
					mem_range->num_bytes = hexstr2num (&pBuf);
					mem_range->start_value = hexstr2num (&pBuf);
					mem_range->end_value = hexstr2num (&pBuf);

					mem_range->next = NULL;
					{
						memory_range *last = state.mem_range;
						while (last && last->next) last = last->next;

						if (last == NULL)
						{
							state.mem_range = mem_range;
						}
						else
						{
							last->next = mem_range;
						}
					}

					mode = FETCH_DATA;
				}
				else
				{
					hiscore_free();
					break;
				}
			}
			else
			{
				/* line is a game name */
				if (mode == FETCH_DATA) 
					break;
			}
		}
		f.close();
	}
	
	timer = machine.scheduler().timer_alloc(FUNC(hiscore_periodic));
	timer->adjust(machine.first_screen()->frame_period(), 0, machine.first_screen()->frame_period());

	machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(hiscore_close), &machine));
}
Exemplo n.º 11
0
static void cchasm_refresh (running_machine &machine)
{
    cchasm_state *state = machine.driver_data<cchasm_state>();

    int pc = 0;
    int done = 0;
    int opcode, data;
    int currentx = 0, currenty = 0;
    int scalex = 0, scaley = 0;
    int color = 0;
    int total_length = 1;   /* length of all lines drawn in a frame */
    int move = 0;

    vector_clear_list();

    while (!done)
    {
        data = state->m_ram[pc];
        opcode = data >> 12;
        data &= 0xfff;
        if ((opcode > COLOR) && (data & 0x800))
            data |= 0xfffff000;

        pc++;

        switch (opcode)
        {
        case HALT:
            done=1;
            break;
        case JUMP:
            pc = data - 0xb00;
            logerror("JUMP to %x\n", data);
            break;
        case COLOR:
            color = VECTOR_COLOR444(data ^ 0xfff);
            break;
        case SCALEY:
            scaley = data << 5;
            break;
        case POSY:
            move = 1;
            currenty = state->m_ycenter + (data << 16);
            break;
        case SCALEX:
            scalex = data << 5;
            break;
        case POSX:
            move = 1;
            currentx = state->m_xcenter - (data << 16);
            break;
        case LENGTH:
            if (move)
            {
                vector_add_point (machine, currentx, currenty, 0, 0);
                move = 0;
            }

            currentx -= data * scalex;
            currenty += data * scaley;

            total_length += abs(data);

            if (color)
                vector_add_point (machine, currentx, currenty, color, 0xff);
            else
                move = 1;
            break;
        default:
            logerror("Unknown refresh proc opcode %x with data %x at pc = %x\n", opcode, data, pc-2);
            done = 1;
            break;
        }
    }
    /* Refresh processor runs with 6 MHz */
    machine.scheduler().timer_set (attotime::from_hz(6000000) * total_length, FUNC(cchasm_refresh_end));
}
Exemplo n.º 12
0
static void update_interrupt_state(running_machine &machine)
{
	compis_state *state = machine.driver_data<compis_state>();
	int i, j, new_vector = 0;

	if (LOG_INTERRUPTS) logerror("update_interrupt_status: req=%02X stat=%02X serv=%02X\n", state->m_i186.intr.request, state->m_i186.intr.status, state->m_i186.intr.in_service);

	/* loop over priorities */
	for (i = 0; i <= state->m_i186.intr.priority_mask; i++)
	{
		/* note: by checking 4 bits, we also verify that the mask is off */
		if ((state->m_i186.intr.timer & 15) == i)
		{
			/* if we're already servicing something at this level, don't generate anything new */
			if (state->m_i186.intr.in_service & 0x01)
				return;

			/* if there's something pending, generate an interrupt */
			if (state->m_i186.intr.status & 0x07)
			{
				if (state->m_i186.intr.status & 1)
					new_vector = 0x08;
				else if (state->m_i186.intr.status & 2)
					new_vector = 0x12;
				else if (state->m_i186.intr.status & 4)
					new_vector = 0x13;
				else
					popmessage("Invalid timer interrupt!");

				/* set the clear mask and generate the int */
				state->m_i186.intr.ack_mask = 0x0001;
				goto generate_int;
			}
		}

		/* check DMA interrupts */
		for (j = 0; j < 2; j++)
			if ((state->m_i186.intr.dma[j] & 15) == i)
			{
				/* if we're already servicing something at this level, don't generate anything new */
				if (state->m_i186.intr.in_service & (0x04 << j))
					return;

				/* if there's something pending, generate an interrupt */
				if (state->m_i186.intr.request & (0x04 << j))
				{
					new_vector = 0x0a + j;

					/* set the clear mask and generate the int */
					state->m_i186.intr.ack_mask = 0x0004 << j;
					goto generate_int;
				}
			}

		/* check external interrupts */
		for (j = 0; j < 4; j++)
			if ((state->m_i186.intr.ext[j] & 15) == i)
			{
				/* if we're already servicing something at this level, don't generate anything new */
				if (state->m_i186.intr.in_service & (0x10 << j))
					return;

				/* if there's something pending, generate an interrupt */
				if (state->m_i186.intr.request & (0x10 << j))
				{
					/* otherwise, generate an interrupt for this request */
					new_vector = 0x0c + j;

					/* set the clear mask and generate the int */
					state->m_i186.intr.ack_mask = 0x0010 << j;
					goto generate_int;
				}
			}
	}
	return;

generate_int:
	/* generate the appropriate interrupt */
	state->m_i186.intr.poll_status = 0x8000 | new_vector;
	if (!state->m_i186.intr.pending)
		cputag_set_input_line(machine, "maincpu", 0, ASSERT_LINE);
	state->m_i186.intr.pending = 1;
	machine.scheduler().trigger(CPU_RESUME_TRIGGER);
	if (LOG_OPTIMIZATION) logerror("  - trigger due to interrupt pending\n");
	if (LOG_INTERRUPTS) logerror("(%f) **** Requesting interrupt vector %02X\n", machine.time().as_double(), new_vector);
}
Exemplo n.º 13
0
void ti990_hold_load(running_machine &machine)
{
	machine.device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
	machine.scheduler().timer_set(attotime::from_msec(100), FUNC(clear_load));
}
Exemplo n.º 14
0
video_manager::video_manager(running_machine &machine)
	: m_machine(machine)
	, m_screenless_frame_timer(nullptr)
	, m_output_changed(false)
	, m_throttle_last_ticks(0)
	, m_throttle_realtime(attotime::zero)
	, m_throttle_emutime(attotime::zero)
	, m_throttle_history(0)
	, m_speed_last_realtime(0)
	, m_speed_last_emutime(attotime::zero)
	, m_speed_percent(1.0)
	, m_overall_real_seconds(0)
	, m_overall_real_ticks(0)
	, m_overall_emutime(attotime::zero)
	, m_overall_valid_counter(0)
	, m_throttled(machine.options().throttle())
	, m_throttle_rate(1.0f)
	, m_fastforward(false)
	, m_seconds_to_run(machine.options().seconds_to_run())
	, m_auto_frameskip(machine.options().auto_frameskip())
	, m_speed(original_speed_setting())
	, m_empty_skip_count(0)
	, m_frameskip_level(machine.options().frameskip())
	, m_frameskip_counter(0)
	, m_frameskip_adjust(0)
	, m_skipping_this_frame(false)
	, m_average_oversleep(0)
	, m_snap_target(nullptr)
	, m_snap_native(true)
	, m_snap_width(0)
	, m_snap_height(0)
	, m_timecode_enabled(false)
	, m_timecode_write(false)
	, m_timecode_text("")
	, m_timecode_start(attotime::zero)
	, m_timecode_total(attotime::zero)
{
	// request a callback upon exiting
	machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(&video_manager::exit, this));
	machine.save().register_postload(save_prepost_delegate(FUNC(video_manager::postload), this));

	// extract initial execution state from global configuration settings
	update_refresh_speed();

	const unsigned screen_count(screen_device_iterator(machine.root_device()).count());
	const bool no_screens(!screen_count);

	// create a render target for snapshots
	const char *viewname = machine.options().snap_view();
	m_snap_native = !no_screens && (viewname[0] == 0 || strcmp(viewname, "native") == 0);

	if (m_snap_native)
	{
		// the native target is hard-coded to our internal layout and has all options disabled
		util::xml::file::ptr const root(util::xml::file::create());
		if (!root)
			throw emu_fatalerror("Couldn't create XML document??");
		util::xml::data_node *const layoutnode(root->add_child("mamelayout", nullptr));
		if (!layoutnode)
			throw emu_fatalerror("Couldn't create XML node??");
		layoutnode->set_attribute_int("version", 2);

		for (unsigned i = 0; screen_count > i; ++i)
		{
			util::xml::data_node *const viewnode(layoutnode->add_child("view", nullptr));
			if (!viewnode)
				throw emu_fatalerror("Couldn't create XML node??");
			viewnode->set_attribute("name", util::xml::normalize_string(util::string_format("s%1$u", i).c_str()));
			util::xml::data_node *const screennode(viewnode->add_child("screen", nullptr));
			if (!screennode)
				throw emu_fatalerror("Couldn't create XML node??");
			screennode->set_attribute_int("index", i);
			util::xml::data_node *const boundsnode(screennode->add_child("bounds", nullptr));
			if (!boundsnode)
				throw emu_fatalerror("Couldn't create XML node??");
			boundsnode->set_attribute_int("left", 0);
			boundsnode->set_attribute_int("top", 0);
			boundsnode->set_attribute_int("right", 1);
			boundsnode->set_attribute_int("bottom", 1);
		}

		m_snap_target = machine.render().target_alloc(*root, RENDER_CREATE_SINGLE_FILE | RENDER_CREATE_HIDDEN);
		m_snap_target->set_backdrops_enabled(false);
		m_snap_target->set_overlays_enabled(false);
		m_snap_target->set_bezels_enabled(false);
		m_snap_target->set_cpanels_enabled(false);
		m_snap_target->set_marquees_enabled(false);
		m_snap_target->set_screen_overlay_enabled(false);
		m_snap_target->set_zoom_to_screen(false);
	}
	else
	{
		// otherwise, non-default targets select the specified view and turn off effects
		m_snap_target = machine.render().target_alloc(nullptr, RENDER_CREATE_HIDDEN);
		m_snap_target->set_view(m_snap_target->configured_view(viewname, 0, 1));
		m_snap_target->set_screen_overlay_enabled(false);
	}

	// extract snap resolution if present
	if (sscanf(machine.options().snap_size(), "%dx%d", &m_snap_width, &m_snap_height) != 2)
		m_snap_width = m_snap_height = 0;

	// start recording movie if specified
	const char *filename = machine.options().mng_write();
	if (filename[0] != 0)
		begin_recording(filename, MF_MNG);

	filename = machine.options().avi_write();
	if (filename[0] != 0)
		begin_recording(filename, MF_AVI);

	// if no screens, create a periodic timer to drive updates
	if (no_screens)
	{
		m_screenless_frame_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(video_manager::screenless_update_callback), this));
		m_screenless_frame_timer->adjust(screen_device::DEFAULT_FRAME_PERIOD, 0, screen_device::DEFAULT_FRAME_PERIOD);
		machine.output().set_notifier(nullptr, video_notifier_callback, this);
	}
}