Example #1
0
static void tilemap_handler(running_machine &machine, render_container *container, ui_gfx_state *state)
{
	render_font *ui_font = ui_get_font(machine);
	float chwidth, chheight;
	render_bounds mapboxbounds;
	render_bounds boxbounds;
	int targwidth = machine.render().ui_target().width();
	int targheight = machine.render().ui_target().height();
	float titlewidth;
	float x0, y0;
	int mapboxwidth, mapboxheight;
	int maxxscale, maxyscale;
	UINT32 mapwidth, mapheight;
	int x, pixelscale;
	char title[100];

	/* get the size of the tilemap itself */
	tilemap_t *tilemap = machine.tilemap().find(state->tilemap.which);
	mapwidth = tilemap->width();
	mapheight = tilemap->height();
	if (state->tilemap.rotate & ORIENTATION_SWAP_XY)
		{ UINT32 temp = mapwidth; mapwidth = mapheight; mapheight = temp; }

	/* add a half character padding for the box */
	chheight = ui_get_line_height(machine);
	chwidth = ui_font->char_width(chheight, machine.render().ui_aspect(), '0');
	boxbounds.x0 = 0.0f + 0.5f * chwidth;
	boxbounds.x1 = 1.0f - 0.5f * chwidth;
	boxbounds.y0 = 0.0f + 0.5f * chheight;
	boxbounds.y1 = 1.0f - 0.5f * chheight;

	/* the tilemap box bounds starts a half character in from the box */
	mapboxbounds = boxbounds;
	mapboxbounds.x0 += 0.5f * chwidth;
	mapboxbounds.x1 -= 0.5f * chwidth;
	mapboxbounds.y0 += 0.5f * chheight;
	mapboxbounds.y1 -= 0.5f * chheight;

	/* add space on the top for a title and a half line of padding */
	mapboxbounds.y0 += 1.5f * chheight;

	/* convert back to pixels */
	mapboxwidth = (mapboxbounds.x1 - mapboxbounds.x0) * (float)targwidth;
	mapboxheight = (mapboxbounds.y1 - mapboxbounds.y0) * (float)targheight;

	/* determine the maximum integral scaling factor */
	pixelscale = state->tilemap.zoom;
	if (pixelscale == 0)
	{
		for (maxxscale = 1; mapwidth * (maxxscale + 1) < mapboxwidth; maxxscale++) ;
		for (maxyscale = 1; mapheight * (maxyscale + 1) < mapboxheight; maxyscale++) ;
		pixelscale = MIN(maxxscale, maxyscale);
	}

	/* recompute the final box size */
	mapboxwidth = MIN(mapboxwidth, mapwidth * pixelscale);
	mapboxheight = MIN(mapboxheight, mapheight * pixelscale);

	/* recompute the bounds, centered within the existing bounds */
	mapboxbounds.x0 += 0.5f * ((mapboxbounds.x1 - mapboxbounds.x0) - (float)mapboxwidth / (float)targwidth);
	mapboxbounds.x1 = mapboxbounds.x0 + (float)mapboxwidth / (float)targwidth;
	mapboxbounds.y0 += 0.5f * ((mapboxbounds.y1 - mapboxbounds.y0) - (float)mapboxheight / (float)targheight);
	mapboxbounds.y1 = mapboxbounds.y0 + (float)mapboxheight / (float)targheight;

	/* now recompute the outer box against this new info */
	boxbounds.x0 = mapboxbounds.x0 - 0.5f * chwidth;
	boxbounds.x1 = mapboxbounds.x1 + 0.5f * chwidth;
	boxbounds.y0 = mapboxbounds.y0 - 2.0f * chheight;
	boxbounds.y1 = mapboxbounds.y1 + 0.5f * chheight;

	/* figure out the title and expand the outer box to fit */
	sprintf(title, "TMAP %d/%d %dx%d OFFS %d,%d", state->tilemap.which, machine.tilemap().count() - 1, mapwidth, mapheight, state->tilemap.xoffs, state->tilemap.yoffs);
	titlewidth = ui_font->string_width(chheight, machine.render().ui_aspect(), title);
	if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth)
	{
		boxbounds.x0 = 0.5f - 0.5f * (titlewidth + chwidth);
		boxbounds.x1 = boxbounds.x0 + titlewidth + chwidth;
	}

	/* go ahead and draw the outer box now */
	ui_draw_outlined_box(container, boxbounds.x0, boxbounds.y0, boxbounds.x1, boxbounds.y1, UI_GFXVIEWER_BG_COLOR);

	/* draw the title */
	x0 = 0.5f - 0.5f * titlewidth;
	y0 = boxbounds.y0 + 0.5f * chheight;
	for (x = 0; title[x] != 0; x++)
	{
		container->add_char(x0, y0, chheight, machine.render().ui_aspect(), ARGB_WHITE, *ui_font, title[x]);
		x0 += ui_font->char_width(chheight, machine.render().ui_aspect(), title[x]);
	}

	/* update the bitmap */
	tilemap_update_bitmap(machine, state, mapboxwidth / pixelscale, mapboxheight / pixelscale);

	/* add the final quad */
	container->add_quad(mapboxbounds.x0, mapboxbounds.y0,
						mapboxbounds.x1, mapboxbounds.y1,
						ARGB_WHITE, state->texture,
						PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(state->tilemap.rotate));

	/* handle keyboard input */
	tilemap_handle_keys(machine, state, mapboxwidth, mapboxheight);
}
Example #2
0
static void tilemap_handler(mame_ui_manager &mui, render_container &container, ui_gfx_state &state)
{
	render_font *ui_font = mui.get_font();
	float chwidth, chheight;
	render_bounds mapboxbounds;
	render_bounds boxbounds;
	int targwidth = mui.machine().render().ui_target().width();
	int targheight = mui.machine().render().ui_target().height();
	float titlewidth;
	float x0, y0;
	int mapboxwidth, mapboxheight;

	// get the size of the tilemap itself
	tilemap_t *tilemap = mui.machine().tilemap().find(state.tilemap.which);
	uint32_t mapwidth = tilemap->width();
	uint32_t mapheight = tilemap->height();
	if (state.tilemap.rotate & ORIENTATION_SWAP_XY)
		std::swap(mapwidth, mapheight);

	// add a half character padding for the box
	chheight = mui.get_line_height();
	chwidth = ui_font->char_width(chheight, mui.machine().render().ui_aspect(), '0');
	boxbounds.x0 = 0.0f + 0.5f * chwidth;
	boxbounds.x1 = 1.0f - 0.5f * chwidth;
	boxbounds.y0 = 0.0f + 0.5f * chheight;
	boxbounds.y1 = 1.0f - 0.5f * chheight;

	// the tilemap box bounds starts a half character in from the box
	mapboxbounds = boxbounds;
	mapboxbounds.x0 += 0.5f * chwidth;
	mapboxbounds.x1 -= 0.5f * chwidth;
	mapboxbounds.y0 += 0.5f * chheight;
	mapboxbounds.y1 -= 0.5f * chheight;

	// add space on the top for a title and a half line of padding
	mapboxbounds.y0 += 1.5f * chheight;

	// convert back to pixels
	mapboxwidth = (mapboxbounds.x1 - mapboxbounds.x0) * (float)targwidth;
	mapboxheight = (mapboxbounds.y1 - mapboxbounds.y0) * (float)targheight;

	// determine the maximum integral scaling factor
	int pixelscale = state.tilemap.zoom;
	if (pixelscale == 0)
	{
		int maxxscale, maxyscale;
		for (maxxscale = 1; mapwidth * (maxxscale + 1) < mapboxwidth; maxxscale++) { }
		for (maxyscale = 1; mapheight * (maxyscale + 1) < mapboxheight; maxyscale++) { }
		pixelscale = std::min(maxxscale, maxyscale);
	}

	// recompute the final box size
	mapboxwidth = std::min(mapboxwidth, int(mapwidth * pixelscale));
	mapboxheight = std::min(mapboxheight, int(mapheight * pixelscale));

	// recompute the bounds, centered within the existing bounds
	mapboxbounds.x0 += 0.5f * ((mapboxbounds.x1 - mapboxbounds.x0) - (float)mapboxwidth / (float)targwidth);
	mapboxbounds.x1 = mapboxbounds.x0 + (float)mapboxwidth / (float)targwidth;
	mapboxbounds.y0 += 0.5f * ((mapboxbounds.y1 - mapboxbounds.y0) - (float)mapboxheight / (float)targheight);
	mapboxbounds.y1 = mapboxbounds.y0 + (float)mapboxheight / (float)targheight;

	// now recompute the outer box against this new info
	boxbounds.x0 = mapboxbounds.x0 - 0.5f * chwidth;
	boxbounds.x1 = mapboxbounds.x1 + 0.5f * chwidth;
	boxbounds.y0 = mapboxbounds.y0 - 2.0f * chheight;
	boxbounds.y1 = mapboxbounds.y1 + 0.5f * chheight;

	// figure out the title
	std::ostringstream title_buf;
	util::stream_format(title_buf, "TILEMAP %d/%d", state.tilemap.which + 1, mui.machine().tilemap().count());

	// if the mouse pointer is over a tile, add some info about its coordinates and color
	int32_t mouse_target_x, mouse_target_y;
	float mouse_x, mouse_y;
	bool mouse_button;
	render_target *mouse_target = mui.machine().ui_input().find_mouse(&mouse_target_x, &mouse_target_y, &mouse_button);
	if (mouse_target != nullptr && mouse_target->map_point_container(mouse_target_x, mouse_target_y, container, mouse_x, mouse_y)
		&& mapboxbounds.x0 <= mouse_x && mapboxbounds.x1 > mouse_x
		&& mapboxbounds.y0 <= mouse_y && mapboxbounds.y1 > mouse_y)
	{
		int xpixel = (mouse_x - mapboxbounds.x0) * targwidth;
		int ypixel = (mouse_y - mapboxbounds.y0) * targheight;
		if (state.tilemap.rotate & ORIENTATION_FLIP_X)
			xpixel = (mapboxwidth - 1) - xpixel;
		if (state.tilemap.rotate & ORIENTATION_FLIP_Y)
			ypixel = (mapboxheight - 1) - ypixel;
		if (state.tilemap.rotate & ORIENTATION_SWAP_XY)
			std::swap(xpixel, ypixel);
		uint32_t col = ((xpixel / pixelscale + state.tilemap.xoffs) / tilemap->tilewidth()) % tilemap->cols();
		uint32_t row = ((ypixel / pixelscale + state.tilemap.yoffs) / tilemap->tileheight()) % tilemap->rows();
		uint8_t gfxnum;
		uint32_t code, color;
		tilemap->get_info_debug(col, row, gfxnum, code, color);
		util::stream_format(title_buf, " @ %d,%d = GFX%d #%X:%X",
							col * tilemap->tilewidth(), row * tilemap->tileheight(),
							int(gfxnum), code, color);
	}
	else
		util::stream_format(title_buf, " %dx%d OFFS %d,%d", tilemap->width(), tilemap->height(), state.tilemap.xoffs, state.tilemap.yoffs);

	if (state.tilemap.flags != TILEMAP_DRAW_ALL_CATEGORIES)
		util::stream_format(title_buf, " CAT %d", state.tilemap.flags);

	// expand the outer box to fit the title
	const std::string title = title_buf.str();
	titlewidth = ui_font->string_width(chheight, mui.machine().render().ui_aspect(), title.c_str());
	if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth)
	{
		boxbounds.x0 = 0.5f - 0.5f * (titlewidth + chwidth);
		boxbounds.x1 = boxbounds.x0 + titlewidth + chwidth;
	}

	// go ahead and draw the outer box now
	mui.draw_outlined_box(container, boxbounds.x0, boxbounds.y0, boxbounds.x1, boxbounds.y1, UI_GFXVIEWER_BG_COLOR);

	// draw the title
	x0 = 0.5f - 0.5f * titlewidth;
	y0 = boxbounds.y0 + 0.5f * chheight;
	for (auto ch : title)
	{
		container.add_char(x0, y0, chheight, mui.machine().render().ui_aspect(), rgb_t::white(), *ui_font, ch);
		x0 += ui_font->char_width(chheight, mui.machine().render().ui_aspect(), ch);
	}

	// update the bitmap
	tilemap_update_bitmap(mui.machine(), state, mapboxwidth / pixelscale, mapboxheight / pixelscale);

	// add the final quad
	container.add_quad(mapboxbounds.x0, mapboxbounds.y0,
						mapboxbounds.x1, mapboxbounds.y1,
						rgb_t::white(), state.texture,
						PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(state.tilemap.rotate));

	// handle keyboard input
	tilemap_handle_keys(mui.machine(), state, mapboxwidth, mapboxheight);
}