-emu/device.cpp: Allow flagging devices as not working or not supporting saved states.

* emu/device.cpp: Removed device_sound_interface from mixins that
  require device to register members for saved states.
* emu/machine.cpp: Finalise saved state registrations before loading
  configuration - network devices no longer leak timers.
* emu/validity.cpp: Added check for systems marked as supporting saved
  states that use devices lacking saved state support (besides slot
  cards).
* machine/mc6852.cpp: First device marked as not supporting saved
  states.
* osd/interface/audio.h: Avoid unnecessary float/double conversions.

-igs/igs_m027.cpp: Added I/O for ccly.
This commit is contained in:
Vas Crabb 2025-05-01 08:14:54 +10:00
parent 30be745e36
commit f0e38cbe5b
36 changed files with 465 additions and 229 deletions

View File

@ -19,7 +19,6 @@ plg1x0_connector::plg1x0_connector(const machine_config &mconfig, const char *ta
void plg1x0_connector::device_start()
{
save_item(NAME(m_dummy_save));
}
void plg1x0_connector::midi_rx(int state)

View File

@ -53,7 +53,6 @@ public:
void do_midi_tx(int state) { m_midi_tx(state); }
protected:
bool m_dummy_save = false; // needed for save-state support
devcb_write_line m_midi_tx;
virtual void device_start() override ATTR_COLD;

View File

@ -4,6 +4,7 @@
#include "keyboard.h"
namespace {
INPUT_PORTS_START(serial_keyboard)
PORT_INCLUDE(generic_keyboard)
@ -12,6 +13,7 @@ INPUT_PORTS_START(serial_keyboard)
PORT_RS232_PARITY("RS232_PARITY", RS232_PARITY_NONE, "Parity", serial_keyboard_device, update_serial)
PORT_RS232_STOPBITS("RS232_STOPBITS", RS232_STOPBITS_1, "Stop Bits", serial_keyboard_device, update_serial)
INPUT_PORTS_END
} // anonymous namespace
serial_keyboard_device::serial_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)

View File

@ -58,9 +58,6 @@ void svi_expander_device::device_start()
{
// get inserted module
m_module = get_card_device();
// register for save states
save_item(NAME(m_dummy_save));
}
//-------------------------------------------------

View File

@ -112,8 +112,6 @@ private:
devcb_read8 m_excsr_handler;
devcb_write8 m_excsw_handler;
bool m_dummy_save = false; // needed for save-state support
};

View File

