mirror of
https://github.com/holub/mame
synced 2025-04-09 18:17:44 +03:00
-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.
This commit is contained in:
parent
d12235d009
commit
25fa1ff89a
@ -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
|
||||
|
@ -440,7 +440,7 @@ private:
|
||||
|
||||
lcd_regs_t regs;
|
||||
emu_timer *timer;
|
||||
std::unique_ptr<bitmap_rgb32> bitmap[2];
|
||||
bitmap_rgb32 bitmap[2];
|
||||
uint32_t vramaddr_cur;
|
||||
uint32_t vramaddr_max;
|
||||
uint32_t offsize;
|
||||
|
@ -543,7 +543,7 @@ private:
|
||||
|
||||
lcd_regs_t regs;
|
||||
emu_timer *timer;
|
||||
std::unique_ptr<bitmap_rgb32> bitmap[2];
|
||||
bitmap_rgb32 bitmap[2];
|
||||
uint32_t vramaddr_cur;
|
||||
uint32_t vramaddr_max;
|
||||
uint32_t offsize;
|
||||
|
@ -587,7 +587,7 @@ private:
|
||||
|
||||
lcd_regs_t regs;
|
||||
emu_timer *timer;
|
||||
std::unique_ptr<bitmap_rgb32> bitmap[2];
|
||||
bitmap_rgb32 bitmap[2];
|
||||
uint32_t vramaddr_cur;
|
||||
uint32_t vramaddr_max;
|
||||
uint32_t offsize;
|
||||
|
@ -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<bitmap_rgb32>(m_screen->width(), m_screen->height());
|
||||
m_lcd.bitmap[1] = std::make_unique<bitmap_rgb32>(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();
|
||||
}
|
||||
|
@ -106,6 +106,25 @@ private:
|
||||
using device_type_set = std::set<std::add_pointer_t<device_type>, device_type_compare>;
|
||||
using device_type_vector = std::vector<std::add_pointer_t<device_type> >;
|
||||
|
||||
|
||||
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<std::string>
|
||||
// known (and filtered) machines
|
||||
//-------------------------------------------------
|
||||
|
||||
void info_xml_creator::output(std::ostream &out, const std::function<bool(const char *shortname, bool &done)> &filter, bool include_devices)
|
||||
void info_xml_creator::output(std::ostream &out, const std::function<bool (const char *shortname, bool &done)> &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::function<bool(const
|
||||
break;
|
||||
|
||||
// do the dirty work asynchronously
|
||||
auto task_proc = [&drivlist, drivers = std::move(drivers), include_devices, &active_task_count]
|
||||
auto task_proc = [&drivlist, drivers = std::move(drivers), collect_devices = bool(devset), &active_task_count]
|
||||
{
|
||||
prepared_info result;
|
||||
std::ostringstream stream;
|
||||
@ -533,7 +535,7 @@ void info_xml_creator::output(std::ostream &out, const std::function<bool(const
|
||||
|
||||
// output each of the drivers
|
||||
for (const game_driver &driver : drivers)
|
||||
output_one(stream, drivlist, driver, include_devices ? &result.m_dev_set : nullptr);
|
||||
output_one(stream, drivlist, driver, collect_devices ? &result.m_dev_set : nullptr);
|
||||
|
||||
// capture the XML snippet
|
||||
result.m_xml_snippet = std::move(stream).str();
|
||||
@ -581,7 +583,7 @@ void info_xml_creator::output(std::ostream &out, const std::function<bool(const
|
||||
}
|
||||
}
|
||||
|
||||
// output devices (both devices with roms and slot devices)
|
||||
// output devices
|
||||
if (include_devices && (!devset || !devset->empty()))
|
||||
{
|
||||
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</%s>\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<std::future<std::string> > tasks;
|
||||
std::queue<std::future<prepared_info> > tasks;
|
||||
std::atomic<unsigned int> 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; });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user