Switch to using delegates for some callbacks:

- non-device timer callbacks
 - machine state changing callbacks
 - configuration callbacks
 - per-screen VBLANK callbacks
 - DRC backend callbacks

For the timer case only, I added wrappers for the old-style functions.
Over time, drivers should switch to device timers instead, reducing the
number of timers that are directly allocated through the scheduler.
This commit is contained in:
Aaron Giles 2011-04-27 20:34:45 +00:00
parent 9092f15964
commit af94c692bb
93 changed files with 293 additions and 327 deletions

View File

@ -1097,7 +1097,7 @@ cheat_manager::cheat_manager(running_machine &machine)
return;
// request a callback
machine.add_notifier(MACHINE_NOTIFY_FRAME, frame_update_static);
machine.add_notifier(MACHINE_NOTIFY_FRAME, machine_notify_delegate(FUNC(cheat_manager::frame_update), this));
// create a global symbol table
m_symtable.add("frame", symbol_table::READ_ONLY, &m_framecount);
@ -1380,11 +1380,6 @@ UINT64 cheat_manager::execute_tobcd(symbol_table &table, void *ref, int params,
// frame_update - per-frame callback
//-------------------------------------------------
void cheat_manager::frame_update_static(running_machine &machine)
{
machine.cheat().frame_update();
}
void cheat_manager::frame_update()
{
// set up for accumulating output

View File

@ -314,7 +314,7 @@ private:
// ======================> cheat_manager
// private machine-global data
class cheat_manager
class cheat_manager : public bindable_object
{
public:
// construction/destruction
@ -343,7 +343,6 @@ public:
private:
// internal helpers
static void frame_update_static(running_machine &machine);
void frame_update();
void load_cheats(const char *filename);

View File

@ -28,8 +28,8 @@ struct _config_type
{
struct _config_type * next; /* next in line */
const char * name; /* node name */
config_callback_func load; /* load callback */
config_callback_func save; /* save callback */
config_saveload_delegate load; /* load callback */
config_saveload_delegate save; /* save callback */
};
@ -75,7 +75,7 @@ void config_init(running_machine &machine)
*
*************************************/
void config_register(running_machine &machine, const char *nodename, config_callback_func load, config_callback_func save)
void config_register(running_machine &machine, const char *nodename, config_saveload_delegate load, config_saveload_delegate save)
{
config_type *newtype;
config_type **ptype;
@ -108,7 +108,7 @@ int config_load_settings(running_machine &machine)
/* loop over all registrants and call their init function */
for (type = typelist; type; type = type->next)
(*type->load)(machine, CONFIG_TYPE_INIT, NULL);
type->load(CONFIG_TYPE_INIT, NULL);
/* now load the controller file */
if (controller[0] != 0)
@ -138,7 +138,7 @@ int config_load_settings(running_machine &machine)
/* loop over all registrants and call their final function */
for (type = typelist; type; type = type->next)
(*type->load)(machine, CONFIG_TYPE_FINAL, NULL);
type->load(CONFIG_TYPE_FINAL, NULL);
/* if we didn't find a saved config, return 0 so the main core knows that it */
/* is the first time the game is run and it should diplay the disclaimer. */
@ -152,7 +152,7 @@ void config_save_settings(running_machine &machine)
/* loop over all registrants and call their init function */
for (type = typelist; type; type = type->next)
(*type->save)(machine, CONFIG_TYPE_INIT, NULL);
type->save(CONFIG_TYPE_INIT, NULL);
/* save the defaults file */
emu_file file(machine.options().cfg_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
@ -167,7 +167,7 @@ void config_save_settings(running_machine &machine)
/* loop over all registrants and call their final function */
for (type = typelist; type; type = type->next)
(*type->save)(machine, CONFIG_TYPE_FINAL, NULL);
type->save(CONFIG_TYPE_FINAL, NULL);
}
@ -253,7 +253,7 @@ static int config_load_xml(running_machine &machine, emu_file &file, int which_t
/* loop over all registrants and call their load function */
for (type = typelist; type; type = type->next)
(*type->load)(machine, which_type, xml_get_sibling(systemnode->child, type->name));
type->load(which_type, xml_get_sibling(systemnode->child, type->name));
count++;
}
@ -308,7 +308,7 @@ static int config_save_xml(running_machine &machine, emu_file &file, int which_t
xml_data_node *curnode = xml_add_child(systemnode, type->name, NULL);
if (!curnode)
goto error;
(*type->save)(machine, which_type, curnode);
type->save(which_type, curnode);
/* if nothing was added, just nuke the node */
if (!curnode->value && !curnode->child)

View File

@ -43,7 +43,7 @@ enum
*
*************************************/
typedef void (*config_callback_func)(running_machine &machine, int config_type, xml_data_node *parentnode);
typedef delegate<void (int, xml_data_node *)> config_saveload_delegate;
@ -54,7 +54,7 @@ typedef void (*config_callback_func)(running_machine &machine, int config_type,
*************************************/
void config_init(running_machine &machine);
void config_register(running_machine &machine, const char *nodename, config_callback_func load, config_callback_func save);
void config_register(running_machine &machine, const char *nodename, config_saveload_delegate load, config_saveload_delegate save);
int config_load_settings(running_machine &machine);
void config_save_settings(running_machine &machine);

View File

@ -319,7 +319,8 @@ drcbe_c::drcbe_c(drcuml_state &drcuml, device_t &device, drc_cache &cache, UINT3
: drcbe_interface(drcuml, cache, device),
m_hash(cache, modes, addrbits, ignorebits),
m_map(cache, 0),
m_labels(cache)
m_labels(cache),
m_fixup_delegate(FUNC(drcbe_c::fixup_label), this)
{
}
@ -403,7 +404,7 @@ void drcbe_c::generate(drcuml_block &block, const instruction *instlist, UINT32
// JMP instructions need to resolve their labels
case OP_JMP:
(dst++)->i = MAKE_OPCODE_FULL(opcode, inst.size(), inst.condition(), inst.flags(), 1);
dst->inst = (drcbec_instruction *)m_labels.get_codeptr(inst.param(0).label(), fixup_label, dst);
dst->inst = (drcbec_instruction *)m_labels.get_codeptr(inst.param(0).label(), m_fixup_delegate, dst);
dst++;
break;

View File

@ -70,7 +70,7 @@ public:
private:
// helpers
void output_parameter(drcbec_instruction **dstptr, void **immedptr, int size, const uml::parameter &param);
static void fixup_label(void *parameter, drccodeptr labelcodeptr);
void fixup_label(void *parameter, drccodeptr labelcodeptr);
int dmulu(UINT64 &dstlo, UINT64 &dsthi, UINT64 src1, UINT64 src2, int flags);
int dmuls(UINT64 &dstlo, UINT64 &dsthi, INT64 src1, INT64 src2, int flags);
@ -78,6 +78,7 @@ private:
drc_hash_table m_hash; // hash table state
drc_map_variables m_map; // code map
drc_label_list m_labels; // label list
drc_label_fixup_delegate m_fixup_delegate; // precomputed delegate
static const UINT32 s_condition_map[32];
static UINT64 s_immediate_zero;

View File

@ -463,7 +463,8 @@ UINT32 drc_map_variables::get_last_value(UINT32 mapvar)
//-------------------------------------------------
drc_label_list::drc_label_list(drc_cache &cache)
: m_cache(cache)
: m_cache(cache),
m_oob_callback_delegate(FUNC(drc_label_list::oob_callback), this)
{
}
@ -497,6 +498,14 @@ void drc_label_list::block_begin(drcuml_block &block)
void drc_label_list::block_end(drcuml_block &block)
{
// can't free until the cache is clean of our OOB requests
assert(!m_cache.generating_code());
// free all of the pending fixup requests
label_fixup *fixup;
while ((fixup = m_fixup_list.detach_head()) != NULL)
m_cache.dealloc(fixup, sizeof(*fixup));
// make sure the label list is clear, and fatalerror if we missed anything
reset(true);
}
@ -508,13 +517,19 @@ void drc_label_list::block_end(drcuml_block &block)
// undefined
//-------------------------------------------------
drccodeptr drc_label_list::get_codeptr(uml::code_label label, fixup_func fixup, void *param)
drccodeptr drc_label_list::get_codeptr(uml::code_label label, drc_label_fixup_delegate callback, void *param)
{
label_entry *curlabel = find_or_allocate(label);
// if no code pointer, request an OOB callback
if (curlabel->m_codeptr == NULL && fixup != NULL)
m_cache.request_oob_codegen(oob_callback, curlabel, (void *)fixup, param);
if (curlabel->m_codeptr == NULL && !callback.isnull())
{
label_fixup *fixup = reinterpret_cast<label_fixup *>(m_cache.alloc(sizeof(*fixup)));
fixup->m_callback = callback;
fixup->m_label = curlabel;
m_fixup_list.append(*fixup);
m_cache.request_oob_codegen(m_oob_callback_delegate, fixup, param);
}
return curlabel->m_codeptr;
}
@ -584,10 +599,8 @@ drc_label_list::label_entry *drc_label_list::find_or_allocate(uml::code_label la
// for labels
//-------------------------------------------------
void drc_label_list::oob_callback(drccodeptr *codeptr, void *param1, void *param2, void *param3)
void drc_label_list::oob_callback(drccodeptr *codeptr, void *param1, void *param2)
{
label_entry *label = (label_entry *)param1;
fixup_func callback = (fixup_func)param2;
(*callback)(param3, label->m_codeptr);
label_fixup *fixup = reinterpret_cast<label_fixup *>(param1);
fixup->m_callback(param2, fixup->m_label->m_codeptr);
}

View File

@ -144,12 +144,11 @@ private:
// ======================> drc_label_list
// structure holding a live list of labels
class drc_label_list
{
// callback function for forward-referenced labels
typedef void (*fixup_func)(void *parameter, drccodeptr labelcodeptr);
typedef delegate<void (void *, drccodeptr)> drc_label_fixup_delegate;
// structure holding a live list of labels
class drc_label_list : public bindable_object
{
public:
// construction/destruction
drc_label_list(drc_cache &cache);
@ -160,7 +159,7 @@ public:
void block_end(drcuml_block &block);
// get/set values
drccodeptr get_codeptr(uml::code_label label, fixup_func fixup, void *param);
drccodeptr get_codeptr(uml::code_label label, drc_label_fixup_delegate fixup, void *param);
void set_codeptr(uml::code_label label, drccodeptr codeptr);
private:
@ -171,15 +170,25 @@ private:
uml::code_label m_label; // the label specified
drccodeptr m_codeptr; // pointer to the relevant code
};
struct label_fixup
{
label_fixup *next() const { return m_next; }
label_fixup * m_next; // pointer to the next oob
label_entry * m_label; // the label in question
drc_label_fixup_delegate m_callback; // callback
};
// internal helpers
void reset(bool fatal_on_leftovers);
label_entry *find_or_allocate(uml::code_label label);
static void oob_callback(drccodeptr *codeptr, void *param1, void *param2, void *param3);
void oob_callback(drccodeptr *codeptr, void *param1, void *param2);
// internal state
drc_cache & m_cache; // pointer to the cache
simple_list<label_entry> m_list; // head of the live list
simple_list<label_fixup> m_fixup_list; // list of pending oob fixups
drc_oob_delegate m_oob_callback_delegate; // pre-computed delegate
};

View File

@ -621,6 +621,8 @@ drcbe_x64::drcbe_x64(drcuml_state &drcuml, device_t &device, drc_cache &cache, U
m_entry(NULL),
m_exit(NULL),
m_nocode(NULL),
m_fixup_label(FUNC(drcbe_x64::fixup_label), this),
m_fixup_exception(FUNC(drcbe_x64::fixup_exception), this),
m_near(*(near_state *)cache.alloc_near(sizeof(m_near)))
{
// build up necessary arrays
@ -2931,7 +2933,7 @@ void drcbe_x64::op_jmp(x86code *&dst, const instruction &inst)
assert(labelp.is_code_label());
// look up the jump target and jump there
x86code *jmptarget = (x86code *)m_labels.get_codeptr(labelp.label(), fixup_label, dst);
x86code *jmptarget = (x86code *)m_labels.get_codeptr(labelp.label(), m_fixup_label, dst);
if (jmptarget == NULL)
jmptarget = dst + 0x7ffffff0;
if (inst.condition() == uml::COND_ALWAYS)
@ -2975,7 +2977,7 @@ void drcbe_x64::op_exh(x86code *&dst, const instruction &inst)
else
{
emit_jcc(dst, X86_CONDITION(inst.condition()), dst + 0x7ffffff0); // jcc exception
m_cache.request_oob_codegen(oob_func_stub<drcbe_x64, &drcbe_x64::fixup_exception>, dst, &const_cast<instruction &>(inst), this);
m_cache.request_oob_codegen(m_fixup_exception, dst, &const_cast<instruction &>(inst));
}
}

View File

@ -149,7 +149,7 @@ private:
void emit_smart_call_r64(x86code *&dst, x86code *target, UINT8 reg);
void emit_smart_call_m64(x86code *&dst, x86code **target);
static void fixup_label(void *parameter, drccodeptr labelcodeptr);
void fixup_label(void *parameter, drccodeptr labelcodeptr);
void fixup_exception(drccodeptr *codeptr, void *param1, void *param2);
static void debug_log_hashjmp(offs_t pc, int mode);
@ -333,6 +333,9 @@ private:
x86code * m_exit; // exit point
x86code * m_nocode; // nocode handler
drc_label_fixup_delegate m_fixup_label; // precomputed delegate for fixups
drc_oob_delegate m_fixup_exception; // precomputed delegate for exception fixups
// state to live in the near cache
struct near_state
{

View File

@ -556,7 +556,9 @@ drcbe_x86::drcbe_x86(drcuml_state &drcuml, device_t &device, drc_cache &cache, U
m_stacksave(0),
m_hashstacksave(0),
m_reslo(0),
m_reshi(0)
m_reshi(0),
m_fixup_label(FUNC(drcbe_x86::fixup_label), this),
m_fixup_exception(FUNC(drcbe_x86::fixup_exception), this)
{
// compute hi pointers for each register
for (int regnum = 0; regnum < ARRAY_LENGTH(int_register_map); regnum++)
@ -3156,7 +3158,7 @@ void drcbe_x86::op_jmp(x86code *&dst, const instruction &inst)
assert(labelp.is_code_label());
// look up the jump target and jump there
x86code *jmptarget = (x86code *)m_labels.get_codeptr(labelp.label(), fixup_label, dst);
x86code *jmptarget = (x86code *)m_labels.get_codeptr(labelp.label(), m_fixup_label, dst);
if (inst.condition() == uml::COND_ALWAYS)
emit_jmp(dst, jmptarget); // jmp target
else
@ -3197,7 +3199,7 @@ void drcbe_x86::op_exh(x86code *&dst, const instruction &inst)
else
{
emit_jcc(dst, X86_CONDITION(inst.condition()), 0); // jcc exception
m_cache.request_oob_codegen(oob_func_stub<drcbe_x86, &drcbe_x86::fixup_exception>, dst, &const_cast<instruction &>(inst), this);
m_cache.request_oob_codegen(m_fixup_exception, dst, &const_cast<instruction &>(inst));
}
}

View File

@ -151,7 +151,7 @@ private:
bool can_skip_upper_load(x86code *&dst, UINT32 *memref, UINT8 reghi);
void track_resolve_link(x86code *&destptr, const emit_link &linkinfo);
static void fixup_label(void *parameter, drccodeptr labelcodeptr);
void fixup_label(void *parameter, drccodeptr labelcodeptr);
void fixup_exception(drccodeptr *codeptr, void *param1, void *param2);
static void debug_log_hashjmp(int mode, offs_t pc);
@ -355,6 +355,9 @@ private:
void * m_hashstacksave; // saved stack pointer for hashjmp
UINT64 m_reslo; // extended low result
UINT64 m_reshi; // extended high result
drc_label_fixup_delegate m_fixup_label; // precomputed delegate for fixups
drc_oob_delegate m_fixup_exception; // precomputed delegate for exception fixups
// globals
typedef void (drcbe_x86::*opcode_generate_func)(x86code *&dst, const uml::instruction &inst);

View File

@ -243,7 +243,7 @@ drccodeptr drc_cache::end_codegen()
while ((oob = m_ooblist.detach_head()) != NULL)
{
// call the callback
(*oob->m_callback)(&m_top, oob->m_param1, oob->m_param2, oob->m_param3);
oob->m_callback(&m_top, oob->m_param1, oob->m_param2);
assert(m_top - m_codegen < CODEGEN_MAX_BYTES);
// release our memory
@ -263,7 +263,7 @@ drccodeptr drc_cache::end_codegen()
// out-of-band codegen
//-------------------------------------------------
void drc_cache::request_oob_codegen(oob_func callback, void *param1, void *param2, void *param3)
void drc_cache::request_oob_codegen(drc_oob_delegate callback, void *param1, void *param2)
{
assert(m_codegen != NULL);
@ -275,7 +275,6 @@ void drc_cache::request_oob_codegen(oob_func callback, void *param1, void *param
oob->m_callback = callback;
oob->m_param1 = param1;
oob->m_param2 = param2;
oob->m_param3 = param3;
// add to the tail
m_ooblist.append(*oob);

View File

@ -63,21 +63,13 @@ typedef UINT8 *drccodeptr;
// helper template for oob codegen
template<class T, void (T::*func)(drccodeptr *codeptr, void *param1, void *param2)>
void oob_func_stub(drccodeptr *codeptr, void *param1, void *param2, void *param3)
{
T *target = reinterpret_cast<T *>(param3);
(target->*func)(codeptr, param1, param2);
}
typedef delegate<void (drccodeptr *, void *, void *)> drc_oob_delegate;
// drc_cache
class drc_cache
{
public:
// out of band codegen callback
typedef void (*oob_func)(drccodeptr *codeptr, void *param1, void *param2, void *param3);
// construction/destruction
drc_cache(size_t bytes);
~drc_cache();
@ -90,6 +82,7 @@ public:
// pointer checking
bool contains_pointer(const void *ptr) const { return ((const drccodeptr)ptr >= m_near && (const drccodeptr)ptr < m_near + m_size); }
bool contains_near_pointer(const void *ptr) const { return ((const drccodeptr)ptr >= m_near && (const drccodeptr)ptr < m_neartop); }
bool generating_code() const { return (m_codegen != NULL); }
// memory management
void flush();
@ -101,7 +94,7 @@ public:
// codegen helpers
drccodeptr *begin_codegen(UINT32 reserve_bytes);
drccodeptr end_codegen();
void request_oob_codegen(oob_func callback, void *param1 = NULL, void *param2 = NULL, void *param3 = NULL);
void request_oob_codegen(drc_oob_delegate callback, void *param1 = NULL, void *param2 = NULL);
private:
// largest block of code that can be generated at once
@ -131,10 +124,9 @@ private:
oob_handler *next() const { return m_next; }
oob_handler * m_next; // next handler
oob_func m_callback; // callback function
drc_oob_delegate m_callback; // callback function
void * m_param1; // 1st pointer parameter
void * m_param2; // 2nd pointer parameter
void * m_param3; // 3rd pointer parameter
};
simple_list<oob_handler> m_ooblist; // list of oob handlers

View File

@ -166,7 +166,7 @@ private:
// interface structure for a back-end
class drcbe_interface
class drcbe_interface : public bindable_object
{
public:
// construction/destruction

View File

@ -135,7 +135,7 @@ static void crosshair_exit(running_machine &machine);
static void crosshair_load(running_machine &machine, int config_type, xml_data_node *parentnode);
static void crosshair_save(running_machine &machine, int config_type, xml_data_node *parentnode);
static void animate(screen_device &device, void *param, bool vblank_state);
static void animate(running_machine &machine, screen_device &device, bool vblank_state);
/***************************************************************************
@ -211,7 +211,7 @@ static void create_bitmap(running_machine &machine, int player)
void crosshair_init(running_machine &machine)
{
/* request a callback upon exiting */
machine.add_notifier(MACHINE_NOTIFY_EXIT, crosshair_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(crosshair_exit), &machine));
/* clear all the globals */
memset(&global, 0, sizeof(global));
@ -242,11 +242,11 @@ void crosshair_init(running_machine &machine)
/* register callbacks for when we load/save configurations */
if (global.usage)
config_register(machine, "crosshairs", crosshair_load, crosshair_save);
config_register(machine, "crosshairs", config_saveload_delegate(FUNC(crosshair_load), &machine), config_saveload_delegate(FUNC(crosshair_save), &machine));
/* register the animation callback */
if (machine.primary_screen != NULL)
machine.primary_screen->register_vblank_callback(animate, NULL);
machine.primary_screen->register_vblank_callback(vblank_state_delegate(FUNC(animate), &machine));
}
@ -325,7 +325,7 @@ void crosshair_set_user_settings(running_machine &machine, UINT8 player, crossha
animate - animates the crosshair once a frame
-------------------------------------------------*/
static void animate(screen_device &device, void *param, bool vblank_state)
static void animate(running_machine &machine, screen_device &device, bool vblank_state)
{
int player;

View File

@ -369,7 +369,7 @@ void debug_command_init(running_machine &machine)
debug_console_register_command(machine, "softreset", CMDFLAG_NONE, 0, 0, 1, execute_softreset);
debug_console_register_command(machine, "hardreset", CMDFLAG_NONE, 0, 0, 1, execute_hardreset);
machine.add_notifier(MACHINE_NOTIFY_EXIT, debug_command_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(debug_command_exit), &machine));
/* set up the initial debugscript if specified */
name = machine.options().debug_script();

View File

@ -99,7 +99,7 @@ void debug_console_init(running_machine &machine)
debug_console_printf(machine, "Currently targeting %s (%s)\n", machine.system().name, machine.system().description);
/* request callback upon exiting */
machine.add_notifier(MACHINE_NOTIFY_EXIT, debug_console_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(debug_console_exit), &machine));
}

View File

@ -113,7 +113,7 @@ struct _debugcpu_private
/* internal helpers */
static void debug_cpu_exit(running_machine &machine);
static void on_vblank(screen_device &device, void *param, bool vblank_state);
static void on_vblank(running_machine &machine, screen_device &device, bool vblank_state);
static void reset_transient_flags(running_machine &machine);
static void process_source_file(running_machine &machine);
@ -182,9 +182,9 @@ void debug_cpu_init(running_machine &machine)
/* add callback for breaking on VBLANK */
if (machine.primary_screen != NULL)
machine.primary_screen->register_vblank_callback(on_vblank, NULL);
machine.primary_screen->register_vblank_callback(vblank_state_delegate(FUNC(on_vblank), &machine));
machine.add_notifier(MACHINE_NOTIFY_EXIT, debug_cpu_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(debug_cpu_exit), &machine));
}
@ -1068,7 +1068,7 @@ static void debug_cpu_exit(running_machine &machine)
on_vblank - called when a VBLANK hits
-------------------------------------------------*/
static void on_vblank(screen_device &device, void *param, bool vblank_state)
static void on_vblank(running_machine &machine, screen_device &device, bool vblank_state)
{
/* just set a global flag to be consumed later */
if (vblank_state)

View File

@ -77,7 +77,7 @@ void debugger_init(running_machine &machine)
debugint_init(machine);
/* allocate a new entry for our global list */
machine.add_notifier(MACHINE_NOTIFY_EXIT, debugger_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(debugger_exit), &machine));
entry = global_alloc(machine_entry);
entry->next = machine_list;
entry->machine = &machine;

View File

@ -921,7 +921,7 @@ void debugint_init(running_machine &machine)
debug_font_width++;
/* FIXME: above does not really work */
debug_font_width = 10;
machine.add_notifier(MACHINE_NOTIFY_EXIT, debugint_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(debugint_exit), &machine));
}
#if 0

View File

@ -124,8 +124,8 @@ void device_list::set_machine_all(running_machine &machine)
void device_list::start_all()
{
// add exit and reset callbacks
machine().add_notifier(MACHINE_NOTIFY_RESET, static_reset);
machine().add_notifier(MACHINE_NOTIFY_EXIT, static_exit);
machine().add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(device_list::reset_all), this));
machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(device_list::exit), this));
// add pre-save and post-load callbacks
machine().save().register_presave(static_pre_save, this);
@ -178,7 +178,7 @@ void device_list::start_new_devices()
// reset_all - reset all devices in the list
//-------------------------------------------------
void device_list::reset_all() const
void device_list::reset_all()
{
// iterate over devices and reset them
for (device_t *device = first(); device != NULL; device = device->next())
@ -266,32 +266,21 @@ device_t *device_list::find(device_type type, int index) const
}
//-------------------------------------------------
// static_reset - internal callback for resetting
// all devices
//-------------------------------------------------
void device_list::static_reset(running_machine &machine)
{
machine.devicelist().reset_all();
}
//-------------------------------------------------
// static_exit - tear down all the devices
//-------------------------------------------------
void device_list::static_exit(running_machine &machine)
void device_list::exit()
{
// first let the debugger save comments
if ((machine.debug_flags & DEBUG_FLAG_ENABLED) != 0)
debug_comment_save(machine);
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
debug_comment_save(machine());
// stop all the devices before we go away
const_cast<device_list &>(machine.devicelist()).stop_all();
stop_all();
// then nuke the devices
const_cast<device_list &>(machine.devicelist()).reset();
reset();
}

View File

@ -126,7 +126,7 @@ typedef void (*write_line_device_func)(device_t *device, int state);
// ======================> tagged_device_list
// tagged_device_list is a tagged_list with additional searching based on type
class device_list : public tagged_list<device_t>
class device_list : public tagged_list<device_t>, public bindable_object
{
typedef tagged_list<device_t> super;
@ -141,7 +141,7 @@ public:
void set_machine_all(running_machine &machine);
void start_all();
void start_new_devices();
void reset_all() const;
void reset_all();
void stop_all();
// pull the generic forms forward
@ -163,8 +163,7 @@ public:
private:
// internal helpers
static void static_reset(running_machine &machine);
static void static_exit(running_machine &machine);
void exit();
static void static_pre_save(running_machine &machine, void *param);
static void static_post_load(running_machine &machine, void *param);
@ -177,7 +176,7 @@ private:
// ======================> device_t
// device_t represents a device
class device_t : public bindable_object
class device_t : public virtual bindable_object
{
DISABLE_COPYING(device_t);
@ -460,7 +459,7 @@ private:
// ======================> device_interface
// device_interface represents runtime information for a particular device interface
class device_interface
class device_interface : public virtual bindable_object
{
DISABLE_COPYING(device_interface);

View File

@ -607,7 +607,7 @@ void device_execute_interface::interface_post_reset()
screen = device().machine().first_screen();
assert(screen != NULL);
screen->register_vblank_callback(static_on_vblank, NULL);
screen->register_vblank_callback(vblank_state_delegate(FUNC(device_execute_interface::on_vblank), this));
}
// reconfigure periodic interrupts
@ -707,46 +707,27 @@ TIMER_CALLBACK( device_execute_interface::static_timed_trigger_callback )
// for this screen
//-------------------------------------------------
void device_execute_interface::static_on_vblank(screen_device &screen, void *param, bool vblank_state)
void device_execute_interface::on_vblank(screen_device &screen, bool vblank_state)
{
// VBLANK starting
if (vblank_state)
{
device_execute_interface *exec = NULL;
for (bool gotone = screen.machine().devicelist().first(exec); gotone; gotone = exec->next(exec))
exec->on_vblank_start(screen);
}
}
// ignore VBLANK end
if (!vblank_state)
return;
void device_execute_interface::on_vblank_start(screen_device &screen)
{
// start the interrupt counter
if (!suspended(SUSPEND_REASON_DISABLE))
m_iloops = 0;
else
m_iloops = -1;
// the hack style VBLANK decleration always uses the first screen
bool interested = false;
if (m_vblank_interrupts_per_frame > 1)
interested = true;
// generate the interrupt callback
if (!suspended(SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE))
(*m_vblank_interrupt)(&m_device);
// for new style declaration, we need to compare the tags
else if (m_vblank_interrupt_screen != NULL)
interested = (strcmp(screen.tag(), m_vblank_interrupt_screen) == 0);
// if interested, call the interrupt handler
if (interested)
// if we have more than one interrupt per frame, start the timer now to trigger the rest of them
if (m_vblank_interrupts_per_frame > 1 && !suspended(SUSPEND_REASON_DISABLE))
{
if (!suspended(SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE))
(*m_vblank_interrupt)(&m_device);
// if we have more than one interrupt per frame, start the timer now to trigger the rest of them
if (m_vblank_interrupts_per_frame > 1 && !suspended(SUSPEND_REASON_DISABLE))
{
m_partial_frame_period = device().machine().primary_screen->frame_period() / m_vblank_interrupts_per_frame;
m_partial_frame_timer->adjust(m_partial_frame_period);
}
m_partial_frame_period = device().machine().primary_screen->frame_period() / m_vblank_interrupts_per_frame;
m_partial_frame_timer->adjust(m_partial_frame_period);
}
}

View File

@ -306,8 +306,7 @@ private:
// callbacks
static void static_timed_trigger_callback(running_machine &machine, void *ptr, int param);
static void static_on_vblank(screen_device &screen, void *param, bool vblank_state);
void on_vblank_start(screen_device &screen);
void on_vblank(screen_device &screen, bool vblank_state);
static void static_trigger_partial_frame_interrupt(running_machine &machine, void *ptr, int param);
void trigger_partial_frame_interrupt();

View File

@ -205,12 +205,6 @@ inline void operator--(_Type &value, int) { value = (_Type)((int)value - 1); }
#define FUNC(x) &x, #x
#define FUNC_NULL NULL, "(null)"
// this macro wraps a member function 'x' from class 'c'
#define MFUNC(c,x) &c::x, #c "::" #x
// this macro wraps a member function 'x' from class 'c' using a templatized stub of type 's'
#define MSTUB(s,c,x) s##_stub<c, &c::x>, #c "::" #x
// standard assertion macros
#undef assert

View File

@ -111,7 +111,7 @@ void palette_init(running_machine &machine)
/* request cleanup */
machine.palette_data = palette;
machine.add_notifier(MACHINE_NOTIFY_EXIT, palette_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(palette_exit), &machine));
/* reset all our data */
palette->format = format;

View File

@ -278,7 +278,7 @@ void image_postdevice_init(running_machine &machine)
}
/* add a callback for when we shut down */
machine.add_notifier(MACHINE_NOTIFY_EXIT, image_unload_all);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(image_unload_all), &machine));
}
/***************************************************************************
INITIALIZATION
@ -291,7 +291,7 @@ void image_postdevice_init(running_machine &machine)
void image_init(running_machine &machine)
{
image_device_init(machine);
config_register(machine, "image_directories", image_dirs_load, image_dirs_save);
config_register(machine, "image_directories", config_saveload_delegate(FUNC(image_dirs_load), &machine), config_saveload_delegate(FUNC(image_dirs_save), &machine));
}

View File

@ -984,8 +984,8 @@ time_t input_port_init(running_machine &machine, const input_port_token *tokens,
//portdata = machine.input_port_data;
/* add an exit callback and a frame callback */
machine.add_notifier(MACHINE_NOTIFY_EXIT, input_port_exit);
machine.add_notifier(MACHINE_NOTIFY_FRAME, frame_update_callback);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(input_port_exit), &machine));
machine.add_notifier(MACHINE_NOTIFY_FRAME, machine_notify_delegate(FUNC(frame_update_callback), &machine));
/* initialize the default port info from the OSD */
init_port_types(machine);
@ -1010,7 +1010,7 @@ time_t input_port_init(running_machine &machine, const input_port_token *tokens,
init_port_state(machine);
/* register callbacks for when we load configurations */
config_register(machine, "input", load_config_callback, save_config_callback);
config_register(machine, "input", config_saveload_delegate(FUNC(load_config_callback), &machine), config_saveload_delegate(FUNC(save_config_callback), &machine));
/* open playback and record files if specified */
basetime = playback_init(machine);
@ -5051,7 +5051,7 @@ static void setup_keybuffer(running_machine &machine)
input_port_private *portdata = machine.input_port_data;
portdata->inputx_timer = machine.scheduler().timer_alloc(FUNC(inputx_timerproc));
portdata->keybuffer = auto_alloc_clear(machine, key_buffer);
machine.add_notifier(MACHINE_NOTIFY_EXIT, clear_keybuffer);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(clear_keybuffer), &machine));
}

