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