From a7e393b36b57cead61978f332135a509b2ddc82a Mon Sep 17 00:00:00 2001 From: AJR Date: Thu, 31 Mar 2016 09:43:53 -0400 Subject: [PATCH] Iterate over core classes C++11 style C++11 range-based for loops can now iterate over simple_list, tagged_list, core_options, device_t::subdevice_list, device_t::interface_list, render_primitive_list and all subclasses of the above, and much code has been refactored to use them. Most core classes that have these lists as members now have methods that return the lists themselves, replacing most of the methods that returned the object at an owned list's head. (A few have been retained due to their use in drivers or OSD.) device_t now manages subdevice and interface lists through subclasses, but has given up the work of adding and removing subdevices to machine_config. memory_manager has its tagged lists exposed, though the old rooted tag lookup methods have been removed (they were privatized already). --- src/devices/bus/abcbus/abc890.cpp | 4 +- src/devices/bus/ti99_peb/bwg.cpp | 8 +- src/devices/bus/ti99_peb/peribox.cpp | 2 +- src/devices/bus/ti99_peb/ti_fdc.cpp | 6 +- src/devices/bus/ti99x/gromport.cpp | 4 +- src/devices/bus/ti99x/joyport.cpp | 2 +- src/devices/machine/legscsi.cpp | 4 +- src/devices/machine/netlist.cpp | 6 +- src/devices/machine/pci.cpp | 7 +- src/emu/addrmap.cpp | 92 +++-- src/emu/audit.cpp | 24 +- src/emu/audit.h | 3 +- src/emu/cheat.cpp | 84 ++-- src/emu/cheat.h | 3 +- src/emu/clifront.cpp | 104 ++--- src/emu/crsshair.cpp | 8 +- src/emu/debug/debugcmd.cpp | 21 +- src/emu/debug/debugcpu.cpp | 7 +- src/emu/debug/debugvw.cpp | 6 +- src/emu/debug/debugvw.h | 2 +- src/emu/debug/dvbpoints.cpp | 4 +- src/emu/debug/dvdisasm.cpp | 4 +- src/emu/debug/dvmemory.cpp | 6 +- src/emu/debug/dvstate.cpp | 8 +- src/emu/debug/dvwpoints.cpp | 4 +- src/emu/debug/express.cpp | 16 +- src/emu/debug/express.h | 2 +- src/emu/device.cpp | 133 ++---- src/emu/device.h | 143 +++++-- src/emu/diexec.cpp | 2 +- src/emu/diimage.cpp | 6 +- src/emu/diimage.h | 2 +- src/emu/dimemory.cpp | 2 +- src/emu/dislot.h | 2 +- src/emu/disound.cpp | 100 ++--- src/emu/disound.h | 4 +- src/emu/distate.cpp | 2 +- src/emu/distate.h | 8 +- src/emu/emuopts.cpp | 2 +- src/emu/info.cpp | 118 +++--- src/emu/ioport.cpp | 378 +++++++++--------- src/emu/ioport.h | 12 +- src/emu/luaengine.cpp | 58 ++- src/emu/mame.cpp | 12 +- src/emu/mconfig.cpp | 94 +++-- src/emu/mconfig.h | 4 + src/emu/memory.cpp | 263 ++++++------ src/emu/memory.h | 20 +- src/emu/render.cpp | 166 ++++---- src/emu/render.h | 11 +- src/emu/rendlay.cpp | 82 ++-- src/emu/save.cpp | 54 +-- src/emu/schedule.cpp | 6 +- src/emu/screen.cpp | 24 +- src/emu/softlist.cpp | 108 ++--- src/emu/softlist.h | 11 +- src/emu/sound.cpp | 8 +- src/emu/sound.h | 2 +- src/emu/tilemap.cpp | 14 +- src/emu/ui/cheatopt.cpp | 28 +- src/emu/ui/custui.cpp | 16 +- src/emu/ui/devopt.cpp | 40 +- src/emu/ui/filesel.cpp | 2 +- src/emu/ui/inifile.cpp | 12 +- src/emu/ui/inputmap.cpp | 134 +++---- src/emu/ui/miscmenu.cpp | 10 +- src/emu/ui/optsmenu.cpp | 6 +- src/emu/ui/selgame.cpp | 14 +- src/emu/ui/selsoft.cpp | 46 +-- src/emu/ui/slotopt.cpp | 16 +- src/emu/ui/swlist.cpp | 36 +- src/emu/ui/swlist.h | 2 +- src/emu/ui/ui.cpp | 24 +- src/emu/validity.cpp | 60 +-- src/lib/util/coretmpl.h | 26 +- src/lib/util/options.cpp | 38 +- src/lib/util/options.h | 4 + src/lib/util/tagmap.h | 5 + src/mame/drivers/besta.cpp | 2 +- src/mame/drivers/galaxian.cpp | 2 +- src/mame/drivers/pasogo.cpp | 2 +- src/osd/modules/debugger/debugwin.cpp | 12 +- .../modules/debugger/osx/deviceinfoviewer.mm | 2 +- src/osd/modules/debugger/osx/devicesviewer.mm | 2 +- src/osd/modules/debugger/qt/dasmwindow.cpp | 6 +- .../debugger/qt/deviceinformationwindow.cpp | 2 +- src/osd/modules/debugger/qt/deviceswindow.cpp | 6 +- src/osd/modules/debugger/qt/memorywindow.cpp | 6 +- .../modules/debugger/win/debugviewinfo.cpp | 4 +- src/osd/modules/input/input_sdlcommon.cpp | 49 ++- src/osd/modules/input/input_windows.cpp | 33 +- src/osd/modules/render/draw13.cpp | 49 ++- src/osd/modules/render/draw13.h | 4 +- src/osd/modules/render/drawbgfx.cpp | 14 +- src/osd/modules/render/drawd3d.cpp | 126 +++--- src/osd/modules/render/drawd3d.h | 6 +- src/osd/modules/render/drawogl.cpp | 75 ++-- src/osd/modules/render/drawsdl.cpp | 10 +- src/osd/windows/winmain.cpp | 10 +- 99 files changed, 1660 insertions(+), 1573 deletions(-) diff --git a/src/devices/bus/abcbus/abc890.cpp b/src/devices/bus/abcbus/abc890.cpp index dc2b88106ae..a188c4f6e76 100644 --- a/src/devices/bus/abcbus/abc890.cpp +++ b/src/devices/bus/abcbus/abc890.cpp @@ -239,9 +239,9 @@ void abc890_t::device_start() void abc890_t::device_reset() { - for (device_t *device = first_subdevice(); device != nullptr; device = device->next()) + for (device_t &device : subdevices()) { - device->reset(); + device.reset(); } } diff --git a/src/devices/bus/ti99_peb/bwg.cpp b/src/devices/bus/ti99_peb/bwg.cpp index 4716ccedf8a..e06dfd5db23 100644 --- a/src/devices/bus/ti99_peb/bwg.cpp +++ b/src/devices/bus/ti99_peb/bwg.cpp @@ -625,10 +625,10 @@ void snug_bwg_device::device_config_complete() elem = nullptr; // Seems to be null when doing a "-listslots" - if (subdevice("0")!=nullptr) m_floppy[0] = static_cast(subdevice("0")->first_subdevice()); - if (subdevice("1")!=nullptr) m_floppy[1] = static_cast(subdevice("1")->first_subdevice()); - if (subdevice("2")!=nullptr) m_floppy[2] = static_cast(subdevice("2")->first_subdevice()); - if (subdevice("3")!=nullptr) m_floppy[3] = static_cast(subdevice("3")->first_subdevice()); + if (subdevice("0")!=nullptr) m_floppy[0] = static_cast(subdevice("0")->subdevices().first()); + if (subdevice("1")!=nullptr) m_floppy[1] = static_cast(subdevice("1")->subdevices().first()); + if (subdevice("2")!=nullptr) m_floppy[2] = static_cast(subdevice("2")->subdevices().first()); + if (subdevice("3")!=nullptr) m_floppy[3] = static_cast(subdevice("3")->subdevices().first()); } INPUT_PORTS_START( bwg_fdc ) diff --git a/src/devices/bus/ti99_peb/peribox.cpp b/src/devices/bus/ti99_peb/peribox.cpp index f91622742d1..79a2192bea6 100644 --- a/src/devices/bus/ti99_peb/peribox.cpp +++ b/src/devices/bus/ti99_peb/peribox.cpp @@ -668,7 +668,7 @@ void peribox_slot_device::device_start(void) void peribox_slot_device::device_config_complete() { m_slotnumber = get_index_from_tagname(); - device_t *carddev = first_subdevice(); + device_t *carddev = subdevices().first(); peribox_device *peb = static_cast(owner()); if (carddev != nullptr) { diff --git a/src/devices/bus/ti99_peb/ti_fdc.cpp b/src/devices/bus/ti99_peb/ti_fdc.cpp index 82585c424ce..97d5962e3cb 100644 --- a/src/devices/bus/ti99_peb/ti_fdc.cpp +++ b/src/devices/bus/ti99_peb/ti_fdc.cpp @@ -390,9 +390,9 @@ void ti_fdc_device::device_reset() void ti_fdc_device::device_config_complete() { // Seems to be null when doing a "-listslots" - if (subdevice("0")!=nullptr) m_floppy[0] = static_cast(subdevice("0")->first_subdevice()); - if (subdevice("1")!=nullptr) m_floppy[1] = static_cast(subdevice("1")->first_subdevice()); - if (subdevice("2")!=nullptr) m_floppy[2] = static_cast(subdevice("2")->first_subdevice()); + if (subdevice("0")!=nullptr) m_floppy[0] = static_cast(subdevice("0")->subdevices().first()); + if (subdevice("1")!=nullptr) m_floppy[1] = static_cast(subdevice("1")->subdevices().first()); + if (subdevice("2")!=nullptr) m_floppy[2] = static_cast(subdevice("2")->subdevices().first()); } FLOPPY_FORMATS_MEMBER(ti_fdc_device::floppy_formats) diff --git a/src/devices/bus/ti99x/gromport.cpp b/src/devices/bus/ti99x/gromport.cpp index baa77932f7e..33ef82ae2a7 100644 --- a/src/devices/bus/ti99x/gromport.cpp +++ b/src/devices/bus/ti99x/gromport.cpp @@ -254,7 +254,7 @@ void gromport_device::cartridge_inserted() void gromport_device::device_config_complete() { - m_connector = static_cast(first_subdevice()); + m_connector = static_cast(subdevices().first()); set_grom_base(0x9800, 0xf800); } @@ -352,7 +352,7 @@ WRITE8_MEMBER(single_conn_device::cruwrite) void single_conn_device::device_start() { - m_cartridge = static_cast(first_subdevice()); + m_cartridge = static_cast(subdevices().first()); } void single_conn_device::device_reset() diff --git a/src/devices/bus/ti99x/joyport.cpp b/src/devices/bus/ti99x/joyport.cpp index 9aab362f812..5cc4dd08e56 100644 --- a/src/devices/bus/ti99x/joyport.cpp +++ b/src/devices/bus/ti99x/joyport.cpp @@ -87,7 +87,7 @@ void joyport_device::device_start() void joyport_device::device_config_complete() { - m_connected = static_cast(first_subdevice()); + m_connected = static_cast(subdevices().first()); } /*****************************************************************************/ diff --git a/src/devices/machine/legscsi.cpp b/src/devices/machine/legscsi.cpp index 23cc5902a29..e8cbd7e9704 100644 --- a/src/devices/machine/legscsi.cpp +++ b/src/devices/machine/legscsi.cpp @@ -133,9 +133,9 @@ UINT8 legacy_scsi_host_adapter::get_status() scsihle_device *legacy_scsi_host_adapter::get_device(int id) { // steal scsi devices from bus - for (device_t *device = m_scsi_port->first_subdevice(); device != nullptr; device = device->next()) + for (device_t &device : m_scsi_port->subdevices()) { - SCSI_PORT_SLOT_device *slot = dynamic_cast(device); + SCSI_PORT_SLOT_device *slot = dynamic_cast(&device); if (slot != nullptr) { scsihle_device *scsidev = dynamic_cast(slot->dev()); diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index d0a06604707..1ca8d185e47 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -312,12 +312,12 @@ void netlist_mame_device_t::device_start() m_setup_func(*m_setup); /* let sub-devices tweak the netlist */ - for( device_t *d = this->first_subdevice(); d != nullptr; d = d->next() ) + for (device_t &d : subdevices()) { - netlist_mame_sub_interface *sdev = dynamic_cast(d); + netlist_mame_sub_interface *sdev = dynamic_cast(&d); if( sdev != nullptr ) { - LOG_DEV_CALLS(("Found subdevice %s/%s\n", d->name(), d->shortname())); + LOG_DEV_CALLS(("Found subdevice %s/%s\n", d.name(), d.shortname())); sdev->custom_netlist_additions(*m_setup); } } diff --git a/src/devices/machine/pci.cpp b/src/devices/machine/pci.cpp index 33a84919f1e..5987a423a09 100644 --- a/src/devices/machine/pci.cpp +++ b/src/devices/machine/pci.cpp @@ -434,14 +434,15 @@ void pci_bridge_device::device_start() for(auto & elem : sub_devices) elem = nullptr; - for(device_t *d = bus_root()->first_subdevice(); d != nullptr; d = d->next()) { - const char *t = d->tag(); + for (device_t &d : bus_root()->subdevices()) + { + const char *t = d.tag(); int l = strlen(t); if(l <= 4 || t[l-5] != ':' || t[l-2] != '.') continue; int id = strtol(t+l-4, nullptr, 16); int fct = t[l-1] - '0'; - sub_devices[(id << 3) | fct] = downcast(d); + sub_devices[(id << 3) | fct] = downcast(&d); } mapper_cb cf_cb(FUNC(pci_bridge_device::regenerate_config_mapping), this); diff --git a/src/emu/addrmap.cpp b/src/emu/addrmap.cpp index 2ae44142ac1..b377fe73231 100644 --- a/src/emu/addrmap.cpp +++ b/src/emu/addrmap.cpp @@ -650,46 +650,50 @@ void address_map::map_validity_check(validity_checker &valid, const device_t &de osd_printf_error("Wrong memory handlers provided for %s space! (width = %d, memory = %08x)\n", spaceconfig.m_name, datawidth, m_databits); // loop over entries and look for errors - for (address_map_entry *entry = m_entrylist.first(); entry != nullptr; entry = entry->next()) + for (address_map_entry &entry : m_entrylist) { - UINT32 bytestart = spaceconfig.addr2byte(entry->m_addrstart); - UINT32 byteend = spaceconfig.addr2byte_end(entry->m_addrend); + UINT32 bytestart = spaceconfig.addr2byte(entry.m_addrstart); + UINT32 byteend = spaceconfig.addr2byte_end(entry.m_addrend); // look for overlapping entries if (!detected_overlap) { - for (address_map_entry *scan = m_entrylist.first(); scan != entry; scan = scan->next()) - if (entry->m_addrstart <= scan->m_addrend && entry->m_addrend >= scan->m_addrstart && - ((entry->m_read.m_type != AMH_NONE && scan->m_read.m_type != AMH_NONE) || - (entry->m_write.m_type != AMH_NONE && scan->m_write.m_type != AMH_NONE))) + for (address_map_entry &scan : m_entrylist) + { + if (&scan == &entry) + break; + if (entry.m_addrstart <= scan.m_addrend && entry.m_addrend >= scan.m_addrstart && + ((entry.m_read.m_type != AMH_NONE && scan.m_read.m_type != AMH_NONE) || + (entry.m_write.m_type != AMH_NONE && scan.m_write.m_type != AMH_NONE))) { - osd_printf_warning("%s space has overlapping memory (%X-%X,%d,%d) vs (%X-%X,%d,%d)\n", spaceconfig.m_name, entry->m_addrstart, entry->m_addrend, entry->m_read.m_type, entry->m_write.m_type, scan->m_addrstart, scan->m_addrend, scan->m_read.m_type, scan->m_write.m_type); + osd_printf_warning("%s space has overlapping memory (%X-%X,%d,%d) vs (%X-%X,%d,%d)\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend, entry.m_read.m_type, entry.m_write.m_type, scan.m_addrstart, scan.m_addrend, scan.m_read.m_type, scan.m_write.m_type); detected_overlap = true; break; } + } } // look for inverted start/end pairs if (byteend < bytestart) - osd_printf_error("Wrong %s memory read handler start = %08x > end = %08x\n", spaceconfig.m_name, entry->m_addrstart, entry->m_addrend); + osd_printf_error("Wrong %s memory read handler start = %08x > end = %08x\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend); // look for misaligned entries if ((bytestart & (alignunit - 1)) != 0 || (byteend & (alignunit - 1)) != (alignunit - 1)) - osd_printf_error("Wrong %s memory read handler start = %08x, end = %08x ALIGN = %d\n", spaceconfig.m_name, entry->m_addrstart, entry->m_addrend, alignunit); + osd_printf_error("Wrong %s memory read handler start = %08x, end = %08x ALIGN = %d\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend, alignunit); // if this is a program space, auto-assign implicit ROM entries - if (entry->m_read.m_type == AMH_ROM && entry->m_region == nullptr) + if (entry.m_read.m_type == AMH_ROM && entry.m_region == nullptr) { - entry->m_region = device.tag(); - entry->m_rgnoffs = entry->m_addrstart; + entry.m_region = device.tag(); + entry.m_rgnoffs = entry.m_addrstart; } // if this entry references a memory region, validate it - if (entry->m_region != nullptr && entry->m_share == nullptr) + if (entry.m_region != nullptr && entry.m_share == nullptr) { // make sure we can resolve the full path to the region bool found = false; - std::string entry_region = entry->m_devbase.subtag(entry->m_region); + std::string entry_region = entry.m_devbase.subtag(entry.m_region); // look for the region device_iterator deviter(device.mconfig().root_device()); @@ -700,68 +704,68 @@ void address_map::map_validity_check(validity_checker &valid, const device_t &de { // verify the address range is within the region's bounds offs_t length = ROMREGION_GETLENGTH(romp); - if (entry->m_rgnoffs + (byteend - bytestart + 1) > length) - osd_printf_error("%s space memory map entry %X-%X extends beyond region '%s' size (%X)\n", spaceconfig.m_name, entry->m_addrstart, entry->m_addrend, entry->m_region, length); + if (entry.m_rgnoffs + (byteend - bytestart + 1) > length) + osd_printf_error("%s space memory map entry %X-%X extends beyond region '%s' size (%X)\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend, entry.m_region, length); found = true; } } // error if not found if (!found) - osd_printf_error("%s space memory map entry %X-%X references non-existant region '%s'\n", spaceconfig.m_name, entry->m_addrstart, entry->m_addrend, entry->m_region); + osd_printf_error("%s space memory map entry %X-%X references non-existant region '%s'\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend, entry.m_region); } // make sure all devices exist - if (entry->m_read.m_type == AMH_DEVICE_DELEGATE) + if (entry.m_read.m_type == AMH_DEVICE_DELEGATE) { // extract the device tag from the proto-delegate const char *devtag = nullptr; - switch (entry->m_read.m_bits) + switch (entry.m_read.m_bits) { - case 8: devtag = entry->m_rproto8.device_name(); break; - case 16: devtag = entry->m_rproto16.device_name(); break; - case 32: devtag = entry->m_rproto32.device_name(); break; - case 64: devtag = entry->m_rproto64.device_name(); break; + case 8: devtag = entry.m_rproto8.device_name(); break; + case 16: devtag = entry.m_rproto16.device_name(); break; + case 32: devtag = entry.m_rproto32.device_name(); break; + case 64: devtag = entry.m_rproto64.device_name(); break; } - if (entry->m_devbase.subdevice(devtag) == nullptr) + if (entry.m_devbase.subdevice(devtag) == nullptr) osd_printf_error("%s space memory map entry reads from nonexistant device '%s'\n", spaceconfig.m_name, devtag != nullptr ? devtag : ""); } - if (entry->m_write.m_type == AMH_DEVICE_DELEGATE) + if (entry.m_write.m_type == AMH_DEVICE_DELEGATE) { // extract the device tag from the proto-delegate const char *devtag = nullptr; - switch (entry->m_write.m_bits) + switch (entry.m_write.m_bits) { - case 8: devtag = entry->m_wproto8.device_name(); break; - case 16: devtag = entry->m_wproto16.device_name(); break; - case 32: devtag = entry->m_wproto32.device_name(); break; - case 64: devtag = entry->m_wproto64.device_name(); break; + case 8: devtag = entry.m_wproto8.device_name(); break; + case 16: devtag = entry.m_wproto16.device_name(); break; + case 32: devtag = entry.m_wproto32.device_name(); break; + case 64: devtag = entry.m_wproto64.device_name(); break; } - if (entry->m_devbase.subdevice(devtag) == nullptr) + if (entry.m_devbase.subdevice(devtag) == nullptr) osd_printf_error("%s space memory map entry writes to nonexistant device '%s'\n", spaceconfig.m_name, devtag != nullptr ? devtag : ""); } - if (entry->m_setoffsethd.m_type == AMH_DEVICE_DELEGATE) + if (entry.m_setoffsethd.m_type == AMH_DEVICE_DELEGATE) { // extract the device tag from the proto-delegate - const char *devtag = entry->m_soproto.device_name(); - if (entry->m_devbase.subdevice(devtag) == nullptr) + const char *devtag = entry.m_soproto.device_name(); + if (entry.m_devbase.subdevice(devtag) == nullptr) osd_printf_error("%s space memory map entry references nonexistant device '%s'\n", spaceconfig.m_name, devtag != nullptr ? devtag : ""); } // make sure ports exist -// if ((entry->m_read.m_type == AMH_PORT && entry->m_read.m_tag != NULL && portlist.find(entry->m_read.m_tag) == NULL) || -// (entry->m_write.m_type == AMH_PORT && entry->m_write.m_tag != NULL && portlist.find(entry->m_write.m_tag) == NULL)) -// osd_printf_error("%s space memory map entry references nonexistant port tag '%s'\n", spaceconfig.m_name, entry->m_read.m_tag); +// if ((entry.m_read.m_type == AMH_PORT && entry.m_read.m_tag != NULL && portlist.find(entry.m_read.m_tag) == NULL) || +// (entry.m_write.m_type == AMH_PORT && entry.m_write.m_tag != NULL && portlist.find(entry.m_write.m_tag) == NULL)) +// osd_printf_error("%s space memory map entry references nonexistant port tag '%s'\n", spaceconfig.m_name, entry.m_read.m_tag); // validate bank and share tags - if (entry->m_read.m_type == AMH_BANK) - valid.validate_tag(entry->m_read.m_tag); - if (entry->m_write.m_type == AMH_BANK) - valid.validate_tag(entry->m_write.m_tag); - if (entry->m_share != nullptr) - valid.validate_tag(entry->m_share); + if (entry.m_read.m_type == AMH_BANK) + valid.validate_tag(entry.m_read.m_tag); + if (entry.m_write.m_type == AMH_BANK) + valid.validate_tag(entry.m_write.m_tag); + if (entry.m_share != nullptr) + valid.validate_tag(entry.m_share); } } diff --git a/src/emu/audit.cpp b/src/emu/audit.cpp index e9e4dee63f2..6797d967218 100644 --- a/src/emu/audit.cpp +++ b/src/emu/audit.cpp @@ -208,10 +208,10 @@ media_auditor::summary media_auditor::audit_software(const char *list_name, soft int required = 0; // now iterate over software parts - for ( software_part *part = swinfo->first_part(); part != nullptr; part = part->next() ) + for (software_part &part : swinfo->parts()) { // now iterate over regions - for ( const rom_entry *region = part->romdata(); region; region = rom_next_region( region ) ) + for ( const rom_entry *region = part.romdata(); region; region = rom_next_region( region ) ) { // now iterate over rom definitions for (const rom_entry *rom = rom_first_file(region); rom; rom = rom_next_file(rom)) @@ -336,25 +336,25 @@ media_auditor::summary media_auditor::summarize(const char *name, std::string *o // loop over records summary overall_status = CORRECT; - for (audit_record *record = m_record_list.first(); record != nullptr; record = record->next()) + for (audit_record &record : m_record_list) { summary best_new_status = INCORRECT; // skip anything that's fine - if (record->substatus() == audit_record::SUBSTATUS_GOOD) + if (record.substatus() == audit_record::SUBSTATUS_GOOD) continue; // output the game name, file name, and length (if applicable) if (output != nullptr) { - output->append(string_format("%-12s: %s", name, record->name())); - if (record->expected_length() > 0) - output->append(string_format(" (%d bytes)", record->expected_length())); + output->append(string_format("%-12s: %s", name, record.name())); + if (record.expected_length() > 0) + output->append(string_format(" (%d bytes)", record.expected_length())); output->append(" - "); } // use the substatus for finer details - switch (record->substatus()) + switch (record.substatus()) { case audit_record::SUBSTATUS_GOOD_NEEDS_REDUMP: if (output != nullptr) output->append("NEEDS REDUMP\n"); @@ -370,19 +370,19 @@ media_auditor::summary media_auditor::summarize(const char *name, std::string *o if (output != nullptr) { output->append("INCORRECT CHECKSUM:\n"); - output->append(string_format("EXPECTED: %s\n", record->expected_hashes().macro_string().c_str())); - output->append(string_format(" FOUND: %s\n", record->actual_hashes().macro_string().c_str())); + output->append(string_format("EXPECTED: %s\n", record.expected_hashes().macro_string().c_str())); + output->append(string_format(" FOUND: %s\n", record.actual_hashes().macro_string().c_str())); } break; case audit_record::SUBSTATUS_FOUND_WRONG_LENGTH: - if (output != nullptr) output->append(string_format("INCORRECT LENGTH: %d bytes\n", record->actual_length())); + if (output != nullptr) output->append(string_format("INCORRECT LENGTH: %d bytes\n", record.actual_length())); break; case audit_record::SUBSTATUS_NOT_FOUND: if (output != nullptr) { - device_t *shared_device = record->shared_device(); + device_t *shared_device = record.shared_device(); if (shared_device == nullptr) output->append("NOT FOUND\n"); else diff --git a/src/emu/audit.h b/src/emu/audit.h index d39ecbb3a91..75d0f3121ba 100644 --- a/src/emu/audit.h +++ b/src/emu/audit.h @@ -141,8 +141,7 @@ public: media_auditor(const driver_enumerator &enumerator); // getters - audit_record *first() const { return m_record_list.first(); } - int count() const { return m_record_list.count(); } + const auto &records() const { return m_record_list; } // audit operations summary audit_media(const char *validation = AUDIT_VALIDATE_FULL); diff --git a/src/emu/cheat.cpp b/src/emu/cheat.cpp index f9fe6499d61..fbd2b7f1479 100644 --- a/src/emu/cheat.cpp +++ b/src/emu/cheat.cpp @@ -181,10 +181,10 @@ const char *cheat_parameter::text() { // if not, we're an item cheat m_curtext = string_format("??? (%d)", UINT32(m_value)); - for (item *curitem = m_itemlist.first(); curitem != nullptr; curitem = curitem->next()) - if (curitem->value() == m_value) + for (item &curitem : m_itemlist) + if (curitem.value() == m_value) { - m_curtext.assign(curitem->text()); + m_curtext.assign(curitem.text()); break; } } @@ -216,8 +216,8 @@ void cheat_parameter::save(emu_file &cheatfile) const // iterate over items else { - for (const item *curitem = m_itemlist.first(); curitem != nullptr; curitem = curitem->next()) - cheatfile.printf("\t\t\t%s\n", curitem->value().format().c_str(), curitem->text()); + for (const item &curitem : m_itemlist) + cheatfile.printf("\t\t\t%s\n", curitem.value().format().c_str(), curitem.text()); cheatfile.printf("\t\t\n"); } } @@ -357,8 +357,8 @@ void cheat_script::execute(cheat_manager &manager, UINT64 &argindex) return; // iterate over entries - for (script_entry *entry = m_entrylist.first(); entry != nullptr; entry = entry->next()) - entry->execute(manager, argindex); + for (script_entry &entry : m_entrylist) + entry.execute(manager, argindex); } @@ -381,8 +381,8 @@ void cheat_script::save(emu_file &cheatfile) const cheatfile.printf(">\n"); // output entries - for (const script_entry *entry = m_entrylist.first(); entry != nullptr; entry = entry->next()) - entry->save(cheatfile); + for (const script_entry &entry : m_entrylist) + entry.save(cheatfile); // close the tag cheatfile.printf("\t\t\n"); @@ -499,8 +499,8 @@ void cheat_script::script_entry::execute(cheat_manager &manager, UINT64 &arginde // iterate over arguments and evaluate them UINT64 params[MAX_ARGUMENTS]; int curarg = 0; - for (output_argument *arg = m_arglist.first(); arg != nullptr; arg = arg->next()) - curarg += arg->values(argindex, ¶ms[curarg]); + for (output_argument &arg : m_arglist) + curarg += arg.values(argindex, ¶ms[curarg]); // generate the astring manager.get_output_astring(m_line, m_justify) = string_format(m_format, @@ -550,8 +550,8 @@ void cheat_script::script_entry::save(emu_file &cheatfile) const else { cheatfile.printf(">\n"); - for (const output_argument *curarg = m_arglist.first(); curarg != nullptr; curarg = curarg->next()) - curarg->save(cheatfile); + for (const output_argument &curarg : m_arglist) + curarg.save(cheatfile); cheatfile.printf("\t\t\t\n"); } } @@ -567,8 +567,8 @@ void cheat_script::script_entry::validate_format(const char *filename, int line) { // first count arguments int argsprovided = 0; - for (const output_argument *curarg = m_arglist.first(); curarg != nullptr; curarg = curarg->next()) - argsprovided += curarg->count(); + for (const output_argument &curarg : m_arglist) + argsprovided += curarg.count(); // now scan the string for valid argument usage const char *p = strchr(m_format.c_str(), '%'); @@ -1026,6 +1026,19 @@ std::unique_ptr &cheat_entry::script_for_state(script_state state) } +//------------------------------------------------- +// is_duplicate - determine if a new cheat entry +// is already included in the list +//------------------------------------------------- + +bool cheat_entry::is_duplicate() const +{ + for (cheat_entry &scannode : manager().entries()) + if (strcmp(scannode.description(), description()) == 0) + return true; + return false; +} + //************************************************************************** // CHEAT MANAGER @@ -1086,9 +1099,9 @@ void cheat_manager::set_enable(bool enable) if (!m_disabled && !enable) { // iterate over running cheats and execute any OFF Scripts - for (cheat_entry *cheat = m_cheatlist.first(); cheat != nullptr; cheat = cheat->next()) - if (cheat->state() == SCRIPT_STATE_RUN) - cheat->execute_off_script(); + for (cheat_entry &cheat : m_cheatlist) + if (cheat.state() == SCRIPT_STATE_RUN) + cheat.execute_off_script(); machine().popmessage("Cheats Disabled"); m_disabled = true; } @@ -1098,9 +1111,9 @@ void cheat_manager::set_enable(bool enable) { // iterate over running cheats and execute any ON Scripts m_disabled = false; - for (cheat_entry *cheat = m_cheatlist.first(); cheat != nullptr; cheat = cheat->next()) - if (cheat->state() == SCRIPT_STATE_RUN) - cheat->execute_on_script(); + for (cheat_entry &cheat : m_cheatlist) + if (cheat.state() == SCRIPT_STATE_RUN) + cheat.execute_on_script(); machine().popmessage("Cheats Enabled"); } } @@ -1186,8 +1199,8 @@ bool cheat_manager::save_all(const char *filename) cheatfile.printf("\n", CHEAT_VERSION); // iterate over cheats in the list and save them - for (cheat_entry *cheat = m_cheatlist.first(); cheat != nullptr; cheat = cheat->next()) - cheat->save(cheatfile); + for (cheat_entry &cheat : m_cheatlist) + cheat.save(cheatfile); // close out the file cheatfile.printf("\n"); @@ -1345,8 +1358,8 @@ void cheat_manager::frame_update() elem.clear(); // iterate over running cheats and execute them - for (cheat_entry *cheat = m_cheatlist.first(); cheat != nullptr; cheat = cheat->next()) - cheat->frame_update(); + for (cheat_entry &cheat : m_cheatlist) + cheat.frame_update(); // increment the frame counter m_framecount++; @@ -1403,23 +1416,16 @@ void cheat_manager::load_cheats(const char *filename) for (xml_data_node *cheatnode = xml_get_sibling(mamecheatnode->child, "cheat"); cheatnode != nullptr; cheatnode = xml_get_sibling(cheatnode->next, "cheat")) { // load this entry - auto curcheat = global_alloc(cheat_entry(*this, m_symtable, filename, *cheatnode)); + cheat_entry *curcheat = global_alloc(cheat_entry(*this, m_symtable, filename, *cheatnode)); // make sure we're not a duplicate - cheat_entry *scannode = nullptr; - if (REMOVE_DUPLICATE_CHEATS) - for (scannode = m_cheatlist.first(); scannode != nullptr; scannode = scannode->next()) - if (strcmp(scannode->description(), curcheat->description()) == 0) - { - osd_printf_verbose("Ignoring duplicate cheat '%s' from file %s\n", curcheat->description(), cheatfile.fullpath()); - break; - } - - // add to the end of the list - if (scannode == nullptr) - m_cheatlist.append(*curcheat); - else + if (REMOVE_DUPLICATE_CHEATS && curcheat->is_duplicate()) + { + osd_printf_verbose("Ignoring duplicate cheat '%s' from file %s\n", curcheat->description(), cheatfile.fullpath()); global_free(curcheat); + } + else // add to the end of the list + m_cheatlist.append(*curcheat); } // free the file and loop for the next one diff --git a/src/emu/cheat.h b/src/emu/cheat.h index 20772e25640..21feea7d25e 100644 --- a/src/emu/cheat.h +++ b/src/emu/cheat.h @@ -243,6 +243,7 @@ public: bool is_value_parameter() const { return (m_parameter != nullptr && !m_parameter->has_itemlist()); } bool is_itemlist_parameter() const { return (m_parameter != nullptr && m_parameter->has_itemlist()); } bool is_oneshot_parameter() const { return (m_parameter != nullptr && !has_run_script() && !has_off_script() && has_change_script()); } + bool is_duplicate() const; // actions bool activate(); @@ -294,7 +295,7 @@ public: // getters running_machine &machine() const { return m_machine; } bool enabled() const { return !m_disabled; } - cheat_entry *first() const { return m_cheatlist.first(); } + const auto &entries() const { return m_cheatlist; } // setters void set_enable(bool enable = true); diff --git a/src/emu/clifront.cpp b/src/emu/clifront.cpp index 8889ab916a1..02c27149231 100644 --- a/src/emu/clifront.cpp +++ b/src/emu/clifront.cpp @@ -130,10 +130,10 @@ int cli_frontend::execute(int argc, char **argv) if (swinfo != nullptr) { // loop through all parts - for (software_part *swpart = swinfo->first_part(); swpart != nullptr; swpart = swpart->next()) + for (software_part &swpart : swinfo->parts()) { - const char *mount = swpart->feature("automount"); - if (swpart->is_compatible(*swlistdev)) + const char *mount = swpart.feature("automount"); + if (swpart.is_compatible(*swlistdev)) { if (mount == nullptr || strcmp(mount,"no") != 0) { @@ -144,17 +144,17 @@ int cli_frontend::execute(int argc, char **argv) const char *interface = image->image_interface(); if (interface != nullptr) { - if (swpart->matches_interface(interface)) + if (swpart.matches_interface(interface)) { const char *option = m_options.value(image->brief_instance_name()); // mount only if not already mounted if (*option == 0) { - std::string val = string_format("%s:%s:%s", swlistdev->list_name(), m_options.software_name(), swpart->name()); + std::string val = string_format("%s:%s:%s", swlistdev->list_name(), m_options.software_name(), swpart.name()); // call this in order to set slot devices according to mounting - m_options.parse_slot_devices(argc, argv, option_errors, image->instance_name(), val.c_str(), swpart); + m_options.parse_slot_devices(argc, argv, option_errors, image->instance_name(), val.c_str(), &swpart); break; } } @@ -661,16 +661,16 @@ void cli_frontend::listslots(const char *gamename) bool first_option = true; // get the options and print them - for (const device_slot_option *option = slot->first_option(); option != nullptr; option = option->next()) + for (const device_slot_option &option : slot->option_list()) { - if (option->selectable()) + if (option.selectable()) { - device_t *dev = (*option->devtype())(drivlist.config(), "dummy", &drivlist.config().root_device(), 0); + device_t *dev = (*option.devtype())(drivlist.config(), "dummy", &drivlist.config().root_device(), 0); dev->config_complete(); if (first_option) { - printf("%-15s %s\n", option->name(),dev->name()); + printf("%-15s %s\n", option.name(),dev->name()); } else { - printf("%-23s %-15s %s\n", "",option->name(),dev->name()); + printf("%-23s %-15s %s\n", "",option.name(),dev->name()); } global_free(dev); @@ -869,11 +869,11 @@ void cli_frontend::verifyroms(const char *gamename) slot_interface_iterator slotiter(config.root_device()); for (const device_slot_interface *slot = slotiter.first(); slot != nullptr; slot = slotiter.next()) { - for (const device_slot_option *option = slot->first_option(); option != nullptr; option = option->next()) + for (const device_slot_option &option : slot->option_list()) { std::string temptag("_"); - temptag.append(option->name()); - device_t *dev = const_cast(config).device_add(&config.root_device(), temptag.c_str(), option->devtype(), 0); + temptag.append(option.name()); + device_t *dev = const_cast(config).device_add(&config.root_device(), temptag.c_str(), option.devtype(), 0); // notify this device and all its subdevices that they are now configured device_iterator subiter(*dev); @@ -1175,36 +1175,36 @@ void cli_frontend::verifysamples(const char *gamename) void cli_frontend::output_single_softlist(FILE *out, software_list_device &swlistdev) { fprintf(out, "\t\n", swlistdev.list_name(), xml_normalize_string(swlistdev.description())); - for (software_info *swinfo = swlistdev.first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) + for (software_info &swinfo : swlistdev.get_info()) { - fprintf( out, "\t\tshortname() ); - if ( swinfo->parentname() != nullptr ) - fprintf( out, " cloneof=\"%s\"", swinfo->parentname() ); - if ( swinfo->supported() == SOFTWARE_SUPPORTED_PARTIAL ) - fprintf( out, " supported=\"partial\"" ); - if ( swinfo->supported() == SOFTWARE_SUPPORTED_NO ) - fprintf( out, " supported=\"no\"" ); - fprintf( out, ">\n" ); - fprintf( out, "\t\t\t%s\n", xml_normalize_string(swinfo->longname()) ); - fprintf( out, "\t\t\t%s\n", xml_normalize_string( swinfo->year() ) ); - fprintf( out, "\t\t\t%s\n", xml_normalize_string( swinfo->publisher() ) ); + fprintf(out, "\t\t\n" ); + fprintf(out, "\t\t\t%s\n", xml_normalize_string(swinfo.longname())); + fprintf(out, "\t\t\t%s\n", xml_normalize_string(swinfo.year())); + fprintf(out, "\t\t\t%s\n", xml_normalize_string(swinfo.publisher())); - for (feature_list_item *flist = swinfo->other_info(); flist != nullptr; flist = flist->next()) - fprintf( out, "\t\t\t\n", flist->name(), xml_normalize_string( flist->value() ) ); + for (feature_list_item &flist : swinfo.other_info()) + fprintf( out, "\t\t\t\n", flist.name(), xml_normalize_string( flist.value() ) ); - for ( software_part *part = swinfo->first_part(); part != nullptr; part = part->next() ) + for (software_part &part : swinfo.parts()) { - fprintf( out, "\t\t\tname() ); - if ( part->interface() != nullptr ) - fprintf( out, " interface=\"%s\"", part->interface() ); + fprintf(out, "\t\t\t\n"); + fprintf(out, ">\n"); - for (feature_list_item *flist = part->featurelist(); flist != nullptr; flist = flist->next()) - fprintf( out, "\t\t\t\t\n", flist->name(), xml_normalize_string(flist->value()) ); + for (feature_list_item &flist : part.featurelist()) + fprintf(out, "\t\t\t\t\n", flist.name(), xml_normalize_string(flist.value())); /* TODO: display rom region information */ - for ( const rom_entry *region = part->romdata(); region; region = rom_next_region( region ) ) + for (const rom_entry *region = part.romdata(); region; region = rom_next_region(region)) { int is_disk = ROMREGION_ISDISKDATA(region); @@ -1312,7 +1312,7 @@ void cli_frontend::listsoftware(const char *gamename) software_list_device_iterator iter(drivlist.config().root_device()); for (software_list_device *swlistdev = iter.first(); swlistdev != nullptr; swlistdev = iter.next()) if (list_map.insert(swlistdev->list_name()).second) - if (swlistdev->first_software_info() != nullptr) + if (!swlistdev->get_info().empty()) { if (isfirst) { fprintf(out, SOFTLIST_XML_BEGIN); isfirst = false; } output_single_softlist(out, *swlistdev); @@ -1356,12 +1356,12 @@ void cli_frontend::verifysoftware(const char *gamename) for (software_list_device *swlistdev = iter.first(); swlistdev != nullptr; swlistdev = iter.next()) if (swlistdev->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM) if (list_map.insert(swlistdev->list_name()).second) - if (swlistdev->first_software_info() != nullptr) + if (!swlistdev->get_info().empty()) { nrlists++; - for (software_info *swinfo = swlistdev->first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) + for (software_info &swinfo : swlistdev->get_info()) { - media_auditor::summary summary = auditor.audit_software(swlistdev->list_name(), swinfo, AUDIT_VALIDATE_FAST); + media_auditor::summary summary = auditor.audit_software(swlistdev->list_name(), &swinfo, AUDIT_VALIDATE_FAST); // if not found, count that and leave it at that if (summary == media_auditor::NOTFOUND) @@ -1373,11 +1373,11 @@ void cli_frontend::verifysoftware(const char *gamename) { // output the summary of the audit std::string summary_string; - auditor.summarize(swinfo->shortname(), &summary_string); + auditor.summarize(swinfo.shortname(), &summary_string); osd_printf_info("%s", summary_string.c_str()); // display information about what we discovered - osd_printf_info("romset %s:%s ", swlistdev->list_name(), swinfo->shortname()); + osd_printf_info("romset %s:%s ", swlistdev->list_name(), swinfo.shortname()); // switch off of the result switch (summary) @@ -1443,7 +1443,7 @@ void cli_frontend::getsoftlist(const char *gamename) software_list_device_iterator iter(drivlist.config().root_device()); for (software_list_device *swlistdev = iter.first(); swlistdev != nullptr; swlistdev = iter.next()) if (core_strwildcmp(gamename, swlistdev->list_name()) == 0 && list_map.insert(swlistdev->list_name()).second) - if (swlistdev->first_software_info() != nullptr) + if (!swlistdev->get_info().empty()) { if (isfirst) { fprintf( out, SOFTLIST_XML_BEGIN); isfirst = FALSE; } output_single_softlist(out, *swlistdev); @@ -1476,14 +1476,14 @@ void cli_frontend::verifysoftlist(const char *gamename) software_list_device_iterator iter(drivlist.config().root_device()); for (software_list_device *swlistdev = iter.first(); swlistdev != nullptr; swlistdev = iter.next()) if (core_strwildcmp(gamename, swlistdev->list_name()) == 0 && list_map.insert(swlistdev->list_name()).second) - if (swlistdev->first_software_info() != nullptr) + if (!swlistdev->get_info().empty()) { matched++; // Get the actual software list contents - for (software_info *swinfo = swlistdev->first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) + for (software_info &swinfo : swlistdev->get_info()) { - media_auditor::summary summary = auditor.audit_software(swlistdev->list_name(), swinfo, AUDIT_VALIDATE_FAST); + media_auditor::summary summary = auditor.audit_software(swlistdev->list_name(), &swinfo, AUDIT_VALIDATE_FAST); // if not found, count that and leave it at that if (summary == media_auditor::NOTFOUND) @@ -1495,11 +1495,11 @@ void cli_frontend::verifysoftlist(const char *gamename) { // output the summary of the audit std::string summary_string; - auditor.summarize(swinfo->shortname(), &summary_string); + auditor.summarize(swinfo.shortname(), &summary_string); osd_printf_info("%s", summary_string.c_str()); // display information about what we discovered - osd_printf_info("romset %s:%s ", swlistdev->list_name(), swinfo->shortname()); + osd_printf_info("romset %s:%s ", swlistdev->list_name(), swinfo.shortname()); // switch off of the result switch (summary) @@ -1964,9 +1964,9 @@ int media_identifier::find_by_hash(const hash_collection &hashes, int length) { if (listnames.insert(swlistdev->list_name()).second) { - for (software_info *swinfo = swlistdev->first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) - for (software_part *part = swinfo->first_part(); part != nullptr; part = part->next()) - for (const rom_entry *region = part->romdata(); region != nullptr; region = rom_next_region(region)) + for (software_info &swinfo : swlistdev->get_info()) + for (software_part &part : swinfo.parts()) + for (const rom_entry *region = part.romdata(); region != nullptr; region = rom_next_region(region)) for (const rom_entry *rom = rom_first_file(region); rom != nullptr; rom = rom_next_file(rom)) { hash_collection romhashes(ROM_GETHASHDATA(rom)); @@ -1977,7 +1977,7 @@ int media_identifier::find_by_hash(const hash_collection &hashes, int length) // output information about the match if (found) osd_printf_info(" "); - osd_printf_info("= %s%-20s %s:%s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), swlistdev->list_name(), swinfo->shortname(), swinfo->longname()); + osd_printf_info("= %s%-20s %s:%s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), swlistdev->list_name(), swinfo.shortname(), swinfo.longname()); found++; } } diff --git a/src/emu/crsshair.cpp b/src/emu/crsshair.cpp index a4bee628ae9..28d5cced1ce 100644 --- a/src/emu/crsshair.cpp +++ b/src/emu/crsshair.cpp @@ -113,11 +113,11 @@ crosshair_manager::crosshair_manager(running_machine &machine) m_auto_time = CROSSHAIR_VISIBILITY_AUTOTIME_DEFAULT; /* determine who needs crosshairs */ - for (ioport_port *port = machine.ioport().first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->crosshair_axis() != CROSSHAIR_AXIS_NONE) + for (ioport_port &port : machine.ioport().ports()) + for (ioport_field &field : port.fields()) + if (field.crosshair_axis() != CROSSHAIR_AXIS_NONE) { - int player = field->player(); + int player = field.player(); assert(player < MAX_PLAYERS); diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp index 2e10b40356e..cd16bd4e691 100644 --- a/src/emu/debug/debugcmd.cpp +++ b/src/emu/debug/debugcmd.cpp @@ -1935,7 +1935,6 @@ static void execute_cheatinit(running_machine &machine, int ref, int params, con UINT64 curaddr; UINT8 i, region_count = 0; - address_map_entry *entry; cheat_region_map cheat_region[100]; memset(cheat_region, 0, sizeof(cheat_region)); @@ -1987,18 +1986,18 @@ static void execute_cheatinit(running_machine &machine, int ref, int params, con /* initialize entire memory by default */ if (params <= 1) { - for (entry = space->map()->m_entrylist.first(); entry != nullptr; entry = entry->next()) + for (address_map_entry &entry : space->map()->m_entrylist) { - cheat_region[region_count].offset = space->address_to_byte(entry->m_addrstart) & space->bytemask(); - cheat_region[region_count].endoffset = space->address_to_byte(entry->m_addrend) & space->bytemask(); - cheat_region[region_count].share = entry->m_share; - cheat_region[region_count].disabled = (entry->m_write.m_type == AMH_RAM) ? FALSE : TRUE; + cheat_region[region_count].offset = space->address_to_byte(entry.m_addrstart) & space->bytemask(); + cheat_region[region_count].endoffset = space->address_to_byte(entry.m_addrend) & space->bytemask(); + cheat_region[region_count].share = entry.m_share; + cheat_region[region_count].disabled = (entry.m_write.m_type == AMH_RAM) ? FALSE : TRUE; /* disable double share regions */ - if (entry->m_share != nullptr) + if (entry.m_share != nullptr) for (i = 0; i < region_count; i++) if (cheat_region[i].share != nullptr) - if (strcmp(cheat_region[i].share, entry->m_share) == 0) + if (strcmp(cheat_region[i].share, entry.m_share) == 0) cheat_region[region_count].disabled = TRUE; region_count++; @@ -2979,12 +2978,12 @@ static void execute_symlist(running_machine &machine, int ref, int params, const } /* gather names for all symbols */ - for (symbol_entry *entry = symtable->first(); entry != nullptr; entry = entry->next()) + for (symbol_entry &entry : symtable->entries()) { /* only display "register" type symbols */ - if (!entry->is_function()) + if (!entry.is_function()) { - namelist[count++] = entry->name(); + namelist[count++] = entry.name(); if (count >= ARRAY_LENGTH(namelist)) break; } diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp index 4e59ed8a652..7e352e7dbe8 100644 --- a/src/emu/debug/debugcpu.cpp +++ b/src/emu/debug/debugcpu.cpp @@ -1666,9 +1666,10 @@ device_debug::device_debug(device_t &device) // add all registers into it std::string tempstr; - for (const device_state_entry *entry = m_state->state_first(); entry != nullptr; entry = entry->next()) { - strmakelower(tempstr.assign(entry->symbol())); - m_symtable.add(tempstr.c_str(), (void *)(FPTR)entry->index(), get_state, set_state); + for (const device_state_entry &entry : m_state->state_entries()) + { + strmakelower(tempstr.assign(entry.symbol())); + m_symtable.add(tempstr.c_str(), (void *)(FPTR)entry.index(), get_state, set_state); } } diff --git a/src/emu/debug/debugvw.cpp b/src/emu/debug/debugvw.cpp index 641a31b41f0..135ac5fb76e 100644 --- a/src/emu/debug/debugvw.cpp +++ b/src/emu/debug/debugvw.cpp @@ -231,9 +231,9 @@ void debug_view::set_source(const debug_view_source &source) const debug_view_source *debug_view::source_for_device(device_t *device) const { - for (debug_view_source *source = m_source_list.first(); source != nullptr; source = source->next()) - if (device == source->device()) - return source; + for (debug_view_source &source : m_source_list) + if (device == source.device()) + return &source; return m_source_list.first(); } diff --git a/src/emu/debug/debugvw.h b/src/emu/debug/debugvw.h index ab4c986172e..cb1852aed2c 100644 --- a/src/emu/debug/debugvw.h +++ b/src/emu/debug/debugvw.h @@ -156,7 +156,7 @@ public: bool cursor_supported() { flush_updates(); return m_supports_cursor; } bool cursor_visible() { flush_updates(); return m_cursor_visible; } const debug_view_source *source() const { return m_source; } - const debug_view_source *first_source() { return m_source_list.first(); } + const debug_view_source *first_source() const { return m_source_list.first(); } const simple_list &source_list() const { return m_source_list; } // setters diff --git a/src/emu/debug/dvbpoints.cpp b/src/emu/debug/dvbpoints.cpp index 89b98e106d0..4e3f6f71bae 100644 --- a/src/emu/debug/dvbpoints.cpp +++ b/src/emu/debug/dvbpoints.cpp @@ -201,10 +201,10 @@ void debug_view_breakpoints::pad_ostream_to_length(std::ostream& str, int len) void debug_view_breakpoints::gather_breakpoints() { m_buffer.resize(0); - for (const debug_view_source *source = m_source_list.first(); source != nullptr; source = source->next()) + for (const debug_view_source &source : m_source_list) { // Collect - device_debug &debugInterface = *source->device()->debug(); + device_debug &debugInterface = *source.device()->debug(); for (device_debug::breakpoint *bp = debugInterface.breakpoint_first(); bp != nullptr; bp = bp->next()) m_buffer.push_back(bp); } diff --git a/src/emu/debug/dvdisasm.cpp b/src/emu/debug/dvdisasm.cpp index 10cb3e75e64..027e50b6f2a 100644 --- a/src/emu/debug/dvdisasm.cpp +++ b/src/emu/debug/dvdisasm.cpp @@ -66,9 +66,9 @@ debug_view_disasm::debug_view_disasm(running_machine &machine, debug_view_osd_up // count the number of comments int total_comments = 0; - for (const debug_view_source *source = m_source_list.first(); source != nullptr; source = source->next()) + for (const debug_view_source &source : m_source_list) { - const debug_view_disasm_source &dasmsource = downcast(*source); + const debug_view_disasm_source &dasmsource = downcast(source); total_comments += dasmsource.m_device.debug()->comment_count(); } diff --git a/src/emu/debug/dvmemory.cpp b/src/emu/debug/dvmemory.cpp index c39372af5b3..8efaa22ef9a 100644 --- a/src/emu/debug/dvmemory.cpp +++ b/src/emu/debug/dvmemory.cpp @@ -147,10 +147,10 @@ void debug_view_memory::enumerate_sources() } // then add all the memory regions - for (memory_region *region = machine().memory().first_region(); region != nullptr; region = region->next()) + for (memory_region ®ion : machine().memory().regions()) { - name = string_format("Region '%s'", region->name()); - m_source_list.append(*global_alloc(debug_view_memory_source(name.c_str(), *region))); + name = string_format("Region '%s'", region.name()); + m_source_list.append(*global_alloc(debug_view_memory_source(name.c_str(), region))); } // finally add all global array symbols diff --git a/src/emu/debug/dvstate.cpp b/src/emu/debug/dvstate.cpp index 8e1fe7513fd..773aa1fc3ee 100644 --- a/src/emu/debug/dvstate.cpp +++ b/src/emu/debug/dvstate.cpp @@ -141,15 +141,15 @@ void debug_view_state::recompute() tailptr = &(*tailptr)->m_next; // add all registers into it - for (const device_state_entry *entry = source.m_stateintf->state_first(); entry != nullptr; entry = entry->next()) - if (entry->divider()) + for (const device_state_entry &entry : source.m_stateintf->state_entries()) + if (entry.divider()) { *tailptr = global_alloc(state_item(REG_DIVIDER, "", 0)); tailptr = &(*tailptr)->m_next; } - else if (entry->visible()) + else if (entry.visible()) { - *tailptr = global_alloc(state_item(entry->index(), entry->symbol(), source.m_stateintf->state_string_max_length(entry->index()))); + *tailptr = global_alloc(state_item(entry.index(), entry.symbol(), source.m_stateintf->state_string_max_length(entry.index()))); tailptr = &(*tailptr)->m_next; } diff --git a/src/emu/debug/dvwpoints.cpp b/src/emu/debug/dvwpoints.cpp index 0e84726a7aa..17582796c39 100644 --- a/src/emu/debug/dvwpoints.cpp +++ b/src/emu/debug/dvwpoints.cpp @@ -224,10 +224,10 @@ void debug_view_watchpoints::pad_ostream_to_length(std::ostream& str, int len) void debug_view_watchpoints::gather_watchpoints() { m_buffer.resize(0); - for (const debug_view_source *source = m_source_list.first(); source != nullptr; source = source->next()) + for (const debug_view_source &source : m_source_list) { // Collect - device_debug &debugInterface = *source->device()->debug(); + device_debug &debugInterface = *source.device()->debug(); for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; ++spacenum) { for (device_debug::watchpoint *wp = debugInterface.watchpoint_first(spacenum); wp != nullptr; wp = wp->next()) diff --git a/src/emu/debug/express.cpp b/src/emu/debug/express.cpp index 62324092a28..7a9ed4697ae 100644 --- a/src/emu/debug/express.cpp +++ b/src/emu/debug/express.cpp @@ -1395,17 +1395,17 @@ UINT64 parsed_expression::execute_tokens() // loop over the entire sequence parse_token t1, t2, result; - for (parse_token *token = m_tokenlist.first(); token != nullptr; token = token->next()) + for (parse_token &token : m_tokenlist) { // symbols/numbers/strings just get pushed - if (!token->is_operator()) + if (!token.is_operator()) { - push_token(*token); + push_token(token); continue; } // otherwise, switch off the operator - switch (token->optype()) + switch (token.optype()) { case TVL_PREINCREMENT: pop_token_lval(t1); @@ -1616,7 +1616,7 @@ UINT64 parsed_expression::execute_tokens() break; case TVL_COMMA: - if (!token->is_function_separator()) + if (!token.is_function_separator()) { pop_token_rval(t2); pop_token_rval(t1); push_token(t2); @@ -1625,15 +1625,15 @@ UINT64 parsed_expression::execute_tokens() case TVL_MEMORYAT: pop_token_rval(t1); - push_token(result.configure_memory(t1.value(), *token)); + push_token(result.configure_memory(t1.value(), token)); break; case TVL_EXECUTEFUNC: - execute_function(*token); + execute_function(token); break; default: - throw expression_error(expression_error::SYNTAX, token->offset()); + throw expression_error(expression_error::SYNTAX, token.offset()); } } diff --git a/src/emu/debug/express.h b/src/emu/debug/express.h index fad3e478cf8..cdb0b8f02d4 100644 --- a/src/emu/debug/express.h +++ b/src/emu/debug/express.h @@ -169,7 +169,7 @@ public: symbol_table(void *globalref, symbol_table *parent = nullptr); // getters - symbol_entry *first() const { return m_symlist.first(); } + const auto &entries() const { return m_symlist; } symbol_table *parent() const { return m_parent; } void *globalref() const { return m_globalref; } diff --git a/src/emu/device.cpp b/src/emu/device.cpp index e6bfa46f051..59e4162314c 100644 --- a/src/emu/device.cpp +++ b/src/emu/device.cpp @@ -33,11 +33,6 @@ device_t::device_t(const machine_config &mconfig, device_type type, const char * m_owner(owner), m_next(nullptr), - m_interface_list(nullptr), - m_execute(nullptr), - m_memory(nullptr), - m_state(nullptr), - m_configured_clock(clock), m_unscaled_clock(clock), m_clock(clock), @@ -79,13 +74,10 @@ device_t::~device_t() // info for a given region //------------------------------------------------- -// NOTE: this being NULL in a C++ member function can lead to undefined behavior. -// However, it is relied on throughout MAME, so will remain for now. - memory_region *device_t::memregion(const char *_tag) const { // build a fully-qualified name and look it up - return machine().memory().region(subtag(_tag).c_str()); + return machine().memory().regions().find(subtag(_tag).c_str()); } @@ -97,7 +89,7 @@ memory_region *device_t::memregion(const char *_tag) const memory_share *device_t::memshare(const char *_tag) const { // build a fully-qualified name and look it up - return machine().memory().shared(subtag(_tag).c_str()); + return machine().memory().shares().find(subtag(_tag).c_str()); } @@ -109,7 +101,7 @@ memory_share *device_t::memshare(const char *_tag) const memory_bank *device_t::membank(const char *_tag) const { // build a fully-qualified name and look it up - return machine().memory().bank(subtag(_tag).c_str()); + return machine().memory().banks().find(subtag(_tag).c_str()); } @@ -164,8 +156,8 @@ void device_t::static_set_clock(device_t &device, UINT32 clock) void device_t::config_complete() { // first notify the interfaces - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_config_complete(); + for (device_interface &intf : interfaces()) + intf.interface_config_complete(); // then notify the device itself device_config_complete(); @@ -183,8 +175,8 @@ void device_t::config_complete() void device_t::validity_check(validity_checker &valid) const { // validate via the interfaces - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_validity_check(valid); + for (device_interface &intf : interfaces()) + intf.interface_validity_check(valid); // let the device itself validate device_validity_check(valid); @@ -198,22 +190,22 @@ void device_t::validity_check(validity_checker &valid) const void device_t::reset() { // let the interfaces do their pre-work - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_pre_reset(); + for (device_interface &intf : interfaces()) + intf.interface_pre_reset(); // reset the device device_reset(); // reset all child devices - for (device_t *child = m_subdevice_list.first(); child != nullptr; child = child->next()) - child->reset(); + for (device_t &child : subdevices()) + child.reset(); // now allow for some post-child reset action device_reset_after_children(); // let the interfaces do their post-work - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_post_reset(); + for (device_interface &intf : interfaces()) + intf.interface_post_reset(); } @@ -334,8 +326,8 @@ void device_t::start() throw emu_fatalerror("Missing some required objects, unable to proceed"); // let the interfaces do their pre-work - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_pre_start(); + for (device_interface &intf : interfaces()) + intf.interface_pre_start(); // remember the number of state registrations int state_registrations = machine().save().registration_count(); @@ -355,8 +347,8 @@ void device_t::start() } // let the interfaces do their post-work - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_post_start(); + for (device_interface &intf : interfaces()) + intf.interface_post_start(); // force an update of the clock notify_clock_changed(); @@ -385,15 +377,15 @@ void device_t::start() void device_t::stop() { // let the interfaces do their pre-work - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_pre_stop(); + for (device_interface &intf : interfaces()) + intf.interface_pre_stop(); // stop the device device_stop(); // let the interfaces do their post-work - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_post_stop(); + for (device_interface &intf : interfaces()) + intf.interface_post_stop(); // free any debugging info m_debug.reset(); @@ -411,8 +403,8 @@ void device_t::stop() void device_t::debug_setup() { // notify the interface - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_debug_setup(); + for (device_interface &intf : interfaces()) + intf.interface_debug_setup(); // notify the device device_debug_setup(); @@ -427,8 +419,8 @@ void device_t::debug_setup() void device_t::pre_save() { // notify the interface - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_pre_save(); + for (device_interface &intf : interfaces()) + intf.interface_pre_save(); // notify the device device_pre_save(); @@ -443,8 +435,8 @@ void device_t::pre_save() void device_t::post_load() { // notify the interface - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_post_load(); + for (device_interface &intf : interfaces()) + intf.interface_post_load(); // notify the device device_post_load(); @@ -459,8 +451,8 @@ void device_t::post_load() void device_t::notify_clock_changed() { // first notify interfaces - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_clock_changed(); + for (device_interface &intf : interfaces()) + intf.interface_clock_changed(); // then notify the device device_clock_changed(); @@ -643,14 +635,12 @@ device_t *device_t::subdevice_slow(const char *tag) const for (int start = 1, end = fulltag.find_first_of(':', start); start != 0 && curdevice != nullptr; start = end + 1, end = fulltag.find_first_of(':', start)) { std::string part(fulltag, start, (end == -1) ? -1 : end - start); - for (curdevice = curdevice->m_subdevice_list.first(); curdevice != nullptr; curdevice = curdevice->next()) - if (part.compare(curdevice->m_basetag)==0) - break; + curdevice = curdevice->subdevices().find(part); } // if we got a match, add to the fast map if (curdevice != nullptr) - m_device_map.insert(std::make_pair(tag, curdevice)); + m_subdevices.m_tagmap.insert(std::make_pair(tag, curdevice)); return curdevice; } @@ -711,65 +701,6 @@ std::string device_t::subtag(const char *tag) const } -//------------------------------------------------- -// add_subdevice - create a new device and add it -// as a subdevice -//------------------------------------------------- - -device_t *device_t::add_subdevice(device_type type, const char *tag, UINT32 clock) -{ - // allocate the device and append to our list - device_t *device = (*type)(mconfig(), tag, this, clock); - m_subdevice_list.append(*device); - - // apply any machine configuration owned by the device now - machine_config_constructor additions = device->machine_config_additions(); - if (additions != nullptr) - (*additions)(const_cast(mconfig()), device, nullptr); - return device; -} - - -//------------------------------------------------- -// add_subdevice - create a new device and use it -// to replace an existing subdevice -//------------------------------------------------- - -device_t *device_t::replace_subdevice(device_t &old, device_type type, const char *tag, UINT32 clock) -{ - // iterate over all devices and remove any references to the old device - device_iterator iter(mconfig().root_device()); - for (device_t *scan = iter.first(); scan != nullptr; scan = iter.next()) - scan->m_device_map.clear(); //remove(&old); - - // create a new device, and substitute it for the old one - device_t *device = (*type)(mconfig(), tag, this, clock); - m_subdevice_list.replace_and_remove(*device, old); - - // apply any machine configuration owned by the device now - machine_config_constructor additions = device->machine_config_additions(); - if (additions != nullptr) - (*additions)(const_cast(mconfig()), device, nullptr); - return device; -} - - -//------------------------------------------------- -// remove_subdevice - remove a given subdevice -//------------------------------------------------- - -void device_t::remove_subdevice(device_t &device) -{ - // iterate over all devices and remove any references - device_iterator iter(mconfig().root_device()); - for (device_t *scan = iter.first(); scan != nullptr; scan = iter.next()) - scan->m_device_map.clear(); //remove(&device); - - // remove from our list - m_subdevice_list.remove(device); -} - - //------------------------------------------------- // register_auto_finder - add a new item to the // list of stuff to find after we go live @@ -797,7 +728,7 @@ device_interface::device_interface(device_t &device, const char *type) m_type(type) { device_interface **tailptr; - for (tailptr = &device.m_interface_list; *tailptr != nullptr; tailptr = &(*tailptr)->m_interface_next) { } + for (tailptr = &device.interfaces().m_head; *tailptr != nullptr; tailptr = &(*tailptr)->m_interface_next) { } *tailptr = this; } diff --git a/src/emu/device.h b/src/emu/device.h index bf04b26d956..61e5066f507 100644 --- a/src/emu/device.h +++ b/src/emu/device.h @@ -93,16 +93,84 @@ class device_t : public delegate_late_bind { DISABLE_COPYING(device_t); - friend class device_interface; - friend class device_memory_interface; - friend class device_state_interface; - friend class device_execute_interface; friend class simple_list; - friend class device_list; - friend class machine_config; friend class running_machine; friend class finder_base; + class subdevice_list + { + friend class device_t; + friend class machine_config; + +public: + // construction/destruction + subdevice_list() { } + + // getters + device_t *first() const { return m_list.first(); } + + // range iterators + auto begin() const { return m_list.begin(); } + auto end() const { return m_list.end(); } + +private: + // private helpers + device_t *find(const std::string &name) const + { + device_t *curdevice; + for (curdevice = m_list.first(); curdevice != nullptr; curdevice = curdevice->next()) + if (name.compare(curdevice->m_basetag) == 0) + return curdevice; + return nullptr; + } + + // private state + simple_list m_list; // list of sub-devices we own + mutable std::unordered_map m_tagmap; // map of devices looked up and found by subtag + }; + + class interface_list + { + friend class device_t; + friend class device_interface; + friend class device_memory_interface; + friend class device_state_interface; + friend class device_execute_interface; + + class auto_iterator + { +public: + // construction/destruction + auto_iterator(device_interface *intf) : m_current(intf) { } + + // required operator overrides + bool operator!=(const auto_iterator &iter) const { return m_current != iter.m_current; } + device_interface &operator*() const { return *m_current; } + const auto &operator++(); + +private: + // private state + device_interface *m_current; + }; + +public: + // construction/destruction + interface_list() : m_head(nullptr), m_execute(nullptr), m_memory(nullptr), m_state(nullptr) { } + + // getters + device_interface *first() const { return m_head; } + + // range iterators + auto begin() const { return auto_iterator(m_head); } + auto end() const { return auto_iterator(nullptr); } + +private: + device_interface * m_head; // head of interface list + device_execute_interface *m_execute; // pre-cached pointer to execute interface + device_memory_interface *m_memory; // pre-cached pointer to memory interface + device_state_interface *m_state; // pre-cached pointer to state interface + }; + protected: // construction/destruction device_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); @@ -130,26 +198,30 @@ public: UINT8 default_bios() const { return m_default_bios; } UINT8 system_bios() const { return m_system_bios; } std::string default_bios_tag() const { return m_default_bios_tag; } - std::string parameter(const char *tag) const; + memory_region *region() const { return m_region; } // interface helpers - device_interface *first_interface() const { return m_interface_list; } + interface_list &interfaces() { return m_interfaces; } + const interface_list &interfaces() const { return m_interfaces; } template bool interface(_DeviceClass *&intf) { intf = dynamic_cast<_DeviceClass *>(this); return (intf != nullptr); } template bool interface(_DeviceClass *&intf) const { intf = dynamic_cast(this); return (intf != nullptr); } // specialized helpers for common core interfaces - bool interface(device_execute_interface *&intf) { intf = m_execute; return (intf != nullptr); } - bool interface(device_execute_interface *&intf) const { intf = m_execute; return (intf != nullptr); } - bool interface(device_memory_interface *&intf) { intf = m_memory; return (intf != nullptr); } - bool interface(device_memory_interface *&intf) const { intf = m_memory; return (intf != nullptr); } - bool interface(device_state_interface *&intf) { intf = m_state; return (intf != nullptr); } - bool interface(device_state_interface *&intf) const { intf = m_state; return (intf != nullptr); } - device_execute_interface &execute() const { assert(m_execute != nullptr); return *m_execute; } - device_memory_interface &memory() const { assert(m_memory != nullptr); return *m_memory; } - device_state_interface &state() const { assert(m_state != nullptr); return *m_state; } + bool interface(device_execute_interface *&intf) { intf = m_interfaces.m_execute; return (intf != nullptr); } + bool interface(device_execute_interface *&intf) const { intf = m_interfaces.m_execute; return (intf != nullptr); } + bool interface(device_memory_interface *&intf) { intf = m_interfaces.m_memory; return (intf != nullptr); } + bool interface(device_memory_interface *&intf) const { intf = m_interfaces.m_memory; return (intf != nullptr); } + bool interface(device_state_interface *&intf) { intf = m_interfaces.m_state; return (intf != nullptr); } + bool interface(device_state_interface *&intf) const { intf = m_interfaces.m_state; return (intf != nullptr); } + device_execute_interface &execute() const { assert(m_interfaces.m_execute != nullptr); return *m_interfaces.m_execute; } + device_memory_interface &memory() const { assert(m_interfaces.m_memory != nullptr); return *m_interfaces.m_memory; } + device_state_interface &state() const { assert(m_interfaces.m_state != nullptr); return *m_interfaces.m_state; } // owned object helpers - device_t *first_subdevice() const { return m_subdevice_list.first(); } + subdevice_list &subdevices() { return m_subdevices; } + const subdevice_list &subdevices() const { return m_subdevices; } + + // device-relative tag lookups std::string subtag(const char *tag) const; std::string siblingtag(const char *tag) const { return (m_owner != nullptr) ? m_owner->subtag(tag) : std::string(tag); } memory_region *memregion(const char *tag) const; @@ -160,7 +232,7 @@ public: device_t *siblingdevice(const char *tag) const; template inline _DeviceClass *subdevice(const char *tag) const { return downcast<_DeviceClass *>(subdevice(tag)); } template inline _DeviceClass *siblingdevice(const char *tag) const { return downcast<_DeviceClass *>(siblingdevice(tag)); } - memory_region *region() const { return m_region; } + std::string parameter(const char *tag) const; // configuration helpers static void static_set_clock(device_t &device, UINT32 clock); @@ -247,17 +319,11 @@ protected: std::string m_searchpath; // search path, used for media loading std::string m_source; // device source file name - // device relationships + // device relationships & interfaces device_t * m_owner; // device that owns us device_t * m_next; // next device by the same owner (of any type/class) - simple_list m_subdevice_list; // list of sub-devices we own - mutable std::unordered_map m_device_map; // map of device names looked up and found - - // device interfaces - device_interface * m_interface_list; // head of interface list - device_execute_interface *m_execute; // pre-cached pointer to execute interface - device_memory_interface *m_memory; // pre-cached pointer to memory interface - device_state_interface *m_state; // pre-cached pointer to state interface + subdevice_list m_subdevices; // container for list of subdevices + interface_list m_interfaces; // container for list of interfaces // device clocks UINT32 m_configured_clock; // originally configured device clock @@ -277,10 +343,7 @@ protected: std::string m_default_bios_tag; // tag of the default system BIOS private: - // private helpers - device_t *add_subdevice(device_type type, const char *tag, UINT32 clock); - device_t *replace_subdevice(device_t &old, device_type type, const char *tag, UINT32 clock); - void remove_subdevice(device_t &device); + // internal helpers device_t *subdevice_slow(const char *tag) const; // private state; accessor use required @@ -317,7 +380,6 @@ public: // iteration helpers device_interface *interface_next() const { return m_interface_next; } - template bool next(_InterfaceClass *&intf) const { return m_device.next(intf); } // optional operation overrides // @@ -379,7 +441,7 @@ public: // search down first if (m_curdepth < m_maxdepth) { - m_current = start->first_subdevice(); + m_current = start->subdevices().first(); if (m_current != nullptr) { m_curdepth++; @@ -593,8 +655,8 @@ inline device_t *device_t::subdevice(const char *tag) const return const_cast(this); // do a quick lookup and return that if possible - auto quick = m_device_map.find(tag); - return (quick != m_device_map.end()) ? quick->second : subdevice_slow(tag); + auto quick = m_subdevices.m_tagmap.find(tag); + return (quick != m_subdevices.m_tagmap.end()) ? quick->second : subdevice_slow(tag); } @@ -620,4 +682,13 @@ inline device_t *device_t::siblingdevice(const char *tag) const return (tag[0] == ':') ? subdevice(tag) : nullptr; } + +// this operator requires device_interface to be a complete type +inline const auto &device_t::interface_list::auto_iterator::operator++() +{ + m_current = m_current->interface_next(); + return *this; +} + + #endif /* __DEVICE_H__ */ diff --git a/src/emu/diexec.cpp b/src/emu/diexec.cpp index 02684095b04..fb3011bc59f 100644 --- a/src/emu/diexec.cpp +++ b/src/emu/diexec.cpp @@ -67,7 +67,7 @@ device_execute_interface::device_execute_interface(const machine_config &mconfig memset(&m_localtime, 0, sizeof(m_localtime)); // configure the fast accessor - device.m_execute = this; + device.interfaces().m_execute = this; } diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp index f225f6cd444..f20c9b7733d 100644 --- a/src/emu/diimage.cpp +++ b/src/emu/diimage.cpp @@ -199,9 +199,9 @@ image_error_t device_image_interface::set_image_filename(const char *filename) const image_device_format *device_image_interface::device_get_named_creatable_format(const char *format_name) { - for (const image_device_format *format = m_formatlist.first(); format != nullptr; format = format->next()) - if (strcmp(format->name(), format_name) == 0) - return format; + for (const image_device_format &format : m_formatlist) + if (strcmp(format.name(), format_name) == 0) + return &format; return nullptr; } diff --git a/src/emu/diimage.h b/src/emu/diimage.h index f15e0e555a9..a0b60823229 100644 --- a/src/emu/diimage.h +++ b/src/emu/diimage.h @@ -228,7 +228,7 @@ public: const char *instance_name() const { return m_instance_name.c_str(); } const char *brief_instance_name() const { return m_brief_instance_name.c_str(); } bool uses_file_extension(const char *file_extension) const; - image_device_format *formatlist() const { return m_formatlist.first(); } + const auto &formatlist() const { return m_formatlist; } bool load(const char *path); bool open_image_file(emu_options &options); diff --git a/src/emu/dimemory.cpp b/src/emu/dimemory.cpp index dbe3647ec01..56543ae551a 100644 --- a/src/emu/dimemory.cpp +++ b/src/emu/dimemory.cpp @@ -127,7 +127,7 @@ device_memory_interface::device_memory_interface(const machine_config &mconfig, memset(m_addrspace, 0, sizeof(m_addrspace)); // configure the fast accessor - device.m_memory = this; + device.interfaces().m_memory = this; } diff --git a/src/emu/dislot.h b/src/emu/dislot.h index 573d8fa2221..4eb73946a44 100644 --- a/src/emu/dislot.h +++ b/src/emu/dislot.h @@ -114,7 +114,7 @@ public: static void static_set_option_clock(device_t &device, const char *option, UINT32 default_clock) { static_option(device, option)->m_clock = default_clock; } bool fixed() const { return m_fixed; } const char *default_option() const { return m_default_option; } - device_slot_option *first_option() const { return m_options.first(); } + const auto &option_list() const { return m_options; } device_slot_option *option(const char *name) const { if (name) return m_options.find(name); return nullptr; } virtual std::string get_default_card_software() { return std::string(); } device_t *get_card_device(); diff --git a/src/emu/disound.cpp b/src/emu/disound.cpp index 7134b588963..1a3544b5d60 100644 --- a/src/emu/disound.cpp +++ b/src/emu/disound.cpp @@ -91,9 +91,9 @@ int device_sound_interface::inputs() const { // scan the list counting streams we own and summing their inputs int inputs = 0; - for (sound_stream *stream = m_device.machine().sound().first_stream(); stream != nullptr; stream = stream->next()) - if (&stream->device() == &m_device) - inputs += stream->input_count(); + for (sound_stream &stream : m_device.machine().sound().streams()) + if (&stream.device() == &m_device) + inputs += stream.input_count(); return inputs; } @@ -107,9 +107,9 @@ int device_sound_interface::outputs() const { // scan the list counting streams we own and summing their outputs int outputs = 0; - for (sound_stream *stream = m_device.machine().sound().first_stream(); stream != nullptr; stream = stream->next()) - if (&stream->device() == &m_device) - outputs += stream->output_count(); + for (sound_stream &stream : m_device.machine().sound().streams()) + if (&stream.device() == &m_device) + outputs += stream.output_count(); return outputs; } @@ -125,15 +125,15 @@ sound_stream *device_sound_interface::input_to_stream_input(int inputnum, int &s assert(inputnum >= 0); // scan the list looking for streams owned by this device - for (sound_stream *stream = m_device.machine().sound().first_stream(); stream != nullptr; stream = stream->next()) - if (&stream->device() == &m_device) + for (sound_stream &stream : m_device.machine().sound().streams()) + if (&stream.device() == &m_device) { - if (inputnum < stream->input_count()) + if (inputnum < stream.input_count()) { stream_inputnum = inputnum; - return stream; + return &stream; } - inputnum -= stream->input_count(); + inputnum -= stream.input_count(); } // not found @@ -152,15 +152,15 @@ sound_stream *device_sound_interface::output_to_stream_output(int outputnum, int assert(outputnum >= 0); // scan the list looking for streams owned by this device - for (sound_stream *stream = m_device.machine().sound().first_stream(); stream != nullptr; stream = stream->next()) - if (&stream->device() == &device()) + for (sound_stream &stream : m_device.machine().sound().streams()) + if (&stream.device() == &device()) { - if (outputnum < stream->output_count()) + if (outputnum < stream.output_count()) { stream_outputnum = outputnum; - return stream; + return &stream; } - outputnum -= stream->output_count(); + outputnum -= stream.output_count(); } // not found @@ -192,10 +192,10 @@ void device_sound_interface::set_output_gain(int outputnum, float gain) // handle ALL_OUTPUTS as a special case if (outputnum == ALL_OUTPUTS) { - for (sound_stream *stream = m_device.machine().sound().first_stream(); stream != nullptr; stream = stream->next()) - if (&stream->device() == &device()) - for (int num = 0; num < stream->output_count(); num++) - stream->set_output_gain(num, gain); + for (sound_stream &stream : m_device.machine().sound().streams()) + if (&stream.device() == &device()) + for (int num = 0; num < stream.output_count(); num++) + stream.set_output_gain(num, gain); } // look up the stream and stream output index @@ -217,10 +217,10 @@ void device_sound_interface::set_output_gain(int outputnum, float gain) int device_sound_interface::inputnum_from_device(device_t &source_device, int outputnum) const { int overall = 0; - for (sound_stream *stream = m_device.machine().sound().first_stream(); stream != nullptr; stream = stream->next()) - if (&stream->device() == &device()) - for (int inputnum = 0; inputnum < stream->input_count(); inputnum++, overall++) - if (stream->input_source_device(inputnum) == &source_device && stream->input_source_outputnum(inputnum) == outputnum) + for (sound_stream &stream : m_device.machine().sound().streams()) + if (&stream.device() == &device()) + for (int inputnum = 0; inputnum < stream.input_count(); inputnum++, overall++) + if (stream.input_source_device(inputnum) == &source_device && stream.input_source_outputnum(inputnum) == outputnum) return overall; return -1; } @@ -235,17 +235,17 @@ int device_sound_interface::inputnum_from_device(device_t &source_device, int ou void device_sound_interface::interface_validity_check(validity_checker &valid) const { // loop over all the routes - for (const sound_route *route = first_route(); route != nullptr; route = route->next()) + for (const sound_route &route : routes()) { // find a device with the requested tag - const device_t *target = device().siblingdevice(route->m_target.c_str()); + const device_t *target = device().siblingdevice(route.m_target.c_str()); if (target == nullptr) - osd_printf_error("Attempting to route sound to non-existant device '%s'\n", route->m_target.c_str()); + osd_printf_error("Attempting to route sound to non-existant device '%s'\n", route.m_target.c_str()); // if it's not a speaker or a sound device, error const device_sound_interface *sound; if (target != nullptr && target->type() != SPEAKER && !target->interface(sound)) - osd_printf_error("Attempting to route sound to a non-sound device '%s' (%s)\n", route->m_target.c_str(), target->name()); + osd_printf_error("Attempting to route sound to a non-sound device '%s' (%s)\n", route.m_target.c_str(), target->name()); } } @@ -262,10 +262,10 @@ void device_sound_interface::interface_pre_start() for (device_sound_interface *sound = iter.first(); sound != nullptr; sound = iter.next()) { // scan each route on the device - for (const sound_route *route = sound->first_route(); route != nullptr; route = route->next()) + for (const sound_route &route : sound->routes()) { // see if we are the target of this route; if we are, make sure the source device is started - device_t *target_device = sound->device().siblingdevice(route->m_target.c_str()); + device_t *target_device = sound->device().siblingdevice(route.m_target.c_str()); if (target_device == &m_device && !sound->device().started()) throw device_missing_dependencies(); } @@ -276,14 +276,14 @@ void device_sound_interface::interface_pre_start() for (device_sound_interface *sound = iter.first(); sound != nullptr; sound = iter.next()) { // scan each route on the device - for (const sound_route *route = sound->first_route(); route != nullptr; route = route->next()) + for (sound_route &route : sound->routes()) { // see if we are the target of this route - device_t *target_device = sound->device().siblingdevice(route->m_target.c_str()); - if (target_device == &m_device && route->m_input == AUTO_ALLOC_INPUT) + device_t *target_device = sound->device().siblingdevice(route.m_target.c_str()); + if (target_device == &m_device && route.m_input == AUTO_ALLOC_INPUT) { - const_cast(route)->m_input = m_auto_allocated_inputs; - m_auto_allocated_inputs += (route->m_output == ALL_OUTPUTS) ? sound->outputs() : 1; + route.m_input = m_auto_allocated_inputs; + m_auto_allocated_inputs += (route.m_output == ALL_OUTPUTS) ? sound->outputs() : 1; } } } @@ -302,32 +302,32 @@ void device_sound_interface::interface_post_start() for (device_sound_interface *sound = iter.first(); sound != nullptr; sound = iter.next()) { // scan each route on the device - for (const sound_route *route = sound->first_route(); route != nullptr; route = route->next()) + for (const sound_route &route : sound->routes()) { // if we are the target of this route, hook it up - device_t *target_device = sound->device().siblingdevice(route->m_target.c_str()); + device_t *target_device = sound->device().siblingdevice(route.m_target.c_str()); if (target_device == &m_device) { // iterate over all outputs, matching any that apply - int inputnum = route->m_input; + int inputnum = route.m_input; int numoutputs = sound->outputs(); for (int outputnum = 0; outputnum < numoutputs; outputnum++) - if (route->m_output == outputnum || route->m_output == ALL_OUTPUTS) + if (route.m_output == outputnum || route.m_output == ALL_OUTPUTS) { // find the output stream to connect from int streamoutputnum; sound_stream *outputstream = sound->output_to_stream_output(outputnum, streamoutputnum); if (outputstream == nullptr) - fatalerror("Sound device '%s' specifies route for non-existant output #%d\n", route->m_target.c_str(), outputnum); + fatalerror("Sound device '%s' specifies route for non-existant output #%d\n", route.m_target.c_str(), outputnum); // find the input stream to connect to int streaminputnum; sound_stream *inputstream = input_to_stream_input(inputnum++, streaminputnum); if (inputstream == nullptr) - fatalerror("Sound device '%s' targeted output #%d to non-existant device '%s' input %d\n", route->m_target.c_str(), outputnum, m_device.tag(), inputnum - 1); + fatalerror("Sound device '%s' targeted output #%d to non-existant device '%s' input %d\n", route.m_target.c_str(), outputnum, m_device.tag(), inputnum - 1); // set the input - inputstream->set_input(streaminputnum, outputstream, streamoutputnum, route->m_gain); + inputstream->set_input(streaminputnum, outputstream, streamoutputnum, route.m_gain); } } } @@ -343,9 +343,9 @@ void device_sound_interface::interface_post_start() void device_sound_interface::interface_pre_reset() { // update all streams on this device prior to reset - for (sound_stream *stream = m_device.machine().sound().first_stream(); stream != nullptr; stream = stream->next()) - if (&stream->device() == &device()) - stream->update(); + for (sound_stream &stream : m_device.machine().sound().streams()) + if (&stream.device() == &device()) + stream.update(); } @@ -418,15 +418,15 @@ void device_mixer_interface::interface_pre_start() // iterate through all routes that point to us and note their mixer output sound_interface_iterator iter(m_device.machine().root_device()); for (device_sound_interface *sound = iter.first(); sound != nullptr; sound = iter.next()) - for (const sound_route *route = sound->first_route(); route != nullptr; route = route->next()) + for (const sound_route &route : sound->routes()) { // see if we are the target of this route - device_t *target_device = sound->device().siblingdevice(route->m_target.c_str()); - if (target_device == &device() && route->m_input < m_auto_allocated_inputs) + device_t *target_device = sound->device().siblingdevice(route.m_target.c_str()); + if (target_device == &device() && route.m_input < m_auto_allocated_inputs) { - int count = (route->m_output == ALL_OUTPUTS) ? sound->outputs() : 1; + int count = (route.m_output == ALL_OUTPUTS) ? sound->outputs() : 1; for (int output = 0; output < count; output++) - m_outputmap[route->m_input + output] = route->m_mixoutput; + m_outputmap[route.m_input + output] = route.m_mixoutput; } } diff --git a/src/emu/disound.h b/src/emu/disound.h index 7f6f6868b98..c1a7b752698 100644 --- a/src/emu/disound.h +++ b/src/emu/disound.h @@ -73,7 +73,7 @@ public: public: sound_route(int output, int input, float gain, const char *target, UINT32 mixoutput); - const sound_route *next() const { return m_next; } + sound_route *next() const { return m_next; } sound_route * m_next; // pointer to next route UINT32 m_output; // output index, or ALL_OUTPUTS @@ -88,7 +88,7 @@ public: virtual ~device_sound_interface(); // configuration access - const sound_route *first_route() const { return m_route_list.first(); } + const auto &routes() const { return m_route_list; } // static inline configuration helpers static sound_route &static_add_route(device_t &device, UINT32 output, const char *target, double gain, UINT32 input = AUTO_ALLOC_INPUT, UINT32 mixoutput = 0); diff --git a/src/emu/distate.cpp b/src/emu/distate.cpp index dcf14c02ee8..3fa2fd8e03b 100644 --- a/src/emu/distate.cpp +++ b/src/emu/distate.cpp @@ -397,7 +397,7 @@ device_state_interface::device_state_interface(const machine_config &mconfig, de memset(m_fast_state, 0, sizeof(m_fast_state)); // configure the fast accessor - device.m_state = this; + device.interfaces().m_state = this; } diff --git a/src/emu/distate.h b/src/emu/distate.h index 67734fefa4b..ebd62eaaddf 100644 --- a/src/emu/distate.h +++ b/src/emu/distate.h @@ -61,7 +61,7 @@ public: device_state_entry &noshow() { m_flags |= DSF_NOSHOW; return *this; } // iteration helpers - const device_state_entry *next() const { return m_next; } + device_state_entry *next() const { return m_next; } // query information int index() const { return m_index; } @@ -124,7 +124,7 @@ public: virtual ~device_state_interface(); // configuration access - const device_state_entry *state_first() const { return m_state_list.first(); } + const auto &state_entries() const { return m_state_list; } // state getters UINT64 state_int(int index); @@ -197,7 +197,7 @@ typedef device_interface_iterator state_interface_iterat inline offs_t device_t::safe_pc() const { - return (m_state != nullptr) ? m_state->pc() : 0; + return (m_interfaces.m_state != nullptr) ? m_interfaces.m_state->pc() : 0; } @@ -208,7 +208,7 @@ inline offs_t device_t::safe_pc() const inline offs_t device_t::safe_pcbase() const { - return (m_state != nullptr) ? m_state->pcbase() : 0; + return (m_interfaces.m_state != nullptr) ? m_interfaces.m_state->pcbase() : 0; } diff --git a/src/emu/emuopts.cpp b/src/emu/emuopts.cpp index 8db25068436..e05a16a5dd5 100644 --- a/src/emu/emuopts.cpp +++ b/src/emu/emuopts.cpp @@ -311,7 +311,7 @@ void emu_options::update_slot_options(const software_part *swpart) { // retrieve info about the device instance const char *name = slot->device().tag() + 1; - if (exists(name) && slot->first_option() != nullptr) + if (exists(name) && !slot->option_list().empty()) { std::string defvalue = slot->get_default_card_software(); if (defvalue.length() > 0) diff --git a/src/emu/info.cpp b/src/emu/info.cpp index dff761d5dcd..7a42ccbb360 100644 --- a/src/emu/info.cpp +++ b/src/emu/info.cpp @@ -335,9 +335,9 @@ void info_xml_creator::output_one_device(device_t &device, const char *devtag) for (device_t *dev = iptiter.first(); dev != nullptr; dev = iptiter.next()) portlist.append(*dev, errors); // check if the device adds player inputs (other than dsw and configs) to the system - for (ioport_port *port = portlist.first(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->type() >= IPT_START1 && field->type() < IPT_UI_FIRST) + for (ioport_port &port : portlist) + for (ioport_field &field : port.fields()) + if (field.type() >= IPT_START1 && field.type() < IPT_UI_FIRST) { has_input = TRUE; break; @@ -409,11 +409,11 @@ void info_xml_creator::output_devices() slot_interface_iterator iter(m_drivlist.config().root_device()); for (const device_slot_interface *slot = iter.first(); slot != nullptr; slot = iter.next()) { - for (const device_slot_option *option = slot->first_option(); option != nullptr; option = option->next()) + for (const device_slot_option &option : slot->option_list()) { std::string temptag("_"); - temptag.append(option->name()); - device_t *dev = const_cast(m_drivlist.config()).device_add(&m_drivlist.config().root_device(), temptag.c_str(), option->devtype(), 0); + temptag.append(option.name()); + device_t *dev = const_cast(m_drivlist.config()).device_add(&m_drivlist.config().root_device(), temptag.c_str(), option.devtype(), 0); // notify this device and all its subdevices that they are now configured device_iterator subiter(*dev); @@ -842,33 +842,33 @@ void info_xml_creator::output_input(const ioport_list &portlist) bool gambling = false; // iterate over the ports - for (ioport_port *port = portlist.first(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + for (ioport_port &port : portlist) + for (ioport_field &field : port.fields()) { int analogtype = -1; // track the highest player number - if (nplayer < field->player() + 1) - nplayer = field->player() + 1; + if (nplayer < field.player() + 1) + nplayer = field.player() + 1; // switch off of the type - switch (field->type()) + switch (field.type()) { // map which joystick directions are present - case IPT_JOYSTICK_UP: joytype[0] |= DIR_UP | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICK_DOWN: joytype[0] |= DIR_DOWN | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICK_LEFT: joytype[0] |= DIR_LEFT | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICK_RIGHT: joytype[0] |= DIR_RIGHT | ((field->way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICK_UP: joytype[0] |= DIR_UP | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICK_DOWN: joytype[0] |= DIR_DOWN | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICK_LEFT: joytype[0] |= DIR_LEFT | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICK_RIGHT: joytype[0] |= DIR_RIGHT | ((field.way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICKLEFT_UP: joytype[1] |= DIR_UP | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICKLEFT_DOWN: joytype[1] |= DIR_DOWN | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICKLEFT_LEFT: joytype[1] |= DIR_LEFT | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICKLEFT_RIGHT: joytype[1] |= DIR_RIGHT | ((field->way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICKLEFT_UP: joytype[1] |= DIR_UP | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICKLEFT_DOWN: joytype[1] |= DIR_DOWN | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICKLEFT_LEFT: joytype[1] |= DIR_LEFT | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICKLEFT_RIGHT: joytype[1] |= DIR_RIGHT | ((field.way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICKRIGHT_UP: joytype[2] |= DIR_UP | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICKRIGHT_DOWN: joytype[2] |= DIR_DOWN | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICKRIGHT_LEFT: joytype[2] |= DIR_LEFT | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICKRIGHT_RIGHT: joytype[2] |= DIR_RIGHT | ((field->way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICKRIGHT_UP: joytype[2] |= DIR_UP | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICKRIGHT_DOWN: joytype[2] |= DIR_DOWN | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICKRIGHT_LEFT: joytype[2] |= DIR_LEFT | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICKRIGHT_RIGHT: joytype[2] |= DIR_RIGHT | ((field.way() == 4) ? DIR_4WAY : 0); break; // mark as an analog input, and get analog stats after switch case IPT_AD_STICK_X: @@ -930,7 +930,7 @@ void info_xml_creator::output_input(const ioport_list &portlist) case IPT_BUTTON14: case IPT_BUTTON15: case IPT_BUTTON16: - nbutton = MAX(nbutton, field->type() - IPT_BUTTON1 + 1); + nbutton = MAX(nbutton, field.type() - IPT_BUTTON1 + 1); break; // track maximum coin index @@ -942,7 +942,7 @@ void info_xml_creator::output_input(const ioport_list &portlist) case IPT_COIN6: case IPT_COIN7: case IPT_COIN8: - ncoin = MAX(ncoin, field->type() - IPT_COIN1 + 1); + ncoin = MAX(ncoin, field.type() - IPT_COIN1 + 1); break; // track presence of these guys @@ -964,11 +964,11 @@ void info_xml_creator::output_input(const ioport_list &portlist) break; default: - if (field->type() > IPT_MAHJONG_FIRST && field->type() < IPT_MAHJONG_LAST) + if (field.type() > IPT_MAHJONG_FIRST && field.type() < IPT_MAHJONG_LAST) mahjong = true; - else if (field->type() > IPT_HANAFUDA_FIRST && field->type() < IPT_HANAFUDA_LAST) + else if (field.type() > IPT_HANAFUDA_FIRST && field.type() < IPT_HANAFUDA_LAST) hanafuda = true; - else if (field->type() > IPT_GAMBLING_FIRST && field->type() < IPT_GAMBLING_LAST) + else if (field.type() > IPT_GAMBLING_FIRST && field.type() < IPT_GAMBLING_LAST) gambling = true; break; } @@ -976,15 +976,15 @@ void info_xml_creator::output_input(const ioport_list &portlist) // get the analog stats if (analogtype != -1) { - if (field->minval() != 0) - control_info[analogtype].min = field->minval(); - if (field->maxval() != 0) - control_info[analogtype].max = field->maxval(); - if (field->sensitivity() != 0) - control_info[analogtype].sensitivity = field->sensitivity(); - if (field->delta() != 0) - control_info[analogtype].keydelta = field->delta(); - if (field->analog_reverse() != 0) + if (field.minval() != 0) + control_info[analogtype].min = field.minval(); + if (field.maxval() != 0) + control_info[analogtype].max = field.maxval(); + if (field.sensitivity() != 0) + control_info[analogtype].sensitivity = field.sensitivity(); + if (field.delta() != 0) + control_info[analogtype].keydelta = field.delta(); + if (field.analog_reverse() != 0) control_info[analogtype].reverse = true; } } @@ -1092,24 +1092,24 @@ void info_xml_creator::output_input(const ioport_list &portlist) void info_xml_creator::output_switches(const ioport_list &portlist, const char *root_tag, int type, const char *outertag, const char *innertag) { // iterate looking for DIP switches - for (ioport_port *port = portlist.first(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->type() == type) + for (ioport_port &port : portlist) + for (ioport_field &field : port.fields()) + if (field.type() == type) { std::ostringstream output; - std::string newtag(port->tag()), oldtag(":"); + std::string newtag(port.tag()), oldtag(":"); newtag = newtag.substr(newtag.find(oldtag.append(root_tag)) + oldtag.length()); // output the switch name information - std::string normalized_field_name(xml_normalize_string(field->name())); + std::string normalized_field_name(xml_normalize_string(field.name())); std::string normalized_newtag(xml_normalize_string(newtag.c_str())); - util::stream_format(output,"\t\t<%s name=\"%s\" tag=\"%s\" mask=\"%u\">\n", outertag, normalized_field_name.c_str(), normalized_newtag.c_str(), field->mask()); + util::stream_format(output,"\t\t<%s name=\"%s\" tag=\"%s\" mask=\"%u\">\n", outertag, normalized_field_name.c_str(), normalized_newtag.c_str(), field.mask()); // loop over settings - for (ioport_setting *setting = field->first_setting(); setting != nullptr; setting = setting->next()) + for (ioport_setting &setting : field.settings()) { - util::stream_format(output,"\t\t\t<%s name=\"%s\" value=\"%u\"%s/>\n", innertag, xml_normalize_string(setting->name()), setting->value(), setting->value() == field->defvalue() ? " default=\"yes\"" : ""); + util::stream_format(output,"\t\t\t<%s name=\"%s\" value=\"%u\"%s/>\n", innertag, xml_normalize_string(setting.name()), setting.value(), setting.value() == field.defvalue() ? " default=\"yes\"" : ""); } // terminate the switch entry @@ -1126,13 +1126,13 @@ void info_xml_creator::output_switches(const ioport_list &portlist, const char * void info_xml_creator::output_ports(const ioport_list &portlist) { // cycle through ports - for (ioport_port *port = portlist.first(); port != nullptr; port = port->next()) + for (ioport_port &port : portlist) { - fprintf(m_output,"\t\t\n",port->tag()); - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + fprintf(m_output,"\t\t\n", port.tag()); + for (ioport_field &field : port.fields()) { - if(field->is_analog()) - fprintf(m_output,"\t\t\t\n",field->mask()); + if(field.is_analog()) + fprintf(m_output,"\t\t\t\n", field.mask()); } // close element fprintf(m_output,"\t\t\n"); @@ -1148,10 +1148,10 @@ void info_xml_creator::output_ports(const ioport_list &portlist) void info_xml_creator::output_adjusters(const ioport_list &portlist) { // iterate looking for Adjusters - for (ioport_port *port = portlist.first(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->type() == IPT_ADJUSTER) - fprintf(m_output, "\t\t\n", xml_normalize_string(field->name()), field->defvalue()); + for (ioport_port &port : portlist) + for (ioport_field &field : port.fields()) + if (field.type() == IPT_ADJUSTER) + fprintf(m_output, "\t\t\n", xml_normalize_string(field.name()), field.defvalue()); } @@ -1298,18 +1298,18 @@ void info_xml_creator::output_slots(device_t &device, const char *root_tag) fprintf(m_output, " interface=\"%s\"", xml_normalize_string(slot->slot_interface())); */ - for (const device_slot_option *option = slot->first_option(); option != nullptr; option = option->next()) + for (const device_slot_option &option : slot->option_list()) { - if (option->selectable()) + if (option.selectable()) { - device_t *dev = const_cast(m_drivlist.config()).device_add(&m_drivlist.config().root_device(), "dummy", option->devtype(), 0); + device_t *dev = const_cast(m_drivlist.config()).device_add(&m_drivlist.config().root_device(), "dummy", option.devtype(), 0); if (!dev->configured()) dev->config_complete(); fprintf(m_output, "\t\t\tname())); + fprintf(m_output, " name=\"%s\"", xml_normalize_string(option.name())); fprintf(m_output, " devname=\"%s\"", xml_normalize_string(dev->shortname())); - if (slot->default_option() != nullptr && strcmp(slot->default_option(),option->name())==0) + if (slot->default_option() != nullptr && strcmp(slot->default_option(),option.name())==0) fprintf(m_output, " default=\"yes\""); fprintf(m_output, "/>\n"); const_cast(m_drivlist.config()).device_remove(&m_drivlist.config().root_device(), "dummy"); diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp index dc197ed8734..3d50bcf9e5e 100644 --- a/src/emu/ioport.cpp +++ b/src/emu/ioport.cpp @@ -659,8 +659,8 @@ void ioport_list::append(device_t &device, std::string &errorbuf) (*constructor)(device, *this, errorbuf); // collapse fields and sort the list - for (ioport_port *port = first(); port != nullptr; port = port->next()) - port->collapse_fields(errorbuf); + for (ioport_port &port : *this) + port.collapse_fields(errorbuf); } @@ -770,10 +770,10 @@ void digital_joystick::frame_update() // read all the associated ports running_machine *machine = nullptr; for (direction_t direction = JOYDIR_UP; direction < JOYDIR_COUNT; ++direction) - for (const simple_list_wrapper *i = m_field[direction].first(); i != nullptr; i = i->next()) + for (const simple_list_wrapper &i : m_field[direction]) { - machine = &i->object()->machine(); - if (machine->input().seq_pressed(i->object()->seq(SEQ_TYPE_STANDARD))) + machine = &i.object()->machine(); + if (machine->input().seq_pressed(i.object()->seq(SEQ_TYPE_STANDARD))) m_current |= 1 << direction; } @@ -903,7 +903,7 @@ void natural_keyboard::post(unicode_char ch) if (LOG_NATURAL_KEYBOARD) { const keycode_map_entry *code = find_code(ch); - machine().logerror("natural_keyboard::post(): code=%i (%s) field->name='%s'\n", int(ch), unicode_to_string(ch).c_str(), (code != nullptr && code->field[0] != nullptr) ? code->field[0]->name() : ""); + machine().logerror("natural_keyboard::post(): code=%i (%s) field.name='%s'\n", int(ch), unicode_to_string(ch).c_str(), (code != nullptr && code->field[0] != nullptr) ? code->field[0]->name() : ""); } // can we post this key in the queue directly? @@ -1074,18 +1074,18 @@ void natural_keyboard::build_codes(ioport_manager &manager) if (curshift == 0 || shift[curshift - 1] != nullptr) // iterate over ports and fields - for (ioport_port *port = manager.first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->type() == IPT_KEYBOARD) + for (ioport_port &port : manager.ports()) + for (ioport_field &field : port.fields()) + if (field.type() == IPT_KEYBOARD) { // fetch the code, ignoring 0 - unicode_char code = field->keyboard_code(curshift); + unicode_char code = field.keyboard_code(curshift); if (code == 0) continue; // is this a shifter key? if (code >= UCHAR_SHIFT_BEGIN && code <= UCHAR_SHIFT_END) - shift[code - UCHAR_SHIFT_BEGIN] = field; + shift[code - UCHAR_SHIFT_BEGIN] = &field; // not a shifter key; record normally else @@ -1093,20 +1093,20 @@ void natural_keyboard::build_codes(ioport_manager &manager) keycode_map_entry newcode; if (curshift == 0) { - newcode.field[0] = field; + newcode.field[0] = &field; newcode.field[1] = nullptr; } else { newcode.field[0] = shift[curshift - 1]; - newcode.field[1] = field; + newcode.field[1] = &field; } newcode.ch = code; m_keycode_map.push_back(newcode); if (LOG_NATURAL_KEYBOARD) { - machine().logerror("natural_keyboard: code=%i (%s) port=%p field->name='%s'\n", int(code), unicode_to_string(code).c_str(), (void *)port, field->name()); + machine().logerror("natural_keyboard: code=%i (%s) port=%p field.name='%s'\n", int(code), unicode_to_string(code).c_str(), (void *)&port, field.name()); } } } @@ -1687,7 +1687,7 @@ void ioport_field::get_user_settings(user_settings &settings) settings.seq[seqtype] = seq(seqtype); // if there's a list of settings or we're an adjuster, copy the current value - if (first_setting() != nullptr || m_type == IPT_ADJUSTER) + if (!m_settinglist.empty() || m_type == IPT_ADJUSTER) settings.value = m_live->value; // if there's analog data, extract the analog settings @@ -1726,7 +1726,7 @@ void ioport_field::set_user_settings(const user_settings &settings) } // if there's a list of settings or we're an adjuster, copy the current value - if (first_setting() != nullptr || m_type == IPT_ADJUSTER) + if (!m_settinglist.empty() || m_type == IPT_ADJUSTER) m_live->value = settings.value; // if there's analog data, extract the analog settings @@ -1755,13 +1755,13 @@ void ioport_field::set_user_settings(const user_settings &settings) const char *ioport_field::setting_name() const { // only makes sense if we have settings - assert(first_setting() != nullptr); + assert(!m_settinglist.empty()); // scan the list of settings looking for a match on the current value - for (ioport_setting *setting = first_setting(); setting != nullptr; setting = setting->next()) - if (setting->enabled()) - if (setting->value() == m_live->value) - return setting->name(); + for (ioport_setting &setting : m_settinglist) + if (setting.enabled()) + if (setting.value() == m_live->value) + return setting.name(); return "INVALID"; } @@ -1775,12 +1775,12 @@ const char *ioport_field::setting_name() const bool ioport_field::has_previous_setting() const { // only makes sense if we have settings - assert(first_setting() != nullptr); + assert(!m_settinglist.empty()); // scan the list of settings looking for a match on the current value - for (ioport_setting *setting = first_setting(); setting != nullptr; setting = setting->next()) - if (setting->enabled()) - return (setting->value() != m_live->value); + for (ioport_setting &setting : m_settinglist) + if (setting.enabled()) + return (setting.value() != m_live->value); return false; } @@ -1794,27 +1794,27 @@ bool ioport_field::has_previous_setting() const void ioport_field::select_previous_setting() { // only makes sense if we have settings - assert(first_setting() != nullptr); + assert(!m_settinglist.empty()); // scan the list of settings looking for a match on the current value ioport_setting *prevsetting = nullptr; bool found_match = false; - for (ioport_setting *setting = first_setting(); setting != nullptr; setting = setting->next()) - if (setting->enabled()) + for (ioport_setting &setting : m_settinglist) + if (setting.enabled()) { - if (setting->value() == m_live->value) + if (setting.value() == m_live->value) { found_match = true; if (prevsetting != nullptr) break; } - prevsetting = setting; + prevsetting = &setting; } // if we didn't find a matching value, select the first if (!found_match) { - for (prevsetting = first_setting(); prevsetting != nullptr; prevsetting = prevsetting->next()) + for (prevsetting = m_settinglist.first(); prevsetting != nullptr; prevsetting = prevsetting->next()) if (prevsetting->enabled()) break; } @@ -1833,16 +1833,16 @@ void ioport_field::select_previous_setting() bool ioport_field::has_next_setting() const { // only makes sense if we have settings - assert(first_setting() != nullptr); + assert(!m_settinglist.empty()); // scan the list of settings looking for a match on the current value bool found = false; - for (ioport_setting *setting = first_setting(); setting != nullptr; setting = setting->next()) - if (setting->enabled()) + for (ioport_setting &setting : m_settinglist) + if (setting.enabled()) { if (found) return true; - if (setting->value() == m_live->value) + if (setting.value() == m_live->value) found = true; } @@ -1858,12 +1858,12 @@ bool ioport_field::has_next_setting() const void ioport_field::select_next_setting() { // only makes sense if we have settings - assert(first_setting() != nullptr); + assert(!m_settinglist.empty()); // scan the list of settings looking for a match on the current value ioport_setting *nextsetting = nullptr; ioport_setting *setting; - for (setting = first_setting(); setting != nullptr; setting = setting->next()) + for (setting = m_settinglist.first(); setting != nullptr; setting = setting->next()) if (setting->enabled()) if (setting->value() == m_live->value) break; @@ -1876,7 +1876,7 @@ void ioport_field::select_next_setting() // if we hit the end, search from the beginning if (nextsetting == nullptr) - for (nextsetting = first_setting(); nextsetting != nullptr; nextsetting = nextsetting->next()) + for (nextsetting = m_settinglist.first(); nextsetting != nullptr; nextsetting = nextsetting->next()) if (nextsetting->enabled()) break; @@ -2154,8 +2154,8 @@ void ioport_field::init_live_state(analog_field *analog) m_condition.initialize(device()); - for (ioport_setting *setting = first_setting(); setting != nullptr; setting = setting->next()) - setting->condition().initialize(setting->device()); + for (ioport_setting &setting : m_settinglist) + setting.condition().initialize(setting.device()); } @@ -2267,12 +2267,12 @@ ioport_manager &ioport_port::manager() const // that intersects the given mask //------------------------------------------------- -ioport_field *ioport_port::field(ioport_value mask) +ioport_field *ioport_port::field(ioport_value mask) const { // if we got the port, look for the field - for (ioport_field *field = first_field(); field != nullptr; field = field->next()) - if ((field->mask() & mask) != 0) - return field; + for (ioport_field &field : fields()) + if ((field.mask() & mask) != 0) + return &field; return nullptr; } @@ -2289,15 +2289,15 @@ ioport_value ioport_port::read() ioport_value result = m_live->digital; // insert dynamic read values - for (dynamic_field *dynfield = m_live->readlist.first(); dynfield != nullptr; dynfield = dynfield->next()) - dynfield->read(result); + for (dynamic_field &dynfield : m_live->readlist) + dynfield.read(result); // apply active high/low state to digital and dynamic read inputs result ^= m_live->defvalue; // insert analog portions - for (analog_field *analog = m_live->analoglist.first(); analog != nullptr; analog = analog->next()) - analog->read(result); + for (analog_field &analog : m_live->analoglist) + analog.read(result); return result; } @@ -2311,9 +2311,9 @@ void ioport_port::write(ioport_value data, ioport_value mem_mask) { // call device line write handlers COMBINE_DATA(&m_live->outputvalue); - for (dynamic_field *dynfield = m_live->writelist.first(); dynfield != nullptr; dynfield = dynfield->next()) - if (dynfield->field().type() == IPT_OUTPUT) - dynfield->write(m_live->outputvalue ^ dynfield->field().defvalue()); + for (dynamic_field &dynfield : m_live->writelist) + if (dynfield.field().type() == IPT_OUTPUT) + dynfield.write(m_live->outputvalue ^ dynfield.field().defvalue()); } @@ -2327,8 +2327,8 @@ void ioport_port::frame_update(ioport_field *mouse_field) m_live->digital = 0; // now loop back and modify based on the inputs - for (ioport_field *field = first_field(); field != nullptr; field = field->next()) - field->frame_update(m_live->digital, field == mouse_field); + for (ioport_field &field : fields()) + field.frame_update(m_live->digital, &field == mouse_field); // hook for MESS's natural keyboard support manager().natkeyboard().frame_update(*this, m_live->digital); @@ -2381,7 +2381,7 @@ void ioport_port::insert_field(ioport_field &newfield, ioport_value &disallowedb // first modify/nuke any entries that intersect our maskbits ioport_field *nextfield; - for (ioport_field *field = first_field(); field != nullptr; field = nextfield) + for (ioport_field *field = m_fieldlist.first(); field != nullptr; field = nextfield) { nextfield = field->next(); if ((field->mask() & newfield.mask()) != 0 && @@ -2401,7 +2401,7 @@ void ioport_port::insert_field(ioport_field &newfield, ioport_value &disallowedb // scan forward to find where to insert ourselves ioport_field *field; - for (field = first_field(); field != nullptr; field = field->next()) + for (field = m_fieldlist.first(); field != nullptr; field = field->next()) if (field->mask() > lowbit) break; @@ -2435,23 +2435,23 @@ ioport_port_live::ioport_port_live(ioport_port &port) outputvalue(0) { // iterate over fields - for (ioport_field *field = port.first_field(); field != nullptr; field = field->next()) + for (ioport_field &field : port.fields()) { // allocate analog state if it's analog analog_field *analog = nullptr; - if (field->is_analog()) - analog = &analoglist.append(*global_alloc(analog_field(*field))); + if (field.is_analog()) + analog = &analoglist.append(*global_alloc(analog_field(field))); // allocate a dynamic field for reading - if (field->has_dynamic_read()) - readlist.append(*global_alloc(dynamic_field(*field))); + if (field.has_dynamic_read()) + readlist.append(*global_alloc(dynamic_field(field))); // allocate a dynamic field for writing - if (field->has_dynamic_write()) - writelist.append(*global_alloc(dynamic_field(*field))); + if (field.has_dynamic_write()) + writelist.append(*global_alloc(dynamic_field(field))); // let the field initialize its live state - field->init_live_state(analog); + field.init_live_state(analog); } } @@ -2518,15 +2518,15 @@ time_t ioport_manager::initialize() for (device_t *device = iter.first(); device != nullptr; device = iter.next()) { int players = 0; - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) + for (ioport_port &port : m_portlist) { - if (&port->device()==device) + if (&port.device() == device) { - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->type_class()==INPUT_CLASS_CONTROLLER) + for (ioport_field &field : port.fields()) + if (field.type_class()==INPUT_CLASS_CONTROLLER) { - if (players < field->player() + 1) players = field->player() + 1; - field->set_player(field->player() + player_offset); + if (players < field.player() + 1) players = field.player() + 1; + field.set_player(field.player() + player_offset); } } } @@ -2534,8 +2534,8 @@ time_t ioport_manager::initialize() } // allocate live structures to mirror the configuration - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - port->init_live_state(); + for (ioport_port &port : m_portlist) + port.init_live_state(); // handle autoselection of devices init_autoselect_devices(IPT_AD_STICK_X, IPT_AD_STICK_Y, IPT_AD_STICK_Z, OPTION_ADSTICK_DEVICE, "analog joystick"); @@ -2550,9 +2550,9 @@ time_t ioport_manager::initialize() // look for 4-way diagonal joysticks and change the default map if we find any const char *joystick_map_default = machine().options().joystick_map(); if (joystick_map_default[0] == 0 || strcmp(joystick_map_default, "auto") == 0) - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->live().joystick != nullptr && field->rotated()) + for (ioport_port &port : m_portlist) + for (ioport_field &field : port.fields()) + if (field.live().joystick != nullptr && field.rotated()) { machine().input().set_global_joystick_map(joystick_map_4way_diagonal); break; @@ -2570,14 +2570,14 @@ time_t ioport_manager::initialize() m_has_bioses = false; // scan the input port array to see what options we need to enable - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + for (ioport_port &port : m_portlist) + for (ioport_field &field : port.fields()) { - if (field->type() == IPT_DIPSWITCH) + if (field.type() == IPT_DIPSWITCH) m_has_dips = true; - if (field->type() == IPT_CONFIG) + if (field.type() == IPT_CONFIG) m_has_configs = true; - if (field->is_analog()) + if (field.is_analog()) m_has_analog = true; } device_iterator deviter(machine().root_device()); @@ -2609,13 +2609,13 @@ void ioport_manager::init_port_types() machine().osd().customize_input_type_list(m_typelist); // now iterate over the OSD-modified types - for (input_type_entry *curtype = first_type(); curtype != nullptr; curtype = curtype->next()) + for (input_type_entry &curtype : m_typelist) { // first copy all the OSD-updated sequences into our current state - curtype->restore_default_seq(); + curtype.restore_default_seq(); // also make a lookup table mapping type/player to the appropriate type list entry - m_type_to_entry[curtype->type()][curtype->player()] = curtype; + m_type_to_entry[curtype.type()][curtype.player()] = &curtype; } } @@ -2660,12 +2660,12 @@ void ioport_manager::init_autoselect_devices(int type1, int type2, int type3, co osd_printf_error("Invalid %s value %s; reverting to keyboard\n", option, stemp); // only scan the list if we haven't already enabled this class of control - if (first_port() != nullptr && !machine().input().device_class(autoenable).enabled()) - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + if (!m_portlist.empty() && !machine().input().device_class(autoenable).enabled()) + for (ioport_port &port : m_portlist) + for (ioport_field &field : port.fields()) // if this port type is in use, apply the autoselect criteria - if ((type1 != 0 && field->type() == type1) || (type2 != 0 && field->type() == type2) || (type3 != 0 && field->type() == type3)) + if ((type1 != 0 && field.type() == type1) || (type2 != 0 && field.type() == type2) || (type3 != 0 && field.type() == type3)) { osd_printf_verbose("Input: Autoenabling %s due to presence of a %s\n", autostring, ananame); machine().input().device_class(autoenable).enable(); @@ -2772,9 +2772,9 @@ bool ioport_manager::type_pressed(ioport_type type, int player) bool ioport_manager::type_class_present(ioport_type_class inputclass) { - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->type_class() == inputclass) + for (ioport_port &port : m_portlist) + for (ioport_field &field : port.fields()) + if (field.type_class() == inputclass) return true; return false; } @@ -2788,15 +2788,15 @@ bool ioport_manager::type_class_present(ioport_type_class inputclass) bool ioport_manager::has_keyboard() const { // iterate over ports and fields - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + for (ioport_port &port : m_portlist) + for (ioport_field &field : port.fields()) { // if we are at init, check IPT_KEYBOARD - if (!m_safe_to_read && field->type() == IPT_KEYBOARD) + if (!m_safe_to_read && field.type() == IPT_KEYBOARD) return true; // else, check if there is a keyboard and if such a keyboard is enabled - if (field->type() == IPT_KEYBOARD && field->enabled()) + if (field.type() == IPT_KEYBOARD && field.enabled()) return true; } @@ -2811,10 +2811,10 @@ bool ioport_manager::has_keyboard() const int ioport_manager::count_players() const { int max_player = 0; - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->type_class() == INPUT_CLASS_CONTROLLER && max_player <= field->player() + 1) - max_player = field->player() + 1; + for (ioport_port &port : m_portlist) + for (ioport_field &field : port.fields()) + if (field.type_class() == INPUT_CLASS_CONTROLLER && max_player <= field.player() + 1) + max_player = field.player() + 1; return max_player; } @@ -2829,11 +2829,11 @@ bool ioport_manager::crosshair_position(int player, float &x, float &y) { // read all the lightgun values bool gotx = false, goty = false; - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->player() == player && field->crosshair_axis() != CROSSHAIR_AXIS_NONE && field->enabled()) + for (ioport_port &port : m_portlist) + for (ioport_field &field : port.fields()) + if (field.player() == player && field.crosshair_axis() != CROSSHAIR_AXIS_NONE && field.enabled()) { - field->crosshair_position(x, y, gotx, goty); + field.crosshair_position(x, y, gotx, goty); // if we got both, stop if (gotx && goty) @@ -2855,16 +2855,16 @@ void ioport_manager::update_defaults() for (int loopnum = 0; loopnum < 2; loopnum++) { // loop over all input ports - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) + for (ioport_port &port : m_portlist) { // only clear on the first pass if (loopnum == 0) - port->live().defvalue = 0; + port.live().defvalue = 0; // first compute the default value for the entire port - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->enabled()) - port->live().defvalue = (port->live().defvalue & ~field->mask()) | (field->live().value & field->mask()); + for (ioport_field &field : port.fields()) + if (field.enabled()) + port.live().defvalue = (port.live().defvalue & ~field.mask()) | (field.live().value & field.mask()); } } } @@ -2878,9 +2878,9 @@ void ioport_manager::update_defaults() digital_joystick &ioport_manager::digjoystick(int player, int number) { // find it in the list - for (digital_joystick *joystick = m_joystick_list.first(); joystick != nullptr; joystick = joystick->next()) - if (joystick->player() == player && joystick->number() == number) - return *joystick; + for (digital_joystick &joystick : m_joystick_list) + if (joystick.player() == player && joystick.number() == number) + return joystick; // create a new one return m_joystick_list.append(*global_alloc(digital_joystick(player, number))); @@ -2918,8 +2918,8 @@ g_profiler.start(PROFILER_INPUT); m_last_frame_time = curtime; // update the digital joysticks - for (digital_joystick *joystick = m_joystick_list.first(); joystick != nullptr; joystick = joystick->next()) - joystick->frame_update(); + for (digital_joystick &joystick : m_joystick_list) + joystick.frame_update(); // compute default values for all the ports update_defaults(); @@ -2944,19 +2944,19 @@ g_profiler.start(PROFILER_INPUT); } // loop over all input ports - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) + for (ioport_port &port : m_portlist) { - port->frame_update(mouse_field); + port.frame_update(mouse_field); // handle playback/record - playback_port(*port); - record_port(*port); + playback_port(port); + record_port(port); // call device line write handlers - ioport_value newvalue = port->read(); - for (dynamic_field *dynfield = port->live().writelist.first(); dynfield != nullptr; dynfield = dynfield->next()) - if (dynfield->field().type() != IPT_OUTPUT) - dynfield->write(newvalue); + ioport_value newvalue = port.read(); + for (dynamic_field &dynfield : port.live().writelist) + if (dynfield.field().type() != IPT_OUTPUT) + dynfield.write(newvalue); } g_profiler.stop(); @@ -3038,9 +3038,9 @@ void ioport_manager::load_config(config_type cfg_type, xml_data_node *parentnode // after applying the controller config, push that back into the backup, since that is // what we will diff against if (cfg_type == config_type::CONFIG_TYPE_CONTROLLER) - for (input_type_entry *entry = m_typelist.first(); entry != nullptr; entry = entry->next()) + for (input_type_entry &entry : m_typelist) for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) - entry->defseq(seqtype) = entry->seq(seqtype); + entry.defseq(seqtype) = entry.seq(seqtype); } @@ -3079,9 +3079,9 @@ void ioport_manager::load_remap_table(xml_data_node *parentnode) // loop over the remapping table, then over default ports, replacing old with new for (int remapnum = 0; remapnum < count; remapnum++) - for (input_type_entry *entry = m_typelist.first(); entry != nullptr; entry = entry->next()) + for (input_type_entry &entry : m_typelist) for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) - entry->m_seq[seqtype].replace(oldtable[remapnum], newtable[remapnum]); + entry.m_seq[seqtype].replace(oldtable[remapnum], newtable[remapnum]); } } @@ -3094,12 +3094,12 @@ void ioport_manager::load_remap_table(xml_data_node *parentnode) bool ioport_manager::load_default_config(xml_data_node *portnode, int type, int player, const input_seq *newseq) { // find a matching port in the list - for (input_type_entry *entry = m_typelist.first(); entry != nullptr; entry = entry->next()) - if (entry->type() == type && entry->player() == player) + for (input_type_entry &entry : m_typelist) + if (entry.type() == type && entry.player() == player) { for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) if (newseq[seqtype][0] != INPUT_CODE_INVALID) - entry->m_seq[seqtype] = newseq[seqtype]; + entry.m_seq[seqtype] = newseq[seqtype]; return true; } @@ -3120,44 +3120,44 @@ bool ioport_manager::load_game_config(xml_data_node *portnode, int type, int pla ioport_value defvalue = xml_get_attribute_int(portnode, "defvalue", 0); // find the port we want; if no tag, search them all - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - if (tag == nullptr || strcmp(port->tag(), tag) == 0) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + for (ioport_port &port : m_portlist) + if (tag == nullptr || strcmp(port.tag(), tag) == 0) + for (ioport_field &field : port.fields()) // find the matching mask and defvalue - if (field->type() == type && field->player() == player && - field->mask() == mask && (field->defvalue() & mask) == (defvalue & mask)) + if (field.type() == type && field.player() == player && + field.mask() == mask && (field.defvalue() & mask) == (defvalue & mask)) { // if a sequence was specified, copy it in for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) if (newseq[seqtype][0] != INPUT_CODE_INVALID) - field->live().seq[seqtype] = newseq[seqtype]; + field.live().seq[seqtype] = newseq[seqtype]; // fetch configurable attributes // for non-analog fields - if (field->live().analog == nullptr) + if (field.live().analog == nullptr) { // fetch the value - field->live().value = xml_get_attribute_int(portnode, "value", field->defvalue()); + field.live().value = xml_get_attribute_int(portnode, "value", field.defvalue()); // fetch yes/no for toggle setting const char *togstring = xml_get_attribute_string(portnode, "toggle", nullptr); if (togstring != nullptr) - field->live().toggle = (strcmp(togstring, "yes") == 0); + field.live().toggle = (strcmp(togstring, "yes") == 0); } // for analog fields else { // get base attributes - field->live().analog->m_delta = xml_get_attribute_int(portnode, "keydelta", field->delta()); - field->live().analog->m_centerdelta = xml_get_attribute_int(portnode, "centerdelta", field->centerdelta()); - field->live().analog->m_sensitivity = xml_get_attribute_int(portnode, "sensitivity", field->sensitivity()); + field.live().analog->m_delta = xml_get_attribute_int(portnode, "keydelta", field.delta()); + field.live().analog->m_centerdelta = xml_get_attribute_int(portnode, "centerdelta", field.centerdelta()); + field.live().analog->m_sensitivity = xml_get_attribute_int(portnode, "sensitivity", field.sensitivity()); // fetch yes/no for reverse setting const char *revstring = xml_get_attribute_string(portnode, "reverse", nullptr); if (revstring != nullptr) - field->live().analog->m_reverse = (strcmp(revstring, "yes") == 0); + field.live().analog->m_reverse = (strcmp(revstring, "yes") == 0); } return true; } @@ -3241,15 +3241,15 @@ bool ioport_manager::save_this_input_field_type(ioport_type type) void ioport_manager::save_default_inputs(xml_data_node *parentnode) { // iterate over ports - for (input_type_entry *entry = m_typelist.first(); entry != nullptr; entry = entry->next()) + for (input_type_entry &entry : m_typelist) { // only save if this port is a type we save - if (save_this_input_field_type(entry->type())) + if (save_this_input_field_type(entry.type())) { // see if any of the sequences have changed input_seq_type seqtype; for (seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) - if (entry->seq(seqtype) != entry->defseq(seqtype)) + if (entry.seq(seqtype) != entry.defseq(seqtype)) break; // if so, we need to add a node @@ -3260,12 +3260,12 @@ void ioport_manager::save_default_inputs(xml_data_node *parentnode) if (portnode != nullptr) { // add the port information and attributes - xml_set_attribute(portnode, "type", input_type_to_token(entry->type(), entry->player()).c_str()); + xml_set_attribute(portnode, "type", input_type_to_token(entry.type(), entry.player()).c_str()); // add only the sequences that have changed from the defaults for (input_seq_type type = SEQ_TYPE_STANDARD; type < SEQ_TYPE_TOTAL; ++type) - if (entry->seq(type) != entry->defseq(type)) - save_sequence(portnode, type, entry->type(), entry->seq(type)); + if (entry.seq(type) != entry.defseq(type)) + save_sequence(portnode, type, entry.type(), entry.seq(type)); } } } @@ -3281,29 +3281,29 @@ void ioport_manager::save_default_inputs(xml_data_node *parentnode) void ioport_manager::save_game_inputs(xml_data_node *parentnode) { // iterate over ports - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (save_this_input_field_type(field->type())) + for (ioport_port &port : m_portlist) + for (ioport_field &field : port.fields()) + if (save_this_input_field_type(field.type())) { // determine if we changed bool changed = false; for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) - changed |= (field->seq(seqtype) != field->defseq(seqtype)); + changed |= (field.seq(seqtype) != field.defseq(seqtype)); // non-analog changes - if (!field->is_analog()) + if (!field.is_analog()) { - changed |= ((field->live().value & field->mask()) != (field->defvalue() & field->mask())); - changed |= (field->live().toggle != field->toggle()); + changed |= ((field.live().value & field.mask()) != (field.defvalue() & field.mask())); + changed |= (field.live().toggle != field.toggle()); } // analog changes else { - changed |= (field->live().analog->m_delta != field->delta()); - changed |= (field->live().analog->m_centerdelta != field->centerdelta()); - changed |= (field->live().analog->m_sensitivity != field->sensitivity()); - changed |= (field->live().analog->m_reverse != field->analog_reverse()); + changed |= (field.live().analog->m_delta != field.delta()); + changed |= (field.live().analog->m_centerdelta != field.centerdelta()); + changed |= (field.live().analog->m_sensitivity != field.sensitivity()); + changed |= (field.live().analog->m_reverse != field.analog_reverse()); } // if we did change, add a new node @@ -3314,36 +3314,36 @@ void ioport_manager::save_game_inputs(xml_data_node *parentnode) if (portnode != nullptr) { // add the identifying information and attributes - xml_set_attribute(portnode, "tag", port->tag()); - xml_set_attribute(portnode, "type", input_type_to_token(field->type(), field->player()).c_str()); - xml_set_attribute_int(portnode, "mask", field->mask()); - xml_set_attribute_int(portnode, "defvalue", field->defvalue() & field->mask()); + xml_set_attribute(portnode, "tag", port.tag()); + xml_set_attribute(portnode, "type", input_type_to_token(field.type(), field.player()).c_str()); + xml_set_attribute_int(portnode, "mask", field.mask()); + xml_set_attribute_int(portnode, "defvalue", field.defvalue() & field.mask()); // add sequences if changed for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) - if (field->seq(seqtype) != field->defseq(seqtype)) - save_sequence(portnode, seqtype, field->type(), field->seq(seqtype)); + if (field.seq(seqtype) != field.defseq(seqtype)) + save_sequence(portnode, seqtype, field.type(), field.seq(seqtype)); // write out non-analog changes - if (!field->is_analog()) + if (!field.is_analog()) { - if ((field->live().value & field->mask()) != (field->defvalue() & field->mask())) - xml_set_attribute_int(portnode, "value", field->live().value & field->mask()); - if (field->live().toggle != field->toggle()) - xml_set_attribute(portnode, "toggle", field->live().toggle ? "yes" : "no"); + if ((field.live().value & field.mask()) != (field.defvalue() & field.mask())) + xml_set_attribute_int(portnode, "value", field.live().value & field.mask()); + if (field.live().toggle != field.toggle()) + xml_set_attribute(portnode, "toggle", field.live().toggle ? "yes" : "no"); } // write out analog changes else { - if (field->live().analog->m_delta != field->delta()) - xml_set_attribute_int(portnode, "keydelta", field->live().analog->m_delta); - if (field->live().analog->m_centerdelta != field->centerdelta()) - xml_set_attribute_int(portnode, "centerdelta", field->live().analog->m_centerdelta); - if (field->live().analog->m_sensitivity != field->sensitivity()) - xml_set_attribute_int(portnode, "sensitivity", field->live().analog->m_sensitivity); - if (field->live().analog->m_reverse != field->analog_reverse()) - xml_set_attribute(portnode, "reverse", field->live().analog->m_reverse ? "yes" : "no"); + if (field.live().analog->m_delta != field.delta()) + xml_set_attribute_int(portnode, "keydelta", field.live().analog->m_delta); + if (field.live().analog->m_centerdelta != field.centerdelta()) + xml_set_attribute_int(portnode, "centerdelta", field.live().analog->m_centerdelta); + if (field.live().analog->m_sensitivity != field.sensitivity()) + xml_set_attribute_int(portnode, "sensitivity", field.live().analog->m_sensitivity); + if (field.live().analog->m_reverse != field.analog_reverse()) + xml_set_attribute(portnode, "reverse", field.live().analog->m_reverse ? "yes" : "no"); } } } @@ -3508,15 +3508,15 @@ void ioport_manager::playback_port(ioport_port &port) playback_read(port.live().digital); // loop over analog ports and save their data - for (analog_field *analog = port.live().analoglist.first(); analog != nullptr; analog = analog->next()) + for (analog_field &analog : port.live().analoglist) { // read current and previous values - playback_read(analog->m_accum); - playback_read(analog->m_previous); + playback_read(analog.m_accum); + playback_read(analog.m_previous); // read configuration information - playback_read(analog->m_sensitivity); - playback_read(analog->m_reverse); + playback_read(analog.m_sensitivity); + playback_read(analog.m_reverse); } } } @@ -3799,15 +3799,15 @@ void ioport_manager::record_port(ioport_port &port) record_write(port.live().digital); // loop over analog ports and save their data - for (analog_field *analog = port.live().analoglist.first(); analog != nullptr; analog = analog->next()) + for (analog_field &analog : port.live().analoglist) { // store current and previous values - record_write(analog->m_accum); - record_write(analog->m_previous); + record_write(analog.m_accum); + record_write(analog.m_previous); // store configuration information - record_write(analog->m_sensitivity); - record_write(analog->m_reverse); + record_write(analog.m_sensitivity); + record_write(analog.m_reverse); } } } @@ -4570,11 +4570,11 @@ ioport_type ioport_manager::token_to_input_type(const char *string, int &player) return ioport_type(ipnum); // find the token in the list - for (input_type_entry *entry = m_typelist.first(); entry != nullptr; entry = entry->next()) - if (entry->token() != nullptr && !strcmp(entry->token(), string)) + for (input_type_entry &entry : m_typelist) + if (entry.token() != nullptr && !strcmp(entry.token(), string)) { - player = entry->player(); - return entry->type(); + player = entry.player(); + return entry.type(); } // if we fail, return IPT_UNKNOWN diff --git a/src/emu/ioport.h b/src/emu/ioport.h index c7fbd8ddd79..d3eabc1578b 100644 --- a/src/emu/ioport.h +++ b/src/emu/ioport.h @@ -1105,8 +1105,8 @@ public: ioport_manager &manager() const; running_machine &machine() const; int modcount() const { return m_modcount; } - ioport_setting *first_setting() const { return m_settinglist.first(); } - ioport_diplocation *first_diplocation() const { return m_diploclist.first(); } + const auto &settings() const { return m_settinglist; } + const auto &diplocations() const { return m_diploclist; } ioport_value mask() const { return m_mask; } ioport_value defvalue() const { return m_defvalue; } @@ -1291,7 +1291,7 @@ public: ioport_manager &manager() const; device_t &device() const { return m_device; } running_machine &machine() const; - ioport_field *first_field() const { return m_fieldlist.first(); } + const auto &fields() const { return m_fieldlist; } const char *tag() const { return m_tag.c_str(); } int modcount() const { return m_modcount; } ioport_value active() const { return m_active; } @@ -1302,7 +1302,7 @@ public: void write(ioport_value value, ioport_value mask = ~0); // other operations - ioport_field *field(ioport_value mask); + ioport_field *field(ioport_value mask) const; void collapse_fields(std::string &errorbuf); void frame_update(ioport_field *mouse_field); void init_live_state(); @@ -1466,7 +1466,7 @@ public: // getters running_machine &machine() const { return m_machine; } - ioport_port *first_port() const { return m_portlist.first(); } + const ioport_list &ports() const { return m_portlist; } bool safe_to_read() const { return m_safe_to_read; } natural_keyboard &natkeyboard() { return m_natkeyboard; } @@ -1477,7 +1477,7 @@ public: bool has_bioses() const { return m_has_bioses; } // type helpers - input_type_entry *first_type() const { return m_typelist.first(); } + const auto &types() const { return m_typelist; } bool type_pressed(ioport_type type, int player = 0); const char *type_name(ioport_type type, UINT8 player); ioport_group type_group(ioport_type type, int player); diff --git a/src/emu/luaengine.cpp b/src/emu/luaengine.cpp index 18ae0172bf7..62667ee0eef 100644 --- a/src/emu/luaengine.cpp +++ b/src/emu/luaengine.cpp @@ -392,9 +392,9 @@ luabridge::LuaRef lua_engine::l_options_get_entries(const T *o) luabridge::LuaRef entries_table = luabridge::LuaRef::newTable(L); int unadorned_index = 0; - for (typename T::entry *curentry = options->first(); curentry != nullptr; curentry = curentry->next()) + for (typename T::entry &curentry : *options) { - const char *name = curentry->name(); + const char *name = curentry.name(); bool is_unadorned = false; // check if it's unadorned if (name && strlen(name) && !strcmp(name, options->unadorned(unadorned_index))) @@ -402,8 +402,8 @@ luabridge::LuaRef lua_engine::l_options_get_entries(const T *o) unadorned_index++; is_unadorned = true; } - if (!curentry->is_header() && !curentry->is_command() && !curentry->is_internal() && !is_unadorned) - entries_table[name] = curentry; + if (!curentry.is_header() && !curentry.is_command() && !curentry.is_internal() && !is_unadorned) + entries_table[name] = &curentry; } return entries_table; @@ -458,8 +458,8 @@ luabridge::LuaRef lua_engine::l_cheat_get_entries(const cheat_manager *c) luabridge::LuaRef entry_table = luabridge::LuaRef::newTable(L); int cheatnum = 0; - for (cheat_entry *entry = cm->first(); entry != nullptr; entry = entry->next()) { - entry_table[cheatnum++] = entry; + for (cheat_entry &entry : cm->entries()) { + entry_table[cheatnum++] = &entry; } return entry_table; @@ -496,10 +496,9 @@ luabridge::LuaRef lua_engine::l_ioport_get_ports(const ioport_manager *m) ioport_manager *im = const_cast(m); lua_State *L = luaThis->m_lua_state; luabridge::LuaRef port_table = luabridge::LuaRef::newTable(L); - ioport_port *port; - for (port = im->first_port(); port != nullptr; port = port->next()) { - port_table[port->tag()] = port; + for (ioport_port &port : im->ports()) { + port_table[port.tag()] = &port; } return port_table; @@ -515,10 +514,9 @@ luabridge::LuaRef lua_engine::l_ioports_port_get_fields(const ioport_port *i) ioport_port *p = const_cast(i); lua_State *L = luaThis->m_lua_state; luabridge::LuaRef f_table = luabridge::LuaRef::newTable(L); - ioport_field *field; - for (field = p->first_field(); field != nullptr; field = field->next()) { - f_table[field->name()] = field; + for (ioport_field &field : p->fields()) { + f_table[field.name()] = &field; } return f_table; @@ -535,9 +533,9 @@ luabridge::LuaRef lua_engine::l_render_get_targets(const render_manager *r) luabridge::LuaRef target_table = luabridge::LuaRef::newTable(L); int tc = 0; - for (render_target *curr_rt = r->first_target(); curr_rt != nullptr; curr_rt = curr_rt->next()) + for (render_target &curr_rt : r->targets()) { - target_table[tc++] = curr_rt; + target_table[tc++] = &curr_rt; } return target_table; @@ -547,10 +545,10 @@ luabridge::LuaRef lua_engine::l_render_get_targets(const render_manager *r) luabridge::LuaRef lua_engine::devtree_dfs(device_t *root, luabridge::LuaRef devs_table) { if (root) { - for (device_t *dev = root->first_subdevice(); dev != nullptr; dev = dev->next()) { - if (dev && dev->configured() && dev->started()) { - devs_table[dev->tag()] = dev; - devtree_dfs(dev, devs_table); + for (device_t &dev : root->subdevices()) { + if (dev.configured() && dev.started()) { + devs_table[dev.tag()] = &dev; + devtree_dfs(&dev, devs_table); } } } @@ -587,11 +585,10 @@ luabridge::LuaRef lua_engine::l_dev_get_states(const device_t *d) device_t *dev = const_cast(d); lua_State *L = luaThis->m_lua_state; luabridge::LuaRef st_table = luabridge::LuaRef::newTable(L); - for (const device_state_entry *s = dev->state().state_first(); s != nullptr; s = s->next()) { + for (device_state_entry &s : dev->state().state_entries()) + { // XXX: refrain from exporting non-visible entries? - if (s) { - st_table[s->symbol()] = const_cast(s); - } + st_table[s.symbol()] = &s; } return st_table; @@ -1385,17 +1382,16 @@ void lua_engine::update_machine() if (m_machine!=nullptr) { // Create the ioport array - ioport_port *port = machine().ioport().first_port(); - while(port) { - ioport_field *field = port->first_field(); - while(field) { - if(field->name()) { - push(m_lua_state, field, tname_ioport); - lua_setfield(m_lua_state, -2, field->name()); + for (ioport_port &port : machine().ioport().ports()) + { + for (ioport_field &field : port.fields()) + { + if (field.name()) + { + push(m_lua_state, &field, tname_ioport); + lua_setfield(m_lua_state, -2, field.name()); } - field = field->next(); } - port = port->next(); } } lua_setglobal(m_lua_state, "ioport"); diff --git a/src/emu/mame.cpp b/src/emu/mame.cpp index 7f22c8abcb7..3c4b35df058 100644 --- a/src/emu/mame.cpp +++ b/src/emu/mame.cpp @@ -192,19 +192,19 @@ void machine_manager::start_luaengine() osd_printf_error("**Error loading plugin.ini**"); } } - for (auto curentry = m_plugins->first(); curentry != nullptr; curentry = curentry->next()) + for (auto &curentry : *m_plugins) { - if (!curentry->is_header()) + if (!curentry.is_header()) { - if (std::find(include.begin(), include.end(), curentry->name()) != include.end()) + if (std::find(include.begin(), include.end(), curentry.name()) != include.end()) { std::string error_string; - m_plugins->set_value(curentry->name(), "1", OPTION_PRIORITY_CMDLINE, error_string); + m_plugins->set_value(curentry.name(), "1", OPTION_PRIORITY_CMDLINE, error_string); } - if (std::find(exclude.begin(), exclude.end(), curentry->name()) != exclude.end()) + if (std::find(exclude.begin(), exclude.end(), curentry.name()) != exclude.end()) { std::string error_string; - m_plugins->set_value(curentry->name(), "0", OPTION_PRIORITY_CMDLINE, error_string); + m_plugins->set_value(curentry.name(), "0", OPTION_PRIORITY_CMDLINE, error_string); } } } diff --git a/src/emu/mconfig.cpp b/src/emu/mconfig.cpp index 6c052d7ce23..793da15c1a0 100644 --- a/src/emu/mconfig.cpp +++ b/src/emu/mconfig.cpp @@ -125,31 +125,27 @@ device_t *machine_config::device_add(device_t *owner, const char *tag, device_ty const char *next = strchr(tag, ':'); assert(next != tag); std::string part(tag, next-tag); - device_t *curdevice; - for (curdevice = owner->m_subdevice_list.first(); curdevice != nullptr; curdevice = curdevice->next()) - if (part.compare(curdevice->m_basetag)==0) - break; - if (!curdevice) + owner = owner->subdevices().find(part); + if (owner == nullptr) throw emu_fatalerror("Could not find %s when looking up path for device %s\n", part.c_str(), orig_tag); - owner = curdevice; tag = next+1; } - assert(tag[0]); + assert(tag[0] != '\0'); - // if there's an owner, let the owner do the work if (owner != nullptr) - return owner->add_subdevice(type, tag, clock); + { + // allocate the new device + device_t *device = (*type)(*this, tag, owner, clock); - // otherwise, allocate the device directly + // append it to the owner's list + return &config_new_device(owner->subdevices().m_list.append(*device)); + } + + // allocate the root device directly assert(m_root_device == nullptr); - m_root_device.reset((*type)(*this, tag, owner, clock)); - - // apply any machine configuration owned by the device now - machine_config_constructor additions = m_root_device->machine_config_additions(); - if (additions != nullptr) - (*additions)(*this, m_root_device.get(), nullptr); - return m_root_device.get(); + m_root_device.reset((*type)(*this, tag, nullptr, clock)); + return &config_new_device(*m_root_device); } @@ -160,17 +156,27 @@ device_t *machine_config::device_add(device_t *owner, const char *tag, device_ty device_t *machine_config::device_replace(device_t *owner, const char *tag, device_type type, UINT32 clock) { - // find the original device by this name (must exist) + // find the original device by relative tag (must exist) assert(owner != nullptr); - device_t *device = owner->subdevice(tag); - if (device == nullptr) + device_t *old_device = owner->subdevice(tag); + if (old_device == nullptr) { osd_printf_warning("Warning: attempting to replace non-existent device '%s'\n", tag); return device_add(owner, tag, type, clock); } - // let the device's owner do the work - return device->owner()->replace_subdevice(*device, type, tag, clock); + // make sure we have the old device's actual owner + owner = old_device->owner(); + assert(owner != nullptr); + + // remove references to the old device + remove_references(*old_device); + + // allocate the new device + device_t *new_device = (*type)(*this, tag, owner, clock); + + // substitute it for the old one in the owner's list + return &config_new_device(owner->subdevices().m_list.replace_and_remove(*new_device, *old_device)); } @@ -181,7 +187,7 @@ device_t *machine_config::device_replace(device_t *owner, const char *tag, devic device_t *machine_config::device_remove(device_t *owner, const char *tag) { - // find the original device by this name (must exist) + // find the original device by relative tag (must exist) assert(owner != nullptr); device_t *device = owner->subdevice(tag); if (device == nullptr) @@ -190,8 +196,15 @@ device_t *machine_config::device_remove(device_t *owner, const char *tag) return nullptr; } + // make sure we have the old device's actual owner + owner = device->owner(); + assert(owner != nullptr); + + // remove references to the old device + remove_references(*device); + // let the device's owner do the work - device->owner()->remove_subdevice(*device); + owner->subdevices().m_list.remove(*device); return nullptr; } @@ -203,7 +216,7 @@ device_t *machine_config::device_remove(device_t *owner, const char *tag) device_t *machine_config::device_find(device_t *owner, const char *tag) { - // find the original device by this name (must exist) + // find the original device by relative tag (must exist) assert(owner != nullptr); device_t *device = owner->subdevice(tag); assert(device != nullptr); @@ -213,3 +226,34 @@ device_t *machine_config::device_find(device_t *owner, const char *tag) // return the device return device; } + + +//------------------------------------------------- +// remove_references - globally remove references +// to a device about to be removed from the tree +//------------------------------------------------- + +void machine_config::remove_references(ATTR_UNUSED device_t &device) +{ + // iterate over all devices and remove any references + device_iterator iter(root_device()); + for (device_t *scan = iter.first(); scan != nullptr; scan = iter.next()) + scan->subdevices().m_tagmap.clear(); //remove(&device); +} + + +//------------------------------------------------- +// config_new_device - helper for recursive +// configuration of newly added devices +//------------------------------------------------- + +device_t &machine_config::config_new_device(device_t &device) +{ + // apply any machine configuration owned by the device now + machine_config_constructor additions = device.machine_config_additions(); + if (additions != nullptr) + (*additions)(*this, &device, nullptr); + + // return the new device + return device; +} diff --git a/src/emu/mconfig.h b/src/emu/mconfig.h index dccc77110e8..d29f9e4fcf3 100644 --- a/src/emu/mconfig.h +++ b/src/emu/mconfig.h @@ -75,6 +75,10 @@ public: device_t *device_find(device_t *owner, const char *tag); private: + // internal helpers + void remove_references(ATTR_UNUSED device_t &device); + device_t &config_new_device(device_t &device); + // internal state const game_driver & m_gamedrv; emu_options & m_options; diff --git a/src/emu/memory.cpp b/src/emu/memory.cpp index 59d1f6d69e2..331345ea63d 100644 --- a/src/emu/memory.cpp +++ b/src/emu/memory.cpp @@ -1558,26 +1558,26 @@ void memory_manager::initialize() } // construct and preprocess the address_map for each space - for (address_space *space = m_spacelist.first(); space != nullptr; space = space->next()) - space->prepare_map(); + for (address_space &space : m_spacelist) + space.prepare_map(); // create the handlers from the resulting address maps - for (address_space *space = m_spacelist.first(); space != nullptr; space = space->next()) - space->populate_from_map(); + for (address_space &space : m_spacelist) + space.populate_from_map(); // allocate memory needed to back each address space - for (address_space *space = m_spacelist.first(); space != nullptr; space = space->next()) - space->allocate_memory(); + for (address_space &space : m_spacelist) + space.allocate_memory(); // find all the allocated pointers - for (address_space *space = m_spacelist.first(); space != nullptr; space = space->next()) - space->locate_memory(); + for (address_space &space : m_spacelist) + space.locate_memory(); // disable logging of unmapped access when no one receives it - for (address_space *space = m_spacelist.first(); space != nullptr; space = space->next()) + for (address_space &space : m_spacelist) { if (!machine().options().log() && !machine().options().oslog() && !(machine().debug_flags & DEBUG_FLAG_ENABLED)) - space->set_log_unmap(false); + space.set_log_unmap(false); } // register a callback to reset banks when reloading state @@ -1603,19 +1603,19 @@ void memory_manager::dump(FILE *file) return; // loop over address spaces - for (address_space *space = m_spacelist.first(); space != nullptr; space = space->next()) + for (address_space &space : m_spacelist) { fprintf(file, "\n\n" "====================================================\n" "Device '%s' %s address space read handler dump\n" - "====================================================\n", space->device().tag(), space->name()); - space->dump_map(file, ROW_READ); + "====================================================\n", space.device().tag(), space.name()); + space.dump_map(file, ROW_READ); fprintf(file, "\n\n" "====================================================\n" "Device '%s' %s address space write handler dump\n" - "====================================================\n", space->device().tag(), space->name()); - space->dump_map(file, ROW_WRITE); + "====================================================\n", space.device().tag(), space.name()); + space.dump_map(file, ROW_WRITE); } } @@ -1647,6 +1647,25 @@ void memory_manager::region_free(const char *name) } +//------------------------------------------------- +// region_containing - helper to determine if +// a block of memory is part of a region +//------------------------------------------------- + +memory_region *memory_manager::region_containing(const void *memory, offs_t bytes) const +{ + const UINT8 *data = reinterpret_cast(memory); + + // look through the region list and return the first match + for (memory_region ®ion : m_regionlist) + if (data >= region.base() && (data + bytes) <= region.end()) + return ®ion; + + // didn't find one + return nullptr; +} + + //------------------------------------------------- // generate_memdump - internal memory dump //------------------------------------------------- @@ -1672,9 +1691,9 @@ static void generate_memdump(running_machine &machine) void memory_manager::bank_reattach() { // for each non-anonymous bank, explicitly reset its entry - for (memory_bank *bank = m_banklist.first(); bank != nullptr; bank = bank->next()) - if (!bank->anonymous() && bank->entry() != BANK_ENTRY_UNSPECIFIED) - bank->set_entry(bank->entry()); + for (memory_bank &bank : m_banklist) + if (!bank.anonymous() && bank.entry() != BANK_ENTRY_UNSPECIFIED) + bank.set_entry(bank.entry()); } @@ -1848,63 +1867,63 @@ void address_space::prepare_map() } // make a pass over the address map, adjusting for the device and getting memory pointers - for (address_map_entry *entry = m_map->m_entrylist.first(); entry != nullptr; entry = entry->next()) + for (address_map_entry &entry : m_map->m_entrylist) { // computed adjusted addresses first - entry->m_bytestart = entry->m_addrstart; - entry->m_byteend = entry->m_addrend; - entry->m_bytemirror = entry->m_addrmirror; - entry->m_bytemask = entry->m_addrmask; - adjust_addresses(entry->m_bytestart, entry->m_byteend, entry->m_bytemask, entry->m_bytemirror); + entry.m_bytestart = entry.m_addrstart; + entry.m_byteend = entry.m_addrend; + entry.m_bytemirror = entry.m_addrmirror; + entry.m_bytemask = entry.m_addrmask; + adjust_addresses(entry.m_bytestart, entry.m_byteend, entry.m_bytemask, entry.m_bytemirror); // if we have a share entry, add it to our map - if (entry->m_share != nullptr) + if (entry.m_share != nullptr) { // if we can't find it, add it to our map - std::string fulltag = entry->m_devbase.subtag(entry->m_share); + std::string fulltag = entry.m_devbase.subtag(entry.m_share); if (manager().m_sharelist.find(fulltag.c_str()) == nullptr) { - VPRINTF(("Creating share '%s' of length 0x%X\n", fulltag.c_str(), entry->m_byteend + 1 - entry->m_bytestart)); - auto share = global_alloc(memory_share(m_map->m_databits, entry->m_byteend + 1 - entry->m_bytestart, endianness())); + VPRINTF(("Creating share '%s' of length 0x%X\n", fulltag.c_str(), entry.m_byteend + 1 - entry.m_bytestart)); + auto share = global_alloc(memory_share(m_map->m_databits, entry.m_byteend + 1 - entry.m_bytestart, endianness())); manager().m_sharelist.append(fulltag.c_str(), *share); } } // if this is a ROM handler without a specified region, attach it to the implicit region - if (m_spacenum == AS_0 && entry->m_read.m_type == AMH_ROM && entry->m_region == nullptr) + if (m_spacenum == AS_0 && entry.m_read.m_type == AMH_ROM && entry.m_region == nullptr) { // make sure it fits within the memory region before doing so, however - if (entry->m_byteend < devregionsize) + if (entry.m_byteend < devregionsize) { - entry->m_region = m_device.tag(); - entry->m_rgnoffs = entry->m_bytestart; + entry.m_region = m_device.tag(); + entry.m_rgnoffs = entry.m_bytestart; } } // validate adjusted addresses against implicit regions - if (entry->m_region != nullptr && entry->m_share == nullptr) + if (entry.m_region != nullptr && entry.m_share == nullptr) { // determine full tag - std::string fulltag = entry->m_devbase.subtag(entry->m_region); + std::string fulltag = entry.m_devbase.subtag(entry.m_region); // find the region memory_region *region = machine().root_device().memregion(fulltag.c_str()); if (region == nullptr) - fatalerror("device '%s' %s space memory map entry %X-%X references non-existant region \"%s\"\n", m_device.tag(), m_name, entry->m_addrstart, entry->m_addrend, entry->m_region); + fatalerror("device '%s' %s space memory map entry %X-%X references non-existant region \"%s\"\n", m_device.tag(), m_name, entry.m_addrstart, entry.m_addrend, entry.m_region); // validate the region - if (entry->m_rgnoffs + (entry->m_byteend - entry->m_bytestart + 1) > region->bytes()) - fatalerror("device '%s' %s space memory map entry %X-%X extends beyond region \"%s\" size (%X)\n", m_device.tag(), m_name, entry->m_addrstart, entry->m_addrend, entry->m_region, region->bytes()); + if (entry.m_rgnoffs + (entry.m_byteend - entry.m_bytestart + 1) > region->bytes()) + fatalerror("device '%s' %s space memory map entry %X-%X extends beyond region \"%s\" size (%X)\n", m_device.tag(), m_name, entry.m_addrstart, entry.m_addrend, entry.m_region, region->bytes()); } // convert any region-relative entries to their memory pointers - if (entry->m_region != nullptr) + if (entry.m_region != nullptr) { // determine full tag - std::string fulltag = entry->m_devbase.subtag(entry->m_region); + std::string fulltag = entry.m_devbase.subtag(entry.m_region); // set the memory address - entry->m_memory = machine().root_device().memregion(fulltag.c_str())->base() + entry->m_rgnoffs; + entry.m_memory = machine().root_device().memregion(fulltag.c_str())->base() + entry.m_rgnoffs; } } @@ -2039,9 +2058,9 @@ void address_space::allocate_memory() // make a first pass over the memory map and track blocks with hardcoded pointers // we do this to make sure they are found by space_find_backing_memory first memory_block *prev_memblock_tail = blocklist.last(); - for (address_map_entry *entry = m_map->m_entrylist.first(); entry != nullptr; entry = entry->next()) - if (entry->m_memory != nullptr) - blocklist.append(*global_alloc(memory_block(*this, entry->m_bytestart, entry->m_byteend, entry->m_memory))); + for (address_map_entry &entry : m_map->m_entrylist) + if (entry.m_memory != nullptr) + blocklist.append(*global_alloc(memory_block(*this, entry.m_bytestart, entry.m_byteend, entry.m_memory))); // loop over all blocks just allocated and assign pointers from them address_map_entry *unassigned = nullptr; @@ -2067,12 +2086,12 @@ void address_space::allocate_memory() changed = false; // scan for unmapped blocks in the adjusted map - for (address_map_entry *entry = m_map->m_entrylist.first(); entry != nullptr; entry = entry->next()) - if (entry->m_memory == nullptr && entry != unassigned && needs_backing_store(entry)) + for (address_map_entry &entry : m_map->m_entrylist) + if (entry.m_memory == nullptr && &entry != unassigned && needs_backing_store(entry)) { // get block start/end blocks for this block - offs_t blockstart = entry->m_bytestart / MEMORY_BLOCK_CHUNK; - offs_t blockend = entry->m_byteend / MEMORY_BLOCK_CHUNK; + offs_t blockstart = entry.m_bytestart / MEMORY_BLOCK_CHUNK; + offs_t blockend = entry.m_byteend / MEMORY_BLOCK_CHUNK; // if we intersect or are adjacent, adjust the start/end if (blockstart <= curblockend + 1 && blockend >= curblockstart - 1) @@ -2104,21 +2123,21 @@ void address_space::allocate_memory() void address_space::locate_memory() { // once this is done, find the starting bases for the banks - for (memory_bank *bank = manager().m_banklist.first(); bank != nullptr; bank = bank->next()) - if (bank->base() == nullptr && bank->references_space(*this, ROW_READWRITE)) + for (memory_bank &bank : manager().banks()) + if (bank.base() == nullptr && bank.references_space(*this, ROW_READWRITE)) { // set the initial bank pointer - for (address_map_entry *entry = m_map->m_entrylist.first(); entry != nullptr; entry = entry->next()) - if (entry->m_bytestart == bank->bytestart() && entry->m_memory != nullptr) + for (address_map_entry &entry : m_map->m_entrylist) + if (entry.m_bytestart == bank.bytestart() && entry.m_memory != nullptr) { - bank->set_base(entry->m_memory); - VPRINTF(("assigned bank '%s' pointer to memory from range %08X-%08X [%p]\n", bank->tag(), entry->m_addrstart, entry->m_addrend, entry->m_memory)); + bank.set_base(entry.m_memory); + VPRINTF(("assigned bank '%s' pointer to memory from range %08X-%08X [%p]\n", bank.tag(), entry.m_addrstart, entry.m_addrend, entry.m_memory)); break; } // if the entry was set ahead of time, override the automatically found pointer - if (!bank->anonymous() && bank->entry() != BANK_ENTRY_UNSPECIFIED) - bank->set_entry(bank->entry()); + if (!bank.anonymous() && bank.entry() != BANK_ENTRY_UNSPECIFIED) + bank.set_entry(bank.entry()); } } @@ -2135,46 +2154,46 @@ address_map_entry *address_space::block_assign_intersecting(offs_t bytestart, of address_map_entry *unassigned = nullptr; // loop over the adjusted map and assign memory to any blocks we can - for (address_map_entry *entry = m_map->m_entrylist.first(); entry != nullptr; entry = entry->next()) + for (address_map_entry &entry : m_map->m_entrylist) { // if we haven't assigned this block yet, see if we have a mapped shared pointer for it - if (entry->m_memory == nullptr && entry->m_share != nullptr) + if (entry.m_memory == nullptr && entry.m_share != nullptr) { - std::string fulltag = entry->m_devbase.subtag(entry->m_share); - memory_share *share = manager().m_sharelist.find(fulltag.c_str()); + std::string fulltag = entry.m_devbase.subtag(entry.m_share); + memory_share *share = manager().shares().find(fulltag.c_str()); if (share != nullptr && share->ptr() != nullptr) { - entry->m_memory = share->ptr(); - VPRINTF(("memory range %08X-%08X -> shared_ptr '%s' [%p]\n", entry->m_addrstart, entry->m_addrend, entry->m_share, entry->m_memory)); + entry.m_memory = share->ptr(); + VPRINTF(("memory range %08X-%08X -> shared_ptr '%s' [%p]\n", entry.m_addrstart, entry.m_addrend, entry.m_share, entry.m_memory)); } else { - VPRINTF(("memory range %08X-%08X -> shared_ptr '%s' but not found\n", entry->m_addrstart, entry->m_addrend, entry->m_share)); + VPRINTF(("memory range %08X-%08X -> shared_ptr '%s' but not found\n", entry.m_addrstart, entry.m_addrend, entry.m_share)); } } // otherwise, look for a match in this block - if (entry->m_memory == nullptr && entry->m_bytestart >= bytestart && entry->m_byteend <= byteend) + if (entry.m_memory == nullptr && entry.m_bytestart >= bytestart && entry.m_byteend <= byteend) { - entry->m_memory = base + (entry->m_bytestart - bytestart); - VPRINTF(("memory range %08X-%08X -> found in block from %08X-%08X [%p]\n", entry->m_addrstart, entry->m_addrend, bytestart, byteend, entry->m_memory)); + entry.m_memory = base + (entry.m_bytestart - bytestart); + VPRINTF(("memory range %08X-%08X -> found in block from %08X-%08X [%p]\n", entry.m_addrstart, entry.m_addrend, bytestart, byteend, entry.m_memory)); } // if we're the first match on a shared pointer, assign it now - if (entry->m_memory != nullptr && entry->m_share != nullptr) + if (entry.m_memory != nullptr && entry.m_share != nullptr) { - std::string fulltag = entry->m_devbase.subtag(entry->m_share); - memory_share *share = manager().m_sharelist.find(fulltag.c_str()); + std::string fulltag = entry.m_devbase.subtag(entry.m_share); + memory_share *share = manager().shares().find(fulltag.c_str()); if (share != nullptr && share->ptr() == nullptr) { - share->set_ptr(entry->m_memory); - VPRINTF(("setting shared_ptr '%s' = %p\n", entry->m_share, entry->m_memory)); + share->set_ptr(entry.m_memory); + VPRINTF(("setting shared_ptr '%s' = %p\n", entry.m_share, entry.m_memory)); } } // keep track of the first unassigned entry - if (entry->m_memory == nullptr && unassigned == nullptr && needs_backing_store(entry)) - unassigned = entry; + if (entry.m_memory == nullptr && unassigned == nullptr && needs_backing_store(entry)) + unassigned = &entry; } return unassigned; @@ -2584,23 +2603,23 @@ void *address_space::find_backing_memory(offs_t addrstart, offs_t addrend) return nullptr; // look in the address map first - for (address_map_entry *entry = m_map->m_entrylist.first(); entry != nullptr; entry = entry->next()) + for (address_map_entry &entry : m_map->m_entrylist) { - offs_t maskstart = bytestart & entry->m_bytemask; - offs_t maskend = byteend & entry->m_bytemask; - if (entry->m_memory != nullptr && maskstart >= entry->m_bytestart && maskend <= entry->m_byteend) + offs_t maskstart = bytestart & entry.m_bytemask; + offs_t maskend = byteend & entry.m_bytemask; + if (entry.m_memory != nullptr && maskstart >= entry.m_bytestart && maskend <= entry.m_byteend) { - VPRINTF(("found in entry %08X-%08X [%p]\n", entry->m_addrstart, entry->m_addrend, (UINT8 *)entry->m_memory + (maskstart - entry->m_bytestart))); - return (UINT8 *)entry->m_memory + (maskstart - entry->m_bytestart); + VPRINTF(("found in entry %08X-%08X [%p]\n", entry.m_addrstart, entry.m_addrend, (UINT8 *)entry.m_memory + (maskstart - entry.m_bytestart))); + return (UINT8 *)entry.m_memory + (maskstart - entry.m_bytestart); } } // if not found there, look in the allocated blocks - for (memory_block *block = manager().m_blocklist.first(); block != nullptr; block = block->next()) - if (block->contains(*this, bytestart, byteend)) + for (memory_block &block : manager().m_blocklist) + if (block.contains(*this, bytestart, byteend)) { - VPRINTF(("found in allocated memory block %08X-%08X [%p]\n", block->bytestart(), block->byteend(), block->data() + (bytestart - block->bytestart()))); - return block->data() + bytestart - block->bytestart(); + VPRINTF(("found in allocated memory block %08X-%08X [%p]\n", block.bytestart(), block.byteend(), block.data() + (bytestart - block.bytestart()))); + return block.data() + bytestart - block.bytestart(); } VPRINTF(("did not find\n")); @@ -2614,25 +2633,25 @@ void *address_space::find_backing_memory(offs_t addrstart, offs_t addrend) // allocating and registering memory //------------------------------------------------- -bool address_space::needs_backing_store(const address_map_entry *entry) +bool address_space::needs_backing_store(const address_map_entry &entry) { // if we are sharing, and we don't have a pointer yet, create one - if (entry->m_share != nullptr) + if (entry.m_share != nullptr) { - std::string fulltag = entry->m_devbase.subtag(entry->m_share); - memory_share *share = manager().m_sharelist.find(fulltag.c_str()); + std::string fulltag = entry.m_devbase.subtag(entry.m_share); + memory_share *share = manager().shares().find(fulltag.c_str()); if (share != nullptr && share->ptr() == nullptr) return true; } // if we're writing to any sort of bank or RAM, then yes, we do need backing - if (entry->m_write.m_type == AMH_BANK || entry->m_write.m_type == AMH_RAM) + if (entry.m_write.m_type == AMH_BANK || entry.m_write.m_type == AMH_RAM) return true; // if we're reading from RAM or from ROM outside of address space 0 or its region, then yes, we do need backing memory_region *region = machine().root_device().memregion(m_device.tag()); - if (entry->m_read.m_type == AMH_RAM || - (entry->m_read.m_type == AMH_ROM && (m_spacenum != AS_0 || region == nullptr || entry->m_addrstart >= region->bytes()))) + if (entry.m_read.m_type == AMH_RAM || + (entry.m_read.m_type == AMH_ROM && (m_spacenum != AS_0 || region == nullptr || entry.m_addrstart >= region->bytes()))) return true; // all other cases don't need backing @@ -2660,16 +2679,8 @@ memory_bank &address_space::bank_find_or_allocate(const char *tag, offs_t addrst offs_t byteend = addrend; adjust_addresses(bytestart, byteend, bytemask, bytemirror); - // if this bank is named, look it up - memory_bank *membank = nullptr; - if (tag != nullptr) - membank = manager().bank(tag); - - // else try to find an exact match - else - for (membank = manager().m_banklist.first(); membank != nullptr; membank = membank->next()) - if (membank->anonymous() && membank->references_space(*this, ROW_READWRITE) && membank->matches_exactly(bytestart, byteend)) - break; + // look up the bank by name, or else by byte range + memory_bank *membank = (tag != nullptr) ? manager().banks().find(tag) : bank_find_anonymous(bytestart, byteend); // if we don't have a bank yet, find a free one if (membank == nullptr) @@ -2700,6 +2711,21 @@ memory_bank &address_space::bank_find_or_allocate(const char *tag, offs_t addrst } +//------------------------------------------------- +// bank_find_anonymous - try to find an anonymous +// bank matching the given byte range +//------------------------------------------------- +memory_bank *address_space::bank_find_anonymous(offs_t bytestart, offs_t byteend) const +{ + // try to find an exact match + for (memory_bank &bank : manager().banks()) + if (bank.anonymous() && bank.references_space(*this, ROW_READWRITE) && bank.matches_exactly(bytestart, byteend)) + return &bank; + + // not found + return nullptr; +} + //************************************************************************** // TABLE MANAGEMENT @@ -3502,9 +3528,9 @@ const char *address_table::handler_name(UINT16 entry) const { // banks have names if (entry >= STATIC_BANK1 && entry <= STATIC_BANKMAX) - for (memory_bank *info = m_space.manager().first_bank(); info != nullptr; info = info->next()) - if (info->index() == entry) - return info->name(); + for (memory_bank &info : m_space.manager().banks()) + if (info.index() == entry) + return info.name(); // constant strings for static entries if (entry == STATIC_INVALID) return "invalid"; @@ -3753,9 +3779,9 @@ direct_read_data::direct_range *direct_read_data::find_range(offs_t byteaddress, entry = m_space.read().lookup_live_nowp(byteaddress); // scan our table - for (direct_range *range = m_rangelist[entry].first(); range != nullptr; range = range->next()) - if (byteaddress >= range->m_bytestart && byteaddress <= range->m_byteend) - return range; + for (direct_range &range : m_rangelist[entry]) + if (byteaddress >= range.m_bytestart && byteaddress <= range.m_byteend) + return ⦥ // didn't find out; allocate a new one direct_range *range = m_freerangelist.first(); @@ -3844,12 +3870,12 @@ memory_block::memory_block(address_space &space, offs_t bytestart, offs_t byteen m_byteend(byteend), m_data(reinterpret_cast(memory)) { + offs_t length = byteend + 1 - bytestart; VPRINTF(("block_allocate('%s',%s,%08X,%08X,%p)\n", space.device().tag(), space.name(), bytestart, byteend, memory)); // allocate a block if needed if (m_data == nullptr) { - offs_t length = byteend + 1 - bytestart; if (length < 4096) { m_allocated.resize(length); @@ -3865,20 +3891,13 @@ memory_block::memory_block(address_space &space, offs_t bytestart, offs_t byteen } // register for saving, but only if we're not part of a memory region - memory_region *region; - for (region = space.machine().memory().first_region(); region != nullptr; region = region->next()) - if (m_data >= region->base() && (m_data + (byteend - bytestart + 1)) < region->end()) - { - VPRINTF(("skipping save of this memory block as it is covered by a memory region\n")); - break; - } - - // if we didn't find a match, register - if (region == nullptr) + if (space.manager().region_containing(m_data, length) != nullptr) + VPRINTF(("skipping save of this memory block as it is covered by a memory region\n")); + else { int bytes_per_element = space.data_width() / 8; std::string name = string_format("%08x-%08x", bytestart, byteend); - space.machine().save().save_memory(nullptr, "memory", space.device().tag(), space.spacenum(), name.c_str(), m_data, bytes_per_element, (UINT32)(byteend + 1 - bytestart) / bytes_per_element); + space.machine().save().save_memory(nullptr, "memory", space.device().tag(), space.spacenum(), name.c_str(), m_data, bytes_per_element, (UINT32)length / bytes_per_element); } } @@ -3943,10 +3962,10 @@ memory_bank::~memory_bank() // and read/write //------------------------------------------------- -bool memory_bank::references_space(address_space &space, read_or_write readorwrite) const +bool memory_bank::references_space(const address_space &space, read_or_write readorwrite) const { - for (bank_reference *ref = m_reflist.first(); ref != nullptr; ref = ref->next()) - if (ref->matches(space, readorwrite)) + for (bank_reference &ref : m_reflist) + if (ref.matches(space, readorwrite)) return true; return false; } @@ -3974,8 +3993,8 @@ void memory_bank::add_reference(address_space &space, read_or_write readorwrite) void memory_bank::invalidate_references() { // invalidate all the direct references to any referenced address spaces - for (bank_reference *ref = m_reflist.first(); ref != nullptr; ref = ref->next()) - ref->space().direct().force_update(); + for (bank_reference &ref : m_reflist) + ref.space().direct().force_update(); } diff --git a/src/emu/memory.h b/src/emu/memory.h index 0b2b493a27d..9097b237e70 100644 --- a/src/emu/memory.h +++ b/src/emu/memory.h @@ -457,8 +457,9 @@ private: void install_bank_generic(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, memory_bank *rbank, memory_bank *wbank); void adjust_addresses(offs_t &start, offs_t &end, offs_t &mask, offs_t &mirror); void *find_backing_memory(offs_t addrstart, offs_t addrend); - bool needs_backing_store(const address_map_entry *entry); + bool needs_backing_store(const address_map_entry &entry); memory_bank &bank_find_or_allocate(const char *tag, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read_or_write readorwrite); + memory_bank *bank_find_anonymous(offs_t bytestart, offs_t byteend) const; address_map_entry *block_assign_intersecting(offs_t bytestart, offs_t byteend, UINT8 *base); protected: @@ -551,7 +552,7 @@ class memory_bank address_space &space() const { return m_space; } // does this reference match the space+read/write combination? - bool matches(address_space &space, read_or_write readorwrite) const + bool matches(const address_space &space, read_or_write readorwrite) const { return (&space == &m_space && (readorwrite == ROW_READWRITE || readorwrite == m_readorwrite)); } @@ -592,7 +593,7 @@ public: bool straddles(offs_t bytestart, offs_t byteend) const { return (m_bytestart < byteend && m_byteend > bytestart); } // track and verify address space references to this bank - bool references_space(address_space &space, read_or_write readorwrite) const; + bool references_space(const address_space &space, read_or_write readorwrite) const; void add_reference(address_space &space, read_or_write readorwrite); // set the base explicitly @@ -718,9 +719,6 @@ private: class memory_manager { friend class address_space; - friend class address_table; - friend class device_t; - friend class memory_block; public: // construction/destruction @@ -729,8 +727,9 @@ public: // getters running_machine &machine() const { return m_machine; } - address_space *first_space() const { return m_spacelist.first(); } - memory_region *first_region() const { return m_regionlist.first(); } + const auto &banks() const { return m_banklist; } + const auto ®ions() const { return m_regionlist; } + const auto &shares() const { return m_sharelist; } // dump the internal memory tables to the given file void dump(FILE *file); @@ -741,13 +740,10 @@ public: // regions memory_region *region_alloc(const char *name, UINT32 length, UINT8 width, endianness_t endian); void region_free(const char *name); + memory_region *region_containing(const void *memory, offs_t bytes) const; private: // internal helpers - memory_bank *first_bank() const { return m_banklist.first(); } - memory_bank *bank(const char *tag) const { return m_banklist.find(tag); } - memory_region *region(const char *tag) { return m_regionlist.find(tag); } - memory_share *shared(const char *tag) { return m_sharelist.find(tag); } void bank_reattach(); // internal state diff --git a/src/emu/render.cpp b/src/emu/render.cpp index 89fadf5e319..06eb8f6b93a 100644 --- a/src/emu/render.cpp +++ b/src/emu/render.cpp @@ -182,7 +182,7 @@ inline item_layer get_layer_and_blendmode(const layout_view &view, int index, in // screens (add) + overlays (RGB multiply) + backdrop (add) + bezels (alpha) + cpanels (alpha) + marquees (alpha) const int *layer_order = layer_order_standard; - if (view.first_item(ITEM_LAYER_BACKDROP) != nullptr && view.first_item(ITEM_LAYER_BACKDROP)->next() != nullptr && view.first_item(ITEM_LAYER_OVERLAY) == nullptr) + if (view.items(ITEM_LAYER_BACKDROP).count() > 1 && view.items(ITEM_LAYER_OVERLAY).empty()) layer_order = layer_order_alternate; // select the layer @@ -266,8 +266,8 @@ inline void render_primitive_list::add_reference(void *refptr) inline bool render_primitive_list::has_reference(void *refptr) const { // skip if we already have one - for (reference *ref = m_reflist.first(); ref != nullptr; ref = ref->next()) - if (ref->m_refptr == refptr) + for (reference &ref : m_reflist) + if (ref.m_refptr == refptr) return true; return false; } @@ -1260,16 +1260,16 @@ void render_target::compute_minimum_size(INT32 &minwidth, INT32 &minheight) for (item_layer layer = ITEM_LAYER_FIRST; layer < ITEM_LAYER_MAX; ++layer) // iterate over items in the layer - for (layout_view::item *curitem = m_curview->first_item(layer); curitem != nullptr; curitem = curitem->next()) - if (curitem->screen() != nullptr) + for (layout_view::item &curitem : m_curview->items(layer)) + if (curitem.screen() != nullptr) { // use a hard-coded default visible area for vector screens - screen_device *screen = curitem->screen(); + screen_device *screen = curitem.screen(); const rectangle vectorvis(0, 639, 0, 479); const rectangle &visarea = (screen->screen_type() == SCREEN_TYPE_VECTOR) ? vectorvis : screen->visible_area(); // apply target orientation to the bounds - render_bounds bounds = curitem->bounds(); + render_bounds bounds = curitem.bounds(); apply_orientation(bounds, m_orientation); normalize_bounds(bounds); @@ -1347,10 +1347,10 @@ render_primitive_list &render_target::get_primitives() if (m_curview->layer_enabled(layer)) { // iterate over items in the layer - for (layout_view::item *curitem = m_curview->first_item(layer); curitem != nullptr; curitem = curitem->next()) + for (layout_view::item &curitem : m_curview->items(layer)) { // first apply orientation to the bounds - render_bounds bounds = curitem->bounds(); + render_bounds bounds = curitem.bounds(); apply_orientation(bounds, root_xform.orientation); normalize_bounds(bounds); @@ -1360,18 +1360,18 @@ render_primitive_list &render_target::get_primitives() item_xform.yoffs = root_xform.yoffs + bounds.y0 * root_xform.yscale; item_xform.xscale = (bounds.x1 - bounds.x0) * root_xform.xscale; item_xform.yscale = (bounds.y1 - bounds.y0) * root_xform.yscale; - item_xform.color.r = curitem->color().r * root_xform.color.r; - item_xform.color.g = curitem->color().g * root_xform.color.g; - item_xform.color.b = curitem->color().b * root_xform.color.b; - item_xform.color.a = curitem->color().a * root_xform.color.a; - item_xform.orientation = orientation_add(curitem->orientation(), root_xform.orientation); + item_xform.color.r = curitem.color().r * root_xform.color.r; + item_xform.color.g = curitem.color().g * root_xform.color.g; + item_xform.color.b = curitem.color().b * root_xform.color.b; + item_xform.color.a = curitem.color().a * root_xform.color.a; + item_xform.orientation = orientation_add(curitem.orientation(), root_xform.orientation); item_xform.no_center = false; // if there is no associated element, it must be a screen element - if (curitem->screen() != nullptr) - add_container_primitives(list, item_xform, curitem->screen()->container(), blendmode); + if (curitem.screen() != nullptr) + add_container_primitives(list, item_xform, curitem.screen()->container(), blendmode); else - add_element_primitives(list, item_xform, *curitem->element(), curitem->state(), blendmode); + add_element_primitives(list, item_xform, *curitem.element(), curitem.state(), blendmode); } } } @@ -1398,7 +1398,7 @@ render_primitive_list &render_target::get_primitives() } // process the debug containers - for (render_container *debug = m_debug_containers.first(); debug != nullptr; debug = debug->next()) + for (render_container &debug : m_debug_containers) { object_transform ui_xform; ui_xform.xoffs = 0; @@ -1411,7 +1411,7 @@ render_primitive_list &render_target::get_primitives() ui_xform.no_center = true; // add UI elements - add_container_primitives(list, ui_xform, *debug, BLENDMODE_ALPHA); + add_container_primitives(list, ui_xform, debug, BLENDMODE_ALPHA); } // process the UI if we are the UI target @@ -1522,11 +1522,11 @@ void render_target::debug_append(render_container &container) void render_target::resolve_tags() { - for (layout_file *file = m_filelist.first(); file != nullptr; file = file->next()) + for (layout_file &file : m_filelist) { - for (layout_view *view = file->first_view(); view != nullptr; view = view->next()) + for (layout_view &view : file.views()) { - view->resolve_tags(); + view.resolve_tags(); } } } @@ -1733,10 +1733,10 @@ void render_target::add_container_primitives(render_primitive_list &list, const } // iterate over elements - for (render_container::item *curitem = container.first_item(); curitem != nullptr; curitem = curitem->next()) + for (render_container::item &curitem : container.items()) { // compute the oriented bounds - render_bounds bounds = curitem->bounds(); + render_bounds bounds = curitem.bounds(); apply_orientation(bounds, container_xform.orientation); // allocate the primitive and set the transformed bounds/color data @@ -1746,7 +1746,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const prim->bounds.x0 = render_round_nearest(container_xform.xoffs + bounds.x0 * container_xform.xscale); prim->bounds.y0 = render_round_nearest(container_xform.yoffs + bounds.y0 * container_xform.yscale); - if (curitem->internal() & INTERNAL_FLAG_CHAR) + if (curitem.internal() & INTERNAL_FLAG_CHAR) { prim->bounds.x1 = prim->bounds.x0 + render_round_nearest((bounds.x1 - bounds.x0) * container_xform.xscale); prim->bounds.y1 = prim->bounds.y0 + render_round_nearest((bounds.y1 - bounds.y0) * container_xform.yscale); @@ -1758,14 +1758,14 @@ void render_target::add_container_primitives(render_primitive_list &list, const } // compute the color of the primitive - prim->color.r = container_xform.color.r * curitem->color().r; - prim->color.g = container_xform.color.g * curitem->color().g; - prim->color.b = container_xform.color.b * curitem->color().b; - prim->color.a = container_xform.color.a * curitem->color().a; + prim->color.r = container_xform.color.r * curitem.color().r; + prim->color.g = container_xform.color.g * curitem.color().g; + prim->color.b = container_xform.color.b * curitem.color().b; + prim->color.a = container_xform.color.a * curitem.color().a; // now switch off the type bool clipped = true; - switch (curitem->type()) + switch (curitem.type()) { case CONTAINER_ITEM_LINE: // adjust the color for brightness/contrast/gamma @@ -1779,8 +1779,8 @@ void render_target::add_container_primitives(render_primitive_list &list, const prim->flags |= PRIMFLAG_TYPE_LINE; // scale the width by the minimum of X/Y scale factors - prim->width = curitem->width() * MIN(container_xform.xscale, container_xform.yscale); - prim->flags |= curitem->flags(); + prim->width = curitem.width() * MIN(container_xform.xscale, container_xform.yscale); + prim->flags |= curitem.flags(); // clip the primitive clipped = render_clip_line(&prim->bounds, &cliprect); @@ -1795,10 +1795,10 @@ void render_target::add_container_primitives(render_primitive_list &list, const normalize_bounds(prim->bounds); // get the scaled bitmap and set the resulting palette - if (curitem->texture() != nullptr) + if (curitem.texture() != nullptr) { // determine the final orientation - int finalorient = orientation_add(PRIMFLAG_GET_TEXORIENT(curitem->flags()), container_xform.orientation); + int finalorient = orientation_add(PRIMFLAG_GET_TEXORIENT(curitem.flags()), container_xform.orientation); // based on the swap values, get the scaled final texture int width = (finalorient & ORIENTATION_SWAP_XY) ? (prim->bounds.y1 - prim->bounds.y0) : (prim->bounds.x1 - prim->bounds.x0); @@ -1806,10 +1806,10 @@ void render_target::add_container_primitives(render_primitive_list &list, const width = MIN(width, m_maxtexwidth); height = MIN(height, m_maxtexheight); - curitem->texture()->get_scaled(width, height, prim->texture, list, curitem->flags()); + curitem.texture()->get_scaled(width, height, prim->texture, list, curitem.flags()); // set the palette - prim->texture.palette = curitem->texture()->get_adjusted_palette(container); + prim->texture.palette = curitem.texture()->get_adjusted_palette(container); // determine UV coordinates prim->texcoords = oriented_texcoords[finalorient]; @@ -1818,16 +1818,16 @@ void render_target::add_container_primitives(render_primitive_list &list, const clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords); // apply the final orientation from the quad flags and then build up the final flags - prim->flags = (curitem->flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) + prim->flags = (curitem.flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) | PRIMFLAG_TEXORIENT(finalorient) - | PRIMFLAG_TEXFORMAT(curitem->texture()->format()); + | PRIMFLAG_TEXFORMAT(curitem.texture()->format()); prim->flags |= blendmode != -1 ? PRIMFLAG_BLENDMODE(blendmode) - : PRIMFLAG_BLENDMODE(PRIMFLAG_GET_BLENDMODE(curitem->flags())); + : PRIMFLAG_BLENDMODE(PRIMFLAG_GET_BLENDMODE(curitem.flags())); } else { - if (curitem->flags() & PRIMFLAG_VECTORBUF_MASK) + if (curitem.flags() & PRIMFLAG_VECTORBUF_MASK) { // determine UV coordinates prim->texcoords = oriented_texcoords[0]; @@ -1842,7 +1842,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const prim->texture.base = nullptr; // set the basic flags - prim->flags = (curitem->flags() & ~PRIMFLAG_BLENDMODE_MASK) + prim->flags = (curitem.flags() & ~PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); // apply clipping @@ -1991,25 +1991,25 @@ bool render_target::map_point_internal(INT32 target_x, INT32 target_y, render_co if (m_curview->layer_enabled(layer)) { // iterate over items in the layer - for (layout_view::item *item = m_curview->first_item(layer); item != nullptr; item = item->next()) + for (layout_view::item &item : m_curview->items(layer)) { bool checkit; // if we're looking for a particular container, verify that we have the right one if (container != nullptr) - checkit = (item->screen() != nullptr && &item->screen()->container() == container); + checkit = (item.screen() != nullptr && &item.screen()->container() == container); // otherwise, assume we're looking for an input else - checkit = item->has_input(); + checkit = item.has_input(); // this target is worth looking at; now check the point - if (checkit && target_fx >= item->bounds().x0 && target_fx < item->bounds().x1 && target_fy >= item->bounds().y0 && target_fy < item->bounds().y1) + if (checkit && target_fx >= item.bounds().x0 && target_fx < item.bounds().x1 && target_fy >= item.bounds().y0 && target_fy < item.bounds().y1) { // point successfully mapped - mapped_x = (target_fx - item->bounds().x0) / (item->bounds().x1 - item->bounds().x0); - mapped_y = (target_fy - item->bounds().y0) / (item->bounds().y1 - item->bounds().y0); - mapped_input_port = item->input_tag_and_mask(mapped_input_mask); + mapped_x = (target_fx - item.bounds().x0) / (item.bounds().x1 - item.bounds().x0); + mapped_y = (target_fy - item.bounds().y0) / (item.bounds().y1 - item.bounds().y0); + mapped_input_port = item.input_tag_and_mask(mapped_input_mask); return true; } } @@ -2027,11 +2027,11 @@ bool render_target::map_point_internal(INT32 target_x, INT32 target_y, render_co layout_view *render_target::view_by_index(int index) const { // scan the list of views within each layout, skipping those that don't apply - for (layout_file *file = m_filelist.first(); file != nullptr; file = file->next()) - for (layout_view *view = file->first_view(); view != nullptr; view = view->next()) - if (!(m_flags & RENDER_CREATE_NO_ART) || !view->has_art()) + for (layout_file &file : m_filelist) + for (layout_view &view : file.views()) + if (!(m_flags & RENDER_CREATE_NO_ART) || !view.has_art()) if (index-- == 0) - return view; + return &view; return nullptr; } @@ -2047,11 +2047,11 @@ int render_target::view_index(layout_view &targetview) const int index = 0; // scan the list of views within each layout, skipping those that don't apply - for (layout_file *file = m_filelist.first(); file != nullptr; file = file->next()) - for (layout_view *view = file->first_view(); view != nullptr; view = view->next()) - if (!(m_flags & RENDER_CREATE_NO_ART) || !view->has_art()) + for (layout_file &file : m_filelist) + for (layout_view &view : file.views()) + if (!(m_flags & RENDER_CREATE_NO_ART) || !view.has_art()) { - if (&targetview == view) + if (&targetview == &view) return index; index++; } @@ -2398,10 +2398,10 @@ void render_target::add_clear_and_optimize_primitive_list(render_primitive_list init_clear_extents(); // scan the list until we hit an intersection quad or a line - for (render_primitive *prim = list.first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : list) { // switch off the type - switch (prim->type) + switch (prim.type) { case render_primitive::LINE: goto done; @@ -2409,32 +2409,32 @@ void render_target::add_clear_and_optimize_primitive_list(render_primitive_list case render_primitive::QUAD: { // stop when we hit an alpha texture - if (PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_ARGB32 || PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_PALETTEA16) + if (PRIMFLAG_GET_TEXFORMAT(prim.flags) == TEXFORMAT_ARGB32 || PRIMFLAG_GET_TEXFORMAT(prim.flags) == TEXFORMAT_PALETTEA16) goto done; // if this quad can't be cleanly removed from the extents list, we're done - if (!remove_clear_extent(prim->bounds)) + if (!remove_clear_extent(prim.bounds)) goto done; // change the blendmode on the first primitive to be NONE - if (PRIMFLAG_GET_BLENDMODE(prim->flags) == BLENDMODE_RGB_MULTIPLY) + if (PRIMFLAG_GET_BLENDMODE(prim.flags) == BLENDMODE_RGB_MULTIPLY) { // RGB multiply will multiply against 0, leaving nothing - set_render_color(&prim->color, 1.0f, 0.0f, 0.0f, 0.0f); - prim->texture.base = nullptr; - prim->flags = (prim->flags & ~PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE); + set_render_color(&prim.color, 1.0f, 0.0f, 0.0f, 0.0f); + prim.texture.base = nullptr; + prim.flags = (prim.flags & ~PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE); } else { // for alpha or add modes, we will blend against 0 or add to 0; treat it like none - prim->flags = (prim->flags & ~PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE); + prim.flags = (prim.flags & ~PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE); } // since alpha is disabled, premultiply the RGB values and reset the alpha to 1.0 - prim->color.r *= prim->color.a; - prim->color.g *= prim->color.a; - prim->color.b *= prim->color.a; - prim->color.a = 1.0f; + prim.color.r *= prim.color.a; + prim.color.g *= prim.color.a; + prim.color.b *= prim.color.a; + prim.color.a = 1.0f; break; } @@ -2496,8 +2496,8 @@ render_manager::~render_manager() bool render_manager::is_live(screen_device &screen) const { // iterate over all live targets and or together their screen masks - for (render_target *target = m_targetlist.first(); target != nullptr; target = target->next()) - if (!target->hidden() && target->view_screens(target->view()).contains(screen)) + for (render_target &target : m_targetlist) + if (!target.hidden() && target.view_screens(target.view()).contains(screen)) return true; return false; } @@ -2512,13 +2512,13 @@ float render_manager::max_update_rate() const { // iterate over all live targets and or together their screen masks float minimum = 0; - for (render_target *target = m_targetlist.first(); target != nullptr; target = target->next()) - if (target->max_update_rate() != 0) + for (render_target &target : m_targetlist) + if (target.max_update_rate() != 0) { if (minimum == 0) - minimum = target->max_update_rate(); + minimum = target.max_update_rate(); else - minimum = MIN(target->max_update_rate(), minimum); + minimum = MIN(target.max_update_rate(), minimum); } return minimum; @@ -2553,10 +2553,10 @@ void render_manager::target_free(render_target *target) render_target *render_manager::target_by_index(int index) const { // count up the targets until we hit the requested index - for (render_target *target = m_targetlist.first(); target != nullptr; target = target->next()) - if (!target->hidden()) + for (render_target &target : m_targetlist) + if (!target.hidden()) if (index-- == 0) - return target; + return ⌖ return nullptr; } @@ -2674,8 +2674,8 @@ void render_manager::invalidate_all(void *refptr) return; // loop over targets - for (render_target *target = m_targetlist.first(); target != nullptr; target = target->next()) - target->invalidate_all(refptr); + for (render_target &target : m_targetlist) + target.invalidate_all(refptr); } @@ -2685,10 +2685,8 @@ void render_manager::invalidate_all(void *refptr) void render_manager::resolve_tags() { - for (render_target *target = m_targetlist.first(); target != nullptr; target = target->next()) - { - target->resolve_tags(); - } + for (render_target &target : m_targetlist) + target.resolve_tags(); } diff --git a/src/emu/render.h b/src/emu/render.h index 92761b45305..0a3c5d87f26 100644 --- a/src/emu/render.h +++ b/src/emu/render.h @@ -371,6 +371,8 @@ class render_primitive_list public: // getters render_primitive *first() const { return m_primlist.first(); } + auto begin() const { return m_primlist.begin(); } + auto end() const { return m_primlist.end(); } // lock management void acquire_lock() { m_lock.lock(); } @@ -573,7 +575,7 @@ private: static void overlay_scale(bitmap_argb32 &dest, bitmap_argb32 &source, const rectangle &sbounds, void *param); // internal helpers - item *first_item() const { return m_itemlist.first(); } + const auto &items() const { return m_itemlist; } item &add_generic(UINT8 type, float x0, float y0, float x1, float y1, rgb_t argb); void recompute_lookups(); void update_palette(); @@ -817,7 +819,7 @@ public: // getters layout_view *next() const { return m_next; } - item *first_item(item_layer layer) const; + const simple_list &items(item_layer layer) const; const char *name() const { return m_name.c_str(); } const render_bounds &bounds() const { return m_bounds; } const render_bounds &screen_bounds() const { return m_scrbounds; } @@ -868,8 +870,8 @@ public: // getters layout_file *next() const { return m_next; } - layout_element *first_element() const { return m_elemlist.first(); } - layout_view *first_view() const { return m_viewlist.first(); } + const auto &elements() const { return m_elemlist; } + const auto &views() const { return m_viewlist; } private: // internal state @@ -1046,6 +1048,7 @@ public: // targets render_target *target_alloc(const char *layoutfile = nullptr, UINT32 flags = 0); void target_free(render_target *target); + const auto &targets() const { return m_targetlist; } render_target *first_target() const { return m_targetlist.first(); } render_target *target_by_index(int index) const; diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp index bca0afc9b25..0db4326c139 100644 --- a/src/emu/rendlay.cpp +++ b/src/emu/rendlay.cpp @@ -453,7 +453,7 @@ layout_element::layout_element(running_machine &machine, xml_data_node &elemnode m_maxstate = 65536; } - if (m_complist.first() != nullptr) + if (!m_complist.empty()) { // determine the scale/offset for normalization float xoffs = bounds.x0; @@ -462,12 +462,12 @@ layout_element::layout_element(running_machine &machine, xml_data_node &elemnode float yscale = 1.0f / (bounds.y1 - bounds.y0); // normalize all the component bounds - for (component *curcomp = m_complist.first(); curcomp != nullptr; curcomp = curcomp->next()) + for (component &curcomp : m_complist) { - curcomp->m_bounds.x0 = (curcomp->m_bounds.x0 - xoffs) * xscale; - curcomp->m_bounds.x1 = (curcomp->m_bounds.x1 - xoffs) * xscale; - curcomp->m_bounds.y0 = (curcomp->m_bounds.y0 - yoffs) * yscale; - curcomp->m_bounds.y1 = (curcomp->m_bounds.y1 - yoffs) * yscale; + curcomp.m_bounds.x0 = (curcomp.m_bounds.x0 - xoffs) * xscale; + curcomp.m_bounds.x1 = (curcomp.m_bounds.x1 - xoffs) * xscale; + curcomp.m_bounds.y0 = (curcomp.m_bounds.y0 - yoffs) * yscale; + curcomp.m_bounds.y1 = (curcomp.m_bounds.y1 - yoffs) * yscale; } } @@ -515,19 +515,19 @@ void layout_element::element_scale(bitmap_argb32 &dest, bitmap_argb32 &source, c texture *elemtex = (texture *)param; // iterate over components that are part of the current state - for (component *curcomp = elemtex->m_element->m_complist.first(); curcomp != nullptr; curcomp = curcomp->next()) - if (curcomp->m_state == -1 || curcomp->m_state == elemtex->m_state) + for (component &curcomp : elemtex->m_element->m_complist) + if (curcomp.m_state == -1 || curcomp.m_state == elemtex->m_state) { // get the local scaled bounds rectangle bounds; - bounds.min_x = render_round_nearest(curcomp->bounds().x0 * dest.width()); - bounds.min_y = render_round_nearest(curcomp->bounds().y0 * dest.height()); - bounds.max_x = render_round_nearest(curcomp->bounds().x1 * dest.width()); - bounds.max_y = render_round_nearest(curcomp->bounds().y1 * dest.height()); + bounds.min_x = render_round_nearest(curcomp.bounds().x0 * dest.width()); + bounds.min_y = render_round_nearest(curcomp.bounds().y0 * dest.height()); + bounds.max_x = render_round_nearest(curcomp.bounds().x1 * dest.width()); + bounds.max_y = render_round_nearest(curcomp.bounds().y1 * dest.height()); bounds &= dest.cliprect(); // based on the component type, add to the texture - curcomp->draw(elemtex->m_element->machine(), dest, bounds, elemtex->m_state); + curcomp.draw(elemtex->m_element->machine(), dest, bounds, elemtex->m_state); } } @@ -2186,21 +2186,22 @@ layout_view::~layout_view() //------------------------------------------------- -// first_item - return the first item in the -// appropriate list +// items - return the appropriate list //------------------------------------------------- -layout_view::item *layout_view::first_item(item_layer layer) const +const simple_list &layout_view::items(item_layer layer) const { + static simple_list s_null_list; + switch (layer) { - case ITEM_LAYER_BACKDROP: return m_backdrop_list.first(); - case ITEM_LAYER_SCREEN: return m_screen_list.first(); - case ITEM_LAYER_OVERLAY: return m_overlay_list.first(); - case ITEM_LAYER_BEZEL: return m_bezel_list.first(); - case ITEM_LAYER_CPANEL: return m_cpanel_list.first(); - case ITEM_LAYER_MARQUEE: return m_marquee_list.first(); - default: return nullptr; + case ITEM_LAYER_BACKDROP: return m_backdrop_list; + case ITEM_LAYER_SCREEN: return m_screen_list; + case ITEM_LAYER_OVERLAY: return m_overlay_list; + case ITEM_LAYER_BEZEL: return m_bezel_list; + case ITEM_LAYER_CPANEL: return m_cpanel_list; + case ITEM_LAYER_MARQUEE: return m_marquee_list; + default: return s_null_list; } } @@ -2235,26 +2236,26 @@ void layout_view::recompute(render_layer_config layerconfig) // only do it if requested if (m_layenabled[layer]) - for (item *curitem = first_item(layer); curitem != nullptr; curitem = curitem->next()) + for (item &curitem : items(layer)) { // accumulate bounds if (first) - m_bounds = curitem->m_rawbounds; + m_bounds = curitem.m_rawbounds; else - union_render_bounds(&m_bounds, &curitem->m_rawbounds); + union_render_bounds(&m_bounds, &curitem.m_rawbounds); first = false; // accumulate screen bounds - if (curitem->m_screen != nullptr) + if (curitem.m_screen != nullptr) { if (scrfirst) - m_scrbounds = curitem->m_rawbounds; + m_scrbounds = curitem.m_rawbounds; else - union_render_bounds(&m_scrbounds, &curitem->m_rawbounds); + union_render_bounds(&m_scrbounds, &curitem.m_rawbounds); scrfirst = false; // accumulate the screens in use while we're scanning - m_screens.add(*curitem->m_screen); + m_screens.add(*curitem.m_screen); } } } @@ -2296,12 +2297,12 @@ void layout_view::recompute(render_layer_config layerconfig) // normalize all the item bounds for (item_layer layer = ITEM_LAYER_FIRST; layer < ITEM_LAYER_MAX; ++layer) - for (item *curitem = first_item(layer); curitem != nullptr; curitem = curitem->next()) + for (item &curitem : items(layer)) { - curitem->m_bounds.x0 = target_bounds.x0 + (curitem->m_rawbounds.x0 - xoffs) * xscale; - curitem->m_bounds.x1 = target_bounds.x0 + (curitem->m_rawbounds.x1 - xoffs) * xscale; - curitem->m_bounds.y0 = target_bounds.y0 + (curitem->m_rawbounds.y0 - yoffs) * yscale; - curitem->m_bounds.y1 = target_bounds.y0 + (curitem->m_rawbounds.y1 - yoffs) * yscale; + curitem.m_bounds.x0 = target_bounds.x0 + (curitem.m_rawbounds.x0 - xoffs) * xscale; + curitem.m_bounds.x1 = target_bounds.x0 + (curitem.m_rawbounds.x1 - xoffs) * xscale; + curitem.m_bounds.y0 = target_bounds.y0 + (curitem.m_rawbounds.y0 - yoffs) * yscale; + curitem.m_bounds.y1 = target_bounds.y0 + (curitem.m_rawbounds.y1 - yoffs) * yscale; } } @@ -2314,9 +2315,9 @@ void layout_view::resolve_tags() { for (item_layer layer = ITEM_LAYER_FIRST; layer < ITEM_LAYER_MAX; ++layer) { - for (item *curitem = first_item(layer); curitem != nullptr; curitem = curitem->next()) + for (item &curitem : items(layer)) { - curitem->resolve_tags(); + curitem.resolve_tags(); } } } @@ -2350,9 +2351,12 @@ layout_view::item::item(running_machine &machine, xml_data_node &itemnode, simpl if (name != nullptr) { // search the list of elements for a match - for (m_element = elemlist.first(); m_element != nullptr; m_element = m_element->next()) - if (strcmp(name, m_element->name()) == 0) + for (layout_element &elem : elemlist) + if (strcmp(name, elem.name()) == 0) + { + m_element = &elem; break; + } // error if not found if (m_element == nullptr) diff --git a/src/emu/save.cpp b/src/emu/save.cpp index 6c875bc08ff..d288b9905c7 100644 --- a/src/emu/save.cpp +++ b/src/emu/save.cpp @@ -112,9 +112,9 @@ void save_manager::register_presave(save_prepost_delegate func) fatalerror("Attempt to register callback function after state registration is closed!\n"); // scan for duplicates and push through to the end - for (state_callback *cb = m_presave_list.first(); cb != nullptr; cb = cb->next()) - if (cb->m_func == func) - fatalerror("Duplicate save state function (%s/%s)\n", cb->m_func.name(), func.name()); + for (state_callback &cb : m_presave_list) + if (cb.m_func == func) + fatalerror("Duplicate save state function (%s/%s)\n", cb.m_func.name(), func.name()); // allocate a new entry m_presave_list.append(*global_alloc(state_callback(func))); @@ -133,9 +133,9 @@ void save_manager::register_postload(save_prepost_delegate func) fatalerror("Attempt to register callback function after state registration is closed!\n"); // scan for duplicates and push through to the end - for (state_callback *cb = m_postload_list.first(); cb != nullptr; cb = cb->next()) - if (cb->m_func == func) - fatalerror("Duplicate save state function (%s/%s)\n", cb->m_func.name(), func.name()); + for (state_callback &cb : m_postload_list) + if (cb.m_func == func) + fatalerror("Duplicate save state function (%s/%s)\n", cb.m_func.name(), func.name()); // allocate a new entry m_postload_list.append(*global_alloc(state_callback(func))); @@ -170,15 +170,15 @@ void save_manager::save_memory(device_t *device, const char *module, const char // look for duplicates and an entry to insert in front of state_entry *insert_after = nullptr; - for (state_entry *entry = m_entry_list.first(); entry != nullptr; entry = entry->next()) + for (state_entry &entry : m_entry_list) { // stop when we find an entry whose name is after ours - if (entry->m_name.compare(totalname)>0) + if (entry.m_name.compare(totalname)>0) break; - insert_after = entry; + insert_after = &entry; // error if we are equal - if (entry->m_name.compare(totalname)==0) + if (entry.m_name.compare(totalname)==0) fatalerror("Duplicate save state registration entry (%s)\n", totalname.c_str()); } @@ -221,8 +221,8 @@ save_error save_manager::check_file(running_machine &machine, emu_file &file, co void save_manager::dispatch_postload() { - for (state_callback *func = m_postload_list.first(); func != nullptr; func = func->next()) - func->m_func(); + for (state_callback &func : m_postload_list) + func.m_func(); } //------------------------------------------------- @@ -252,15 +252,15 @@ save_error save_manager::read_file(emu_file &file) bool flip = NATIVE_ENDIAN_VALUE_LE_BE((header[9] & SS_MSB_FIRST) != 0, (header[9] & SS_MSB_FIRST) == 0); // read all the data, flipping if necessary - for (state_entry *entry = m_entry_list.first(); entry != nullptr; entry = entry->next()) + for (state_entry &entry : m_entry_list) { - UINT32 totalsize = entry->m_typesize * entry->m_typecount; - if (file.read(entry->m_data, totalsize) != totalsize) + UINT32 totalsize = entry.m_typesize * entry.m_typecount; + if (file.read(entry.m_data, totalsize) != totalsize) return STATERR_READ_ERROR; // handle flipping if (flip) - entry->flip_data(); + entry.flip_data(); } // call the post-load functions @@ -277,8 +277,8 @@ save_error save_manager::read_file(emu_file &file) void save_manager::dispatch_presave() { - for (state_callback *func = m_presave_list.first(); func != nullptr; func = func->next()) - func->m_func(); + for (state_callback &func : m_presave_list) + func.m_func(); } //------------------------------------------------- @@ -311,10 +311,10 @@ save_error save_manager::write_file(emu_file &file) dispatch_presave(); // then write all the data - for (state_entry *entry = m_entry_list.first(); entry != nullptr; entry = entry->next()) + for (state_entry &entry : m_entry_list) { - UINT32 totalsize = entry->m_typesize * entry->m_typecount; - if (file.write(entry->m_data, totalsize) != totalsize) + UINT32 totalsize = entry.m_typesize * entry.m_typecount; + if (file.write(entry.m_data, totalsize) != totalsize) return STATERR_WRITE_ERROR; } return STATERR_NONE; @@ -330,15 +330,15 @@ UINT32 save_manager::signature() const { // iterate over entries UINT32 crc = 0; - for (state_entry *entry = m_entry_list.first(); entry != nullptr; entry = entry->next()) + for (state_entry &entry : m_entry_list) { // add the entry name to the CRC - crc = core_crc32(crc, (UINT8 *)entry->m_name.c_str(), entry->m_name.length()); + crc = core_crc32(crc, (UINT8 *)entry.m_name.c_str(), entry.m_name.length()); // add the type and size to the CRC UINT32 temp[2]; - temp[0] = LITTLE_ENDIANIZE_INT32(entry->m_typecount); - temp[1] = LITTLE_ENDIANIZE_INT32(entry->m_typesize); + temp[0] = LITTLE_ENDIANIZE_INT32(entry.m_typecount); + temp[1] = LITTLE_ENDIANIZE_INT32(entry.m_typesize); crc = core_crc32(crc, (UINT8 *)&temp[0], sizeof(temp)); } return crc; @@ -352,8 +352,8 @@ UINT32 save_manager::signature() const void save_manager::dump_registry() const { - for (state_entry *entry = m_entry_list.first(); entry != nullptr; entry = entry->next()) - LOG(("%s: %d x %d\n", entry->m_name.c_str(), entry->m_typesize, entry->m_typecount)); + for (state_entry &entry : m_entry_list) + LOG(("%s: %d x %d\n", entry.m_name.c_str(), entry.m_typesize, entry.m_typecount)); } diff --git a/src/emu/schedule.cpp b/src/emu/schedule.cpp index e0bc57c2fff..2e87a62b06f 100644 --- a/src/emu/schedule.cpp +++ b/src/emu/schedule.cpp @@ -726,8 +726,8 @@ void device_scheduler::compute_perfect_interleave() { // adjust all the actuals; this doesn't affect the current m_quantum_minimum = perfect; - for (quantum_slot *quant = m_quantum_list.first(); quant != nullptr; quant = quant->next()) - quant->m_actual = MAX(quant->m_requested, m_quantum_minimum); + for (quantum_slot &quant : m_quantum_list) + quant.m_actual = MAX(quant.m_requested, m_quantum_minimum); } } } @@ -742,7 +742,7 @@ void device_scheduler::compute_perfect_interleave() void device_scheduler::rebuild_execute_list() { // if we haven't yet set a scheduling quantum, do it now - if (m_quantum_list.first() == nullptr) + if (m_quantum_list.empty()) { // set the core scheduling quantum attotime min_quantum = machine().config().m_minimum_quantum; diff --git a/src/emu/screen.cpp b/src/emu/screen.cpp index 111a1b3232a..952c84ca30a 100644 --- a/src/emu/screen.cpp +++ b/src/emu/screen.cpp @@ -566,8 +566,8 @@ void screen_device::realloc_screen_bitmaps() INT32 effheight = MAX(m_height, m_visarea.max_y + 1); // reize all registered screen bitmaps - for (auto_bitmap_item *item = m_auto_bitmap_list.first(); item != nullptr; item = item->next()) - item->m_bitmap.resize(effwidth, effheight); + for (auto_bitmap_item &item : m_auto_bitmap_list) + item.m_bitmap.resize(effwidth, effheight); // re-set up textures if (m_palette != nullptr) @@ -910,15 +910,13 @@ void screen_device::register_vblank_callback(vblank_state_delegate vblank_callba // validate arguments assert(!vblank_callback.isnull()); - // check if we already have this callback registered - callback_item *item; - for (item = m_callback_list.first(); item != nullptr; item = item->next()) - if (item->m_callback == vblank_callback) - break; + // do nothing if we already have this callback registered + for (callback_item &item : m_callback_list) + if (item.m_callback == vblank_callback) + return; // if not found, register - if (item == nullptr) - m_callback_list.append(*global_alloc(callback_item(vblank_callback))); + m_callback_list.append(*global_alloc(callback_item(vblank_callback))); } @@ -955,8 +953,8 @@ void screen_device::vblank_begin() machine().video().frame_update(); // call the screen specific callbacks - for (callback_item *item = m_callback_list.first(); item != nullptr; item = item->next()) - item->m_callback(*this, true); + for (callback_item &item : m_callback_list) + item.m_callback(*this, true); if (!m_screen_vblank.isnull()) m_screen_vblank(*this, true); @@ -979,8 +977,8 @@ void screen_device::vblank_begin() void screen_device::vblank_end() { // call the screen specific callbacks - for (callback_item *item = m_callback_list.first(); item != nullptr; item = item->next()) - item->m_callback(*this, false); + for (callback_item &item : m_callback_list) + item.m_callback(*this, false); if (!m_screen_vblank.isnull()) m_screen_vblank(*this, false); diff --git a/src/emu/softlist.cpp b/src/emu/softlist.cpp index d554b394c21..e86415b3d35 100644 --- a/src/emu/softlist.cpp +++ b/src/emu/softlist.cpp @@ -128,9 +128,9 @@ const char *software_part::feature(const char *feature_name) const assert(feature_name != nullptr); // scan the feature list for an entry matching feature_name and return the value - for (const feature_list_item *feature = m_featurelist.first(); feature != nullptr; feature = feature->next()) - if (strcmp(feature->name(), feature_name) == 0) - return feature->value(); + for (const feature_list_item &feature : m_featurelist) + if (strcmp(feature.name(), feature_name) == 0) + return feature.value(); return nullptr; } @@ -232,14 +232,14 @@ software_part *software_info::find_part(const char *partname, const char *interf return m_partdata.first(); // look for the part by name and match against the interface if provided - for (software_part *part = m_partdata.first(); part != nullptr; part = part->next()) - if (partname != nullptr && strcmp(partname, part->name()) == 0) + for (software_part &part : m_partdata) + if (partname != nullptr && strcmp(partname, part.name()) == 0) { - if (interface == nullptr || part->matches_interface(interface)) - return part; + if (interface == nullptr || part.matches_interface(interface)) + return ∂ } - else if (partname == nullptr && part->matches_interface(interface)) - return part; + else if (partname == nullptr && part.matches_interface(interface)) + return ∂ return nullptr; } @@ -255,8 +255,8 @@ bool software_info::has_multiple_parts(const char *interface) const int count = 0; // increment the count for each match and stop if we hit more than 1 - for (software_part *part = first_part(); part != nullptr; part = part->next()) - if (part->matches_interface(interface)) + for (software_part &part : m_partdata) + if (part.matches_interface(interface)) if (++count > 1) return true; @@ -338,14 +338,14 @@ void software_list_device::find_approx_matches(const char *name, int matches, so } // iterate over our info (will cause a parse if needed) - for (software_info *swinfo = first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) + for (software_info &swinfo : get_info()) { - software_part *part = swinfo->first_part(); + software_part *part = swinfo.first_part(); if ((interface == nullptr || part->matches_interface(interface)) && part->is_compatible(*this)) { // pick the best match between driver name and description - int longpenalty = driver_list::penalty_compare(name, swinfo->longname()); - int shortpenalty = driver_list::penalty_compare(name, swinfo->shortname()); + int longpenalty = driver_list::penalty_compare(name, swinfo.longname()); + int shortpenalty = driver_list::penalty_compare(name, swinfo.shortname()); int curpenalty = MIN(longpenalty, shortpenalty); // insert into the sorted table of matches @@ -361,7 +361,7 @@ void software_list_device::find_approx_matches(const char *name, int matches, so penalty[matchnum + 1] = penalty[matchnum]; list[matchnum + 1] = list[matchnum]; } - list[matchnum] = swinfo; + list[matchnum] = &swinfo; penalty[matchnum] = curpenalty; } } @@ -455,8 +455,8 @@ software_info *software_list_device::find(const char *look_for, software_info *p bool iswild = strchr(look_for, '*') != nullptr || strchr(look_for, '?'); - // find a match (will cause a parse if needed when calling first_software_info) - for (prev = (prev != nullptr) ? prev->next() : first_software_info(); prev != nullptr; prev = prev->next()) + // find a match (will cause a parse if needed when calling get_info) + for (prev = (prev != nullptr) ? prev->next() : get_info().first(); prev != nullptr; prev = prev->next()) if ((iswild && core_strwildcmp(look_for, prev->shortname()) == 0) || core_stricmp(look_for, prev->shortname()) == 0) break; @@ -527,7 +527,7 @@ void software_list_device::internal_validity_check(validity_checker &valid) softlist_map names; softlist_map descriptions; - for (software_info *swinfo = first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) + for (software_info &swinfo : get_info()) { // first parse and output core errors if any if (m_errors.length() > 0) @@ -539,98 +539,98 @@ void software_list_device::internal_validity_check(validity_checker &valid) // Now check if the xml data is valid: // Did we lost any description? - if (swinfo->longname() == nullptr) + if (swinfo.longname() == nullptr) { - osd_printf_error("%s: %s has no description\n", filename(), swinfo->shortname()); + osd_printf_error("%s: %s has no description\n", filename(), swinfo.shortname()); break; } // Did we lost any year? - if (swinfo->year() == nullptr) + if (swinfo.year() == nullptr) { - osd_printf_error("%s: %s has no year\n", filename(), swinfo->shortname()); + osd_printf_error("%s: %s has no year\n", filename(), swinfo.shortname()); break; } // Did we lost any publisher? - if (swinfo->publisher() == nullptr) + if (swinfo.publisher() == nullptr) { - osd_printf_error("%s: %s has no publisher\n", filename(), swinfo->shortname()); + osd_printf_error("%s: %s has no publisher\n", filename(), swinfo.shortname()); break; } // Did we lost the software parts? - if (swinfo->num_parts() == 0) + if (swinfo.parts().empty()) { - osd_printf_error("%s: %s has no part\n", filename(), swinfo->shortname()); + osd_printf_error("%s: %s has no part\n", filename(), swinfo.shortname()); break; } // Second, since the xml is fine, run additional checks: // check for duplicate names - if (!names.insert(std::make_pair(swinfo->shortname(), swinfo)).second) + if (!names.insert(std::make_pair(swinfo.shortname(), &swinfo)).second) { - software_info *match = names.find(swinfo->shortname())->second; - osd_printf_error("%s: %s is a duplicate name (%s)\n", filename(), swinfo->shortname(), match->shortname()); + software_info *match = names.find(swinfo.shortname())->second; + osd_printf_error("%s: %s is a duplicate name (%s)\n", filename(), swinfo.shortname(), match->shortname()); } // check for duplicate descriptions - std::string longname = std::string(swinfo->longname()); - if (!descriptions.insert(std::make_pair(strmakelower(longname), swinfo)).second) - osd_printf_error("%s: %s is a duplicate description (%s)\n", filename(), swinfo->longname(), swinfo->shortname()); + std::string longname = std::string(swinfo.longname()); + if (!descriptions.insert(std::make_pair(strmakelower(longname), &swinfo)).second) + osd_printf_error("%s: %s is a duplicate description (%s)\n", filename(), swinfo.longname(), swinfo.shortname()); bool is_clone = false; - if (swinfo->parentname() != nullptr) + if (swinfo.parentname() != nullptr) { is_clone = true; - if (strcmp(swinfo->parentname(), swinfo->shortname()) == 0) + if (strcmp(swinfo.parentname(), swinfo.shortname()) == 0) { - osd_printf_error("%s: %s is set as a clone of itself\n", filename(), swinfo->shortname()); + osd_printf_error("%s: %s is set as a clone of itself\n", filename(), swinfo.shortname()); break; } // make sure the parent exists - software_info *swinfo2 = find(swinfo->parentname()); + software_info *swinfo2 = find(swinfo.parentname()); if (swinfo2 == nullptr) - osd_printf_error("%s: parent '%s' software for '%s' not found\n", filename(), swinfo->parentname(), swinfo->shortname()); + osd_printf_error("%s: parent '%s' software for '%s' not found\n", filename(), swinfo.parentname(), swinfo.shortname()); else if (swinfo2->parentname() != nullptr) - osd_printf_error("%s: %s is a clone of a clone\n", filename(), swinfo->shortname()); + osd_printf_error("%s: %s is a clone of a clone\n", filename(), swinfo.shortname()); } // make sure the driver name is 8 chars or less - if ((is_clone && strlen(swinfo->shortname()) > NAME_LEN_CLONE) || (!is_clone && strlen(swinfo->shortname()) > NAME_LEN_PARENT)) - osd_printf_error("%s: %s %s driver name must be %d characters or less\n", filename(), swinfo->shortname(), + if ((is_clone && strlen(swinfo.shortname()) > NAME_LEN_CLONE) || (!is_clone && strlen(swinfo.shortname()) > NAME_LEN_PARENT)) + osd_printf_error("%s: %s %s driver name must be %d characters or less\n", filename(), swinfo.shortname(), is_clone ? "clone" : "parent", is_clone ? NAME_LEN_CLONE : NAME_LEN_PARENT); // make sure the year is only digits, '?' or '+' - for (const char *s = swinfo->year(); *s != 0; s++) + for (const char *s = swinfo.year(); *s != 0; s++) if (!isdigit((UINT8)*s) && *s != '?' && *s != '+') { - osd_printf_error("%s: %s has an invalid year '%s'\n", filename(), swinfo->shortname(), swinfo->year()); + osd_printf_error("%s: %s has an invalid year '%s'\n", filename(), swinfo.shortname(), swinfo.year()); break; } softlist_map part_names; - for (software_part *part = swinfo->first_part(); part != nullptr; part = part->next()) + for (software_part &part : swinfo.parts()) { - if (part->interface() == nullptr) - osd_printf_error("%s: %s has a part (%s) without interface\n", filename(), swinfo->shortname(), part->name()); + if (part.interface() == nullptr) + osd_printf_error("%s: %s has a part (%s) without interface\n", filename(), swinfo.shortname(), part.name()); - if (part->romdata() == nullptr) - osd_printf_error("%s: %s has a part (%s) with no data\n", filename(), swinfo->shortname(), part->name()); + if (part.romdata() == nullptr) + osd_printf_error("%s: %s has a part (%s) with no data\n", filename(), swinfo.shortname(), part.name()); - if (!part_names.insert(std::make_pair(part->name(), swinfo)).second) - osd_printf_error("%s: %s has a part (%s) whose name is duplicate\n", filename(), swinfo->shortname(), part->name()); + if (!part_names.insert(std::make_pair(part.name(), &swinfo)).second) + osd_printf_error("%s: %s has a part (%s) whose name is duplicate\n", filename(), swinfo.shortname(), part.name()); - for (const rom_entry *data = part->romdata(); data->_name != nullptr; data++) + for (const rom_entry *data = part.romdata(); data->_name != nullptr; data++) if (data->_hashdata != nullptr) { // make sure the hash is valid hash_collection hashes; if (!hashes.from_internal_string(data->_hashdata)) - osd_printf_error("%s: %s has rom '%s' with an invalid hash string '%s'\n", filename(), swinfo->shortname(), data->_name, data->_hashdata); + osd_printf_error("%s: %s has rom '%s' with an invalid hash string '%s'\n", filename(), swinfo.shortname(), data->_name, data->_hashdata); } } } @@ -1253,7 +1253,7 @@ void softlist_parser::parse_soft_end(const char *tagname) // get the info; if present, copy shared data (we assume name/value strings live // in the string pool and don't need to be reallocated) if (m_current_info != nullptr) - for (feature_list_item *item = m_current_info->shared_info(); item != nullptr; item = item->next()) - m_current_part->m_featurelist.append(*global_alloc(feature_list_item(item->name(), item->value()))); + for (feature_list_item &item : m_current_info->shared_info()) + m_current_part->m_featurelist.append(*global_alloc(feature_list_item(item.name(), item.value()))); } } diff --git a/src/emu/softlist.h b/src/emu/softlist.h index 63ce6f0da20..976bc64c642 100644 --- a/src/emu/softlist.h +++ b/src/emu/softlist.h @@ -111,7 +111,7 @@ public: software_info &info() const { return m_info; } const char *name() const { return m_name; } const char *interface() const { return m_interface; } - feature_list_item *featurelist() const { return m_featurelist.first(); } + const auto &featurelist() const { return m_featurelist; } rom_entry *romdata(unsigned int index = 0) { return (index < m_romdata.size()) ? &m_romdata[index] : nullptr; } // helpers @@ -150,12 +150,11 @@ public: const char *parentname() const { return m_parentname; } const char *year() const { return m_year; } const char *publisher() const { return m_publisher; } - feature_list_item *other_info() const { return m_other_info.first(); } - feature_list_item *shared_info() const { return m_shared_info.first(); } + const auto &other_info() const { return m_other_info; } + const auto &shared_info() const { return m_shared_info; } UINT32 supported() const { return m_supported; } - int num_parts() const { return m_partdata.count(); } + const auto &parts() const { return m_partdata; } software_part *first_part() const { return m_partdata.first(); } - software_part *last_part() const { return m_partdata.last(); } // additional operations software_part *find_part(const char *partname, const char *interface = nullptr); @@ -203,10 +202,10 @@ public: const char *description() { if (!m_parsed) parse(); return m_description; } bool valid() { if (!m_parsed) parse(); return m_infolist.count() > 0; } const char *errors_string() { if (!m_parsed) parse(); return m_errors.c_str(); } + const auto &get_info() { if (!m_parsed) parse(); return m_infolist; } // operations software_info *find(const char *look_for, software_info *prev = nullptr); - software_info *first_software_info() { if (!m_parsed) parse(); return m_infolist.first(); } void find_approx_matches(const char *name, int matches, software_info **list, const char *interface); void release(); diff --git a/src/emu/sound.cpp b/src/emu/sound.cpp index 47e7dcc90e8..12093cb0689 100644 --- a/src/emu/sound.cpp +++ b/src/emu/sound.cpp @@ -1090,15 +1090,15 @@ void sound_manager::update(void *ptr, int param) } // iterate over all the streams and update them - for (sound_stream *stream = m_stream_list.first(); stream != nullptr; stream = stream->next()) - stream->update_with_accounting(second_tick); + for (sound_stream &stream : m_stream_list) + stream.update_with_accounting(second_tick); // remember the update time m_last_update = curtime; // update sample rates if they have changed - for (sound_stream *stream = m_stream_list.first(); stream != nullptr; stream = stream->next()) - stream->apply_sample_rate_changes(); + for (sound_stream &stream : m_stream_list) + stream.apply_sample_rate_changes(); g_profiler.stop(); } diff --git a/src/emu/sound.h b/src/emu/sound.h index b3584969284..842106ba0af 100644 --- a/src/emu/sound.h +++ b/src/emu/sound.h @@ -199,7 +199,7 @@ public: // getters running_machine &machine() const { return m_machine; } int attenuation() const { return m_attenuation; } - sound_stream *first_stream() const { return m_stream_list.first(); } + const auto &streams() const { return m_stream_list; } attotime last_update() const { return m_last_update; } attoseconds_t update_attoseconds() const { return m_update_attoseconds; } diff --git a/src/emu/tilemap.cpp b/src/emu/tilemap.cpp index 807c1b30cf8..69bde8821c0 100644 --- a/src/emu/tilemap.cpp +++ b/src/emu/tilemap.cpp @@ -1503,11 +1503,11 @@ tilemap_manager::~tilemap_manager() while (found) { found = false; - for (tilemap_t *tmap = m_tilemap_list.first(); tmap != nullptr; tmap = tmap->next()) - if (tmap->device() != nullptr) + for (tilemap_t &tmap : m_tilemap_list) + if (tmap.device() != nullptr) { found = true; - m_tilemap_list.detach(*tmap); + m_tilemap_list.detach(tmap); break; } } @@ -1553,8 +1553,8 @@ tilemap_t &tilemap_manager::create(device_gfx_interface &decoder, tilemap_get_in void tilemap_manager::set_flip_all(UINT32 attributes) { - for (tilemap_t *tmap = m_tilemap_list.first(); tmap != nullptr; tmap = tmap->next()) - tmap->set_flip(attributes); + for (tilemap_t &tmap : m_tilemap_list) + tmap.set_flip(attributes); } @@ -1565,8 +1565,8 @@ void tilemap_manager::set_flip_all(UINT32 attributes) void tilemap_manager::mark_all_dirty() { - for (tilemap_t *tmap = m_tilemap_list.first(); tmap != nullptr; tmap = tmap->next()) - tmap->mark_all_dirty(); + for (tilemap_t &tmap : m_tilemap_list) + tmap.mark_all_dirty(); } diff --git a/src/emu/ui/cheatopt.cpp b/src/emu/ui/cheatopt.cpp index ceb2c3301f5..fecb954cd0f 100644 --- a/src/emu/ui/cheatopt.cpp +++ b/src/emu/ui/cheatopt.cpp @@ -36,8 +36,8 @@ void ui_menu_cheat::handle() /* handle reset all + reset all cheats for reload all option */ if ((menu_event->itemref == ITEMREF_CHEATS_RESET_ALL || menu_event->itemref == ITEMREF_CHEATS_RELOAD_ALL) && menu_event->iptkey == IPT_UI_SELECT) { - for (cheat_entry *curcheat = machine().cheat().first(); curcheat != nullptr; curcheat = curcheat->next()) - if (curcheat->select_default_state()) + for (cheat_entry &curcheat : machine().cheat().entries()) + if (curcheat.select_default_state()) changed = true; } @@ -124,12 +124,12 @@ void ui_menu_cheat::populate() item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); // add other cheats - if (machine().cheat().first() != nullptr) { - for (cheat_entry *curcheat = machine().cheat().first(); curcheat != nullptr; curcheat = curcheat->next()) + if (!machine().cheat().entries().empty()) { + for (cheat_entry &curcheat : machine().cheat().entries()) { UINT32 flags; - curcheat->menu_text(text, subtext, flags); - item_append(text.c_str(), subtext.c_str(), flags, curcheat); + curcheat.menu_text(text, subtext, flags); + item_append(text.c_str(), subtext.c_str(), flags, &curcheat); } /* add a separator */ @@ -249,8 +249,6 @@ void ui_menu_autofire::handle() void ui_menu_autofire::populate() { - ioport_field *field; - ioport_port *port; char temp_text[64]; /* add autofire toggle item */ @@ -260,16 +258,16 @@ void ui_menu_autofire::populate() /* iterate over the input ports and add autofire toggle items */ int menu_items = 0; - for (port = machine().ioport().first_port(); port != nullptr; port = port->next()) + for (ioport_port &port : machine().ioport().ports()) { bool is_first_button = true; - for (field = port->first_field(); field != nullptr; field = field->next()) + for (ioport_field &field : port.fields()) { - if ((field->name()) && ((field->type() >= IPT_BUTTON1 && field->type() <= IPT_BUTTON16))) // IPT_BUTTON1 + 15))) + if ((field.name()) && ((field.type() >= IPT_BUTTON1 && field.type() <= IPT_BUTTON16))) // IPT_BUTTON1 + 15))) { menu_items++; ioport_field::user_settings settings; - field->get_user_settings(settings); + field.get_user_settings(settings); if (is_first_button) { @@ -281,13 +279,13 @@ void ui_menu_autofire::populate() if (!autofire_toggle) { // item is enabled and can be switched to values on/off - item_append(field->name(), (settings.autofire ? _("On") : _("Off")), - (settings.autofire ? MENU_FLAG_LEFT_ARROW : MENU_FLAG_RIGHT_ARROW), (void *)field); + item_append(field.name(), (settings.autofire ? _("On") : _("Off")), + (settings.autofire ? MENU_FLAG_LEFT_ARROW : MENU_FLAG_RIGHT_ARROW), (void *)&field); } else { // item is disabled - item_append(field->name(), (settings.autofire ? _("On") : _("Off")), + item_append(field.name(), (settings.autofire ? _("On") : _("Off")), MENU_FLAG_DISABLE | MENU_FLAG_INVERT, nullptr); } } diff --git a/src/emu/ui/custui.cpp b/src/emu/ui/custui.cpp index 816875131dc..6eabfeb65b1 100644 --- a/src/emu/ui/custui.cpp +++ b/src/emu/ui/custui.cpp @@ -215,18 +215,18 @@ ui_menu_font_ui::ui_menu_font_ui(running_machine &machine, render_container *con m_info_size = moptions.infos_size(); m_font_size = moptions.font_rows(); - for (ui_options::entry *f_entry = moptions.first(); f_entry != nullptr; f_entry = f_entry->next()) + for (ui_options::entry &f_entry : moptions) { - const char *name = f_entry->name(); - if (name && strlen(name) && !strcmp(OPTION_INFOS_SIZE, f_entry->name())) + const char *name = f_entry.name(); + if (name && strlen(name) && !strcmp(OPTION_INFOS_SIZE, f_entry.name())) { - m_info_max = atof(f_entry->maximum()); - m_info_min = atof(f_entry->minimum()); + m_info_max = atof(f_entry.maximum()); + m_info_min = atof(f_entry.minimum()); } - else if (name && strlen(name) && !strcmp(OPTION_FONT_ROWS, f_entry->name())) + else if (name && strlen(name) && !strcmp(OPTION_FONT_ROWS, f_entry.name())) { - m_font_max = atof(f_entry->maximum()); - m_font_min = atof(f_entry->minimum()); + m_font_max = atof(f_entry.maximum()); + m_font_min = atof(f_entry.minimum()); } } diff --git a/src/emu/ui/devopt.cpp b/src/emu/ui/devopt.cpp index bafb8e77114..bc99b960e81 100644 --- a/src/emu/ui/devopt.cpp +++ b/src/emu/ui/devopt.cpp @@ -189,47 +189,47 @@ void ui_menu_device_config::populate() portlist.append(*iptdev, errors); // check if the device adds inputs to the system - for (ioport_port *port = portlist.first(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + for (ioport_port &port : portlist) + for (ioport_field &field : port.fields()) { - if (field->type() >= IPT_MAHJONG_FIRST && field->type() < IPT_MAHJONG_LAST) + if (field.type() >= IPT_MAHJONG_FIRST && field.type() < IPT_MAHJONG_LAST) input_mj++; - else if (field->type() >= IPT_HANAFUDA_FIRST && field->type() < IPT_HANAFUDA_LAST) + else if (field.type() >= IPT_HANAFUDA_FIRST && field.type() < IPT_HANAFUDA_LAST) input_hana++; - else if (field->type() >= IPT_GAMBLING_FIRST && field->type() < IPT_GAMBLING_LAST) + else if (field.type() >= IPT_GAMBLING_FIRST && field.type() < IPT_GAMBLING_LAST) input_gamble++; - else if (field->type() >= IPT_ANALOG_FIRST && field->type() < IPT_ANALOG_LAST) + else if (field.type() >= IPT_ANALOG_FIRST && field.type() < IPT_ANALOG_LAST) input_analog++; - else if (field->type() == IPT_ADJUSTER) + else if (field.type() == IPT_ADJUSTER) input_adjust++; - else if (field->type() == IPT_KEYPAD) + else if (field.type() == IPT_KEYPAD) input_keypad++; - else if (field->type() == IPT_KEYBOARD) + else if (field.type() == IPT_KEYBOARD) input_keyboard++; - else if (field->type() >= IPT_START1 && field->type() < IPT_UI_FIRST) + else if (field.type() >= IPT_START1 && field.type() < IPT_UI_FIRST) input++; - else if (field->type() == IPT_DIPSWITCH) + else if (field.type() == IPT_DIPSWITCH) { dips++; - dips_opt << " " << field->name(); - for (ioport_setting *setting = field->first_setting(); setting != nullptr; setting = setting->next()) + dips_opt << " " << field.name(); + for (ioport_setting &setting : field.settings()) { - if (setting->value() == field->defvalue()) + if (setting.value() == field.defvalue()) { - util::stream_format(dips_opt, " [default: %s]\n", setting->name()); + util::stream_format(dips_opt, " [default: %s]\n", setting.name()); break; } } } - else if (field->type() == IPT_CONFIG) + else if (field.type() == IPT_CONFIG) { confs++; - confs_opt << " " << field->name(); - for (ioport_setting *setting = field->first_setting(); setting != nullptr; setting = setting->next()) + confs_opt << " " << field.name(); + for (ioport_setting &setting : field.settings()) { - if (setting->value() == field->defvalue()) + if (setting.value() == field.defvalue()) { - util::stream_format(confs_opt, " [default: %s]\n", setting->name()); + util::stream_format(confs_opt, " [default: %s]\n", setting.name()); break; } } diff --git a/src/emu/ui/filesel.cpp b/src/emu/ui/filesel.cpp index 58b3d338ffe..7acab761ea5 100644 --- a/src/emu/ui/filesel.cpp +++ b/src/emu/ui/filesel.cpp @@ -275,7 +275,7 @@ void ui_menu_file_create::populate() item_append(_("New Image Name:"), new_image_name, 0, ITEMREF_NEW_IMAGE_NAME); // do we support multiple formats? - if (ENABLE_FORMATS) format = m_image->formatlist(); + if (ENABLE_FORMATS) format = m_image->formatlist().first(); if (ENABLE_FORMATS && (format != nullptr)) { item_append(_("Image Format:"), m_current_format->description(), 0, ITEMREF_FORMAT); diff --git a/src/emu/ui/inifile.cpp b/src/emu/ui/inifile.cpp index 33bd433a7f7..3324d56363e 100644 --- a/src/emu/ui/inifile.cpp +++ b/src/emu/ui/inifile.cpp @@ -231,21 +231,21 @@ void favorite_manager::add_favorite_game() if (swinfo->parentname()) { software_list_device *swlist = software_list_device::find_by_name(machine().config(), image->software_list_name()); - for (software_info *c_swinfo = swlist->first_software_info(); c_swinfo != nullptr; c_swinfo = c_swinfo->next()) + for (software_info &c_swinfo : swlist->get_info()) { - std::string c_parent(c_swinfo->parentname()); + std::string c_parent(c_swinfo.parentname()); if (!c_parent.empty() && c_parent == swinfo->shortname()) { - tmpmatches.parentlongname = c_swinfo->longname(); + tmpmatches.parentlongname = c_swinfo.longname(); break; } } } tmpmatches.usage.clear(); - for (feature_list_item *flist = swinfo->other_info(); flist != nullptr; flist = flist->next()) - if (!strcmp(flist->name(), "usage")) - tmpmatches.usage = flist->value(); + for (feature_list_item &flist : swinfo->other_info()) + if (!strcmp(flist.name(), "usage")) + tmpmatches.usage = flist.value(); tmpmatches.devicetype = strensure(image->image_type_name()); tmpmatches.available = true; diff --git a/src/emu/ui/inputmap.cpp b/src/emu/ui/inputmap.cpp index df146fcf3e1..616e3e80bfa 100644 --- a/src/emu/ui/inputmap.cpp +++ b/src/emu/ui/inputmap.cpp @@ -100,10 +100,10 @@ void ui_menu_input_general::populate() suborder[SEQ_TYPE_INCREMENT] = 2; /* iterate over the input ports and add menu items */ - for (input_type_entry *entry = machine().ioport().first_type(); entry != nullptr; entry = entry->next()) + for (input_type_entry &entry : machine().ioport().types()) /* add if we match the group and we have a valid name */ - if (entry->group() == group && entry->name() != nullptr && entry->name()[0] != 0) + if (entry.group() == group && entry.name() != nullptr && entry.name()[0] != 0) { input_seq_type seqtype; @@ -114,15 +114,15 @@ void ui_menu_input_general::populate() /* build an entry for the standard sequence */ input_item_data *item = (input_item_data *)m_pool_alloc(sizeof(*item)); memset(item, 0, sizeof(*item)); - item->ref = entry; - if(pollingitem && pollingref == entry && pollingseq == seqtype) + item->ref = &entry; + if(pollingitem && pollingref == &entry && pollingseq == seqtype) pollingitem = item; item->seqtype = seqtype; - item->seq = machine().ioport().type_seq(entry->type(), entry->player(), seqtype); - item->defseq = &entry->defseq(seqtype); + item->seq = machine().ioport().type_seq(entry.type(), entry.player(), seqtype); + item->defseq = &entry.defseq(seqtype); item->sortorder = sortorder * 4 + suborder[seqtype]; - item->type = ioport_manager::type_is_analog(entry->type()) ? (INPUT_TYPE_ANALOG + seqtype) : INPUT_TYPE_DIGITAL; - item->name = entry->name(); + item->type = ioport_manager::type_is_analog(entry.type()) ? (INPUT_TYPE_ANALOG + seqtype) : INPUT_TYPE_DIGITAL; + item->name = entry.name(); item->owner_name = nullptr; item->next = itemlist; itemlist = item; @@ -162,29 +162,29 @@ void ui_menu_input_specific::populate() suborder[SEQ_TYPE_INCREMENT] = 2; /* iterate over the input ports and add menu items */ - for (ioport_port *port = machine().ioport().first_port(); port != nullptr; port = port->next()) + for (ioport_port &port : machine().ioport().ports()) { port_count++; - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + for (ioport_field &field : port.fields()) { - const char *name = field->name(); + const char *name = field.name(); /* add if we match the group and we have a valid name */ - if (name != nullptr && field->enabled() && - ((field->type() == IPT_OTHER && field->name() != nullptr) || machine().ioport().type_group(field->type(), field->player()) != IPG_INVALID)) + if (name != nullptr && field.enabled() && + ((field.type() == IPT_OTHER && field.name() != nullptr) || machine().ioport().type_group(field.type(), field.player()) != IPG_INVALID)) { input_seq_type seqtype; UINT32 sortorder; /* determine the sorting order */ - if (field->type() >= IPT_START1 && field->type() < IPT_ANALOG_LAST) + if (field.type() >= IPT_START1 && field.type() < IPT_ANALOG_LAST) { - sortorder = (field->type() << 2) | (field->player() << 12); - if (strcmp(field->device().tag(), ":")) + sortorder = (field.type() << 2) | (field.player() << 12); + if (strcmp(field.device().tag(), ":")) sortorder |= (port_count & 0xfff) * 0x10000; } else - sortorder = field->type() | 0xf000; + sortorder = field.type() | 0xf000; /* loop over all sequence types */ for (seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) @@ -192,16 +192,16 @@ void ui_menu_input_specific::populate() /* build an entry for the standard sequence */ input_item_data *item = (input_item_data *)m_pool_alloc(sizeof(*item)); memset(item, 0, sizeof(*item)); - item->ref = field; + item->ref = &field; item->seqtype = seqtype; - if(pollingitem && pollingref == field && pollingseq == seqtype) + if(pollingitem && pollingref == item->ref && pollingseq == seqtype) pollingitem = item; - item->seq = field->seq(seqtype); - item->defseq = &field->defseq(seqtype); + item->seq = field.seq(seqtype); + item->defseq = &field.defseq(seqtype); item->sortorder = sortorder + suborder[seqtype]; - item->type = field->is_analog() ? (INPUT_TYPE_ANALOG + seqtype) : INPUT_TYPE_DIGITAL; + item->type = field.is_analog() ? (INPUT_TYPE_ANALOG + seqtype) : INPUT_TYPE_DIGITAL; item->name = name; - item->owner_name = field->device().tag(); + item->owner_name = field.device().tag(); item->next = itemlist; itemlist = item; @@ -537,8 +537,6 @@ ui_menu_settings::ui_menu_settings(running_machine &machine, render_container *c void ui_menu_settings::populate() { - ioport_field *field; - ioport_port *port; dip_descriptor **diplist_tailptr; std::string prev_owner; bool first_entry = true; @@ -549,51 +547,50 @@ void ui_menu_settings::populate() diplist_tailptr = &diplist; /* loop over input ports and set up the current values */ - for (port = machine().ioport().first_port(); port != nullptr; port = port->next()) - for (field = port->first_field(); field != nullptr; field = field->next()) - if (field->type() == type && field->enabled()) + for (ioport_port &port : machine().ioport().ports()) + for (ioport_field &field : port.fields()) + if (field.type() == type && field.enabled()) { UINT32 flags = 0; /* set the left/right flags appropriately */ - if (field->has_previous_setting()) + if (field.has_previous_setting()) flags |= MENU_FLAG_LEFT_ARROW; - if (field->has_next_setting()) + if (field.has_next_setting()) flags |= MENU_FLAG_RIGHT_ARROW; /* add the menu item */ - if (strcmp(field->device().tag(), prev_owner.c_str()) != 0) + if (strcmp(field.device().tag(), prev_owner.c_str()) != 0) { if (first_entry) first_entry = false; else item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); - string_format("[root%s]", field->device().tag()); - item_append(string_format("[root%s]", field->device().tag()).c_str(), nullptr, 0, nullptr); - prev_owner.assign(field->device().tag()); + string_format("[root%s]", field.device().tag()); + item_append(string_format("[root%s]", field.device().tag()).c_str(), nullptr, 0, nullptr); + prev_owner.assign(field.device().tag()); } - item_append(field->name(), field->setting_name(), flags, (void *)field); + item_append(field.name(), field.setting_name(), flags, (void *)&field); /* for DIP switches, build up the model */ - if (type == IPT_DIPSWITCH && field->first_diplocation() != nullptr) + if (type == IPT_DIPSWITCH && !field.diplocations().empty()) { - const ioport_diplocation *diploc; ioport_field::user_settings settings; - UINT32 accummask = field->mask(); + UINT32 accummask = field.mask(); /* get current settings */ - field->get_user_settings(settings); + field.get_user_settings(settings); /* iterate over each bit in the field */ - for (diploc = field->first_diplocation(); diploc != nullptr; diploc = diploc->next()) + for (const ioport_diplocation &diploc : field.diplocations()) { UINT32 mask = accummask & ~(accummask - 1); dip_descriptor *dip; /* find the matching switch name */ for (dip = diplist; dip != nullptr; dip = dip->next) - if (strcmp(dip->name, diploc->name()) == 0) + if (strcmp(dip->name, diploc.name()) == 0) break; /* allocate new if none */ @@ -601,7 +598,7 @@ void ui_menu_settings::populate() { dip = (dip_descriptor *)m_pool_alloc(sizeof(*dip)); dip->next = nullptr; - dip->name = diploc->name(); + dip->name = diploc.name(); dip->mask = dip->state = 0; *diplist_tailptr = dip; diplist_tailptr = &dip->next; @@ -609,9 +606,9 @@ void ui_menu_settings::populate() } /* apply the bits */ - dip->mask |= 1 << (diploc->number() - 1); - if (((settings.value & mask) != 0 && !diploc->inverted()) || ((settings.value & mask) == 0 && diploc->inverted())) - dip->state |= 1 << (diploc->number() - 1); + dip->mask |= 1 << (diploc.number() - 1); + if (((settings.value & mask) != 0 && !diploc.inverted()) || ((settings.value & mask) == 0 && diploc.inverted())) + dip->state |= 1 << (diploc.number() - 1); /* clear the relevant bit in the accumulated mask */ accummask &= ~mask; @@ -651,7 +648,6 @@ void ui_menu_settings_dip_switches::custom_render(void *selectedref, float top, // iterate over DIP switches for (dip_descriptor *dip = diplist; dip != nullptr; dip = dip->next) { - const ioport_diplocation *diploc; UINT32 selectedmask = 0; // determine the mask of selected bits @@ -659,10 +655,10 @@ void ui_menu_settings_dip_switches::custom_render(void *selectedref, float top, { ioport_field *field = (ioport_field *)selectedref; - if (field != nullptr && field->first_diplocation() != nullptr) - for (diploc = field->first_diplocation(); diploc != nullptr; diploc = diploc->next()) - if (strcmp(dip->name, diploc->name()) == 0) - selectedmask |= 1 << (diploc->number() - 1); + if (field != nullptr && !field->diplocations().empty()) + for (const ioport_diplocation &diploc : field->diplocations()) + if (strcmp(dip->name, diploc.name()) == 0) + selectedmask |= 1 << (diploc.number() - 1); } // draw one switch @@ -815,28 +811,26 @@ ui_menu_analog::ui_menu_analog(running_machine &machine, render_container *conta void ui_menu_analog::populate() { - ioport_field *field; - ioport_port *port; std::string text; std::string subtext; std::string prev_owner; bool first_entry = true; /* loop over input ports and add the items */ - for (port = machine().ioport().first_port(); port != nullptr; port = port->next()) - for (field = port->first_field(); field != nullptr; field = field->next()) - if (field->is_analog() && field->enabled()) + for (ioport_port &port : machine().ioport().ports()) + for (ioport_field &field : port.fields()) + if (field.is_analog() && field.enabled()) { ioport_field::user_settings settings; int use_autocenter = false; int type; /* based on the type, determine if we enable autocenter */ - switch (field->type()) + switch (field.type()) { case IPT_POSITIONAL: case IPT_POSITIONAL_V: - if (field->analog_wraps()) + if (field.analog_wraps()) break; case IPT_AD_STICK_X: @@ -855,7 +849,7 @@ void ui_menu_analog::populate() } /* get the user settings */ - field->get_user_settings(settings); + field.get_user_settings(settings); /* iterate over types */ for (type = 0; type < ANALOG_ITEM_COUNT; type++) @@ -863,19 +857,19 @@ void ui_menu_analog::populate() { analog_item_data *data; UINT32 flags = 0; - if (strcmp(field->device().tag(), prev_owner.c_str()) != 0) + if (strcmp(field.device().tag(), prev_owner.c_str()) != 0) { if (first_entry) first_entry = false; else item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); - item_append(string_format("[root%s]", field->device().tag()).c_str(), nullptr, 0, nullptr); - prev_owner.assign(field->device().tag()); + item_append(string_format("[root%s]", field.device().tag()).c_str(), nullptr, 0, nullptr); + prev_owner.assign(field.device().tag()); } /* allocate a data item for tracking what this menu item refers to */ data = (analog_item_data *)m_pool_alloc(sizeof(*data)); - data->field = field; + data->field = &field; data->type = type; /* determine the properties of this item */ @@ -883,39 +877,39 @@ void ui_menu_analog::populate() { default: case ANALOG_ITEM_KEYSPEED: - text = string_format("%s Digital Speed", field->name()); + text = string_format("%s Digital Speed", field.name()); subtext = string_format("%d", settings.delta); data->min = 0; data->max = 255; data->cur = settings.delta; - data->defvalue = field->delta(); + data->defvalue = field.delta(); break; case ANALOG_ITEM_CENTERSPEED: - text = string_format("%s Autocenter Speed", field->name()); + text = string_format("%s Autocenter Speed", field.name()); subtext = string_format("%d", settings.centerdelta); data->min = 0; data->max = 255; data->cur = settings.centerdelta; - data->defvalue = field->centerdelta(); + data->defvalue = field.centerdelta(); break; case ANALOG_ITEM_REVERSE: - text = string_format("%s Reverse", field->name()); + text = string_format("%s Reverse", field.name()); subtext.assign(settings.reverse ? "On" : "Off"); data->min = 0; data->max = 1; data->cur = settings.reverse; - data->defvalue = field->analog_reverse(); + data->defvalue = field.analog_reverse(); break; case ANALOG_ITEM_SENSITIVITY: - text = string_format("%s Sensitivity", field->name()); + text = string_format("%s Sensitivity", field.name()); subtext = string_format("%d", settings.sensitivity); data->min = 1; data->max = 255; data->cur = settings.sensitivity; - data->defvalue = field->sensitivity(); + data->defvalue = field.sensitivity(); break; } diff --git a/src/emu/ui/miscmenu.cpp b/src/emu/ui/miscmenu.cpp index 3846244d73e..edca54ebd20 100644 --- a/src/emu/ui/miscmenu.cpp +++ b/src/emu/ui/miscmenu.cpp @@ -942,13 +942,13 @@ void ui_menu_plugins_configure::populate() { plugin_options& plugins = machine().manager().plugins(); - for (auto curentry = plugins.first(); curentry != nullptr; curentry = curentry->next()) + for (auto &curentry : plugins) { - if (!curentry->is_header()) + if (!curentry.is_header()) { - auto enabled = std::string(curentry->value()) == "1"; - item_append(curentry->description(), enabled ? _("On") : _("Off"), - enabled ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW, (void *)(FPTR)curentry->name()); + auto enabled = std::string(curentry.value()) == "1"; + item_append(curentry.description(), enabled ? _("On") : _("Off"), + enabled ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW, (void *)(FPTR)curentry.name()); } } item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); diff --git a/src/emu/ui/optsmenu.cpp b/src/emu/ui/optsmenu.cpp index a87de984694..fef44b8e542 100644 --- a/src/emu/ui/optsmenu.cpp +++ b/src/emu/ui/optsmenu.cpp @@ -346,11 +346,11 @@ void save_main_option(running_machine &machine) } } - for (emu_options::entry *f_entry = machine.options().first(); f_entry != nullptr; f_entry = f_entry->next()) + for (emu_options::entry &f_entry : machine.options()) { - if (f_entry->is_changed()) + if (f_entry.is_changed()) { - options.set_value(f_entry->name(), f_entry->value(), OPTION_PRIORITY_CMDLINE, error_string); + options.set_value(f_entry.name(), f_entry.value(), OPTION_PRIORITY_CMDLINE, error_string); } } diff --git a/src/emu/ui/selgame.cpp b/src/emu/ui/selgame.cpp index 28b3a295b05..1ac26804bb5 100644 --- a/src/emu/ui/selgame.cpp +++ b/src/emu/ui/selgame.cpp @@ -1038,7 +1038,7 @@ void ui_menu_select_game::inkey_select(const ui_menu_event *m_event) { software_list_device_iterator iter(enumerator.config().root_device()); for (software_list_device *swlistdev = iter.first(); swlistdev != nullptr; swlistdev = iter.next()) - if (swlistdev->first_software_info() != nullptr) + if (!swlistdev->get_info().empty()) { ui_menu::stack_push(global_alloc_clear(machine(), container, driver)); return; @@ -1149,14 +1149,14 @@ void ui_menu_select_game::inkey_select_favorite(const ui_menu_event *m_event) else if (!mopt.skip_parts_menu() && swinfo->has_multiple_parts(ui_swinfo->interface.c_str())) { s_parts parts; - for (const software_part *swpart = swinfo->first_part(); swpart != nullptr; swpart = swpart->next()) + for (const software_part &swpart : swinfo->parts()) { - if (swpart->matches_interface(ui_swinfo->interface.c_str())) + if (swpart.matches_interface(ui_swinfo->interface.c_str())) { - std::string menu_part_name(swpart->name()); - if (swpart->feature("part_id") != nullptr) - menu_part_name.assign("(").append(swpart->feature("part_id")).append(")"); - parts.emplace(swpart->name(), menu_part_name); + std::string menu_part_name(swpart.name()); + if (swpart.feature("part_id") != nullptr) + menu_part_name.assign("(").append(swpart.feature("part_id")).append(")"); + parts.emplace(swpart.name(), menu_part_name); } } ui_menu::stack_push(global_alloc_clear(machine(), container, parts, ui_swinfo)); diff --git a/src/emu/ui/selsoft.cpp b/src/emu/ui/selsoft.cpp index 050b9409061..0022297f6c8 100644 --- a/src/emu/ui/selsoft.cpp +++ b/src/emu/ui/selsoft.cpp @@ -533,9 +533,9 @@ void ui_menu_select_software::build_software_list() { m_filter.swlist.name.push_back(swlist->list_name()); m_filter.swlist.description.push_back(swlist->description()); - for (software_info *swinfo = swlist->first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) + for (software_info &swinfo : swlist->get_info()) { - software_part *part = swinfo->first_part(); + software_part *part = swinfo.first_part(); if (part->is_compatible(*swlist)) { const char *instance_name = nullptr; @@ -561,12 +561,12 @@ void ui_menu_select_software::build_software_list() if (instance_name == nullptr || type_name == nullptr) continue; - tmpmatches.shortname = strensure(swinfo->shortname()); - tmpmatches.longname = strensure(swinfo->longname()); - tmpmatches.parentname = strensure(swinfo->parentname()); - tmpmatches.year = strensure(swinfo->year()); - tmpmatches.publisher = strensure(swinfo->publisher()); - tmpmatches.supported = swinfo->supported(); + tmpmatches.shortname = strensure(swinfo.shortname()); + tmpmatches.longname = strensure(swinfo.longname()); + tmpmatches.parentname = strensure(swinfo.parentname()); + tmpmatches.year = strensure(swinfo.year()); + tmpmatches.publisher = strensure(swinfo.publisher()); + tmpmatches.supported = swinfo.supported(); tmpmatches.part = strensure(part->name()); tmpmatches.driver = m_driver; tmpmatches.listname = strensure(swlist->list_name()); @@ -576,9 +576,9 @@ void ui_menu_select_software::build_software_list() tmpmatches.usage.clear(); tmpmatches.available = false; - for (feature_list_item *flist = swinfo->other_info(); flist != nullptr; flist = flist->next()) - if (!strcmp(flist->name(), "usage")) - tmpmatches.usage = flist->value(); + for (feature_list_item &flist : swinfo.other_info()) + if (!strcmp(flist.name(), "usage")) + tmpmatches.usage = flist.value(); m_swinfo.push_back(tmpmatches); m_filter.region.set(tmpmatches.longname); @@ -937,14 +937,14 @@ void ui_menu_select_software::inkey_select(const ui_menu_event *m_event) else if (!mopt.skip_parts_menu() && swinfo->has_multiple_parts(ui_swinfo->interface.c_str())) { s_parts parts; - for (const software_part *swpart = swinfo->first_part(); swpart != nullptr; swpart = swpart->next()) + for (const software_part &swpart : swinfo->parts()) { - if (swpart->matches_interface(ui_swinfo->interface.c_str())) + if (swpart.matches_interface(ui_swinfo->interface.c_str())) { - std::string menu_part_name(swpart->name()); - if (swpart->feature("part_id") != nullptr) - menu_part_name.assign("(").append(swpart->feature("part_id")).append(")"); - parts.emplace(swpart->name(), menu_part_name); + std::string menu_part_name(swpart.name()); + if (swpart.feature("part_id") != nullptr) + menu_part_name.assign("(").append(swpart.feature("part_id")).append(")"); + parts.emplace(swpart.name(), menu_part_name); } } ui_menu::stack_push(global_alloc_clear(machine(), container, parts, ui_swinfo)); @@ -2091,14 +2091,14 @@ void ui_bios_selection::handle() if (!machine().ui().options().skip_parts_menu() && swinfo->has_multiple_parts(ui_swinfo->interface.c_str())) { s_parts parts; - for (const software_part *swpart = swinfo->first_part(); swpart != nullptr; swpart = swpart->next()) + for (const software_part &swpart : swinfo->parts()) { - if (swpart->matches_interface(ui_swinfo->interface.c_str())) + if (swpart.matches_interface(ui_swinfo->interface.c_str())) { - std::string menu_part_name(swpart->name()); - if (swpart->feature("part_id") != nullptr) - menu_part_name.assign("(").append(swpart->feature("part_id")).append(")"); - parts.emplace(swpart->name(), menu_part_name); + std::string menu_part_name(swpart.name()); + if (swpart.feature("part_id") != nullptr) + menu_part_name.assign("(").append(swpart.feature("part_id")).append(")"); + parts.emplace(swpart.name(), menu_part_name); } } ui_menu::stack_push(global_alloc_clear(machine(), container, parts, ui_swinfo)); diff --git a/src/emu/ui/slotopt.cpp b/src/emu/ui/slotopt.cpp index c4fd58f754f..693c28a9ba8 100644 --- a/src/emu/ui/slotopt.cpp +++ b/src/emu/ui/slotopt.cpp @@ -45,12 +45,12 @@ int ui_menu_slot_devices::slot_get_current_index(device_slot_interface *slot) if (current != nullptr) { int val = 0; - for (const device_slot_option *option = slot->first_option(); option != nullptr; option = option->next()) + for (const device_slot_option &option : slot->option_list()) { - if (option == current) + if (&option == current) return val; - if (option->selectable()) + if (option.selectable()) val++; } } @@ -64,8 +64,8 @@ int ui_menu_slot_devices::slot_get_current_index(device_slot_interface *slot) int ui_menu_slot_devices::slot_get_length(device_slot_interface *slot) { int val = 0; - for (const device_slot_option *option = slot->first_option(); option != nullptr; option = option->next()) - if (option->selectable()) + for (const device_slot_option &option : slot->option_list()) + if (option.selectable()) val++; return val; @@ -113,12 +113,12 @@ const char *ui_menu_slot_devices::slot_get_option(device_slot_interface *slot, i if (index >= 0) { int val = 0; - for (const device_slot_option *option = slot->first_option(); option != nullptr; option = option->next()) + for (const device_slot_option &option : slot->option_list()) { if (val == index) - return option->name(); + return option.name(); - if (option->selectable()) + if (option.selectable()) val++; } } diff --git a/src/emu/ui/swlist.cpp b/src/emu/ui/swlist.cpp index 3c2595389b2..c66435e69dc 100644 --- a/src/emu/ui/swlist.cpp +++ b/src/emu/ui/swlist.cpp @@ -76,18 +76,18 @@ void ui_menu_software_parts::populate() item_append(_("[software list]"), nullptr, 0, entry3); } - for (const software_part *swpart = m_info->first_part(); swpart != nullptr; swpart = swpart->next()) + for (const software_part &swpart : m_info->parts()) { - if (swpart->matches_interface(m_interface)) + if (swpart.matches_interface(m_interface)) { software_part_menu_entry *entry = (software_part_menu_entry *) m_pool_alloc(sizeof(*entry)); // check if the available parts have specific part_id to be displayed (e.g. "Map Disc", "Bonus Disc", etc.) // if not, we simply display "part_name"; if yes we display "part_name (part_id)" - std::string menu_part_name(swpart->name()); - if (swpart->feature("part_id") != nullptr) - menu_part_name.append(" (").append(swpart->feature("part_id")).append(")"); + std::string menu_part_name(swpart.name()); + if (swpart.feature("part_id") != nullptr) + menu_part_name.append(" (").append(swpart.feature("part_id")).append(")"); entry->type = T_ENTRY; - entry->part = swpart; + entry->part = &swpart; item_append(m_info->shortname(), menu_part_name.c_str(), 0, entry); } } @@ -182,24 +182,24 @@ int ui_menu_software_list::compare_entries(const entry_info *e1, const entry_inf // append_software_entry - populate a specific list //------------------------------------------------- -ui_menu_software_list::entry_info *ui_menu_software_list::append_software_entry(const software_info *swinfo) +ui_menu_software_list::entry_info *ui_menu_software_list::append_software_entry(const software_info &swinfo) { entry_info *entry = nullptr; entry_info **entryptr; bool entry_updated = FALSE; // check if at least one of the parts has the correct interface and add a menu entry only in this case - for (const software_part *swpart = swinfo->first_part(); swpart != nullptr; swpart = swpart->next()) + for (const software_part &swpart : swinfo.parts()) { - if (swpart->matches_interface(m_interface) && swpart->is_compatible(*m_swlist)) + if (swpart.matches_interface(m_interface) && swpart.is_compatible(*m_swlist)) { entry_updated = TRUE; // allocate a new entry entry = (entry_info *) m_pool_alloc(sizeof(*entry)); memset(entry, 0, sizeof(*entry)); - entry->short_name = pool_strdup(swinfo->shortname()); - entry->long_name = pool_strdup(swinfo->longname()); + entry->short_name = pool_strdup(swinfo.shortname()); + entry->long_name = pool_strdup(swinfo.longname()); break; } } @@ -228,7 +228,7 @@ ui_menu_software_list::entry_info *ui_menu_software_list::append_software_entry( void ui_menu_software_list::populate() { // build up the list of entries for the menu - for (const software_info *swinfo = m_swlist->first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) + for (const software_info &swinfo : m_swlist->get_info()) append_software_entry(swinfo); // add an entry to change ordering @@ -411,11 +411,11 @@ void ui_menu_software::populate() software_list_device_iterator iter(machine().config().root_device()); for (software_list_device *swlistdev = iter.first(); swlistdev != nullptr; swlistdev = iter.next()) if (swlistdev->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM) - if (swlistdev->first_software_info() != nullptr && m_interface != nullptr) + if (!swlistdev->get_info().empty() && m_interface != nullptr) { bool found = false; - for (const software_info *swinfo = swlistdev->first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) - if (swinfo->first_part()->matches_interface(m_interface)) + for (const software_info &swinfo : swlistdev->get_info()) + if (swinfo.first_part()->matches_interface(m_interface)) found = true; if (found) item_append(swlistdev->description(), nullptr, 0, (void *)swlistdev); @@ -424,11 +424,11 @@ void ui_menu_software::populate() // add compatible software lists for this system for (software_list_device *swlistdev = iter.first(); swlistdev != nullptr; swlistdev = iter.next()) if (swlistdev->list_type() == SOFTWARE_LIST_COMPATIBLE_SYSTEM) - if (swlistdev->first_software_info() != nullptr && m_interface != nullptr) + if (!swlistdev->get_info().empty() && m_interface != nullptr) { bool found = false; - for (const software_info *swinfo = swlistdev->first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) - if (swinfo->first_part()->matches_interface(m_interface)) + for (const software_info &swinfo : swlistdev->get_info()) + if (swinfo.first_part()->matches_interface(m_interface)) found = true; if (found) { diff --git a/src/emu/ui/swlist.h b/src/emu/ui/swlist.h index 944aeadf6c5..253eeb6e7c8 100644 --- a/src/emu/ui/swlist.h +++ b/src/emu/ui/swlist.h @@ -63,7 +63,7 @@ private: // functions int compare_entries(const entry_info *e1, const entry_info *e2, bool shortname); - entry_info *append_software_entry(const software_info *swinfo); + entry_info *append_software_entry(const software_info &swinfo); }; diff --git a/src/emu/ui/ui.cpp b/src/emu/ui/ui.cpp index 0b15f24edc6..9bb27762c3b 100644 --- a/src/emu/ui/ui.cpp +++ b/src/emu/ui/ui.cpp @@ -1905,8 +1905,6 @@ static slider_state *slider_alloc(running_machine &machine, const char *title, I static slider_state *slider_init(running_machine &machine) { - ioport_field *field; - ioport_port *port; slider_state *listhead = nullptr; slider_state **tailptr = &listhead; std::string str; @@ -1929,12 +1927,12 @@ static slider_state *slider_init(running_machine &machine) } // add analog adjusters - for (port = machine.ioport().first_port(); port != nullptr; port = port->next()) - for (field = port->first_field(); field != nullptr; field = field->next()) - if (field->type() == IPT_ADJUSTER) + for (ioport_port &port : machine.ioport().ports()) + for (ioport_field &field : port.fields()) + if (field.type() == IPT_ADJUSTER) { - void *param = (void *)field; - *tailptr = slider_alloc(machine, field->name(), field->minval(), field->defvalue(), field->maxval(), 1, slider_adjuster, param); + void *param = (void *)&field; + *tailptr = slider_alloc(machine, field.name(), field.minval(), field.defvalue(), field.maxval(), 1, slider_adjuster, param); tailptr = &(*tailptr)->next; } @@ -2040,15 +2038,15 @@ static slider_state *slider_init(running_machine &machine) #ifdef MAME_DEBUG // add crosshair adjusters - for (port = machine.ioport().first_port(); port != nullptr; port = port->next()) - for (field = port->first_field(); field != nullptr; field = field->next()) - if (field->crosshair_axis() != CROSSHAIR_AXIS_NONE && field->player() == 0) + for (ioport_port &port : machine.ioport().ports()) + for (ioport_field &field : port.fields()) + if (field.crosshair_axis() != CROSSHAIR_AXIS_NONE && field.player() == 0) { - void *param = (void *)field; - str = string_format(_("Crosshair Scale %1$s"), (field->crosshair_axis() == CROSSHAIR_AXIS_X) ? _("X") : _("Y")); + void *param = (void *)&field; + str = string_format(_("Crosshair Scale %1$s"), (field.crosshair_axis() == CROSSHAIR_AXIS_X) ? _("X") : _("Y")); *tailptr = slider_alloc(machine, str.c_str(), -3000, 1000, 3000, 100, slider_crossscale, param); tailptr = &(*tailptr)->next; - str = string_format(_("Crosshair Offset %1$s"), (field->crosshair_axis() == CROSSHAIR_AXIS_X) ? _("X") : _("Y")); + str = string_format(_("Crosshair Offset %1$s"), (field.crosshair_axis() == CROSSHAIR_AXIS_X) ? _("X") : _("Y")); *tailptr = slider_alloc(machine, str.c_str(), -3000, 0, 3000, 100, slider_crossoffset, param); tailptr = &(*tailptr)->next; } diff --git a/src/emu/validity.cpp b/src/emu/validity.cpp index 7feb39a1a71..bfe5c40221e 100644 --- a/src/emu/validity.cpp +++ b/src/emu/validity.cpp @@ -751,30 +751,30 @@ void validity_checker::validate_dip_settings(ioport_field &field) bool coin_error = false; // iterate through the settings - for (ioport_setting *setting = field.first_setting(); setting != nullptr; setting = setting->next()) + for (ioport_setting &setting : field.settings()) { // note any coinage strings - int strindex = get_defstr_index(setting->name()); + int strindex = get_defstr_index(setting.name()); if (strindex >= __input_string_coinage_start && strindex <= __input_string_coinage_end) coin_list[strindex - __input_string_coinage_start] = 1; // make sure demo sounds default to on - if (field.name() == demo_sounds && strindex == INPUT_STRING_On && field.defvalue() != setting->value()) + if (field.name() == demo_sounds && strindex == INPUT_STRING_On && field.defvalue() != setting.value()) osd_printf_error("Demo Sounds must default to On\n"); // check for bad demo sounds options if (field.name() == demo_sounds && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No)) - osd_printf_error("Demo Sounds option must be Off/On, not %s\n", setting->name()); + osd_printf_error("Demo Sounds option must be Off/On, not %s\n", setting.name()); // check for bad flip screen options if (field.name() == flipscreen && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No)) - osd_printf_error("Flip Screen option must be Off/On, not %s\n", setting->name()); + osd_printf_error("Flip Screen option must be Off/On, not %s\n", setting.name()); // if we have a neighbor, compare ourselves to him - if (setting->next() != nullptr) + if (setting.next() != nullptr) { // check for inverted off/on dispswitch order - int next_strindex = get_defstr_index(setting->next()->name(), true); + int next_strindex = get_defstr_index(setting.next()->name(), true); if (strindex == INPUT_STRING_On && next_strindex == INPUT_STRING_Off) osd_printf_error("%s option must have Off/On options in the order: Off, On\n", field.name()); @@ -788,9 +788,9 @@ void validity_checker::validate_dip_settings(ioport_field &field) // check for proper coin ordering else if (strindex >= __input_string_coinage_start && strindex <= __input_string_coinage_end && next_strindex >= __input_string_coinage_start && next_strindex <= __input_string_coinage_end && - strindex >= next_strindex && setting->condition() == setting->next()->condition()) + strindex >= next_strindex && setting.condition() == setting.next()->condition()) { - osd_printf_error("%s option has unsorted coinage %s > %s\n", field.name(), setting->name(), setting->next()->name()); + osd_printf_error("%s option has unsorted coinage %s > %s\n", field.name(), setting.name(), setting.next()->name()); coin_error = true; } } @@ -850,39 +850,39 @@ void validity_checker::validate_inputs() osd_printf_error("I/O port error during construction:\n%s\n", errorbuf.c_str()); // do a first pass over ports to add their names and find duplicates - for (ioport_port *port = portlist.first(); port != nullptr; port = port->next()) - if (!port_map.insert(port->tag()).second) - osd_printf_error("Multiple I/O ports with the same tag '%s' defined\n", port->tag()); + for (ioport_port &port : portlist) + if (!port_map.insert(port.tag()).second) + osd_printf_error("Multiple I/O ports with the same tag '%s' defined\n", port.tag()); // iterate over ports - for (ioport_port *port = portlist.first(); port != nullptr; port = port->next()) + for (ioport_port &port : portlist) { - m_current_ioport = port->tag(); + m_current_ioport = port.tag(); // iterate through the fields on this port - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + for (ioport_field &field : port.fields()) { // verify analog inputs - if (field->is_analog()) - validate_analog_input_field(*field); + if (field.is_analog()) + validate_analog_input_field(field); // look for invalid (0) types which should be mapped to IPT_OTHER - if (field->type() == IPT_INVALID) + if (field.type() == IPT_INVALID) osd_printf_error("Field has an invalid type (0); use IPT_OTHER instead\n"); // verify dip switches - if (field->type() == IPT_DIPSWITCH) + if (field.type() == IPT_DIPSWITCH) { // dip switch fields must have a name - if (field->name() == nullptr) + if (field.name() == nullptr) osd_printf_error("DIP switch has a NULL name\n"); // verify the settings list - validate_dip_settings(*field); + validate_dip_settings(field); } // verify names - const char *name = field->specific_name(); + const char *name = field.specific_name(); if (name != nullptr) { // check for empty string @@ -902,13 +902,13 @@ void validity_checker::validate_inputs() } // verify conditions on the field - if (!field->condition().none()) - validate_condition(field->condition(), *device, port_map); + if (!field.condition().none()) + validate_condition(field.condition(), *device, port_map); // verify conditions on the settings - for (ioport_setting *setting = field->first_setting(); setting != nullptr; setting = setting->next()) - if (!setting->condition().none()) - validate_condition(setting->condition(), *device, port_map); + for (ioport_setting &setting : field.settings()) + if (!setting.condition().none()) + validate_condition(setting.condition(), *device, port_map); } // done with this port @@ -966,11 +966,11 @@ void validity_checker::validate_devices() slot_interface_iterator slotiter(m_current_config->root_device()); for (const device_slot_interface *slot = slotiter.first(); slot != nullptr; slot = slotiter.next()) { - for (const device_slot_option *option = slot->first_option(); option != nullptr; option = option->next()) + for (const device_slot_option &option : slot->option_list()) { std::string temptag("_"); - temptag.append(option->name()); - device_t *dev = const_cast(*m_current_config).device_add(&m_current_config->root_device(), temptag.c_str(), option->devtype(), 0); + temptag.append(option.name()); + device_t *dev = const_cast(*m_current_config).device_add(&m_current_config->root_device(), temptag.c_str(), option.devtype(), 0); // notify this device and all its subdevices that they are now configured device_iterator subiter(*dev); diff --git a/src/lib/util/coretmpl.h b/src/lib/util/coretmpl.h index 9201041b2d9..48a9dfe68d6 100644 --- a/src/lib/util/coretmpl.h +++ b/src/lib/util/coretmpl.h @@ -40,6 +40,23 @@ typedef std::vector dynamic_buffer; template class simple_list final { + class auto_iterator + { +public: + // construction/destruction + auto_iterator(_ElementType *ptr) noexcept : m_current(ptr) { } + + // required operator overrides + bool operator!=(const auto_iterator &iter) const noexcept { return m_current != iter.m_current; } + _ElementType &operator*() const noexcept { return *m_current; } + // note that _ElementType::next() must not return a const ptr + const auto_iterator &operator++() noexcept { m_current = m_current->next(); return *this; } + +private: + // private state + _ElementType *m_current; + }; + public: // we don't support deep copying simple_list(const simple_list &) = delete; @@ -57,16 +74,21 @@ public: _ElementType *first() const noexcept { return m_head; } _ElementType *last() const noexcept { return m_tail; } int count() const noexcept { return m_count; } + bool empty() const noexcept { return m_count == 0; } + + // range iterators + auto begin() const noexcept { return auto_iterator(m_head); } + auto end() const noexcept { return auto_iterator(nullptr); } // remove (free) all objects in the list, leaving an empty list - void reset() + void reset() noexcept { while (m_head != nullptr) remove(*m_head); } // add the given object to the head of the list - _ElementType &prepend(_ElementType &object) + _ElementType &prepend(_ElementType &object) noexcept { object.m_next = m_head; m_head = &object; diff --git a/src/lib/util/options.cpp b/src/lib/util/options.cpp index 9890ae46115..7e8b993c0b2 100644 --- a/src/lib/util/options.cpp +++ b/src/lib/util/options.cpp @@ -226,11 +226,11 @@ core_options &core_options::operator=(const core_options &rhs) bool core_options::operator==(const core_options &rhs) { // iterate over options in the first list - for (entry *curentry = m_entrylist.first(); curentry != nullptr; curentry = curentry->next()) - if (!curentry->is_header()) + for (entry &curentry : m_entrylist) + if (!curentry.is_header()) { // if the values differ, return false - if (strcmp(curentry->value(), rhs.value(curentry->name())) != 0) + if (strcmp(curentry.value(), rhs.value(curentry.name())) != 0) return false; } @@ -468,8 +468,8 @@ bool core_options::parse_ini_file(util::core_file &inifile, int priority, int ig void core_options::revert(int priority) { // iterate over options and revert to defaults if below the given priority - for (entry *curentry = m_entrylist.first(); curentry != nullptr; curentry = curentry->next()) - curentry->revert(priority); + for (entry &curentry : m_entrylist) + curentry.revert(priority); } @@ -489,10 +489,10 @@ std::string core_options::output_ini(const core_options *diff) const const char *last_header = nullptr; // loop over all items - for (entry *curentry = m_entrylist.first(); curentry != nullptr; curentry = curentry->next()) + for (entry &curentry : m_entrylist) { - const char *name = curentry->name(); - const char *value = curentry->value(); + const char *name = curentry.name(); + const char *value = curentry.value(); bool is_unadorned = false; // check if it's unadorned @@ -503,13 +503,13 @@ std::string core_options::output_ini(const core_options *diff) const } // header: record description - if (curentry->is_header()) - last_header = curentry->description(); + if (curentry.is_header()) + last_header = curentry.description(); // otherwise, output entries for all non-command items - else if (!curentry->is_command()) + else if (!curentry.is_command()) { - if ( !curentry->is_internal() ) + if (!curentry.is_internal()) { // look up counterpart in diff, if diff is specified if (diff == nullptr || strcmp(value, diff->value(name)) != 0) @@ -549,15 +549,15 @@ std::string core_options::output_help() const std::ostringstream buffer; // loop over all items - for (entry *curentry = m_entrylist.first(); curentry != nullptr; curentry = curentry->next()) + for (entry &curentry : m_entrylist) { // header: just print - if (curentry->is_header()) - util::stream_format(buffer, "\n#\n# %s\n#\n", curentry->description()); + if (curentry.is_header()) + util::stream_format(buffer, "\n#\n# %s\n#\n", curentry.description()); // otherwise, output entries for all non-deprecated items - else if (curentry->description() != nullptr) - util::stream_format(buffer, "-%-20s%s\n", curentry->name(), curentry->description()); + else if (curentry.description() != nullptr) + util::stream_format(buffer, "-%-20s%s\n", curentry.name(), curentry.description()); } return buffer.str(); } @@ -744,8 +744,8 @@ void core_options::copyfrom(const core_options &src) reset(); // iterate through the src options and make our own - for (entry *curentry = src.m_entrylist.first(); curentry != nullptr; curentry = curentry->next()) - append_entry(*global_alloc(entry(curentry->name(), curentry->description(), curentry->flags(), curentry->default_value()))); + for (entry &curentry : src.m_entrylist) + append_entry(*global_alloc(entry(curentry.name(), curentry.description(), curentry.flags(), curentry.default_value()))); } /** diff --git a/src/lib/util/options.h b/src/lib/util/options.h index 4ffdf00ae35..56cdbf90c1f 100644 --- a/src/lib/util/options.h +++ b/src/lib/util/options.h @@ -132,6 +132,10 @@ public: entry *first() const { return m_entrylist.first(); } const char *command() const { return m_command.c_str(); } + // range iterators + auto begin() const { return m_entrylist.begin(); } + auto end() const { return m_entrylist.end(); } + // configuration void add_entry(const char *name, const char *description, UINT32 flags = 0, const char *defvalue = nullptr, bool override_existing = false); void add_entry(const options_entry &data, bool override_existing = false) { add_entry(data.name, data.description, data.flags, data.defvalue, override_existing); } diff --git a/src/lib/util/tagmap.h b/src/lib/util/tagmap.h index cdbaf63d7fe..94de6c55879 100644 --- a/src/lib/util/tagmap.h +++ b/src/lib/util/tagmap.h @@ -56,6 +56,11 @@ public: _ElementType *first() const { return m_list.first(); } _ElementType *last() const { return m_list.last(); } int count() const { return m_list.count(); } + bool empty() const { return m_list.empty(); } + + // range iterators + auto begin() const { return m_list.begin(); } + auto end() const { return m_list.end(); } // remove (free) all objects in the list, leaving an empty list void reset() { m_list.reset(); m_map.clear(); } diff --git a/src/mame/drivers/besta.cpp b/src/mame/drivers/besta.cpp index 86f81074a68..042c723027a 100644 --- a/src/mame/drivers/besta.cpp +++ b/src/mame/drivers/besta.cpp @@ -87,7 +87,7 @@ WRITE8_MEMBER( besta_state::mpcc_reg_w ) m_term_data = data; break; case 10: - dynamic_cast(devconf)->write(*machine().memory().first_space(), 0, data); + dynamic_cast(devconf)->write(generic_space(), 0, data); default: m_mpcc_regs[offset] = data; break; diff --git a/src/mame/drivers/galaxian.cpp b/src/mame/drivers/galaxian.cpp index 7c9b7fff23c..0ec73f982b8 100644 --- a/src/mame/drivers/galaxian.cpp +++ b/src/mame/drivers/galaxian.cpp @@ -6351,7 +6351,7 @@ DRIVER_INIT_MEMBER(galaxian_state,gmgalax) membank("bank1")->configure_entries(0, 2, memregion("maincpu")->base() + 0x10000, 0x4000); /* callback when the game select is toggled */ - gmgalax_game_changed(*machine().ioport().first_port()->first_field(), nullptr, 0, 0); + gmgalax_game_changed(*machine().ioport().ports().first()->fields().first(), nullptr, 0, 0); save_item(NAME(m_gmgalax_selected_game)); } diff --git a/src/mame/drivers/pasogo.cpp b/src/mame/drivers/pasogo.cpp index dad0174a079..463e2de34d2 100644 --- a/src/mame/drivers/pasogo.cpp +++ b/src/mame/drivers/pasogo.cpp @@ -528,7 +528,7 @@ void pasogo_state::machine_reset() membank("bank27")->set_base(m_cart_rom->base()); m_ems_index = 0; memset(m_ems_bank, 0, sizeof(m_ems_bank)); - contrast(*color->first_field(), nullptr, 0, color->read()); + contrast(*color->fields().first(), nullptr, 0, color->read()); } static MACHINE_CONFIG_START( pasogo, pasogo_state ) diff --git a/src/osd/modules/debugger/debugwin.cpp b/src/osd/modules/debugger/debugwin.cpp index 634332899c3..3c85b5f4119 100644 --- a/src/osd/modules/debugger/debugwin.cpp +++ b/src/osd/modules/debugger/debugwin.cpp @@ -163,8 +163,8 @@ void debugger_windows::debugger_update() debug_cpu_get_visible_cpu(*m_machine)->debug()->halt_on_next_instruction("User-initiated break\n"); // if we were focused on some window's edit box, reset it to default - for (debugwin_info *info = m_window_list.first(); info != NULL; info = info->next()) - info->restore_field(focuswnd); + for (debugwin_info &info : m_window_list) + info.restore_field(focuswnd); } } } @@ -229,16 +229,16 @@ void debugger_windows::remove_window(debugwin_info &info) void debugger_windows::show_all() { - for (debugwin_info *info = m_window_list.first(); info != NULL; info = info->next()) - info->show(); + for (debugwin_info &info : m_window_list) + info.show(); } void debugger_windows::hide_all() { SetForegroundWindow(win_window_list->m_hwnd); - for (debugwin_info *info = m_window_list.first(); info != NULL; info = info->next()) - info->hide(); + for (debugwin_info &info : m_window_list) + info.hide(); } diff --git a/src/osd/modules/debugger/osx/deviceinfoviewer.mm b/src/osd/modules/debugger/osx/deviceinfoviewer.mm index 1f045870883..dd1b43ccf60 100644 --- a/src/osd/modules/debugger/osx/deviceinfoviewer.mm +++ b/src/osd/modules/debugger/osx/deviceinfoviewer.mm @@ -165,7 +165,7 @@ toView:contentView]; // add interfaces if present - device_interface *interface = device->first_interface(); + device_interface *interface = device->interfaces().first(); if (interface != NULL) { NSBox *const interfacesBox = [self makeBox:@"Interfaces" toFit:contentView]; diff --git a/src/osd/modules/debugger/osx/devicesviewer.mm b/src/osd/modules/debugger/osx/devicesviewer.mm index ddf08602bc6..356cc2d1393 100644 --- a/src/osd/modules/debugger/osx/devicesviewer.mm +++ b/src/osd/modules/debugger/osx/devicesviewer.mm @@ -34,7 +34,7 @@ - (void)wrapChildren { NSMutableArray *const tmp = [[NSMutableArray alloc] init]; - for (device_t *child = device->first_subdevice(); child != NULL; child = child->next()) + for (device_t *child = device->subdevices().first(); child != NULL; child = child->next()) { MAMEDeviceWrapper *const wrap = [[MAMEDeviceWrapper alloc] initWithMachine:*machine device:*child]; diff --git a/src/osd/modules/debugger/qt/dasmwindow.cpp b/src/osd/modules/debugger/qt/dasmwindow.cpp index ae8f1ff35e3..3a430f67a84 100644 --- a/src/osd/modules/debugger/qt/dasmwindow.cpp +++ b/src/osd/modules/debugger/qt/dasmwindow.cpp @@ -265,11 +265,9 @@ void DasmWindow::populateComboBox() return; m_cpuComboBox->clear(); - for (const debug_view_source* source = m_dasmView->view()->first_source(); - source != NULL; - source = source->next()) + for (const debug_view_source &source : m_dasmView->view()->source_list()) { - m_cpuComboBox->addItem(source->name()); + m_cpuComboBox->addItem(source.name()); } } diff --git a/src/osd/modules/debugger/qt/deviceinformationwindow.cpp b/src/osd/modules/debugger/qt/deviceinformationwindow.cpp index 54cc4406d23..12a286ff2b6 100644 --- a/src/osd/modules/debugger/qt/deviceinformationwindow.cpp +++ b/src/osd/modules/debugger/qt/deviceinformationwindow.cpp @@ -51,7 +51,7 @@ void DeviceInformationWindow::fill_device_information() gl1->addWidget(new QLabel(QString(m_device->shortname()), primaryFrame), 2, 1); int cpos = 3; - device_interface *intf = m_device->first_interface(); + device_interface *intf = m_device->interfaces().first(); if(intf) { gl1->addWidget(new QLabel(QString("Interfaces"), primaryFrame), cpos, 0); while(intf) { diff --git a/src/osd/modules/debugger/qt/deviceswindow.cpp b/src/osd/modules/debugger/qt/deviceswindow.cpp index b9c8f276f69..f3e4c25c586 100644 --- a/src/osd/modules/debugger/qt/deviceswindow.cpp +++ b/src/osd/modules/debugger/qt/deviceswindow.cpp @@ -55,7 +55,7 @@ QModelIndex DevicesWindowModel::index(int row, int column, const QModelIndex &pa } else { device_t *dparent = static_cast(parent.internalPointer()); int count = row; - for(target = dparent->first_subdevice(); count && target; target = target->next()) + for(target = dparent->subdevices().first(); count && target; target = target->next()) count--; } @@ -79,7 +79,7 @@ QModelIndex DevicesWindowModel::parent(const QModelIndex &index) const device_t *dpp = dparent->owner(); int row = 0; if(dpp) { - for(device_t *child = dpp->first_subdevice(); child && child != dparent; child = child->next()) + for(device_t *child = dpp->subdevices().first(); child && child != dparent; child = child->next()) row++; } return createIndex(row, 0, dparent); @@ -92,7 +92,7 @@ int DevicesWindowModel::rowCount(const QModelIndex &parent) const device_t *dparent = static_cast(parent.internalPointer()); int count = 0; - for(device_t *child = dparent->first_subdevice(); child; child = child->next()) + for (device_t &child : dparent->subdevices()) count++; return count; diff --git a/src/osd/modules/debugger/qt/memorywindow.cpp b/src/osd/modules/debugger/qt/memorywindow.cpp index 3992dc0fd85..7b86740fe51 100644 --- a/src/osd/modules/debugger/qt/memorywindow.cpp +++ b/src/osd/modules/debugger/qt/memorywindow.cpp @@ -282,11 +282,9 @@ void MemoryWindow::populateComboBox() return; m_memoryComboBox->clear(); - for (const debug_view_source* source = m_memTable->view()->first_source(); - source != NULL; - source = source->next()) + for (const debug_view_source &source : m_memTable->view()->source_list()) { - m_memoryComboBox->addItem(source->name()); + m_memoryComboBox->addItem(source.name()); } } diff --git a/src/osd/modules/debugger/win/debugviewinfo.cpp b/src/osd/modules/debugger/win/debugviewinfo.cpp index 3a8aab66d74..3f355cf8a34 100644 --- a/src/osd/modules/debugger/win/debugviewinfo.cpp +++ b/src/osd/modules/debugger/win/debugviewinfo.cpp @@ -110,9 +110,9 @@ UINT32 debugview_info::maxwidth() { UINT32 max = m_view->total_size().x; debug_view_source const *const cursource = m_view->source(); - for (debug_view_source const *source = m_view->first_source(); source != NULL; source = source->next()) + for (const debug_view_source &source : m_view->source_list()) { - m_view->set_source(*source); + m_view->set_source(source); UINT32 const chars = m_view->total_size().x; if (max < chars) max = chars; diff --git a/src/osd/modules/input/input_sdlcommon.cpp b/src/osd/modules/input/input_sdlcommon.cpp index 03e924b5a71..0f6116fa048 100644 --- a/src/osd/modules/input/input_sdlcommon.cpp +++ b/src/osd/modules/input/input_sdlcommon.cpp @@ -139,14 +139,13 @@ void sdl_osd_interface::customize_input_type_list(simple_list { input_item_id mameid_code; input_code ui_code; - input_type_entry *entry; const char* uimode; char fullmode[64]; // loop over the defaults - for (entry = typelist.first(); entry != NULL; entry = entry->next()) + for (input_type_entry &entry : typelist) { - switch (entry->type()) + switch (entry.type()) { // configurable UI mode switch case IPT_UI_TOGGLE_UI: @@ -165,23 +164,23 @@ void sdl_osd_interface::customize_input_type_list(simple_list mameid_code = keyboard_trans_table::instance().lookup_mame_code(fullmode); } ui_code = input_code(DEVICE_CLASS_KEYBOARD, 0, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, input_item_id(mameid_code)); - entry->defseq(SEQ_TYPE_STANDARD).set(ui_code); + entry.defseq(SEQ_TYPE_STANDARD).set(ui_code); break; // alt-enter for fullscreen case IPT_OSD_1: - entry->configure_osd("TOGGLE_FULLSCREEN", "Toggle Fullscreen"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_ENTER, KEYCODE_LALT); + entry.configure_osd("TOGGLE_FULLSCREEN", "Toggle Fullscreen"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_ENTER, KEYCODE_LALT); break; // disable UI_SELECT when LALT is down, this stops selecting // things in the menu when toggling fullscreen with LALT+ENTER /* case IPT_UI_SELECT: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_ENTER, input_seq::not_code, KEYCODE_LALT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_ENTER, input_seq::not_code, KEYCODE_LALT); break;*/ // page down for fastforward (must be OSD_3 as per src/emu/ui.c) case IPT_UI_FAST_FORWARD: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_PGDN); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_PGDN); break; // OSD hotkeys use LCTRL and start at F3, they start at @@ -191,63 +190,63 @@ void sdl_osd_interface::customize_input_type_list(simple_list // LCTRL-F3 to toggle fullstretch case IPT_OSD_2: - entry->configure_osd("TOGGLE_FULLSTRETCH", "Toggle Uneven stretch"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F3, KEYCODE_LCONTROL); + entry.configure_osd("TOGGLE_FULLSTRETCH", "Toggle Uneven stretch"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F3, KEYCODE_LCONTROL); break; // add a Not lcrtl condition to the reset key case IPT_UI_SOFT_RESET: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F3, input_seq::not_code, KEYCODE_LCONTROL, input_seq::not_code, KEYCODE_LSHIFT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F3, input_seq::not_code, KEYCODE_LCONTROL, input_seq::not_code, KEYCODE_LSHIFT); break; // LCTRL-F4 to toggle keep aspect case IPT_OSD_4: - entry->configure_osd("TOGGLE_KEEP_ASPECT", "Toggle Keepaspect"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F4, KEYCODE_LCONTROL); + entry.configure_osd("TOGGLE_KEEP_ASPECT", "Toggle Keepaspect"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F4, KEYCODE_LCONTROL); break; // add a Not lcrtl condition to the show gfx key case IPT_UI_SHOW_GFX: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F4, input_seq::not_code, KEYCODE_LCONTROL); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F4, input_seq::not_code, KEYCODE_LCONTROL); break; // LCTRL-F5 to toggle OpenGL filtering case IPT_OSD_5: - entry->configure_osd("TOGGLE_FILTER", "Toggle Filter"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F5, KEYCODE_LCONTROL); + entry.configure_osd("TOGGLE_FILTER", "Toggle Filter"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F5, KEYCODE_LCONTROL); break; // add a Not lcrtl condition to the toggle debug key case IPT_UI_TOGGLE_DEBUG: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F5, input_seq::not_code, KEYCODE_LCONTROL); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F5, input_seq::not_code, KEYCODE_LCONTROL); break; // LCTRL-F6 to decrease OpenGL prescaling case IPT_OSD_6: - entry->configure_osd("DECREASE_PRESCALE", "Decrease Prescaling"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F6, KEYCODE_LCONTROL); + entry.configure_osd("DECREASE_PRESCALE", "Decrease Prescaling"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F6, KEYCODE_LCONTROL); break; // add a Not lcrtl condition to the toggle cheat key case IPT_UI_TOGGLE_CHEAT: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F6, input_seq::not_code, KEYCODE_LCONTROL); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F6, input_seq::not_code, KEYCODE_LCONTROL); break; // LCTRL-F7 to increase OpenGL prescaling case IPT_OSD_7: - entry->configure_osd("INCREASE_PRESCALE", "Increase Prescaling"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F7, KEYCODE_LCONTROL); + entry.configure_osd("INCREASE_PRESCALE", "Increase Prescaling"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F7, KEYCODE_LCONTROL); break; // add a Not lcrtl condition to the load state key case IPT_UI_LOAD_STATE: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F7, input_seq::not_code, KEYCODE_LCONTROL, input_seq::not_code, KEYCODE_LSHIFT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F7, input_seq::not_code, KEYCODE_LCONTROL, input_seq::not_code, KEYCODE_LSHIFT); break; // add a Not lcrtl condition to the throttle key case IPT_UI_THROTTLE: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F10, input_seq::not_code, KEYCODE_LCONTROL); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F10, input_seq::not_code, KEYCODE_LCONTROL); break; // disable the config menu if the ALT key is down // (allows ALT-TAB to switch between apps) case IPT_UI_CONFIGURE: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_TAB, input_seq::not_code, KEYCODE_LALT, input_seq::not_code, KEYCODE_RALT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_TAB, input_seq::not_code, KEYCODE_LALT, input_seq::not_code, KEYCODE_RALT); break; // leave everything else alone diff --git a/src/osd/modules/input/input_windows.cpp b/src/osd/modules/input/input_windows.cpp index 1ad092e1281..2132247b828 100644 --- a/src/osd/modules/input/input_windows.cpp +++ b/src/osd/modules/input/input_windows.cpp @@ -54,17 +54,16 @@ void windows_osd_interface::poll_input(running_machine &machine) const void windows_osd_interface::customize_input_type_list(simple_list &typelist) { - input_type_entry *entry; const char* uimode; // loop over the defaults - for (entry = typelist.first(); entry != nullptr; entry = entry->next()) - switch (entry->type()) + for (input_type_entry &entry : typelist) + switch (entry.type()) { // disable the config menu if the ALT key is down // (allows ALT-TAB to switch between windows apps) case IPT_UI_CONFIGURE: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_TAB, input_seq::not_code, KEYCODE_LALT, input_seq::not_code, KEYCODE_RALT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_TAB, input_seq::not_code, KEYCODE_LALT, input_seq::not_code, KEYCODE_RALT); break; // configurable UI mode switch @@ -78,50 +77,50 @@ void windows_osd_interface::customize_input_type_list(simple_listdefseq(SEQ_TYPE_STANDARD).set(ui_code); + entry.defseq(SEQ_TYPE_STANDARD).set(ui_code); } } break; // alt-enter for fullscreen case IPT_OSD_1: - entry->configure_osd("TOGGLE_FULLSCREEN", "Toggle Fullscreen"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_ENTER, KEYCODE_LALT, input_seq::or_code, KEYCODE_ENTER, KEYCODE_RALT); + entry.configure_osd("TOGGLE_FULLSCREEN", "Toggle Fullscreen"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_ENTER, KEYCODE_LALT, input_seq::or_code, KEYCODE_ENTER, KEYCODE_RALT); break; // lalt-F12 for fullscreen snap (HLSL) case IPT_OSD_2: - entry->configure_osd("RENDER_SNAP", "Take Rendered Snapshot"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, KEYCODE_LALT, input_seq::not_code, KEYCODE_LSHIFT); + entry.configure_osd("RENDER_SNAP", "Take Rendered Snapshot"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, KEYCODE_LALT, input_seq::not_code, KEYCODE_LSHIFT); break; // add a NOT-lalt to our default F12 case IPT_UI_SNAPSHOT: // emu/input.c: input_seq(KEYCODE_F12, input_seq::not_code, KEYCODE_LSHIFT) - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_LALT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_LALT); break; // lshift-lalt-F12 for fullscreen video (HLSL) case IPT_OSD_3: - entry->configure_osd("RENDER_AVI", "Record Rendered Video"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, KEYCODE_LSHIFT, KEYCODE_LALT); + entry.configure_osd("RENDER_AVI", "Record Rendered Video"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, KEYCODE_LSHIFT, KEYCODE_LALT); break; // add a NOT-lalt to our default shift-F12 case IPT_UI_RECORD_MOVIE: // emu/input.c: input_seq(KEYCODE_F12, KEYCODE_LSHIFT) - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_LALT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_LALT); break; // add a NOT-lalt to write timecode file case IPT_UI_TIMECODE: // emu/input.c: input_seq(KEYCODE_F12, input_seq::not_code, KEYCODE_LSHIFT) - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_LALT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_LALT); break; // lctrl-lalt-F5 to toggle post-processing case IPT_OSD_4: - entry->configure_osd("POST_PROCESS", "Toggle Post-Processing"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F5, KEYCODE_LALT, KEYCODE_LCONTROL); + entry.configure_osd("POST_PROCESS", "Toggle Post-Processing"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F5, KEYCODE_LALT, KEYCODE_LCONTROL); break; // add a NOT-lctrl-lalt to our default F5 case IPT_UI_TOGGLE_DEBUG: // emu/input.c: input_seq(KEYCODE_F5) - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F5, input_seq::not_code, KEYCODE_LCONTROL, input_seq::not_code, KEYCODE_LALT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F5, input_seq::not_code, KEYCODE_LCONTROL, input_seq::not_code, KEYCODE_LALT); break; // leave everything else alone diff --git a/src/osd/modules/render/draw13.cpp b/src/osd/modules/render/draw13.cpp index f189fc48cca..79356d4ea22 100644 --- a/src/osd/modules/render/draw13.cpp +++ b/src/osd/modules/render/draw13.cpp @@ -248,17 +248,17 @@ void texture_info::set_coloralphamode(SDL_Texture *texture_id, const render_colo } } -void texture_info::render_quad(const render_primitive *prim, const int x, const int y) +void texture_info::render_quad(const render_primitive &prim, const int x, const int y) { SDL_Rect target_rect; target_rect.x = x; target_rect.y = y; - target_rect.w = round_nearest(prim->bounds.x1) - round_nearest(prim->bounds.x0); - target_rect.h = round_nearest(prim->bounds.y1) - round_nearest(prim->bounds.y0); + target_rect.w = round_nearest(prim.bounds.x1) - round_nearest(prim.bounds.x0); + target_rect.h = round_nearest(prim.bounds.y1) - round_nearest(prim.bounds.y0); SDL_SetTextureBlendMode(m_texture_id, m_sdl_blendmode); - set_coloralphamode(m_texture_id, &prim->color); + set_coloralphamode(m_texture_id, &prim.color); //printf("%d %d %d %d\n", target_rect.x, target_rect.y, target_rect.w, target_rect.h); // Arghhh .. Just another bug. SDL_RenderCopy has severe issues with scaling ... SDL_RenderCopy(m_renderer->m_sdl_renderer, m_texture_id, nullptr, &target_rect); @@ -266,14 +266,14 @@ void texture_info::render_quad(const render_primitive *prim, const int x, const //SDL_RenderCopyEx(m_renderer->m_sdl_renderer, m_texture_id, nullptr, nullptr, 0, nullptr, SDL_FLIP_NONE); } -void renderer_sdl1::render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y) +void renderer_sdl1::render_quad(texture_info *texture, const render_primitive &prim, const int x, const int y) { SDL_Rect target_rect; target_rect.x = x; target_rect.y = y; - target_rect.w = round_nearest(prim->bounds.x1 - prim->bounds.x0); - target_rect.h = round_nearest(prim->bounds.y1 - prim->bounds.y0); + target_rect.w = round_nearest(prim.bounds.x1 - prim.bounds.x0); + target_rect.h = round_nearest(prim.bounds.y1 - prim.bounds.y0); if (texture) { @@ -292,12 +292,12 @@ void renderer_sdl1::render_quad(texture_info *texture, const render_primitive *p } else { - UINT32 sr = (UINT32)(255.0f * prim->color.r); - UINT32 sg = (UINT32)(255.0f * prim->color.g); - UINT32 sb = (UINT32)(255.0f * prim->color.b); - UINT32 sa = (UINT32)(255.0f * prim->color.a); + UINT32 sr = (UINT32)(255.0f * prim.color.r); + UINT32 sg = (UINT32)(255.0f * prim.color.g); + UINT32 sb = (UINT32)(255.0f * prim.color.b); + UINT32 sa = (UINT32)(255.0f * prim.color.a); - SDL_SetRenderDrawBlendMode(m_sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags))); + SDL_SetRenderDrawBlendMode(m_sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim.flags))); SDL_SetRenderDrawColor(m_sdl_renderer, sr, sg, sb, sa); SDL_RenderFillRect(m_sdl_renderer, &target_rect); } @@ -499,7 +499,6 @@ void renderer_sdl1::destroy_all_textures() int renderer_sdl1::draw(int update) { - render_primitive *prim; texture_info *texture=nullptr; float vofs, hofs; int blit_pixels = 0; @@ -559,30 +558,30 @@ int renderer_sdl1::draw(int update) window().m_primlist->acquire_lock(); // now draw - for (prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : *window().m_primlist) { Uint8 sr, sg, sb, sa; - switch (prim->type) + switch (prim.type) { case render_primitive::LINE: - sr = (int)(255.0f * prim->color.r); - sg = (int)(255.0f * prim->color.g); - sb = (int)(255.0f * prim->color.b); - sa = (int)(255.0f * prim->color.a); + sr = (int)(255.0f * prim.color.r); + sg = (int)(255.0f * prim.color.g); + sb = (int)(255.0f * prim.color.b); + sa = (int)(255.0f * prim.color.a); - SDL_SetRenderDrawBlendMode(m_sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags))); + SDL_SetRenderDrawBlendMode(m_sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim.flags))); SDL_SetRenderDrawColor(m_sdl_renderer, sr, sg, sb, sa); - SDL_RenderDrawLine(m_sdl_renderer, prim->bounds.x0 + hofs, prim->bounds.y0 + vofs, - prim->bounds.x1 + hofs, prim->bounds.y1 + vofs); + SDL_RenderDrawLine(m_sdl_renderer, prim.bounds.x0 + hofs, prim.bounds.y0 + vofs, + prim.bounds.x1 + hofs, prim.bounds.y1 + vofs); break; case render_primitive::QUAD: - texture = texture_update(*prim); + texture = texture_update(prim); if (texture) blit_pixels += (texture->raw_height() * texture->raw_width()); render_quad(texture, prim, - round_nearest(hofs + prim->bounds.x0), - round_nearest(vofs + prim->bounds.y0)); + round_nearest(hofs + prim.bounds.x0), + round_nearest(vofs + prim.bounds.y0)); break; default: throw emu_fatalerror("Unexpected render_primitive type\n"); diff --git a/src/osd/modules/render/draw13.h b/src/osd/modules/render/draw13.h index e6d15a757bb..3bd8acf608b 100644 --- a/src/osd/modules/render/draw13.h +++ b/src/osd/modules/render/draw13.h @@ -62,7 +62,7 @@ public: ~texture_info(); void set_data(const render_texinfo &texsource, const UINT32 flags); - void render_quad(const render_primitive *prim, const int x, const int y); + void render_quad(const render_primitive &prim, const int x, const int y); bool matches(const render_primitive &prim, const quad_setup_data &setup); copy_info_t *compute_size_type(); @@ -176,7 +176,7 @@ private: void expand_copy_info(const copy_info_t *list); void add_list(copy_info_t **head, const copy_info_t *element, Uint32 bm); - void render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y); + void render_quad(texture_info *texture, const render_primitive &prim, const int x, const int y); texture_info *texture_find(const render_primitive &prim, const quad_setup_data &setup); texture_info *texture_update(const render_primitive &prim); diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp index 0b98fe24d6b..85b76864b23 100644 --- a/src/osd/modules/render/drawbgfx.cpp +++ b/src/osd/modules/render/drawbgfx.cpp @@ -1226,21 +1226,21 @@ bool renderer_bgfx::check_for_dirty_atlas() bool atlas_dirty = false; std::map acquired_infos; - for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : *window().m_primlist) { - bool pack = prim->packable(PACKABLE_SIZE); - if (prim->type == render_primitive::QUAD && prim->texture.base != nullptr && pack) + bool pack = prim.packable(PACKABLE_SIZE); + if (prim.type == render_primitive::QUAD && prim.texture.base != nullptr && pack) { - const UINT32 hash = get_texture_hash(prim); + const UINT32 hash = get_texture_hash(&prim); // If this texture is packable and not currently in the atlas, prepare the texture for putting in the atlas if ((hash != 0 && m_hash_to_entry[hash].hash() == 0 && acquired_infos[hash].hash() == 0) || (hash != 0 && m_hash_to_entry[hash].hash() != hash && acquired_infos[hash].hash() == 0)) { // Create create the texture and mark the atlas dirty atlas_dirty = true; - m_texinfo.push_back(rectangle_packer::packable_rectangle(hash, prim->flags & PRIMFLAG_TEXFORMAT_MASK, - prim->texture.width, prim->texture.height, - prim->texture.rowpixels, prim->texture.palette, prim->texture.base)); + m_texinfo.push_back(rectangle_packer::packable_rectangle(hash, prim.flags & PRIMFLAG_TEXFORMAT_MASK, + prim.texture.width, prim.texture.height, + prim.texture.rowpixels, prim.texture.palette, prim.texture.base)); acquired_infos[hash] = m_texinfo[m_texinfo.size() - 1]; } } diff --git a/src/osd/modules/render/drawd3d.cpp b/src/osd/modules/render/drawd3d.cpp index 708ed01cd6c..930a02f3103 100644 --- a/src/osd/modules/render/drawd3d.cpp +++ b/src/osd/modules/render/drawd3d.cpp @@ -630,31 +630,31 @@ int renderer_d3d9::pre_window_draw_check() void d3d_texture_manager::update_textures() { - for (render_primitive *prim = m_renderer->window().m_primlist->first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : *m_renderer->window().m_primlist) { - if (prim->texture.base != nullptr) + if (prim.texture.base != nullptr) { - texture_info *texture = find_texinfo(&prim->texture, prim->flags); + texture_info *texture = find_texinfo(&prim.texture, prim.flags); if (texture == nullptr) { if (m_renderer->get_shaders()->enabled()) { // if there isn't one, create a new texture without prescale - texture = global_alloc(texture_info(this, &prim->texture, 1, prim->flags)); + texture = global_alloc(texture_info(this, &prim.texture, 1, prim.flags)); } else { // if there isn't one, create a new texture - texture = global_alloc(texture_info(this, &prim->texture, m_renderer->window().prescale(), prim->flags)); + texture = global_alloc(texture_info(this, &prim.texture, m_renderer->window().prescale(), prim.flags)); } } else { // if there is one, but with a different seqid, copy the data - if (texture->get_texinfo().seqid != prim->texture.seqid) + if (texture->get_texinfo().seqid != prim.texture.seqid) { - texture->set_data(&prim->texture, prim->flags); - texture->get_texinfo().seqid = prim->texture.seqid; + texture->set_data(&prim.texture, prim.flags); + texture->get_texinfo().seqid = prim.texture.seqid; } } @@ -669,7 +669,7 @@ void d3d_texture_manager::update_textures() } } } - else if(m_renderer->get_shaders()->vector_enabled() && PRIMFLAG_GET_VECTORBUF(prim->flags)) + else if(m_renderer->get_shaders()->vector_enabled() && PRIMFLAG_GET_VECTORBUF(prim.flags)) { if (!m_renderer->get_shaders()->get_vector_target(prim)) { @@ -706,9 +706,9 @@ void renderer_d3d9::begin_frame() // loop over line primitives m_line_count = 0; - for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : *window().m_primlist) { - if (prim->type == render_primitive::LINE && PRIMFLAG_GET_VECTOR(prim->flags)) + if (prim.type == render_primitive::LINE && PRIMFLAG_GET_VECTOR(prim.flags)) { m_line_count++; } @@ -718,12 +718,12 @@ void renderer_d3d9::begin_frame() void renderer_d3d9::process_primitives() { // Rotating index for vector time offsets - for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : *window().m_primlist) { - switch (prim->type) + switch (prim.type) { case render_primitive::LINE: - if (PRIMFLAG_GET_VECTOR(prim->flags)) + if (PRIMFLAG_GET_VECTOR(prim.flags)) { if (m_line_count > 0) batch_vectors(); @@ -1404,12 +1404,12 @@ void renderer_d3d9::batch_vectors() int line_index = 0; float period = options.screen_vector_time_period(); UINT32 cached_flags = 0; - for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : *window().m_primlist) { - switch (prim->type) + switch (prim.type) { case render_primitive::LINE: - if (PRIMFLAG_GET_VECTOR(prim->flags)) + if (PRIMFLAG_GET_VECTOR(prim.flags)) { if (period == 0.0f || m_line_count == 0) { @@ -1420,15 +1420,15 @@ void renderer_d3d9::batch_vectors() batch_vector(prim, (float)(start_index + line_index) / ((float)m_line_count * period)); line_index++; } - cached_flags = prim->flags; + cached_flags = prim.flags; } break; case render_primitive::QUAD: - if (PRIMFLAG_GET_VECTORBUF(prim->flags)) + if (PRIMFLAG_GET_VECTORBUF(prim.flags)) { - width = prim->bounds.x1 - prim->bounds.x0; - height = prim->bounds.y1 - prim->bounds.y0; + width = prim.bounds.x1 - prim.bounds.x0; + height = prim.bounds.y1 - prim.bounds.y0; } break; @@ -1452,10 +1452,10 @@ void renderer_d3d9::batch_vectors() m_line_count = 0; } -void renderer_d3d9::batch_vector(const render_primitive *prim, float line_time) +void renderer_d3d9::batch_vector(const render_primitive &prim, float line_time) { // compute the effective width based on the direction of the line - float effwidth = prim->width; + float effwidth = prim.width; if (effwidth < 0.5f) { effwidth = 0.5f; @@ -1463,10 +1463,10 @@ void renderer_d3d9::batch_vector(const render_primitive *prim, float line_time) // determine the bounds of a quad to draw this line render_bounds b0, b1; - render_line_to_quad(&prim->bounds, effwidth, &b0, &b1); + render_line_to_quad(&prim.bounds, effwidth, &b0, &b1); // iterate over AA steps - for (const line_aa_step *step = PRIMFLAG_GET_ANTIALIAS(prim->flags) ? line_aa_4step : line_aa_1step; + for (const line_aa_step *step = PRIMFLAG_GET_ANTIALIAS(prim.flags) ? line_aa_4step : line_aa_1step; step->weight != 0; step++) { // get a pointer to the vertex buffer @@ -1492,10 +1492,10 @@ void renderer_d3d9::batch_vector(const render_primitive *prim, float line_time) float line_length = sqrtf(dx * dx + dy * dy); // determine the color of the line - INT32 r = (INT32)(prim->color.r * step->weight * 255.0f); - INT32 g = (INT32)(prim->color.g * step->weight * 255.0f); - INT32 b = (INT32)(prim->color.b * step->weight * 255.0f); - INT32 a = (INT32)(prim->color.a * 255.0f); + INT32 r = (INT32)(prim.color.r * step->weight * 255.0f); + INT32 g = (INT32)(prim.color.g * step->weight * 255.0f); + INT32 b = (INT32)(prim.color.b * step->weight * 255.0f); + INT32 a = (INT32)(prim.color.a * 255.0f); if (r > 255 || g > 255 || b > 255) { if (r > 2*255 || g > 2*255 || b > 2*255) @@ -1554,10 +1554,10 @@ void renderer_d3d9::batch_vector(const render_primitive *prim, float line_time) // draw_line //============================================================ -void renderer_d3d9::draw_line(const render_primitive *prim) +void renderer_d3d9::draw_line(const render_primitive &prim) { // compute the effective width based on the direction of the line - float effwidth = prim->width; + float effwidth = prim.width; if (effwidth < 0.5f) { effwidth = 0.5f; @@ -1565,10 +1565,10 @@ void renderer_d3d9::draw_line(const render_primitive *prim) // determine the bounds of a quad to draw this line render_bounds b0, b1; - render_line_to_quad(&prim->bounds, effwidth, &b0, &b1); + render_line_to_quad(&prim.bounds, effwidth, &b0, &b1); // iterate over AA steps - for (const line_aa_step *step = PRIMFLAG_GET_ANTIALIAS(prim->flags) ? line_aa_4step : line_aa_1step; + for (const line_aa_step *step = PRIMFLAG_GET_ANTIALIAS(prim.flags) ? line_aa_4step : line_aa_1step; step->weight != 0; step++) { // get a pointer to the vertex buffer @@ -1593,10 +1593,10 @@ void renderer_d3d9::draw_line(const render_primitive *prim) vertex[3].y = b1.y1 + step->yoffs; // determine the color of the line - INT32 r = (INT32)(prim->color.r * step->weight * 255.0f); - INT32 g = (INT32)(prim->color.g * step->weight * 255.0f); - INT32 b = (INT32)(prim->color.b * step->weight * 255.0f); - INT32 a = (INT32)(prim->color.a * 255.0f); + INT32 r = (INT32)(prim.color.r * step->weight * 255.0f); + INT32 g = (INT32)(prim.color.g * step->weight * 255.0f); + INT32 b = (INT32)(prim.color.b * step->weight * 255.0f); + INT32 a = (INT32)(prim.color.a * 255.0f); if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; @@ -1627,7 +1627,7 @@ void renderer_d3d9::draw_line(const render_primitive *prim) } // now add a polygon entry - m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim->flags, get_vector_texture(), + m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim.flags, get_vector_texture(), D3DTOP_MODULATE, 0.0f, 1.0f, 0.0f, 0.0f); m_numpolys++; } @@ -1638,9 +1638,9 @@ void renderer_d3d9::draw_line(const render_primitive *prim) // draw_quad //============================================================ -void renderer_d3d9::draw_quad(const render_primitive *prim) +void renderer_d3d9::draw_quad(const render_primitive &prim) { - texture_info *texture = m_texture_manager->find_texinfo(&prim->texture, prim->flags); + texture_info *texture = m_texture_manager->find_texinfo(&prim.texture, prim.flags); if (texture == nullptr) { @@ -1653,16 +1653,16 @@ void renderer_d3d9::draw_quad(const render_primitive *prim) return; // fill in the vertexes clockwise - vertex[0].x = prim->bounds.x0; - vertex[0].y = prim->bounds.y0; - vertex[1].x = prim->bounds.x1; - vertex[1].y = prim->bounds.y0; - vertex[2].x = prim->bounds.x0; - vertex[2].y = prim->bounds.y1; - vertex[3].x = prim->bounds.x1; - vertex[3].y = prim->bounds.y1; - float width = prim->bounds.x1 - prim->bounds.x0; - float height = prim->bounds.y1 - prim->bounds.y0; + vertex[0].x = prim.bounds.x0; + vertex[0].y = prim.bounds.y0; + vertex[1].x = prim.bounds.x1; + vertex[1].y = prim.bounds.y0; + vertex[2].x = prim.bounds.x0; + vertex[2].y = prim.bounds.y1; + vertex[3].x = prim.bounds.x1; + vertex[3].y = prim.bounds.y1; + float width = prim.bounds.x1 - prim.bounds.x0; + float height = prim.bounds.y1 - prim.bounds.y0; // set the texture coordinates if (texture != nullptr) @@ -1671,21 +1671,21 @@ void renderer_d3d9::draw_quad(const render_primitive *prim) vec2f& stop = texture->get_uvstop(); vec2f delta = stop - start; - vertex[0].u0 = start.c.x + delta.c.x * prim->texcoords.tl.u; - vertex[0].v0 = start.c.y + delta.c.y * prim->texcoords.tl.v; - vertex[1].u0 = start.c.x + delta.c.x * prim->texcoords.tr.u; - vertex[1].v0 = start.c.y + delta.c.y * prim->texcoords.tr.v; - vertex[2].u0 = start.c.x + delta.c.x * prim->texcoords.bl.u; - vertex[2].v0 = start.c.y + delta.c.y * prim->texcoords.bl.v; - vertex[3].u0 = start.c.x + delta.c.x * prim->texcoords.br.u; - vertex[3].v0 = start.c.y + delta.c.y * prim->texcoords.br.v; + vertex[0].u0 = start.c.x + delta.c.x * prim.texcoords.tl.u; + vertex[0].v0 = start.c.y + delta.c.y * prim.texcoords.tl.v; + vertex[1].u0 = start.c.x + delta.c.x * prim.texcoords.tr.u; + vertex[1].v0 = start.c.y + delta.c.y * prim.texcoords.tr.v; + vertex[2].u0 = start.c.x + delta.c.x * prim.texcoords.bl.u; + vertex[2].v0 = start.c.y + delta.c.y * prim.texcoords.bl.v; + vertex[3].u0 = start.c.x + delta.c.x * prim.texcoords.br.u; + vertex[3].v0 = start.c.y + delta.c.y * prim.texcoords.br.v; } // determine the color, allowing for over modulation - INT32 r = (INT32)(prim->color.r * 255.0f); - INT32 g = (INT32)(prim->color.g * 255.0f); - INT32 b = (INT32)(prim->color.b * 255.0f); - INT32 a = (INT32)(prim->color.a * 255.0f); + INT32 r = (INT32)(prim.color.r * 255.0f); + INT32 g = (INT32)(prim.color.g * 255.0f); + INT32 b = (INT32)(prim.color.b * 255.0f); + INT32 a = (INT32)(prim.color.a * 255.0f); DWORD modmode = D3DTOP_MODULATE; if (texture != nullptr) { @@ -1720,7 +1720,7 @@ void renderer_d3d9::draw_quad(const render_primitive *prim) } // now add a polygon entry - m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim->flags, texture, modmode, width, height); + m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim.flags, texture, modmode, width, height); m_numpolys++; } diff --git a/src/osd/modules/render/drawd3d.h b/src/osd/modules/render/drawd3d.h index de8506ebfbd..2f4b675cba2 100644 --- a/src/osd/modules/render/drawd3d.h +++ b/src/osd/modules/render/drawd3d.h @@ -85,9 +85,9 @@ public: void begin_frame(); void end_frame(); - void draw_line(const render_primitive *prim); - void draw_quad(const render_primitive *prim); - void batch_vector(const render_primitive *prim, float line_time); + void draw_line(const render_primitive &prim); + void draw_quad(const render_primitive &prim); + void batch_vector(const render_primitive &prim, float line_time); void batch_vectors(); vertex * mesh_alloc(int numverts); diff --git a/src/osd/modules/render/drawogl.cpp b/src/osd/modules/render/drawogl.cpp index 96c1559b23a..452a3c570ab 100644 --- a/src/osd/modules/render/drawogl.cpp +++ b/src/osd/modules/render/drawogl.cpp @@ -1014,7 +1014,6 @@ void renderer_ogl::loadGLExtensions() int renderer_ogl::draw(const int update) { - render_primitive *prim; ogl_texture_info *texture=nullptr; float vofs, hofs; int pendingPrimitive=GL_NO_PRIMITIVE, curPrimitive=GL_NO_PRIMITIVE; @@ -1160,11 +1159,11 @@ int renderer_ogl::draw(const int update) window().m_primlist->acquire_lock(); // now draw - for (prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : *window().m_primlist) { int i; - switch (prim->type) + switch (prim.type) { /** * Try to stay in one Begin/End block as long as possible, @@ -1173,7 +1172,7 @@ int renderer_ogl::draw(const int update) case render_primitive::LINE: #if !USE_WIN32_STYLE_LINES // check if it's really a point - if (((prim->bounds.x1 - prim->bounds.x0) == 0) && ((prim->bounds.y1 - prim->bounds.y0) == 0)) + if (((prim.bounds.x1 - prim.bounds.x0) == 0) && ((prim.bounds.y1 - prim.bounds.y0) == 0)) { curPrimitive=GL_POINTS; } else { @@ -1188,10 +1187,10 @@ int renderer_ogl::draw(const int update) if ( pendingPrimitive==GL_NO_PRIMITIVE ) { - set_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags)); + set_blendmode(PRIMFLAG_GET_BLENDMODE(prim.flags)); } - glColor4f(prim->color.r, prim->color.g, prim->color.b, prim->color.a); + glColor4f(prim.color.r, prim.color.g, prim.color.b, prim.color.a); if(pendingPrimitive!=curPrimitive) { @@ -1202,12 +1201,12 @@ int renderer_ogl::draw(const int update) // check if it's really a point if (curPrimitive==GL_POINTS) { - glVertex2f(prim->bounds.x0+hofs, prim->bounds.y0+vofs); + glVertex2f(prim.bounds.x0+hofs, prim.bounds.y0+vofs); } else { - glVertex2f(prim->bounds.x0+hofs, prim->bounds.y0+vofs); - glVertex2f(prim->bounds.x1+hofs, prim->bounds.y1+vofs); + glVertex2f(prim.bounds.x0+hofs, prim.bounds.y0+vofs); + glVertex2f(prim.bounds.x1+hofs, prim.bounds.y1+vofs); } #else { @@ -1223,15 +1222,15 @@ int renderer_ogl::draw(const int update) pendingPrimitive=GL_NO_PRIMITIVE; } - set_blendmode(sdl, PRIMFLAG_GET_BLENDMODE(prim->flags)); + set_blendmode(sdl, PRIMFLAG_GET_BLENDMODE(prim.flags)); // compute the effective width based on the direction of the line - effwidth = prim->width(); + effwidth = prim.width(); if (effwidth < 0.5f) effwidth = 0.5f; // determine the bounds of a quad to draw this line - render_line_to_quad(&prim->bounds, effwidth, &b0, &b1); + render_line_to_quad(&prim.bounds, effwidth, &b0, &b1); // fix window position b0.x0 += hofs; @@ -1244,7 +1243,7 @@ int renderer_ogl::draw(const int update) b1.y1 += vofs; // iterate over AA steps - for (step = PRIMFLAG_GET_ANTIALIAS(prim->flags) ? line_aa_4step : line_aa_1step; step->weight != 0; step++) + for (step = PRIMFLAG_GET_ANTIALIAS(prim.flags) ? line_aa_4step : line_aa_1step; step->weight != 0; step++) { glBegin(GL_TRIANGLE_STRIP); @@ -1261,17 +1260,17 @@ int renderer_ogl::draw(const int update) glVertex2f(b1.x1 + step->xoffs, b1.y1 + step->yoffs); // determine the color of the line - r = (prim->color.r * step->weight); - g = (prim->color.g * step->weight); - b = (prim->color.b * step->weight); - a = (prim->color.a * 255.0f); + r = (prim.color.r * step->weight); + g = (prim.color.g * step->weight); + b = (prim.color.b * step->weight); + a = (prim.color.a * 255.0f); if (r > 1.0) r = 1.0; if (g > 1.0) g = 1.0; if (b > 1.0) b = 1.0; if (a > 1.0) a = 1.0; glColor4f(r, g, b, a); -// texture = texture_update(window, prim, 0); +// texture = texture_update(window, &prim, 0); // if (texture) printf("line has texture!\n"); // if we have a texture to use for the vectors, use it here @@ -1306,11 +1305,11 @@ int renderer_ogl::draw(const int update) pendingPrimitive=GL_NO_PRIMITIVE; } - glColor4f(prim->color.r, prim->color.g, prim->color.b, prim->color.a); + glColor4f(prim.color.r, prim.color.g, prim.color.b, prim.color.a); - set_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags)); + set_blendmode(PRIMFLAG_GET_BLENDMODE(prim.flags)); - texture = texture_update(prim, 0); + texture = texture_update(&prim, 0); if ( texture && texture->type==TEXTURE_TYPE_SHADER ) { @@ -1319,14 +1318,14 @@ int renderer_ogl::draw(const int update) if ( i==m_glsl_program_mb2sc ) { // i==glsl_program_mb2sc -> transformation mamebm->scrn - m_texVerticex[0]=prim->bounds.x0 + hofs; - m_texVerticex[1]=prim->bounds.y0 + vofs; - m_texVerticex[2]=prim->bounds.x1 + hofs; - m_texVerticex[3]=prim->bounds.y0 + vofs; - m_texVerticex[4]=prim->bounds.x1 + hofs; - m_texVerticex[5]=prim->bounds.y1 + vofs; - m_texVerticex[6]=prim->bounds.x0 + hofs; - m_texVerticex[7]=prim->bounds.y1 + vofs; + m_texVerticex[0]=prim.bounds.x0 + hofs; + m_texVerticex[1]=prim.bounds.y0 + vofs; + m_texVerticex[2]=prim.bounds.x1 + hofs; + m_texVerticex[3]=prim.bounds.y0 + vofs; + m_texVerticex[4]=prim.bounds.x1 + hofs; + m_texVerticex[5]=prim.bounds.y1 + vofs; + m_texVerticex[6]=prim.bounds.x0 + hofs; + m_texVerticex[7]=prim.bounds.y1 + vofs; } else { // 1:1 tex coord CCW (0/0) (1/0) (1/1) (0/1) on texture dimensions m_texVerticex[0]=(GLfloat)0.0; @@ -1341,19 +1340,19 @@ int renderer_ogl::draw(const int update) if(i>0) // first fetch already done { - texture = texture_update(prim, i); + texture = texture_update(&prim, i); } glDrawArrays(GL_QUADS, 0, 4); } } else { - m_texVerticex[0]=prim->bounds.x0 + hofs; - m_texVerticex[1]=prim->bounds.y0 + vofs; - m_texVerticex[2]=prim->bounds.x1 + hofs; - m_texVerticex[3]=prim->bounds.y0 + vofs; - m_texVerticex[4]=prim->bounds.x1 + hofs; - m_texVerticex[5]=prim->bounds.y1 + vofs; - m_texVerticex[6]=prim->bounds.x0 + hofs; - m_texVerticex[7]=prim->bounds.y1 + vofs; + m_texVerticex[0]=prim.bounds.x0 + hofs; + m_texVerticex[1]=prim.bounds.y0 + vofs; + m_texVerticex[2]=prim.bounds.x1 + hofs; + m_texVerticex[3]=prim.bounds.y0 + vofs; + m_texVerticex[4]=prim.bounds.x1 + hofs; + m_texVerticex[5]=prim.bounds.y1 + vofs; + m_texVerticex[6]=prim.bounds.x0 + hofs; + m_texVerticex[7]=prim.bounds.y1 + vofs; glDrawArrays(GL_QUADS, 0, 4); } diff --git a/src/osd/modules/render/drawsdl.cpp b/src/osd/modules/render/drawsdl.cpp index 932f88acc2b..2450dd1b8b3 100644 --- a/src/osd/modules/render/drawsdl.cpp +++ b/src/osd/modules/render/drawsdl.cpp @@ -397,12 +397,12 @@ int renderer_sdl2::draw(int update) // FIXME: this could be a lot easier if we get the primlist here! // Bounds would be set fit for purpose and done! - for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : *window().m_primlist) { - prim->bounds.x0 = floor(fw * prim->bounds.x0 + 0.5f); - prim->bounds.x1 = floor(fw * prim->bounds.x1 + 0.5f); - prim->bounds.y0 = floor(fh * prim->bounds.y0 + 0.5f); - prim->bounds.y1 = floor(fh * prim->bounds.y1 + 0.5f); + prim.bounds.x0 = floor(fw * prim.bounds.x0 + 0.5f); + prim.bounds.x1 = floor(fw * prim.bounds.x1 + 0.5f); + prim.bounds.y0 = floor(fh * prim.bounds.y0 + 0.5f); + prim.bounds.y1 = floor(fh * prim.bounds.y1 + 0.5f); } // render to it diff --git a/src/osd/windows/winmain.cpp b/src/osd/windows/winmain.cpp index c4a1c458768..55cbde387e6 100644 --- a/src/osd/windows/winmain.cpp +++ b/src/osd/windows/winmain.cpp @@ -1049,7 +1049,7 @@ const char *symbol_manager::symbol_for_address(FPTR address) if (!query_system_for_address(address)) { // if that fails, scan the cache if we have one - if (m_cache.first() != nullptr) + if (!m_cache.empty()) scan_cache_for_address(address); // or else try to open a sym/map file and find it there @@ -1172,13 +1172,13 @@ void symbol_manager::scan_cache_for_address(FPTR address) FPTR best_addr = 0; // walk the cache, looking for valid entries - for (cache_entry *entry = m_cache.first(); entry != nullptr; entry = entry->next()) + for (cache_entry &entry : m_cache) // if this is the best one so far, remember it - if (entry->m_address <= address && entry->m_address > best_addr) + if (entry.m_address <= address && entry.m_address > best_addr) { - best_addr = entry->m_address; - best_symbol = entry->m_name; + best_addr = entry.m_address; + best_symbol = entry.m_name; } // format the symbol and remember the last base