View File

@ -595,7 +595,7 @@ void input_init(running_machine &machine)
code_pressed_memory_reset(machine);
/* request a per-frame callback for bookkeeping */
machine.add_notifier(MACHINE_NOTIFY_FRAME, input_frame);
machine.add_notifier(MACHINE_NOTIFY_FRAME, machine_notify_delegate(FUNC(input_frame), &machine));
/* read input enable options */
device_list[DEVICE_CLASS_KEYBOARD].enabled = TRUE;

View File

@ -264,7 +264,7 @@ void running_machine::start()
generic_sound_init(*this);
// allocate a soft_reset timer
m_soft_reset_timer = m_scheduler.timer_alloc(MSTUB(timer_expired, running_machine, soft_reset), this);
m_soft_reset_timer = m_scheduler.timer_alloc(timer_expired_delegate(FUNC(running_machine::soft_reset), this));
// init the osd layer
m_osd.init(*this);
@ -403,7 +403,7 @@ int running_machine::run(bool firstrun)
ui_display_startup_screens(*this, firstrun, !settingsloaded);
// perform a soft reset -- this takes us to the running phase
soft_reset(*this);
soft_reset();
// run the CPUs until a reset or exit
m_hard_reset_pending = false;
@ -656,7 +656,7 @@ void running_machine::region_free(const char *name)
// given type
//-------------------------------------------------
void running_machine::add_notifier(machine_notification event, notify_callback callback)
void running_machine::add_notifier(machine_notification event, machine_notify_delegate callback)
{
assert_always(m_current_phase == MACHINE_PHASE_INIT, "Can only call add_notifier at init time!");
@ -767,7 +767,7 @@ UINT32 running_machine::rand()
void running_machine::call_notifiers(machine_notification which)
{
for (notifier_callback_item *cb = m_notifier_list[which].first(); cb != NULL; cb = cb->next())
(*cb->m_func)(*this);
cb->m_func();
}
@ -859,7 +859,7 @@ cancel:
// of the system
//-------------------------------------------------
void running_machine::soft_reset(running_machine &machine, int param)
void running_machine::soft_reset(void *ptr, INT32 param)
{
logerror("Soft reset\n");
@ -927,7 +927,7 @@ memory_region::~memory_region()
// notifier_callback_item - constructor
//-------------------------------------------------
running_machine::notifier_callback_item::notifier_callback_item(notify_callback func)
running_machine::notifier_callback_item::notifier_callback_item(machine_notify_delegate func)
: m_next(NULL),
m_func(func)
{

View File

@ -306,6 +306,8 @@ public:
// ======================> running_machine
typedef delegate<void ()> machine_notify_delegate;
// description of the currently-running machine
class running_machine : public bindable_object
{
@ -314,7 +316,6 @@ class running_machine : public bindable_object
friend void debugger_init(running_machine &machine);
friend class sound_manager;
typedef void (*notify_callback)(running_machine &machine);
typedef void (*logerror_callback)(running_machine &machine, const char *string);
// must be at top of member variables
@ -371,7 +372,7 @@ public:
int run(bool firstrun);
void pause();
void resume();
void add_notifier(machine_notification event, notify_callback callback);
void add_notifier(machine_notification event, machine_notify_delegate callback);
void call_notifiers(machine_notification which);
void add_logerror_callback(logerror_callback callback);
void set_ui_active(bool active) { m_ui_active = active; }
@ -440,7 +441,7 @@ private:
void set_saveload_filename(const char *filename);
void fill_systime(system_time &systime, time_t t);
void handle_saveload();
void soft_reset(running_machine &machine, int param = 0);
void soft_reset(void *ptr = NULL, INT32 param = 0);
// internal callbacks
static void logfile_callback(running_machine &machine, const char *buffer);
@ -499,14 +500,14 @@ private:
struct notifier_callback_item
{
// construction/destruction
notifier_callback_item(notify_callback func);
notifier_callback_item(machine_notify_delegate func);
// getters
notifier_callback_item *next() const { return m_next; }
// state
notifier_callback_item * m_next;
notify_callback m_func;
machine_notify_delegate m_func;
};
simple_list<notifier_callback_item> m_notifier_list[MACHINE_NOTIFY_COUNT];

View File

@ -108,17 +108,17 @@ void generic_machine_init(running_machine &machine)
state->memcard_inserted = -1;
/* register a reset callback and save state for interrupt enable */
machine.add_notifier(MACHINE_NOTIFY_RESET, interrupt_reset);
machine.add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(interrupt_reset), &machine));
machine.save().save_item(NAME(state->interrupt_enable));
/* register for configuration */
config_register(machine, "counters", counters_load, counters_save);
config_register(machine, "counters", config_saveload_delegate(FUNC(counters_load), &machine), config_saveload_delegate(FUNC(counters_save), &machine));
/* for memory cards, request save state and an exit callback */
if (machine.config().m_memcard_handler != NULL)
{
state_save_register_global(machine, state->memcard_inserted);
machine.add_notifier(MACHINE_NOTIFY_EXIT, memcard_eject);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(memcard_eject), &machine));
}
}

