UI updates:

* Re-wrote localisation loader: sanitise input, check for buffer overruns, fix endianness handling, keep data in a single allocated block, do a single hash lookup when fetching a string, print diagnostic output when things go wrong
* Sort UI language menu so it's not in whatever random order the filesystem yields
* Fixed most menu code to adjust L/R border for UI aspect ratio and pass container to render manager when getting UI aspect ratio
* Converted a couple more things to use smart pointers
This commit is contained in:
Vas Crabb 2019-11-22 17:53:31 +11:00
parent aefe95ecd9
commit 09746dfedd
11 changed files with 355 additions and 237 deletions

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:Miodrag Milanovic
// copyright-holders:Vas Crabb
/***************************************************************************
language.cpp
@ -11,69 +11,165 @@
#include "emu.h"
#include "emuopts.h"
static std::unordered_map<std::string, std::string> g_translation;
#include <cstring>
#include <memory>
#include <new>
#include <unordered_map>
const char *lang_translate(const char *word)
namespace {
constexpr uint32_t MO_MAGIC = 0x950412de;
constexpr uint32_t MO_MAGIC_REVERSED = 0xde120495;
struct cstr_hash
{
if (g_translation.find(word) == g_translation.end())
size_t operator()(char const *s) const noexcept
{
return word;
// Bernstein string hash
size_t result(5381);
while (*s)
result = ((result << 5) + result) + u8(*s++);
return result;
}
return g_translation[word].c_str();
};
struct cstr_compare
{
size_t operator()(char const *x, char const *y) const noexcept
{
return !std::strcmp(x, y);
}
};
std::unique_ptr<u32 []> f_translation_data;
std::unordered_map<char const *, char const *, cstr_hash, cstr_compare> f_translation_map;
} // anonymous namespace
char const *lang_translate(char const *word)
{
auto const found = f_translation_map.find(word);
return (f_translation_map.end() != found) ? found->second : word;
}
const uint32_t MO_MAGIC = 0x950412de;
const uint32_t MO_MAGIC_REVERSED = 0xde120495;
inline uint32_t endianchange(uint32_t value) {
uint32_t b0 = (value >> 0) & 0xff;
uint32_t b1 = (value >> 8) & 0xff;
uint32_t b2 = (value >> 16) & 0xff;
uint32_t b3 = (value >> 24) & 0xff;
return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
}
void load_translation(emu_options &m_options)
{
g_translation.clear();
f_translation_data.reset();
f_translation_map.clear();
emu_file file(m_options.language_path(), OPEN_FLAG_READ);
auto name = std::string(m_options.language());
std::string name = m_options.language();
strreplace(name, " ", "_");
strreplace(name, "(", "");
strreplace(name, ")", "");
if (file.open(name.c_str(), PATH_SEPARATOR "strings.mo") == osd_file::error::NONE)
if (file.open(name.c_str(), PATH_SEPARATOR "strings.mo") != osd_file::error::NONE)
{
uint64_t size = file.size();
uint32_t *buffer = global_alloc_array(uint32_t, size / 4 + 1);
file.read(buffer, size);
file.close();
if (buffer[0] != MO_MAGIC && buffer[0] != MO_MAGIC_REVERSED)
{
global_free_array(buffer);
return;
}
if (buffer[0] == MO_MAGIC_REVERSED)
{
for (auto i = 0; i < (size / 4) + 1; ++i)
{
buffer[i] = endianchange(buffer[i]);
}
}
uint32_t number_of_strings = buffer[2];
uint32_t original_table_offset = buffer[3] >> 2;
uint32_t translation_table_offset = buffer[4] >> 2;
const char *data = reinterpret_cast<const char*>(buffer);
for (auto i = 1; i < number_of_strings; ++i)
{
std::string original = (const char *)data + buffer[original_table_offset + 2 * i + 1];
std::string translation = (const char *)data + buffer[translation_table_offset + 2 * i + 1];
g_translation.emplace(std::move(original), std::move(translation));
}
global_free_array(buffer);
osd_printf_error("Error opening translation file %s\n", name);
return;
}
u64 const size = file.size();
if (20 > size)
{
file.close();
osd_printf_error("Error reading translation file %s: %u-byte file is too small to contain translation data\n", name, size);
return;
}
f_translation_data.reset(new (std::nothrow) uint32_t [(size + 3) / 4]);
if (!f_translation_data)
{
file.close();
osd_printf_error("Failed to allocate %u bytes to load translation data file %s\n", size, name);
return;
}
auto const read = file.read(f_translation_data.get(), size);
file.close();
if (read != size)
{
osd_printf_error("Error reading translation file %s: requested %u bytes but got %u bytes\n", name, size, read);
f_translation_data.reset();
return;
}
if ((f_translation_data[0] != MO_MAGIC) && (f_translation_data[0] != MO_MAGIC_REVERSED))
{
osd_printf_error("Error reading translation file %s: unrecognized magic number 0x%08X\n", name, f_translation_data[0]);
f_translation_data.reset();
return;
}
auto fetch_word =
[reversed = f_translation_data[0] == MO_MAGIC_REVERSED, words = f_translation_data.get()] (size_t offset)
{
return reversed ? swapendian_int32(words[offset]) : words[offset];
};
// FIXME: check major/minor version number
if ((fetch_word(3) % 4) || (fetch_word(4) % 4))
{
osd_printf_error("Error reading translation file %s: table offsets %u and %u are not word-aligned\n", name, fetch_word(3), fetch_word(4));
f_translation_data.reset();
return;
}
u32 const number_of_strings = fetch_word(2);
u32 const original_table_offset = fetch_word(3) >> 2;
u32 const translation_table_offset = fetch_word(4) >> 2;
if ((4 * (original_table_offset + (u64(number_of_strings) * 2))) > size)
{
osd_printf_error("Error reading translation file %s: %u-entry original string table at offset %u extends past end of %u-byte file\n", name, number_of_strings, fetch_word(3), size);
f_translation_data.reset();
return;
}
if ((4 * (translation_table_offset + (u64(number_of_strings) * 2))) > size)
{
osd_printf_error("Error reading translation file %s: %u-entry translated string table at offset %u extends past end of %u-byte file\n", name, number_of_strings, fetch_word(4), size);
f_translation_data.reset();
return;
}
osd_printf_verbose("Reading translation file %s: %u strings, original table at word offset %u, translated table at word offset %u\n", name, number_of_strings, original_table_offset, translation_table_offset);
char const *const data = reinterpret_cast<char const *>(f_translation_data.get());
for (u32 i = 1; number_of_strings > i; ++i)
{
u32 const original_length = fetch_word(original_table_offset + (2 * i));
u32 const original_offset = fetch_word(original_table_offset + (2 * i) + 1);
if ((original_length + original_offset) >= size)
{
osd_printf_error("Error reading translation file %s: %u-byte original string %u at offset %u extends past end of %u-byte file\n", name, original_length, i, original_offset, size);
continue;
}
if (data[original_length + original_offset])
{
osd_printf_error("Error reading translation file %s: %u-byte original string %u at offset %u is not correctly NUL-terminated\n", name, original_length, i, original_offset);
continue;
}
u32 const translation_length = fetch_word(translation_table_offset + (2 * i));
u32 const translation_offset = fetch_word(translation_table_offset + (2 * i) + 1);
if ((translation_length + translation_offset) >= size)
{
osd_printf_error("Error reading translation file %s: %u-byte translated string %u at offset %u extends past end of %u-byte file\n", name, translation_length, i, translation_offset, size);
continue;
}
if (data[translation_length + translation_offset])
{
osd_printf_error("Error reading translation file %s: %u-byte translated string %u at offset %u is not correctly NUL-terminated\n", name, translation_length, i, translation_offset);
continue;
}
char const *const original = &data[original_offset];
char const *const translation = &data[translation_offset];
auto const ins = f_translation_map.emplace(original, translation);
if (!ins.second)
osd_printf_warning("Loading translation file %s: translation %u '%s'='%s' conflicts with previous translation '%s'='%s'\n", name, i, original, translation, ins.first->first, ins.first->second);
}
osd_printf_verbose("Loaded %u translations from file %s\n", f_translation_map.size(), name);
}

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:Miodrag Milanovic
// copyright-holders:Vas Crabb
/***************************************************************************
language.h
@ -12,10 +12,6 @@
#pragma once
#ifndef __EMU_H__
#error Dont include this file directly; include emu.h instead.
#endif
//**************************************************************************
// LOCALIZATION SUPPORT
//**************************************************************************

View File

@ -22,6 +22,7 @@
#include "uiinput.h"
#include <algorithm>
#include <iterator>
#include <utility>
@ -43,22 +44,27 @@ menu_custom_ui::menu_custom_ui(mame_ui_manager &mui, render_container &container
{
// load languages
file_enumerator path(mui.machine().options().language_path());
auto lang = mui.machine().options().language();
const char *const lang = mui.machine().options().language();
const osd::directory::entry *dirent;
std::size_t cnt = 0;
std::string name;
while ((dirent = path.next()))
{
if (dirent->type == osd::directory::entry::entry_type::DIR && strcmp(dirent->name, ".") != 0 && strcmp(dirent->name, "..") != 0)
{
auto name = std::string(dirent->name);
name = dirent->name;
auto i = strreplace(name, "_", " (");
if (i > 0) name = name.append(")");
m_lang.push_back(name);
if (strcmp(name.c_str(), lang) == 0)
m_currlang = cnt;
++cnt;
if (i > 0)
name.append(")");
m_lang.emplace_back(std::move(name));
}
}
std::sort(
m_lang.begin(),
m_lang.end(),
[] (const std::string &x, const std::string &y) { return 0 > core_stricmp(x.c_str(), y.c_str()); });
const auto found = std::lower_bound(m_lang.begin(), m_lang.end(), lang, [] (std::string const &x, const char *y) { return 0 > core_stricmp(x.c_str(), y); });
if ((m_lang.end() != found) && !core_stricmp(found->c_str(), lang))
m_currlang = std::distance(m_lang.begin(), found);
}
//-------------------------------------------------
@ -527,10 +533,11 @@ void menu_colors_ui::custom_render(void *selectedref, float top, float bottom, f
// compute maxwidth
char const *const topbuf = _("Menu Preview");
const float lr_border = ui().box_lr_border() * machine().render().ui_aspect(&container());
float width;
ui().draw_text_full(container(), topbuf, 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::NEVER,
mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width, nullptr);
float maxwidth = width + 2.0f * ui().box_lr_border();
float maxwidth = width + 2.0f * lr_border;
std::string sampletxt[5];
@ -544,12 +551,12 @@ void menu_colors_ui::custom_render(void *selectedref, float top, float bottom, f
{
ui().draw_text_full(container(), elem.c_str(), 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::NEVER,
mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width, nullptr);
width += 2 * ui().box_lr_border();
width += 2 * lr_border;
maxwidth = std::max(maxwidth, width);
}
// compute our bounds for header
float x1 = origx2 + 2.0f * ui().box_lr_border();
float x1 = origx2 + 2.0f * lr_border;
float x2 = x1 + maxwidth;
float y1 = origy1;
float y2 = y1 + bottom - ui().box_tb_border();
@ -558,8 +565,8 @@ void menu_colors_ui::custom_render(void *selectedref, float top, float bottom, f
ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_GREEN_COLOR);
// take off the borders
x1 += ui().box_lr_border();
x2 -= ui().box_lr_border();
x1 += lr_border;
x2 -= lr_border;
y1 += ui().box_tb_border();
y2 -= ui().box_tb_border();
@ -569,8 +576,8 @@ void menu_colors_ui::custom_render(void *selectedref, float top, float bottom, f
// compute our bounds for menu preview
float line_height = ui().get_line_height();
x1 -= ui().box_lr_border();
x2 += ui().box_lr_border();
x1 -= lr_border;
x2 += lr_border;
y1 = y2 + 2.0f * ui().box_tb_border();
y2 = y1 + 5.0f * line_height + 2.0f * ui().box_tb_border();
@ -578,8 +585,8 @@ void menu_colors_ui::custom_render(void *selectedref, float top, float bottom, f
ui().draw_outlined_box(container(), x1, y1, x2, y2, m_color_table[MUI_BACKGROUND_COLOR].color);
// take off the borders
x1 += ui().box_lr_border();
x2 -= ui().box_lr_border();
x1 += lr_border;
x2 -= lr_border;
y1 += ui().box_tb_border();
// draw normal text
@ -819,7 +826,8 @@ void menu_rgb_ui::custom_render(void *selectedref, float top, float bottom, floa
// top text
ui().draw_text_full(container(), m_title.c_str(), 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::NEVER,
mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width);
width += 2 * ui().box_lr_border();
const float lr_border = ui().box_lr_border() * machine().render().ui_aspect(&container());
width += 2 * lr_border;
maxwidth = std::max(maxwidth, width);
// compute our bounds
@ -832,8 +840,8 @@ void menu_rgb_ui::custom_render(void *selectedref, float top, float bottom, floa
ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_GREEN_COLOR);
// take off the borders
x1 += ui().box_lr_border();
x2 -= ui().box_lr_border();
x1 += lr_border;
x2 -= lr_border;
y1 += ui().box_tb_border();
// draw the text within it
@ -843,7 +851,7 @@ void menu_rgb_ui::custom_render(void *selectedref, float top, float bottom, floa
std::string sampletxt(_("Color preview ="));
ui().draw_text_full(container(), sampletxt.c_str(), 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::NEVER,
mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width);
width += 2 * ui().box_lr_border();
width += 2 * lr_border;
maxwidth = std::max(origx2 - origx1, width);
// compute our bounds
@ -856,14 +864,14 @@ void menu_rgb_ui::custom_render(void *selectedref, float top, float bottom, floa
ui().draw_outlined_box(container(), x1, y1, x1 + width, y2, UI_RED_COLOR);
// take off the borders
x1 += ui().box_lr_border();
x1 += lr_border;
y1 += ui().box_tb_border();
// draw the normal text
ui().draw_text_full(container(), sampletxt.c_str(), x1, y1, width - ui().box_lr_border(), ui::text_layout::CENTER, ui::text_layout::NEVER,
ui().draw_text_full(container(), sampletxt.c_str(), x1, y1, width - lr_border, ui::text_layout::CENTER, ui::text_layout::NEVER,
mame_ui_manager::NORMAL, rgb_t::white(), rgb_t::black());
x1 += width + ui().box_lr_border();
x1 += width + lr_border;
y1 -= ui().box_tb_border();
// draw color box

View File

@ -149,10 +149,11 @@ void menu_dats_view::populate(float &customtop, float &custombottom)
void menu_dats_view::draw(uint32_t flags)
{
float const aspect = machine().render().ui_aspect(&container());
float const line_height = ui().get_line_height();
float const ud_arrow_width = line_height * machine().render().ui_aspect();
float const gutter_width = 0.52f * line_height * machine().render().ui_aspect();
float const visible_width = 1.0f - (2.0f * ui().box_lr_border());
float const ud_arrow_width = line_height * aspect;
float const gutter_width = 0.52f * line_height * aspect;
float const visible_width = 1.0f - (2.0f * ui().box_lr_border() * aspect);
float const visible_left = (1.0f - visible_width) * 0.5f;
float const extra_height = 2.0f * line_height;
float const visible_extra_menu_height = get_customtop() + get_custombottom() + extra_height;
@ -191,7 +192,7 @@ void menu_dats_view::draw(uint32_t flags)
int const n_loop = (std::min)(visible_items, m_visible_lines);
for (int linenum = 0; linenum < n_loop; linenum++)
{
float const line_y = visible_top + (float)linenum * line_height;
float const line_y = visible_top + float(linenum) * line_height;
int const itemnum = top_line + linenum;
menu_item const &pitem = item(itemnum);
char const *const itemtext = pitem.text.c_str();
@ -295,9 +296,10 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
float width;
std::string driver = (m_issoft == true) ? m_swinfo->longname : m_driver->type.fullname();
float const lr_border = ui().box_lr_border() * machine().render().ui_aspect(&container());
ui().draw_text_full(container(), driver.c_str(), 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width, nullptr);
width += 2 * ui().box_lr_border();
width += 2 * lr_border;
maxwidth = std::max(maxwidth, width);
// compute our bounds
@ -310,8 +312,8 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_GREEN_COLOR);
// take off the borders
x1 += ui().box_lr_border();
x2 -= ui().box_lr_border();
x1 += lr_border;
x2 -= lr_border;
y1 += ui().box_tb_border();
ui().draw_text_full(container(), driver.c_str(), x1, y1, x2 - x1, ui::text_layout::CENTER, ui::text_layout::NEVER,
@ -328,8 +330,8 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
float space = (1.0f - maxwidth) / (m_items_list.size() * 2);
// compute our bounds
x1 -= ui().box_lr_border();
x2 += ui().box_lr_border();
x1 -= lr_border;
x2 += lr_border;
y1 = y2 + ui().box_tb_border();
y2 += ui().get_line_height() + 2.0f * ui().box_tb_border();
@ -361,7 +363,7 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
std::string revision;
revision.assign(_("Revision: ")).append(m_items_list[m_actual].revision);
ui().draw_text_full(container(), revision.c_str(), 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::TRUNCATE, mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width, nullptr);
width += 2 * ui().box_lr_border();
width += 2 * lr_border;
maxwidth = std::max(origx2 - origx1, width);
// compute our bounds
@ -374,8 +376,8 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_GREEN_COLOR);
// take off the borders
x1 += ui().box_lr_border();
x2 -= ui().box_lr_border();
x1 += lr_border;
x2 -= lr_border;
y1 += ui().box_tb_border();
// draw the text within it
@ -393,9 +395,10 @@ void menu_dats_view::get_data()
std::string buffer;
mame_machine_manager::instance()->lua()->call_plugin("data", m_items_list[m_actual].option, buffer);
float const aspect = machine().render().ui_aspect(&container());
float const line_height = ui().get_line_height();
float const gutter_width = 0.52f * line_height * machine().render().ui_aspect();
float const visible_width = 1.0f - (2.0f * ui().box_lr_border());
float const gutter_width = 0.52f * line_height * aspect;
float const visible_width = 1.0f - (2.0f * ui().box_lr_border() * aspect);
float const effective_width = visible_width - 2.0f * gutter_width;
auto lines = ui().wrap_text(container(), buffer.c_str(), 0.0f, 0.0f, effective_width, xstart, xend);
@ -417,7 +420,7 @@ void menu_dats_view::get_data_sw()
else
mame_machine_manager::instance()->lua()->call_plugin("data", m_items_list[m_actual].option - 1, buffer);
auto lines = ui().wrap_text(container(), buffer.c_str(), 0.0f, 0.0f, 1.0f - (4.0f * ui().box_lr_border()), xstart, xend);
auto lines = ui().wrap_text(container(), buffer.c_str(), 0.0f, 0.0f, 1.0f - (4.0f * ui().box_lr_border() * machine().render().ui_aspect(&container())), xstart, xend);
for (int x = 0; x < lines; ++x)
{
std::string tempbuf(buffer.substr(xstart[x], xend[x] - xstart[x]));

View File

@ -86,7 +86,7 @@ void menu_file_selector::custom_render(void *selectedref, float top, float botto
ui().draw_outlined_box(container(), x1, y1, x2, y2, ui().colors().background_color());
// take off the borders
x1 += ui().box_lr_border();
x1 += ui().box_lr_border() * machine().render().ui_aspect(&container());
y1 += ui().box_tb_border();
size_t hit_start = 0, hit_span = 0;

View File

@ -16,48 +16,49 @@
namespace ui {
/***************************************************************************
IMPLEMENTATION
***************************************************************************/
menu_control_floppy_image::menu_control_floppy_image(mame_ui_manager &mui, render_container &container, device_image_interface &image) : menu_control_device_image(mui, container, image)
menu_control_floppy_image::menu_control_floppy_image(mame_ui_manager &mui, render_container &container, device_image_interface &image) :
menu_control_device_image(mui, container, image),
fd(dynamic_cast<floppy_image_device &>(image)),
input_format(nullptr),
output_format(nullptr),
input_filename(),
output_filename()
{
floppy_image_device *fd = static_cast<floppy_image_device *>(&m_image);
const floppy_image_format_t *fif_list = fd->get_formats();
int fcnt = 0;
for(const floppy_image_format_t *i = fif_list; i; i = i->next)
for(const floppy_image_format_t *i = fd.get_formats(); i; i = i->next)
fcnt++;
format_array = global_alloc_array(floppy_image_format_t *, fcnt);
input_format = output_format = nullptr;
input_filename = output_filename = "";
format_array = std::make_unique<floppy_image_format_t * []>(fcnt);
}
menu_control_floppy_image::~menu_control_floppy_image()
{
global_free_array(format_array);
}
void menu_control_floppy_image::do_load_create()
{
floppy_image_device *fd = static_cast<floppy_image_device *>(&m_image);
if(input_filename.compare("")==0) {
image_init_result err = fd->create(output_filename, nullptr, nullptr);
image_init_result err = fd.create(output_filename, nullptr, nullptr);
if (err != image_init_result::PASS) {
machine().popmessage("Error: %s", fd->error());
machine().popmessage("Error: %s", fd.error());
return;
}
} else {
image_init_result err = fd->load(input_filename);
image_init_result err = fd.load(input_filename);
if ((err == image_init_result::PASS) && (output_filename.compare("") != 0))
err = fd->reopen_for_write(output_filename) ? image_init_result::FAIL : image_init_result::PASS;
err = fd.reopen_for_write(output_filename) ? image_init_result::FAIL : image_init_result::PASS;
if (err != image_init_result::PASS) {
machine().popmessage("Error: %s", fd->error());
machine().popmessage("Error: %s", fd.error());
return;
}
}
if(output_format)
fd->setup_write(output_format);
fd.setup_write(output_format);
}
void menu_control_floppy_image::hook_load(const std::string &filename)
@ -91,10 +92,9 @@ void menu_control_floppy_image::hook_load(const std::string &filename)
void menu_control_floppy_image::handle()
{
floppy_image_device *fd = static_cast<floppy_image_device *>(&m_image);
switch (m_state) {
case DO_CREATE: {
floppy_image_format_t *fif_list = fd->get_formats();
floppy_image_format_t *fif_list = fd.get_formats();
int ext_match;
int total_usable = 0;
for(floppy_image_format_t *i = fif_list; i; i = i->next) {
@ -111,7 +111,7 @@ void menu_control_floppy_image::handle()
format_array[total_usable++] = i;
}
m_submenu_result.i = -1;
menu::stack_push<menu_select_format>(ui(), container(), format_array, ext_match, total_usable, &m_submenu_result.i);
menu::stack_push<menu_select_format>(ui(), container(), format_array.get(), ext_match, total_usable, &m_submenu_result.i);
m_state = SELECT_FORMAT;
break;
@ -133,7 +133,7 @@ void menu_control_floppy_image::handle()
switch(m_submenu_result.rw) {
case menu_select_rw::result::READONLY:
do_load_create();
fd->setup_write(nullptr);
fd.setup_write(nullptr);
stack_pop();
break;

View File

@ -5,18 +5,21 @@
ui/floppycntrl.h
***************************************************************************/
#pragma once
#ifndef MAME_FRONTEND_UI_FLOPPYCNTRL_H
#define MAME_FRONTEND_UI_FLOPPYCNTRL_H
#pragma once
#include "ui/imgcntrl.h"
#include "imagedev/floppy.h"
#include "formats/flopimg.h"
#include <memory>
namespace ui {
class menu_control_floppy_image : public menu_control_device_image
{
public:
@ -26,7 +29,8 @@ public:
private:
enum { SELECT_FORMAT = LAST_ID, SELECT_MEDIA, SELECT_RW };
floppy_image_format_t **format_array;
floppy_image_device &fd;
std::unique_ptr<floppy_image_format_t * []> format_array;
floppy_image_format_t *input_format, *output_format;
std::string input_filename, output_filename;

View File

@ -510,10 +510,12 @@ void menu::draw(uint32_t flags)
bool const customonly = (flags & PROCESS_CUSTOM_ONLY);
bool const noimage = (flags & PROCESS_NOIMAGE);
bool const noinput = (flags & PROCESS_NOINPUT);
float const aspect = machine().render().ui_aspect(&container());
float const line_height = ui().get_line_height();
float const lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
float const ud_arrow_width = line_height * machine().render().ui_aspect();
float const lr_arrow_width = 0.4f * line_height * aspect;
float const ud_arrow_width = line_height * aspect;
float const gutter_width = lr_arrow_width * 1.3f;
float const lr_border = ui().box_lr_border() * aspect;
if (&machine().system() == &GAME_NAME(___empty) && !noimage)
draw_background();
@ -546,8 +548,8 @@ void menu::draw(uint32_t flags)
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 (visible_width + 2.0f * lr_border > 1.0f)
visible_width = 1.0f - 2.0f * 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)
@ -561,9 +563,9 @@ void menu::draw(uint32_t flags)
float const visible_top = ((1.0f - visible_main_menu_height - visible_extra_menu_height) * 0.5f) + m_customtop;
// first add us a box
float const x1 = visible_left - ui().box_lr_border();
float const x1 = visible_left - lr_border;
float const y1 = visible_top - ui().box_tb_border();
float const x2 = visible_left + visible_width + ui().box_lr_border();
float const x2 = visible_left + visible_width + lr_border;
float const y2 = visible_top + visible_main_menu_height + ui().box_tb_border();
if (!customonly)
ui().draw_outlined_box(container(), x1, y1, x2, y2, ui().colors().background_color());
@ -670,8 +672,8 @@ void menu::draw(uint32_t flags)
if (pitem.flags & FLAG_UI_HEADING)
{
float heading_width = ui().get_string_width(itemtext);
container().add_line(visible_left, line_y0 + 0.5f * line_height, visible_left + ((visible_width - heading_width) / 2) - ui().box_lr_border(), line_y0 + 0.5f * line_height, UI_LINE_WIDTH, ui().colors().border_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
container().add_line(visible_left + visible_width - ((visible_width - heading_width) / 2) + ui().box_lr_border(), line_y0 + 0.5f * line_height, visible_left + visible_width, line_y0 + 0.5f * line_height, UI_LINE_WIDTH, ui().colors().border_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
container().add_line(visible_left, line_y0 + 0.5f * line_height, visible_left + ((visible_width - heading_width) / 2) - lr_border, line_y0 + 0.5f * line_height, UI_LINE_WIDTH, ui().colors().border_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
container().add_line(visible_left + visible_width - ((visible_width - heading_width) / 2) + lr_border, line_y0 + 0.5f * line_height, visible_left + visible_width, line_y0 + 0.5f * line_height, UI_LINE_WIDTH, ui().colors().border_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
}
ui().draw_text_full(container(), itemtext, effective_left, line_y0, effective_width,
ui::text_layout::CENTER, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr);
@ -764,15 +766,15 @@ void menu::draw(uint32_t flags)
ui::text_layout::RIGHT, ui::text_layout::WORD, mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &target_width, &target_height);
// determine the target location
float const target_x = visible_left + visible_width - target_width - ui().box_lr_border();
float const target_x = visible_left + visible_width - target_width - lr_border;
float 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(),
ui().draw_outlined_box(container(), target_x - lr_border,
target_y - ui().box_tb_border(),
target_x + target_width + ui().box_lr_border(),
target_x + target_width + lr_border,
target_y + target_height + ui().box_tb_border(),
subitem_invert ? ui().colors().selected_bg_color() : ui().colors().background_color());
@ -798,14 +800,16 @@ void menu::draw_text_box()
{
const char *text = m_items[0].text.c_str();
const char *backtext = m_items[1].text.c_str();
float const aspect = machine().render().ui_aspect(&container());
float line_height = ui().get_line_height();
float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
float lr_arrow_width = 0.4f * line_height * aspect;
float gutter_width = lr_arrow_width;
float const lr_border = ui().box_lr_border() * aspect;
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,
ui().draw_text_full(container(), text, 0, 0, 1.0f - 2.0f * lr_border - 2.0f * gutter_width,
ui::text_layout::LEFT, ui::text_layout::WORD, mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &target_width, &target_height);
target_height += 2.0f * line_height;
if (target_height > 1.0f - 2.0f * ui().box_tb_border())
@ -820,19 +824,19 @@ void menu::draw_text_box()
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_x < lr_border + gutter_width)
target_x = lr_border + gutter_width;
if (target_x + target_width + gutter_width + lr_border > 1.0f)
target_x = 1.0f - 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,
ui().draw_outlined_box(container(), target_x - lr_border - gutter_width,
target_y - ui().box_tb_border(),
target_x + target_width + gutter_width + ui().box_lr_border(),
target_x + target_width + gutter_width + lr_border,
target_y + target_height + ui().box_tb_border(),
(m_items[0].flags & FLAG_REDTEXT) ? UI_RED_COLOR : ui().colors().background_color());
ui().draw_text_full(container(), text, target_x, target_y, target_width,
@ -1289,7 +1293,7 @@ void menu::extra_text_draw_box(float origx1, float origx2, float origy, float ys
ui().draw_outlined_box(container(), x1, y1, x2, y2, ui().colors().background_color());
// take off the borders
x1 += ui().box_lr_border();
x1 += ui().box_lr_border() * machine().render().ui_aspect(&container());
y1 += ui().box_tb_border();
// draw the text within it
@ -1313,7 +1317,7 @@ void menu::draw_background()
void menu::extra_text_position(float origx1, float origx2, float origy, float yspan, text_layout &layout,
int direction, float &x1, float &y1, float &x2, float &y2)
{
float width = layout.actual_width() + (2 * ui().box_lr_border());
float width = layout.actual_width() + (2 * ui().box_lr_border() * machine().render().ui_aspect(&container()));
float maxwidth = std::max(width, origx2 - origx1);
// compute our bounds

View File

@ -711,7 +711,7 @@ void menu_select_launch::custom_render(void *selectedref, float top, float botto
// is favorite? draw the star
if (isstar)
draw_star(origx1 + ui().box_lr_border(), origy2 + (2.0f * ui().box_tb_border()));
draw_star(origx1 + ui().box_lr_border() * machine().render().ui_aspect(&container()), origy2 + (2.0f * ui().box_tb_border()));
}
@ -816,7 +816,7 @@ void menu_select_launch::inkey_dats()
void menu_select_launch::draw_common_arrow(float origx1, float origy1, float origx2, float origy2, int current, int dmin, int dmax, float title_size)
{
auto line_height = ui().get_line_height();
auto lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
auto lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect(&container());
auto gutter_width = lr_arrow_width * 1.3f;
// set left-right arrows dimension
@ -927,10 +927,12 @@ float menu_select_launch::draw_left_panel(
// outline the box and inset by the border width
float const origy1(y1);
float const origy2(y2);
x2 = x1 + left_width + 2.0f * ui().box_lr_border();;
float const aspect(machine().render().ui_aspect(&container()));
float const lr_border(ui().box_lr_border() * aspect);
x2 = x1 + left_width + 2.0f * lr_border;
ui().draw_outlined_box(container(), x1, y1, x2, y2, ui().colors().background_color());
x1 += ui().box_lr_border();
x2 -= ui().box_lr_border();
x1 += lr_border;
x2 -= lr_border;
y1 += ui().box_tb_border();
y2 -= ui().box_tb_border();
@ -987,12 +989,12 @@ float menu_select_launch::draw_left_panel(
y1 += line_height_max;
}
x1 = x2 + ui().box_lr_border();
x2 = x1 + 2.0f * ui().box_lr_border();
x1 = x2 + lr_border;
x2 = x1 + 2.0f * lr_border;
y1 = origy1;
y2 = origy2;
float const space = x2 - x1;
float const lr_arrow_width = 0.4f * space * machine().render().ui_aspect();
float const lr_arrow_width = 0.4f * space * aspect;
// set left-right arrows dimension
float const ar_x0 = 0.5f * (x2 + x1) - 0.5f * lr_arrow_width;
@ -1010,7 +1012,7 @@ float menu_select_launch::draw_left_panel(
}
draw_arrow(ar_x0, ar_y0, ar_x1, ar_y1, fgcolor, ROT90 ^ ORIENTATION_FLIP_X);
return x2 + ui().box_lr_border();
return x2 + lr_border;
}
@ -1118,7 +1120,7 @@ bool menu_select_launch::scale_icon(bitmap_argb32 &&src, texture_and_bitmap &dst
{
// calculate available space for the icon in pixels
float const height(ui().get_line_height());
float const width(height * container().manager().ui_aspect());
float const width(height * container().manager().ui_aspect(&container()));
render_target const &target(machine().render().ui_target());
uint32_t const dst_height(target.height());
uint32_t const dst_width(target.width());
@ -1204,8 +1206,10 @@ void menu_select_launch::draw_toolbar(float x1, float y1, float x2, float y2)
ui().draw_outlined_box(container(), x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
// take off the borders
x1 += ui().box_lr_border();
x2 -= ui().box_lr_border();
float const aspect(machine().render().ui_aspect(&container()));
float const lr_border(ui().box_lr_border() * aspect);
x1 += lr_border;
x2 -= lr_border;
y1 += ui().box_tb_border();
y2 -= ui().box_tb_border();
@ -1214,7 +1218,7 @@ void menu_select_launch::draw_toolbar(float x1, float y1, float x2, float y2)
auto const num_valid(std::count_if(std::begin(t_bitmap), std::end(t_bitmap), [](bitmap_argb32 const &e) { return e.valid(); }));
float const space_x = (y2 - y1) * container().manager().ui_aspect(&container());
float const space_x = (y2 - y1) * aspect;
float const total = (float(num_valid) * space_x) + (float(num_valid - 1) * 0.001f);
x1 += (x2 - x1) * 0.5f - total * 0.5f;
x2 = x1 + space_x;
@ -1247,7 +1251,7 @@ void menu_select_launch::draw_toolbar(float x1, float y1, float x2, float y2)
void menu_select_launch::draw_star(float x0, float y0)
{
float y1 = y0 + ui().get_line_height();
float x1 = x0 + ui().get_line_height() * container().manager().ui_aspect();
float x1 = x0 + ui().get_line_height() * container().manager().ui_aspect(&container());
container().add_quad(x0, y0, x1, y1, rgb_t::white(), m_cache->star_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_PACKABLE);
}
@ -1814,12 +1818,14 @@ void menu_select_launch::handle_events(uint32_t flags, event &ev)
void menu_select_launch::draw(uint32_t flags)
{
bool noinput = (flags & PROCESS_NOINPUT);
float const aspect = machine().render().ui_aspect(&container());
float const lr_border = ui().box_lr_border() * aspect;
float line_height = ui().get_line_height();
float const ud_arrow_width = line_height * machine().render().ui_aspect();
float const ud_arrow_width = line_height * aspect;
float const gutter_width = 0.52f * ud_arrow_width;
float const icon_offset = m_has_icons ? (1.5f * ud_arrow_width) : 0.0f;
float right_panel_size = (ui_globals::panels_status == HIDE_BOTH || ui_globals::panels_status == HIDE_RIGHT_PANEL) ? 2.0f * ui().box_lr_border() : 0.3f;
float visible_width = 1.0f - 4.0f * ui().box_lr_border();
float right_panel_size = (ui_globals::panels_status == HIDE_BOTH || ui_globals::panels_status == HIDE_RIGHT_PANEL) ? 2.0f * lr_border : 0.3f;
float visible_width = 1.0f - 4.0f * lr_border;
float primary_left = (1.0f - visible_width) * 0.5f;
float primary_width = visible_width;
@ -1854,18 +1860,18 @@ void menu_select_launch::draw(uint32_t flags)
visible_top += get_customtop();
// compute left box size
float x1 = visible_left - ui().box_lr_border();
float x1 = visible_left - lr_border;
float y1 = visible_top - ui().box_tb_border();
float x2 = x1 + 2.0f * ui().box_lr_border();
float x2 = x1 + 2.0f * lr_border;
float y2 = visible_top + visible_main_menu_height + ui().box_tb_border() + extra_height;
// add left box
visible_left = draw_left_panel(x1, y1, x2, y2);
visible_width -= right_panel_size + visible_left - 2.0f * ui().box_lr_border();
visible_width -= right_panel_size + visible_left - 2.0f * lr_border;
// compute and add main box
x1 = visible_left - ui().box_lr_border();
x2 = visible_left + visible_width + ui().box_lr_border();
x1 = visible_left - lr_border;
x2 = visible_left + visible_width + lr_border;
float line = visible_top + (float(m_visible_lines) * line_height);
ui().draw_outlined_box(container(), x1, y1, x2, y2, ui().colors().background_color());
@ -2053,8 +2059,8 @@ void menu_select_launch::draw(uint32_t flags)
draw_right_panel(x1, y1, x2, y2);
x1 = primary_left - ui().box_lr_border();
x2 = primary_left + primary_width + ui().box_lr_border();
x1 = primary_left - lr_border;
x2 = primary_left + primary_width + lr_border;
// if there is something special to add, do it by calling the virtual method
custom_render(get_selection_ref(), get_customtop(), get_custombottom(), x1, y1, x2, y2);
@ -2080,10 +2086,11 @@ void menu_select_launch::draw(uint32_t flags)
void menu_select_launch::draw_right_panel(float origx1, float origy1, float origx2, float origy2)
{
float const aspect(machine().render().ui_aspect(&container()));
bool const hide((ui_globals::panels_status == HIDE_RIGHT_PANEL) || (ui_globals::panels_status == HIDE_BOTH));
float const x2(hide ? origx2 : (origx1 + 2.0f * ui().box_lr_border()));
float const x2(hide ? origx2 : (origx1 + 2.0f * ui().box_lr_border() * aspect));
float const space(x2 - origx1);
float const lr_arrow_width(0.4f * space * machine().render().ui_aspect());
float const lr_arrow_width(0.4f * space * aspect);
// set left-right arrows dimension
float const ar_x0(0.5f * (x2 + origx1) - 0.5f * lr_arrow_width);
@ -2342,7 +2349,7 @@ void menu_select_launch::arts_render(float origx1, float origy1, float origx2, f
std::string menu_select_launch::arts_render_common(float origx1, float origy1, float origx2, float origy2)
{
float const line_height = ui().get_line_height();
float const gutter_width = 0.4f * line_height * machine().render().ui_aspect() * 1.3f;
float const gutter_width = 0.4f * line_height * machine().render().ui_aspect(&container()) * 1.3f;
std::string snaptext, searchstr;
get_title_search(snaptext, searchstr);
@ -2555,8 +2562,9 @@ void menu_select_launch::exit(running_machine &machine)
float menu_select_launch::draw_collapsed_left_panel(float x1, float y1, float x2, float y2)
{
float const aspect = machine().render().ui_aspect(&container());
float const space = x2 - x1;
float const lr_arrow_width = 0.4f * space * machine().render().ui_aspect();
float const lr_arrow_width = 0.4f * space * aspect;
// set left-right arrows dimension
float const ar_x0 = 0.5f * (x2 + x1) - (0.5f * lr_arrow_width);
@ -2575,7 +2583,7 @@ float menu_select_launch::draw_collapsed_left_panel(float x1, float y1, float x2
draw_arrow(ar_x0, ar_y0, ar_x1, ar_y1, fgcolor, ROT90);
return x2 + ui().box_lr_border();
return x2 + ui().box_lr_border() * aspect;
}
@ -2669,8 +2677,9 @@ void menu_select_launch::infos_render(float origx1, float origy1, float origx2,
}
origy1 += ui().box_tb_border();
float gutter_width = 0.4f * line_height * machine().render().ui_aspect() * 1.3f;
float ud_arrow_width = line_height * machine().render().ui_aspect();
float const aspect(machine().render().ui_aspect(&container()));
float const gutter_width = 0.4f * line_height * aspect * 1.3f;
float const ud_arrow_width = line_height * aspect;
float oy1 = origy1 + line_height;
char const *const snaptext(m_info_view ? m_items_list[m_info_view - 1].c_str() : _(first));

View File

@ -230,23 +230,24 @@ void menu_sliders::custom_render(void *selectedref, float top, float bottom, flo
tempstring.insert(0, " ").insert(0, curslider->description);
// move us to the bottom of the screen, and expand to full width
const float lr_border = ui().box_lr_border() * machine().render().ui_aspect(&container());
y2 = 1.0f - ui().box_tb_border();
y1 = y2 - bottom;
x1 = ui().box_lr_border();
x2 = 1.0f - ui().box_lr_border();
x1 = lr_border;
x2 = 1.0f - lr_border;
// draw extra menu area
ui().draw_outlined_box(container(), x1, y1, x2, y2, ui().colors().background_color());
y1 += ui().box_tb_border();
// determine the text height
ui().draw_text_full(container(), tempstring.c_str(), 0, 0, x2 - x1 - 2.0f * ui().box_lr_border(),
ui().draw_text_full(container(), tempstring.c_str(), 0, 0, x2 - x1 - 2.0f * lr_border,
ui::text_layout::CENTER, ui::text_layout::TRUNCATE, mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), nullptr, &text_height);
// draw the thermometer
bar_left = x1 + ui().box_lr_border();
bar_left = x1 + lr_border;
bar_area_top = y1;
bar_width = x2 - x1 - 2.0f * ui().box_lr_border();
bar_width = x2 - x1 - 2.0f * lr_border;
bar_area_height = line_height;
// compute positions
@ -267,7 +268,7 @@ void menu_sliders::custom_render(void *selectedref, float top, float bottom, flo
container().add_line(default_x, bar_bottom, default_x, bar_area_top + bar_area_height, UI_LINE_WIDTH, ui().colors().border_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
// draw the actual text
ui().draw_text_full(container(), tempstring.c_str(), x1 + ui().box_lr_border(), y1 + line_height, x2 - x1 - 2.0f * ui().box_lr_border(),
ui().draw_text_full(container(), tempstring.c_str(), x1 + lr_border, y1 + line_height, x2 - x1 - 2.0f * lr_border,
ui::text_layout::CENTER, ui::text_layout::WORD, mame_ui_manager::NORMAL, ui().colors().text_color(), ui().colors().text_bg_color(), nullptr, &text_height);
}
}

View File

@ -391,16 +391,16 @@ static void palette_handler(mame_ui_manager &mui, render_container &container, u
int total = state.palette.which ? palette->indirect_entries() : palette->entries();
const rgb_t *raw_color = palette->palette()->entry_list_raw();
render_font *ui_font = mui.get_font();
float chwidth, chheight;
float titlewidth;
float x0, y0;
render_bounds cellboxbounds;
render_bounds boxbounds;
int x, y, skip;
int skip;
// 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');
const float aspect = mui.machine().render().ui_aspect(&container);
const float chheight = mui.get_line_height();
const float chwidth = ui_font->char_width(chheight, aspect, '0');
boxbounds.x0 = 0.0f + 0.5f * chwidth;
boxbounds.x1 = 1.0f - 0.5f * chwidth;
boxbounds.y0 = 0.0f + 0.5f * chheight;
@ -420,8 +420,8 @@ static void palette_handler(mame_ui_manager &mui, render_container &container, u
cellboxbounds.y0 += 3.0f * chheight;
// compute the cell size
float cellwidth = (cellboxbounds.x1 - cellboxbounds.x0) / (float)state.palette.columns;
float cellheight = (cellboxbounds.y1 - cellboxbounds.y0) / (float)state.palette.columns;
const float cellwidth = (cellboxbounds.x1 - cellboxbounds.x0) / float(state.palette.columns);
const float cellheight = (cellboxbounds.y1 - cellboxbounds.y0) / float(state.palette.columns);
// figure out the title
std::ostringstream title_buf;
@ -433,7 +433,7 @@ static void palette_handler(mame_ui_manager &mui, render_container &container, u
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);
render_target *const 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)
@ -454,7 +454,7 @@ static void palette_handler(mame_ui_manager &mui, render_container &container, u
// 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());
titlewidth = ui_font->string_width(chheight, aspect, title.c_str());
x0 = 0.0f;
if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth)
x0 = boxbounds.x0 - (0.5f - 0.5f * (titlewidth + chwidth));
@ -467,17 +467,17 @@ static void palette_handler(mame_ui_manager &mui, render_container &container, u
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);
container.add_char(x0, y0, chheight, aspect, rgb_t::white(), *ui_font, ch);
x0 += ui_font->char_width(chheight, aspect, ch);
}
// draw the top column headers
skip = (int)(chwidth / cellwidth);
for (x = 0; x < state.palette.columns; x += 1 + skip)
skip = int(chwidth / cellwidth);
for (int x = 0; x < state.palette.columns; 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, mui.machine().render().ui_aspect(), rgb_t::white(), *ui_font, "0123456789ABCDEF"[x & 0xf]);
container.add_char(x0 + 0.5f * (cellwidth - chwidth), y0, chheight, aspect, rgb_t::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
@ -486,8 +486,8 @@ static void palette_handler(mame_ui_manager &mui, render_container &container, u
}
// draw the side column headers
skip = (int)(chheight / cellheight);
for (y = 0; y < state.palette.columns; y += 1 + skip)
skip = int(chheight / cellheight);
for (int y = 0; y < state.palette.columns; y += 1 + skip)
// only display if there is data to show
if (state.palette.offset + y * state.palette.columns < total)
@ -503,21 +503,21 @@ static void palette_handler(mame_ui_manager &mui, render_container &container, u
// draw the row header
sprintf(buffer, "%5X", state.palette.offset + y * state.palette.columns);
for (x = 4; x >= 0; x--)
for (int x = 4; x >= 0; x--)
{
x0 -= ui_font->char_width(chheight, mui.machine().render().ui_aspect(), buffer[x]);
container.add_char(x0, y0 + 0.5f * (cellheight - chheight), chheight, mui.machine().render().ui_aspect(), rgb_t::white(), *ui_font, buffer[x]);
x0 -= ui_font->char_width(chheight, aspect, buffer[x]);
container.add_char(x0, y0 + 0.5f * (cellheight - chheight), chheight, aspect, rgb_t::white(), *ui_font, buffer[x]);
}
}
// now add the rectangles for the colors
for (y = 0; y < state.palette.columns; y++)
for (x = 0; x < state.palette.columns; x++)
for (int y = 0; y < state.palette.columns; y++)
for (int x = 0; x < state.palette.columns; x++)
{
int index = state.palette.offset + y * state.palette.columns + x;
if (index < total)
{
pen_t pen = state.palette.which ? palette->indirect_color(index) : raw_color[index];
const pen_t pen = state.palette.which ? palette->indirect_color(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));
@ -625,10 +625,6 @@ static void gfxset_handler(mame_ui_manager &mui, render_container &container, ui
ui_gfx_info &info = state.gfxdev[dev];
device_gfx_interface &interface = *info.interface;
gfx_element &gfx = *interface.gfx(set);
float fullwidth, fullheight;
float cellwidth, cellheight;
float chwidth, chheight;
float titlewidth;
float x0, y0;
render_bounds cellboxbounds;
render_bounds boxbounds;
@ -636,13 +632,14 @@ static void gfxset_handler(mame_ui_manager &mui, render_container &container, ui
int targwidth = mui.machine().render().ui_target().width();
int targheight = mui.machine().render().ui_target().height();
int cellxpix, cellypix;
int xcells, ycells;
int xcells;
int pixelscale = 0;
int x, y, skip;
int skip;
// 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');
const float aspect = mui.machine().render().ui_aspect(&container);
const float chheight = mui.get_line_height();
const float chwidth = ui_font->char_width(chheight, aspect, '0');
boxbounds.x0 = 0.0f + 0.5f * chwidth;
boxbounds.x1 = 1.0f - 0.5f * chwidth;
boxbounds.y0 = 0.0f + 0.5f * chheight;
@ -662,8 +659,8 @@ static void gfxset_handler(mame_ui_manager &mui, render_container &container, ui
cellboxbounds.y0 += 3.0f * chheight;
// convert back to pixels
cellboxwidth = (cellboxbounds.x1 - cellboxbounds.x0) * (float)targwidth;
cellboxheight = (cellboxbounds.y1 - cellboxbounds.y0) * (float)targheight;
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 + ((info.rotate[set] & ORIENTATION_SWAP_XY) ? gfx.height() : gfx.width());
@ -684,20 +681,20 @@ static void gfxset_handler(mame_ui_manager &mui, render_container &container, ui
pixelscale = std::max(1, pixelscale);
// in the Y direction, we just display as many as we can
ycells = cellboxheight / (pixelscale * cellypix);
const int ycells = cellboxheight / (pixelscale * cellypix);
// now determine the actual cellbox size
cellboxwidth = std::min(cellboxwidth, xcells * pixelscale * cellxpix);
cellboxheight = std::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;
const float cellwidth = (cellboxwidth / float(xcells)) / float(targwidth);
const float 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;
const float fullwidth = float(cellboxwidth) / float(targwidth) + 6.5f * chwidth;
const float fullheight = float(cellboxheight) / float(targheight) + 4.0f * chheight;
// recompute boxbounds from this
boxbounds.x0 = (1.0f - fullwidth) * 0.5f;
@ -707,9 +704,9 @@ static void gfxset_handler(mame_ui_manager &mui, render_container &container, ui
// recompute cellboxbounds
cellboxbounds.x0 = boxbounds.x0 + 6.0f * chwidth;
cellboxbounds.x1 = cellboxbounds.x0 + (float)cellboxwidth / (float)targwidth;
cellboxbounds.x1 = cellboxbounds.x0 + float(cellboxwidth) / float(targwidth);
cellboxbounds.y0 = boxbounds.y0 + 3.5f * chheight;
cellboxbounds.y1 = cellboxbounds.y0 + (float)cellboxheight / (float)targheight;
cellboxbounds.y1 = cellboxbounds.y0 + float(cellboxheight) / float(targheight);
// figure out the title
std::ostringstream title_buf;
@ -720,7 +717,7 @@ static void gfxset_handler(mame_ui_manager &mui, render_container &container, ui
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);
render_target *const 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)
@ -748,7 +745,7 @@ static void gfxset_handler(mame_ui_manager &mui, render_container &container, ui
// 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());
const float titlewidth = ui_font->string_width(chheight, aspect, title.c_str());
x0 = 0.0f;
if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth)
x0 = boxbounds.x0 - (0.5f - 0.5f * (titlewidth + chwidth));
@ -761,17 +758,17 @@ static void gfxset_handler(mame_ui_manager &mui, render_container &container, ui
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);
container.add_char(x0, y0, chheight, aspect, rgb_t::white(), *ui_font, ch);
x0 += ui_font->char_width(chheight, aspect, ch);
}
// draw the top column headers
skip = (int)(chwidth / cellwidth);
for (x = 0; x < xcells; x += 1 + skip)
skip = int(chwidth / cellwidth);
for (int 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, mui.machine().render().ui_aspect(), rgb_t::white(), *ui_font, "0123456789ABCDEF"[x & 0xf]);
container.add_char(x0 + 0.5f * (cellwidth - chwidth), y0, chheight, aspect, rgb_t::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
@ -780,8 +777,8 @@ static void gfxset_handler(mame_ui_manager &mui, render_container &container, ui
}
// draw the side column headers
skip = (int)(chheight / cellheight);
for (y = 0; y < ycells; y += 1 + skip)
skip = int(chheight / cellheight);
for (int y = 0; y < ycells; y += 1 + skip)
// only display if there is data to show
if (info.offset[set] + y * xcells < gfx.elements())
@ -797,10 +794,10 @@ static void gfxset_handler(mame_ui_manager &mui, render_container &container, ui
// draw the row header
sprintf(buffer, "%5X", info.offset[set] + y * xcells);
for (x = 4; x >= 0; x--)
for (int x = 4; x >= 0; x--)
{
x0 -= ui_font->char_width(chheight, mui.machine().render().ui_aspect(), buffer[x]);
container.add_char(x0, y0 + 0.5f * (cellheight - chheight), chheight, mui.machine().render().ui_aspect(), rgb_t::white(), *ui_font, buffer[x]);
x0 -= ui_font->char_width(chheight, aspect, buffer[x]);
container.add_char(x0, y0 + 0.5f * (cellheight - chheight), chheight, aspect, rgb_t::white(), *ui_font, buffer[x]);
}
}
@ -1053,11 +1050,10 @@ static void gfxset_draw_item(running_machine &machine, gfx_element &gfx, int ind
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();
const int targwidth = mui.machine().render().ui_target().width();
const int targheight = mui.machine().render().ui_target().height();
float titlewidth;
float x0, y0;
int mapboxwidth, mapboxheight;
@ -1070,8 +1066,9 @@ static void tilemap_handler(mame_ui_manager &mui, render_container &container, u
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');
const float aspect = mui.machine().render().ui_aspect(&container);
const float chheight = mui.get_line_height();
const float chwidth = ui_font->char_width(chheight, aspect, '0');
boxbounds.x0 = 0.0f + 0.5f * chwidth;
boxbounds.x1 = 1.0f - 0.5f * chwidth;
boxbounds.y0 = 0.0f + 0.5f * chheight;
@ -1125,7 +1122,7 @@ static void tilemap_handler(mame_ui_manager &mui, render_container &container, u
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);
render_target *const 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)
@ -1155,7 +1152,7 @@ static void tilemap_handler(mame_ui_manager &mui, render_container &container, u
// 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());
titlewidth = ui_font->string_width(chheight, aspect, title.c_str());
if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth)
{
boxbounds.x0 = 0.5f - 0.5f * (titlewidth + chwidth);
@ -1170,8 +1167,8 @@ static void tilemap_handler(mame_ui_manager &mui, render_container &container, u
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);
container.add_char(x0, y0, chheight, aspect, rgb_t::white(), *ui_font, ch);
x0 += ui_font->char_width(chheight, aspect, ch);
}
// update the bitmap
@ -1231,7 +1228,7 @@ static void tilemap_handle_keys(running_machine &machine, ui_gfx_state &state, i
}
// return to (0,0) (HOME)
if( machine.ui_input().pressed(IPT_UI_HOME))
if (machine.ui_input().pressed(IPT_UI_HOME))
{
state.tilemap.xoffs = 0;
state.tilemap.yoffs = 0;