diff options
author | Miodrag Milanovic <mmicko@gmail.com> | 2016-06-05 21:11:56 +0200 |
---|---|---|
committer | Miodrag Milanovic <mmicko@gmail.com> | 2016-06-05 21:11:56 +0200 |
commit | dba7c1ac9420110762b635cffe605190399251e5 (patch) | |
tree | 0e0598f22988eacd7daf15874972b1f53d5e8dcc /src/osd/modules/output | |
parent | eb2617f7ae2d4d052de0cdbb4c7dfff3d8dc2c96 (diff) |
Placed back old output system as module "-output windows" need more things cleaned (nw)
Diffstat (limited to 'src/osd/modules/output')
-rw-r--r-- | src/osd/modules/output/output_module.h | 7 | ||||
-rw-r--r-- | src/osd/modules/output/win32_output.cpp | 336 | ||||
-rw-r--r-- | src/osd/modules/output/win32_output.h | 86 |
3 files changed, 428 insertions, 1 deletions
diff --git a/src/osd/modules/output/output_module.h b/src/osd/modules/output/output_module.h index 81fcaae2cce..f3461d3e1f6 100644 --- a/src/osd/modules/output/output_module.h +++ b/src/osd/modules/output/output_module.h @@ -20,11 +20,16 @@ class output_module { public: - output_module() { } + output_module(): m_machine(nullptr) { } virtual ~output_module() { } virtual void notify(const char *outname, INT32 value) = 0; + + void set_machine(running_machine *machine) { m_machine = machine; }; + running_machine &machine() const { return *m_machine; } +private: + running_machine *m_machine; }; #endif /* OUTPUT_MODULE_H_ */ diff --git a/src/osd/modules/output/win32_output.cpp b/src/osd/modules/output/win32_output.cpp new file mode 100644 index 00000000000..419a1dc1692 --- /dev/null +++ b/src/osd/modules/output/win32_output.cpp @@ -0,0 +1,336 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +//============================================================ +// +// output.c - Win32 implementation of MAME output routines +// +//============================================================ + +#if defined(OSD_WINDOWS) + +// standard windows headers +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +// MAME headers +#include "emu.h" +#include "winmain.h" + +#include "winutil.h" +#include "win32_output.h" + + +//============================================================ +// CONSTANTS +//============================================================ + +// window styles +#define WINDOW_STYLE WS_OVERLAPPEDWINDOW +#define WINDOW_STYLE_EX 0 + + + +//============================================================ +// TYPEDEFS +//============================================================ + +struct registered_client +{ + registered_client * next; // next client in the list + LPARAM id; // client-specified ID + HWND hwnd; // client HWND + running_machine * machine; +}; + + +// message IDs +static UINT om_mame_start; +static UINT om_mame_stop; +static UINT om_mame_update_state; +static UINT om_mame_register_client; +static UINT om_mame_unregister_client; +static UINT om_mame_get_id_string; + + + +//============================================================ +// FUNCTION PROTOTYPES +//============================================================ + +static LRESULT CALLBACK output_window_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam); + +class output_win32 : public osd_module, public output_module +{ +public: + output_win32() + : osd_module(OSD_OUTPUT_PROVIDER, "windows"), output_module() + { + } + virtual ~output_win32() { } + + virtual int init(const osd_options &options) override; + virtual void exit() override; + + // output_module + + virtual void notify(const char *outname, INT32 value) override; + + int create_window_class(void); + LRESULT register_client(HWND hwnd, LPARAM id); + LRESULT unregister_client(HWND hwnd, LPARAM id); + LRESULT send_id_string(HWND hwnd, LPARAM id); + +private: + // our HWND + HWND m_output_hwnd; + + // client list + registered_client * m_clientlist; + +}; + + +//============================================================ +// output_init +//============================================================ + +int output_win32::init(const osd_options &options) +{ + int result; + + // reset globals + m_clientlist = nullptr; + + // create our window class + result = create_window_class(); + assert(result == 0); + (void)result; // to silence gcc 4.6 + + // create a window + m_output_hwnd = CreateWindowEx( + WINDOW_STYLE_EX, + OUTPUT_WINDOW_CLASS, + OUTPUT_WINDOW_NAME, + WINDOW_STYLE, + 0, 0, + 1, 1, + nullptr, + nullptr, + GetModuleHandleUni(), + nullptr); + assert(m_output_hwnd != nullptr); + + // set a pointer to the running machine + SetWindowLongPtr(m_output_hwnd, GWLP_USERDATA, (LONG_PTR)this); + + // allocate message ids + om_mame_start = RegisterWindowMessage(OM_MAME_START); + assert(om_mame_start != 0); + om_mame_stop = RegisterWindowMessage(OM_MAME_STOP); + assert(om_mame_stop != 0); + om_mame_update_state = RegisterWindowMessage(OM_MAME_UPDATE_STATE); + assert(om_mame_update_state != 0); + + om_mame_register_client = RegisterWindowMessage(OM_MAME_REGISTER_CLIENT); + assert(om_mame_register_client != 0); + om_mame_unregister_client = RegisterWindowMessage(OM_MAME_UNREGISTER_CLIENT); + assert(om_mame_unregister_client != 0); + om_mame_get_id_string = RegisterWindowMessage(OM_MAME_GET_ID_STRING); + assert(om_mame_get_id_string != 0); + + // broadcast a startup message + PostMessage(HWND_BROADCAST, om_mame_start, (WPARAM)m_output_hwnd, 0); + + return 0; +} + + +//============================================================ +// output_exit +//============================================================ + +void output_win32::exit() +{ + // free all the clients + while (m_clientlist != nullptr) + { + registered_client *temp = m_clientlist; + m_clientlist = temp->next; + global_free(temp); + } + + // broadcast a shutdown message + PostMessage(HWND_BROADCAST, om_mame_stop, (WPARAM)m_output_hwnd, 0); +} + + +//============================================================ +// create_window_class +//============================================================ + +int output_win32::create_window_class(void) +{ + static UINT8 classes_created = FALSE; + + /* only do this once */ + if (!classes_created) + { + WNDCLASS wc = { 0 }; + + // initialize the description of the window class + wc.lpszClassName = OUTPUT_WINDOW_CLASS; + wc.hInstance = GetModuleHandleUni(); + wc.lpfnWndProc = output_window_proc; + + UnregisterClass(wc.lpszClassName, wc.hInstance); + + // register the class; fail if we can't + if (!RegisterClass(&wc)) + return 1; + classes_created = TRUE; + } + + return 0; +} + + +//============================================================ +// output_window_proc +//============================================================ + +static LRESULT CALLBACK output_window_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam) +{ + LONG_PTR ptr = GetWindowLongPtr(wnd, GWLP_USERDATA); + output_win32 &output = *(output_win32 *)ptr; + + // register a new client + if (message == om_mame_register_client) + return output.register_client((HWND)wparam, lparam); + + // unregister a client + else if (message == om_mame_unregister_client) + return output.unregister_client((HWND)wparam, lparam); + + // get a string for an ID + else if (message == om_mame_get_id_string) + return output.send_id_string((HWND)wparam, lparam); + + else + return DefWindowProc(wnd, message, wparam, lparam); +} + + +//============================================================ +// register_client +//============================================================ + +LRESULT output_win32::register_client(HWND hwnd, LPARAM id) +{ + registered_client **client; + + // find the end of the list; if we find ourself already registered, + // return 1 + for (client = &m_clientlist; *client != nullptr; client = &(*client)->next) + if ((*client)->id == id) + { + (*client)->hwnd = hwnd; + machine().output().notify_all(this); + return 1; + } + + // add us to the end + *client = global_alloc(registered_client); + (*client)->next = nullptr; + (*client)->id = id; + (*client)->hwnd = hwnd; + (*client)->machine = &machine(); + + // request a notification for all outputs + machine().output().notify_all(this); + return 0; +} + + +//============================================================ +// unregister_client +//============================================================ + +LRESULT output_win32::unregister_client(HWND hwnd, LPARAM id) +{ + registered_client **client; + int found = FALSE; + + // find any matching IDs in the list and remove them + for (client = &m_clientlist; *client != nullptr; client = &(*client)->next) + if ((*client)->id == id) + { + registered_client *temp = *client; + *client = (*client)->next; + global_free(temp); + found = TRUE; + break; + } + + // return an error if not found + return found ? 0 : 1; +} + + +//============================================================ +// send_id_string +//============================================================ + +LRESULT output_win32::send_id_string(HWND hwnd, LPARAM id) +{ + COPYDATASTRUCT copydata; + const char *name; + int datalen; + + // id 0 is the name of the game + if (id == 0) + name = machine().system().name; + else + name = machine().output().id_to_name(id); + + // a NULL name is an empty string + if (name == nullptr) + name = ""; + + // allocate memory for the message + datalen = sizeof(copydata_id_string) + strlen(name) + 1; + dynamic_buffer buffer(datalen); + copydata_id_string *temp = (copydata_id_string *)&buffer[0]; + temp->id = id; + strcpy(temp->string, name); + + // reply by using SendMessage with WM_COPYDATA + copydata.dwData = COPYDATA_MESSAGE_ID_STRING; + copydata.cbData = datalen; + copydata.lpData = temp; + SendMessage(hwnd, WM_COPYDATA, (WPARAM)m_output_hwnd, (LPARAM)©data); + + return 0; +} + + +//============================================================ +// notifier_callback +//============================================================ + +void output_win32::notify(const char *outname, INT32 value) +{ + registered_client *client; + // loop over clients and notify them + for (client = m_clientlist; client != nullptr; client = client->next) + { + PostMessage(client->hwnd, om_mame_update_state, client->machine->output().name_to_id(outname), value); + } +} + + + +#else +MODULE_NOT_SUPPORTED(output_win32, OSD_OUTPUT_PROVIDER, "windows") +#endif + +MODULE_DEFINITION(OUTPUT_WIN32, output_win32) diff --git a/src/osd/modules/output/win32_output.h b/src/osd/modules/output/win32_output.h new file mode 100644 index 00000000000..9d71332b44b --- /dev/null +++ b/src/osd/modules/output/win32_output.h @@ -0,0 +1,86 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +//============================================================ +// +// output.h - Win32 implementation of MAME output routines +// +//============================================================ + +#ifndef __WINDOWS_OUTPUT_H__ +#define __WINDOWS_OUTPUT_H__ + + +//============================================================ +// CONSTANTS +//============================================================ + +// window parameters +#define OUTPUT_WINDOW_CLASS TEXT("MAMEOutput") +#define OUTPUT_WINDOW_NAME TEXT("MAMEOutput") + +// +// These messages are sent by MAME: +// + +// OM_MAME_START: broadcast when MAME initializes +// WPARAM = HWND of MAME's output window +// LPARAM = unused +#define OM_MAME_START TEXT("MAMEOutputStart") + +// OM_MAME_STOP: broadcast when MAME shuts down +// WPARAM = HWND of MAME's output window +// LPARAM = unused +#define OM_MAME_STOP TEXT("MAMEOutputStop") + +// OM_MAME_UPDATE_STATE: sent to registered clients when the state +// of an output changes +// WPARAM = ID of the output +// LPARAM = new value for the output +#define OM_MAME_UPDATE_STATE TEXT("MAMEOutputUpdateState") + + +// +// These messages are sent by external clients to MAME: +// + +// OM_MAME_REGISTER_CLIENT: sent to MAME to register a client +// WPARAM = HWND of client's listener window +// LPARAM = client-specified ID (must be unique) +#define OM_MAME_REGISTER_CLIENT TEXT("MAMEOutputRegister") + +// OM_MAME_UNREGISTER_CLIENT: sent to MAME to unregister a client +// WPARAM = HWND of client's listener window +// LPARAM = client-specified ID (must match registration) +#define OM_MAME_UNREGISTER_CLIENT TEXT("MAMEOutputUnregister") + +// OM_MAME_GET_ID_STRING: requests the string associated with a +// given ID. ID=0 is always the name of the game. Other IDs are +// only discoverable from a OM_MAME_UPDATE_STATE message. The +// result will be sent back as a WM_COPYDATA message with MAME's +// output window as the sender, dwData = the ID of the string, +// and lpData pointing to a NULL-terminated string. +// WPARAM = HWND of client's listener window +// LPARAM = ID you wish to know about +#define OM_MAME_GET_ID_STRING TEXT("MAMEOutputGetIDString") + + +// +// These constants are used to identify WM_COPYDATA messages +// coming from MAME: +// + +#define COPYDATA_MESSAGE_ID_STRING 1 + + + +//============================================================ +// TYPE DEFINITIONS +//============================================================ + +struct copydata_id_string +{ + UINT32 id; // ID that was requested + char string[1]; // string array containing the data +}; + +#endif /* __WINDOWS_OUTPUT_H__ */ |