View File

@ -287,9 +287,8 @@ static void update_slider_pos(ldcore_data *ldcore, attotime curtime)
change of the VBLANK signal
-------------------------------------------------*/
static void vblank_state_changed(screen_device &screen, void *param, bool vblank_state)
static void vblank_state_changed(device_t *device, screen_device &screen, bool vblank_state)
{
device_t *device = (device_t *)param;
laserdisc_state *ld = get_safe_token(device);
ldcore_data *ldcore = ld->core;
attotime curtime = screen.machine().time();
@ -1393,7 +1392,7 @@ static void init_video(device_t *device)
int index;
/* register for VBLANK callbacks */
ld->screen->register_vblank_callback(vblank_state_changed, (void *)device);
ld->screen->register_vblank_callback(vblank_state_delegate(FUNC(vblank_state_changed), device));
/* allocate video frames */
for (index = 0; index < ARRAY_LENGTH(ldcore->frame); index++)
@ -1517,7 +1516,7 @@ static DEVICE_START( laserdisc )
init_audio(device);
/* register callbacks */
config_register(device->machine(), "laserdisc", configuration_load, configuration_save);
config_register(device->machine(), "laserdisc", config_saveload_delegate(FUNC(configuration_load), &device->machine()), config_saveload_delegate(FUNC(configuration_save), &device->machine()));
}