@ -22,7 +22,6 @@ waveblaster_connector::waveblaster_connector(const machine_config &mconfig, cons
void waveblaster_connector::device_start()
{
save_item(NAME(m_dummy_save));
}
void waveblaster_connector::midi_rx(int state)

View File

@ -31,7 +31,6 @@ public:
void do_midi_tx(int state) { m_midi_tx(state); }
protected:
bool m_dummy_save = false; // needed for save-state support
devcb_write_line m_midi_tx;
virtual void device_start() override ATTR_COLD;

View File

@ -41,6 +41,8 @@ class mc6852_device : public device_t,
public device_serial_interface
{
public:
static constexpr flags_type emulation_flags() { return flags::SAVE_UNSUPPORTED; }
// construction/destruction
mc6852_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

View File

@ -27,6 +27,4 @@ mixer_device::mixer_device(const machine_config &mconfig, const char *tag, devic
void mixer_device::device_start()
{
// register for save states
save_item(NAME(m_dummy_save));
}

View File

@ -20,11 +20,8 @@ public:
mixer_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
protected:
// device-level overrides
// device_t implementation
virtual void device_start() override ATTR_COLD;
private:
bool m_dummy_save = false; // needed for save-state support
};
#endif // MAME_SOUND_MIXER_H

View File

@ -544,11 +544,10 @@ void device_t::start()
// complain if nothing was registered by the device
state_registrations = machine().save().registration_count() - state_registrations;
device_execute_interface *exec;
device_sound_interface *sound;
if (state_registrations == 0 && (interface(exec) || interface(sound)) && type() != SPEAKER && type() != MICROPHONE)
if ((state_registrations == 0) && interface(exec))
{
logerror("Device did not register any state to save!\n");
if ((machine().system().flags & MACHINE_SUPPORTS_SAVE) != 0)
if (!(type().emulation_flags() & flags::SAVE_UNSUPPORTED))
fatalerror("Device '%s' did not register any state to save!\n", tag());
}

View File

@ -63,6 +63,18 @@ template <typename T>
using is_device_interface = std::bool_constant<std::is_base_of_v<device_interface, T> && !is_device_implementation<T>::value>;
struct device_flags
{
enum type : u16
{
NOT_WORKING = u16(1) << 0,
SAVE_UNSUPPORTED = u16(1) << 1,
NONE = u16(0),
ALL = (u16(1) << 2) - 1U
};
};
struct device_feature
{
enum type : u32
@ -107,6 +119,7 @@ struct device_feature
};
};
DECLARE_ENUM_BITWISE_OPERATORS(device_flags::type);
DECLARE_ENUM_BITWISE_OPERATORS(device_feature::type);
@ -165,14 +178,9 @@ private:
template <class DeviceClass, char const *ShortName, char const *FullName, char const *Source>
struct device_tag_struct { typedef DeviceClass type; };
template <class DriverClass, char const *ShortName, char const *FullName, char const *Source, device_feature::type Unemulated, device_feature::type Imperfect>
template <class DriverClass, char const *ShortName, char const *FullName, char const *Source, device_flags::type Flags, device_feature::type Unemulated, device_feature::type Imperfect>
struct driver_tag_struct { typedef DriverClass type; };
template <class DeviceClass, char const *ShortName, char const *FullName, char const *Source>
auto device_tag_func() { return device_tag_struct<DeviceClass, ShortName, FullName, Source>{ }; };
template <class DriverClass, char const *ShortName, char const *FullName, char const *Source, device_feature::type Unemulated, device_feature::type Imperfect>
auto driver_tag_func() { return driver_tag_struct<DriverClass, ShortName, FullName, Source, Unemulated, Imperfect>{ }; };
class device_type_impl_base
{
private:
@ -205,6 +213,7 @@ private:
char const *const m_shortname;
char const *const m_fullname;
char const *const m_source;
device_flags::type const m_emulation_flags;
device_feature::type const m_unemulated_features;
device_feature::type const m_imperfect_features;
device_type_impl_base const *const m_parent_rom;
@ -220,6 +229,7 @@ public:
, m_shortname(nullptr)
, m_fullname(nullptr)
, m_source(nullptr)
, m_emulation_flags(device_flags::NONE)
, m_unemulated_features(device_feature::NONE)
, m_imperfect_features(device_feature::NONE)
, m_parent_rom(nullptr)
@ -228,12 +238,13 @@ public:
}
template <class DeviceClass, char const *ShortName, char const *FullName, char const *Source>
device_type_impl_base(device_tag_struct<DeviceClass, ShortName, FullName, Source> (*)())
device_type_impl_base(device_tag_struct<DeviceClass, ShortName, FullName, Source>)
: m_creator(&create_device<DeviceClass>)
, m_type(typeid(DeviceClass))
, m_shortname(ShortName)
, m_fullname(FullName)
, m_source(Source)
, m_emulation_flags(DeviceClass::emulation_flags())
, m_unemulated_features(DeviceClass::unemulated_features())
, m_imperfect_features(DeviceClass::imperfect_features())
, m_parent_rom(DeviceClass::parent_rom_device_type())
@ -241,13 +252,14 @@ public:
{
}
template <class DriverClass, char const *ShortName, char const *FullName, char const *Source, device_feature::type Unemulated, device_feature::type Imperfect>
device_type_impl_base(driver_tag_struct<DriverClass, ShortName, FullName, Source, Unemulated, Imperfect> (*)())
template <class DriverClass, char const *ShortName, char const *FullName, char const *Source, device_flags::type Flags, device_feature::type Unemulated, device_feature::type Imperfect>
device_type_impl_base(driver_tag_struct<DriverClass, ShortName, FullName, Source, Flags, Unemulated, Imperfect>)
: m_creator(&create_driver<DriverClass>)
, m_type(typeid(DriverClass))
, m_shortname(ShortName)
, m_fullname(FullName)
, m_source(Source)
, m_emulation_flags(DriverClass::emulation_flags() | Flags)
, m_unemulated_features(DriverClass::unemulated_features() | Unemulated)
, m_imperfect_features((DriverClass::imperfect_features() & ~Unemulated) | Imperfect)
, m_parent_rom(DriverClass::parent_rom_device_type())
@ -259,6 +271,7 @@ public:
char const *shortname() const { return m_shortname; }
char const *fullname() const { return m_fullname; }
char const *source() const { return m_source; }
device_flags::type emulation_flags() const { return m_emulation_flags; }
device_feature::type unemulated_features() const { return m_unemulated_features; }
device_feature::type imperfect_features() const { return m_imperfect_features; }
device_type_impl_base const *parent_rom_device_type() const { return m_parent_rom; }
@ -306,22 +319,6 @@ typedef emu::detail::device_type_impl_base const &device_type;
typedef std::add_pointer_t<device_type> device_type_ptr;
extern emu::detail::device_registrar const registered_device_types;
template <
typename DeviceClass,
char const *ShortName,
char const *FullName,
char const *Source>
constexpr auto device_creator = &emu::detail::device_tag_func<DeviceClass, ShortName, FullName, Source>;
template <
typename DriverClass,
char const *ShortName,
char const *FullName,
char const *Source,
emu::detail::device_feature::type Unemulated,
emu::detail::device_feature::type Imperfect>
constexpr auto driver_device_creator = &emu::detail::driver_tag_func<DriverClass, ShortName, FullName, Source, Unemulated, Imperfect>;
/// \addtogroup machinedef
/// \{
@ -404,7 +401,7 @@ constexpr auto driver_device_creator = &emu::detail::driver_tag_func<DriverClass
struct Type##_device_traits { static constexpr char const shortname[] = ShortName, fullname[] = FullName, source[] = __FILE__; }; \
constexpr char const Type##_device_traits::shortname[], Type##_device_traits::fullname[], Type##_device_traits::source[]; \
} \
emu::detail::device_type_impl<Class> const Type = device_creator<Class, (Type##_device_traits::shortname), (Type##_device_traits::fullname), (Type##_device_traits::source)>; \
emu::detail::device_type_impl<Class> const Type = emu::detail::device_tag_struct<Class, (Type##_device_traits::shortname), (Type##_device_traits::fullname), (Type##_device_traits::source)>{ }; \
template class device_finder<Class, false>; \
template class device_finder<Class, true>;
@ -440,7 +437,7 @@ constexpr auto driver_device_creator = &emu::detail::driver_tag_func<DriverClass
struct Type##_device_traits { static constexpr char const shortname[] = ShortName, fullname[] = FullName, source[] = __FILE__; }; \
constexpr char const Type##_device_traits::shortname[], Type##_device_traits::fullname[], Type##_device_traits::source[]; \
} \
emu::detail::device_type_impl<Base> const Type = device_creator<Class, (Type##_device_traits::shortname), (Type##_device_traits::fullname), (Type##_device_traits::source)>;
emu::detail::device_type_impl<Base> const Type = emu::detail::device_tag_struct<Class, (Type##_device_traits::shortname), (Type##_device_traits::fullname), (Type##_device_traits::source)>{ };
/// \}
@ -565,9 +562,22 @@ protected:
public:
// device flags
using flags = emu::detail::device_flags;
using flags_type = emu::detail::device_flags::type;
using feature = emu::detail::device_feature;
using feature_type = emu::detail::device_feature::type;
/// \brief Report emulation status flags
///
/// Implement this member in a derived class to declare flags
/// pertaining to the overall emulation status of the device. Some
/// flags propagate to all other devices and systems that use the
/// device.
/// \return Bitwise or of the flag constants pertaining to the
/// device emulation.
/// \sa unemulated_features imperfect_features
static constexpr flags_type emulation_flags() { return flags::NONE; }
/// \brief Report unemulated features
///
/// Implement this member in a derived class to declare features
@ -577,7 +587,7 @@ public:
/// displayed on starting a system.
/// \return Bitwise or of the feature constants for unemulated
/// features of the device.
/// \sa imperfect_features
/// \sa emulation_flags imperfect_features
static constexpr feature_type unemulated_features() { return feature::NONE; }
/// \brief Report imperfectly emulated features
@ -594,7 +604,7 @@ public:
/// in a red warning being displayed when starting a system.
/// \return Bitwise or of the feature constants for imperfectly
/// emulated features of the device.
/// \sa unemulated_features
/// \sa emulation_flags unemulated_features
static constexpr feature_type imperfect_features() { return feature::NONE; }
/// \brief Get parent device type for ROM search

View File

@ -40,15 +40,13 @@ struct machine_flags
ROT180 = FLIP_X | FLIP_Y,
ROT270 = FLIP_Y | SWAP_XY,
NOT_WORKING = 0x0000'0040,
SUPPORTS_SAVE = 0x0000'0080, // system supports save states
NO_COCKTAIL = 0x0000'0100, // screen flip support is missing
IS_BIOS_ROOT = 0x0000'0200, // this driver entry is a BIOS root
REQUIRES_ARTWORK = 0x0000'0400, // requires external artwork for key game elements
UNOFFICIAL = 0x0000'0800, // unofficial hardware modification
NO_SOUND_HW = 0x0000'1000, // system has no sound output
MECHANICAL = 0x0000'2000, // contains mechanical parts (pinball, redemption games, ...)
IS_INCOMPLETE = 0x0000'4000 // official system with blatantly incomplete hardware/software
NO_COCKTAIL = 0x0000'0040, // screen flip support is missing
IS_BIOS_ROOT = 0x0000'0080, // this driver entry is a BIOS root
REQUIRES_ARTWORK = 0x0000'0100, // requires external artwork for key game elements
UNOFFICIAL = 0x0000'0200, // unofficial hardware modification
NO_SOUND_HW = 0x0000'0400, // system has no sound output
MECHANICAL = 0x0000'0800, // contains mechanical parts (pinball, redemption games, ...)
IS_INCOMPLETE = 0x0000'1000 // official system with blatantly incomplete hardware/software
};
};
@ -65,8 +63,6 @@ DECLARE_ENUM_BITWISE_OPERATORS(machine_flags::type);
/// \{
// flags for machine drivers
constexpr u64 MACHINE_NOT_WORKING = machine_flags::NOT_WORKING; ///< Imperfect emulation prevents using the system as intended
constexpr u64 MACHINE_SUPPORTS_SAVE = machine_flags::SUPPORTS_SAVE; ///< All devices in the system supports save states (enables auto save feature, and won't show a warning on using save states)
constexpr u64 MACHINE_NO_COCKTAIL = machine_flags::NO_COCKTAIL; ///< The system supports screen flipping for use in a cocktail cabinet, but this feature is not properly emulated
constexpr u64 MACHINE_IS_BIOS_ROOT = machine_flags::IS_BIOS_ROOT; ///< The system represents an empty system board of some kind - clones are treated as separate systems rather than variants
constexpr u64 MACHINE_REQUIRES_ARTWORK = machine_flags::REQUIRES_ARTWORK; ///< The system requires external artwork for key functionality
@ -75,18 +71,20 @@ constexpr u64 MACHINE_NO_SOUND_HW = machine_flags::NO_SOUND_HW;
constexpr u64 MACHINE_MECHANICAL = machine_flags::MECHANICAL; ///< The system depends on mechanical features for key functionality
constexpr u64 MACHINE_IS_INCOMPLETE = machine_flags::IS_INCOMPLETE; ///< The system represents an incomplete prototype
// flags that map to device feature flags
constexpr u64 MACHINE_UNEMULATED_PROTECTION = 0x00000001'00000000; ///< Some form of protection is imperfectly emulated (e.g. copy protection or anti-tampering)
constexpr u64 MACHINE_WRONG_COLORS = 0x00000002'00000000; ///< Colours are completely wrong
constexpr u64 MACHINE_IMPERFECT_COLORS = 0x00000004'00000000; ///< Colours are close but not completely accurate
constexpr u64 MACHINE_IMPERFECT_GRAPHICS = 0x00000008'00000000; ///< Graphics are emulated incorrectly for the system
constexpr u64 MACHINE_NO_SOUND = 0x00000010'00000000; ///< The system has sound output, but it is not emulated
constexpr u64 MACHINE_IMPERFECT_SOUND = 0x00000020'00000000; ///< Sound is known to be imperfectly emulated for the system
constexpr u64 MACHINE_IMPERFECT_CONTROLS = 0x00000040'00000000; ///< Controls or inputs are emulated imperfectly for the system
constexpr u64 MACHINE_NODEVICE_MICROPHONE = 0x00000080'00000000; ///< The system has unemulated audio capture functionality
constexpr u64 MACHINE_NODEVICE_PRINTER = 0x00000100'00000000; ///< The system has unemulated printer functionality
constexpr u64 MACHINE_NODEVICE_LAN = 0x00000200'00000000; ///< The system has unemulated local area networking
constexpr u64 MACHINE_IMPERFECT_TIMING = 0x00000400'00000000; ///< Timing is known to be imperfectly emulated for the system
// flags that map to device emulation and feature flags
constexpr u64 MACHINE_NOT_WORKING = 0x00000001'00000000; ///< Imperfect emulation prevents using the system as intended
constexpr u64 MACHINE_SUPPORTS_SAVE = 0x00000002'00000000; ///< All devices in the system supports save states (enables auto save feature, and won't show a warning on using save states)
constexpr u64 MACHINE_UNEMULATED_PROTECTION = 0x00000004'00000000; ///< Some form of protection is imperfectly emulated (e.g. copy protection or anti-tampering)
constexpr u64 MACHINE_WRONG_COLORS = 0x00000008'00000000; ///< Colours are completely wrong
constexpr u64 MACHINE_IMPERFECT_COLORS = 0x00000010'00000000; ///< Colours are close but not completely accurate
constexpr u64 MACHINE_IMPERFECT_GRAPHICS = 0x00000020'00000000; ///< Graphics are emulated incorrectly for the system
constexpr u64 MACHINE_NO_SOUND = 0x00000040'00000000; ///< The system has sound output, but it is not emulated
constexpr u64 MACHINE_IMPERFECT_SOUND = 0x00000080'00000000; ///< Sound is known to be imperfectly emulated for the system
constexpr u64 MACHINE_IMPERFECT_CONTROLS = 0x00000100'00000000; ///< Controls or inputs are emulated imperfectly for the system
constexpr u64 MACHINE_NODEVICE_MICROPHONE = 0x00000200'00000000; ///< The system has unemulated audio capture functionality
constexpr u64 MACHINE_NODEVICE_PRINTER = 0x00000400'00000000; ///< The system has unemulated printer functionality
constexpr u64 MACHINE_NODEVICE_LAN = 0x00000800'00000000; ///< The system has unemulated local area networking
constexpr u64 MACHINE_IMPERFECT_TIMING = 0x00001000'00000000; ///< Timing is known to be imperfectly emulated for the system
/// \}
/// \}
@ -107,6 +105,20 @@ public:
typedef void (*machine_creator_wrapper)(machine_config &, device_t &);
typedef void (*driver_init_wrapper)(device_t &);
/// \brief Get emulation flags
///
/// Converts system flags corresponding to device emulation flags to
/// a device flags type bit field.
/// \param [in] flags A system flags bit field.
/// \return A device flags type bit field corresponding to emulation
/// flags declared in the \p flags argument.
static constexpr device_t::flags_type emulation_flags(u64 flags)
{
return
((flags & MACHINE_NOT_WORKING) ? device_t::flags::NOT_WORKING : device_t::flags::NONE) |
((flags & MACHINE_SUPPORTS_SAVE) ? device_t::flags::NONE : device_t::flags::SAVE_UNSUPPORTED);
}
/// \brief Get unemulated system features
///
/// Converts system flags corresponding to unemulated device
@ -169,18 +181,19 @@ public:
// static game traits
#define GAME_DRIVER_TRAITS(NAME, FULLNAME) \
namespace { \
struct GAME_TRAITS_NAME(NAME) { static constexpr char const shortname[] = #NAME, fullname[] = FULLNAME, source[] = __FILE__; }; \
constexpr char const GAME_TRAITS_NAME(NAME)::shortname[], GAME_TRAITS_NAME(NAME)::fullname[], GAME_TRAITS_NAME(NAME)::source[]; \
}
namespace { \
struct GAME_TRAITS_NAME(NAME) { static constexpr char const shortname[] = #NAME, fullname[] = FULLNAME, source[] = __FILE__; }; \
constexpr char const GAME_TRAITS_NAME(NAME)::shortname[], GAME_TRAITS_NAME(NAME)::fullname[], GAME_TRAITS_NAME(NAME)::source[]; \
}
#define GAME_DRIVER_TYPE(NAME, CLASS, FLAGS) \
driver_device_creator< \
CLASS, \
(GAME_TRAITS_NAME(NAME)::shortname), \
(GAME_TRAITS_NAME(NAME)::fullname), \
(GAME_TRAITS_NAME(NAME)::source), \
game_driver::unemulated_features(FLAGS), \
game_driver::imperfect_features(FLAGS)>
emu::detail::driver_tag_struct< \
CLASS, \
(GAME_TRAITS_NAME(NAME)::shortname), \
(GAME_TRAITS_NAME(NAME)::fullname), \
(GAME_TRAITS_NAME(NAME)::source), \
game_driver::emulation_flags(FLAGS), \
game_driver::unemulated_features(FLAGS), \
game_driver::imperfect_features(FLAGS)>{ }
/// \addtogroup machinedef

View File

@ -234,14 +234,28 @@ void running_machine::start()
if (filename[0] != 0 && !m_video->is_recording())
m_video->begin_recording(filename, movie_recording::format::AVI);
// if we're coming in with a savegame request, process it now
const char *savegame = options().state();
if (savegame[0] != 0)
{
// if we're coming in with a savegame request, process it now
schedule_load(savegame);
// if we're in autosave mode, schedule a load
else if (options().autosave() && (m_system.flags & MACHINE_SUPPORTS_SAVE) != 0)
schedule_load("auto");
}
else if (options().autosave())
{
// if we're in autosave mode, schedule a load
// m_save.supported() won't be set until save state registrations are finalised
bool supported = true;
for (device_t &device : device_enumerator(root_device()))
{
if (device.type().emulation_flags() & device_t::flags::SAVE_UNSUPPORTED)
{
supported = false;
break;
}
}
if (supported)
schedule_load("auto");
}
manager().update_machine();
}
@ -286,15 +300,13 @@ int running_machine::run(bool quiet)
// then finish setting up our local machine
start();
// disallow save state registrations starting here
m_save.allow_registration(false);
// load the configuration settings
manager().before_load_settings(*this);
m_configuration->load_settings();
// disallow save state registrations starting here.
// Don't do it earlier, config load can create network
// devices with timers.
m_save.allow_registration(false);
// load the NVRAM
nvram_load();
@ -413,7 +425,7 @@ void running_machine::schedule_exit()
m_scheduler.eat_all_cycles();
// if we're autosaving on exit, schedule a save as well
if (options().autosave() && (m_system.flags & MACHINE_SUPPORTS_SAVE) && this->time() > attotime::zero)
if (options().autosave() && m_save.supported() && (this->time() > attotime::zero))
schedule_save("auto");
}
@ -910,7 +922,7 @@ void running_machine::handle_saveload()
case STATERR_NONE:
{
const char *const opnamed = (m_saveload_schedule == saveload_schedule::LOAD) ? "Loaded" : "Saved";
if (!(m_system.flags & MACHINE_SUPPORTS_SAVE))
if (!m_save.supported())
popmessage("%s state %s %s.\nWarning: Save states are not officially supported for this system.", opnamed, preposname, m_saveload_pending_file);
else
popmessage("%s state %s %s.", opnamed, preposname, m_saveload_pending_file);

View File

@ -67,6 +67,7 @@ enum
save_manager::save_manager(running_machine &machine)
: m_machine(machine)
, m_reg_allowed(true)
, m_supported(false)
{
m_rewind = std::make_unique<rewinder>(*this);
}
@ -100,6 +101,16 @@ void save_manager::allow_registration(bool allowed)
if (dupes_found)
fatalerror("%d duplicate save state entries found.\n", dupes_found);
m_supported = true;
for (device_t &device : device_enumerator(machine().root_device()))
{
if (device.type().emulation_flags() & device_t::flags::SAVE_UNSUPPORTED)
{
m_supported = false;
break;
}
}
dump_registry();
// everything is registered by now, evaluate the savestate size
@ -934,7 +945,7 @@ void rewinder::report_error(save_error error, rewind_operation operation)
// success
case STATERR_NONE:
{
const u64 supported = m_save.machine().system().flags & MACHINE_SUPPORTS_SAVE;
const u64 supported = m_save.supported();
const char *const warning = supported || !m_first_time_warning ? "" :
"Rewind warning: Save states are not officially supported for this machine.\n";
const char *const opnamed = (operation == rewind_operation::LOAD) ? "loaded" : "captured";

View File

@ -159,6 +159,7 @@ public:
rewinder *rewind() { return m_rewind.get(); }
int registration_count() const { return m_entry_list.size(); }
bool registration_allowed() const { return m_reg_allowed; }
bool supported() const { return m_supported; }
// registration control
void allow_registration(bool allowed = true);
@ -333,6 +334,7 @@ private:
running_machine & m_machine; // reference to our machine
std::unique_ptr<rewinder> m_rewind; // rewinder
bool m_reg_allowed; // are registrations allowed?
bool m_supported; // are saved states supported?
std::vector<std::unique_ptr<state_entry>> m_entry_list; // list of registered entries
std::vector<std::unique_ptr<ram_state>> m_ramstate_list; // list of ram states

View File

@ -2144,6 +2144,49 @@ void validity_checker::validate_driver(device_t &root)
osd_printf_error("Driver cannot have features that are both unemulated and imperfect (0x%08X)\n", util::underlying_value(unemulated & imperfect));
if ((m_current_driver->flags & machine_flags::NO_SOUND_HW) && ((unemulated | imperfect) & device_t::feature::SOUND))
osd_printf_error("Machine without sound hardware cannot have unemulated/imperfect sound\n");
// catch systems marked as supporting save states that contain devices that don't support save states
if (!(m_current_driver->type.emulation_flags() & device_t::flags::SAVE_UNSUPPORTED))
{
std::set<std::add_pointer_t<device_type> > nosave;
device_enumerator iter(root);
std::string_view cardtag;
for (auto &device : iter)
{
// ignore any children of a slot card
if (!cardtag.empty())
{
std::string_view tag(device.tag());
if ((tag.length() > cardtag.length()) && (tag.substr(0, cardtag.length()) == cardtag) && tag[cardtag.length()] == ':')
continue;
else
cardtag = std::string_view();
}
// check to see if this is a slot card
device_t *const parent(device.owner());
if (parent)
{
device_slot_interface *slot;
parent->interface(slot);
if (slot && (slot->get_card_device() == &device))
{
cardtag = device.tag();
continue;
}
}
if (device.type().emulation_flags() & device_t::flags::SAVE_UNSUPPORTED)
nosave.emplace(&device.type());
}
if (!nosave.empty())
{
std::ostringstream buf;
for (auto const &devtype : nosave)
util::stream_format(buf, "%s(%s) %s\n", core_filename_extract_base(devtype->source()), devtype->shortname(), devtype->fullname());
osd_printf_error("Machine is marked as supporting save states but uses devices that lack save state support:\n%s", std::move(buf).str());
}
}
}

View File

@ -143,7 +143,7 @@ void output_input(std::ostream &out, const ioport_list &portlist);
void output_switches(std::ostream &out, const ioport_list &portlist, const char *root_tag, int type, const char *outertag, const char *loctag, const char *innertag);
void output_ports(std::ostream &out, const ioport_list &portlist);
void output_adjusters(std::ostream &out, const ioport_list &portlist);
void output_driver(std::ostream &out, game_driver const &driver, device_t::feature_type unemulated, device_t::feature_type imperfect);
void output_driver(std::ostream &out, game_driver const &driver, device_t::flags_type flags, device_t::feature_type unemulated, device_t::feature_type imperfect);
void output_features(std::ostream &out, device_type type, device_t::feature_type unemulated, device_t::feature_type imperfect);
void output_images(std::ostream &out, device_t &device, const char *root_tag);
void output_slots(std::ostream &out, machine_config &config, device_t &device, const char *root_tag, device_type_set *devtypes);
@ -699,6 +699,7 @@ void output_one(std::ostream &out, driver_enumerator &drivlist, const game_drive
// allocate input ports and build overall emulation status
ioport_list portlist;
device_t::flags_type overall_flags(driver.type.emulation_flags());
device_t::feature_type overall_unemulated(driver.type.unemulated_features());
device_t::feature_type overall_imperfect(driver.type.imperfect_features());
{
@ -706,6 +707,7 @@ void output_one(std::ostream &out, driver_enumerator &drivlist, const game_drive
for (device_t &device : iter)
{
portlist.append(device, errors);
overall_flags |= device.type().emulation_flags() & ~device_t::flags::NOT_WORKING;
overall_unemulated |= device.type().unemulated_features();
overall_imperfect |= device.type().imperfect_features();
@ -791,7 +793,7 @@ void output_one(std::ostream &out, driver_enumerator &drivlist, const game_drive
output_switches(out, portlist, "", IPT_CONFIG, "configuration", "conflocation", "confsetting");
output_ports(out, portlist);
output_adjusters(out, portlist);
output_driver(out, driver, overall_unemulated, overall_imperfect);
output_driver(out, driver, overall_flags, overall_unemulated, overall_imperfect);
output_features(out, driver.type, overall_unemulated, overall_imperfect);
output_images(out, config.root_device(), "");
output_slots(out, config, config.root_device(), "", devtypes);
@ -1998,7 +2000,12 @@ void output_adjusters(std::ostream &out, const ioport_list &portlist)
// output_driver - print driver status
//-------------------------------------------------
void output_driver(std::ostream &out, game_driver const &driver, device_t::feature_type unemulated, device_t::feature_type imperfect)
void output_driver(
std::ostream &out,
game_driver const &driver,
device_t::flags_type flags,
device_t::feature_type unemulated,
device_t::feature_type imperfect)
{
out << "\t\t<driver";
@ -2011,8 +2018,9 @@ void output_driver(std::ostream &out, game_driver const &driver, device_t::featu
emulation problems.
*/
u32 const flags = driver.flags;
bool const machine_preliminary(flags & (machine_flags::NOT_WORKING | machine_flags::MECHANICAL));
u32 const driver_flags = driver.flags;
bool const not_working(driver.type.emulation_flags() & device_t::flags::NOT_WORKING);
bool const machine_preliminary(not_working || (driver_flags & machine_flags::MECHANICAL));
bool const unemulated_preliminary(unemulated & (device_t::feature::PALETTE | device_t::feature::GRAPHICS | device_t::feature::SOUND | device_t::feature::KEYBOARD));
bool const imperfect_preliminary((unemulated | imperfect) & device_t::feature::PROTECTION);
@ -2023,29 +2031,29 @@ void output_driver(std::ostream &out, game_driver const &driver, device_t::featu
else
out << " status=\"good\"";
if (flags & machine_flags::NOT_WORKING)
if (not_working)
out << " emulation=\"preliminary\"";
else
out << " emulation=\"good\"";
if (flags & machine_flags::NO_COCKTAIL)
if (driver_flags & machine_flags::NO_COCKTAIL)
out << " cocktail=\"preliminary\"";
if (flags & machine_flags::SUPPORTS_SAVE)
out << " savestate=\"supported\"";
else
if (flags & device_t::flags::SAVE_UNSUPPORTED)
out << " savestate=\"unsupported\"";
else
out << " savestate=\"supported\"";
if (flags & machine_flags::REQUIRES_ARTWORK)
if (driver_flags & machine_flags::REQUIRES_ARTWORK)
out << " requiresartwork=\"yes\"";
if (flags & machine_flags::UNOFFICIAL)
if (driver_flags & machine_flags::UNOFFICIAL)
out << " unofficial=\"yes\"";
if (flags & machine_flags::NO_SOUND_HW)
if (driver_flags & machine_flags::NO_SOUND_HW)
out << " nosoundhardware=\"yes\"";
if (flags & machine_flags::IS_INCOMPLETE)
if (driver_flags & machine_flags::IS_INCOMPLETE)
out << " incomplete=\"yes\"";
out << "/>\n";

View File

@ -1527,8 +1527,8 @@ void lua_engine::initialize()
}
return rot;
});
game_driver_type["not_working"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::NOT_WORKING) != 0; });
game_driver_type["supports_save"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::SUPPORTS_SAVE) != 0; });
game_driver_type["not_working"] = sol::property([] (game_driver const &driver) { return (driver.type.emulation_flags() & device_t::flags::NOT_WORKING) != 0; });
game_driver_type["supports_save"] = sol::property([] (game_driver const &driver) { return (driver.type.emulation_flags() & device_t::flags::SAVE_UNSUPPORTED) == 0; });
game_driver_type["no_cocktail"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::NO_COCKTAIL) != 0; });
game_driver_type["is_bios_root"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::IS_BIOS_ROOT) != 0; });
game_driver_type["requires_artwork"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::REQUIRES_ARTWORK) != 0; });

