Example #1
0
static void ui_messagebox_center(struct advance_ui_context* context, adv_bitmap* dst, int x, int y, const char* begin, const char* end, struct ui_color cf, struct ui_color cb, adv_pixel* map, adv_color_def def)
{
	int border_x, border_y;
	int size_x, size_y;
	int pos_x, pos_y;
	adv_bitmap* flat;

	border_x = adv_font_sizex(context->state.ui_font);
	border_y = adv_font_sizey(context->state.ui_font) / 2;

	end = adv_font_sizex_limit(context->state.ui_font, begin, end, dst->size_x - border_x * 2);

	size_x = border_x * 2 + adv_font_sizex_string(context->state.ui_font, begin, end);
	size_y = border_y * 2 + adv_font_sizey(context->state.ui_font);

	pos_x = x - size_x / 2;
	pos_y = y - size_y / 2;

	if (ui_alpha(def))
		flat = adv_bitmap_alloc(size_x, size_y, color_def_bytes_per_pixel_get(context->state.buffer_def));
	else
		flat = adv_bitmap_alloc(size_x, size_y, color_def_bytes_per_pixel_get(def));

	adv_bitmap_box(flat, 0, 0, size_x, size_y, 1, cf.f);
	adv_bitmap_clear(flat, 1, 1, size_x - 2, size_y - 2, cb.b);

	if (ui_alpha(def))
		adv_font_put_string_map(context->state.ui_font, flat, border_x, border_y, begin, end, map);
	else
		adv_font_put_string(context->state.ui_font, flat, border_x, border_y, begin, end, cf.p, cb.p);

	if (ui_alpha(def))
		adv_bitmap_put_alpha(dst, pos_x, pos_y, def, flat, 0, 0, flat->size_x, flat->size_y, context->state.buffer_def);
	else
		adv_bitmap_put(dst, pos_x, pos_y, flat, 0, 0, flat->size_x, flat->size_y);

	adv_bitmap_free(flat);
}
Example #2
0
static void ui_help_update(struct advance_ui_context* context, adv_bitmap* dst, struct ui_color_set* color)
{
	int size_x;
	int size_y;
	int pos_x;
	int pos_y;
	unsigned cx;
	unsigned cy;
	unsigned i;
	unsigned pb;
	char msg_buffer[256];
	adv_bitmap* flat;
	adv_color_def def = color->def;

	struct mame_digital_map_entry digital_map[UI_MAP_MAX];
	unsigned digital_mac;

	mame_ui_input_map(&digital_mac, digital_map, UI_MAP_MAX);

	size_x = context->state.help_image->size_x;
	size_y = context->state.help_image->size_y;

	pos_x = dst->size_x / 2 - size_x / 2;
	pos_y = dst->size_y / 8;

	if (ui_alpha(def))
		flat = adv_bitmap_alloc(size_x, size_y, color_def_bytes_per_pixel_get(context->state.buffer_def));
	else
		flat = adv_bitmap_alloc(size_x, size_y, color_def_bytes_per_pixel_get(def));

	pb = 0; /* black on RGB format */

	for (cy = 0; cy < context->state.help_image->size_y; ++cy) {
		for (cx = 0; cx < context->state.help_image->size_x; ++cx) {
			adv_pixel c;
			if ((adv_bitmap_pixel_get(context->state.help_image, cx, cy)) != pb) {
				c = color->ui_f.f;
			} else {
				c = color->ui_b.b;
			}
			adv_bitmap_pixel_put(flat, cx, cy, c);
		}
	}

	msg_buffer[0] = 0;

	for (i = 0; i < digital_mac; ++i) {
		unsigned j;
		adv_bool pred_not = 0;

		if (digital_map[i].port_state) {
			struct mame_port* p;
			p = mame_port_find(digital_map[i].port);
			if (p) {
				unsigned k;

				/* add the port name only one time */
				/* if the port list is broken, a port name may appers more than one time */

				for (k = 0; k < i; ++k)
					if (digital_map[k].port == digital_map[i].port)
						break;

				if (k == i) {
					if (msg_buffer[0])
						sncat(msg_buffer, sizeof(msg_buffer), ", ");
					sncat(msg_buffer, sizeof(msg_buffer), p->desc);
				}
			}
		}

		for (j = 0; j < MAME_INPUT_MAP_MAX && digital_map[i].seq[j] != DIGITAL_SPECIAL_NONE; ++j) {
			if (!pred_not) {
				unsigned k;
				unsigned ckf;
				unsigned ckb;

				switch (mame_port_player(digital_map[i].port)) {
				case 1: ckb = color->help_p1.b; break;
				case 2: ckb = color->help_p2.b; break;
				case 3: ckb = color->help_p3.b; break;
				case 4: ckb = color->help_p4.b; break;
				default: ckb = color->help_u.b; break;
				}
				ckf = color->ui_f.f;

				if (digital_map[i].port_state) {
					ckf = color->ui_f.f;
					ckb = color->ui_f.b;
				}

				for (k = 0; k < context->config.help_mac; ++k) {
					if (context->config.help_map[k].code == digital_map[i].seq[j]) {
						struct help_entry* h = context->config.help_map + k;
						ui_help_update_key(flat, context->state.help_image, 0, 0, h->x, h->y, h->dx, h->dy, ckf, ckb, pb);
					}
				}
			}

			pred_not = digital_map[i].seq[j] == DIGITAL_SPECIAL_NOT;
		}
	}

	if (ui_alpha(def))
		adv_bitmap_put_alpha(dst, pos_x, pos_y, def, flat, 0, 0, flat->size_x, flat->size_y, context->state.buffer_def);
	else
		adv_bitmap_put(dst, pos_x, pos_y, flat, 0, 0, flat->size_x, flat->size_y);

	adv_bitmap_free(flat);

	if (msg_buffer[0])
		ui_messagebox_center(context, dst, dst->size_x / 2, pos_y + size_y + adv_font_sizey(context->state.ui_font) * 2, msg_buffer, msg_buffer + strlen(msg_buffer), color->ui_f, color->ui_b, color->ui_alpha, color->def);
}
Example #3
0
static void ui_scroll(struct advance_ui_context* context, adv_bitmap* dst, char* begin, char* end, unsigned pos, struct ui_color text_f, struct ui_color text_b, adv_pixel* text_map, struct ui_color title_f, struct ui_color title_b, adv_pixel* title_map, adv_color_def def)
{
	unsigned size_r;
	unsigned size_v;
	int step_x, step_y;
	int border_x, border_y;
	int size_x, size_y;
	int pos_x, pos_y;
	int limit_x;
	char* i;
	char* start;
	unsigned n;
	adv_bitmap* flat;

	step_x = adv_font_sizex(context->state.ui_font);
	step_y = adv_font_sizey(context->state.ui_font);

	border_x = step_x;
	border_y = step_y / 2;

	/* remove unprintable chars */
	i = begin;
	while (i != end) {
		if (!((*i >= ' ' && *i <= '~') || *i == '\n'))
			*i = ' ';
		++i;
	}

	/* count size_r and compute width and wrap long line */
	limit_x = dst->size_x - 6 * border_x;
	size_r = 0;
	size_x = 0;
	i = begin;
	start = begin;
	while (i != end) {
		unsigned width;
		char* j = i;

		width = 0;
		while (j != end && *j != '\n') {
			unsigned char_width;

			char_width = adv_font_sizex_char(context->state.ui_font, *j);
			if (width + char_width > limit_x) {
				char* b = j;
				/* search first space backward */
				while (b != i && !isspace(*b))
					--b;
				if (b != i) {
					/* adjust the position */
					if (pos > size_r)
						++pos;
					/* insert a break */
					*b = '\n';
					j = b;
					break;
				}
			} else {
				width += char_width;
			}
			++j;
		}

		if (size_r == pos)
			start = i;

		++size_r;
		width = adv_font_sizex_string(context->state.ui_font, i, j);
		if (width > size_x)
			size_x = width;

		if (j != end)
			i = j + 1;
		else
			i = j;
	}

	/* size */
	size_x += 2 * border_x;
	if (size_x > dst->size_x)
		size_x = dst->size_x;
	size_v = (dst->size_y - 4 * border_y) / step_y;
	if (size_v > size_r)
		size_v = size_r;
	size_y = size_v * step_y + 2 * border_y;

	/* position */
	pos_x = dst->size_x / 2 - size_x / 2;
	pos_y = dst->size_y / 2 - size_y / 2;

	if (ui_alpha(def))
		flat = adv_bitmap_alloc(size_x, size_y, color_def_bytes_per_pixel_get(context->state.buffer_def));
	else
		flat = adv_bitmap_alloc(size_x, size_y, color_def_bytes_per_pixel_get(def));

	/* put */
	adv_bitmap_box(flat, 0, 0, size_x, size_y, 1, text_f.f);
	adv_bitmap_clear(flat, 1, 1, size_x - 2, size_y - 2, text_b.b);

	n = 0;
	i = start;
	while (i != end && n < size_v) {
		struct ui_color f;
		struct ui_color b;
		adv_pixel* m;
		char* k;
		char* j = i;
		const char* je;
		while (j != end && *j != '\n')
			++j;

		je = adv_font_sizex_limit(context->state.ui_font, i, j, size_x - 2 * border_x);

		for (k = i; k != j; ++k) {
			if (islower(*k))
				break;
		}
		if (ui_recognize_title(i, j)) {
			f = title_f;
			b = title_b;
			m = title_map;
		} else {
			f = text_f;
			b = text_b;
			m = text_map;
		}

		ui_text_left(context, flat, border_x, border_y + n * step_y, i, je, f, b, m, def);

		if (j != end)
			i = j + 1;
		else
			i = j;
		++n;
	}

	if (ui_alpha(def))
		adv_bitmap_put_alpha(dst, pos_x, pos_y, def, flat, 0, 0, flat->size_x, flat->size_y, context->state.buffer_def);
	else
		adv_bitmap_put(dst, pos_x, pos_y, flat, 0, 0, flat->size_x, flat->size_y);

	adv_bitmap_free(flat);
}
Example #4
0
static void ui_menu(struct advance_ui_context* context, adv_bitmap* dst, struct ui_menu_entry* menu_map, unsigned menu_mac, int menu_sel, struct ui_color entry_f, struct ui_color entry_b, adv_pixel* entry_map, struct ui_color select_f, struct ui_color select_b, adv_pixel* select_map, struct ui_color title_f, struct ui_color title_b, adv_pixel* title_map, adv_color_def def)
{
	int step_x, step_y;
	int border_x, border_y;
	int size_x, size_y;
	int pos_x, pos_y;
	int pos_r;
	int pos_s;
	int size_r;
	unsigned i;
	unsigned y;
	unsigned dft_dx;
	unsigned dft_dy;
	int up;
	int down;
	adv_bitmap* flat;

	step_x = adv_font_sizex(context->state.ui_font);
	step_y = adv_font_sizey(context->state.ui_font);

	dft_dx = dst->size_x * 3 / 4;
	dft_dy = dst->size_y * 2 / 5;

	border_x = step_x;
	border_y = step_y / 2;

	/* compute the size of the menu */

	size_x = border_x * 2;
	size_y = border_y * 2;

	/* search the selected position */
	pos_r = 0;
	pos_s = 0;
	for (i = 0; i < menu_mac; ++i) {
		switch (menu_map[i].type) {
		case ui_menu_text:
		case ui_menu_option:
			if (menu_sel == pos_r) {
				pos_s = i;
			}
			++pos_r;
			break;
		default:
			break;
		}
	}

	up = 0;
	down = 0;
	size_r = 0;
	pos_r = pos_s;

	while (1) {
		unsigned width;
		unsigned height;

		if (size_r == 0) {
			i = pos_r;
		} else if (up <= down && pos_r > 0) {
			i = pos_r - 1;
		} else if (up > down && pos_r + size_r < menu_mac) {
			i = pos_r + size_r;
		} else if (pos_r > 0) {
			i = pos_r - 1;
		} else if (pos_r + size_r < menu_mac) {
			i = pos_r + size_r;
		} else {
			break;
		}

		switch (menu_map[i].type) {
		case ui_menu_title:
			width = border_x * 2 + adv_font_sizex_string(context->state.ui_font, menu_map[i].text_buffer, menu_map[i].text_buffer + strlen(menu_map[i].text_buffer));
			height = step_y;
			break;
		case ui_menu_text:
			width = border_x * 2 + adv_font_sizex_string(context->state.ui_font, menu_map[i].text_buffer, menu_map[i].text_buffer + strlen(menu_map[i].text_buffer));
			height = step_y;
			break;
		case ui_menu_option:
			width = border_x * 2 + adv_font_sizex_string(context->state.ui_font, menu_map[i].text_buffer, menu_map[i].text_buffer + strlen(menu_map[i].text_buffer));
			width += border_x * 3 + adv_font_sizex_string(context->state.ui_font, menu_map[i].option_buffer, menu_map[i].option_buffer + strlen(menu_map[i].option_buffer));
			height = step_y;
			break;
		case ui_menu_dft:
			width = dft_dx;
			height = dft_dy;
			break;
		default:
			width = 0;
			height = 0;
			break;
		}

		if (size_y + height > dst->size_y)
			break;

		size_y += height;

		if (size_x < width)
			size_x = width;

		if (i == pos_r) {
			++size_r;
		} else if (i < pos_r) {
			up += height;
			--pos_r;
			++size_r;
		} else if (i > pos_r) {
			down += height;
			++size_r;
		}
	}

	if (size_x > dst->size_x)
		size_x = dst->size_x;

	/* position */
	pos_x = dst->size_x / 2 - size_x / 2;
	pos_y = dst->size_y / 2 - size_y / 2;

	if (ui_alpha(def))
		flat = adv_bitmap_alloc(size_x, size_y, color_def_bytes_per_pixel_get(context->state.buffer_def));
	else
		flat = adv_bitmap_alloc(size_x, size_y, color_def_bytes_per_pixel_get(def));

	/* put */
	adv_bitmap_box(flat, 0, 0, size_x, size_y, 1, entry_f.f);
	adv_bitmap_clear(flat, 1, 1, size_x - 2, size_y - 2, entry_b.b);

	y = border_y;

	for (i = 0; i < size_r; ++i) {
		struct ui_menu_entry* e = &menu_map[i + pos_r];
		struct ui_color cef;
		struct ui_color ceb;
		struct ui_color ctf;
		struct ui_color ctb;
		adv_pixel* cem;
		adv_pixel* ctm;

		unsigned height = e->type == ui_menu_dft ? dft_dy : step_y;
		unsigned width = size_x - 2 * border_x;

		if (i + pos_r == pos_s) {
			cef = select_f;
			ceb = select_b;
			cem = select_map;
			ctf = select_f;
			ctb = select_b;
			ctm = select_map;
		} else {
			cef = entry_f;
			ceb = entry_b;
			cem = entry_map;
			ctf = title_f;
			ctb = title_b;
			ctm = title_map;
		}

		adv_bitmap_clear(flat, border_x / 2, y, size_x - (border_x / 2) * 2, height, ceb.b);

		if (e->type == ui_menu_option) {
			const char* begin = e->text_buffer;
			const char* end = e->text_buffer + strlen(e->text_buffer);

			end = adv_font_sizex_limit(context->state.ui_font, begin, end, width);

			ui_text_left(context, flat, border_x, y, begin, end, cef, ceb, cem, def);

			width -= adv_font_sizex_string(context->state.ui_font, begin, end);

			begin = e->option_buffer;
			end = e->option_buffer + strlen(e->option_buffer);

			end = adv_font_sizex_limit(context->state.ui_font, begin, end, width);

			ui_text_right(context, flat, size_x - border_x, y, begin, end, ctf, ctb, ctm, def);
		} else if (e->type == ui_menu_title || e->type == ui_menu_text) {
			const char* begin = e->text_buffer;
			const char* end = e->text_buffer + strlen(e->text_buffer);

			adv_bool title = e->type == ui_menu_title;

			end = adv_font_sizex_limit(context->state.ui_font, begin, end, width);

			ui_text_center(context, flat, size_x / 2, y, begin, end, title ? ctf : cef, title ? ctb : ceb, title ? ctm : cem, def);
		} else if (e->type == ui_menu_dft) {
			ui_dft(context, flat, border_x, y + border_y, size_x - border_x * 2, height - border_y * 2, e->m, e->n, e->cut1, e->cut2, cef, ceb, ctf, def);
		}

		y += height;
	}

	if (ui_alpha(def))
		adv_bitmap_put_alpha(dst, pos_x, pos_y, def, flat, 0, 0, flat->size_x, flat->size_y, context->state.buffer_def);
	else
		adv_bitmap_put(dst, pos_x, pos_y, flat, 0, 0, flat->size_x, flat->size_y);

	adv_bitmap_free(flat);
}
Example #5
0
/**
 * Load a .pcx file in a bitmap.
 * Only the 8 and 24 bits format are supported.
 * \param f File to load.
 * \param rgb Where to put the palette information. it must point to a vector of 256 elements.
 * \param rgb_max Where to put the number of palette entries.
 * \return The loaded bitmap or 0 on error.
 */
