mirror of
https://github.com/holub/mame
synced 2025-04-24 09:20:02 +03:00
-emu/render.cpp: Load from all external artwork paths.
-emu/rendlay.cpp: Made real component drawing code a bit less gross. -emu/debugcon.cpp: Less screaming now that things aren't macros.
This commit is contained in:
parent
d6f7c7febf
commit
853fdf7542
@ -650,12 +650,12 @@ bool debugger_commands::debug_command_parameter_command(const char *param)
|
||||
|
||||
/* validate the comment; success if no error */
|
||||
CMDERR err = m_console.validate_command(param);
|
||||
if (err.ERROR_CLASS() == CMDERR::NONE)
|
||||
if (err.error_class() == CMDERR::NONE)
|
||||
return true;
|
||||
|
||||
/* output an error */
|
||||
m_console.printf("Error in command: %s\n", param);
|
||||
m_console.printf(" %*s^", err.ERROR_OFFSET(), "");
|
||||
m_console.printf(" %*s^", err.error_offset(), "");
|
||||
m_console.printf("%s\n", debugger_console::cmderr_to_string(err));
|
||||
return 0;
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ CMDERR debugger_console::internal_execute_command(bool execute, int params, char
|
||||
|
||||
/* no params is an error */
|
||||
if (params == 0)
|
||||
return CMDERR(CMDERR::NONE, 0);
|
||||
return CMDERR::none();
|
||||
|
||||
/* the first parameter has the command and the real first parameter; separate them */
|
||||
for (p = param[0]; *p && isspace(u8(*p)); p++) { }
|
||||
@ -287,9 +287,9 @@ CMDERR debugger_console::internal_execute_command(bool execute, int params, char
|
||||
|
||||
/* error if not found */
|
||||
if (!found)
|
||||
return CMDERR::MAKE_UNKNOWN_COMMAND(0);
|
||||
return CMDERR::unknown_command(0);
|
||||
if (foundcount > 1)
|
||||
return CMDERR::MAKE_AMBIGUOUS_COMMAND(0);
|
||||
return CMDERR::ambiguous_command(0);
|
||||
|
||||
/* NULL-terminate and trim space around all the parameters */
|
||||
for (i = 1; i < params; i++)
|
||||
@ -301,9 +301,9 @@ CMDERR debugger_console::internal_execute_command(bool execute, int params, char
|
||||
|
||||
/* see if we have the right number of parameters */
|
||||
if (params < found->minparams)
|
||||
return CMDERR::MAKE_NOT_ENOUGH_PARAMS(0);
|
||||
return CMDERR::not_enough_params(0);
|
||||
if (params > found->maxparams)
|
||||
return CMDERR::MAKE_TOO_MANY_PARAMS(0);
|
||||
return CMDERR::too_many_params(0);
|
||||
|
||||
/* execute the handler */
|
||||
if (execute)
|
||||
@ -311,7 +311,7 @@ CMDERR debugger_console::internal_execute_command(bool execute, int params, char
|
||||
std::vector<std::string> params_vec(param, param + params);
|
||||
found->handler(found->ref, params_vec);
|
||||
}
|
||||
return CMDERR(CMDERR::NONE, 0);
|
||||
return CMDERR::none();
|
||||
}
|
||||
|
||||
|
||||
@ -353,9 +353,9 @@ CMDERR debugger_console::internal_parse_command(const std::string &original_comm
|
||||
case '(':
|
||||
case '[':
|
||||
case '{': parens[parendex++] = c; break;
|
||||
case ')': if (parendex == 0 || parens[--parendex] != '(') return CMDERR::MAKE_UNBALANCED_PARENS(p - command); break;
|
||||
case ']': if (parendex == 0 || parens[--parendex] != '[') return CMDERR::MAKE_UNBALANCED_PARENS(p - command); break;
|
||||
case '}': if (parendex == 0 || parens[--parendex] != '{') return CMDERR::MAKE_UNBALANCED_PARENS(p - command); break;
|
||||
case ')': if (parendex == 0 || parens[--parendex] != '(') return CMDERR::unbalanced_parens(p - command); break;
|
||||
case ']': if (parendex == 0 || parens[--parendex] != '[') return CMDERR::unbalanced_parens(p - command); break;
|
||||
case '}': if (parendex == 0 || parens[--parendex] != '{') return CMDERR::unbalanced_parens(p - command); break;
|
||||
case ',': if (parendex == 0) params[paramcount++] = p; break;
|
||||
case ';': if (parendex == 0) foundend = true; break;
|
||||
case '-': if (parendex == 0 && paramcount == 1 && p[1] == '-') isexpr = true; *p = c; break;
|
||||
@ -369,9 +369,9 @@ CMDERR debugger_console::internal_parse_command(const std::string &original_comm
|
||||
|
||||
/* check for unbalanced parentheses or quotes */
|
||||
if (instring)
|
||||
return CMDERR::MAKE_UNBALANCED_QUOTES(p - command);
|
||||
return CMDERR::unbalanced_quotes(p - command);
|
||||
if (parendex != 0)
|
||||
return CMDERR::MAKE_UNBALANCED_PARENS(p - command);
|
||||
return CMDERR::unbalanced_parens(p - command);
|
||||
|
||||
/* NULL-terminate if we ended in a semicolon */
|
||||
p--;
|
||||
@ -396,17 +396,17 @@ CMDERR debugger_console::internal_parse_command(const std::string &original_comm
|
||||
}
|
||||
catch (expression_error &err)
|
||||
{
|
||||
return CMDERR::MAKE_EXPRESSION_ERROR(err);
|
||||
return CMDERR::expression_error(err);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const CMDERR result = internal_execute_command(execute, paramcount, ¶ms[0]);
|
||||
if (result.ERROR_CLASS() != CMDERR::NONE)
|
||||
return CMDERR(result.ERROR_CLASS(), command_start - command);
|
||||
if (result.error_class() != CMDERR::NONE)
|
||||
return CMDERR(result.error_class(), command_start - command);
|
||||
}
|
||||
}
|
||||
return CMDERR(CMDERR::NONE, 0);
|
||||
return CMDERR::none();
|
||||
}
|
||||
|
||||
|
||||
@ -424,11 +424,11 @@ CMDERR debugger_console::execute_command(const std::string &command, bool echo)
|
||||
const CMDERR result = internal_parse_command(command, true);
|
||||
|
||||
/* display errors */
|
||||
if (result.ERROR_CLASS() != CMDERR::NONE)
|
||||
if (result.error_class() != CMDERR::NONE)
|
||||
{
|
||||
if (!echo)
|
||||
printf(">%s\n", command.c_str());
|
||||
printf(" %*s^\n", result.ERROR_OFFSET(), "");
|
||||
printf(" %*s^\n", result.error_offset(), "");
|
||||
printf("%s\n", cmderr_to_string(result).c_str());
|
||||
}
|
||||
|
||||
@ -547,8 +547,8 @@ void debugger_console::process_source_file()
|
||||
|
||||
std::string debugger_console::cmderr_to_string(CMDERR error)
|
||||
{
|
||||
const int offset = error.ERROR_OFFSET();
|
||||
switch (error.ERROR_CLASS())
|
||||
const int offset = error.error_offset();
|
||||
switch (error.error_class())
|
||||
{
|
||||
case CMDERR::UNKNOWN_COMMAND: return "unknown command";
|
||||
case CMDERR::AMBIGUOUS_COMMAND: return "ambiguous command";
|
||||
|
@ -41,33 +41,37 @@ constexpr u32 CMDFLAG_CUSTOM_HELP = 0x0002;
|
||||
***************************************************************************/
|
||||
|
||||
// CMDERR is an error code for command evaluation
|
||||
struct CMDERR
|
||||
class CMDERR
|
||||
{
|
||||
public:
|
||||
// values for the error code in a command error
|
||||
static constexpr u32 NONE = 0;
|
||||
static constexpr u32 UNKNOWN_COMMAND = 1;
|
||||
static constexpr u32 AMBIGUOUS_COMMAND = 2;
|
||||
static constexpr u32 UNBALANCED_PARENS = 3;
|
||||
static constexpr u32 UNBALANCED_QUOTES = 4;
|
||||
static constexpr u32 NOT_ENOUGH_PARAMS = 5;
|
||||
static constexpr u32 TOO_MANY_PARAMS = 6;
|
||||
static constexpr u32 EXPRESSION_ERROR = 7;
|
||||
|
||||
u32 val;
|
||||
static constexpr u16 NONE = 0;
|
||||
static constexpr u16 UNKNOWN_COMMAND = 1;
|
||||
static constexpr u16 AMBIGUOUS_COMMAND = 2;
|
||||
static constexpr u16 UNBALANCED_PARENS = 3;
|
||||
static constexpr u16 UNBALANCED_QUOTES = 4;
|
||||
static constexpr u16 NOT_ENOUGH_PARAMS = 5;
|
||||
static constexpr u16 TOO_MANY_PARAMS = 6;
|
||||
static constexpr u16 EXPRESSION_ERROR = 7;
|
||||
|
||||
// command error assembly/disassembly
|
||||
constexpr CMDERR(u32 a, u32 b) : val((a << 16) | (b & 0xffff)) { }
|
||||
constexpr u32 ERROR_CLASS() const { return val >> 16; }
|
||||
constexpr u32 ERROR_OFFSET() const { return val & 0xffff; }
|
||||
constexpr CMDERR(u16 c, u16 o) : m_error_class(c), m_error_offset(o) { }
|
||||
constexpr u16 error_class() const { return m_error_class; }
|
||||
constexpr u16 error_offset() const { return m_error_offset; }
|
||||
|
||||
// assemble specific error conditions
|
||||
static constexpr CMDERR MAKE_UNKNOWN_COMMAND(u32 x) { return CMDERR(UNKNOWN_COMMAND, x); }
|
||||
static constexpr CMDERR MAKE_AMBIGUOUS_COMMAND(u32 x) { return CMDERR(AMBIGUOUS_COMMAND, x); }
|
||||
static constexpr CMDERR MAKE_UNBALANCED_PARENS(u32 x) { return CMDERR(UNBALANCED_PARENS, x); }
|
||||
static constexpr CMDERR MAKE_UNBALANCED_QUOTES(u32 x) { return CMDERR(UNBALANCED_QUOTES, x); }
|
||||
static constexpr CMDERR MAKE_NOT_ENOUGH_PARAMS(u32 x) { return CMDERR(NOT_ENOUGH_PARAMS, x); }
|
||||
static constexpr CMDERR MAKE_TOO_MANY_PARAMS(u32 x) { return CMDERR(TOO_MANY_PARAMS, x); }
|
||||
static constexpr CMDERR MAKE_EXPRESSION_ERROR(u32 x) { return CMDERR(EXPRESSION_ERROR, x); }
|
||||
static constexpr CMDERR none() { return CMDERR(NONE, 0); }
|
||||
static constexpr CMDERR unknown_command(u16 x) { return CMDERR(UNKNOWN_COMMAND, x); }
|
||||
static constexpr CMDERR ambiguous_command(u16 x) { return CMDERR(AMBIGUOUS_COMMAND, x); }
|
||||
static constexpr CMDERR unbalanced_parens(u16 x) { return CMDERR(UNBALANCED_PARENS, x); }
|
||||
static constexpr CMDERR unbalanced_quotes(u16 x) { return CMDERR(UNBALANCED_QUOTES, x); }
|
||||
static constexpr CMDERR not_enough_params(u16 x) { return CMDERR(NOT_ENOUGH_PARAMS, x); }
|
||||
static constexpr CMDERR too_many_params(u16 x) { return CMDERR(TOO_MANY_PARAMS, x); }
|
||||
static constexpr CMDERR expression_error(u16 x) { return CMDERR(EXPRESSION_ERROR, x); }
|
||||
|
||||
private:
|
||||
u16 m_error_class, m_error_offset;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -1665,7 +1665,7 @@ void render_target::load_layout_files(util::xml::data_node const &rootnode, bool
|
||||
|
||||
// if there's an explicit file, load that first
|
||||
const std::string &basename = m_manager.machine().basename();
|
||||
have_artwork |= load_layout_file(m_manager.machine().root_device(), basename.c_str(), rootnode);
|
||||
have_artwork |= load_layout_file(m_manager.machine().root_device(), rootnode, m_manager.machine().options().art_path(), basename.c_str());
|
||||
|
||||
// if we're only loading this file, we know our final result
|
||||
if (!singlefile)
|
||||
@ -2084,7 +2084,7 @@ void render_target::load_additional_layout_files(const char *basename, bool have
|
||||
}
|
||||
|
||||
// try to parse it
|
||||
if (!load_layout_file(m_manager.machine().root_device(), nullptr, *root))
|
||||
if (!load_layout_file(m_manager.machine().root_device(), *root, m_manager.machine().options().art_path(), nullptr))
|
||||
throw emu_fatalerror("Couldn't parse generated layout??");
|
||||
}
|
||||
}
|
||||
@ -2111,7 +2111,7 @@ bool render_target::load_layout_file(const char *dirname, const internal_layout
|
||||
zerr = inflateInit(&stream);
|
||||
if (zerr != Z_OK)
|
||||
{
|
||||
fatalerror("could not inflateInit");
|
||||
osd_printf_error("render_target::load_layout_file: zlib initialization error\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2127,23 +2127,21 @@ bool render_target::load_layout_file(const char *dirname, const internal_layout
|
||||
}
|
||||
else if (zerr != Z_OK)
|
||||
{
|
||||
fatalerror("decompression error\n");
|
||||
osd_printf_error("render_target::load_layout_file: zlib decompression error\n");
|
||||
inflateEnd(&stream);
|
||||
return false;
|
||||
}
|
||||
|
||||
// clean up
|
||||
zerr = inflateEnd(&stream);
|
||||
if (zerr != Z_OK)
|
||||
{
|
||||
fatalerror("inflateEnd error\n");
|
||||
return false;
|
||||
}
|
||||
osd_printf_error("render_target::load_layout_file: zlib cleanup error\n");
|
||||
|
||||
util::xml::file::ptr rootnode(util::xml::file::string_read(reinterpret_cast<char const *>(tempout.get()), nullptr));
|
||||
tempout.reset();
|
||||
|
||||
// if we didn't get a properly-formatted XML file, record a warning and exit
|
||||
if (!load_layout_file(device ? *device : m_manager.machine().root_device(), dirname, *rootnode))
|
||||
if (!load_layout_file(device ? *device : m_manager.machine().root_device(), *rootnode, m_manager.machine().options().art_path(), dirname))
|
||||
{
|
||||
osd_printf_warning("Improperly formatted XML string, ignoring\n");
|
||||
return false;
|
||||
@ -2157,28 +2155,39 @@ bool render_target::load_layout_file(const char *dirname, const internal_layout
|
||||
bool render_target::load_layout_file(const char *dirname, const char *filename)
|
||||
{
|
||||
// build the path and optionally prepend the directory
|
||||
std::string fname = std::string(filename).append(".lay");
|
||||
std::string fname;
|
||||
if (dirname)
|
||||
fname.insert(0, PATH_SEPARATOR).insert(0, dirname);
|
||||
fname.append(dirname).append(PATH_SEPARATOR);
|
||||
fname.append(filename).append(".lay");
|
||||
|
||||
// attempt to open the file; bail if we can't
|
||||
emu_file layoutfile(m_manager.machine().options().art_path(), OPEN_FLAG_READ);
|
||||
layoutfile.set_restrict_to_mediapath(1);
|
||||
osd_file::error const filerr(layoutfile.open(fname));
|
||||
if (filerr != osd_file::error::NONE)
|
||||
return false;
|
||||
|
||||
// read the file
|
||||
// attempt to open matching files
|
||||
util::xml::parse_options parseopt;
|
||||
util::xml::parse_error parseerr;
|
||||
parseopt.error = &parseerr;
|
||||
util::xml::file::ptr rootnode(util::xml::file::read(layoutfile, &parseopt));
|
||||
if (!rootnode)
|
||||
emu_file layoutfile(m_manager.machine().options().art_path(), OPEN_FLAG_READ);
|
||||
layoutfile.set_restrict_to_mediapath(1);
|
||||
bool result(false);
|
||||
for (osd_file::error filerr = layoutfile.open(fname); osd_file::error::NONE == filerr; filerr = layoutfile.open_next())
|
||||
{
|
||||
if (parseerr.error_message)
|
||||
// read the file and parse as XML
|
||||
util::xml::file::ptr const rootnode(util::xml::file::read(layoutfile, &parseopt));
|
||||
if (rootnode)
|
||||
{
|
||||
// extract directory name from location of layout file
|
||||
std::string artdir(layoutfile.fullpath());
|
||||
auto const dirsep(std::find_if(artdir.rbegin(), artdir.rend(), &util::is_directory_separator));
|
||||
artdir.erase(dirsep.base(), artdir.end());
|
||||
|
||||
// record a warning if we didn't get a properly-formatted XML file
|
||||
if (!load_layout_file(m_manager.machine().root_device(), *rootnode, nullptr, artdir.c_str()))
|
||||
osd_printf_warning("Improperly formatted XML layout file '%s', ignoring\n", filename);
|
||||
else
|
||||
result = true;
|
||||
}
|
||||
else if (parseerr.error_message)
|
||||
{
|
||||
osd_printf_warning(
|
||||
"Error parsing XML file '%s' at line %d column %d: %s, ignoring\n",
|
||||
"Error parsing XML layout file '%s' at line %d column %d: %s, ignoring\n",
|
||||
filename,
|
||||
parseerr.error_line,
|
||||
parseerr.error_column,
|
||||
@ -2186,29 +2195,18 @@ bool render_target::load_layout_file(const char *dirname, const char *filename)
|
||||
}
|
||||
else
|
||||
{
|
||||
osd_printf_warning("Error parsing XML file '%s', ignorning\n", filename);
|
||||
osd_printf_warning("Error parsing XML layout file '%s', ignorning\n", filename);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// if we didn't get a properly-formatted XML file, record a warning and exit
|
||||
if (!load_layout_file(m_manager.machine().root_device(), dirname, *rootnode))
|
||||
{
|
||||
osd_printf_warning("Improperly formatted XML file '%s', ignoring\n", filename);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool render_target::load_layout_file(device_t &device, const char *dirname, util::xml::data_node const &rootnode)
|
||||
bool render_target::load_layout_file(device_t &device, util::xml::data_node const &rootnode, const char *searchpath, const char *dirname)
|
||||
{
|
||||
// parse and catch any errors
|
||||
try
|
||||
{
|
||||
m_filelist.emplace_back(device, rootnode, dirname);
|
||||
m_filelist.emplace_back(device, rootnode, searchpath, dirname);
|
||||
}
|
||||
catch (emu_fatalerror &)
|
||||
{
|
||||
|
@ -538,7 +538,7 @@ public:
|
||||
using environment = emu::render::detail::layout_environment;
|
||||
|
||||
// construction/destruction
|
||||
layout_element(environment &env, util::xml::data_node const &elemnode, const char *dirname);
|
||||
layout_element(environment &env, util::xml::data_node const &elemnode);
|
||||
virtual ~layout_element();
|
||||
|
||||
// getters
|
||||
@ -563,7 +563,7 @@ private:
|
||||
typedef std::unique_ptr<component> ptr;
|
||||
|
||||
// construction/destruction
|
||||
component(environment &env, util::xml::data_node const &compnode, const char *dirname);
|
||||
component(environment &env, util::xml::data_node const &compnode);
|
||||
virtual ~component() = default;
|
||||
|
||||
// setup
|
||||
@ -641,13 +641,13 @@ private:
|
||||
int m_state; // associated state number
|
||||
};
|
||||
|
||||
typedef component::ptr (*make_component_func)(environment &env, util::xml::data_node const &compnode, const char *dirname);
|
||||
typedef component::ptr (*make_component_func)(environment &env, util::xml::data_node const &compnode);
|
||||
typedef std::map<std::string, make_component_func> make_component_map;
|
||||
|
||||
// internal helpers
|
||||
static void element_scale(bitmap_argb32 &dest, bitmap_argb32 &source, const rectangle &sbounds, void *param);
|
||||
template <typename T> static component::ptr make_component(environment &env, util::xml::data_node const &compnode, const char *dirname);
|
||||
template <int D> static component::ptr make_dotmatrix_component(environment &env, util::xml::data_node const &compnode, const char *dirname);
|
||||
template <typename T> static component::ptr make_component(environment &env, util::xml::data_node const &compnode);
|
||||
template <int D> static component::ptr make_dotmatrix_component(environment &env, util::xml::data_node const &compnode);
|
||||
|
||||
static make_component_map const s_make_component; // maps component XML names to creator functions
|
||||
|
||||
@ -946,7 +946,7 @@ public:
|
||||
using view_list = std::list<layout_view>;
|
||||
|
||||
// construction/destruction
|
||||
layout_file(device_t &device, util::xml::data_node const &rootnode, char const *dirname);
|
||||
layout_file(device_t &device, util::xml::data_node const &rootnode, char const *searchpath, char const *dirname);
|
||||
~layout_file();
|
||||
|
||||
// getters
|
||||
@ -959,7 +959,6 @@ private:
|
||||
|
||||
// add elements and parameters
|
||||
void add_elements(
|
||||
char const *dirname,
|
||||
environment &env,
|
||||
util::xml::data_node const &parentnode,
|
||||
group_map &groupmap,
|
||||
@ -1068,7 +1067,7 @@ private:
|
||||
void load_additional_layout_files(const char *basename, bool have_artwork);
|
||||
bool load_layout_file(const char *dirname, const char *filename);
|
||||
bool load_layout_file(const char *dirname, const internal_layout &layout_data, device_t *device = nullptr);
|
||||
bool load_layout_file(device_t &device, const char *dirname, util::xml::data_node const &rootnode);
|
||||
bool load_layout_file(device_t &device, util::xml::data_node const &rootnode, const char *searchpath, const char *dirname);
|
||||
void add_container_primitives(render_primitive_list &list, const object_transform &root_xform, const object_transform &xform, render_container &container, int blendmode);
|
||||
void add_element_primitives(render_primitive_list &list, const object_transform &xform, layout_element &element, int state, int blendmode);
|
||||
std::pair<float, float> map_point_internal(s32 target_x, s32 target_y);
|
||||
|
@ -582,18 +582,24 @@ private:
|
||||
util::ovectorstream m_buffer;
|
||||
std::shared_ptr<NSVGrasterizer> const m_svg_rasterizer;
|
||||
device_t &m_device;
|
||||
char const *const m_search_path;
|
||||
char const *const m_directory_name;
|
||||
layout_environment *const m_next = nullptr;
|
||||
bool m_cached = false;
|
||||
|
||||
public:
|
||||
explicit layout_environment(device_t &device)
|
||||
layout_environment(device_t &device, char const *searchpath, char const *dirname)
|
||||
: m_svg_rasterizer(nsvgCreateRasterizer(), util::nsvg_deleter())
|
||||
, m_device(device)
|
||||
, m_search_path(searchpath)
|
||||
, m_directory_name(dirname)
|
||||
{
|
||||
}
|
||||
explicit layout_environment(layout_environment &next)
|
||||
: m_svg_rasterizer(next.m_svg_rasterizer)
|
||||
, m_device(next.m_device)
|
||||
, m_search_path(next.m_search_path)
|
||||
, m_directory_name(next.m_directory_name)
|
||||
, m_next(&next)
|
||||
{
|
||||
}
|
||||
@ -602,6 +608,8 @@ public:
|
||||
device_t &device() const { return m_device; }
|
||||
running_machine &machine() const { return device().machine(); }
|
||||
bool is_root_device() const { return &device() == &machine().root_device(); }
|
||||
char const *search_path() const { return m_search_path; }
|
||||
char const *directory_name() const { return m_directory_name; }
|
||||
std::shared_ptr<NSVGrasterizer> const &svg_rasterizer() const { return m_svg_rasterizer; }
|
||||
|
||||
void set_parameter(std::string &&name, std::string &&value)
|
||||
@ -1117,7 +1125,7 @@ layout_element::make_component_map const layout_element::s_make_component{
|
||||
// layout_element - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
layout_element::layout_element(environment &env, util::xml::data_node const &elemnode, const char *dirname)
|
||||
layout_element::layout_element(environment &env, util::xml::data_node const &elemnode)
|
||||
: m_machine(env.machine())
|
||||
, m_defstate(env.get_attribute_int(elemnode, "defstate", -1))
|
||||
, m_statemask(0)
|
||||
@ -1133,7 +1141,7 @@ layout_element::layout_element(environment &env, util::xml::data_node const &ele
|
||||
throw layout_syntax_error(util::string_format("unknown element component %s", compnode->get_name()));
|
||||
|
||||
// insert the new component into the list
|
||||
component const &newcomp(**m_complist.emplace(m_complist.end(), make_func->second(env, *compnode, dirname)));
|
||||
component const &newcomp(**m_complist.emplace(m_complist.end(), make_func->second(env, *compnode)));
|
||||
|
||||
// accumulate bounds
|
||||
if (first)
|
||||
@ -1539,10 +1547,11 @@ class layout_element::image_component : public component
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
image_component(environment &env, util::xml::data_node const &compnode, char const *dirname)
|
||||
: component(env, compnode, dirname)
|
||||
image_component(environment &env, util::xml::data_node const &compnode)
|
||||
: component(env, compnode)
|
||||
, m_rasterizer(env.svg_rasterizer())
|
||||
, m_dirname(dirname ? dirname : "")
|
||||
, m_searchpath(env.search_path() ? env.search_path() : "")
|
||||
, m_dirname(env.directory_name() ? env.directory_name() : "")
|
||||
, m_imagefile(env.get_attribute_string(compnode, "file", ""))
|
||||
, m_alphafile(env.get_attribute_string(compnode, "alphafile", ""))
|
||||
, m_data(get_data(compnode))
|
||||
@ -1552,7 +1561,7 @@ public:
|
||||
// overrides
|
||||
virtual void preload(running_machine &machine) override
|
||||
{
|
||||
if (!m_bitmap.valid())
|
||||
if (!m_bitmap.valid() && !m_svg)
|
||||
load_image(machine);
|
||||
}
|
||||
|
||||
@ -1685,11 +1694,17 @@ private:
|
||||
void load_image(running_machine &machine)
|
||||
{
|
||||
// if we have a filename, go with that
|
||||
emu_file file(machine.options().art_path(), OPEN_FLAG_READ);
|
||||
emu_file file(m_searchpath.empty() ? m_dirname : m_searchpath, OPEN_FLAG_READ);
|
||||
if (!m_imagefile.empty())
|
||||
{
|
||||
LOGMASKED(LOG_IMAGE_LOAD, "Image component attempt to load image file '%s%s%s'\n", m_dirname, PATH_SEPARATOR, m_imagefile);
|
||||
osd_file::error const imgerr = file.open(m_dirname.empty() ? m_imagefile : (m_dirname + PATH_SEPARATOR + m_imagefile));
|
||||
std::string filename;
|
||||
if (!m_searchpath.empty())
|
||||
filename = m_dirname;
|
||||
if (!filename.empty() && !util::is_directory_separator(filename[filename.size() - 1]))
|
||||
filename.append(PATH_SEPARATOR);
|
||||
filename.append(m_imagefile);
|
||||
LOGMASKED(LOG_IMAGE_LOAD, "Image component attempt to load image file '%s'\n", filename);
|
||||
osd_file::error const imgerr = file.open(filename);
|
||||
if (osd_file::error::NONE == imgerr)
|
||||
{
|
||||
if (!load_bitmap(file))
|
||||
@ -1701,10 +1716,10 @@ private:
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGMASKED(LOG_IMAGE_LOAD, "Image component unable to open image file '%s%s%s'\n", m_dirname, PATH_SEPARATOR, m_imagefile);
|
||||
LOGMASKED(LOG_IMAGE_LOAD, "Image component unable to open image file '%s'\n", filename);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (!m_data.empty())
|
||||
{
|
||||
load_image_data();
|
||||
}
|
||||
@ -1714,8 +1729,14 @@ private:
|
||||
{
|
||||
if (m_bitmap.valid())
|
||||
{
|
||||
LOGMASKED(LOG_IMAGE_LOAD, "Image component attempt to load alpha channel from file '%s%s%s'\n", m_dirname, PATH_SEPARATOR, m_alphafile);
|
||||
osd_file::error const alferr = file.open(m_dirname.empty() ? m_alphafile : (m_dirname + PATH_SEPARATOR + m_alphafile));
|
||||
std::string filename;
|
||||
if (!m_searchpath.empty())
|
||||
filename = m_dirname;
|
||||
if (!filename.empty() && !util::is_directory_separator(filename[filename.size() - 1]))
|
||||
filename.append(PATH_SEPARATOR);
|
||||
filename.append(m_alphafile);
|
||||
LOGMASKED(LOG_IMAGE_LOAD, "Image component attempt to load alpha channel from file '%s'\n", filename);
|
||||
osd_file::error const alferr = file.open(filename);
|
||||
if (osd_file::error::NONE == alferr)
|
||||
{
|
||||
// TODO: no way to detect corner case where we had alpha from the image but the alpha PNG makes it entirely opaque
|
||||
@ -1725,7 +1746,7 @@ private:
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGMASKED(LOG_IMAGE_LOAD, "Image component unable to open alpha channel file '%s%s%s'\n", m_dirname, PATH_SEPARATOR, m_alphafile);
|
||||
LOGMASKED(LOG_IMAGE_LOAD, "Image component unable to open alpha channel file '%s'\n", filename);
|
||||
}
|
||||
}
|
||||
else if (m_svg)
|
||||
@ -1754,6 +1775,7 @@ private:
|
||||
// clear out this stuff in case it's large
|
||||
if (!m_svg)
|
||||
m_rasterizer.reset();
|
||||
m_searchpath.clear();
|
||||
m_dirname.clear();
|
||||
m_imagefile.clear();
|
||||
m_alphafile.clear();
|
||||
@ -1773,7 +1795,7 @@ private:
|
||||
std::string::size_type const end(m_data.find_first_not_of(base64tail, tail));
|
||||
if (std::string::npos == end)
|
||||
{
|
||||
LOGMASKED(LOG_IMAGE_LOAD, "Image component decoding Base64 image m_data\n");
|
||||
LOGMASKED(LOG_IMAGE_LOAD, "Image component decoding Base64 image data\n");
|
||||
char *dst(&m_data[0]);
|
||||
unsigned trailing(0U);
|
||||
for (std::string::size_type i = 0U; (m_data.size() > i) && ('=' != m_data[i]); ++i)
|
||||
@ -1923,6 +1945,7 @@ private:
|
||||
bool m_hasalpha = false; // is there any alpha component present?
|
||||
|
||||
// cold state
|
||||
std::string m_searchpath; // asset search path (for lazy loading)
|
||||
std::string m_dirname; // directory name of image file (for lazy loading)
|
||||
std::string m_imagefile; // name of the image file (for lazy loading)
|
||||
std::string m_alphafile; // name of the alpha file (for lazy loading)
|
||||
@ -1935,8 +1958,8 @@ class layout_element::rect_component : public component
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
rect_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
|
||||
: component(env, compnode, dirname)
|
||||
rect_component(environment &env, util::xml::data_node const &compnode)
|
||||
: component(env, compnode)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1988,8 +2011,8 @@ class layout_element::disk_component : public component
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
disk_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
|
||||
: component(env, compnode, dirname)
|
||||
disk_component(environment &env, util::xml::data_node const &compnode)
|
||||
: component(env, compnode)
|
||||
{
|
||||
}
|
||||
|
||||
@ -2054,8 +2077,8 @@ class layout_element::text_component : public component
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
text_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
|
||||
: component(env, compnode, dirname)
|
||||
text_component(environment &env, util::xml::data_node const &compnode)
|
||||
: component(env, compnode)
|
||||
{
|
||||
m_string = env.get_attribute_string(compnode, "string", "");
|
||||
m_textalign = env.get_attribute_int(compnode, "align", 0);
|
||||
@ -2081,8 +2104,8 @@ class layout_element::led7seg_component : public component
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
led7seg_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
|
||||
: component(env, compnode, dirname)
|
||||
led7seg_component(environment &env, util::xml::data_node const &compnode)
|
||||
: component(env, compnode)
|
||||
{
|
||||
}
|
||||
|
||||
@ -2143,8 +2166,8 @@ class layout_element::led8seg_gts1_component : public component
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
led8seg_gts1_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
|
||||
: component(env, compnode, dirname)
|
||||
led8seg_gts1_component(environment &env, util::xml::data_node const &compnode)
|
||||
: component(env, compnode)
|
||||
{
|
||||
}
|
||||
|
||||
@ -2211,8 +2234,8 @@ class layout_element::led14seg_component : public component
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
led14seg_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
|
||||
: component(env, compnode, dirname)
|
||||
led14seg_component(environment &env, util::xml::data_node const &compnode)
|
||||
: component(env, compnode)
|
||||
{
|
||||
}
|
||||
|
||||
@ -2323,8 +2346,8 @@ class layout_element::led16seg_component : public component
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
led16seg_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
|
||||
: component(env, compnode, dirname)
|
||||
led16seg_component(environment &env, util::xml::data_node const &compnode)
|
||||
: component(env, compnode)
|
||||
{
|
||||
}
|
||||
|
||||
@ -2445,8 +2468,8 @@ class layout_element::led14segsc_component : public component
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
led14segsc_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
|
||||
: component(env, compnode, dirname)
|
||||
led14segsc_component(environment &env, util::xml::data_node const &compnode)
|
||||
: component(env, compnode)
|
||||
{
|
||||
}
|
||||
|
||||
@ -2568,8 +2591,8 @@ class layout_element::led16segsc_component : public component
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
led16segsc_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
|
||||
: component(env, compnode, dirname)
|
||||
led16segsc_component(environment &env, util::xml::data_node const &compnode)
|
||||
: component(env, compnode)
|
||||
{
|
||||
}
|
||||
|
||||
@ -2700,8 +2723,8 @@ class layout_element::dotmatrix_component : public component
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
dotmatrix_component(int dots, environment &env, util::xml::data_node const &compnode, const char *dirname)
|
||||
: component(env, compnode, dirname)
|
||||
dotmatrix_component(int dots, environment &env, util::xml::data_node const &compnode)
|
||||
: component(env, compnode)
|
||||
, m_dots(dots)
|
||||
{
|
||||
}
|
||||
@ -2741,8 +2764,8 @@ class layout_element::simplecounter_component : public component
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
simplecounter_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
|
||||
: component(env, compnode, dirname)
|
||||
simplecounter_component(environment &env, util::xml::data_node const &compnode)
|
||||
: component(env, compnode)
|
||||
, m_digits(env.get_attribute_int(compnode, "digits", 2))
|
||||
, m_textalign(env.get_attribute_int(compnode, "align", 0))
|
||||
, m_maxstate(env.get_attribute_int(compnode, "maxstate", 999))
|
||||
@ -2774,49 +2797,30 @@ class layout_element::reel_component : public component
|
||||
|
||||
public:
|
||||
// construction/destruction
|
||||
reel_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
|
||||
: component(env, compnode, dirname)
|
||||
reel_component(environment &env, util::xml::data_node const &compnode)
|
||||
: component(env, compnode)
|
||||
, m_searchpath(env.search_path() ? env.search_path() : "")
|
||||
, m_dirname(env.directory_name() ? env.directory_name() : "")
|
||||
{
|
||||
for (auto & elem : m_hasalpha)
|
||||
elem = false;
|
||||
|
||||
std::string symbollist = env.get_attribute_string(compnode, "symbollist", "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15");
|
||||
|
||||
// split out position names from string and figure out our number of symbols
|
||||
int location;
|
||||
m_numstops = 0;
|
||||
location=symbollist.find(',');
|
||||
while (location!=-1)
|
||||
for (std::string::size_type location = symbollist.find(','); std::string::npos != location; location = symbollist.find(','))
|
||||
{
|
||||
m_stopnames[m_numstops] = symbollist;
|
||||
m_stopnames[m_numstops] = m_stopnames[m_numstops].substr(0, location);
|
||||
symbollist = symbollist.substr(location+1, symbollist.length()-(location-1));
|
||||
m_stopnames[m_numstops] = symbollist.substr(0, location);
|
||||
symbollist.erase(0, location + 1);
|
||||
m_numstops++;
|
||||
location=symbollist.find(',');
|
||||
}
|
||||
m_stopnames[m_numstops++] = symbollist;
|
||||
|
||||
// careful, dirname is nullptr if we're coming from internal layout, and our string assignment doesn't like that
|
||||
if (dirname != nullptr)
|
||||
m_dirname = dirname;
|
||||
|
||||
for (int i=0;i<m_numstops;i++)
|
||||
for (int i = 0; i < m_numstops; i++)
|
||||
{
|
||||
location=m_stopnames[i].find(':');
|
||||
if (location!=-1)
|
||||
std::string::size_type const location = m_stopnames[i].find(':');
|
||||
if (location != std::string::npos)
|
||||
{
|
||||
m_imagefile[i] = m_stopnames[i];
|
||||
m_stopnames[i] = m_stopnames[i].substr(0, location);
|
||||
m_imagefile[i] = m_imagefile[i].substr(location+1, m_imagefile[i].length()-(location-1));
|
||||
|
||||
//m_alphafile[i] =
|
||||
m_file[i] = std::make_unique<emu_file>(env.machine().options().art_path(), OPEN_FLAG_READ);
|
||||
}
|
||||
else
|
||||
{
|
||||
//m_imagefile[i] = 0;
|
||||
//m_alphafile[i] = 0;
|
||||
m_file[i].reset();
|
||||
m_imagefile[i] = m_stopnames[i].substr(location + 1);
|
||||
m_stopnames[i].erase(location);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2829,6 +2833,17 @@ public:
|
||||
protected:
|
||||
// overrides
|
||||
virtual int maxstate() const override { return 65535; }
|
||||
|
||||
virtual void preload(running_machine &machine) override
|
||||
{
|
||||
for (int i = 0; i < m_numstops; i++)
|
||||
{
|
||||
if (!m_imagefile[i].empty() && !m_bitmap[i].valid())
|
||||
load_reel_bitmap(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override
|
||||
{
|
||||
if (m_beltreel)
|
||||
@ -2850,16 +2865,12 @@ protected:
|
||||
u32 const b = c.b * 255.0f;
|
||||
u32 const a = c.a * 255.0f;
|
||||
|
||||
// get the width of the string
|
||||
auto font = machine.render().font_alloc("default");
|
||||
float aspect = 1.0f;
|
||||
s32 width;
|
||||
|
||||
int curry = 0;
|
||||
int num_shown = m_numsymbolsvisible;
|
||||
|
||||
int ourheight = bounds.height();
|
||||
|
||||
auto font = machine.render().font_alloc("default");
|
||||
for (int fruit = 0;fruit<m_numstops;fruit++)
|
||||
{
|
||||
int basey;
|
||||
@ -2884,47 +2895,31 @@ protected:
|
||||
// only render the symbol / text if it's actually in view because the code is SLOW
|
||||
if ((endpos >= bounds.top()) && (basey <= bounds.bottom()))
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
width = font->string_width(ourheight / num_shown, aspect, m_stopnames[fruit].c_str());
|
||||
if (width < bounds.width())
|
||||
break;
|
||||
aspect *= 0.9f;
|
||||
}
|
||||
if (!m_imagefile[fruit].empty() && !m_bitmap[fruit].valid())
|
||||
load_reel_bitmap(fruit);
|
||||
|
||||
s32 curx;
|
||||
curx = bounds.left() + (bounds.width() - width) / 2;
|
||||
|
||||
if (m_file[fruit])
|
||||
if (!m_bitmap[fruit].valid())
|
||||
load_reel_bitmap(fruit);
|
||||
|
||||
if (m_file[fruit]) // render gfx
|
||||
if (m_bitmap[fruit].valid()) // render gfx
|
||||
{
|
||||
bitmap_argb32 tempbitmap2(dest.width(), ourheight/num_shown);
|
||||
render_resample_argb_bitmap_hq(tempbitmap2, m_bitmap[fruit], c);
|
||||
|
||||
if (m_bitmap[fruit].valid())
|
||||
for (int y = 0; y < ourheight/num_shown; y++)
|
||||
{
|
||||
render_resample_argb_bitmap_hq(tempbitmap2, m_bitmap[fruit], c);
|
||||
int effy = basey + y;
|
||||
|
||||
for (int y = 0; y < ourheight/num_shown; y++)
|
||||
if (effy >= bounds.top() && effy <= bounds.bottom())
|
||||
{
|
||||
int effy = basey + y;
|
||||
|
||||
if (effy >= bounds.top() && effy <= bounds.bottom())
|
||||
u32 const *const src = &tempbitmap2.pix(y);
|
||||
u32 *const d = &dest.pix(effy);
|
||||
for (int x = 0; x < dest.width(); x++)
|
||||
{
|
||||
u32 const *const src = &tempbitmap2.pix(y);
|
||||
u32 *const d = &dest.pix(effy);
|
||||
for (int x = 0; x < dest.width(); x++)
|
||||
int effx = x;
|
||||
if (effx >= bounds.left() && effx <= bounds.right())
|
||||
{
|
||||
int effx = x;
|
||||
if (effx >= bounds.left() && effx <= bounds.right())
|
||||
u32 spix = rgb_t(src[x]).a();
|
||||
if (spix != 0)
|
||||
{
|
||||
u32 spix = rgb_t(src[x]).a();
|
||||
if (spix != 0)
|
||||
{
|
||||
d[effx] = src[x];
|
||||
}
|
||||
d[effx] = src[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2941,6 +2936,20 @@ protected:
|
||||
const char *s = origs;
|
||||
char32_t schar;
|
||||
|
||||
// get the width of the string
|
||||
float aspect = 1.0f;
|
||||
s32 width;
|
||||
|
||||
while (1)
|
||||
{
|
||||
width = font->string_width(ourheight / num_shown, aspect, m_stopnames[fruit].c_str());
|
||||
if (width < bounds.width())
|
||||
break;
|
||||
aspect *= 0.9f;
|
||||
}
|
||||
|
||||
s32 curx = bounds.left() + (bounds.width() - width) / 2;
|
||||
|
||||
// loop over characters
|
||||
while (*s != 0)
|
||||
{
|
||||
@ -3011,15 +3020,12 @@ private:
|
||||
u32 const b = c.b * 255.0f;
|
||||
u32 const a = c.a * 255.0f;
|
||||
|
||||
// get the width of the string
|
||||
auto font = machine.render().font_alloc("default");
|
||||
float aspect = 1.0f;
|
||||
s32 width;
|
||||
int currx = 0;
|
||||
int num_shown = m_numsymbolsvisible;
|
||||
|
||||
int ourwidth = bounds.width();
|
||||
|
||||
auto font = machine.render().font_alloc("default");
|
||||
for (int fruit = 0;fruit<m_numstops;fruit++)
|
||||
{
|
||||
int basex;
|
||||
@ -3043,56 +3049,53 @@ private:
|
||||
// only render the symbol / text if it's actually in view because the code is SLOW
|
||||
if ((endpos >= bounds.left()) && (basex <= bounds.right()))
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
width = font->string_width(dest.height(), aspect, m_stopnames[fruit].c_str());
|
||||
if (width < bounds.width())
|
||||
break;
|
||||
aspect *= 0.9f;
|
||||
}
|
||||
if (!m_imagefile[fruit].empty() && !m_bitmap[fruit].valid())
|
||||
load_reel_bitmap(fruit);
|
||||
|
||||
s32 curx;
|
||||
curx = bounds.left();
|
||||
|
||||
if (m_file[fruit])
|
||||
if (!m_bitmap[fruit].valid())
|
||||
load_reel_bitmap(fruit);
|
||||
|
||||
if (m_file[fruit]) // render gfx
|
||||
if (m_bitmap[fruit].valid()) // render gfx
|
||||
{
|
||||
bitmap_argb32 tempbitmap2(ourwidth/num_shown, dest.height());
|
||||
render_resample_argb_bitmap_hq(tempbitmap2, m_bitmap[fruit], c);
|
||||
|
||||
if (m_bitmap[fruit].valid())
|
||||
for (int y = 0; y < dest.height(); y++)
|
||||
{
|
||||
render_resample_argb_bitmap_hq(tempbitmap2, m_bitmap[fruit], c);
|
||||
int effy = y;
|
||||
|
||||
for (int y = 0; y < dest.height(); y++)
|
||||
if (effy >= bounds.top() && effy <= bounds.bottom())
|
||||
{
|
||||
int effy = y;
|
||||
|
||||
if (effy >= bounds.top() && effy <= bounds.bottom())
|
||||
u32 const *const src = &tempbitmap2.pix(y);
|
||||
u32 *const d = &dest.pix(effy);
|
||||
for (int x = 0; x < ourwidth/num_shown; x++)
|
||||
{
|
||||
u32 const *const src = &tempbitmap2.pix(y);
|
||||
u32 *const d = &dest.pix(effy);
|
||||
for (int x = 0; x < ourwidth/num_shown; x++)
|
||||
int effx = basex + x;
|
||||
if (effx >= bounds.left() && effx <= bounds.right())
|
||||
{
|
||||
int effx = basex + x;
|
||||
if (effx >= bounds.left() && effx <= bounds.right())
|
||||
u32 spix = rgb_t(src[x]).a();
|
||||
if (spix != 0)
|
||||
{
|
||||
u32 spix = rgb_t(src[x]).a();
|
||||
if (spix != 0)
|
||||
{
|
||||
d[effx] = src[x];
|
||||
}
|
||||
d[effx] = src[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else // render text (fallback)
|
||||
{
|
||||
// get the width of the string
|
||||
float aspect = 1.0f;
|
||||
s32 width;
|
||||
while (1)
|
||||
{
|
||||
width = font->string_width(dest.height(), aspect, m_stopnames[fruit].c_str());
|
||||
if (width < bounds.width())
|
||||
break;
|
||||
aspect *= 0.9f;
|
||||
}
|
||||
|
||||
s32 curx = bounds.left();
|
||||
|
||||
// allocate a temporary bitmap
|
||||
bitmap_argb32 tempbitmap(dest.width(), dest.height());
|
||||
|
||||
@ -3157,34 +3160,29 @@ private:
|
||||
|
||||
void load_reel_bitmap(int number)
|
||||
{
|
||||
// load the basic bitmap
|
||||
assert(m_file != nullptr);
|
||||
if (m_file[number]->open(m_dirname + PATH_SEPARATOR + m_imagefile[number]) == osd_file::error::NONE)
|
||||
{
|
||||
/*m_hasalpha[number] = */ render_load_png(m_bitmap[number], *m_file[number]);
|
||||
m_file[number]->close();
|
||||
}
|
||||
emu_file file(m_searchpath.empty() ? m_dirname : m_searchpath, OPEN_FLAG_READ);
|
||||
std::string filename;
|
||||
if (!m_searchpath.empty())
|
||||
filename = m_dirname;
|
||||
if (!filename.empty() && !util::is_directory_separator(filename[filename.size() - 1]))
|
||||
filename.append(PATH_SEPARATOR);
|
||||
filename.append(m_imagefile[number]);
|
||||
|
||||
// load the alpha bitmap if specified
|
||||
//if (m_bitmap[number].valid() && m_alphafile[number])
|
||||
// render_load_png(m_bitmap[number], *m_file[number], m_dirname, m_alphafile[number], true);
|
||||
// load the basic bitmap
|
||||
if (file.open(filename) == osd_file::error::NONE)
|
||||
render_load_png(m_bitmap[number], file);
|
||||
|
||||
// if we can't load the bitmap just use text rendering
|
||||
if (!m_bitmap[number].valid())
|
||||
{
|
||||
// fallback to text rendering
|
||||
m_file[number].reset();
|
||||
}
|
||||
m_imagefile[number].clear();
|
||||
|
||||
}
|
||||
|
||||
// internal state
|
||||
bitmap_argb32 m_bitmap[MAX_BITMAPS]; // source bitmap for images
|
||||
std::string m_searchpath; // asset search path (for lazy loading)
|
||||
std::string m_dirname; // directory name of image file (for lazy loading)
|
||||
std::unique_ptr<emu_file> m_file[MAX_BITMAPS]; // file object for reading image/alpha files
|
||||
std::string m_imagefile[MAX_BITMAPS]; // name of the image file (for lazy loading)
|
||||
std::string m_alphafile[MAX_BITMAPS]; // name of the alpha file (for lazy loading)
|
||||
bool m_hasalpha[MAX_BITMAPS]; // is there any alpha component present?
|
||||
|
||||
// basically made up of multiple text strings / gfx
|
||||
int m_numstops;
|
||||
@ -3201,9 +3199,9 @@ private:
|
||||
//-------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
layout_element::component::ptr layout_element::make_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
|
||||
layout_element::component::ptr layout_element::make_component(environment &env, util::xml::data_node const &compnode)
|
||||
{
|
||||
return std::make_unique<T>(env, compnode, dirname);
|
||||
return std::make_unique<T>(env, compnode);
|
||||
}
|
||||
|
||||
|
||||
@ -3213,9 +3211,9 @@ layout_element::component::ptr layout_element::make_component(environment &env,
|
||||
//-------------------------------------------------
|
||||
|
||||
template <int D>
|
||||
layout_element::component::ptr layout_element::make_dotmatrix_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
|
||||
layout_element::component::ptr layout_element::make_dotmatrix_component(environment &env, util::xml::data_node const &compnode)
|
||||
{
|
||||
return std::make_unique<dotmatrix_component>(D, env, compnode, dirname);
|
||||
return std::make_unique<dotmatrix_component>(D, env, compnode);
|
||||
}
|
||||
|
||||
|
||||
@ -3276,7 +3274,7 @@ layout_element::texture &layout_element::texture::operator=(texture &&that)
|
||||
// component - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
layout_element::component::component(environment &env, util::xml::data_node const &compnode, const char *dirname)
|
||||
layout_element::component::component(environment &env, util::xml::data_node const &compnode)
|
||||
: m_statemask(env.get_attribute_int(compnode, "statemask", env.get_attribute_string(compnode, "state", "")[0] ? ~0 : 0))
|
||||
, m_stateval(env.get_attribute_int(compnode, "state", m_statemask) & m_statemask)
|
||||
{
|
||||
@ -4576,13 +4574,17 @@ layout_view::visibility_toggle::visibility_toggle(std::string &&name, u32 mask)
|
||||
// layout_file - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
layout_file::layout_file(device_t &device, util::xml::data_node const &rootnode, char const *dirname)
|
||||
layout_file::layout_file(
|
||||
device_t &device,
|
||||
util::xml::data_node const &rootnode,
|
||||
char const *searchpath,
|
||||
char const *dirname)
|
||||
: m_elemmap()
|
||||
, m_viewlist()
|
||||
{
|
||||
try
|
||||
{
|
||||
environment env(device);
|
||||
environment env(device, searchpath, dirname);
|
||||
|
||||
// find the layout node
|
||||
util::xml::data_node const *const mamelayoutnode = rootnode.get_child("mamelayout");
|
||||
@ -4596,7 +4598,7 @@ layout_file::layout_file(device_t &device, util::xml::data_node const &rootnode,
|
||||
|
||||
// parse all the parameters, elements and groups
|
||||
group_map groupmap;
|
||||
add_elements(dirname, env, *mamelayoutnode, groupmap, false, true);
|
||||
add_elements(env, *mamelayoutnode, groupmap, false, true);
|
||||
|
||||
// parse all the views
|
||||
for (util::xml::data_node const *viewnode = mamelayoutnode->get_child("view"); viewnode != nullptr; viewnode = viewnode->get_next_sibling("view"))
|
||||
@ -4633,7 +4635,6 @@ layout_file::~layout_file()
|
||||
|
||||
|
||||
void layout_file::add_elements(
|
||||
char const *dirname,
|
||||
environment &env,
|
||||
util::xml::data_node const &parentnode,
|
||||
group_map &groupmap,
|
||||
@ -4654,7 +4655,7 @@ void layout_file::add_elements(
|
||||
char const *const name(env.get_attribute_string(*childnode, "name", nullptr));
|
||||
if (!name)
|
||||
throw layout_syntax_error("element lacks name attribute");
|
||||
if (!m_elemmap.emplace(std::piecewise_construct, std::forward_as_tuple(name), std::forward_as_tuple(env, *childnode, dirname)).second)
|
||||
if (!m_elemmap.emplace(std::piecewise_construct, std::forward_as_tuple(name), std::forward_as_tuple(env, *childnode)).second)
|
||||
throw layout_syntax_error(util::string_format("duplicate element name %s", name));
|
||||
}
|
||||
else if (!strcmp(childnode->get_name(), "group"))
|
||||
@ -4673,7 +4674,7 @@ void layout_file::add_elements(
|
||||
environment local(env);
|
||||
for (int i = 0; count > i; ++i)
|
||||
{
|
||||
add_elements(dirname, local, *childnode, groupmap, true, !i);
|
||||
add_elements(local, *childnode, groupmap, true, !i);
|
||||
local.increment_parameters();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user