void ui_menu_file_create::populate() { astring buffer; const image_device_format *format; const char *new_image_name; /* append the "New Image Name" item */ if (get_selection() == ITEMREF_NEW_IMAGE_NAME) { buffer.cat(filename_buffer).cat("_"); new_image_name = buffer; } else { new_image_name = filename_buffer; } item_append("New Image Name:", new_image_name, 0, ITEMREF_NEW_IMAGE_NAME); /* do we support multiple formats? */ format = image->device_get_creatable_formats(); if (ENABLE_FORMATS && (format != NULL)) { item_append("Image Format:", current_format->m_description, 0, ITEMREF_FORMAT); current_format = format; } /* finish up the menu */ item_append(MENU_SEPARATOR_ITEM, NULL, 0, NULL); item_append("Create", NULL, 0, ITEMREF_CREATE); customtop = ui_get_line_height(machine()) + 3.0f * UI_BOX_TB_BORDER; }
void ui_menu::draw_text_box() { const char *text = item[0].text; const char *backtext = item[1].text; float line_height = ui_get_line_height(machine()); float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect(); float gutter_width = lr_arrow_width; float target_width, target_height, prior_width; float target_x, target_y; /* compute the multi-line target width/height */ ui_draw_text_full(container, text, 0, 0, 1.0f - 2.0f * UI_BOX_LR_BORDER - 2.0f * gutter_width, JUSTIFY_LEFT, WRAP_WORD, DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &target_width, &target_height); target_height += 2.0f * line_height; if (target_height > 1.0f - 2.0f * UI_BOX_TB_BORDER) target_height = floor((1.0f - 2.0f * UI_BOX_TB_BORDER) / line_height) * line_height; /* maximum against "return to prior menu" text */ prior_width = ui_get_string_width(machine(), backtext) + 2.0f * gutter_width; target_width = MAX(target_width, prior_width); /* determine the target location */ target_x = 0.5f - 0.5f * target_width; target_y = 0.5f - 0.5f * target_height; /* make sure we stay on-screen */ if (target_x < UI_BOX_LR_BORDER + gutter_width) target_x = UI_BOX_LR_BORDER + gutter_width; if (target_x + target_width + gutter_width + UI_BOX_LR_BORDER > 1.0f) target_x = 1.0f - UI_BOX_LR_BORDER - gutter_width - target_width; if (target_y < UI_BOX_TB_BORDER) target_y = UI_BOX_TB_BORDER; if (target_y + target_height + UI_BOX_TB_BORDER > 1.0f) target_y = 1.0f - UI_BOX_TB_BORDER - target_height; /* add a box around that */ ui_draw_outlined_box(container, target_x - UI_BOX_LR_BORDER - gutter_width, target_y - UI_BOX_TB_BORDER, target_x + target_width + gutter_width + UI_BOX_LR_BORDER, target_y + target_height + UI_BOX_TB_BORDER, (item[0].flags & MENU_FLAG_REDTEXT) ? UI_RED_COLOR : UI_BACKGROUND_COLOR); ui_draw_text_full(container, text, target_x, target_y, target_width, JUSTIFY_LEFT, WRAP_WORD, DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, NULL, NULL); /* draw the "return to prior menu" text with a hilight behind it */ container->add_quad( target_x + 0.5f * UI_LINE_WIDTH, target_y + target_height - line_height, target_x + target_width - 0.5f * UI_LINE_WIDTH, target_y + target_height, UI_SELECTED_BG_COLOR, hilight_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE)); ui_draw_text_full(container, backtext, target_x, target_y + target_height - line_height, target_width, JUSTIFY_CENTER, WRAP_TRUNCATE, DRAW_NORMAL, UI_SELECTED_COLOR, UI_SELECTED_BG_COLOR, NULL, NULL); /* artificially set the hover to the last item so a double-click exits */ hover = numitems - 1; }
void cheat_manager::render_text(render_container &container) { // render any text and free it along the way for (int linenum = 0; linenum < ARRAY_LENGTH(m_output); linenum++) if (m_output[linenum]) { // output the text ui_draw_text_full(&container, m_output[linenum], 0.0f, (float)linenum * ui_get_line_height(machine()), 1.0f, m_justify[linenum], WRAP_NEVER, DRAW_OPAQUE, ARGB_WHITE, ARGB_BLACK, NULL, NULL); } }
void cheat_manager::frame_update() { // set up for accumulating output m_lastline = 0; m_numlines = floor(1.0f / ui_get_line_height(machine())); m_numlines = MIN(m_numlines, ARRAY_LENGTH(m_output)); for (int linenum = 0; linenum < ARRAY_LENGTH(m_output); linenum++) m_output[linenum].reset(); // iterate over running cheats and execute them for (cheat_entry *cheat = m_cheatlist.first(); cheat != NULL; cheat = cheat->next()) cheat->frame_update(); // increment the frame counter m_framecount++; }
void ui_menu_file_manager::populate() { char buffer[2048]; astring tmp_name; /* cycle through all devices for this system */ image_interface_iterator iter(machine().root_device()); for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) { /* get the image type/id */ snprintf(buffer, ARRAY_LENGTH(buffer), "%s (%s)", image->device().name(), image->brief_instance_name()); /* get the base name */ if (image->basename() != NULL) { tmp_name.cpy(image->basename()); /* if the image has been loaded through softlist, also show the loaded part */ if (image->part_entry() != NULL) { const software_part *tmp = image->part_entry(); if (tmp->name != NULL) { tmp_name.cat(" ("); tmp_name.cat(tmp->name); /* also check if this part has a specific part_id (e.g. "Map Disc", "Bonus Disc", etc.), and in case display it */ if (image->get_feature("part_id") != NULL) { tmp_name.cat(": "); tmp_name.cat(image->get_feature("part_id")); } tmp_name.cat(")"); } } } else tmp_name.cpy("---"); /* record the menu item */ item_append(buffer, tmp_name.cstr(), 0, (void *) image); } custombottom = ui_get_line_height(machine()) + 3.0f * UI_BOX_TB_BORDER; }
/* display a small tape icon, with the current position in the tape image */ static void device_display_cassette(mess_image *image) { char buf[65]; float x, y; int n; double position, length; cassette_state uistate; /* abort if we should not be showing the image */ if (!image_exists(image)) return; if (!cassette_is_motor_on(image)) return; /* figure out where we are in the cassette */ position = cassette_get_position(image); length = cassette_get_length(image); uistate = cassette_get_state(image) & CASSETTE_MASK_UISTATE; /* choose a location on the screen */ x = 0.0f; y = image_index_in_device(image) * ui_get_line_height(); /* choose which frame of the animation we are at */ n = ((int) position / ANIMATION_FPS) % ANIMATION_FRAMES; /* character pairs 2-3, 4-5, 6-7, 8-9 form little tape cassette images */ snprintf(buf, sizeof(buf) / sizeof(buf[0]), "%c%c %c %02d:%02d (%04d) [%02d:%02d (%04d)]", n * 2 + 2, /* cassette icon left */ n * 2 + 3, /* cassette icon right */ (uistate == CASSETTE_PLAY) ? 16 : 14, /* play or record icon */ ((int) position / 60), ((int) position % 60), (int) position, ((int) length / 60), ((int) length % 60), (int) length); /* draw the cassette */ ui_draw_text_box(buf, JUSTIFY_LEFT, x, y, UI_FILLCOLOR); }
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); }
static void gfxset_handler(running_machine &machine, render_container *container, ui_gfx_state *state) { render_font *ui_font = ui_get_font(machine); int set = state->gfxset.set; gfx_element *gfx = machine.gfx[set]; float fullwidth, fullheight; float cellwidth, cellheight; float chwidth, chheight; float titlewidth; //float cellaspect; float x0, y0; render_bounds cellboxbounds; render_bounds boxbounds; int cellboxwidth, cellboxheight; int targwidth = machine.render().ui_target().width(); int targheight = machine.render().ui_target().height(); int cellxpix, cellypix; int xcells, ycells; int pixelscale = 0; int x, y, skip; char title[100]; /* 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 character cell box bounds starts a half character in from the box */ cellboxbounds = boxbounds; cellboxbounds.x0 += 0.5f * chwidth; cellboxbounds.x1 -= 0.5f * chwidth; cellboxbounds.y0 += 0.5f * chheight; cellboxbounds.y1 -= 0.5f * chheight; /* add space on the left for 5 characters of text, plus a half character of padding */ cellboxbounds.x0 += 5.5f * chwidth; /* add space on the top for a title, a half line of padding, a header, and another half line */ cellboxbounds.y0 += 3.0f * chheight; /* convert back to pixels */ cellboxwidth = (cellboxbounds.x1 - cellboxbounds.x0) * (float)targwidth; cellboxheight = (cellboxbounds.y1 - cellboxbounds.y0) * (float)targheight; /* compute the number of source pixels in a cell */ cellxpix = 1 + ((state->gfxset.rotate[state->gfxset.set] & ORIENTATION_SWAP_XY) ? gfx->height() : gfx->width()); cellypix = 1 + ((state->gfxset.rotate[state->gfxset.set] & ORIENTATION_SWAP_XY) ? gfx->width() : gfx->height()); /* compute the largest pixel scale factor that still fits */ xcells = state->gfxset.count[set]; while (xcells > 1) { pixelscale = (cellboxwidth / xcells) / cellxpix; if (pixelscale != 0) break; xcells--; } /* worst case, we need a pixel scale of 1 */ pixelscale = MAX(1, pixelscale); /* in the Y direction, we just display as many as we can */ ycells = cellboxheight / (pixelscale * cellypix); /* now determine the actual cellbox size */ cellboxwidth = MIN(cellboxwidth, xcells * pixelscale * cellxpix); cellboxheight = MIN(cellboxheight, ycells * pixelscale * cellypix); /* compute the size of a single cell at this pixel scale factor, as well as the aspect ratio */ cellwidth = (cellboxwidth / (float)xcells) / (float)targwidth; cellheight = (cellboxheight / (float)ycells) / (float)targheight; //cellaspect = cellwidth / cellheight; /* working from the new width/height, recompute the boxbounds */ fullwidth = (float)cellboxwidth / (float)targwidth + 6.5f * chwidth; fullheight = (float)cellboxheight / (float)targheight + 4.0f * chheight; /* recompute boxbounds from this */ boxbounds.x0 = (1.0f - fullwidth) * 0.5f; boxbounds.x1 = boxbounds.x0 + fullwidth; boxbounds.y0 = (1.0f - fullheight) * 0.5f; boxbounds.y1 = boxbounds.y0 + fullheight; /* figure out the title and expand the outer box to fit */ for (x = 0; x < MAX_GFX_ELEMENTS && machine.gfx[x] != NULL; x++) ; sprintf(title, "GFX %d/%d %dx%d COLOR %X", state->gfxset.set, x - 1, gfx->width(), gfx->height(), state->gfxset.color[set]); titlewidth = ui_font->string_width(chheight, machine.render().ui_aspect(), title); x0 = 0.0f; if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth) x0 = boxbounds.x0 - (0.5f - 0.5f * (titlewidth + chwidth)); /* go ahead and draw the outer box now */ ui_draw_outlined_box(container, boxbounds.x0 - x0, boxbounds.y0, boxbounds.x1 + x0, 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]); } /* draw the top column headers */ skip = (int)(chwidth / cellwidth); for (x = 0; x < xcells; x += 1 + skip) { x0 = boxbounds.x0 + 6.0f * chwidth + (float)x * cellwidth; y0 = boxbounds.y0 + 2.0f * chheight; container->add_char(x0 + 0.5f * (cellwidth - chwidth), y0, chheight, machine.render().ui_aspect(), ARGB_WHITE, *ui_font, "0123456789ABCDEF"[x & 0xf]); /* if we're skipping, draw a point between the character and the box to indicate which */ /* one it's referring to */ if (skip != 0) container->add_point(x0 + 0.5f * cellwidth, 0.5f * (y0 + chheight + boxbounds.y0 + 3.5f * chheight), UI_LINE_WIDTH, ARGB_WHITE, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } /* draw the side column headers */ skip = (int)(chheight / cellheight); for (y = 0; y < ycells; y += 1 + skip) /* only display if there is data to show */ if (state->gfxset.offset[set] + y * xcells < gfx->elements()) { char buffer[10]; /* if we're skipping, draw a point between the character and the box to indicate which */ /* one it's referring to */ x0 = boxbounds.x0 + 5.5f * chwidth; y0 = boxbounds.y0 + 3.5f * chheight + (float)y * cellheight; if (skip != 0) container->add_point(0.5f * (x0 + boxbounds.x0 + 6.0f * chwidth), y0 + 0.5f * cellheight, UI_LINE_WIDTH, ARGB_WHITE, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); /* draw the row header */ sprintf(buffer, "%5X", state->gfxset.offset[set] + y * xcells); for (x = 4; x >= 0; x--) { x0 -= ui_font->char_width(chheight, machine.render().ui_aspect(), buffer[x]); container->add_char(x0, y0 + 0.5f * (cellheight - chheight), chheight, machine.render().ui_aspect(), ARGB_WHITE, *ui_font, buffer[x]); } } /* update the bitmap */ gfxset_update_bitmap(machine, state, xcells, ycells, gfx); /* add the final quad */ container->add_quad(boxbounds.x0 + 6.0f * chwidth, boxbounds.y0 + 3.5f * chheight, boxbounds.x0 + 6.0f * chwidth + (float)cellboxwidth / (float)targwidth, boxbounds.y0 + 3.5f * chheight + (float)cellboxheight / (float)targheight, ARGB_WHITE, state->texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); /* handle keyboard navigation before drawing */ gfxset_handle_keys(machine, state, xcells, ycells); }
static void palette_handler(running_machine &machine, render_container *container, ui_gfx_state *state) { int total = state->palette.which ? colortable_palette_get_size(machine.colortable) : machine.total_colors(); const char *title = state->palette.which ? "COLORTABLE" : "PALETTE"; const rgb_t *raw_color = palette_entry_list_raw(machine.palette); render_font *ui_font = ui_get_font(machine); float cellwidth, cellheight; float chwidth, chheight; float titlewidth; float x0, y0; render_bounds cellboxbounds; render_bounds boxbounds; int x, y, skip; /* 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 character cell box bounds starts a half character in from the box */ cellboxbounds = boxbounds; cellboxbounds.x0 += 0.5f * chwidth; cellboxbounds.x1 -= 0.5f * chwidth; cellboxbounds.y0 += 0.5f * chheight; cellboxbounds.y1 -= 0.5f * chheight; /* add space on the left for 5 characters of text, plus a half character of padding */ cellboxbounds.x0 += 5.5f * chwidth; /* add space on the top for a title, a half line of padding, a header, and another half line */ cellboxbounds.y0 += 3.0f * chheight; /* figure out the title and expand the outer box to fit */ titlewidth = ui_font->string_width(chheight, machine.render().ui_aspect(), title); x0 = 0.0f; if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth) x0 = boxbounds.x0 - (0.5f - 0.5f * (titlewidth + chwidth)); /* go ahead and draw the outer box now */ ui_draw_outlined_box(container, boxbounds.x0 - x0, boxbounds.y0, boxbounds.x1 + x0, 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]); } /* compute the cell size */ cellwidth = (cellboxbounds.x1 - cellboxbounds.x0) / (float)state->palette.count; cellheight = (cellboxbounds.y1 - cellboxbounds.y0) / (float)state->palette.count; /* draw the top column headers */ skip = (int)(chwidth / cellwidth); for (x = 0; x < state->palette.count; x += 1 + skip) { x0 = boxbounds.x0 + 6.0f * chwidth + (float)x * cellwidth; y0 = boxbounds.y0 + 2.0f * chheight; container->add_char(x0 + 0.5f * (cellwidth - chwidth), y0, chheight, machine.render().ui_aspect(), ARGB_WHITE, *ui_font, "0123456789ABCDEF"[x & 0xf]); /* if we're skipping, draw a point between the character and the box to indicate which */ /* one it's referring to */ if (skip != 0) container->add_point(x0 + 0.5f * cellwidth, 0.5f * (y0 + chheight + cellboxbounds.y0), UI_LINE_WIDTH, ARGB_WHITE, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } /* draw the side column headers */ skip = (int)(chheight / cellheight); for (y = 0; y < state->palette.count; y += 1 + skip) /* only display if there is data to show */ if (state->palette.offset + y * state->palette.count < total) { char buffer[10]; /* if we're skipping, draw a point between the character and the box to indicate which */ /* one it's referring to */ x0 = boxbounds.x0 + 5.5f * chwidth; y0 = boxbounds.y0 + 3.5f * chheight + (float)y * cellheight; if (skip != 0) container->add_point(0.5f * (x0 + cellboxbounds.x0), y0 + 0.5f * cellheight, UI_LINE_WIDTH, ARGB_WHITE, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); /* draw the row header */ sprintf(buffer, "%5X", state->palette.offset + y * state->palette.count); for (x = 4; x >= 0; x--) { x0 -= ui_font->char_width(chheight, machine.render().ui_aspect(), buffer[x]); container->add_char(x0, y0 + 0.5f * (cellheight - chheight), chheight, machine.render().ui_aspect(), ARGB_WHITE, *ui_font, buffer[x]); } } /* now add the rectangles for the colors */ for (y = 0; y < state->palette.count; y++) for (x = 0; x < state->palette.count; x++) { int index = state->palette.offset + y * state->palette.count + x; if (index < total) { pen_t pen = state->palette.which ? colortable_palette_get_color(machine.colortable, index) : raw_color[index]; container->add_rect(cellboxbounds.x0 + x * cellwidth, cellboxbounds.y0 + y * cellheight, cellboxbounds.x0 + (x + 1) * cellwidth, cellboxbounds.y0 + (y + 1) * cellheight, 0xff000000 | pen, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } } /* handle keys */ palette_handle_keys(machine, state); }
void ui_menu::draw(bool customonly) { float line_height = ui_get_line_height(machine()); float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect(); float ud_arrow_width = line_height * machine().render().ui_aspect(); float gutter_width = lr_arrow_width * 1.3f; float x1, y1, x2, y2; float effective_width, effective_left; float visible_width, visible_main_menu_height; float visible_extra_menu_height = 0; float visible_top, visible_left; int selected_subitem_too_big = FALSE; int visible_lines; int top_line; int itemnum, linenum; int mouse_hit, mouse_button; render_target *mouse_target; INT32 mouse_target_x, mouse_target_y; float mouse_x = -1, mouse_y = -1; /* compute the width and height of the full menu */ visible_width = 0; visible_main_menu_height = 0; for (itemnum = 0; itemnum < numitems; itemnum++) { const ui_menu_item &pitem = item[itemnum]; float total_width; /* compute width of left hand side */ total_width = gutter_width + ui_get_string_width(machine(), pitem.text) + gutter_width; /* add in width of right hand side */ if (pitem.subtext) total_width += 2.0f * gutter_width + ui_get_string_width(machine(), pitem.subtext); /* track the maximum */ if (total_width > visible_width) visible_width = total_width; /* track the height as well */ visible_main_menu_height += line_height; } /* account for extra space at the top and bottom */ visible_extra_menu_height = customtop + custombottom; /* add a little bit of slop for rounding */ visible_width += 0.01f; visible_main_menu_height += 0.01f; /* if we are too wide or too tall, clamp it down */ if (visible_width + 2.0f * UI_BOX_LR_BORDER > 1.0f) visible_width = 1.0f - 2.0f * UI_BOX_LR_BORDER; /* if the menu and extra menu won't fit, take away part of the regular menu, it will scroll */ if (visible_main_menu_height + visible_extra_menu_height + 2.0f * UI_BOX_TB_BORDER > 1.0f) visible_main_menu_height = 1.0f - 2.0f * UI_BOX_TB_BORDER - visible_extra_menu_height; visible_lines = floor(visible_main_menu_height / line_height); visible_main_menu_height = (float)visible_lines * line_height; /* compute top/left of inner menu area by centering */ visible_left = (1.0f - visible_width) * 0.5f; visible_top = (1.0f - (visible_main_menu_height + visible_extra_menu_height)) * 0.5f; /* if the menu is at the bottom of the extra, adjust */ visible_top += customtop; /* first add us a box */ x1 = visible_left - UI_BOX_LR_BORDER; y1 = visible_top - UI_BOX_TB_BORDER; x2 = visible_left + visible_width + UI_BOX_LR_BORDER; y2 = visible_top + visible_main_menu_height + UI_BOX_TB_BORDER; if (!customonly) ui_draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR); /* determine the first visible line based on the current selection */ top_line = selected - visible_lines / 2; if (top_line < 0) top_line = 0; if (top_line + visible_lines >= numitems) top_line = numitems - visible_lines; /* determine effective positions taking into account the hilighting arrows */ effective_width = visible_width - 2.0f * gutter_width; effective_left = visible_left + gutter_width; /* locate mouse */ mouse_hit = FALSE; mouse_button = FALSE; if (!customonly) { mouse_target = ui_input_find_mouse(machine(), &mouse_target_x, &mouse_target_y, &mouse_button); if (mouse_target != NULL) if (mouse_target->map_point_container(mouse_target_x, mouse_target_y, *container, mouse_x, mouse_y)) mouse_hit = TRUE; } /* loop over visible lines */ hover = numitems + 1; if (!customonly) for (linenum = 0; linenum < visible_lines; linenum++) { float line_y = visible_top + (float)linenum * line_height; itemnum = top_line + linenum; const ui_menu_item &pitem = item[itemnum]; const char *itemtext = pitem.text; rgb_t fgcolor = UI_TEXT_COLOR; rgb_t bgcolor = UI_TEXT_BG_COLOR; rgb_t fgcolor2 = UI_SUBITEM_COLOR; rgb_t fgcolor3 = UI_CLONE_COLOR; float line_x0 = x1 + 0.5f * UI_LINE_WIDTH; float line_y0 = line_y; float line_x1 = x2 - 0.5f * UI_LINE_WIDTH; float line_y1 = line_y + line_height; /* set the hover if this is our item */ if (mouse_hit && line_x0 <= mouse_x && line_x1 > mouse_x && line_y0 <= mouse_y && line_y1 > mouse_y && pitem.is_selectable()) hover = itemnum; /* if we're selected, draw with a different background */ if (itemnum == selected) { fgcolor = UI_SELECTED_COLOR; bgcolor = UI_SELECTED_BG_COLOR; fgcolor2 = UI_SELECTED_COLOR; fgcolor3 = UI_SELECTED_COLOR; } /* else if the mouse is over this item, draw with a different background */ else if (itemnum == hover) { fgcolor = UI_MOUSEOVER_COLOR; bgcolor = UI_MOUSEOVER_BG_COLOR; fgcolor2 = UI_MOUSEOVER_COLOR; fgcolor3 = UI_MOUSEOVER_COLOR; } /* if we have some background hilighting to do, add a quad behind everything else */ if (bgcolor != UI_TEXT_BG_COLOR) container->add_quad(line_x0, line_y0, line_x1, line_y1, bgcolor, hilight_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE)); /* if we're on the top line, display the up arrow */ if (linenum == 0 && top_line != 0) { container->add_quad( 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, line_y + 0.25f * line_height, 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, line_y + 0.75f * line_height, fgcolor, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT0)); if (hover == itemnum) hover = -2; } /* if we're on the bottom line, display the down arrow */ else if (linenum == visible_lines - 1 && itemnum != numitems - 1) { container->add_quad( 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, line_y + 0.25f * line_height, 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, line_y + 0.75f * line_height, fgcolor, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT0 ^ ORIENTATION_FLIP_Y)); if (hover == itemnum) hover = -1; } /* if we're just a divider, draw a line */ else if (strcmp(itemtext, MENU_SEPARATOR_ITEM) == 0) container->add_line(visible_left, line_y + 0.5f * line_height, visible_left + visible_width, line_y + 0.5f * line_height, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); /* if we don't have a subitem, just draw the string centered */ else if (pitem.subtext == NULL) ui_draw_text_full(container, itemtext, effective_left, line_y, effective_width, JUSTIFY_CENTER, WRAP_TRUNCATE, DRAW_NORMAL, fgcolor, bgcolor, NULL, NULL); /* otherwise, draw the item on the left and the subitem text on the right */ else { int subitem_invert = pitem.flags & MENU_FLAG_INVERT; const char *subitem_text = pitem.subtext; float item_width, subitem_width; /* draw the left-side text */ ui_draw_text_full(container, itemtext, effective_left, line_y, effective_width, JUSTIFY_LEFT, WRAP_TRUNCATE, DRAW_NORMAL, fgcolor, bgcolor, &item_width, NULL); /* give 2 spaces worth of padding */ item_width += 2.0f * gutter_width; /* if the subitem doesn't fit here, display dots */ if (ui_get_string_width(machine(), subitem_text) > effective_width - item_width) { subitem_text = "..."; if (itemnum == selected) selected_subitem_too_big = TRUE; } /* draw the subitem right-justified */ ui_draw_text_full(container, subitem_text, effective_left + item_width, line_y, effective_width - item_width, JUSTIFY_RIGHT, WRAP_TRUNCATE, DRAW_NORMAL, subitem_invert ? fgcolor3 : fgcolor2, bgcolor, &subitem_width, NULL); /* apply arrows */ if (itemnum == selected && (pitem.flags & MENU_FLAG_LEFT_ARROW)) { container->add_quad( effective_left + effective_width - subitem_width - gutter_width, line_y + 0.1f * line_height, effective_left + effective_width - subitem_width - gutter_width + lr_arrow_width, line_y + 0.9f * line_height, fgcolor, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90 ^ ORIENTATION_FLIP_X)); } if (itemnum == selected && (pitem.flags & MENU_FLAG_RIGHT_ARROW)) { container->add_quad( effective_left + effective_width + gutter_width - lr_arrow_width, line_y + 0.1f * line_height, effective_left + effective_width + gutter_width, line_y + 0.9f * line_height, fgcolor, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90)); } } } /* if the selected subitem is too big, display it in a separate offset box */ if (selected_subitem_too_big) { const ui_menu_item &pitem = item[selected]; int subitem_invert = pitem.flags & MENU_FLAG_INVERT; linenum = selected - top_line; float line_y = visible_top + (float)linenum * line_height; float target_width, target_height; float target_x, target_y; /* compute the multi-line target width/height */ ui_draw_text_full(container, pitem.subtext, 0, 0, visible_width * 0.75f, JUSTIFY_RIGHT, WRAP_WORD, DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &target_width, &target_height); /* determine the target location */ target_x = visible_left + visible_width - target_width - UI_BOX_LR_BORDER; target_y = line_y + line_height + UI_BOX_TB_BORDER; if (target_y + target_height + UI_BOX_TB_BORDER > visible_main_menu_height) target_y = line_y - target_height - UI_BOX_TB_BORDER; /* add a box around that */ ui_draw_outlined_box(container, target_x - UI_BOX_LR_BORDER, target_y - UI_BOX_TB_BORDER, target_x + target_width + UI_BOX_LR_BORDER, target_y + target_height + UI_BOX_TB_BORDER, subitem_invert ? UI_SELECTED_BG_COLOR : UI_BACKGROUND_COLOR); ui_draw_text_full(container, pitem.subtext, target_x, target_y, target_width, JUSTIFY_RIGHT, WRAP_WORD, DRAW_NORMAL, UI_SELECTED_COLOR, UI_SELECTED_BG_COLOR, NULL, NULL); } /* if there is something special to add, do it by calling the virtual method */ custom_render((selected >= 0 && selected < numitems) ? item[selected].ref : NULL, customtop, custombottom, x1, y1, x2, y2); /* return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow */ visitems = visible_lines - (top_line != 0) - (top_line + visible_lines != numitems); }
/* display a small tape icon, with the current position in the tape image */ static DEVICE_IMAGE_DISPLAY(cassette) { device_t *device = &image.device(); char buf[65]; float x, y; int n; double position, length; cassette_state uistate; device_t *dev; static const UINT8 shapes[8] = { 0x2d, 0x5c, 0x7c, 0x2f, 0x2d, 0x20, 0x20, 0x20 }; /* abort if we should not be showing the image */ if (!image.exists()) return; if (!cassette_is_motor_on(device)) return; /* figure out where we are in the cassette */ position = cassette_get_position(device); length = cassette_get_length(device); uistate = (cassette_state)(cassette_get_state(device) & CASSETTE_MASK_UISTATE); /* choose a location on the screen */ x = 0.2f; y = 0.5f; dev = device->machine().m_devicelist.first(CASSETTE ); while ( dev && strcmp( dev->tag(), device->tag() ) ) { y += 1; dev = dev->typenext(); } y *= ui_get_line_height(device->machine()) + 2.0f * UI_BOX_TB_BORDER; /* choose which frame of the animation we are at */ n = ((int) position / ANIMATION_FPS) % ANIMATION_FRAMES; /* Since you can have anything in a BDF file, we will use crude ascii characters instead */ snprintf(buf, ARRAY_LENGTH(buf), "%c%c %c %02d:%02d (%04d) [%02d:%02d (%04d)]", #if 0 /* THE ANIMATION HASN'T WORKED SINCE 0.114 - LEFT HERE FOR REFERENCE */ /* NEVER SEEN THE PLAY / RECORD ICONS */ /* character pairs 2-3, 4-5, 6-7, 8-9 form little tape cassette images */ n * 2 + 2, /* cassette icon left */ n * 2 + 3, /* cassette icon right */ (uistate == CASSETTE_PLAY) ? 16 : 14, /* play or record icon */ #else shapes[n], /* cassette icon left */ shapes[n|4], /* cassette icon right */ (uistate == CASSETTE_PLAY) ? 0x50 : 0x52, /* play (P) or record (R) */ #endif ((int) position / 60), ((int) position % 60), (int) position, ((int) length / 60), ((int) length % 60), (int) length); /* draw the cassette */ ui_draw_text_box(&device->machine().render().ui_container(), buf, JUSTIFY_LEFT, x, y, UI_BACKGROUND_COLOR); }
void ui_menu_file_selector::populate() { zippath_directory *directory = NULL; file_error err = FILERR_NONE; const osd_directory_entry *dirent; const file_selector_entry *entry; const file_selector_entry *selected_entry = NULL; int i; const char *volume_name; const char *path = current_directory; /* open the directory */ err = zippath_opendir(path, &directory); if (err != FILERR_NONE) goto done; /* clear out the menu entries */ entrylist = NULL; if (has_empty) { /* add the "[empty slot]" entry */ append_entry(SELECTOR_ENTRY_TYPE_EMPTY, NULL, NULL); } if (has_create) { /* add the "[create]" entry */ append_entry(SELECTOR_ENTRY_TYPE_CREATE, NULL, NULL); } if (has_softlist) /* add the "[software list]" entry */ append_entry(SELECTOR_ENTRY_TYPE_SOFTWARE_LIST, NULL, NULL); /* add the drives */ i = 0; while((volume_name = osd_get_volume_name(i))!=NULL) { append_entry(SELECTOR_ENTRY_TYPE_DRIVE, volume_name, volume_name); i++; } /* build the menu for each item */ while((dirent = zippath_readdir(directory)) != NULL) { /* append a dirent entry */ entry = append_dirent_entry(dirent); if (entry != NULL) { /* set the selected item to be the first non-parent directory or file */ if ((selected_entry == NULL) && strcmp(dirent->name, "..")) selected_entry = entry; /* do we have to select this file? */ if (!mame_stricmp(current_file, dirent->name)) selected_entry = entry; } } /* append all of the menu entries */ for (entry = entrylist; entry != NULL; entry = entry->next) append_entry_menu_item(entry); /* set the selection (if we have one) */ if (selected_entry != NULL) set_selection((void *) selected_entry); /* set up custom render proc */ customtop = ui_get_line_height(machine()) + 3.0f * UI_BOX_TB_BORDER; done: if (directory != NULL) zippath_closedir(directory); }
/* display a small tape icon, with the current position in the tape image */ void cassette_image_device::call_display() { char buf[65]; float x, y; int n; double position, length; cassette_state uistate; cassette_image_device *dev; static const UINT8 shapes[8] = { 0x2d, 0x5c, 0x7c, 0x2f, 0x2d, 0x20, 0x20, 0x20 }; /* abort if we should not be showing the image */ if (!exists()) return; if (!is_motor_on()) return; /* figure out where we are in the cassette */ position = get_position(); length = get_length(); uistate = (cassette_state)(get_state() & CASSETTE_MASK_UISTATE); /* choose a location on the screen */ x = 0.2f; y = 0.5f; cassette_device_iterator iter(device().machine().root_device()); for (dev = iter.first(); dev != NULL && strcmp( dev->tag(), device().tag() ); dev = iter.next()) y += 1; y *= ui_get_line_height(device().machine()) + 2.0f * UI_BOX_TB_BORDER; /* choose which frame of the animation we are at */ n = ((int) position / ANIMATION_FPS) % ANIMATION_FRAMES; /* Since you can have anything in a BDF file, we will use crude ascii characters instead */ snprintf(buf, ARRAY_LENGTH(buf), "%c%c %c %02d:%02d (%04d) [%02d:%02d (%04d)]", #if 0 /* THE ANIMATION HASN'T WORKED SINCE 0.114 - LEFT HERE FOR REFERENCE */ /* NEVER SEEN THE PLAY / RECORD ICONS */ /* character pairs 2-3, 4-5, 6-7, 8-9 form little tape cassette images */ n * 2 + 2, /* cassette icon left */ n * 2 + 3, /* cassette icon right */ (uistate == CASSETTE_PLAY) ? 16 : 14, /* play or record icon */ #else shapes[n], /* cassette icon left */ shapes[n|4], /* cassette icon right */ (uistate == CASSETTE_PLAY) ? 0x50 : 0x52, /* play (P) or record (R) */ #endif ((int) position / 60), ((int) position % 60), (int) position, ((int) length / 60), ((int) length % 60), (int) length); /* draw the cassette */ ui_draw_text_box(&device().machine().render().ui_container(), buf, JUSTIFY_LEFT, x, y, UI_BACKGROUND_COLOR); // make sure tape stops at end when playing if ((m_state & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY) { if ( m_cassette ) { if (position > length) { m_state = (cassette_state)(( m_state & ~CASSETTE_MASK_UISTATE ) | CASSETTE_STOPPED); position = length; } } } }