diff options
Diffstat (limited to 'src/frontend/mame/ui/viewgfx.cpp')
-rw-r--r-- | src/frontend/mame/ui/viewgfx.cpp | 193 |
1 files changed, 92 insertions, 101 deletions
diff --git a/src/frontend/mame/ui/viewgfx.cpp b/src/frontend/mame/ui/viewgfx.cpp index 1da14866c57..1c263fed451 100644 --- a/src/frontend/mame/ui/viewgfx.cpp +++ b/src/frontend/mame/ui/viewgfx.cpp @@ -9,14 +9,15 @@ *********************************************************************/ #include "emu.h" +#include "ui/viewgfx.h" + + #include "emupal.h" -#include "ui/ui.h" -#include "uiinput.h" #include "render.h" #include "rendfont.h" #include "rendutil.h" #include "tilemap.h" -#include "ui/viewgfx.h" +#include "uiinput.h" #include <cmath> @@ -32,9 +33,9 @@ enum ui_gfx_modes UI_GFX_TILEMAP }; -static const uint8_t MAX_GFX_DECODERS = 8; -static const int MAX_ZOOM_LEVEL = 8; -static const int MIN_ZOOM_LEVEL = 8; +constexpr uint8_t MAX_GFX_DECODERS = 8; +constexpr int MAX_ZOOM_LEVEL = 8; +constexpr int MIN_ZOOM_LEVEL = 8; @@ -49,16 +50,16 @@ struct ui_gfx_info uint8_t setcount; // how many gfx sets device has uint8_t rotate[MAX_GFX_ELEMENTS]; // current rotation (orientation) value uint8_t columns[MAX_GFX_ELEMENTS]; // number of items per row - int offset[MAX_GFX_ELEMENTS]; // current offset of top,left item - int color[MAX_GFX_ELEMENTS]; // current color selected + int offset[MAX_GFX_ELEMENTS]; // current offset of top,left item + int color[MAX_GFX_ELEMENTS]; // current color selected device_palette_interface *palette[MAX_GFX_ELEMENTS]; // associated palette (maybe multiple choice one day?) - int color_count[MAX_GFX_ELEMENTS]; // Range of color values + int color_count[MAX_GFX_ELEMENTS]; // Range of color values }; struct ui_gfx_state { bool started; // have we called ui_gfx_count_devices() yet? - uint8_t mode; // which mode are we in? + uint8_t mode; // which mode are we in? // intermediate bitmaps bool bitmap_dirty; // is the bitmap dirty? @@ -69,19 +70,19 @@ struct ui_gfx_state struct { device_palette_interface *interface; // pointer to current palette - int devcount; // how many palette devices exist - int devindex; // which palette device is visible - uint8_t which; // which subset (pens or indirect colors)? - uint8_t columns; // number of items per row - int offset; // current offset of top left item + int devcount; // how many palette devices exist + int devindex; // which palette device is visible + uint8_t which; // which subset (pens or indirect colors)? + uint8_t columns; // number of items per row + int offset; // current offset of top left item } palette; // graphics-specific data struct { - uint8_t devcount; // how many gfx devices exist - uint8_t devindex; // which device is visible - uint8_t set; // which set is visible + uint8_t devcount; // how many gfx devices exist + uint8_t devindex; // which device is visible + uint8_t set; // which set is visible } gfxset; // information about each gfx device @@ -90,14 +91,14 @@ struct ui_gfx_state // tilemap-specific data struct { - int which; // which tilemap are we viewing? - int xoffs; // current X offset - int yoffs; // current Y offset - int zoom; // zoom factor, either x or 1/x - bool zoom_frac; // zoom via reciprocal fractions - bool auto_zoom; // auto-zoom toggle - uint8_t rotate; // current rotation (orientation) value - uint32_t flags; // render flags + int which; // which tilemap are we viewing? + int xoffs; // current X offset + int yoffs; // current Y offset + int zoom; // zoom factor, either x or 1/x + bool zoom_frac; // zoom via reciprocal fractions + bool auto_zoom; // auto-zoom toggle + uint8_t rotate; // current rotation (orientation) value + uint32_t flags; // render flags } tilemap; }; @@ -130,7 +131,7 @@ static void gfxset_update_bitmap(running_machine &machine, ui_gfx_state &state, static void gfxset_handler(mame_ui_manager &mui, render_container &container, ui_gfx_state &state); // tilemap handling -static void tilemap_handle_keys(running_machine &machine, ui_gfx_state &state, int viswidth, int visheight); +static void tilemap_handle_keys(running_machine &machine, ui_gfx_state &state, float pixelscale); static void tilemap_update_bitmap(running_machine &machine, ui_gfx_state &state, int width, int height); static void tilemap_handler(mame_ui_manager &mui, render_container &container, ui_gfx_state &state); @@ -542,20 +543,13 @@ static void palette_handler(mame_ui_manager &mui, render_container &container, u static void palette_handle_keys(running_machine &machine, ui_gfx_state &state) { device_palette_interface *palette = state.palette.interface; - int rowcount, screencount; - int total; - // handle zoom (minus,plus) if (machine.ui_input().pressed(IPT_UI_ZOOM_OUT)) - state.palette.columns /= 2; + state.palette.columns = std::min<uint8_t>(state.palette.columns * 2, 64); if (machine.ui_input().pressed(IPT_UI_ZOOM_IN)) - state.palette.columns *= 2; - - // clamp within range - if (state.palette.columns <= 4) - state.palette.columns = 4; - if (state.palette.columns > 64) - state.palette.columns = 64; + state.palette.columns = std::max<uint8_t>(state.palette.columns / 2, 4); + if (machine.ui_input().pressed(IPT_UI_ZOOM_DEFAULT)) + state.palette.columns = 16; // handle colormap selection (open bracket,close bracket) if (machine.ui_input().pressed(IPT_UI_PREV_GROUP)) @@ -584,11 +578,11 @@ static void palette_handle_keys(running_machine &machine, ui_gfx_state &state) } // cache some info in locals - total = state.palette.which ? palette->indirect_entries() : palette->entries(); + const int total = state.palette.which ? palette->indirect_entries() : palette->entries(); // determine number of entries per row and total - rowcount = state.palette.columns; - screencount = rowcount * rowcount; + const int rowcount = state.palette.columns; + const int screencount = rowcount * rowcount; // handle keyboard navigation if (machine.ui_input().pressed_repeat(IPT_UI_UP, 4)) @@ -855,17 +849,14 @@ static void gfxset_handle_keys(running_machine &machine, ui_gfx_state &state, in gfx_element &gfx = *info.interface->gfx(set); // handle cells per line (minus,plus) - if (machine.ui_input().pressed(IPT_UI_ZOOM_OUT)) - { info.columns[set] = xcells - 1; state.bitmap_dirty = true; } - - if (machine.ui_input().pressed(IPT_UI_ZOOM_IN)) + if (machine.ui_input().pressed(IPT_UI_ZOOM_OUT) && (xcells < 128)) { info.columns[set] = xcells + 1; state.bitmap_dirty = true; } - // clamp within range - if (info.columns[set] < 2) - { info.columns[set] = 2; state.bitmap_dirty = true; } - if (info.columns[set] > 128) - { info.columns[set] = 128; state.bitmap_dirty = true; } + if (machine.ui_input().pressed(IPT_UI_ZOOM_IN) && (xcells > 2)) + { info.columns[set] = xcells - 1; state.bitmap_dirty = true; } + + if (machine.ui_input().pressed(IPT_UI_ZOOM_DEFAULT) && (xcells != 16)) + { info.columns[set] = 16; state.bitmap_dirty = true; } // handle rotation (R) if (machine.ui_input().pressed(IPT_UI_ROTATE)) @@ -918,18 +909,16 @@ static void gfxset_handle_keys(running_machine &machine, ui_gfx_state &state, in static void gfxset_update_bitmap(running_machine &machine, ui_gfx_state &state, int xcells, int ycells, gfx_element &gfx) { - int dev = state.gfxset.devindex; - int set = state.gfxset.set; + const int dev = state.gfxset.devindex; + const int set = state.gfxset.set; ui_gfx_info &info = state.gfxdev[dev]; - int cellxpix, cellypix; - int x, y; // compute the number of source pixels in a cell - cellxpix = 1 + ((info.rotate[set] & ORIENTATION_SWAP_XY) ? gfx.height() : gfx.width()); - cellypix = 1 + ((info.rotate[set] & ORIENTATION_SWAP_XY) ? gfx.width() : gfx.height()); + const int cellxpix = 1 + ((info.rotate[set] & ORIENTATION_SWAP_XY) ? gfx.height() : gfx.width()); + const int cellypix = 1 + ((info.rotate[set] & ORIENTATION_SWAP_XY) ? gfx.width() : gfx.height()); // realloc the bitmap if it is too small - if (!state.bitmap.valid() || state.texture == nullptr || state.bitmap.width() != cellxpix * xcells || state.bitmap.height() != cellypix * ycells) + if (!state.bitmap.valid() || !state.texture || state.bitmap.width() != cellxpix * xcells || state.bitmap.height() != cellypix * ycells) { // free the old stuff machine.render().texture_free(state.texture); @@ -948,37 +937,28 @@ static void gfxset_update_bitmap(running_machine &machine, ui_gfx_state &state, if (state.bitmap_dirty) { // loop over rows - for (y = 0; y < ycells; y++) + for (int y = 0, index = info.offset[set]; y < ycells; y++) { - rectangle cellbounds; - // make a rect that covers this row - cellbounds.set(0, state.bitmap.width() - 1, y * cellypix, (y + 1) * cellypix - 1); + rectangle cellbounds(0, state.bitmap.width() - 1, y * cellypix, (y + 1) * cellypix - 1); // only display if there is data to show - if (info.offset[set] + y * xcells < gfx.elements()) + if (index < gfx.elements()) { // draw the individual cells - for (x = 0; x < xcells; x++) + for (int x = 0; x < xcells; x++, index++) { - int index = info.offset[set] + y * xcells + x; - // update the bounds for this cell cellbounds.min_x = x * cellxpix; cellbounds.max_x = (x + 1) * cellxpix - 1; - // only render if there is data - if (index < gfx.elements()) + if (index < gfx.elements()) // only render if there is data gfxset_draw_item(machine, gfx, index, state.bitmap, cellbounds.min_x, cellbounds.min_y, info.color[set], info.rotate[set], info.palette[set]); - - // otherwise, fill with transparency - else + else // otherwise, fill with transparency state.bitmap.fill(0, cellbounds); } } - - // otherwise, fill with transparency - else + else // otherwise, fill with transparency state.bitmap.fill(0, cellbounds); } @@ -1090,19 +1070,21 @@ static void tilemap_handler(mame_ui_manager &mui, render_container &container, u mapboxwidth = (mapboxbounds.x1 - mapboxbounds.x0) * float(targwidth); mapboxheight = (mapboxbounds.y1 - mapboxbounds.y0) * float(targheight); - // determine the maximum integral scaling factor - float pixelscale = state.tilemap.zoom_frac ? (1.0f / state.tilemap.zoom) : float(state.tilemap.zoom); + float pixelscale; if (state.tilemap.auto_zoom) { - uint32_t maxxscale, maxyscale; - for (maxxscale = 1; mapwidth * (maxxscale + 1) < mapboxwidth; maxxscale++) { } - for (maxyscale = 1; mapheight * (maxyscale + 1) < mapboxheight; maxyscale++) { } - pixelscale = float(std::min(maxxscale, maxyscale)); + // determine the maximum integral scaling factor + pixelscale = std::min(std::floor(mapboxwidth / mapwidth), std::floor(mapboxheight / mapheight)); + pixelscale = std::max(pixelscale, 1.0f); + } + else + { + pixelscale = state.tilemap.zoom_frac ? (1.0f / state.tilemap.zoom) : float(state.tilemap.zoom); } // recompute the final box size - mapboxwidth = std::min(mapboxwidth, int(std::round(mapwidth * pixelscale))); - mapboxheight = std::min(mapboxheight, int(std::round(mapheight * pixelscale))); + mapboxwidth = std::min<int>(mapboxwidth, std::lround(mapwidth * pixelscale)); + mapboxheight = std::min<int>(mapboxheight, std::lround(mapheight * pixelscale)); // recompute the bounds, centered within the existing bounds mapboxbounds.x0 += 0.5f * ((mapboxbounds.x1 - mapboxbounds.x0) - float(mapboxwidth) / targwidth); @@ -1137,8 +1119,8 @@ static void tilemap_handler(mame_ui_manager &mui, render_container &container, u ypixel = (mapboxheight - 1) - ypixel; if (state.tilemap.rotate & ORIENTATION_SWAP_XY) std::swap(xpixel, ypixel); - uint32_t col = ((int(std::round(xpixel / pixelscale)) + state.tilemap.xoffs) / tilemap->tilewidth()) % tilemap->cols(); - uint32_t row = ((int(std::round(ypixel / pixelscale)) + state.tilemap.yoffs) / tilemap->tileheight()) % tilemap->rows(); + uint32_t col = ((std::lround(xpixel / pixelscale) + state.tilemap.xoffs) / tilemap->tilewidth()) % tilemap->cols(); + uint32_t row = ((std::lround(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); @@ -1174,7 +1156,7 @@ static void tilemap_handler(mame_ui_manager &mui, render_container &container, u } // update the bitmap - tilemap_update_bitmap(mui.machine(), state, int(std::round(mapboxwidth / pixelscale)), int(std::round(mapboxheight / pixelscale))); + tilemap_update_bitmap(mui.machine(), state, std::lround(mapboxwidth / pixelscale), std::lround(mapboxheight / pixelscale)); // add the final quad container.add_quad(mapboxbounds.x0, mapboxbounds.y0, @@ -1183,7 +1165,7 @@ static void tilemap_handler(mame_ui_manager &mui, render_container &container, u PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(state.tilemap.rotate)); // handle keyboard input - tilemap_handle_keys(mui.machine(), state, mapboxwidth, mapboxheight); + tilemap_handle_keys(mui.machine(), state, pixelscale); } @@ -1192,7 +1174,7 @@ static void tilemap_handler(mame_ui_manager &mui, render_container &container, u // tilemap view //------------------------------------------------- -static void tilemap_handle_keys(running_machine &machine, ui_gfx_state &state, int viswidth, int visheight) +static void tilemap_handle_keys(running_machine &machine, ui_gfx_state &state, float pixelscale) { // handle tilemap selection (open bracket,close bracket) if (machine.ui_input().pressed(IPT_UI_PREV_GROUP) && state.tilemap.which > 0) @@ -1211,9 +1193,16 @@ static void tilemap_handle_keys(running_machine &machine, ui_gfx_state &state, i // handle zoom (minus,plus) if (machine.ui_input().pressed(IPT_UI_ZOOM_OUT) && !at_min_zoom) { - state.tilemap.auto_zoom = false; - - if (state.tilemap.zoom_frac) + if (state.tilemap.auto_zoom) + { + // auto zoom never uses fractional factors + state.tilemap.zoom = std::lround(pixelscale) - 1; + state.tilemap.zoom_frac = !state.tilemap.zoom; + if (state.tilemap.zoom_frac) + state.tilemap.zoom = 2; + state.tilemap.auto_zoom = false; + } + else if (state.tilemap.zoom_frac) { // remaining in fractional zoom range state.tilemap.zoom++; @@ -1232,14 +1221,19 @@ static void tilemap_handle_keys(running_machine &machine, ui_gfx_state &state, i state.bitmap_dirty = true; - machine.popmessage(state.tilemap.zoom_frac ? "Zoom = 1/%d" : "Zoom = %d", state.tilemap.zoom); + machine.popmessage(state.tilemap.zoom_frac ? _("Zoom = 1/%1$d") : _("Zoom = %1$d"), state.tilemap.zoom); } if (machine.ui_input().pressed(IPT_UI_ZOOM_IN) && !at_max_zoom) { - state.tilemap.auto_zoom = false; - - if (!state.tilemap.zoom_frac) + if (state.tilemap.auto_zoom) + { + // auto zoom never uses fractional factors + state.tilemap.zoom = std::min<int>(std::lround(pixelscale) + 1, MAX_ZOOM_LEVEL); + state.tilemap.zoom_frac = false; + state.tilemap.auto_zoom = false; + } + else if (!state.tilemap.zoom_frac) { // remaining in integer zoom range state.tilemap.zoom++; @@ -1258,17 +1252,14 @@ static void tilemap_handle_keys(running_machine &machine, ui_gfx_state &state, i state.bitmap_dirty = true; - machine.popmessage(state.tilemap.zoom_frac ? "Zoom = 1/%d" : "Zoom = %d", state.tilemap.zoom); + machine.popmessage(state.tilemap.zoom_frac ? _("Zoom = 1/%1$d") : _("Zoom = %1$d"), state.tilemap.zoom); } - if (machine.ui_input().pressed(IPT_UI_ZOOM_AUTO)) + if (machine.ui_input().pressed(IPT_UI_ZOOM_DEFAULT) && !state.tilemap.auto_zoom) { - state.tilemap.auto_zoom = !state.tilemap.auto_zoom; + state.tilemap.auto_zoom = true; - if (state.tilemap.auto_zoom) - machine.popmessage("Auto Zoom"); - else - machine.popmessage(state.tilemap.zoom_frac ? "Zoom = 1/%d" : "Zoom = %d", state.tilemap.zoom); + machine.popmessage(_("Expand to fit")); } // handle rotation (R) @@ -1372,7 +1363,7 @@ static void tilemap_update_bitmap(running_machine &machine, ui_gfx_state &state, std::swap(width, height); // realloc the bitmap if it is too small - if (!state.bitmap.valid() || state.texture == nullptr || state.bitmap.width() != width || state.bitmap.height() != height) + if (!state.bitmap.valid() || !state.texture || state.bitmap.width() != width || state.bitmap.height() != height) { // free the old stuff machine.render().texture_free(state.texture); |