summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@arcor.de>2015-03-04 01:39:52 +0100
committer couriersud <couriersud@arcor.de>2015-03-04 01:39:52 +0100
commit98a6781c271b004174052bbd1750351149bf91ce (patch)
treeaea69d555669dfacd6eb94ff0dd84d02a9443fd8
parentc5deacfe57571bdcfdfb7bec9a3033be1f78fda7 (diff)
First step to move osd_printf_* into osd again. Callbacks are now
implemented using an interface and use a push/pop approach where the pop can happen out of order of pushes. [Couriersud]
-rw-r--r--src/emu/validity.c82
-rw-r--r--src/emu/validity.h14
-rw-r--r--src/osd/modules/lib/osdobj_common.c43
-rw-r--r--src/osd/modules/lib/osdobj_common.h5
-rw-r--r--src/osd/osdcore.c85
-rw-r--r--src/osd/osdcore.h28
-rw-r--r--src/osd/windows/winmain.c63
7 files changed, 175 insertions, 145 deletions
diff --git a/src/emu/validity.c b/src/emu/validity.c
index cacf92cdafa..4ad2453da32 100644
--- a/src/emu/validity.c
+++ b/src/emu/validity.c
@@ -199,18 +199,18 @@ void validity_checker::check_all()
if (m_errors > 0 || m_warnings > 0)
{
astring tempstr;
- output_via_delegate(m_saved_error_output, "Core: %d errors, %d warnings\n", m_errors, m_warnings);
+ output_via_delegate(OSD_OUTPUT_CHANNEL_ERROR, "Core: %d errors, %d warnings\n", m_errors, m_warnings);
if (m_errors > 0)
{
m_error_text.replace("\n", "\n ");
- output_via_delegate(m_saved_error_output, "Errors:\n %s", m_error_text.cstr());
+ output_via_delegate(OSD_OUTPUT_CHANNEL_ERROR, "Errors:\n %s", m_error_text.cstr());
}
if (m_warnings > 0)
{
m_warning_text.replace("\n", "\n ");
- output_via_delegate(m_saved_error_output, "Warnings:\n %s", m_warning_text.cstr());
+ output_via_delegate(OSD_OUTPUT_CHANNEL_ERROR, "Warnings:\n %s", m_warning_text.cstr());
}
- output_via_delegate(m_saved_error_output, "\n");
+ output_via_delegate(OSD_OUTPUT_CHANNEL_ERROR, "\n");
}
// then iterate over all drivers and check them
@@ -232,8 +232,7 @@ void validity_checker::check_all()
void validity_checker::validate_begin()
{
// take over error and warning outputs
- m_saved_error_output = osd_set_output_channel(OSD_OUTPUT_CHANNEL_ERROR, output_delegate(FUNC(validity_checker::error_output), this));
- m_saved_warning_output = osd_set_output_channel(OSD_OUTPUT_CHANNEL_WARNING, output_delegate(FUNC(validity_checker::warning_output), this));
+ osd_output::push(this);
// reset all our maps
m_names_map.reset();
@@ -257,8 +256,7 @@ void validity_checker::validate_begin()
void validity_checker::validate_end()
{
// restore the original output callbacks
- osd_set_output_channel(OSD_OUTPUT_CHANNEL_ERROR, m_saved_error_output);
- osd_set_output_channel(OSD_OUTPUT_CHANNEL_WARNING, m_saved_warning_output);
+ osd_output::pop(this);
}
@@ -301,18 +299,18 @@ void validity_checker::validate_one(const game_driver &driver)
if (m_errors > start_errors || m_warnings > start_warnings)
{
astring tempstr;
- output_via_delegate(m_saved_error_output, "Driver %s (file %s): %d errors, %d warnings\n", driver.name, core_filename_extract_base(tempstr, driver.source_file).cstr(), m_errors - start_errors, m_warnings - start_warnings);
+ output_via_delegate(OSD_OUTPUT_CHANNEL_ERROR, "Driver %s (file %s): %d errors, %d warnings\n", driver.name, core_filename_extract_base(tempstr, driver.source_file).cstr(), m_errors - start_errors, m_warnings - start_warnings);
if (m_errors > start_errors)
{
m_error_text.replace("\n", "\n ");
- output_via_delegate(m_saved_error_output, "Errors:\n %s", m_error_text.cstr());
+ output_via_delegate(OSD_OUTPUT_CHANNEL_ERROR, "Errors:\n %s", m_error_text.cstr());
}
if (m_warnings > start_warnings)
{
m_warning_text.replace("\n", "\n ");
- output_via_delegate(m_saved_error_output, "Warnings:\n %s", m_warning_text.cstr());
+ output_via_delegate(OSD_OUTPUT_CHANNEL_ERROR, "Warnings:\n %s", m_warning_text.cstr());
}
- output_via_delegate(m_saved_error_output, "\n");
+ output_via_delegate(OSD_OUTPUT_CHANNEL_ERROR, "\n");
}
// reset the driver/device
@@ -834,10 +832,10 @@ void validity_checker::validate_dip_settings(ioport_field &field)
// if we have a coin error, demonstrate the correct way
if (coin_error)
{
- output_via_delegate(m_saved_error_output, " Note proper coin sort order should be:\n");
+ output_via_delegate(OSD_OUTPUT_CHANNEL_ERROR, " Note proper coin sort order should be:\n");
for (int entry = 0; entry < ARRAY_LENGTH(coin_list); entry++)
if (coin_list[entry])
- output_via_delegate(m_saved_error_output, " %s\n", ioport_string_from_index(__input_string_coinage_start + entry));
+ output_via_delegate(OSD_OUTPUT_CHANNEL_ERROR, " %s\n", ioport_string_from_index(__input_string_coinage_start + entry));
}
}
@@ -1057,53 +1055,51 @@ void validity_checker::build_output_prefix(astring &string)
// error_output - error message output override
//-------------------------------------------------
-void validity_checker::error_output(const char *format, va_list argptr)
+void validity_checker::output_callback(osd_output_channel channel, const char *msg, va_list args)
{
- // count the error
- m_errors++;
-
- // output the source(driver) device 'tag'
astring output;
- build_output_prefix(output);
-
- // generate the string
- output.catvprintf(format, argptr);
- m_error_text.cat(output);
-}
-
+ switch (channel)
+ {
+ case OSD_OUTPUT_CHANNEL_ERROR:
+ // count the error
+ m_errors++;
-//-------------------------------------------------
-// warning_output - warning message output
-// override
-//-------------------------------------------------
+ // output the source(driver) device 'tag'
+ build_output_prefix(output);
-void validity_checker::warning_output(const char *format, va_list argptr)
-{
- // count the error
- m_warnings++;
+ // generate the string
+ output.catvprintf(msg, args);
+ m_error_text.cat(output);
+ break;
+ case OSD_OUTPUT_CHANNEL_WARNING:
+ // count the error
+ m_warnings++;
- // output the source(driver) device 'tag'
- astring output;
- build_output_prefix(output);
+ // output the source(driver) device 'tag'
+ build_output_prefix(output);
- // generate the string and output to the original target
- output.catvprintf(format, argptr);
- m_warning_text.cat(output);
+ // generate the string and output to the original target
+ output.catvprintf(msg, args);
+ m_warning_text.cat(output);
+ break;
+ default:
+ chain_output(channel, msg, args);
+ break;
+ }
}
-
//-------------------------------------------------
// output_via_delegate - helper to output a
// message via a varargs string, so the argptr
// can be forwarded onto the given delegate
//-------------------------------------------------
-void validity_checker::output_via_delegate(output_delegate &delegate, const char *format, ...)
+void validity_checker::output_via_delegate(osd_output_channel channel, const char *format, ...)
{
va_list argptr;
// call through to the delegate with the proper parameters
va_start(argptr, format);
- delegate(format, argptr);
+ this->chain_output(channel, format, argptr);
va_end(argptr);
}
diff --git a/src/emu/validity.h b/src/emu/validity.h
index 1c1756f3c79..0dc58f6ff1d 100644
--- a/src/emu/validity.h
+++ b/src/emu/validity.h
@@ -26,7 +26,7 @@ class machine_config;
// core validity checker class
-class validity_checker
+class validity_checker : public osd_output
{
// internal map types
typedef tagmap_t<const game_driver *> game_driver_map;
@@ -52,6 +52,11 @@ public:
// generic registry of already-checked stuff
bool already_checked(const char *string) { return (m_already_checked.add(string, 1, false) == TMERR_DUPLICATE); }
+ // osd_output interface
+
+protected:
+ virtual void output_callback(osd_output_channel channel, const char *msg, va_list args);
+
private:
// internal helpers
const char *ioport_string_from_index(UINT32 index);
@@ -75,9 +80,7 @@ private:
// output helpers
void build_output_prefix(astring &string);
- void error_output(const char *format, va_list argptr);
- void warning_output(const char *format, va_list argptr);
- void output_via_delegate(output_delegate &delegate, const char *format, ...) ATTR_PRINTF(3,4);
+ void output_via_delegate(osd_output_channel channel, const char *format, ...) ATTR_PRINTF(3,4);
// internal driver list
driver_enumerator m_drivlist;
@@ -102,9 +105,6 @@ private:
int_map m_region_map;
tagmap_t<UINT8> m_already_checked;
- // callbacks
- output_delegate m_saved_error_output;
- output_delegate m_saved_warning_output;
};
#endif
diff --git a/src/osd/modules/lib/osdobj_common.c b/src/osd/modules/lib/osdobj_common.c
index df208356c52..222a7d0aca6 100644
--- a/src/osd/modules/lib/osdobj_common.c
+++ b/src/osd/modules/lib/osdobj_common.c
@@ -133,12 +133,24 @@ osd_options::osd_options()
//-------------------------------------------------
osd_common_t::osd_common_t(osd_options &options)
- : m_machine(NULL),
+ : osd_output(), m_machine(NULL),
m_options(options),
m_sound(NULL),
m_debugger(NULL)
+{
+ osd_output::push(this);
+}
+
+//-------------------------------------------------
+// osd_interface - destructor
+//-------------------------------------------------
+osd_common_t::~osd_common_t()
{
+ for(int i= 0; i < m_video_names.count(); ++i)
+ osd_free(const_cast<char*>(m_video_names[i]));
+ //m_video_options,reset();
+ osd_output::pop(this);
}
#define REGISTER_MODULE(_O, _X ) { extern const module_type _X; _O . register_module( _X ); }
@@ -228,18 +240,33 @@ void osd_common_t::update_option(const char * key, dynamic_array<const char *> &
m_options.set_description(key, core_strdup(current_value.cat(new_option_value).cstr()));
}
+
//-------------------------------------------------
-// osd_interface - destructor
+// output_callback - callback for osd_printf_...
//-------------------------------------------------
-
-osd_common_t::~osd_common_t()
+void osd_common_t::output_callback(osd_output_channel channel, const char *msg, va_list args)
{
- for(int i= 0; i < m_video_names.count(); ++i)
- osd_free(const_cast<char*>(m_video_names[i]));
- //m_video_options,reset();
+ switch (channel)
+ {
+ case OSD_OUTPUT_CHANNEL_ERROR:
+ case OSD_OUTPUT_CHANNEL_WARNING:
+ vfprintf(stderr, msg, args);
+ break;
+ case OSD_OUTPUT_CHANNEL_INFO:
+ case OSD_OUTPUT_CHANNEL_VERBOSE:
+ case OSD_OUTPUT_CHANNEL_LOG:
+ vfprintf(stdout, msg, args);
+ break;
+ case OSD_OUTPUT_CHANNEL_DEBUG:
+#ifdef MAME_DEBUG
+ vfprintf(stdout, msg, args);
+#endif
+ break;
+ default:
+ break;
+ }
}
-
//-------------------------------------------------
// init - initialize the OSD system.
//-------------------------------------------------
diff --git a/src/osd/modules/lib/osdobj_common.h b/src/osd/modules/lib/osdobj_common.h
index 36952dc1731..3b7ce43114c 100644
--- a/src/osd/modules/lib/osdobj_common.h
+++ b/src/osd/modules/lib/osdobj_common.h
@@ -140,7 +140,7 @@ private:
// ======================> osd_interface
// description of the currently-running machine
-class osd_common_t : public osd_interface
+class osd_common_t : public osd_interface, osd_output
{
public:
// construction/destruction
@@ -211,6 +211,9 @@ public:
osd_options &options() { return m_options; }
+ // osd_output interface ...
+ virtual void output_callback(osd_output_channel channel, const char *msg, va_list args);
+
protected:
virtual bool input_init();
virtual void input_pause();
diff --git a/src/osd/osdcore.c b/src/osd/osdcore.c
index fff285c02da..ddba6866b22 100644
--- a/src/osd/osdcore.c
+++ b/src/osd/osdcore.c
@@ -3,70 +3,49 @@
bool g_print_verbose = false;
+static const int MAXSTACK = 10;
+static osd_output *m_stack[MAXSTACK];
+static int m_ptr = -1;
/*-------------------------------------------------
- osd_file_output_callback - default callback
- for file output
+ osd_output
-------------------------------------------------*/
-void osd_file_output_callback(FILE *param, const char *format, va_list argptr)
+void osd_output::push(osd_output *delegate)
{
- vfprintf(param, format, argptr);
+ assert(m_ptr < MAXSTACK);
+ delegate->m_chain = (m_ptr >= 0 ? m_stack[m_ptr] : NULL);
+ m_ptr++;
+ m_stack[m_ptr] = delegate;
+ //printf("push m_ptr == %d\n", m_ptr);
}
-
-/*-------------------------------------------------
- osd_null_output_callback - default callback
- for no output
--------------------------------------------------*/
-
-void osd_null_output_callback(FILE *param, const char *format, va_list argptr)
+void osd_output::pop(osd_output *delegate)
{
+ int f = -1;
+ for (int i=0; i<=m_ptr; i++)
+ if (m_stack[i] == delegate)
+ {
+ f = i;
+ break;
+ }
+ if (f >= 0)
+ {
+ if (f < m_ptr)
+ m_stack[f+1]->m_chain = m_stack[f]->m_chain;
+ m_ptr--;
+ for (int i = f; i <= m_ptr; i++)
+ m_stack[i] = m_stack[i+1];
+ }
+ //printf("pop m_ptr == %d\n", m_ptr);
}
-
-/* output channels */
-static output_delegate output_cb[OSD_OUTPUT_CHANNEL_COUNT] =
-{
- output_delegate(FUNC(osd_file_output_callback), stderr), // OSD_OUTPUT_CHANNEL_ERROR
- output_delegate(FUNC(osd_file_output_callback), stderr), // OSD_OUTPUT_CHANNEL_WARNING
- output_delegate(FUNC(osd_file_output_callback), stdout), // OSD_OUTPUT_CHANNEL_INFO
-#ifdef MAME_DEBUG
- output_delegate(FUNC(osd_file_output_callback), stdout), // OSD_OUTPUT_CHANNEL_DEBUG
-#else
- output_delegate(FUNC(osd_null_output_callback), stdout), // OSD_OUTPUT_CHANNEL_DEBUG
-#endif
- output_delegate(FUNC(osd_file_output_callback), stdout), // OSD_OUTPUT_CHANNEL_VERBOSE
- output_delegate(FUNC(osd_file_output_callback), stdout) // OSD_OUTPUT_CHANNEL_LOG
-};
-
-
/***************************************************************************
OUTPUT MANAGEMENT
***************************************************************************/
/*-------------------------------------------------
- osd_set_output_channel - configure an output
- channel
--------------------------------------------------*/
-
-output_delegate osd_set_output_channel(output_channel channel, output_delegate callback)
-{
- if (!(channel < OSD_OUTPUT_CHANNEL_COUNT) || callback.isnull())
- {
- throw std::exception();
- }
-
- /* return the originals if requested */
- output_delegate prevcb = output_cb[channel];
-
- /* set the new ones */
- output_cb[channel] = callback;
- return prevcb;
-}
-
-/*-------------------------------------------------
osd_printf_error - output an error to the
appropriate callback
-------------------------------------------------*/
@@ -77,7 +56,7 @@ void CLIB_DECL osd_printf_error(const char *format, ...)
/* do the output */
va_start(argptr, format);
- output_cb[OSD_OUTPUT_CHANNEL_ERROR](format, argptr);
+ if (m_ptr >= 0) m_stack[m_ptr]->output_callback(OSD_OUTPUT_CHANNEL_ERROR, format, argptr);
va_end(argptr);
}
@@ -93,7 +72,7 @@ void CLIB_DECL osd_printf_warning(const char *format, ...)
/* do the output */
va_start(argptr, format);
- output_cb[OSD_OUTPUT_CHANNEL_WARNING](format, argptr);
+ if (m_ptr >= 0) m_stack[m_ptr]->output_callback(OSD_OUTPUT_CHANNEL_WARNING, format, argptr);
va_end(argptr);
}
@@ -109,7 +88,7 @@ void CLIB_DECL osd_printf_info(const char *format, ...)
/* do the output */
va_start(argptr, format);
- output_cb[OSD_OUTPUT_CHANNEL_INFO](format, argptr);
+ if (m_ptr >= 0) m_stack[m_ptr]->output_callback(OSD_OUTPUT_CHANNEL_INFO, format, argptr);
va_end(argptr);
}
@@ -129,7 +108,7 @@ void CLIB_DECL osd_printf_verbose(const char *format, ...)
/* do the output */
va_start(argptr, format);
- output_cb[OSD_OUTPUT_CHANNEL_VERBOSE](format, argptr);
+ if (m_ptr >= 0) m_stack[m_ptr]->output_callback(OSD_OUTPUT_CHANNEL_VERBOSE, format, argptr);
va_end(argptr);
}
@@ -145,7 +124,7 @@ void CLIB_DECL osd_printf_debug(const char *format, ...)
/* do the output */
va_start(argptr, format);
- output_cb[OSD_OUTPUT_CHANNEL_DEBUG](format, argptr);
+ if (m_ptr >= 0) m_stack[m_ptr]->output_callback(OSD_OUTPUT_CHANNEL_DEBUG, format, argptr);
va_end(argptr);
}
diff --git a/src/osd/osdcore.h b/src/osd/osdcore.h
index 8659592fc5c..ceb0cb45dbc 100644
--- a/src/osd/osdcore.h
+++ b/src/osd/osdcore.h
@@ -20,7 +20,6 @@
#define __OSDCORE_H__
#include "osdcomm.h"
-#include "delegate.h"
#include <stdarg.h>
/***************************************************************************
@@ -926,7 +925,7 @@ const char *osd_get_volume_name(int idx);
/* ----- output management ----- */
// output channels
-enum output_channel
+enum osd_output_channel
{
OSD_OUTPUT_CHANNEL_ERROR,
OSD_OUTPUT_CHANNEL_WARNING,
@@ -937,11 +936,26 @@ enum output_channel
OSD_OUTPUT_CHANNEL_COUNT
};
-// output channel callback
-typedef delegate<void (const char *, va_list)> output_delegate;
-
-/* set the output handler for a channel, returns the current one */
-output_delegate osd_set_output_channel(output_channel channel, output_delegate callback);
+class osd_output
+{
+public:
+ osd_output() : m_chain(NULL) { }
+ virtual ~osd_output() { }
+
+ virtual void output_callback(osd_output_channel channel, const char *msg, va_list args) = 0;
+
+ static void push(osd_output *delegate);
+ static void pop(osd_output *delegate);
+protected:
+
+ void chain_output(osd_output_channel channel, const char *msg, va_list args)
+ {
+ if (m_chain != NULL)
+ m_chain->output_callback(channel, msg, args);
+ }
+private:
+ osd_output *m_chain;
+};
/* calls to be used by the code */
void CLIB_DECL osd_printf_error(const char *format, ...) ATTR_PRINTF(1,2);
diff --git a/src/osd/windows/winmain.c b/src/osd/windows/winmain.c
index ffda737bfbd..8a52feb921a 100644
--- a/src/osd/windows/winmain.c
+++ b/src/osd/windows/winmain.c
@@ -198,6 +198,31 @@ private:
FPTR * m_buffer_end;
};
+//============================================================
+// winui_output_error
+//============================================================
+
+class winui_output_error : public osd_output
+{
+public:
+ virtual void output_callback(osd_output_channel channel, const char *msg, va_list args)
+ {
+ if (channel == OSD_OUTPUT_CHANNEL_ERROR)
+ {
+ char buffer[1024];
+
+ // if we are in fullscreen mode, go to windowed mode
+ if ((video_config.windowed == 0) && (win_window_list != NULL))
+ winwindow_toggle_full_screen();
+
+ vsnprintf(buffer, ARRAY_LENGTH(buffer), msg, args);
+ win_message_box_utf8(win_window_list ? win_window_list->m_hwnd : NULL, buffer, emulator_info::get_appname(), MB_OK);
+ }
+ else
+ chain_output(channel, msg, args);
+ }
+};
+
@@ -237,7 +262,6 @@ static BOOL WINAPI control_handler(DWORD type);
static int is_double_click_start(int argc);
static DWORD WINAPI watchdog_thread_entry(LPVOID lpParameter);
static LONG WINAPI exception_filter(struct _EXCEPTION_POINTERS *info);
-static void winui_output_error(delegate_late_bind *__dummy, const char *format, va_list argptr);
@@ -391,24 +415,27 @@ int main(int argc, char *argv[])
extern void (*s_debugger_stack_crawler)();
s_debugger_stack_crawler = winmain_dump_stack;
- // if we're a GUI app, out errors to message boxes
- if (win_is_gui_application() || is_double_click_start(argc))
- {
- // if we are a GUI app, output errors to message boxes
- osd_set_output_channel(OSD_OUTPUT_CHANNEL_ERROR, output_delegate(FUNC(winui_output_error), (delegate_late_bind *)0));
-
- // make sure any console window that opened on our behalf is nuked
- FreeConsole();
- }
// parse config and cmdline options
DWORD result = 0;
{
windows_options options;
windows_osd_interface osd(options);
+ // if we're a GUI app, out errors to message boxes
+ // Initialize this after the osd interface so that we are first in the
+ // output order
+ winui_output_error winerror;
+ if (win_is_gui_application() || is_double_click_start(argc))
+ {
+ // if we are a GUI app, output errors to message boxes
+ osd_output::push(&winerror);
+ // make sure any console window that opened on our behalf is nuked
+ FreeConsole();
+ }
osd.register_options();
cli_frontend frontend(options, osd);
result = frontend.execute(argc, argv);
+ osd_output::pop(&winerror);
}
// free symbols
symbols = NULL;
@@ -464,22 +491,6 @@ static BOOL WINAPI control_handler(DWORD type)
}
-//============================================================
-// winui_output_error
-//============================================================
-
-static void winui_output_error(delegate_late_bind *param, const char *format, va_list argptr)
-{
- char buffer[1024];
-
- // if we are in fullscreen mode, go to windowed mode
- if ((video_config.windowed == 0) && (win_window_list != NULL))
- winwindow_toggle_full_screen();
-
- vsnprintf(buffer, ARRAY_LENGTH(buffer), format, argptr);
- win_message_box_utf8(win_window_list ? win_window_list->m_hwnd : NULL, buffer, emulator_info::get_appname(), MB_OK);
-}
-
//============================================================