From 25fa1ff89a95cde45eda378e177806ef80dffa04 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Thu, 13 Mar 2025 16:45:07 +1100 Subject: [PATCH] -Fixed some -listxml issues: * frontend/mame/infoxml.cpp: Recursively discover device types when filtering output. * frontend/mame/infoxml.cpp: Don't waste time/memory collecting device types when not filtering. * scripts/target/mame: Sort driver projects and sources within driver projects to give more determinisitc output on filesystems that don't enumerate in order by filename (e.g. XFS or ext). -machine/s3c24xx.hxx: Got rid of a layer of indirection on LCD bitmaps. --- scripts/target/mame/mame.lua | 2 + src/devices/machine/s3c2400.h | 2 +- src/devices/machine/s3c2410.h | 2 +- src/devices/machine/s3c2440.h | 2 +- src/devices/machine/s3c24xx.hxx | 34 +++++------ src/frontend/mame/infoxml.cpp | 99 ++++++++++++++++++++++----------- 6 files changed, 88 insertions(+), 53 deletions(-) diff --git a/scripts/target/mame/mame.lua b/scripts/target/mame/mame.lua index 457429507e6..06df39602a6 100644 --- a/scripts/target/mame/mame.lua +++ b/scripts/target/mame/mame.lua @@ -52,6 +52,7 @@ function linkProjects_mame_mame(_target, _subtarget) end end end + table.sort(projects) table.insert(projects, "shared") -- must stay at the end links(projects) end @@ -105,6 +106,7 @@ function createProjects_mame_mame(_target, _subtarget) if 0 < #sources then createMAMEProjects(_target, _subtarget, name) + table.sort(sources) files(sources) end end diff --git a/src/devices/machine/s3c2400.h b/src/devices/machine/s3c2400.h index 2cc19885eea..a2726374b9e 100644 --- a/src/devices/machine/s3c2400.h +++ b/src/devices/machine/s3c2400.h @@ -440,7 +440,7 @@ private: lcd_regs_t regs; emu_timer *timer; - std::unique_ptr bitmap[2]; + bitmap_rgb32 bitmap[2]; uint32_t vramaddr_cur; uint32_t vramaddr_max; uint32_t offsize; diff --git a/src/devices/machine/s3c2410.h b/src/devices/machine/s3c2410.h index 85c5a442f3e..594200a1f16 100644 --- a/src/devices/machine/s3c2410.h +++ b/src/devices/machine/s3c2410.h @@ -543,7 +543,7 @@ private: lcd_regs_t regs; emu_timer *timer; - std::unique_ptr bitmap[2]; + bitmap_rgb32 bitmap[2]; uint32_t vramaddr_cur; uint32_t vramaddr_max; uint32_t offsize; diff --git a/src/devices/machine/s3c2440.h b/src/devices/machine/s3c2440.h index 8bbc720971a..64f614bc208 100644 --- a/src/devices/machine/s3c2440.h +++ b/src/devices/machine/s3c2440.h @@ -587,7 +587,7 @@ private: lcd_regs_t regs; emu_timer *timer; - std::unique_ptr bitmap[2]; + bitmap_rgb32 bitmap[2]; uint32_t vramaddr_cur; uint32_t vramaddr_max; uint32_t offsize; diff --git a/src/devices/machine/s3c24xx.hxx b/src/devices/machine/s3c24xx.hxx index 15835cb6122..fd467104fbd 100644 --- a/src/devices/machine/s3c24xx.hxx +++ b/src/devices/machine/s3c24xx.hxx @@ -422,7 +422,7 @@ uint32_t S3C24_CLASS_NAME::s3c24xx_lcd_dma_read_bits(int count) void S3C24_CLASS_NAME::s3c24xx_lcd_render_tpal() { - bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; + bitmap_rgb32 &bitmap = m_lcd.bitmap[0]; uint32_t color = s3c24xx_get_color_tpal(); for (int y = m_lcd.vpos_min; y <= m_lcd.vpos_max; y++) { @@ -436,7 +436,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_tpal() void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_01() { - bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; + bitmap_rgb32 &bitmap = m_lcd.bitmap[0]; uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { @@ -467,7 +467,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_01() void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_02() { - bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; + bitmap_rgb32 &bitmap = m_lcd.bitmap[0]; uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { @@ -490,7 +490,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_02() void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_04() { - bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; + bitmap_rgb32 &bitmap = m_lcd.bitmap[0]; uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { @@ -513,7 +513,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_04() void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_08() { - bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; + bitmap_rgb32 &bitmap = m_lcd.bitmap[0]; uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { @@ -536,7 +536,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_08() void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_12_p() { - bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; + bitmap_rgb32 &bitmap = m_lcd.bitmap[0]; uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 16; i++) { @@ -554,7 +554,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_12_p() void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_12_u() // not tested { - bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; + bitmap_rgb32 &bitmap = m_lcd.bitmap[0]; uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { @@ -577,7 +577,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_12_u() // not tested void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_01() { - bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; + bitmap_rgb32 &bitmap = m_lcd.bitmap[0]; uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { @@ -600,7 +600,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_01() void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_02() { - bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; + bitmap_rgb32 &bitmap = m_lcd.bitmap[0]; uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { @@ -623,7 +623,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_02() void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_04() { - bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; + bitmap_rgb32 &bitmap = m_lcd.bitmap[0]; uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { @@ -646,7 +646,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_04() void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_08() { - bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; + bitmap_rgb32 &bitmap = m_lcd.bitmap[0]; uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { @@ -669,7 +669,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_08() void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_16() { - bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; + bitmap_rgb32 &bitmap = m_lcd.bitmap[0]; uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { @@ -733,8 +733,8 @@ TIMER_CALLBACK_MEMBER( S3C24_CLASS_NAME::s3c24xx_lcd_timer_exp ) void S3C24_CLASS_NAME::s3c24xx_video_start() { - m_lcd.bitmap[0] = std::make_unique(m_screen->width(), m_screen->height()); - m_lcd.bitmap[1] = std::make_unique(m_screen->width(), m_screen->height()); + m_lcd.bitmap[0].allocate(m_screen->width(), m_screen->height()); + m_lcd.bitmap[1].allocate(m_screen->width(), m_screen->height()); m_cpu->space(AS_PROGRAM).cache(m_cache); } @@ -770,12 +770,12 @@ uint32_t S3C24_CLASS_NAME::s3c24xx_video_update(screen_device &screen, bitmap_rg { if (m_lcd.framerate >= 1195) { - bitmap_blend( bitmap, *m_lcd.bitmap[0], *m_lcd.bitmap[1]); - copybitmap( *m_lcd.bitmap[1], *m_lcd.bitmap[0], 0, 0, 0, 0, cliprect); + bitmap_blend(bitmap, m_lcd.bitmap[0], m_lcd.bitmap[1]); + copybitmap(m_lcd.bitmap[1], m_lcd.bitmap[0], 0, 0, 0, 0, cliprect); } else { - copybitmap( bitmap, *m_lcd.bitmap[0], 0, 0, 0, 0, cliprect); + copybitmap(bitmap, m_lcd.bitmap[0], 0, 0, 0, 0, cliprect); } s3c24xx_lcd_dma_init(); } diff --git a/src/frontend/mame/infoxml.cpp b/src/frontend/mame/infoxml.cpp index 95ca0826ede..b81aab7d8d0 100644 --- a/src/frontend/mame/infoxml.cpp +++ b/src/frontend/mame/infoxml.cpp @@ -106,6 +106,25 @@ private: using device_type_set = std::set, device_type_compare>; using device_type_vector = std::vector >; + +struct prepared_info +{ + prepared_info() = default; + prepared_info(const prepared_info &) = delete; + prepared_info(prepared_info &&) = default; +#if defined(_CPPLIB_VER) && defined(_MSVC_STL_VERSION) + // MSVCPRT currently requires default-constructible std::future promise types to be assignable + // remove this workaround when that's fixed + prepared_info &operator=(const prepared_info &) = default; +#else + prepared_info &operator=(const prepared_info &) = delete; +#endif + + std::string m_xml_snippet; + device_type_set m_dev_set; +}; + + // internal helper void output_header(std::ostream &out, bool dtd); void output_footer(std::ostream &out); @@ -131,8 +150,8 @@ void output_slots(std::ostream &out, machine_config &config, device_t &device, c void output_software_lists(std::ostream &out, device_t &root, const char *root_tag); void output_ramoptions(std::ostream &out, device_t &root); -void output_one_device(std::ostream &out, machine_config &config, device_t &device, const char *devtag); -void output_devices(std::ostream &out, emu_options &lookup_options, device_type_set const *filter); +void output_one_device(std::ostream &out, machine_config &config, device_t &device, const char *devtag, device_type_set *devtypes); +void output_devices(std::ostream &out, emu_options &lookup_options, device_type_set *filter); char const *get_merge_name(driver_list const &drivlist, game_driver const &driver, util::hash_collection const &romhashes); char const *get_merge_name(machine_config &config, device_t const &device, util::hash_collection const &romhashes); @@ -459,25 +478,8 @@ void info_xml_creator::output(std::ostream &out, const std::vector // known (and filtered) machines //------------------------------------------------- -void info_xml_creator::output(std::ostream &out, const std::function &filter, bool include_devices) +void info_xml_creator::output(std::ostream &out, const std::function &filter, bool include_devices) { - struct prepared_info - { - prepared_info() = default; - prepared_info(const prepared_info &) = delete; - prepared_info(prepared_info &&) = default; -#if defined(_CPPLIB_VER) && defined(_MSVC_STL_VERSION) - // MSVCPRT currently requires default-constructible std::future promise types to be assignable - // remove this workaround when that's fixed - prepared_info &operator=(const prepared_info &) = default; -#else - prepared_info &operator=(const prepared_info &) = delete; -#endif - - std::string m_xml_snippet; - device_type_set m_dev_set; - }; - // prepare a driver enumerator and the queue driver_enumerator drivlist(m_lookup_options); device_filter devfilter(filter); @@ -525,7 +527,7 @@ void info_xml_creator::output(std::ostream &out, const std::functionempty())) { output_header_if_necessary(out); @@ -806,7 +808,7 @@ void output_one(std::ostream &out, driver_enumerator &drivlist, const game_drive // a single device //------------------------------------------------- -void output_one_device(std::ostream &out, machine_config &config, device_t &device, const char *devtag) +void output_one_device(std::ostream &out, machine_config &config, device_t &device, const char *devtag, device_type_set *devtypes) { using util::xml::normalize_string; @@ -827,6 +829,8 @@ void output_one_device(std::ostream &out, machine_config &config, device_t &devi portlist.append(dev, errors); overall_unemulated |= dev.type().unemulated_features(); overall_imperfect |= dev.type().imperfect_features(); + + devtypes->insert(&device.type()); } } @@ -871,7 +875,7 @@ void output_one_device(std::ostream &out, machine_config &config, device_t &devi output_adjusters(out, portlist); output_features(out, device.type(), overall_unemulated, overall_imperfect); output_images(out, device, devtag); - output_slots(out, config, device, devtag, nullptr); + output_slots(out, config, device, devtag, devtypes); output_software_lists(out, device, devtag); util::stream_format(out, "\t\n", XML_TOP); } @@ -882,12 +886,13 @@ void output_one_device(std::ostream &out, machine_config &config, device_t &devi // registered device types //------------------------------------------------- -void output_devices(std::ostream &out, emu_options &lookup_options, device_type_set const *filter) +void output_devices(std::ostream &out, emu_options &lookup_options, device_type_set *filter) { - auto const action = [&lookup_options, &out] (auto &types, auto deref) + device_type_set catchup; + auto const action = [&lookup_options, &out, filter, &catchup] (auto &types, auto deref) { // machinery for making output order deterministic and capping outstanding tasks - std::queue > tasks; + std::queue > tasks; std::atomic active_task_count = 0; unsigned int const maximum_active_task_count = std::thread::hardware_concurrency() + 10; unsigned int const maximum_outstanding_task_count = maximum_active_task_count + 20; @@ -909,10 +914,11 @@ void output_devices(std::ostream &out, emu_options &lookup_options, device_type_ break; // do the dirty work asynchronously - auto task_proc = [&active_task_count, &lookup_options, batch = std::move(batch)] + auto task_proc = [&active_task_count, &lookup_options, batch = std::move(batch), collect_devices = bool(filter)] { // use a single machine configuration and stream for a batch of devices machine_config config(GAME_NAME(___empty), lookup_options); + prepared_info result; std::ostringstream stream; stream.imbue(std::locale::classic()); for (auto type : batch) @@ -930,14 +936,17 @@ void output_devices(std::ostream &out, emu_options &lookup_options, device_type_ device.config_complete(); // print details and remove it - output_one_device(stream, config, *dev, dev->tag()); + output_one_device(stream, config, *dev, dev->tag(), collect_devices ? &result.m_dev_set : nullptr); machine_config::token const tok(config.begin_configuration(config.root_device())); config.device_remove("_tmp"); } + // capture the XML snippet + result.m_xml_snippet = std::move(stream).str(); + // we're done with the task; decrement the counter and return active_task_count--; - return std::move(stream).str(); + return result; }; // add this task to the queue @@ -949,20 +958,44 @@ void output_devices(std::ostream &out, emu_options &lookup_options, device_type_ if (!tasks.empty()) { // wait for the oldest task to complete and get the info, in the spirit of determinism - std::string snippet = tasks.front().get(); + prepared_info pi = tasks.front().get(); tasks.pop(); // emit whatever XML we accumulated in the task - out << snippet; + out << pi.m_xml_snippet; + + // recursively collect device types if necessary + if (filter) + { + for (const auto &x : pi.m_dev_set) + { + if (filter->find(x) == filter->end()) + catchup.insert(x); + } + } } } }; // run through devices if (filter) + { action(*filter, [] (auto &x) { return x; }); + + // repeat until no more device types are discovered + while (!catchup.empty()) + { + for (const auto &x : catchup) + filter->insert(x); + device_type_set more = std::move(catchup); + catchup = device_type_set(); + action(more, [] (auto &x) { return x; }); + } + } else + { action(registered_device_types, [] (auto &x) { return &x; }); + } }