View File

@ -147,11 +147,11 @@ INLINE output_item *create_new_item(const char *outname, INT32 value)
void output_init(running_machine &machine)
{
/* add pause callback */
machine.add_notifier(MACHINE_NOTIFY_PAUSE, output_pause);
machine.add_notifier(MACHINE_NOTIFY_RESUME, output_resume);
machine.add_notifier(MACHINE_NOTIFY_PAUSE, machine_notify_delegate(FUNC(output_pause), &machine));
machine.add_notifier(MACHINE_NOTIFY_RESUME, machine_notify_delegate(FUNC(output_resume), &machine));
/* get a callback when done */
machine.add_notifier(MACHINE_NOTIFY_EXIT, output_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(output_exit), &machine));
/* reset the lists */
memset(itemtable, 0, sizeof(itemtable));

View File

@ -2465,7 +2465,7 @@ render_manager::render_manager(running_machine &machine)
m_screen_container_list(machine.respool())
{
// register callbacks
config_register(machine, "video", config_load_static, config_save_static);
config_register(machine, "video", config_saveload_delegate(FUNC(render_manager::config_load), this), config_saveload_delegate(FUNC(render_manager::config_save), this));
// create one container per screen
for (screen_device *screen = machine.first_screen(); screen != NULL; screen = screen->next_screen())
@ -2684,11 +2684,6 @@ void render_manager::container_free(render_container *container)
// configuration file
//-------------------------------------------------
void render_manager::config_load_static(running_machine &machine, int config_type, xml_data_node *parentnode)
{
machine.render().config_load(config_type, parentnode);
}
void render_manager::config_load(int config_type, xml_data_node *parentnode)
{
// we only care about game files
@ -2748,11 +2743,6 @@ void render_manager::config_load(int config_type, xml_data_node *parentnode)
// file
//-------------------------------------------------
void render_manager::config_save_static(running_machine &machine, int config_type, xml_data_node *parentnode)
{
machine.render().config_save(config_type, parentnode);
}
void render_manager::config_save(int config_type, xml_data_node *parentnode)
{
// we only care about game files

View File

@ -714,7 +714,7 @@ private:
// ======================> render_manager
// contains machine-global information and operations
class render_manager
class render_manager : public bindable_object
{
friend class render_target;
@ -761,8 +761,6 @@ private:
void container_free(render_container *container);
// config callbacks
static void config_load_static(running_machine &machine, int config_type, xml_data_node *parentnode);
static void config_save_static(running_machine &machine, int config_type, xml_data_node *parentnode);
void config_load(int config_type, xml_data_node *parentnode);
void config_save(int config_type, xml_data_node *parentnode);

View File

@ -1513,7 +1513,7 @@ void rom_init(running_machine &machine)
machine.romload_data = romdata = auto_alloc_clear(machine, romload_private);
/* make sure we get called back on the way out */
machine.add_notifier(MACHINE_NOTIFY_EXIT, rom_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(rom_exit), &machine));
/* reset the romdata struct */
romdata->m_machine = &machine;

View File

@ -78,10 +78,8 @@ emu_timer::emu_timer()
: m_machine(NULL),
m_next(NULL),
m_prev(NULL),
m_callback(NULL),
m_param(0),
m_ptr(NULL),
m_func(NULL),
m_enabled(false),
m_temporary(false),
m_period(attotime::zero),
@ -107,7 +105,7 @@ emu_timer::~emu_timer()
// re-allocated as a non-device timer
//-------------------------------------------------
emu_timer &emu_timer::init(running_machine &machine, timer_expired_func callback, const char *name, void *ptr, bool temporary)
emu_timer &emu_timer::init(running_machine &machine, timer_expired_delegate callback, void *ptr, bool temporary)
{
// ensure the entire timer state is clean
m_machine = &machine;
@ -116,7 +114,6 @@ emu_timer &emu_timer::init(running_machine &machine, timer_expired_func callback
m_callback = callback;
m_param = 0;
m_ptr = ptr;
m_func = (name != NULL) ? name : "?";
m_enabled = false;
m_temporary = temporary;
m_period = attotime::never;
@ -146,10 +143,9 @@ emu_timer &emu_timer::init(device_t &device, device_timer_id id, void *ptr, bool
m_machine = &device.machine();
m_next = NULL;
m_prev = NULL;
m_callback = NULL;
m_callback = timer_expired_delegate();
m_param = 0;
m_ptr = ptr;
m_func = NULL;
m_enabled = false;
m_temporary = temporary;
m_period = attotime::never;
@ -274,9 +270,9 @@ void emu_timer::register_save()
// for non-device timers, it is an index based on the callback function name
if (m_device == NULL)
{
name = m_func;
name = m_callback.name();
for (emu_timer *curtimer = machine().scheduler().first_timer(); curtimer != NULL; curtimer = curtimer->next())
if (!curtimer->m_temporary && curtimer->m_device == NULL && strcmp(curtimer->m_func, m_func) == 0)
if (!curtimer->m_temporary && curtimer->m_device == NULL && strcmp(curtimer->m_callback.name(), m_callback.name()) == 0)
index++;
}
@ -340,7 +336,7 @@ device_scheduler::device_scheduler(running_machine &machine) :
m_quantum_minimum(ATTOSECONDS_IN_NSEC(1) / 1000)
{
// append a single never-expiring timer so there is always one in the list
m_timer_list = &m_timer_allocator.alloc()->init(machine, NULL, NULL, NULL, true);
m_timer_list = &m_timer_allocator.alloc()->init(machine, timer_expired_delegate(), NULL, true);
m_timer_list->adjust(attotime::never);
// register global states
@ -532,7 +528,7 @@ void device_scheduler::trigger(int trigid, attotime after)
// if we have a non-zero time, schedule a timer
if (after != attotime::zero)
timer_set(after, MSTUB(timer_expired, device_scheduler, timed_trigger), trigid, this);
timer_set(after, timer_expired_delegate(FUNC(device_scheduler::timed_trigger), this), trigid);
// send the trigger to everyone who cares
else
@ -560,9 +556,9 @@ void device_scheduler::boost_interleave(attotime timeslice_time, attotime boost_
// timer and return a pointer
//-------------------------------------------------
emu_timer *device_scheduler::timer_alloc(timer_expired_func callback, const char *name, void *ptr)
emu_timer *device_scheduler::timer_alloc(timer_expired_delegate callback, void *ptr)
{
return &m_timer_allocator.alloc()->init(machine(), callback, name, ptr, false);
return &m_timer_allocator.alloc()->init(machine(), callback, ptr, false);
}
@ -572,9 +568,9 @@ emu_timer *device_scheduler::timer_alloc(timer_expired_func callback, const char
// amount of time
//-------------------------------------------------
void device_scheduler::timer_set(attotime duration, timer_expired_func callback, const char *name, int param, void *ptr)
void device_scheduler::timer_set(attotime duration, timer_expired_delegate callback, int param, void *ptr)
{
m_timer_allocator.alloc()->init(machine(), callback, name, ptr, true).adjust(duration, param);
m_timer_allocator.alloc()->init(machine(), callback, ptr, true).adjust(duration, param);
}
@ -584,9 +580,9 @@ void device_scheduler::timer_set(attotime duration, timer_expired_func callback,
// frequency
//-------------------------------------------------
void device_scheduler::timer_pulse(attotime period, timer_expired_func callback, const char *name, int param, void *ptr)
void device_scheduler::timer_pulse(attotime period, timer_expired_delegate callback, int param, void *ptr)
{
m_timer_allocator.alloc()->init(machine(), callback, name, ptr, false).adjust(period, param, period);
m_timer_allocator.alloc()->init(machine(), callback, ptr, false).adjust(period, param, period);
}
@ -630,7 +626,7 @@ void device_scheduler::eat_all_cycles()
// given amount of time
//-------------------------------------------------
void device_scheduler::timed_trigger(running_machine &machine, INT32 param)
void device_scheduler::timed_trigger(void *ptr, INT32 param)
{
trigger(param);
}
@ -874,8 +870,8 @@ void device_scheduler::execute_timers()
if (timer.m_device != NULL)
timer.m_device->timer_expired(timer, timer.m_id, timer.m_param, timer.m_ptr);
else if (timer.m_callback != NULL)
(*timer.m_callback)(machine(), timer.m_ptr, timer.m_param);
else if (!timer.m_callback.isnull())
timer.m_callback(timer.m_ptr, timer.m_param);
g_profiler.stop();
}

View File

@ -71,6 +71,9 @@
//**************************************************************************
// timer callbacks look like this
typedef delegate<void (void *, INT32)> timer_expired_delegate;
// old-skool callbacks are like this
typedef void (*timer_expired_func)(running_machine &machine, void *ptr, INT32 param);
// stub for when the ptr parameter points to a class
@ -96,7 +99,7 @@ class emu_timer
~emu_timer();
// allocation and re-use
emu_timer &init(running_machine &machine, timer_expired_func callback, const char *name, void *ptr, bool temporary);
emu_timer &init(running_machine &machine, timer_expired_delegate callback, void *ptr, bool temporary);
emu_timer &init(device_t &device, device_timer_id id, void *ptr, bool temporary);
emu_timer &release();
@ -132,10 +135,9 @@ private:
running_machine * m_machine; // reference to the owning machine
emu_timer * m_next; // next timer in order in the list
emu_timer * m_prev; // previous timer in order in the list
timer_expired_func m_callback; // callback function
timer_expired_delegate m_callback; // callback function
INT32 m_param; // integer parameter
void * m_ptr; // pointer parameter
const char * m_func; // string name of the callback function
bool m_enabled; // is the timer enabled?
bool m_temporary; // is the timer temporary?
attotime m_period; // the repeat frequency of the timer
@ -148,7 +150,7 @@ private:
// ======================> device_scheduler
class device_scheduler
class device_scheduler : public bindable_object
{
friend class device_execute_interface;
friend class emu_timer;
@ -172,10 +174,16 @@ public:
void boost_interleave(attotime timeslice_time, attotime boost_duration);
// timers, specified by callback/name
emu_timer *timer_alloc(timer_expired_func callback, const char *name, void *ptr = NULL);
void timer_set(attotime duration, timer_expired_func callback, const char *name, int param = 0, void *ptr = NULL);
void timer_pulse(attotime period, timer_expired_func callback, const char *name, int param = 0, void *ptr = NULL);
void synchronize(timer_expired_func callback = NULL, const char *name = NULL, int param = 0, void *ptr = NULL) { timer_set(attotime::zero, callback, name, param, ptr); }
emu_timer *timer_alloc(timer_expired_delegate callback, void *ptr = NULL);
void timer_set(attotime duration, timer_expired_delegate callback, int param = 0, void *ptr = NULL);
void timer_pulse(attotime period, timer_expired_delegate callback, int param = 0, void *ptr = NULL);
void synchronize(timer_expired_delegate callback = timer_expired_delegate(), int param = 0, void *ptr = NULL) { timer_set(attotime::zero, callback, param, ptr); }
// timers with old-skool callbacks
emu_timer *timer_alloc(timer_expired_func callback, const char *name, void *ptr = NULL) { return timer_alloc(timer_expired_delegate(callback, name, &machine()), ptr); }
void timer_set(attotime duration, timer_expired_func callback, const char *name, int param = 0, void *ptr = NULL) { timer_set(duration, timer_expired_delegate(callback, name, &machine()), param, ptr); }
void timer_pulse(attotime period, timer_expired_func callback, const char *name, int param = 0, void *ptr = NULL) { timer_pulse(period, timer_expired_delegate(callback, name, &machine()), param, ptr); }
void synchronize(timer_expired_func callback, const char *name = NULL, int param = 0, void *ptr = NULL) { timer_set(attotime::zero, callback, name, param, ptr); }
// timers, specified by device/id; generally devices should use the device_t methods instead
emu_timer *timer_alloc(device_t &device, device_timer_id id = 0, void *ptr = NULL);
@ -186,7 +194,7 @@ public:
private:
// callbacks
void timed_trigger(running_machine &machine, INT32 param);
void timed_trigger(void *ptr, INT32 param);
void postload();
// scheduling helpers

View File

@ -106,8 +106,7 @@ screen_device::screen_device(const machine_config &mconfig, const char *tag, dev
m_scanline0_timer(NULL),
m_scanline_timer(NULL),
m_frame_number(0),
m_partial_updates_this_frame(0),
m_callback_list(NULL)
m_partial_updates_this_frame(0)
{
m_visarea.min_x = m_visarea.min_y = 0;
m_visarea.max_x = m_width - 1;
@ -756,25 +755,20 @@ attotime screen_device::time_until_vblank_end() const
// callback
//-------------------------------------------------
void screen_device::register_vblank_callback(vblank_state_changed_func vblank_callback, void *param)
void screen_device::register_vblank_callback(vblank_state_delegate vblank_callback)
{
// validate arguments
assert(vblank_callback != NULL);
assert(!vblank_callback.isnull());
// check if we already have this callback registered
callback_item **itemptr;
for (itemptr = &m_callback_list; *itemptr != NULL; itemptr = &(*itemptr)->m_next)
if ((*itemptr)->m_callback == vblank_callback)
callback_item *item;
for (item = m_callback_list.first(); item != NULL; item = item->next())
if (item->m_callback == vblank_callback)
break;
// if not found, register
if (*itemptr == NULL)
{
*itemptr = auto_alloc(machine(), callback_item);
(*itemptr)->m_next = NULL;
(*itemptr)->m_callback = vblank_callback;
(*itemptr)->m_param = param;
}
if (item == NULL)
m_callback_list.append(*global_alloc(callback_item(vblank_callback)));
}
@ -790,8 +784,8 @@ void screen_device::vblank_begin_callback()
m_vblank_end_time = m_vblank_start_time + attotime(0, m_vblank_period);
// call the screen specific callbacks
for (callback_item *item = m_callback_list; item != NULL; item = item->m_next)
(*item->m_callback)(*this, item->m_param, true);
for (callback_item *item = m_callback_list.first(); item != NULL; item = item->next())
item->m_callback(*this, true);
// if this is the primary screen and we need to update now
if (this == machine().primary_screen && !(machine().config().m_video_attributes & VIDEO_UPDATE_AFTER_VBLANK))
@ -816,8 +810,8 @@ void screen_device::vblank_begin_callback()
void screen_device::vblank_end_callback()
{
// call the screen specific callbacks
for (callback_item *item = m_callback_list; item != NULL; item = item->m_next)
(*item->m_callback)(*this, item->m_param, false);
for (callback_item *item = m_callback_list.first(); item != NULL; item = item->next())
item->m_callback(*this, false);
// if this is the primary screen and we need to update now
if (this == machine().primary_screen && (machine().config().m_video_attributes & VIDEO_UPDATE_AFTER_VBLANK))
@ -1100,4 +1094,3 @@ void screen_device::screen_eof()
machine().driver_data<driver_device>()->screen_eof();
}
}

View File

@ -72,7 +72,8 @@ class screen_device;
// callback that is called to notify of a change in the VBLANK state
typedef void (*vblank_state_changed_func)(screen_device &device, void *param, bool vblank_state);
typedef delegate<void (screen_device &, bool)> vblank_state_delegate;
typedef UINT32 (*screen_update_func)(screen_device *screen, bitmap_t *bitmap, const rectangle *cliprect);
typedef void (*screen_eof_func)(screen_device *screen, running_machine &machine);
@ -147,7 +148,7 @@ public:
void update_now();
// additional helpers
void register_vblank_callback(vblank_state_changed_func vblank_callback, void *param);
void register_vblank_callback(vblank_state_delegate vblank_callback);
bitmap_t *alloc_compatible_bitmap(int width = 0, int height = 0) { return auto_bitmap_alloc(machine(), (width == 0) ? m_width : width, (height == 0) ? m_height : height, format()); }
// internal to the video system
@ -230,13 +231,18 @@ private:
UINT64 m_frame_number; // the current frame number
UINT32 m_partial_updates_this_frame;// partial update counter this frame
struct callback_item
class callback_item
{
public:
callback_item(vblank_state_delegate callback)
: m_next(NULL),
m_callback(callback) { }
callback_item *next() const { return m_next; }
callback_item * m_next;
vblank_state_changed_func m_callback;
void * m_param;
vblank_state_delegate m_callback;
};
callback_item * m_callback_list; // list of VBLANK callbacks
simple_list<callback_item> m_callback_list; // list of VBLANK callbacks
};
// device type definition

View File

@ -800,10 +800,10 @@ sound_manager::sound_manager(running_machine &machine)
m_wavfile = wav_open(wavfile, machine.sample_rate(), 2);
// register callbacks
config_register(machine, "mixer", &sound_manager::config_load, &sound_manager::config_save);
machine.add_notifier(MACHINE_NOTIFY_PAUSE, &sound_manager::pause);
machine.add_notifier(MACHINE_NOTIFY_RESUME, &sound_manager::resume);
machine.add_notifier(MACHINE_NOTIFY_RESET, &sound_manager::reset);
config_register(machine, "mixer", config_saveload_delegate(FUNC(sound_manager::config_load), this), config_saveload_delegate(FUNC(sound_manager::config_save), this));
machine.add_notifier(MACHINE_NOTIFY_PAUSE, machine_notify_delegate(FUNC(sound_manager::pause), this));
machine.add_notifier(MACHINE_NOTIFY_RESUME, machine_notify_delegate(FUNC(sound_manager::resume), this));
machine.add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(sound_manager::reset), this));
// register global states
state_save_register_global(machine, m_last_update);
@ -896,11 +896,11 @@ void sound_manager::mute(bool mute, UINT8 reason)
// reset - reset all sound chips
//-------------------------------------------------
void sound_manager::reset(running_machine &machine)
void sound_manager::reset()
{
// reset all the sound chips
device_sound_interface *sound = NULL;
for (bool gotone = machine.devicelist().first(sound); gotone; gotone = sound->next(sound))
for (bool gotone = machine().devicelist().first(sound); gotone; gotone = sound->next(sound))
sound->device().reset();
}
@ -909,9 +909,9 @@ void sound_manager::reset(running_machine &machine)
// pause - pause sound output
//-------------------------------------------------
void sound_manager::pause(running_machine &machine)
void sound_manager::pause()
{
machine.sound().mute(true, MUTE_REASON_PAUSE);
mute(true, MUTE_REASON_PAUSE);
}
@ -919,9 +919,9 @@ void sound_manager::pause(running_machine &machine)
// resume - resume sound output
//-------------------------------------------------
void sound_manager::resume(running_machine &machine)
void sound_manager::resume()
{
machine.sound().mute(false, MUTE_REASON_PAUSE);
mute(false, MUTE_REASON_PAUSE);
}
@ -930,7 +930,7 @@ void sound_manager::resume(running_machine &machine)
// configuration file
//-------------------------------------------------
void sound_manager::config_load(running_machine &machine, int config_type, xml_data_node *parentnode)
void sound_manager::config_load(int config_type, xml_data_node *parentnode)
{
// we only care about game files
if (config_type != CONFIG_TYPE_GAME)
@ -944,7 +944,7 @@ void sound_manager::config_load(running_machine &machine, int config_type, xml_d
for (xml_data_node *channelnode = xml_get_sibling(parentnode->child, "channel"); channelnode != NULL; channelnode = xml_get_sibling(channelnode->next, "channel"))
{
speaker_input info;
if (machine.sound().indexed_speaker_input(xml_get_attribute_int(channelnode, "index", -1), info))
if (indexed_speaker_input(xml_get_attribute_int(channelnode, "index", -1), info))
{
float defvol = xml_get_attribute_float(channelnode, "defvol", -1000.0);
float newvol = xml_get_attribute_float(channelnode, "newvol", -1000.0);
@ -960,7 +960,7 @@ void sound_manager::config_load(running_machine &machine, int config_type, xml_d
// file
//-------------------------------------------------
void sound_manager::config_save(running_machine &machine, int config_type, xml_data_node *parentnode)
void sound_manager::config_save(int config_type, xml_data_node *parentnode)
{
// we only care about game files
if (config_type != CONFIG_TYPE_GAME)
@ -971,7 +971,7 @@ void sound_manager::config_save(running_machine &machine, int config_type, xml_d
for (int mixernum = 0; ; mixernum++)
{
speaker_input info;
if (!machine.sound().indexed_speaker_input(mixernum, info))
if (!indexed_speaker_input(mixernum, info))
break;
float defvol = info.stream->initial_input_gain(info.inputnum);
float newvol = info.stream->input_gain(info.inputnum);

View File

@ -199,7 +199,7 @@ private:
// ======================> sound_manager
class sound_manager
class sound_manager : public bindable_object
{
friend class sound_stream;
@ -242,11 +242,11 @@ public:
private:
// internal helpers
void mute(bool mute, UINT8 reason);
static void reset(running_machine &machine);
static void pause(running_machine &machine);
static void resume(running_machine &machine);
static void config_load(running_machine &machine, int config_type, xml_data_node *parentnode);
static void config_save(running_machine &machine, int config_type, xml_data_node *parentnode);
void reset();
void pause();
void resume();
void config_load(int config_type, xml_data_node *parentnode);
void config_save(int config_type, xml_data_node *parentnode);
static TIMER_CALLBACK( update_static ) { reinterpret_cast<sound_manager *>(ptr)->update(); }
void update();

View File

@ -305,7 +305,7 @@ void tilemap_init(running_machine &machine)
if (screen_width != 0 && screen_height != 0)
{
machine.priority_bitmap = auto_bitmap_alloc(machine, screen_width, screen_height, BITMAP_FORMAT_INDEXED8);
machine.add_notifier(MACHINE_NOTIFY_EXIT, tilemap_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(tilemap_exit), &machine));
}
}

View File

@ -237,7 +237,7 @@ INLINE int is_breakable_char(unicode_char ch)
int ui_init(running_machine &machine)
{
/* make sure we clean up after ourselves */
machine.add_notifier(MACHINE_NOTIFY_EXIT, ui_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(ui_exit), &machine));
/* initialize the other UI bits */
ui_menu_init(machine);

View File

@ -109,7 +109,7 @@ void ui_gfx_init(running_machine &machine)
int gfx;
/* make sure we clean up after ourselves */
machine.add_notifier(MACHINE_NOTIFY_EXIT, ui_gfx_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(ui_gfx_exit), &machine));
/* initialize our global state */
memset(state, 0, sizeof(*state));

View File

@ -80,7 +80,7 @@ void ui_input_init(running_machine &machine)
machine.ui_input_data->current_mouse_y = -1;
/* add a frame callback to poll inputs */
machine.add_notifier(MACHINE_NOTIFY_FRAME, ui_input_frame_update);
machine.add_notifier(MACHINE_NOTIFY_FRAME, machine_notify_delegate(FUNC(ui_input_frame_update), &machine));
}

View File

@ -413,7 +413,7 @@ void ui_menu_init(running_machine &machine)
arrow_texture = machine.render().texture_alloc(menu_render_triangle);
/* add an exit callback to free memory */
machine.add_notifier(MACHINE_NOTIFY_EXIT, ui_menu_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(ui_menu_exit), &machine));
}

View File

@ -135,7 +135,7 @@ video_manager::video_manager(running_machine &machine)
m_movie_frame(0)
{
// request a callback upon exiting
machine.add_notifier(MACHINE_NOTIFY_EXIT, exit_static);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(video_manager::exit), this));
machine.save().register_postload(state_postload_stub<video_manager, &video_manager::postload>, this);
// extract initial execution state from global configuration settings
@ -180,7 +180,7 @@ video_manager::video_manager(running_machine &machine)
// if no screens, create a periodic timer to drive updates
if (machine.primary_screen == NULL)
{
m_screenless_frame_timer = machine.scheduler().timer_alloc(FUNC(screenless_update_callback), this);
m_screenless_frame_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(video_manager::screenless_update_callback), this));
m_screenless_frame_timer->adjust(screen_device::DEFAULT_FRAME_PERIOD, 0, screen_device::DEFAULT_FRAME_PERIOD);
}
}
@ -535,11 +535,6 @@ void video_manager::add_sound_to_recording(const INT16 *sound, int numsamples)
// video_exit - close down the video system
//-------------------------------------------------
void video_manager::exit_static(running_machine &machine)
{
machine.video().exit();
}
void video_manager::exit()
{
// stop recording any movie
@ -570,10 +565,10 @@ void video_manager::exit()
// when there are no screens to drive it
//-------------------------------------------------
TIMER_CALLBACK( video_manager::screenless_update_callback )
void video_manager::screenless_update_callback(void *ptr, int param)
{
// force an update
reinterpret_cast<video_manager *>(ptr)->frame_update(false);
frame_update(false);
}

View File

@ -70,7 +70,7 @@ typedef struct _avi_file avi_file;
// ======================> video_manager
class video_manager
class video_manager : public bindable_object
{
friend class screen_device;
@ -118,9 +118,8 @@ public:
private:
// internal helpers
static void exit_static(running_machine &machine);
void exit();
static TIMER_CALLBACK( screenless_update_callback );
void screenless_update_callback(void *ptr, int param);
void postload();
// effective value helpers

View File

@ -41,7 +41,7 @@ void watchdog_init(running_machine &machine)
/* allocate a timer for the watchdog */
watchdog_timer = machine.scheduler().timer_alloc(FUNC(watchdog_callback));
machine.add_notifier(MACHINE_NOTIFY_RESET, watchdog_internal_reset);
machine.add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(watchdog_internal_reset), &machine));
/* save some stuff in the default tag */
machine.save().save_item(NAME(watchdog_enabled));
@ -84,7 +84,7 @@ static TIMER_CALLBACK( watchdog_callback )
timers
-------------------------------------------------*/
static void on_vblank(screen_device &screen, void *param, bool vblank_state)
static void on_vblank(running_machine &machine, screen_device &screen, bool vblank_state)
{
/* VBLANK starting */
if (vblank_state && watchdog_enabled)
@ -118,7 +118,7 @@ void watchdog_reset(running_machine &machine)
/* register a VBLANK callback for the primary screen */
if (machine.primary_screen != NULL)
machine.primary_screen->register_vblank_callback(on_vblank, NULL);
machine.primary_screen->register_vblank_callback(vblank_state_delegate(FUNC(on_vblank), &machine));
}
/* timer-based watchdog? */

View File

@ -2318,7 +2318,7 @@ static void cps3_exit(running_machine &machine)
static MACHINE_START( cps3 )
{
wd33c93_init(machine, &scsi_intf);
machine.add_notifier(MACHINE_NOTIFY_EXIT, cps3_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(cps3_exit), &machine));
}
static MACHINE_RESET( cps3 )

View File

@ -936,7 +936,7 @@ static void atapi_init(running_machine &machine)
SCSIAllocInstance( machine, SCSI_DEVICE_CDROM, &state->m_atapi_device_data[0], "scsi0" );
// TODO: the slave drive can be either CD-ROM, DVD-ROM or HDD
SCSIAllocInstance( machine, SCSI_DEVICE_CDROM, &state->m_atapi_device_data[1], "scsi1" );
machine.add_notifier(MACHINE_NOTIFY_EXIT, atapi_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(atapi_exit), &machine));
}
static void atapi_reset(running_machine &machine)

View File

@ -365,7 +365,7 @@ static MACHINE_START( konamigq )
/* init the scsi controller and hook up it's DMA */
am53cf96_init(machine, &scsi_intf);
machine.add_notifier(MACHINE_NOTIFY_EXIT, konamigq_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(konamigq_exit), &machine));
psx_dma_install_read_handler(machine, 5, scsi_dma_read);
psx_dma_install_write_handler(machine, 5, scsi_dma_write);

View File

@ -306,7 +306,7 @@ static DRIVER_INIT( konamigv )
/* init the scsi controller and hook up it's DMA */
am53cf96_init(machine, &scsi_intf);
machine.add_notifier(MACHINE_NOTIFY_EXIT, konamigv_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(konamigv_exit), &machine));
psx_dma_install_read_handler(machine, 5, scsi_dma_read);
psx_dma_install_write_handler(machine, 5, scsi_dma_write);
}

View File

@ -1032,7 +1032,7 @@ static void atapi_init(running_machine &machine)
state->m_available_cdroms[ i ] = NULL;
}
}
machine.add_notifier(MACHINE_NOTIFY_EXIT, atapi_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(atapi_exit), &machine));
state->save_item( NAME(state->m_atapi_regs) );