adv_bitmap* adv_bitmap_load_pcx(adv_color_rgb* rgb, unsigned* rgb_max, adv_fz* f)
{
    struct pcx_header_t h;
    adv_bitmap* bitmap;
    unsigned width, height, depth;

    if (pcx_header_read(f, &h)!=0) {
        goto out;
    }

    /* limitations */
    if (h.bits_per_pixel != 8) {
        goto out;
    }

    if (h.planes != 1 && h.planes != 3) {
        goto out;
    }

    width = h.x_max - h.x_min + 1;
    height = h.y_max - h.y_min + 1;
    depth = h.planes;

    bitmap = adv_bitmap_alloc(width, height, depth);
    if (!bitmap) {
        goto out;
    }

    if (depth == 1) {
        unsigned i;
        unsigned y;

        for(y=0; y<height; ++y) {
            struct pcx_decode_state state;
            uint8* dst_off = adv_bitmap_line(bitmap, y);
            state.count = 0;
            pcx_decode(dst_off, width, f, &state, 1);
            pcx_ignore(h.bytes_per_line - width, f, &state);
            if (state.count!=0)
                goto out_bitmap;
        }

        if (fzgetc(f)!=12)
            goto out_bitmap;

        for (i=0; i<256; ++i) {
            rgb[i].red = fzgetc(f);
            rgb[i].green = fzgetc(f);
            rgb[i].blue = fzgetc(f);
        }
        *rgb_max = 256;
    } else {
        unsigned y;
        for(y=0; y<height; ++y) {
            struct pcx_decode_state state;
            uint8* dst_off = adv_bitmap_line(bitmap, y);
            state.count = 0;
            pcx_decode(dst_off, width, f, &state, 3);
            pcx_ignore(h.bytes_per_line - width, f, &state);
            pcx_decode(dst_off + 1, width, f, &state, 3);
            pcx_ignore(h.bytes_per_line - width, f, &state);
            pcx_decode(dst_off + 2, width, f, &state, 3);
            pcx_ignore(h.bytes_per_line - width, f, &state);
            if (state.count!=0)
                goto out_bitmap;
        }
    }

    return bitmap;

out_bitmap:
    adv_bitmap_free(bitmap);
out:
    return 0;
}
Example #6
0
/**
 * Load a .ico file in a bitmap.
 * Only the 16 and 256 color formats are supported.
 * \param f File to load.
 * \param rgb Where to put the palette information. it must point to a vector of 256 elements.
 * \param rgb_max Where to put the number of palette entries.
 * \param bitmap_mask Where to put the mask bitmap. 
 * \return The loaded bitmap or 0 on error.
 */
