diff options
-rw-r--r-- | src/emu/tilemap.cpp | 21 | ||||
-rw-r--r-- | src/emu/tilemap.h | 16 | ||||
-rw-r--r-- | src/frontend/mame/ui/ui.cpp | 5 | ||||
-rw-r--r-- | src/frontend/mame/ui/ui.h | 3 | ||||
-rw-r--r-- | src/frontend/mame/ui/viewgfx.cpp | 148 |
5 files changed, 157 insertions, 36 deletions
diff --git a/src/emu/tilemap.cpp b/src/emu/tilemap.cpp index 54dc5cc9d8e..5659169a19b 100644 --- a/src/emu/tilemap.cpp +++ b/src/emu/tilemap.cpp @@ -1475,6 +1475,27 @@ void tilemap_t::draw_debug(screen_device &screen, bitmap_rgb32 &dest, UINT32 scr } +//------------------------------------------------- +// get_info_debug - extract info for one tile +//------------------------------------------------- + +void tilemap_t::get_info_debug(UINT32 col, UINT32 row, int &gfxnum, int &code, int &color) +{ + // first map to the memory index + tilemap_memory_index memindex = memory_index(col, row); + + // next invoke the get info callback + m_tile_get_info(*this, m_tileinfo, memindex); + + // get the GFX number and code + gfxnum = m_tileinfo.gfxnum; + code = m_tileinfo.code; + + // work back from the palette base to get the color + gfx_element *gfx = m_tileinfo.decoder->gfx(gfxnum); + color = (m_tileinfo.palette_base - gfx->colorbase()) / gfx->granularity(); +} + //************************************************************************** // TILEMAP MANAGER diff --git a/src/emu/tilemap.h b/src/emu/tilemap.h index 5692589457e..56f611a6308 100644 --- a/src/emu/tilemap.h +++ b/src/emu/tilemap.h @@ -91,7 +91,11 @@ 1. First create a new tilemap by calling tilemap_manager::create(). The parameters are as follows: - decoder = reference to your device_gfx_interface + decoder = reference to your device_gfx_interface; note that the + graphics the tilemap will use do not have to be decoded + first, but the decoder must be ready to provide a palette, + which means device_missing_dependencies must be thrown if + the decoder has not already started tile_get_info = callback function which accepts a memory index and in return fills in a tile_data structure that describes @@ -444,11 +448,12 @@ struct tile_data UINT8 flags; // defaults to 0; one or more of TILE_* flags above UINT8 pen_mask; // defaults to 0xff; mask to apply to pen_data while rendering the tile UINT8 gfxnum; // defaults to 0xff; specify index of gfx for auto-invalidation on dirty + UINT32 code; void set(int _gfxnum, int rawcode, int rawcolor, int _flags) { gfx_element *gfx = decoder->gfx(_gfxnum); - int code = rawcode % gfx->elements(); + code = rawcode % gfx->elements(); pen_data = gfx->get_data(code); palette_base = gfx->colorbase() + gfx->granularity() * (rawcolor % gfx->colors()); flags = _flags; @@ -498,10 +503,16 @@ public: running_machine &machine() const; tilemap_device *device() const { return m_device; } palette_device &palette() const { return *m_palette; } + device_gfx_interface &decoder() const { return *m_tileinfo.decoder; } + tilemap_t *next() const { return m_next; } void *user_data() const { return m_user_data; } memory_array &basemem() { return m_basemem; } memory_array &extmem() { return m_extmem; } + UINT32 rows() const { return m_rows; } + UINT32 cols() const { return m_cols; } + UINT32 tilewidth() const { return m_tilewidth; } + UINT32 tileheight() const { return m_tileheight; } UINT32 width() const { return m_width; } UINT32 height() const { return m_height; } bool enabled() const { return m_enable; } @@ -514,6 +525,7 @@ public: bitmap_ind8 &flagsmap() { pixmap_update(); return m_flagsmap; } UINT8 *tile_flags() { pixmap_update(); return &m_tileflags[0]; } tilemap_memory_index memory_index(UINT32 col, UINT32 row) { return m_mapper(col, row, m_cols, m_rows); } + void get_info_debug(UINT32 col, UINT32 row, int &gfxnum, int &code, int &color); // setters void enable(bool enable = true) { m_enable = enable; } diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp index 5c7f4a54a39..85374c14c64 100644 --- a/src/frontend/mame/ui/ui.cpp +++ b/src/frontend/mame/ui/ui.cpp @@ -754,7 +754,8 @@ void mame_ui_manager::show_mouse(bool status) bool mame_ui_manager::is_menu_active(void) { - return m_handler_callback_type == ui_callback_type::MENU; + return m_handler_callback_type == ui_callback_type::MENU + || m_handler_callback_type == ui_callback_type::VIEWER; } @@ -1155,7 +1156,7 @@ UINT32 mame_ui_manager::handler_ingame(render_container &container) if (!is_paused) machine().pause(); using namespace std::placeholders; - set_handler(ui_callback_type::GENERAL, std::bind(&ui_gfx_ui_handler, _1, std::ref(*this), is_paused)); + set_handler(ui_callback_type::VIEWER, std::bind(&ui_gfx_ui_handler, _1, std::ref(*this), is_paused)); return is_paused ? 1 : 0; } diff --git a/src/frontend/mame/ui/ui.h b/src/frontend/mame/ui/ui.h index 3baa5db61c2..03f32496e1a 100644 --- a/src/frontend/mame/ui/ui.h +++ b/src/frontend/mame/ui/ui.h @@ -135,7 +135,8 @@ enum class ui_callback_type { GENERAL, MODAL, - MENU + MENU, + VIEWER }; // ======================> mame_ui_manager diff --git a/src/frontend/mame/ui/viewgfx.cpp b/src/frontend/mame/ui/viewgfx.cpp index f299cacd3cf..8dc9bd331a8 100644 --- a/src/frontend/mame/ui/viewgfx.cpp +++ b/src/frontend/mame/ui/viewgfx.cpp @@ -387,8 +387,8 @@ static void palette_handler(mame_ui_manager &mui, render_container &container, u // if the mouse pointer is over one of our cells, add some info about the corresponding palette entry INT32 mouse_target_x, mouse_target_y; - bool mouse_button; 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) && cellboxbounds.x0 <= mouse_x && cellboxbounds.x1 > mouse_x @@ -661,12 +661,49 @@ static void gfxset_handler(mame_ui_manager &mui, render_container &container, ui boxbounds.y0 = (1.0f - fullheight) * 0.5f; boxbounds.y1 = boxbounds.y0 + fullheight; - // figure out the title and expand the outer box to fit - const std::string title = string_format("'%s' %d/%d %dx%d COLOR %X", - interface.device().tag(), - set, info.setcount - 1, - gfx.width(), gfx.height(), - info.color[set]); + // recompute cellboxbounds + cellboxbounds.x0 = boxbounds.x0 + 6.0f * chwidth; + cellboxbounds.x1 = cellboxbounds.x0 + (float)cellboxwidth / (float)targwidth; + cellboxbounds.y0 = boxbounds.y0 + 3.5f * chheight; + cellboxbounds.y1 = cellboxbounds.y0 + (float)cellboxheight / (float)targheight; + + // figure out the title + std::ostringstream title_buf; + util::stream_format(title_buf, "'%s' %d/%d", interface.device().tag(), set, info.setcount - 1); + + // if the mouse pointer is over a pixel in a tile, add some info about the tile and pixel + bool found_pixel = false; + INT32 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) + && cellboxbounds.x0 <= mouse_x && cellboxbounds.x1 > mouse_x + && cellboxbounds.y0 <= mouse_y && cellboxbounds.y1 > mouse_y) + { + int code = info.offset[set] + int((mouse_x - cellboxbounds.x0) / cellwidth) + int((mouse_y - cellboxbounds.y0) / cellheight) * xcells; + int xpixel = int((mouse_x - cellboxbounds.x0) / (cellwidth / cellxpix)) % cellxpix; + int ypixel = int((mouse_y - cellboxbounds.y0) / (cellheight / cellypix)) % cellypix; + if (code < gfx.elements() && xpixel < (cellxpix - 1) && ypixel < (cellypix - 1)) + { + found_pixel = true; + if (info.rotate[set] & ORIENTATION_FLIP_X) + xpixel = (cellxpix - 2) - xpixel; + if (info.rotate[set] & ORIENTATION_FLIP_Y) + ypixel = (cellypix - 2) - ypixel; + if (info.rotate[set] & ORIENTATION_SWAP_XY) + std::swap(xpixel, ypixel); + UINT8 pixdata = gfx.get_data(code)[xpixel + ypixel * gfx.rowbytes()]; + util::stream_format(title_buf, " #%X:%X @ %d,%d = %X", + code, info.color[set], xpixel, ypixel, + gfx.colorbase() + info.color[set] * gfx.granularity() + pixdata); + } + } + if (!found_pixel) + util::stream_format(title_buf, " %dx%d COLOR %X/%X", gfx.width(), gfx.height(), info.color[set], gfx.colors()); + + // 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()); x0 = 0.0f; if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth) @@ -727,9 +764,7 @@ static void gfxset_handler(mame_ui_manager &mui, render_container &container, ui gfxset_update_bitmap(mui.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, + container.add_quad(cellboxbounds.x0, cellboxbounds.y0, cellboxbounds.x1, cellboxbounds.y1, rgb_t::white, state.texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); // handle keyboard navigation before drawing @@ -943,12 +978,11 @@ static void gfxset_draw_item(running_machine &machine, gfx_element &gfx, int ind } else { - int temp; if (rotate & ORIENTATION_FLIP_X) effx = gfx.height() - 1 - effx; if (rotate & ORIENTATION_FLIP_Y) effy = gfx.width() - 1 - effy; - temp = effx; effx = effy; effy = temp; + std::swap(effx, effy); } // get a pointer to the start of this source row @@ -982,15 +1016,13 @@ static void tilemap_handler(mame_ui_manager &mui, render_container &container, u float titlewidth; float x0, y0; int mapboxwidth, mapboxheight; - int maxxscale, maxyscale; - UINT32 mapwidth, mapheight; // get the size of the tilemap itself tilemap_t *tilemap = mui.machine().tilemap().find(state.tilemap.which); - mapwidth = tilemap->width(); - mapheight = tilemap->height(); + UINT32 mapwidth = tilemap->width(); + UINT32 mapheight = tilemap->height(); if (state.tilemap.rotate & ORIENTATION_SWAP_XY) - { UINT32 temp = mapwidth; mapwidth = mapheight; mapheight = temp; } + std::swap(mapwidth, mapheight); // add a half character padding for the box chheight = mui.get_line_height(); @@ -1018,6 +1050,7 @@ static void tilemap_handler(mame_ui_manager &mui, render_container &container, u 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); @@ -1039,8 +1072,40 @@ static void tilemap_handler(mame_ui_manager &mui, render_container &container, u 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 - const std::string title = string_format("TILEMAP %d/%d %dx%d OFFS %d,%d", state.tilemap.which, mui.machine().tilemap().count() - 1, mapwidth, mapheight, state.tilemap.xoffs, state.tilemap.yoffs); + // figure out the title + std::ostringstream title_buf; + util::stream_format(title_buf, "TILEMAP %d/%d", state.tilemap.which, mui.machine().tilemap().count() - 1); + + // if the mouse pointer is over a tile, add some info about its coordinates and color + INT32 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); + int col = ((xpixel / pixelscale + state.tilemap.xoffs) / tilemap->tilewidth()) % tilemap->cols(); + int row = ((ypixel / pixelscale + state.tilemap.yoffs) / tilemap->tileheight()) % tilemap->rows(); + int gfxnum, 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(), + gfxnum, code, color); + } + else + util::stream_format(title_buf, " %dx%d OFFS %d,%d", tilemap->width(), tilemap->height(), state.tilemap.xoffs, state.tilemap.yoffs); + + // 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) { @@ -1081,9 +1146,6 @@ static void tilemap_handler(mame_ui_manager &mui, render_container &container, u static void tilemap_handle_keys(running_machine &machine, ui_gfx_state &state, int viswidth, int visheight) { - UINT32 mapwidth, mapheight; - int step; - // handle tilemap selection (open bracket,close bracket) if (machine.ui_input().pressed(IPT_UI_PREV_GROUP) && state.tilemap.which > 0) { state.tilemap.which--; state.bitmap_dirty = true; } @@ -1092,8 +1154,8 @@ static void tilemap_handle_keys(running_machine &machine, ui_gfx_state &state, i // cache some info in locals tilemap_t *tilemap = machine.tilemap().find(state.tilemap.which); - mapwidth = tilemap->width(); - mapheight = tilemap->height(); + UINT32 mapwidth = tilemap->width(); + UINT32 mapheight = tilemap->height(); // handle zoom (minus,plus) if (machine.ui_input().pressed(IPT_UI_ZOOM_OUT) && state.tilemap.zoom > 0) @@ -1127,18 +1189,42 @@ static void tilemap_handle_keys(running_machine &machine, ui_gfx_state &state, i state.bitmap_dirty = true; } - // handle navigation (up,down,left,right) - step = 8; + // handle navigation (up,down,left,right), taking orientation into account + int step = 8; // this may be applied more than once if multiple directions are pressed if (machine.input().code_pressed(KEYCODE_LSHIFT)) step = 1; if (machine.input().code_pressed(KEYCODE_LCONTROL)) step = 64; if (machine.ui_input().pressed_repeat(IPT_UI_UP, 4)) - { state.tilemap.yoffs -= step; state.bitmap_dirty = true; } + { + if (state.tilemap.rotate & ORIENTATION_SWAP_XY) + state.tilemap.xoffs -= (state.tilemap.rotate & ORIENTATION_FLIP_Y) ? -step : step; + else + state.tilemap.yoffs -= (state.tilemap.rotate & ORIENTATION_FLIP_Y) ? -step : step; + state.bitmap_dirty = true; + } if (machine.ui_input().pressed_repeat(IPT_UI_DOWN, 4)) - { state.tilemap.yoffs += step; state.bitmap_dirty = true; } + { + if (state.tilemap.rotate & ORIENTATION_SWAP_XY) + state.tilemap.xoffs += (state.tilemap.rotate & ORIENTATION_FLIP_Y) ? -step : step; + else + state.tilemap.yoffs += (state.tilemap.rotate & ORIENTATION_FLIP_Y) ? -step : step; + state.bitmap_dirty = true; + } if (machine.ui_input().pressed_repeat(IPT_UI_LEFT, 6)) - { state.tilemap.xoffs -= step; state.bitmap_dirty = true; } + { + if (state.tilemap.rotate & ORIENTATION_SWAP_XY) + state.tilemap.yoffs -= (state.tilemap.rotate & ORIENTATION_FLIP_X) ? -step : step; + else + state.tilemap.xoffs -= (state.tilemap.rotate & ORIENTATION_FLIP_X) ? -step : step; + state.bitmap_dirty = true; + } if (machine.ui_input().pressed_repeat(IPT_UI_RIGHT, 6)) - { state.tilemap.xoffs += step; state.bitmap_dirty = true; } + { + if (state.tilemap.rotate & ORIENTATION_SWAP_XY) + state.tilemap.yoffs += (state.tilemap.rotate & ORIENTATION_FLIP_X) ? -step : step; + else + state.tilemap.xoffs += (state.tilemap.rotate & ORIENTATION_FLIP_X) ? -step : step; + state.bitmap_dirty = true; + } // clamp within range while (state.tilemap.xoffs < 0) @@ -1161,7 +1247,7 @@ static void tilemap_update_bitmap(running_machine &machine, ui_gfx_state &state, { // swap the coordinates back if they were talking about a rotated surface if (state.tilemap.rotate & ORIENTATION_SWAP_XY) - { UINT32 temp = width; width = height; height = temp; } + std::swap(width, height); // realloc the bitmap if it is too small if (state.bitmap == nullptr || state.texture == nullptr || state.bitmap->width() != width || state.bitmap->height() != height) |