View File

@ -1264,7 +1264,7 @@ static void install_speedups(running_machine &machine, const speedup_entry *entr
machine.device("maincpu")->memory().space(AS_PROGRAM)->install_legacy_read_handler(entries[i].offset, entries[i].offset + 3, speedup_handlers[i].func, speedup_handlers[i].name);
#ifdef MAME_DEBUG
machine.add_notifier(MACHINE_NOTIFY_EXIT, report_speedups);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(report_speedups), &machine));
#endif
}

View File

@ -1197,13 +1197,13 @@ static void configure_fast_ram(running_machine &machine)
static MACHINE_START(model3_10)
{
lsi53c810_init(machine, &scsi_intf);
machine.add_notifier(MACHINE_NOTIFY_EXIT, model3_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(model3_exit), &machine));
configure_fast_ram(machine);
}
static MACHINE_START(model3_15)
{
lsi53c810_init(machine, &scsi_intf);
machine.add_notifier(MACHINE_NOTIFY_EXIT, model3_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(model3_exit), &machine));
configure_fast_ram(machine);
}
static MACHINE_START(model3_20)

View File

@ -3149,7 +3149,7 @@ static MACHINE_START( stv )
stv_register_protection_savestates(machine); // machine/stvprot.c
machine.add_notifier(MACHINE_NOTIFY_EXIT, stvcd_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(stvcd_exit), &machine));
smpc_ram[0x23] = DectoBCD(systime.local_time.year /100);
smpc_ram[0x25] = DectoBCD(systime.local_time.year %100);
@ -3192,7 +3192,7 @@ static MACHINE_START( saturn )
state_save_register_global(machine, smpcSR);
state_save_register_global_array(machine, SMEM);
machine.add_notifier(MACHINE_NOTIFY_EXIT, stvcd_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(stvcd_exit), &machine));
}