adv_bitmap* adv_bitmap_load_icon(adv_color_rgb* rgb, unsigned* rgb_max, adv_bitmap** bitmap_mask, adv_fz* f)
{
	adv_bitmap* bitmap;
	struct icon_header_t header;
	struct icon_entry_t* entry;
	int i;

	if (icon_header_read(f, &header) != 0)
		goto out;

	if (header.reserved != 0)
		goto out;

	if (header.type != 1)
		goto out;

	if (header.count < 1)
		goto out;

	entry = malloc(header.count * sizeof(struct icon_entry_t));
	if (!entry)
		goto out;

	for(i=0;i<header.count;++i) {
		if (icon_entry_read(f, entry + i)!=0)
			goto out_entry;
	}

	for(i=0;i<header.count;++i) {
		struct icon_bitmap_header_t bitmap_header;
		unsigned j, y;
		unsigned colors;

		if (entry[i].color == 0) {
			colors = 256;
			if (entry[i].bit != 8 && entry[i].bit != 0) /* 0 is out of standard but acceptable */
				continue; /* unsupported */
		} else if (entry[i].color == 16) {
			colors = 16;
			if (entry[i].bit != 4 && entry[i].bit != 0) /* 0 is out of standard but acceptable */
				continue; /* unsupported */
		} else {
			continue; /* unsupported */
		}

		if (entry[i].planes != 1 && entry[i].planes != 0) /* 0 is out of standard but acceptable */
			continue; /* unsupported */

		if (fzseek(f, entry[i].offset, SEEK_SET)!=0)
			goto out_entry;

		if (icon_bitmap_header_read(f, &bitmap_header) != 0)
			goto out_entry;

		if (colors == 256) {
			if (bitmap_header.bit != 8)
				continue; /* unsupported */
		} else if (colors == 16) {
			if (bitmap_header.bit != 4)
				continue; /* unsupported */
		}

		if (bitmap_header.planes != 1)
			continue; /* unsupported */

		if (bitmap_header.compression != 0) 
			continue; /* unsupported */

		for(j=0;j<colors;++j) {
			struct icon_rgb_t color;
			if (icon_rgb_read(f, &color) != 0)
				goto out_entry;
			rgb[j].red = color.red;
			rgb[j].green = color.green;
			rgb[j].blue = color.blue;
		}
		*rgb_max = colors;

		bitmap = adv_bitmap_alloc(entry[i].width, entry[i].height, 1);
		if (!bitmap)
			goto out_entry;

		*bitmap_mask = adv_bitmap_alloc(entry[i].width, entry[i].height, 1);
		if (!*bitmap_mask)
			goto out_bitmap;

		if (colors == 256) {
			/* read bitmap xor data (8 bit per pixel) */
			for(y=0;y<bitmap->size_y;++y) {
				unsigned char* line = adv_bitmap_line(bitmap, bitmap->size_y - y - 1);
				if (fzread(line, bitmap->size_x*bitmap->bytes_per_pixel, 1, f)!=1)
					goto out_bitmap_mask;
			}
		} else if (colors == 16) {
			/* read bitmap xor data (4 bit per pixel) */
			for(y=0;y<bitmap->size_y;++y) {
				int k;
				unsigned char* line = adv_bitmap_line(bitmap, bitmap->size_y - y - 1);
				if (fzread(line, bitmap->size_x / 2, 1, f)!=1)
					goto out_bitmap_mask;
				/* convert */
				for(k=bitmap->size_x-1;k>=0;--k) {
					if (k & 1)
						line[k] = line[k/2] & 0xF;
					else
						line[k] = line[k/2] >> 4;
				}
			}
		}

		/* read bitmap mask data (1 bit per pixel) */
		for(y=0;y<bitmap->size_y;++y) {
			unsigned x ;
			unsigned char* line = adv_bitmap_line(*bitmap_mask, bitmap->size_y - y - 1);
			x = 0;
			while (x < bitmap->size_x) {
				unsigned bc;
				int b = fzgetc(f);
				if (b==EOF)
					goto out_bitmap_mask;
				if (x + 8 > bitmap->size_x)
					bc = bitmap->size_x - x; /* waste unused bit */
				else
					bc = 8;
				x += bc;
				while (bc) {
					if (b & 0x80)
						*line = 0;
					else
						*line = 1;
					b = b << 1;
					++line;
					--bc;
				}
			}
		}

		free(entry);
		return bitmap;
	}

	goto out_entry;

out_bitmap_mask:
	adv_bitmap_free(*bitmap_mask);
out_bitmap:
	adv_bitmap_free(bitmap);
out_entry:
	free(entry);
out:
	return 0;
}