View File

@ -36,9 +36,10 @@ namespace ui {
namespace {
constexpr machine_flags::type MACHINE_ERRORS = machine_flags::NOT_WORKING | machine_flags::MECHANICAL;
constexpr machine_flags::type MACHINE_ERRORS = machine_flags::MECHANICAL;
constexpr machine_flags::type MACHINE_WARNINGS = machine_flags::NO_COCKTAIL | machine_flags::REQUIRES_ARTWORK;
constexpr machine_flags::type MACHINE_BTANB = machine_flags::NO_SOUND_HW | machine_flags::IS_INCOMPLETE;
constexpr device_t::flags_type DEVICE_ERRORS = device_t::flags::NOT_WORKING;
constexpr std::pair<device_t::feature_type, char const *> FEATURE_NAMES[] = {
{ device_t::feature::PROTECTION, N_p("emulation-feature", "protection") },
@ -63,7 +64,14 @@ constexpr std::pair<device_t::feature_type, char const *> FEATURE_NAMES[] = {
{ device_t::feature::LAN, N_p("emulation-feature", "LAN") },
{ device_t::feature::WAN, N_p("emulation-feature", "WAN") } };
void get_general_warnings(std::ostream &buf, running_machine &machine, machine_flags::type flags, device_t::feature_type unemulated, device_t::feature_type imperfect)
void get_general_warnings(
std::ostream &buf,
running_machine &machine,
machine_flags::type machflags,
device_t::flags_type devflags,
device_t::feature_type unemulated,
device_t::feature_type imperfect,
bool has_nonworking_devices)
{
// add a warning if any ROMs were loaded with warnings
bool bad_roms(false);
@ -79,7 +87,7 @@ void get_general_warnings(std::ostream &buf, running_machine &machine, machine_f
}
// if we have at least one warning flag, print the general header
if ((machine.rom_load().knownbad() > 0) || (flags & (MACHINE_ERRORS | MACHINE_WARNINGS | MACHINE_BTANB)) || unemulated || imperfect)
if ((machine.rom_load().knownbad() > 0) || (machflags & (MACHINE_ERRORS | MACHINE_WARNINGS | MACHINE_BTANB)) || (devflags & DEVICE_ERRORS) || unemulated || imperfect || has_nonworking_devices)
{
if (bad_roms)
buf << '\n';
@ -91,8 +99,12 @@ void get_general_warnings(std::ostream &buf, running_machine &machine, machine_f
buf << _("One or more ROMs/disk images for this system have not been correctly dumped.\n");
}
void get_device_warnings(std::ostream &buf, device_t::feature_type unemulated, device_t::feature_type imperfect)
void get_device_warnings(std::ostream &buf, device_t::flags_type flags, device_t::feature_type unemulated, device_t::feature_type imperfect)
{
// add line for not working
if (flags & device_t::flags::NOT_WORKING)
buf << _("THIS DEVICE DOES NOT WORK.\n");
// add line for unemulated features
if (unemulated)
{
@ -126,48 +138,74 @@ void get_device_warnings(std::ostream &buf, device_t::feature_type unemulated, d
}
}
void get_system_warnings(std::ostream &buf, running_machine &machine, machine_flags::type flags, device_t::feature_type unemulated, device_t::feature_type imperfect)
void get_system_warnings(
std::ostream &buf,
running_machine &machine,
machine_flags::type machflags,
device_t::flags_type devflags,
device_t::feature_type unemulated,
device_t::feature_type imperfect,
bool has_nonworking_devices)
{
std::streampos start_position = buf.tellp();
// start with the unemulated/imperfect features
get_device_warnings(buf, unemulated, imperfect);
get_device_warnings(buf, device_t::flags::NONE, unemulated, imperfect);
// add one line per machine warning flag
if (flags & ::machine_flags::NO_COCKTAIL)
if (machflags & ::machine_flags::NO_COCKTAIL)
buf << _("Screen flipping in cocktail mode is not supported.\n");
if (flags & ::machine_flags::REQUIRES_ARTWORK)
if (machflags & ::machine_flags::REQUIRES_ARTWORK)
buf << _("This system requires external artwork files.\n");
// add the 'BTANB' warnings
if (flags & ::machine_flags::IS_INCOMPLETE)
if (machflags & ::machine_flags::IS_INCOMPLETE)
{
if (buf.tellp() > start_position)
buf << '\n';
buf << _("This system was never completed. It may exhibit strange behavior or missing elements that are not bugs in the emulation.\n");
}
if (flags & ::machine_flags::NO_SOUND_HW)
if (machflags & ::machine_flags::NO_SOUND_HW)
{
if (buf.tellp() > start_position)
buf << '\n';
buf << _("This system has no sound hardware, MAME will produce no sounds, this is expected behavior.\n");
}
// list devices that don't work
if (has_nonworking_devices)
{
if (buf.tellp() > start_position)
buf << '\n';
buf << _("The following devices do not work: ");
bool first = true;
std::set<std::add_pointer_t<device_type> > seen;
for (device_t &device : device_enumerator(machine.root_device()))
{
if ((device.type().emulation_flags() & device_t::flags::NOT_WORKING) && seen.insert(&device.type()).second)
{
util::stream_format(buf, first ? _("%s") : _(", %s"), device.type().fullname());
first = false;
}
}
buf << '\n';
}
// these are more severe warnings
if (flags & ::machine_flags::MECHANICAL)
if (machflags & ::machine_flags::MECHANICAL)
{
if (buf.tellp() > start_position)
buf << '\n';
buf << _("Elements of this system cannot be emulated accurately as they require physical interaction or consist of mechanical devices. It is not possible to fully experience this system.\n");
}
if (flags & ::machine_flags::NOT_WORKING)
if (devflags & device_t::flags::NOT_WORKING)
{
if (buf.tellp() > start_position)
buf << '\n';
buf << _("THIS SYSTEM DOESN'T WORK. The emulation for this system is not yet complete. There is nothing you can do to fix this problem except wait for the developers to improve the emulation.\n");
}
if ((flags & MACHINE_ERRORS) || ((machine.system().type.unemulated_features() | machine.system().type.imperfect_features()) & device_t::feature::PROTECTION))
if ((machflags & MACHINE_ERRORS) || (devflags & DEVICE_ERRORS) || ((machine.system().type.unemulated_features() | machine.system().type.imperfect_features()) & device_t::feature::PROTECTION))
{
// find the parent of this driver
driver_enumerator drivlist(machine.options());
@ -183,7 +221,7 @@ void get_system_warnings(std::ostream &buf, running_machine &machine, machine_fl
if (drivlist.current() == maindrv || drivlist.clone() == maindrv)
{
game_driver const &driver(drivlist.driver());
if (!(driver.flags & MACHINE_ERRORS) && !((driver.type.unemulated_features() | driver.type.imperfect_features()) & device_t::feature::PROTECTION))
if (!(driver.flags & MACHINE_ERRORS) && !(driver.type.emulation_flags() & DEVICE_ERRORS) && !((driver.type.unemulated_features() | driver.type.imperfect_features()) & device_t::feature::PROTECTION))
{
// this one works, add a header and display the name of the clone
if (!foundworking)
@ -220,8 +258,10 @@ machine_static_info::machine_static_info(const ui_options &options, machine_conf
machine_static_info::machine_static_info(const ui_options &options, machine_config const &config, ioport_list const *ports)
: m_options(options)
, m_flags(config.gamedrv().flags)
, m_emulation_flags(config.gamedrv().type.emulation_flags())
, m_unemulated_features(config.gamedrv().type.unemulated_features())
, m_imperfect_features(config.gamedrv().type.imperfect_features())
, m_has_nonworking_devices(false)
, m_has_bioses(false)
, m_has_dips(false)
, m_has_configs(false)
@ -238,8 +278,10 @@ machine_static_info::machine_static_info(const ui_options &options, machine_conf
m_flags &= ~::machine_flags::NO_SOUND_HW;
// build overall emulation status
m_emulation_flags |= device.type().emulation_flags() & ~device_t::flags::NOT_WORKING;
m_unemulated_features |= device.type().unemulated_features();
m_imperfect_features |= device.type().imperfect_features();
m_has_nonworking_devices = m_has_nonworking_devices || (device.type().emulation_flags() & device_t::flags::NOT_WORKING);
// look for BIOS options
device_t const *const parent(device.owner());
@ -297,9 +339,14 @@ machine_static_info::machine_static_info(const ui_options &options, machine_conf
// issues that warrant a yellow/red message
//-------------------------------------------------
bool machine_static_info::has_warnings() const
bool machine_static_info::has_warnings() const noexcept
{
return (machine_flags() & (MACHINE_ERRORS | MACHINE_WARNINGS)) || unemulated_features() || imperfect_features();
return
(machine_flags() & (MACHINE_ERRORS | MACHINE_WARNINGS)) ||
(emulation_flags() & DEVICE_ERRORS) ||
unemulated_features() ||
imperfect_features() ||
has_nonworking_devices();
}
@ -308,10 +355,11 @@ bool machine_static_info::has_warnings() const
// system has issues that warrant a red message
//-------------------------------------------------
bool machine_static_info::has_severe_warnings() const
bool machine_static_info::has_severe_warnings() const noexcept
{
return
(machine_flags() & MACHINE_ERRORS) ||
(emulation_flags() & DEVICE_ERRORS) ||
(unemulated_features() & (device_t::feature::PROTECTION | device_t::feature::GRAPHICS | device_t::feature::SOUND)) ||
(imperfect_features() & device_t::feature::PROTECTION);
}
@ -322,7 +370,7 @@ bool machine_static_info::has_severe_warnings() const
// driver status box
//-------------------------------------------------
rgb_t machine_static_info::status_color() const
rgb_t machine_static_info::status_color() const noexcept
{
if (has_severe_warnings())
return UI_RED_COLOR;
@ -338,7 +386,7 @@ rgb_t machine_static_info::status_color() const
// warning message based on severity
//-------------------------------------------------
rgb_t machine_static_info::warnings_color() const
rgb_t machine_static_info::warnings_color() const noexcept
{
if (has_severe_warnings())
return UI_RED_COLOR;
@ -373,8 +421,8 @@ machine_info::machine_info(running_machine &machine)
std::string machine_info::warnings_string() const
{
std::ostringstream buf;
get_general_warnings(buf, m_machine, machine_flags(), unemulated_features(), imperfect_features());
get_system_warnings(buf, m_machine, machine_flags(), unemulated_features(), imperfect_features());
get_general_warnings(buf, m_machine, machine_flags(), emulation_flags(), unemulated_features(), imperfect_features(), has_nonworking_devices());
get_system_warnings(buf, m_machine, machine_flags(), emulation_flags(), unemulated_features(), imperfect_features(), has_nonworking_devices());
return buf.str();
}
@ -600,26 +648,26 @@ void menu_warn_info::populate_text(std::optional<text_layout> &layout, float &wi
machine_info const &info(ui().machine_info());
device_t &root(machine().root_device());
get_general_warnings(buf, machine(), info.machine_flags(), info.unemulated_features(), info.imperfect_features());
if ((info.machine_flags() & (MACHINE_ERRORS | MACHINE_WARNINGS | MACHINE_BTANB)) || root.type().unemulated_features() || root.type().imperfect_features())
get_general_warnings(buf, machine(), info.machine_flags(), info.emulation_flags(), info.unemulated_features(), info.imperfect_features(), info.has_nonworking_devices());
if ((info.machine_flags() & (MACHINE_ERRORS | MACHINE_WARNINGS | MACHINE_BTANB)) || (root.type().emulation_flags() & DEVICE_ERRORS) || root.type().unemulated_features() || root.type().imperfect_features())
{
seen.insert(&root.type());
if (!first)
buf << '\n';
first = false;
util::stream_format(buf, _("%1$s:\n"), root.name());
get_system_warnings(buf, machine(), info.machine_flags(), root.type().unemulated_features(), root.type().imperfect_features());
get_system_warnings(buf, machine(), info.machine_flags(), root.type().emulation_flags(), root.type().unemulated_features(), root.type().imperfect_features(), false);
}
for (device_t const &device : device_enumerator(root))
{
if ((device.type().unemulated_features() || device.type().imperfect_features()) && seen.insert(&device.type()).second)
if (((device.type().emulation_flags() & DEVICE_ERRORS) || device.type().unemulated_features() || device.type().imperfect_features()) && seen.insert(&device.type()).second)
{
if (!first)
buf << '\n';
first = false;
util::stream_format(buf, _("%1$s:\n"), device.name());
get_device_warnings(buf, device.type().unemulated_features(), device.type().imperfect_features());
get_device_warnings(buf, device.type().emulation_flags(), device.type().unemulated_features(), device.type().imperfect_features());
}
}

View File

@ -30,25 +30,27 @@ public:
machine_static_info(const ui_options &options, machine_config const &config);
// overall emulation status
::machine_flags::type machine_flags() const { return m_flags; }
device_t::feature_type unemulated_features() const { return m_unemulated_features; }
device_t::feature_type imperfect_features() const { return m_imperfect_features; }
::machine_flags::type machine_flags() const noexcept { return m_flags; }
device_t::flags_type emulation_flags() const noexcept { return m_emulation_flags; }
device_t::feature_type unemulated_features() const noexcept { return m_unemulated_features; }
device_t::feature_type imperfect_features() const noexcept { return m_imperfect_features; }
// has... getters
bool has_bioses() const { return m_has_bioses; }
bool has_nonworking_devices() const noexcept { return m_has_nonworking_devices; }
bool has_bioses() const noexcept { return m_has_bioses; }
// has input types getters
bool has_dips() const { return m_has_dips; }
bool has_configs() const { return m_has_configs; }
bool has_keyboard() const { return m_has_keyboard; }
bool has_test_switch() const { return m_has_test_switch; }
bool has_analog() const { return m_has_analog; }
bool has_dips() const noexcept { return m_has_dips; }
bool has_configs() const noexcept { return m_has_configs; }
bool has_keyboard() const noexcept { return m_has_keyboard; }
bool has_test_switch() const noexcept { return m_has_test_switch; }
bool has_analog() const noexcept { return m_has_analog; }
// warning severity indications
bool has_warnings() const;
bool has_severe_warnings() const;
rgb_t status_color() const;
rgb_t warnings_color() const;
bool has_warnings() const noexcept;
bool has_severe_warnings() const noexcept;
rgb_t status_color() const noexcept;
rgb_t warnings_color() const noexcept;
protected:
machine_static_info(const ui_options &options, machine_config const &config, ioport_list const &ports);
@ -60,10 +62,12 @@ private:
// overall feature status
::machine_flags::type m_flags;
device_t::flags_type m_emulation_flags;
device_t::feature_type m_unemulated_features;
device_t::feature_type m_imperfect_features;
// has...
bool m_has_nonworking_devices;
bool m_has_bioses;
// has input types

View File

@ -126,7 +126,7 @@ void menu_main::populate()
item_append(_("menu-main", "System Information"), 0, (void *)GAME_INFO);
if (ui().found_machine_warnings())
if (ui().machine_info().has_warnings())
item_append(_("menu-main", "Warning Information"), 0, (void *)WARN_INFO);
for (device_image_interface &image : image_interface_enumerator(machine().root_device()))

View File

@ -222,6 +222,7 @@ template void menu_select_launch::draw_left_panel<software_filter>(u32 flags, so
menu_select_launch::system_flags::system_flags(machine_static_info const &info)
: m_machine_flags(info.machine_flags())
, m_emulation_flags(info.emulation_flags())
, m_unemulated_features(info.unemulated_features())
, m_imperfect_features(info.imperfect_features())
, m_has_keyboard(info.has_keyboard())
@ -873,7 +874,7 @@ void menu_select_launch::custom_render(uint32_t flags, void *selectedref, float
// next line is overall driver status
system_flags const &flags(get_system_flags(driver));
if (flags.machine_flags() & machine_flags::NOT_WORKING)
if (flags.emulation_flags() & device_t::flags::NOT_WORKING)
tempbuf[2] = _("Status: NOT WORKING");
else if ((flags.unemulated_features() | flags.imperfect_features()) & device_t::feature::PROTECTION)
tempbuf[2] = _("Status: Unemulated Protection");
@ -4150,7 +4151,7 @@ void menu_select_launch::general_info(ui_system_info const *system, game_driver
if (flags.has_keyboard())
str << _("Keyboard Inputs\tYes\n");
if (flags.machine_flags() & machine_flags::NOT_WORKING)
if (flags.emulation_flags() & device_t::flags::NOT_WORKING)
str << _("Overall\tNOT WORKING\n");
else if ((flags.unemulated_features() | flags.imperfect_features()) & device_t::feature::PROTECTION)
str << _("Overall\tUnemulated Protection\n");
@ -4262,13 +4263,13 @@ void menu_select_launch::general_info(ui_system_info const *system, game_driver
else if (flags.imperfect_features() & device_t::feature::TIMING)
str << _("Timing\tImperfect\n");
str << ((flags.machine_flags() & machine_flags::MECHANICAL) ? _("Mechanical System\tYes\n") : _("Mechanical System\tNo\n"));
str << ((flags.machine_flags() & machine_flags::REQUIRES_ARTWORK) ? _("Requires Artwork\tYes\n") : _("Requires Artwork\tNo\n"));
str << ((flags.machine_flags() & machine_flags::MECHANICAL) ? _("Mechanical System\tYes\n") : _("Mechanical System\tNo\n"));
str << ((flags.machine_flags() & machine_flags::REQUIRES_ARTWORK) ? _("Requires Artwork\tYes\n") : _("Requires Artwork\tNo\n"));
if (flags.machine_flags() & machine_flags::NO_COCKTAIL)
str << _("Support Cocktail\tNo\n");
str << ((flags.machine_flags() & machine_flags::IS_BIOS_ROOT) ? _("System is BIOS\tYes\n") : _("System is BIOS\tNo\n"));
str << ((flags.machine_flags() & machine_flags::SUPPORTS_SAVE) ? _("Support Save\tYes\n") : _("Support Save\tNo\n"));
str << ((flags.machine_flags() & ORIENTATION_SWAP_XY) ? _("Screen Orientation\tVertical\n") : _("Screen Orientation\tHorizontal\n"));
str << ((flags.machine_flags() & machine_flags::IS_BIOS_ROOT) ? _("System is BIOS\tYes\n") : _("System is BIOS\tNo\n"));
str << ((flags.emulation_flags() & device_t::flags::SAVE_UNSUPPORTED) ? _("Support Save\tNo\n") : _("Support Save\tYes\n"));
str << ((flags.machine_flags() & ORIENTATION_SWAP_XY) ? _("Screen Orientation\tVertical\n") : _("Screen Orientation\tHorizontal\n"));
bool found = false;
for (romload::region const &region : romload::entries(driver.rom).get_regions())
{

View File

@ -88,6 +88,7 @@ protected:
system_flags &operator=(system_flags &&) = default;
::machine_flags::type machine_flags() const { return m_machine_flags; }
device_t::flags_type emulation_flags() const { return m_emulation_flags; }
device_t::feature_type unemulated_features() const { return m_unemulated_features; }
device_t::feature_type imperfect_features() const { return m_imperfect_features; }
bool has_keyboard() const { return m_has_keyboard; }
@ -96,6 +97,7 @@ protected:
private:
::machine_flags::type m_machine_flags;
device_t::flags_type m_emulation_flags;
device_t::feature_type m_unemulated_features;
device_t::feature_type m_imperfect_features;
bool m_has_keyboard;

View File

@ -43,7 +43,8 @@ simple_menu_select_game::simple_menu_select_game(mame_ui_manager &mui, render_co
, m_driverlist(driver_list::total() + 1)
, m_drivlist()
, m_cached_driver(nullptr)
, m_cached_flags(machine_flags::NOT_WORKING)
, m_cached_machine_flags(machine_flags::ROT0)
, m_cached_emulation_flags(device_t::flags::NOT_WORKING)
, m_cached_unemulated(device_t::feature::NONE), m_cached_imperfect(device_t::feature::NONE)
, m_cached_color(ui().colors().background_color())
{
@ -353,14 +354,15 @@ void simple_menu_select_game::custom_render(uint32_t flags, void *selectedref, f
emu_options clean_options;
machine_static_info const info(ui().options(), machine_config(*driver, clean_options));
m_cached_driver = driver;
m_cached_flags = info.machine_flags();
m_cached_machine_flags = info.machine_flags();
m_cached_emulation_flags = info.emulation_flags();
m_cached_unemulated = info.unemulated_features();
m_cached_imperfect = info.imperfect_features();
m_cached_color = info.status_color();
}
// next line is overall driver status
if (m_cached_flags & machine_flags::NOT_WORKING)
if (m_cached_emulation_flags & device_t::flags::NOT_WORKING)
tempbuf[3] = _("Status: NOT WORKING");
else if ((m_cached_unemulated | m_cached_imperfect) & device_t::feature::PROTECTION)
tempbuf[3] = _("Status: Unemulated Protection");
@ -375,7 +377,7 @@ void simple_menu_select_game::custom_render(uint32_t flags, void *selectedref, f
else
tempbuf[4] = _("Graphics: OK, ");
if (m_cached_flags & machine_flags::NO_SOUND_HW)
if (m_cached_machine_flags & machine_flags::NO_SOUND_HW)
tempbuf[4].append(_("Sound: None"));
else if (m_cached_unemulated & device_t::feature::SOUND)
tempbuf[4].append(_("Sound: Unimplemented"));

View File

@ -59,7 +59,8 @@ private:
// cached driver flags
const game_driver * m_cached_driver;
machine_flags::type m_cached_flags;
machine_flags::type m_cached_machine_flags;
device_t::flags_type m_cached_emulation_flags;
device_t::feature_type m_cached_unemulated;
device_t::feature_type m_cached_imperfect;
rgb_t m_cached_color;

View File

@ -270,7 +270,6 @@ mame_ui_manager::mame_ui_manager(running_machine &machine)
, m_mouse_arrow_texture(nullptr)
, m_pointers_changed(false)
, m_target_font_height(0)
, m_has_warnings(false)
, m_unthrottle_mute(false)
, m_image_display_enabled(true)
, m_machine_info()
@ -697,12 +696,10 @@ void mame_ui_manager::display_startup_screens(bool first_time)
break;
case 1:
warning_text = machine_info().warnings_string();
m_has_warnings = !warning_text.empty();
if (show_warnings)
{
bool need_warning = m_has_warnings;
if (machine_info().has_severe_warnings() || !m_has_warnings)
bool need_warning = machine_info().has_warnings();
if (machine_info().has_severe_warnings() || !machine_info().has_warnings())
{
// critical warnings - no need to persist stuff
m_unemulated_features.clear();
@ -717,6 +714,8 @@ void mame_ui_manager::display_startup_screens(bool first_time)
for (device_t &device : device_enumerator(machine().root_device()))
{
device_t::feature_type unemulated = device.type().unemulated_features();
if ((&device != &machine().root_device()) && (device.type().emulation_flags() & device_t::flags::NOT_WORKING))
unemulated_features.emplace(device.type().shortname(), "functionality");
for (std::underlying_type_t<device_t::feature_type> feature = 1U; unemulated; feature <<= 1)
{
if (unemulated & feature)
@ -764,6 +763,7 @@ void mame_ui_manager::display_startup_screens(bool first_time)
}
if (need_warning)
{
warning_text = machine_info().warnings_string();
warning_text.append(_("\n\nPress any key to continue"));
set_handler(ui_callback_type::MODAL, handler_callback_func(handler_messagebox_anykey));
warning_color = machine_info().warnings_color();
@ -815,7 +815,7 @@ void mame_ui_manager::display_startup_screens(bool first_time)
}
// update last launch time if this was a run that was eligible for emulation warnings
if (m_has_warnings && show_warnings && !machine().scheduled_event_pending())
if (machine_info().has_warnings() && show_warnings && !machine().scheduled_event_pending())
m_last_launch_time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
// if we're the empty driver, force the menus on

View File

@ -204,7 +204,6 @@ public:
void show_menu();
virtual bool is_menu_active() override;
bool can_paste();
bool found_machine_warnings() const { return m_has_warnings; }
void image_handler_ingame();
void request_quit();
void set_pointer_activity_timeout(int target, std::chrono::steady_clock::duration timeout) noexcept;
@ -314,7 +313,6 @@ private:
ui_options m_ui_options;
ui_colors m_ui_colors;
float m_target_font_height;
bool m_has_warnings;
bool m_unthrottle_mute;
bool m_image_display_enabled;

View File

@ -680,7 +680,7 @@ class working_machine_filter_impl : public simple_filter_impl_base<machine_filte
public:
working_machine_filter_impl(machine_filter_data const &data, char const *value, util::core_file *file, unsigned indent) { }
virtual bool apply(ui_system_info const &system) const override { return !(system.driver->flags & machine_flags::NOT_WORKING); }
virtual bool apply(ui_system_info const &system) const override { return !(system.driver->type.emulation_flags() & device_t::flags::NOT_WORKING); }
};
@ -743,7 +743,7 @@ class save_machine_filter_impl : public simple_filter_impl_base<machine_filter,
public:
save_machine_filter_impl(machine_filter_data const &data, char const *value, util::core_file *file, unsigned indent) { }
virtual bool apply(ui_system_info const &system) const override { return system.driver->flags & machine_flags::SUPPORTS_SAVE; }
virtual bool apply(ui_system_info const &system) const override { return !(system.driver->type.emulation_flags() & device_t::flags::SAVE_UNSUPPORTED); }
};

View File

@ -155,6 +155,7 @@ public:
void mgzz(machine_config &config) ATTR_COLD;
void oceanpar(machine_config &config) ATTR_COLD;
void tripslot(machine_config &config) ATTR_COLD;
void ccly(machine_config &config) ATTR_COLD;
void extradrw(machine_config &config) ATTR_COLD;
void chessc2(machine_config &config) ATTR_COLD;
@ -1446,6 +1447,108 @@ INPUT_PORTS_START( tripslot )
PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "SW3:8" )
INPUT_PORTS_END
INPUT_PORTS_START( ccly )
// preliminary - game seems to lack an input test
// To access sound test, hold Service Mode and reset, then press Service Mode and Book-Keeping simultaneously
PORT_START("PORTB")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SLOT_STOP1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01)
PORT_SERVICE_NO_TOGGLE( 0x08, IP_ACTIVE_LOW ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00)
PORT_SERVICE_NO_TOGGLE( 0x04, IP_ACTIVE_LOW ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_NAME("Small / Half Gamble / Show Odds")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_NAME("Big")
PORT_START("PORTC")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_NAME("Bet / Double Up")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_NAME("Big")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_NAME("Start / Take Score")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_READ_LINE_DEVICE_MEMBER("hopper", FUNC(hopper_device::line_r))
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01)
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_NAME("Start / Take Score")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_READ_LINE_DEVICE_MEMBER("hopper", FUNC(hopper_device::line_r))
PORT_BIT( 0x60, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00)
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00)
PORT_START("PLAYER")
PORT_BIT( 0x00001, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01)
PORT_BIT( 0x00002, IP_ACTIVE_LOW, IPT_SLOT_STOP3 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01)
PORT_BIT( 0x00004, IP_ACTIVE_LOW, IPT_SLOT_STOP2 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01)
PORT_BIT( 0x00038, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01)
PORT_BIT( 0x00001, IP_ACTIVE_LOW, IPT_SLOT_STOP2 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00)
PORT_BIT( 0x00002, IP_ACTIVE_LOW, IPT_SLOT_STOP1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00)
PORT_BIT( 0x00004, IP_ACTIVE_LOW, IPT_SLOT_STOP3 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00)
PORT_BIT( 0x00008, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_NAME("Small / Half Gamble / Show Odds")
PORT_BIT( 0x00010, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00)
PORT_BIT( 0x00020, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00)
PORT_BIT( 0x000c0, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00100, IP_ACTIVE_HIGH, IPT_UNKNOWN ) // must be low or most inputs are ignored
PORT_BIT( 0xffe00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("CLEARMEM")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MEMORY_RESET ) PORT_TOGGLE
PORT_START("PPIB")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_WRITE_LINE_MEMBER(FUNC(igs_m027_state::counter_w<4>)) // key-out
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_WRITE_LINE_MEMBER(FUNC(igs_m027_state::counter_w<0>)) // coin
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_WRITE_LINE_DEVICE_MEMBER("hopper", FUNC(hopper_device::motor_w))
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_WRITE_LINE_MEMBER(FUNC(igs_m027_state::counter_w<3>)) // payout
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_WRITE_LINE_MEMBER(FUNC(igs_m027_state::counter_w<2>)) // key-in
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_WRITE_LINE_MEMBER(FUNC(igs_m027_state::counter_w<0>)) // coin 1
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_WRITE_LINE_MEMBER(FUNC(igs_m027_state::counter_w<2>)) // key-in
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_WRITE_LINE_MEMBER(FUNC(igs_m027_state::counter_w<1>)) // coin 2
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_WRITE_LINE_MEMBER(FUNC(igs_m027_state::counter_w<3>)) // payout
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_WRITE_LINE_MEMBER(FUNC(igs_m027_state::counter_w<4>)) // key-out
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_WRITE_LINE_DEVICE_MEMBER("hopper", FUNC(hopper_device::motor_w))
PORT_START("DSW1")
PORT_DIPUNKNOWN_DIPLOC( 0x01, 0x01, "SW1:1" )
PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x02, "SW1:2" )
PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x04, "SW1:3" )
PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x08, "SW1:4" )
PORT_DIPUNKNOWN_DIPLOC( 0x10, 0x10, "SW1:5" )
PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x20, "SW1:6" )
PORT_DIPUNKNOWN_DIPLOC( 0x40, 0x40, "SW1:7" )
PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "SW1:8" )
PORT_START("DSW2")
PORT_DIPNAME( 0x01, 0x01, "Operation Mode" ) PORT_DIPLOCATION("SW2:1") // 操作模式
PORT_DIPSETTING( 0x01, "Amusement" ) // 娱乐配线
PORT_DIPSETTING( 0x00, "Fruit Machine" ) // 水果配线
PORT_DIPNAME( 0x02, 0x02, DEF_STR(Demo_Sounds) ) PORT_DIPLOCATION("SW2:2") // 示范音乐
PORT_DIPSETTING( 0x00, DEF_STR(Off) ) // 无
PORT_DIPSETTING( 0x02, DEF_STR(On) ) // 有
PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x04, "SW2:3" )
PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x08, "SW2:4" )
PORT_DIPUNKNOWN_DIPLOC( 0x10, 0x10, "SW2:5" )
PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x20, "SW2:6" )
PORT_DIPUNKNOWN_DIPLOC( 0x40, 0x40, "SW2:7" )
PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "SW2:8" )
PORT_START("DSW3")
PORT_DIPUNKNOWN_DIPLOC( 0x01, 0x01, "SW3:1" )
PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x02, "SW3:2" )
PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x04, "SW3:3" )
PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x08, "SW3:4" )
PORT_DIPUNKNOWN_DIPLOC( 0x10, 0x10, "SW3:5" )
PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x20, "SW3:6" )
PORT_DIPUNKNOWN_DIPLOC( 0x40, 0x40, "SW3:7" )
PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "SW3:8" )
INPUT_PORTS_END
INPUT_PORTS_START( chessc2 )
// preliminary - game seems to lack an input test and settings are locked out with password
@ -1639,28 +1742,28 @@ template <unsigned Start>
void igs_m027_state::lamps_w(u8 data)
{
// active high outputs
// +------+-------------------------------+-------------------------------+---------------+
// | lamp | jking02 | tripslot | oceanpar |
// | +---------------+---------------+---------------+---------------+ |
// | | 36+10 | 28-Pin | 36+10 | 28-Pin | |
// +------+---------------+---------------+---------------+---------------+---------------+
// | 1 | stop 4/start | | start | | start |
// | 2 | stop 3/small | | stop 3/small | | stop 2/small |
// | 3 | bet | | stop 5/bet | | bet |
// | 4 | stop 1/take | | stop 4/take | | stop 3/take |
// | 5 | stop 2/double | | stop 2/double | | stop 1/double |
// | 6 | stop all/big | | stop 1/big | | stop all/big |
// | 7 | | | | | |
// | 8 | | | | | |
// | 9 | | bet | | stop 5/bet | |
// | 10 | | start | | start | |
// | 11 | | | | | |
// | 12 | | stop 1/take | | stop 1/big | |
// | 13 | | stop 2/big | | stop 2/double | |
// | 14 | | stop 4/double | | stop 4/take | |
// | 15 | | stop 3/small | | stop 3/small | |
// | 16 | | | | | |
// +------+---------------+---------------+---------------+---------------+---------------+
// +------+-------------------------------+-------------------------------+---------------+--------+
// | lamp | jking02 | tripslot | oceanpar | ccly |
// | +---------------+---------------+---------------+---------------+ +--------+
// | | 36+10 | 28-Pin | 36+10 | 28-Pin | | Fruit |
// +------+---------------+---------------+---------------+---------------+---------------+--------|
// | 1 | stop 4/start | | start | | start | start |
// | 2 | stop 3/small | | stop 3/small | | stop 2/small | small |
// | 3 | bet | | stop 5/bet | | bet | bet |
// | 4 | stop 1/take | | stop 4/take | | stop 3/take | take |
// | 5 | stop 2/double | | stop 2/double | | stop 1/double | double |
// | 6 | stop all/big | | stop 1/big | | stop all/big | big |
// | 7 | | | | | | |
// | 8 | | | | | | |
// | 9 | | bet | | stop 5/bet | | |
// | 10 | | start | | start | | |
// | 11 | | | | | | |
// | 12 | | stop 1/take | | stop 1/big | | |
// | 13 | | stop 2/big | | stop 2/double | | |
// | 14 | | stop 4/double | | stop 4/take | | |
// | 15 | | stop 3/small | | stop 3/small | | |
// | 16 | | | | | | |
// +------+---------------+---------------+---------------+---------------+---------------+--------+
for (unsigned i = 0; 8 > i; ++i)
m_out_lamps[Start + i] = BIT(data, i);
}
@ -1771,7 +1874,7 @@ void igs_m027_state::counter_w(int state)
template <bool Xor>
void igs_m027_state::m027_noppi(machine_config &config)
{
IGS027A(config, m_maincpu, 22'000'000); // Jungle King 2002 has a 22Mhz Xtal, what about the others?
IGS027A(config, m_maincpu, 22'000'000); // Jungle King 2002 has a 22MHz Xtal, what about the others?
m_maincpu->set_addrmap(AS_PROGRAM, &igs_m027_state::m027_noppi_map<Xor>);
m_maincpu->out_port().set(FUNC(igs_m027_state::io_select_w<1>));
@ -2026,6 +2129,18 @@ void igs_m027_state::tripslot(machine_config &config)
HOPPER(config, m_hopper, attotime::from_msec(50));
}
void igs_m027_state::ccly(machine_config &config)
{
m027_1ppi<true>(config);
m_maincpu->in_port().set_ioport("PLAYER");
m_ppi[0]->out_pb_callback().set_ioport("PPIB");
m_ppi[0]->out_pc_callback().set(FUNC(igs_m027_state::lamps_w<0>));
HOPPER(config, m_hopper, attotime::from_msec(50));
}
void igs_m027_state::extradrw(machine_config &config)
{
m027_2ppis<false>(config);
@ -2313,7 +2428,7 @@ U17 is a ATF16V8B-15P labeled ( FG-1 ) (read protected)
U10 is a IGS 003c Dip 40 pin ( Maybe 8255 ? )
U24 is a IGS031 QFP with 208 pin
U32 is a IGS027a QFP with 120 pin ( Encrypted ARM, internal code, stamped P9 A/K II )
Crystal Frequency = 22.000 Mhz
Crystal Frequency = 22.000 MHz
Sound Processor ( U6295 )
*/
@ -3711,7 +3826,7 @@ GAME( 2005, cjddzlf, 0, cjddz, cjddz, igs_m027_stat
GAME( 2005, cjtljp, 0, xypdk, lhzb4, igs_m027_state, init_cjtljp, ROT0, "IGS", "Chaoji Tuolaji Jiaqiang Ban (V206CN)", 0 ) // 2005 date in internal ROM
GAME( 2005, xypdk, 0, xypdk, lhzb4, igs_m027_state, init_xypdk, ROT0, "IGS", "Xingyun Pao De Kuai (V106CN)", 0 )
GAMEL( 2007, tripslot, 0, tripslot, tripslot, igs_m027_state, init_tripslot, ROT0, "IGS", "Triple Slot (V200VE)", 0, layout_tripslot ) // 2007 date in internal ROM at least, could be later, default settings password is all 'start 1'
GAME( 2005, ccly, crzybugs, m027_1ppi<true>, base, igs_m027_state, init_ccly, ROT0, "IGS", "Chong Chong Leyuan (V100CN)", MACHINE_NOT_WORKING )
GAME( 2005, ccly, crzybugs, ccly, ccly, igs_m027_state, init_ccly, ROT0, "IGS", "Chong Chong Leyuan (V100CN)", MACHINE_NOT_WORKING )
// this has a 2nd 8255
GAME( 2001, extradrw, 0, extradrw, base, igs_m027_state, init_extradrw, ROT0, "IGS", "Extra Draw (V100VE)", MACHINE_NOT_WORKING )
// these have an IGS025 protection device instead of the 8255

View File

@ -91,7 +91,6 @@ protected:
private:
sound_stream *m_stream = nullptr;
output_finder<> m_led_out;
bool m_dummy_save = false; // needed for save-state support
};
DEFINE_DEVICE_TYPE(MILTON_LED_FILTER, milton_filter_device, "milton_led_filter", "Milton LED Filter")
@ -107,7 +106,6 @@ void milton_filter_device::device_start()
{
m_stream = stream_alloc(1, 1, machine().sample_rate());
m_led_out.resolve();
save_item(NAME(m_dummy_save));
}
void milton_filter_device::sound_stream_update(sound_stream &stream)

View File

@ -150,8 +150,6 @@ void gottlieb_sound_p2_device::device_add_mconfig(machine_config &config)
void gottlieb_sound_p2_device::device_start()
{
// register for save states
save_item(NAME(m_dummy_save));
}
@ -369,8 +367,6 @@ void gottlieb_sound_r1_device::device_add_mconfig(machine_config &config)
void gottlieb_sound_r1_device::device_start()
{
// register for save states
save_item(NAME(m_dummy_save));
}

View File

@ -69,9 +69,6 @@ protected:
// devices
required_device<m6503_device> m_cpu;
required_device<mos6530_device> m_r6530;
private:
bool m_dummy_save = false; // needed for save-state support
};
@ -127,9 +124,6 @@ protected:
// devices
required_device<mc1408_device> m_dac;
required_device<mos6532_device> m_riot;
private:
bool m_dummy_save = false; // needed for save-state support
};

View File

@ -914,8 +914,6 @@ void williams_s4_sound_device::device_add_mconfig(machine_config &config)
//-------------------------------------------------
void williams_s4_sound_device::device_start()
{
// register for save states
save_item(NAME(m_dummy_save));
}
//-------------------------------------------------
@ -1031,8 +1029,6 @@ void williams_s6_sound_device::device_add_mconfig(machine_config &config)
//-------------------------------------------------
void williams_s6_sound_device::device_start()
{
// register for save states
save_item(NAME(m_dummy_save));
}
//-------------------------------------------------
@ -1142,8 +1138,6 @@ void williams_s9_sound_device::device_add_mconfig(machine_config &config)
//-------------------------------------------------
void williams_s9_sound_device::device_start()
{
// register for save states
save_item(NAME(m_dummy_save));
}
//-------------------------------------------------
@ -1260,9 +1254,6 @@ void williams_s11_sound_device::device_start()
u8 *ROM = memregion("audiocpu")->base();
membank("bank0")->configure_entries(0, 2, &ROM[0x0000], 0x4000);
membank("bank1")->configure_entries(0, 2, &ROM[0x8000], 0x4000);
// register for save states
save_item(NAME(m_dummy_save));
}
//-------------------------------------------------

View File

@ -223,7 +223,6 @@ private:
void williams_s4_map(address_map &map) ATTR_COLD;
required_device<m6808_cpu_device> m_cpu;
required_device<pia6821_device> m_pia;
bool m_dummy_save = false; // needed for save-state support
};
@ -254,7 +253,6 @@ private:
required_device<m6802_cpu_device> m_cpu;
required_device<pia6821_device> m_pia;
required_device<hc55516_device> m_hc;
bool m_dummy_save = false; // needed for save-state support
};
@ -285,7 +283,6 @@ private:
required_device<m6802_cpu_device> m_cpu;
required_device<pia6821_device> m_pia;
required_device<hc55516_device> m_hc;
bool m_dummy_save = false; // needed for save-state support
};
@ -317,7 +314,6 @@ private:
required_device<m6802_cpu_device> m_cpu;
required_device<pia6821_device> m_pia;
required_device<hc55516_device> m_hc;
bool m_dummy_save = false; // needed for save-state support
};
#endif // MAME_SHARED_WILLIAMSSOUND_H

View File

@ -6,10 +6,11 @@
#pragma once
#include <string>
#include <array>
#include <cmath>
#include <string>
#include <vector>
#include <math.h>
namespace osd {
@ -25,7 +26,7 @@ struct audio_info {
uint32_t m_id;
audio_rate_range m_rate;
std::vector<std::string> m_port_names;
std::vector<std::array<double, 3>> m_port_positions;
std::vector<std::array<double, 3> > m_port_positions;
uint32_t m_sinks;
uint32_t m_sources;
@ -45,8 +46,9 @@ struct audio_info {
std::vector<stream_info> m_streams;
};
static inline float db_to_linear(float db) { return db <= -96 ? 0.0 : pow(10, db/20); }
static inline float linear_to_db(float linear) { return linear <= 1/65536.0 ? -96 : 20*log10(linear); }
}
inline float db_to_linear(float db) { return (db <= -96.0F) ? 0.0F : std::pow(10.0F, db / 20.0F); }
inline float linear_to_db(float linear) { return (linear <= (1.0F / 65536.0F)) ? -96.0F : (20.0F * std::log10(linear)); }
#endif
} // namespace osd
#endif // MAME_OSD_INTERFACE_AUDIO_H