View File

@ -2729,7 +2729,7 @@ static void init_common(running_machine &machine)
state->save_item(NAME(state->m_dac_out));
state->save_item(NAME(state->m_dac_vol));
machine.add_notifier(MACHINE_NOTIFY_RESET, reset_common);
machine.add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(reset_common), &machine));
}
static DRIVER_INIT( taitosj )

View File

@ -349,10 +349,10 @@ void atari_machine_start(running_machine &machine)
gtia_init(machine, &gtia_intf);
/* pokey */
machine.add_notifier(MACHINE_NOTIFY_RESET, pokey_reset);
machine.add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(pokey_reset), &machine));
/* ANTIC */
machine.add_notifier(MACHINE_NOTIFY_RESET, _antic_reset);
machine.add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(_antic_reset), &machine));
/* save states */
state_save_register_global_pointer(machine, ((UINT8 *) &antic.r), sizeof(antic.r));

View File

@ -410,7 +410,7 @@ static void sys16_decrypt(running_machine &machine, const UINT8 *key,int cputype
int A;
decrypted = auto_alloc_array(machine, UINT16, size/2);
machine.add_notifier(MACHINE_NOTIFY_EXIT, clear_decrypted);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(clear_decrypted), &machine));
space->set_decrypted_region(0x000000, size - 1, decrypted);
for (A = 0;A < size;A+=2)

View File

@ -1943,7 +1943,7 @@ static void genesis_machine_stop(running_machine &machine)
MACHINE_START( md_sram )
{
machine.add_notifier(MACHINE_NOTIFY_EXIT, genesis_machine_stop);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(genesis_machine_stop), &machine));
}
/******* 32X image loading *******/

View File

@ -121,7 +121,7 @@ void tecmosys_prot_init(running_machine &machine, int which)
case 2: state->m_device_data = &tkdensha_data; break;
}
machine.add_notifier(MACHINE_NOTIFY_RESET, tecmosys_prot_reset);
machine.add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(tecmosys_prot_reset), &machine));
}
READ16_HANDLER(tecmosys_prot_status_r)

View File

@ -62,7 +62,7 @@ VIDEO_START( gaelco3d )
int width, height;
state->m_poly = poly_alloc(machine, 2000, sizeof(poly_extra_data), 0);
machine.add_notifier(MACHINE_NOTIFY_EXIT, gaelco3d_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(gaelco3d_exit), &machine));
state->m_screenbits = machine.primary_screen->alloc_compatible_bitmap();

View File

@ -37,7 +37,7 @@ VIDEO_START( galastrm )
state->m_polybitmap = machine.primary_screen->alloc_compatible_bitmap();
state->m_poly = poly_alloc(machine, 16, sizeof(poly_extra_data), POLYFLAG_ALLOW_QUADS);
machine.add_notifier(MACHINE_NOTIFY_EXIT, galastrm_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(galastrm_exit), &machine));
}
/************************************************************

View File

@ -68,7 +68,7 @@ void gtia_init(running_machine &machine, const gtia_interface *intf)
memset(&gtia, 0, sizeof(gtia));
gtia.intf = *intf;
machine.add_notifier(MACHINE_NOTIFY_RESET, gtia_reset);
machine.add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(gtia_reset), &machine));
/* state saves */
gtia_state(machine);

View File

@ -220,7 +220,7 @@ void K001005_init(running_machine &machine)
K001005_3d_fifo = auto_alloc_array(machine, UINT32, 0x10000);
poly = poly_alloc(machine, 4000, sizeof(poly_extra_data), POLYFLAG_ALLOW_QUADS);
machine.add_notifier(MACHINE_NOTIFY_EXIT, K001005_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(K001005_exit), &machine));
for (i=0; i < 128; i++)
{

View File

@ -29,7 +29,7 @@ void jal_blend_init(running_machine &machine, int enable)
if (enable)
{
jal_blend_table = auto_alloc_array_clear(machine, UINT8, 0xc00);
machine.add_notifier(MACHINE_NOTIFY_RESET, jal_blend_reset);
machine.add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(jal_blend_reset), &machine));
}
else
{

View File

@ -68,7 +68,7 @@ VIDEO_START( midvunit )
midvunit_state *state = machine.driver_data<midvunit_state>();
state->m_scanline_timer = machine.scheduler().timer_alloc(FUNC(scanline_timer_cb));
state->m_poly = poly_alloc(machine, 4000, sizeof(poly_extra_data), POLYFLAG_ALLOW_QUADS);
machine.add_notifier(MACHINE_NOTIFY_EXIT, midvunit_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(midvunit_exit), &machine));
state_save_register_global_array(machine, state->m_video_regs);
state_save_register_global_array(machine, state->m_dma_data);

View File

@ -259,7 +259,7 @@ VIDEO_START( midzeus )
poly = poly_alloc(machine, 10000, sizeof(poly_extra_data), POLYFLAG_ALLOW_QUADS);
/* we need to cleanup on exit */
machine.add_notifier(MACHINE_NOTIFY_EXIT, exit_handler);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(exit_handler), &machine));
yoffs = 0;
texel_width = 256;

View File

@ -273,7 +273,7 @@ VIDEO_START( midzeus2 )
poly = poly_alloc(machine, 10000, sizeof(poly_extra_data), POLYFLAG_ALLOW_QUADS);
/* we need to cleanup on exit */
machine.add_notifier(MACHINE_NOTIFY_EXIT, exit_handler);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(exit_handler), &machine));
zbase = 2.0f;
yoffs = 0;

View File

@ -2715,7 +2715,7 @@ VIDEO_START(model2)
state->m_sys24_bitmap = auto_alloc(machine, bitmap_t(width, height+4, BITMAP_FORMAT_INDEXED16));
state->m_poly = poly_alloc(machine, 4000, sizeof(poly_extra_data), 0);
machine.add_notifier(MACHINE_NOTIFY_EXIT, model2_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(model2_exit), &machine));
/* initialize the hardware rasterizer */
model2_3d_init( machine, (UINT16*)machine.region("user3")->base() );

View File

@ -120,7 +120,7 @@ VIDEO_START( model3 )
int width, height;
state->m_poly = poly_alloc(machine, 4000, sizeof(poly_extra_data), 0);
machine.add_notifier(MACHINE_NOTIFY_EXIT, model3_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(model3_exit), &machine));
width = machine.primary_screen->width();
height = machine.primary_screen->height();

View File

@ -2230,8 +2230,8 @@ static VIDEO_START( common )
#else
state->m_poly = poly_alloc(machine, 4000, sizeof(poly_extra_data), 0);
#endif
machine.add_notifier(MACHINE_NOTIFY_RESET, namcos22_reset);
machine.add_notifier(MACHINE_NOTIFY_EXIT, namcos22_exit);
machine.add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(namcos22_reset), &machine));
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(namcos22_exit), &machine));
gfx_element_set_source(machine.gfx[GFX_CHAR], (UINT8 *)state->m_cgram);
}

View File

@ -5444,7 +5444,7 @@ static void stv_vdp2_exit (running_machine &machine)
static int stv_vdp2_start (running_machine &machine)
{
machine.add_notifier(MACHINE_NOTIFY_EXIT, stv_vdp2_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(stv_vdp2_exit), &machine));
stv_vdp2_regs = auto_alloc_array_clear(machine, UINT32, 0x040000/4 );
stv_vdp2_vram = auto_alloc_array_clear(machine, UINT32, 0x100000/4 ); // actually we only need half of it since we don't emulate extra 4mbit ram cart.

View File

@ -177,7 +177,7 @@ VIDEO_START( taitojc )
int width, height;
state->m_poly = poly_alloc(machine, 4000, sizeof(poly_extra_data), POLYFLAG_ALLOW_QUADS);
machine.add_notifier(MACHINE_NOTIFY_EXIT, taitojc_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(taitojc_exit), &machine));
/* find first empty slot to decode gfx */
for (state->m_gfx_index = 0; state->m_gfx_index < MAX_GFX_ELEMENTS; state->m_gfx_index++)

View File

@ -1995,6 +1995,6 @@ void tia_init(running_machine &machine, const struct tia_interface* ti)
tia_reset( machine );
machine.add_notifier(MACHINE_NOTIFY_RESET, tia_reset);
machine.add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(tia_reset), &machine));
}

View File

@ -544,7 +544,7 @@ VIDEO_START( ygv608 )
tilemap_B = NULL;
ygv608_register_state_save(machine);
machine.add_notifier(MACHINE_NOTIFY_EXIT, ygv608_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(ygv608_exit), &machine));
}
static void draw_sprites(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect)

View File

@ -545,7 +545,7 @@ static void configuration_save(running_machine &machine, int config_type, xml_da
void sdl_osd_interface::init_debugger()
{
/* register callbacks */
config_register(machine(), "debugger", configuration_load, configuration_save);
config_register(machine(), "debugger", config_saveload_delegate(FUNC(configuration_load), &machine), config_saveload_delegate(FUNC(configuration_save), &machine));
}

View File

@ -1105,9 +1105,9 @@ void sdlinput_init(running_machine &machine)
app_has_mouse_focus = 1;
// we need pause and exit callbacks
machine.add_notifier(MACHINE_NOTIFY_PAUSE, sdlinput_pause);
machine.add_notifier(MACHINE_NOTIFY_RESUME, sdlinput_resume);
machine.add_notifier(MACHINE_NOTIFY_EXIT, sdlinput_exit);
machine.add_notifier(MACHINE_NOTIFY_PAUSE, machine_notify_delegate(FUNC(sdlinput_pause), &machine);
machine.add_notifier(MACHINE_NOTIFY_RESUME, machine_notify_delegate(FUNC(sdlinput_resume), &machine));
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(sdlinput_exit), &machine));
// allocate a lock for input synchronizations
input_lock = osd_lock_alloc();

View File

@ -75,7 +75,7 @@ void sdloutput_init(running_machine &machine)
{
int fildes;
machine.add_notifier(MACHINE_NOTIFY_EXIT, sdloutput_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(sdloutput_exit), &machine));
fildes = open(SDLMAME_OUTPUT, O_RDWR | O_NONBLOCK);

View File

@ -622,7 +622,7 @@ void sdl_osd_interface::init(running_machine &machine)
osd_sdl_info();
}
// must be before sdlvideo_init!
machine.add_notifier(MACHINE_NOTIFY_EXIT, osd_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(osd_exit), &machine));
defines_verbose();

View File

@ -93,7 +93,7 @@ void sdlaudio_init(running_machine &machine)
if (sdl_init(machine))
return;
machine.add_notifier(MACHINE_NOTIFY_EXIT, sdl_cleanup_audio);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(sdl_cleanup_audio), &machine));
// set the startup volume
machine.osd().set_mastervolume(attenuation);
}

View File

@ -110,7 +110,7 @@ int sdlvideo_init(running_machine &machine)
extract_video_config(machine);
// ensure we get called on the way out
machine.add_notifier(MACHINE_NOTIFY_EXIT, video_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(video_exit), &machine));
// set up monitors first
init_monitors();

View File

@ -213,7 +213,7 @@ int sdlwindow_init(running_machine &machine)
main_threadid = SDL_ThreadID();
// ensure we get called on the way out
machine.add_notifier(MACHINE_NOTIFY_EXIT, sdlwindow_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(sdlwindow_exit), &machine));
// if multithreading, create a thread to run the windows
if (multithreading_enabled)

View File

@ -507,9 +507,9 @@ INLINE INT32 normalize_absolute_axis(INT32 raw, INT32 rawmin, INT32 rawmax)
void wininput_init(running_machine &machine)
{
// we need pause and exit callbacks
machine.add_notifier(MACHINE_NOTIFY_PAUSE, wininput_pause);
machine.add_notifier(MACHINE_NOTIFY_RESUME, wininput_resume);
machine.add_notifier(MACHINE_NOTIFY_EXIT, wininput_exit);
machine.add_notifier(MACHINE_NOTIFY_PAUSE, machine_notify_delegate(FUNC(wininput_pause), &machine));
machine.add_notifier(MACHINE_NOTIFY_RESUME, machine_notify_delegate(FUNC(wininput_resume), &machine));
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(wininput_exit), &machine));
// allocate a lock for input synchronizations, since messages sometimes come from another thread
input_lock = osd_lock_alloc();
@ -952,7 +952,7 @@ static void win32_init(running_machine &machine)
return;
// we need an exit callback
machine.add_notifier(MACHINE_NOTIFY_EXIT, win32_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(win32_exit), &machine));
// allocate two lightgun devices
for (gunnum = 0; gunnum < 2; gunnum++)
@ -1120,7 +1120,7 @@ static void dinput_init(running_machine &machine)
mame_printf_verbose("DirectInput: Using DirectInput %d\n", dinput_version >> 8);
// we need an exit callback
machine.add_notifier(MACHINE_NOTIFY_EXIT, dinput_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(dinput_exit), &machine));
// initialize keyboard devices, but only if we don't have any yet
if (keyboard_list == NULL)
@ -1660,7 +1660,7 @@ static void rawinput_init(running_machine &machine)
HMODULE user32;
// we need pause and exit callbacks
machine.add_notifier(MACHINE_NOTIFY_EXIT, rawinput_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(rawinput_exit), &machine));
// look in user32 for the raw input APIs
user32 = LoadLibrary(TEXT("user32.dll"));

View File

@ -119,7 +119,7 @@ void winoutput_init(running_machine &machine)
int result;
// ensure we get cleaned up
machine.add_notifier(MACHINE_NOTIFY_EXIT, winoutput_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(winoutput_exit), &machine));
// reset globals
clientlist = NULL;

View File

@ -119,7 +119,7 @@ void winsound_init(running_machine &machine)
return;
// ensure we get called on the way out
machine.add_notifier(MACHINE_NOTIFY_EXIT, sound_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(sound_exit), &machine));
// attempt to initialize directsound
// don't make it fatal if we can't -- we'll just run without sound

View File

@ -111,7 +111,7 @@ void winvideo_init(running_machine &machine)
int index;
// ensure we get called on the way out
machine.add_notifier(MACHINE_NOTIFY_EXIT, winvideo_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(winvideo_exit), &machine));
// extract data from the options
extract_video_config(machine);

View File

@ -230,7 +230,7 @@ void winwindow_init(running_machine &machine)
main_threadid = GetCurrentThreadId();
// ensure we get called on the way out
machine.add_notifier(MACHINE_NOTIFY_EXIT, winwindow_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(winwindow_exit), &machine));
// set up window class and register it
create_window_class();

View File

@ -560,7 +560,7 @@ void windows_osd_interface::init(running_machine &machine)
SetThreadPriority(GetCurrentThread(), options.priority());
// ensure we get called on the way out
machine.add_notifier(MACHINE_NOTIFY_EXIT, osd_exit);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(osd_exit), &machine));
// get number of processors
stemp = options.numprocessors();