From 198ada82ecf81d7d99a137881727370b69dc63bb Mon Sep 17 00:00:00 2001 From: libretroadmin Date: Wed, 15 Jun 2022 16:46:38 +0200 Subject: [PATCH] Get rid of profiler --- scripts/src/emu.lua | 2 - src/emu/device.cpp | 1 - src/emu/device.ipp | 4 - src/emu/diexec.cpp | 2 - src/emu/diexec.h | 1 - src/emu/drawgfxt.ipp | 26 - src/emu/emu.h | 1 - src/emu/input.cpp | 5 - src/emu/ioport.cpp | 44 - src/emu/machine.cpp | 8 - src/emu/machine.h | 4 - src/emu/profiler.cpp | 232 -- src/emu/profiler.h | 213 -- src/emu/recording.cpp | 3 - src/emu/schedule.cpp | 48 - src/emu/schedule.h | 4 - src/emu/screen.cpp | 51 - src/emu/sound.cpp | 192 +- src/emu/sound.h | 42 - src/emu/tilemap.cpp | 12 - src/emu/uiinput.cpp | 4 - src/emu/video.cpp | 22 - src/frontend/mame/luaengine.ipp | 2 - src/frontend/mame/ui/submenu.cpp | 4 - src/frontend/mame/ui/ui.cpp | 21 - src/frontend/mame/ui/ui.h | 1 - src/osd/mac/appdelegate.h | 15 - src/osd/mac/appdelegate.mm | 38 - src/osd/mac/macmain.cpp | 268 --- src/osd/mac/main.mm | 42 - src/osd/mac/mamefswindow.h | 15 - src/osd/mac/mamefswindow.mm | 41 - src/osd/mac/oglview.h | 19 - src/osd/mac/oglview.mm | 106 - src/osd/mac/osdmac.h | 87 - src/osd/mac/video.cpp | 307 --- src/osd/mac/window.cpp | 916 -------- src/osd/mac/window.h | 114 - src/osd/mac/windowcontroller.h | 16 - src/osd/mac/windowcontroller.mm | 137 -- .../modules/diagnostics/diagnostics_module.h | 9 - .../modules/diagnostics/diagnostics_win32.cpp | 1100 ---------- src/osd/modules/diagnostics/none.cpp | 12 - src/osd/windows/ledutil.cpp | 708 ------ src/osd/windows/video.cpp | 284 --- src/osd/windows/video.h | 29 - src/osd/windows/window.cpp | 1894 ----------------- src/osd/windows/window.h | 184 -- src/osd/windows/winmain.cpp | 566 ----- src/osd/windows/winmain.h | 332 --- src/osd/windows/winmenu.cpp | 33 - 51 files changed, 3 insertions(+), 8218 deletions(-) delete mode 100644 src/emu/profiler.cpp delete mode 100644 src/emu/profiler.h delete mode 100644 src/osd/mac/appdelegate.h delete mode 100644 src/osd/mac/appdelegate.mm delete mode 100644 src/osd/mac/macmain.cpp delete mode 100644 src/osd/mac/main.mm delete mode 100644 src/osd/mac/mamefswindow.h delete mode 100644 src/osd/mac/mamefswindow.mm delete mode 100644 src/osd/mac/oglview.h delete mode 100644 src/osd/mac/oglview.mm delete mode 100644 src/osd/mac/osdmac.h delete mode 100644 src/osd/mac/video.cpp delete mode 100644 src/osd/mac/window.cpp delete mode 100644 src/osd/mac/window.h delete mode 100644 src/osd/mac/windowcontroller.h delete mode 100644 src/osd/mac/windowcontroller.mm delete mode 100644 src/osd/modules/diagnostics/diagnostics_win32.cpp delete mode 100644 src/osd/windows/ledutil.cpp delete mode 100644 src/osd/windows/video.cpp delete mode 100644 src/osd/windows/video.h delete mode 100644 src/osd/windows/window.cpp delete mode 100644 src/osd/windows/window.h delete mode 100644 src/osd/windows/winmain.cpp delete mode 100644 src/osd/windows/winmain.h delete mode 100644 src/osd/windows/winmenu.cpp diff --git a/scripts/src/emu.lua b/scripts/src/emu.lua index cea49b2f..e70fe411 100644 --- a/scripts/src/emu.lua +++ b/scripts/src/emu.lua @@ -174,8 +174,6 @@ files { MAME_DIR .. "src/emu/network.h", MAME_DIR .. "src/emu/parameters.cpp", MAME_DIR .. "src/emu/parameters.h", - MAME_DIR .. "src/emu/profiler.cpp", - MAME_DIR .. "src/emu/profiler.h", MAME_DIR .. "src/emu/output.cpp", MAME_DIR .. "src/emu/output.h", MAME_DIR .. "src/emu/recording.cpp", diff --git a/src/emu/device.cpp b/src/emu/device.cpp index c9097a59..690f0c89 100644 --- a/src/emu/device.cpp +++ b/src/emu/device.cpp @@ -589,7 +589,6 @@ void device_t::start() device_sound_interface *sound; if (state_registrations == 0 && (interface(exec) || interface(sound)) && type() != SPEAKER) { - logerror("Device did not register any state to save!\n"); if ((machine().system().flags & MACHINE_SUPPORTS_SAVE) != 0) fatalerror("Device '%s' did not register any state to save!\n", tag()); } diff --git a/src/emu/device.ipp b/src/emu/device.ipp index 820f8109..f41fb3a0 100644 --- a/src/emu/device.ipp +++ b/src/emu/device.ipp @@ -88,8 +88,6 @@ inline void device_t::logerror(Format &&fmt, Params &&... args) const { if (m_machine != nullptr && m_machine->allow_logging()) { - g_profiler.start(PROFILER_LOGERROR); - // dump to the buffer m_string_buffer.clear(); m_string_buffer.seekp(0); @@ -98,8 +96,6 @@ inline void device_t::logerror(Format &&fmt, Params &&... args) const m_string_buffer.put('\0'); m_machine->strlog(&m_string_buffer.vec()[0]); - - g_profiler.stop(); } } diff --git a/src/emu/diexec.cpp b/src/emu/diexec.cpp index 2e0e5acc..70247042 100644 --- a/src/emu/diexec.cpp +++ b/src/emu/diexec.cpp @@ -40,7 +40,6 @@ device_execute_interface::device_execute_interface(const machine_config &mconfig , m_nextexec(nullptr) , m_driver_irq(device) , m_timedint_timer(nullptr) - , m_profiler(PROFILER_IDLE) , m_icountptr(nullptr) , m_cycles_running(0) , m_cycles_stolen(0) @@ -359,7 +358,6 @@ void device_execute_interface::interface_pre_start() // fill in the initial states int const index = device_enumerator(device().machine().root_device()).indexof(*this); m_suspend = SUSPEND_REASON_RESET; - m_profiler = profile_type(index + PROFILER_DEVICE_FIRST); m_inttrigger = index + TRIGGER_INT; // allocate timers if we need them diff --git a/src/emu/diexec.h b/src/emu/diexec.h index 065248a9..82858342 100644 --- a/src/emu/diexec.h +++ b/src/emu/diexec.h @@ -303,7 +303,6 @@ private: emu_timer * m_timedint_timer; // reference to this device's periodic interrupt timer // cycle counting and executing - profile_type m_profiler; // profiler tag int * m_icountptr; // pointer to the icount int m_cycles_running; // number of cycles we are executing int m_cycles_stolen; // number of cycles we artificially stole diff --git a/src/emu/drawgfxt.ipp b/src/emu/drawgfxt.ipp index 4d756497..7130ca3d 100644 --- a/src/emu/drawgfxt.ipp +++ b/src/emu/drawgfxt.ipp @@ -421,7 +421,6 @@ while (0) template inline void gfx_element::drawgfx_core(BitmapType &dest, const rectangle &cliprect, u32 code, int flipx, int flipy, s32 destx, s32 desty, FunctionClass pixel_op) { - g_profiler.start(PROFILER_DRAWGFX); do { assert(dest.valid()); assert(dest.cliprect().contains(cliprect)); @@ -551,14 +550,12 @@ inline void gfx_element::drawgfx_core(BitmapType &dest, const rectangle &cliprec } } } while (0); - g_profiler.stop(); } template inline void gfx_element::drawgfx_core(BitmapType &dest, const rectangle &cliprect, u32 code, int flipx, int flipy, s32 destx, s32 desty, PriorityType &priority, FunctionClass pixel_op) { - g_profiler.start(PROFILER_DRAWGFX); do { assert(dest.valid()); assert(priority.valid()); @@ -695,7 +692,6 @@ inline void gfx_element::drawgfx_core(BitmapType &dest, const rectangle &cliprec } } } while (0); - g_profiler.stop(); } @@ -724,7 +720,6 @@ inline void gfx_element::drawgfx_core(BitmapType &dest, const rectangle &cliprec template inline void gfx_element::drawgfxzoom_core(BitmapType &dest, const rectangle &cliprect, u32 code, int flipx, int flipy, s32 destx, s32 desty, u32 scalex, u32 scaley, FunctionClass pixel_op) { - g_profiler.start(PROFILER_DRAWGFX); do { assert(dest.valid()); assert(dest.cliprect().contains(cliprect)); @@ -830,14 +825,12 @@ inline void gfx_element::drawgfxzoom_core(BitmapType &dest, const rectangle &cli } } } while (0); - g_profiler.stop(); } template inline void gfx_element::drawgfxzoom_core(BitmapType &dest, const rectangle &cliprect, u32 code, int flipx, int flipy, s32 destx, s32 desty, u32 scalex, u32 scaley, PriorityType &priority, FunctionClass pixel_op) { - g_profiler.start(PROFILER_DRAWGFX); do { assert(dest.valid()); assert(priority.valid()); @@ -877,10 +870,7 @@ inline void gfx_element::drawgfxzoom_core(BitmapType &dest, const rectangle &cli // compute final pixel in Y and exit if we are entirely clipped s32 destendy = desty + dstheight - 1; if (desty > cliprect.bottom() || destendy < cliprect.top()) - { - g_profiler.stop(); return; - } // apply top clip s32 srcy = 0; @@ -950,7 +940,6 @@ inline void gfx_element::drawgfxzoom_core(BitmapType &dest, const rectangle &cli } } } while (0); - g_profiler.stop(); } @@ -975,7 +964,6 @@ inline void gfx_element::drawgfxzoom_core(BitmapType &dest, const rectangle &cli template inline void copybitmap_core(BitmapType &dest, const BitmapType &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, FunctionClass pixel_op) { - g_profiler.start(PROFILER_COPYBITMAP); do { assert(dest.valid()); assert(src.valid()); @@ -1108,14 +1096,12 @@ inline void copybitmap_core(BitmapType &dest, const BitmapType &src, int flipx, } } } while (0); - g_profiler.stop(); } template inline void copybitmap_core(BitmapType &dest, const BitmapType &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, PriorityType &priority, FunctionClass pixel_op) { - g_profiler.start(PROFILER_COPYBITMAP); do { assert(dest.valid()); assert(src.valid()); @@ -1255,7 +1241,6 @@ inline void copybitmap_core(BitmapType &dest, const BitmapType &src, int flipx, } } } while (0); - g_profiler.stop(); } @@ -1283,8 +1268,6 @@ inline void copybitmap_core(BitmapType &dest, const BitmapType &src, int flipx, template inline void copyrozbitmap_core(BitmapType &dest, const rectangle &cliprect, const BitmapType &src, s32 startx, s32 starty, s32 incxx, s32 incxy, s32 incyx, s32 incyy, bool wraparound, FunctionClass pixel_op) { - g_profiler.start(PROFILER_COPYBITMAP); - assert(dest.valid()); assert(dest.valid()); assert(dest.cliprect().contains(cliprect)); @@ -1293,10 +1276,7 @@ inline void copyrozbitmap_core(BitmapType &dest, const rectangle &cliprect, cons // ignore empty/invalid cliprects if (cliprect.empty()) - { - g_profiler.stop(); return; - } // compute fixed-point 16.16 size of the source bitmap u32 srcfixwidth = src.width() << 16; @@ -1537,14 +1517,12 @@ inline void copyrozbitmap_core(BitmapType &dest, const rectangle &cliprect, cons } } } - g_profiler.stop(); } template inline void copyrozbitmap_core(BitmapType &dest, const rectangle &cliprect, const BitmapType &src, s32 startx, s32 starty, s32 incxx, s32 incxy, s32 incyx, s32 incyy, bool wraparound, PriorityType &priority, FunctionClass pixel_op) { - g_profiler.start(PROFILER_COPYBITMAP); assert(dest.valid()); assert(dest.valid()); @@ -1555,10 +1533,7 @@ inline void copyrozbitmap_core(BitmapType &dest, const rectangle &cliprect, cons // ignore empty/invalid cliprects if (cliprect.empty()) - { - g_profiler.stop(); return; - } // compute fixed-point 16.16 size of the source bitmap u32 srcfixwidth = src.width() << 16; @@ -1811,7 +1786,6 @@ inline void copyrozbitmap_core(BitmapType &dest, const rectangle &cliprect, cons } } } - g_profiler.stop(); } diff --git a/src/emu/emu.h b/src/emu/emu.h index d648ee93..333e77e6 100644 --- a/src/emu/emu.h +++ b/src/emu/emu.h @@ -32,7 +32,6 @@ #include "eminline.h" #include "xtal.h" #include "attotime.h" -#include "profiler.h" // http interface helpers #include "http.h" diff --git a/src/emu/input.cpp b/src/emu/input.cpp index 5c49d1c2..377eea8f 100644 --- a/src/emu/input.cpp +++ b/src/emu/input.cpp @@ -595,7 +595,6 @@ input_manager::~input_manager() s32 input_manager::code_value(input_code code) { - g_profiler.start(PROFILER_INPUT); s32 result = 0; // dummy loop to allow clean early exits @@ -654,7 +653,6 @@ s32 input_manager::code_value(input_code code) } while (0); // stop the profiler before exiting - g_profiler.stop(); return result; } @@ -1305,7 +1303,6 @@ void input_manager::seq_from_tokens(input_seq &seq, std::string_view string) { if (code.device_class() < DEVICE_CLASS_FIRST_VALID) { - osd_printf_warning("Input: Dropping invalid input token %s\n", token); while (operators) { seq.backspace(); @@ -1379,8 +1376,6 @@ bool input_manager::map_device_to_controller(const devicemap_table &table) { // remap devindex input_devclass->remap_device_index(device->devindex(), devindex); - osd_printf_verbose("Input: Remapped %s #%d: %s (device id: %s)\n", input_devclass->name(), devindex, device->name(), device->id()); - break; } } diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp index a9b86776..0e305789 100644 --- a/src/emu/ioport.cpp +++ b/src/emu/ioport.cpp @@ -94,7 +94,6 @@ #include "emuopts.h" #include "config.h" #include "xmlfile.h" -#include "profiler.h" #include "ui/uimain.h" #include "inputdev.h" #include "natkeyboard.h" @@ -1747,8 +1746,6 @@ time_t ioport_manager::initialize() { std::string errors; m_portlist.append(device, errors); - if (!errors.empty()) - osd_printf_error("Input port errors:\n%s", errors); } // renumber player numbers for controller ports @@ -1861,7 +1858,6 @@ void ioport_manager::init_autoselect_devices(int type1, int type2, int type3, co } if (autoenable_class == nullptr) { - osd_printf_error("Invalid %s value %s; reverting to keyboard\n", option, stemp); autoenable_class = &machine().input().device_class(DEVICE_CLASS_KEYBOARD); } @@ -1873,7 +1869,6 @@ void ioport_manager::init_autoselect_devices(int type1, int type2, int type3, co // if this port type is in use, apply the autoselect criteria if ((type1 != 0 && field.type() == type1) || (type2 != 0 && field.type() == type2) || (type3 != 0 && field.type() == type3)) { - osd_printf_verbose("Input: Autoenabling %s due to presence of a %s\n", autoenable_class->name(), ananame); autoenable_class->enable(); break; } @@ -2067,8 +2062,6 @@ void ioport_manager::frame_update_callback() void ioport_manager::frame_update() { - g_profiler.start(PROFILER_INPUT); - // record/playback information about the current frame attotime curtime = machine().time(); playback_frame(curtime); @@ -2104,8 +2097,6 @@ void ioport_manager::frame_update() if (dynfield.field().type() != IPT_OUTPUT) dynfield.write(newvalue); } - - g_profiler.stop(); } @@ -2406,30 +2397,6 @@ bool ioport_manager::load_controller_config( field.m_flags &= ~ioport_field::FIELD_FLAG_TOGGLE; } } - else - { - // for analog fields - -#if 0 // changing this stuff causes issues because of the way it's tied up with the analog_field object - // get base attributes - field.live().analog->m_delta = field.m_delta = portnode.get_attribute_int("keydelta", field.delta()); - field.live().analog->m_centerdelta = field.m_centerdelta = portnode.get_attribute_int("centerdelta", field.centerdelta()); - field.live().analog->m_sensitivity = field.m_sensitivity = portnode.get_attribute_int("sensitivity", field.sensitivity()); - - // fetch yes/no for reverse setting - char const *const revstring = portnode.get_attribute_string("reverse", nullptr); - if (revstring && !strcmp(revstring, "yes")) - { - field.live().analog->m_reverse = true; - field.m_flags |= ioport_field::ANALOG_FLAG_REVERSE; - } - else if (revstring && !strcmp(revstring, "no")) - { - field.live().analog->m_reverse = false; - field.m_flags &= ~ioport_field::ANALOG_FLAG_REVERSE; - } -#endif - } // successfully applied return true; @@ -2813,16 +2780,10 @@ time_t ioport_manager::playback_init() fatalerror("Input file format version mismatch\n"); // output info to console - osd_printf_info("Input file: %s\n", filename); - osd_printf_info("INP version %u.%u\n", header.get_majversion(), header.get_minversion()); time_t basetime = header.get_basetime(); - osd_printf_info("Created %s\n", ctime(&basetime)); - osd_printf_info("Recorded using %s\n", header.get_appdesc()); // verify the header against the current game std::string const sysname = header.get_sysname(); - if (sysname != machine().system().name) - osd_printf_info("Input file is for machine '%s', not for current machine '%s'\n", sysname, machine().system().name); // enable compression m_playback_stream = util::zlib_read(m_playback_file, 16386); @@ -2850,15 +2811,10 @@ void ioport_manager::playback_end(const char *message) // display speed stats if (m_playback_accumulated_speed > 0) m_playback_accumulated_speed /= m_playback_accumulated_frames; - osd_printf_info("Total playback frames: %d\n", u32(m_playback_accumulated_frames)); - osd_printf_info("Average recorded speed: %d%%\n", u32((m_playback_accumulated_speed * 200 + 1) >> 21)); // close the program at the end of inp file playback if (machine().options().exit_after_playback()) - { - osd_printf_info("Exiting MAME now...\n"); machine().schedule_exit(); - } } } diff --git a/src/emu/machine.cpp b/src/emu/machine.cpp index 196fa080..26f99209 100644 --- a/src/emu/machine.cpp +++ b/src/emu/machine.cpp @@ -318,8 +318,6 @@ int running_machine::run(bool quiet) // run the CPUs until a reset or exit while ((!m_hard_reset_pending && !m_exit_pending) || m_saveload_schedule != saveload_schedule::NONE) { - g_profiler.start(PROFILER_EXTRA); - #if defined(__LIBRETRO__) //non-libco break out to LIBRETRO LOOP return 0; @@ -335,8 +333,6 @@ int running_machine::run(bool quiet) // handle save/load if (m_saveload_schedule != saveload_schedule::NONE) handle_saveload(); - - g_profiler.stop(); } m_manager.http()->clear(); @@ -1286,8 +1282,6 @@ void running_machine::emscripten_main_loop() { running_machine *machine = emscripten_running_machine; - g_profiler.start(PROFILER_EXTRA); - // execute CPUs if not paused if (!machine->m_paused) { @@ -1319,8 +1313,6 @@ void running_machine::emscripten_main_loop() { emscripten_cancel_main_loop(); } - - g_profiler.stop(); } void running_machine::emscripten_set_running_machine(running_machine *machine) diff --git a/src/emu/machine.h b/src/emu/machine.h index 633d6561..9cad16d6 100644 --- a/src/emu/machine.h +++ b/src/emu/machine.h @@ -404,8 +404,6 @@ inline void running_machine::logerror(Format &&fmt, Params &&... args) const // process only if there is a target if (allow_logging()) { - g_profiler.start(PROFILER_LOGERROR); - // dump to the buffer m_string_buffer.clear(); m_string_buffer.seekp(0); @@ -413,8 +411,6 @@ inline void running_machine::logerror(Format &&fmt, Params &&... args) const m_string_buffer.put('\0'); strlog(&m_string_buffer.vec()[0]); - - g_profiler.stop(); } } diff --git a/src/emu/profiler.cpp b/src/emu/profiler.cpp deleted file mode 100644 index 765373e3..00000000 --- a/src/emu/profiler.cpp +++ /dev/null @@ -1,232 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/*************************************************************************** - - profiler.cpp - - Functions to manage profiling of MAME execution. - -**************************************************************************** - - Profiling is scope-based. To start profiling, put a profiler_scope - object on the stack. To end profiling, just end the scope: - - { - profiler_scope scope(PROFILER_VIDEO); - - your_work_here(); - } - - the profiler handles a FILO list so calls may be nested. - -***************************************************************************/ - -#include "emu.h" -#include "profiler.h" - - - -//************************************************************************** -// TYPE DEFINITIONS -//************************************************************************** - -struct profile_string -{ - int type; - const char *string; -}; - - - -//************************************************************************** -// GLOBAL VARIABLES -//************************************************************************** - -profiler_state g_profiler; - - - -//************************************************************************** -// CONSTANTS -//************************************************************************** - -#define TEXT_UPDATE_TIME 0.5 - - - -//************************************************************************** -// DUMMY PROFILER STATE -//************************************************************************** - -//------------------------------------------------- -// dummy_profiler_state - constructor -//------------------------------------------------- - -dummy_profiler_state::dummy_profiler_state() -{ -} - - - -//************************************************************************** -// REAL PROFILER STATE -//************************************************************************** - -//------------------------------------------------- -// real_profiler_state - constructor -//------------------------------------------------- - -real_profiler_state::real_profiler_state() -{ - memset(m_filo, 0, sizeof(m_filo)); - memset(m_data, 0, sizeof(m_data)); - reset(false); -} - - - -//------------------------------------------------- -// reset - initializes state -//------------------------------------------------- - -void real_profiler_state::reset(bool enabled) -{ - m_text_time = attotime::never; - - if (enabled) - { - // we're enabled now - m_filoptr = m_filo; - - // set up dummy entry - m_filoptr->start = 0; - m_filoptr->type = PROFILER_TOTAL; - } - else - { - // magic value to indicate disabled - m_filoptr = nullptr; - } -} - - - -//------------------------------------------------- -// text - return the current text in an std::string -//------------------------------------------------- - -const char *real_profiler_state::text(running_machine &machine) -{ - start(PROFILER_PROFILER); - - // get the current time - attotime current_time = machine.scheduler().time(); - - // we only want to update the text periodically - if ((m_text_time == attotime::never) || ((current_time - m_text_time).as_double() >= TEXT_UPDATE_TIME)) - { - update_text(machine); - m_text_time = current_time; - } - - stop(); - return m_text.c_str(); -} - - - -//------------------------------------------------- -// update_text - update the current std::string -//------------------------------------------------- - -void real_profiler_state::update_text(running_machine &machine) -{ - static const profile_string names[] = - { - { PROFILER_DRC_COMPILE, "DRC Compilation" }, - { PROFILER_MEM_REMAP, "Memory Remapping" }, - { PROFILER_MEMREAD, "Memory Read" }, - { PROFILER_MEMWRITE, "Memory Write" }, - { PROFILER_VIDEO, "Video Update" }, - { PROFILER_DRAWGFX, "drawgfx" }, - { PROFILER_COPYBITMAP, "copybitmap" }, - { PROFILER_TILEMAP_DRAW, "Tilemap Draw" }, - { PROFILER_TILEMAP_DRAW_ROZ, "Tilemap ROZ Draw" }, - { PROFILER_TILEMAP_UPDATE, "Tilemap Update" }, - { PROFILER_BLIT, "OSD Blitting" }, - { PROFILER_SOUND, "Sound Generation" }, - { PROFILER_TIMER_CALLBACK, "Timer Callbacks" }, - { PROFILER_INPUT, "Input Processing" }, - { PROFILER_MOVIE_REC, "Movie Recording" }, - { PROFILER_LOGERROR, "Error Logging" }, - { PROFILER_LUA, "LUA" }, - { PROFILER_EXTRA, "Unaccounted/Overhead" }, - { PROFILER_USER1, "User 1" }, - { PROFILER_USER2, "User 2" }, - { PROFILER_USER3, "User 3" }, - { PROFILER_USER4, "User 4" }, - { PROFILER_USER5, "User 5" }, - { PROFILER_USER6, "User 6" }, - { PROFILER_USER7, "User 7" }, - { PROFILER_USER8, "User 8" }, - { PROFILER_PROFILER, "Profiler" }, - { PROFILER_IDLE, "Idle" } - }; - - // compute the total time for all bits, not including profiler or idle - u64 computed = 0; - profile_type curtype; - for (curtype = PROFILER_DEVICE_FIRST; curtype < PROFILER_PROFILER; ++curtype) - computed += m_data[curtype]; - - // save that result in normalize, and continue adding the rest - u64 normalize = computed; - for ( ; curtype < PROFILER_TOTAL; ++curtype) - computed += m_data[curtype]; - - // this becomes the total; if we end up with 0 for anything, we were just started, so return empty - u64 total = computed; - if (total == 0 || normalize == 0) - { - m_text.clear(); - return; - } - - // loop over all types and generate the string - device_enumerator iter(machine.root_device()); - std::ostringstream stream; - for (curtype = PROFILER_DEVICE_FIRST; curtype < PROFILER_TOTAL; ++curtype) - { - // determine the accumulated time for this type - computed = m_data[curtype]; - - // if we have non-zero data and we're ready to display, do it - if (computed != 0) - { - // start with the un-normalized percentage - util::stream_format(stream, "%02d%% ", (int)((computed * 100 + total / 2) / total)); - - // followed by the normalized percentage for everything but profiler and idle - if (curtype < PROFILER_PROFILER) - util::stream_format(stream, "%02d%% ", (int)((computed * 100 + normalize / 2) / normalize)); - - // and then the text - if (curtype >= PROFILER_DEVICE_FIRST && curtype <= PROFILER_DEVICE_MAX) - util::stream_format(stream, "'%s'", iter.byindex(curtype - PROFILER_DEVICE_FIRST)->tag()); - else - for (auto & name : names) - if (name.type == curtype) - { - stream << name.string; - break; - } - - // followed by a carriage return - stream << '\n'; - } - } - - // reset data set to 0 - memset(m_data, 0, sizeof(m_data)); - m_text = stream.str(); -} diff --git a/src/emu/profiler.h b/src/emu/profiler.h deleted file mode 100644 index 8341e075..00000000 --- a/src/emu/profiler.h +++ /dev/null @@ -1,213 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/*************************************************************************** - - profiler.h - - Functions to manage profiling of MAME execution. - -**************************************************************************** - - Profiling is scope-based. To start profiling, put a profiler_scope - object on the stack. To end profiling, just end the scope: - - { - profiler_scope scope(PROFILER_VIDEO); - - your_work_here(); - } - - the profiler handles a FILO list so calls may be nested. - -***************************************************************************/ - -#ifndef MAME_EMU_PROFILER_H -#define MAME_EMU_PROFILER_H - -#pragma once - - -//************************************************************************** -// CONSTANTS -//************************************************************************** - -enum profile_type -{ - PROFILER_DEVICE_FIRST = 0, - PROFILER_DEVICE_MAX = PROFILER_DEVICE_FIRST + 256, - PROFILER_DRC_COMPILE, - PROFILER_MEM_REMAP, - PROFILER_MEMREAD, - PROFILER_MEMWRITE, - PROFILER_VIDEO, - PROFILER_DRAWGFX, - PROFILER_COPYBITMAP, - PROFILER_TILEMAP_DRAW, - PROFILER_TILEMAP_DRAW_ROZ, - PROFILER_TILEMAP_UPDATE, - PROFILER_BLIT, - PROFILER_SOUND, - PROFILER_TIMER_CALLBACK, - PROFILER_INPUT, // input.cpp and inptport.cpp - PROFILER_MOVIE_REC, // movie recording - PROFILER_LOGERROR, // logerror - PROFILER_LUA, // LUA - PROFILER_EXTRA, // everything else - - // the USER types are available to driver writers to profile - // custom sections of the code - PROFILER_USER1, - PROFILER_USER2, - PROFILER_USER3, - PROFILER_USER4, - PROFILER_USER5, - PROFILER_USER6, - PROFILER_USER7, - PROFILER_USER8, - - PROFILER_PROFILER, - PROFILER_IDLE, - PROFILER_TOTAL -}; -DECLARE_ENUM_INCDEC_OPERATORS(profile_type) - - - -//************************************************************************** -// TYPE DEFINITIONS -//************************************************************************** - - -// ======================> real_profiler_state - -class real_profiler_state -{ -public: - // construction/destruction - real_profiler_state(); - - // getters - bool enabled() const - { - return m_filoptr != nullptr; - } - const char *text(running_machine &machine); - - // enable/disable - void enable(bool state = true) - { - if (state != enabled()) - { - reset(state); - } - } - - // start/stop - void start(profile_type type) { if (enabled()) real_start(type); } - void stop() { if (enabled()) real_stop(); } - -private: - void reset(bool enabled); - void update_text(running_machine &machine); - - //------------------------------------------------- - // real_start - mark the beginning of a - // profiler entry - //------------------------------------------------- - ATTR_FORCE_INLINE void real_start(profile_type type) - { - // fail if we overflow - if (m_filoptr >= &m_filo[std::size(m_filo) - 1]) - throw emu_fatalerror("Profiler FILO overflow (type = %d)\n", type); - - // get current tick count - osd_ticks_t curticks = get_profile_ticks(); - - // update previous entry - m_data[m_filoptr->type] += curticks - m_filoptr->start; - - // move to next entry - m_filoptr++; - - // fill in this entry - m_filoptr->type = type; - m_filoptr->start = curticks; - } - - //------------------------------------------------- - // real_stop - mark the end of a profiler entry - //------------------------------------------------- - ATTR_FORCE_INLINE void real_stop() - { - // degenerate scenario - if (UNEXPECTED(m_filoptr <= m_filo)) - return; - - // get current tick count - osd_ticks_t curticks = get_profile_ticks(); - - // account for the time taken - m_data[m_filoptr->type] += curticks - m_filoptr->start; - - // move back an entry - m_filoptr--; - - // reset previous entry start time - m_filoptr->start = curticks; - } - - // an entry in the FILO - struct filo_entry - { - int type; // type of entry - osd_ticks_t start; // start time - }; - - // internal state - filo_entry * m_filoptr; // current FILO index - std::string m_text; // profiler text - attotime m_text_time; // profiler text last update - filo_entry m_filo[32]; // array of FILO entries - osd_ticks_t m_data[PROFILER_TOTAL + 1]; // array of data -}; - - -// ======================> dummy_profiler_state - -class dummy_profiler_state -{ -public: - // construction/destruction - dummy_profiler_state(); - - // getters - bool enabled() const { return false; } - const char *text(running_machine &machine) { return ""; } - - // enable/disable - void enable(bool state = true) { } - - // start/stop - void start(profile_type type) { } - void stop() { } -}; - - -// ======================> profiler_state - -#ifdef MAME_PROFILER -typedef real_profiler_state profiler_state; -#else -typedef dummy_profiler_state profiler_state; -#endif - - - -//************************************************************************** -// GLOBAL VARIABLES -//************************************************************************** - -extern profiler_state g_profiler; - - -#endif /* MAME_EMU_PROFILER_H */ diff --git a/src/emu/recording.cpp b/src/emu/recording.cpp index 9e3c1f3f..7de727a0 100644 --- a/src/emu/recording.cpp +++ b/src/emu/recording.cpp @@ -218,14 +218,11 @@ bool avi_movie_recording::append_single_video_frame(bitmap_rgb32 &bitmap, const bool avi_movie_recording::add_sound_to_recording(const s16 *sound, int numsamples) { - g_profiler.start(PROFILER_MOVIE_REC); - // write the next frame avi_file::error avierr = m_avi_file->append_sound_samples(0, sound + 0, numsamples, 1); if (avierr == avi_file::error::NONE) avierr = m_avi_file->append_sound_samples(1, sound + 1, numsamples, 1); - g_profiler.stop(); return avierr == avi_file::error::NONE; } diff --git a/src/emu/schedule.cpp b/src/emu/schedule.cpp index b98f5922..d34e24d5 100644 --- a/src/emu/schedule.cpp +++ b/src/emu/schedule.cpp @@ -11,10 +11,6 @@ #include "emu.h" #include "debugger.h" -//************************************************************************** -// DEBUGGING -//************************************************************************** - #define PRECISION @@ -284,25 +280,6 @@ inline void emu_timer::schedule_next_period() scheduler.timer_list_insert(*this); } - -//------------------------------------------------- -// dump - dump internal state to a single output -// line in the error log -//------------------------------------------------- - -void emu_timer::dump() const -{ - machine().logerror("%p: en=%d temp=%d exp=%15s start=%15s per=%15s param=%d ptr=%p", this, m_enabled, m_temporary, m_expire.as_string(PRECISION), m_start.as_string(PRECISION), m_period.as_string(PRECISION), m_param, m_ptr); - if (m_device == nullptr) - if (m_callback.name() == nullptr) - machine().logerror(" cb=NULL\n"); - else - machine().logerror(" cb=%s\n", m_callback.name()); - else - machine().logerror(" dev=%s id=%d\n", m_device->tag(), m_id); -} - - //------------------------------------------------- // device_timer_expired - trampoline to avoid a // conditional jump on the hot path @@ -384,11 +361,7 @@ bool device_scheduler::can_save() const // if any live temporary timers exit, fail for (emu_timer *timer = m_timer_list; timer != nullptr; timer = timer->next()) if (timer->m_temporary && !timer->expire().is_never()) - { - machine().logerror("Failed save state attempt due to anonymous timers:\n"); - dump_timers(); return false; - } // otherwise, we're good return true; @@ -476,8 +449,6 @@ void device_scheduler::timeslice() // if we're not suspended, actually execute if (exec->m_suspend == 0) { - g_profiler.start(exec->m_profiler); - // note that this global variable cycles_stolen can be modified // via the call to cpu_execute exec->m_cycles_stolen = 0; @@ -497,7 +468,6 @@ void device_scheduler::timeslice() ran -= *exec->m_icountptr; assert(ran >= exec->m_cycles_stolen); ran -= exec->m_cycles_stolen; - g_profiler.stop(); } // account for these cycles @@ -867,12 +837,8 @@ inline void device_scheduler::execute_timers() // call the callback if (was_enabled) { - g_profiler.start(PROFILER_TIMER_CALLBACK); - if (!timer.m_callback.isnull()) timer.m_callback(timer.m_ptr, timer.m_param); - - g_profiler.stop(); } // reset or remove the timer, but only if it wasn't modified during the callback @@ -936,17 +902,3 @@ void device_scheduler::add_scheduling_quantum(const attotime &quantum, const att m_quantum_list.insert_after(quant, insert_after); } } - - -//------------------------------------------------- -// dump_timers - dump the current timer state -//------------------------------------------------- - -void device_scheduler::dump_timers() const -{ - machine().logerror("=============================================\n"); - machine().logerror("Timer Dump: Time = %15s\n", time().as_string(PRECISION)); - for (emu_timer *timer = first_timer(); timer != nullptr; timer = timer->next()) - timer->dump(); - machine().logerror("=============================================\n"); -} diff --git a/src/emu/schedule.h b/src/emu/schedule.h index 9e90ed68..e37daf8e 100644 --- a/src/emu/schedule.h +++ b/src/emu/schedule.h @@ -77,7 +77,6 @@ private: // internal helpers void register_save(); void schedule_next_period(); - void dump() const; static void device_timer_expired(emu_timer &timer, void *ptr, s32 param); // internal state @@ -132,9 +131,6 @@ public: emu_timer *timer_alloc(device_t &device, device_timer_id id = 0, void *ptr = nullptr); void timer_set(const attotime &duration, device_t &device, device_timer_id id = 0, int param = 0, void *ptr = nullptr); - // debugging - void dump_timers() const; - // for emergencies only! void eat_all_cycles(); diff --git a/src/emu/screen.cpp b/src/emu/screen.cpp index 19b0d05b..bb1c6961 100644 --- a/src/emu/screen.cpp +++ b/src/emu/screen.cpp @@ -20,16 +20,6 @@ #include - -//************************************************************************** -// DEBUGGING -//************************************************************************** - -#define VERBOSE (0) -#define LOG_PARTIAL_UPDATES(x) do { if (VERBOSE) logerror x; } while (0) - - - //************************************************************************** // GLOBAL VARIABLES //************************************************************************** @@ -1156,32 +1146,21 @@ void screen_device::set_visible_area(int min_x, int max_x, int min_y, int max_y) bool screen_device::update_partial(int scanline) { - LOG_PARTIAL_UPDATES(("Partial: update_partial(%s, %d): ", tag(), scanline)); - // these two checks only apply if we're allowed to skip frames if (!(m_video_attributes & VIDEO_ALWAYS_UPDATE)) { // if skipping this frame, bail if (machine().video().skip_this_frame()) - { - LOG_PARTIAL_UPDATES(("skipped due to frameskipping\n")); return false; - } // skip if this screen is not visible anywhere if (!machine().render().is_live(*this)) - { - LOG_PARTIAL_UPDATES(("skipped because screen not live\n")); return false; - } } // skip if we already rendered this line if (scanline < m_last_partial_scan) - { - LOG_PARTIAL_UPDATES(("skipped because line was already rendered\n")); return false; - } // set the range of scanlines to render rectangle clip(m_visarea); @@ -1189,15 +1168,9 @@ bool screen_device::update_partial(int scanline) // skip if entirely outside of visible area if (clip.top() > clip.bottom()) - { - LOG_PARTIAL_UPDATES(("skipped because outside of visible area\n")); return false; - } // otherwise, render - LOG_PARTIAL_UPDATES(("updating %d-%d\n", clip.top(), clip.bottom())); - g_profiler.start(PROFILER_VIDEO); - u32 flags = 0; if (m_video_attributes & VIDEO_VARIABLE_WIDTH) { @@ -1237,8 +1210,6 @@ bool screen_device::update_partial(int scanline) m_partial_updates_this_frame++; } - g_profiler.stop(); - // if we modified the bitmap, we have to commit m_changed |= ~flags & UPDATE_HAS_NOT_CHANGED; @@ -1261,17 +1232,11 @@ void screen_device::update_now() { // if skipping this frame, bail if (machine().video().skip_this_frame()) - { - LOG_PARTIAL_UPDATES(("skipped due to frameskipping\n")); return; - } // skip if this screen is not visible anywhere if (!machine().render().is_live(*this)) - { - LOG_PARTIAL_UPDATES(("skipped because screen not live\n")); return; - } } int current_vpos = vpos(); @@ -1280,19 +1245,11 @@ void screen_device::update_now() // skip if we already rendered this line if (current_vpos < m_last_partial_scan) - { - LOG_PARTIAL_UPDATES(("skipped because line was already rendered\n")); return; - } // if beam position is the same, there's nothing to update if (current_vpos == m_last_partial_scan && current_hpos == m_partial_scan_hpos) - { - LOG_PARTIAL_UPDATES(("skipped because beam position is unchanged\n")); return; - } - - LOG_PARTIAL_UPDATES(("update_now(): Y=%d, X=%d, last partial %d, partial hpos %d (vis %d %d)\n", current_vpos, current_hpos, m_last_partial_scan, m_partial_scan_hpos, m_visarea.right(), m_visarea.bottom())); // start off by doing a partial update up to the line before us, in case that was necessary if (current_vpos > m_last_partial_scan) @@ -1309,8 +1266,6 @@ void screen_device::update_now() // if there's something to draw, do it if (!clip.empty()) { - g_profiler.start(PROFILER_VIDEO); - u32 flags = 0; screen_bitmap &curbitmap = m_bitmap[m_curbitmap]; if (m_video_attributes & VIDEO_VARIABLE_WIDTH) @@ -1333,7 +1288,6 @@ void screen_device::update_now() } } - g_profiler.stop(); m_partial_updates_this_frame++; // if we modified the bitmap, we have to commit @@ -1360,10 +1314,6 @@ void screen_device::update_now() // and if there's something to draw, do it if (!clip.empty()) { - g_profiler.start(PROFILER_VIDEO); - - LOG_PARTIAL_UPDATES(("doing scanline partial draw: Y %d X %d-%d\n", clip.bottom(), clip.left(), clip.right())); - u32 flags = 0; screen_bitmap &curbitmap = m_bitmap[m_curbitmap]; if (m_video_attributes & VIDEO_VARIABLE_WIDTH) @@ -1387,7 +1337,6 @@ void screen_device::update_now() } m_partial_updates_this_frame++; - g_profiler.stop(); // if we modified the bitmap, we have to commit m_changed |= ~flags & UPDATE_HAS_NOT_CHANGED; diff --git a/src/emu/sound.cpp b/src/emu/sound.cpp index 56b7d7ef..b0adbb01 100644 --- a/src/emu/sound.cpp +++ b/src/emu/sound.cpp @@ -15,20 +15,6 @@ #include "config.h" #include "wavwrite.h" - - -//************************************************************************** -// DEBUGGING -//************************************************************************** - -#define VERBOSE (0) - -#define VPRINTF(x) do { if (VERBOSE) osd_printf_debug x; } while (0) - -#define LOG_OUTPUT_WAV (0) - - - //************************************************************************** // CONSTANTS //************************************************************************** @@ -67,10 +53,6 @@ stream_buffer::stream_buffer(u32 sample_rate) : stream_buffer::~stream_buffer() { -#if (SOUND_DEBUG) - if (m_wav_file) - flush_wav(); -#endif } @@ -120,14 +102,7 @@ void stream_buffer::set_sample_rate(u32 rate, bool resample) for (int index = 0; index < buffered_samples; index++) { end = prev_index(end); -#if (SOUND_DEBUG) - // multiple resamples can occur before clearing out old NaNs so - // neuter them for this specific case - if (std::isnan(m_buffer[end])) - buffer[index] = 0; - else -#endif - buffer[index] = get(end); + buffer[index] = get(end); } } } @@ -147,12 +122,6 @@ void stream_buffer::set_sample_rate(u32 rate, bool resample) // otherwise just copy our previously-downsampled data if (resample) { -#if (SOUND_DEBUG) - // for aggressive debugging, fill the buffer with NANs to catch anyone - // reading beyond what we resample below - fill(NAN); -#endif - if (new_rate_higher) backfill_upsample(&buffer[0], buffered_samples, prevend, prevperiod); else @@ -171,56 +140,6 @@ void stream_buffer::set_sample_rate(u32 rate, bool resample) fill(0); } - -//------------------------------------------------- -// open_wav - open a WAV file for logging purposes -//------------------------------------------------- - -#if (SOUND_DEBUG) -void stream_buffer::open_wav(char const *filename) -{ - // always open at 48k so that sound programs can handle it - // re-sample as needed - m_wav_file = util::wav_open(filename, 48000, 1); -} -#endif - - -//------------------------------------------------- -// flush_wav - flush data to the WAV file -//------------------------------------------------- - -#if (SOUND_DEBUG) -void stream_buffer::flush_wav() -{ - // skip if no file - if (!m_wav_file) - return; - - // grab a view of the data from the last-written point - read_stream_view view(this, m_last_written, m_end_sample, 1.0f); - m_last_written = m_end_sample; - - // iterate over chunks for conversion - s16 buffer[1024]; - for (int samplebase = 0; samplebase < view.samples(); samplebase += std::size(buffer)) - { - // clamp to the buffer size - int cursamples = view.samples() - samplebase; - if (cursamples > std::size(buffer)) - cursamples = std::size(buffer); - - // convert and fill - for (int sampindex = 0; sampindex < cursamples; sampindex++) - buffer[sampindex] = s16(view.get(samplebase + sampindex) * 32768.0); - - // write to the WAV - util::wav_add_data_16(*m_wav_file, buffer, cursamples); - } -} -#endif - - //------------------------------------------------- // index_time - return the attotime of a given // index within the buffer @@ -284,15 +203,8 @@ void stream_buffer::backfill_downsample(sample_t *dest, int samples, attotime ne int dstindex; for (dstindex = 0; dstindex < samples && time.seconds() >= 0; dstindex++) { - u32 srcindex = time_to_buffer_index(time, false); -#if (SOUND_DEBUG) - // multiple resamples can occur before clearing out old NaNs so - // neuter them for this specific case - if (std::isnan(m_buffer[srcindex])) - dest[dstindex] = 0; - else -#endif - dest[dstindex] = get(srcindex); + u32 srcindex = time_to_buffer_index(time, false); + dest[dstindex] = get(srcindex); time -= newperiod; } for ( ; dstindex < samples; dstindex++) @@ -373,22 +285,6 @@ void sound_stream_output::init(sound_stream &stream, u32 index, char const *tag) // save our state auto &save = stream.device().machine().save(); save.save_item(&stream.device(), "stream.output", tag, index, NAME(m_gain)); - -#if (LOG_OUTPUT_WAV) - std::string filename = stream.device().machine().basename(); - filename += stream.device().tag(); - for (int index = 0; index < filename.size(); index++) - if (filename[index] == ':') - filename[index] = '_'; - if (dynamic_cast(&stream) != nullptr) - filename += "_resampler"; - filename += "_OUT_"; - char buf[10]; - sprintf(buf, "%d", index); - filename += buf; - filename += ".wav"; - m_buffer.open_wav(filename.c_str()); -#endif } @@ -648,9 +544,6 @@ void sound_stream::set_sample_rate(u32 new_rate) void sound_stream::set_input(int index, sound_stream *input_stream, int output_index, float gain) { - VPRINTF(("stream_set_input(%p, '%s', %d, %p, %d, %f)\n", (void *)this, m_device.tag(), - index, (void *)input_stream, output_index, (double) gain)); - // make sure it's a valid input if (index >= m_input.size()) fatalerror("stream_set_input attempted to configure nonexistent input %d (%d max)\n", index, int(m_input.size())); @@ -704,8 +597,6 @@ read_stream_view sound_stream::update_view(attotime start, attotime end, u32 out if (start > end) start = end; - g_profiler.start(PROFILER_SOUND); - // reposition our start to coincide with the current buffer end attotime update_start = m_output[outputnum].end_time(); if (update_start <= end) @@ -732,27 +623,12 @@ read_stream_view sound_stream::update_view(attotime start, attotime end, u32 out sound_assert(m_resampling_disabled || m_input_view[inputnum].sample_rate() == m_sample_rate); } -#if (SOUND_DEBUG) - // clear each output view to NANs before we call the callback - for (unsigned int outindex = 0; outindex < m_output.size(); outindex++) - m_output_view[outindex].fill(NAN); -#endif // if we have an extended callback, that's all we need m_callback_ex(*this, m_input_view, m_output_view); -#if (SOUND_DEBUG) - // make sure everything was overwritten - for (unsigned int outindex = 0; outindex < m_output.size(); outindex++) - for (int sampindex = 0; sampindex < m_output_view[outindex].samples(); sampindex++) - m_output_view[outindex].get(sampindex); - - for (unsigned int outindex = 0; outindex < m_output.size(); outindex++) - m_output[outindex].m_buffer.flush_wav(); -#endif } } - g_profiler.stop(); // return the requested view return read_stream_view(m_output_view[outputnum], start); @@ -793,9 +669,6 @@ void sound_stream::apply_sample_rate_changes(u32 updatenum, u32 downstream_rate) if (new_rate != SAMPLE_RATE_INVALID && new_rate != m_sample_rate) { // update to the new rate and notify everyone -#if (SOUND_DEBUG) - printf("stream %s changing rates %d -> %d\n", name().c_str(), m_sample_rate, new_rate); -#endif m_sample_rate = new_rate; sample_rate_changed(); } @@ -806,29 +679,6 @@ void sound_stream::apply_sample_rate_changes(u32 updatenum, u32 downstream_rate) input.apply_sample_rate_changes(updatenum, m_sample_rate); } - -//------------------------------------------------- -// print_graph_recursive - helper for debugging; -// prints info on this stream and then recursively -// prints info on all inputs -//------------------------------------------------- - -#if (SOUND_DEBUG) -void sound_stream::print_graph_recursive(int indent, int index) -{ - osd_printf_info("%*s%s Ch.%d @ %d\n", indent, "", name(), index + m_output_base, sample_rate()); - for (int index = 0; index < m_input.size(); index++) - if (m_input[index].valid()) - { - if (m_input[index].m_resampler_source != nullptr) - m_input[index].m_resampler_source->stream().print_graph_recursive(indent + 2, m_input[index].m_resampler_source->index()); - else - m_input[index].m_native_source->stream().print_graph_recursive(indent + 2, m_input[index].m_native_source->index()); - } -} -#endif - - //------------------------------------------------- // sample_rate_changed - recompute sample // rate data, and all streams that are affected @@ -1084,12 +934,6 @@ sound_manager::sound_manager(running_machine &machine) : if (m_nosound_mode && wavfile[0] == 0 && avifile[0] == 0) machine.m_sample_rate = 11025; - // count the mixers -#if VERBOSE - mixer_interface_enumerator iter(machine.root_device()); - VPRINTF(("total mixers = %d\n", iter.count())); -#endif - // register callbacks machine.configuration().config_register( "mixer", @@ -1312,25 +1156,6 @@ void sound_manager::reset() m_speakers.emplace_back(speaker); } - -#if (SOUND_DEBUG) - // dump the sound graph when we start up - for (speaker_device &speaker : speaker_device_enumerator(machine().root_device())) - { - int index; - sound_stream *output = speaker.output_to_stream_output(0, index); - if (output != nullptr) - output->print_graph_recursive(0, index); - } - - // dump the orphan list as well - if (m_orphan_stream_list.size() != 0) - { - osd_printf_info("\nOrphaned streams:\n"); - for (auto &stream : m_orphan_stream_list) - osd_printf_info(" %s\n", stream.first->name()); - } -#endif } } @@ -1459,10 +1284,6 @@ stream_buffer::sample_t sound_manager::adjust_toward_compressor_scale(stream_buf void sound_manager::update(void *ptr, int param) { - VPRINTF(("sound_update\n")); - - g_profiler.start(PROFILER_SOUND); - // determine the duration of this update attotime update_period = machine().time() - m_last_update; sound_assert(update_period.seconds() == 0); @@ -1522,11 +1343,6 @@ void sound_manager::update(void *ptr, int param) m_compressor_scale = 1.0; } -#if (SOUND_DEBUG) - if (lscale != m_compressor_scale) - printf("scale=%.5f\n", m_compressor_scale); -#endif - // track whether there are pending scale changes in left/right stream_buffer::sample_t lprev = 0, rprev = 0; @@ -1597,6 +1413,4 @@ void sound_manager::update(void *ptr, int param) // notify that new samples have been generated emulator_info::sound_hook(); - - g_profiler.stop(); } diff --git a/src/emu/sound.h b/src/emu/sound.h index 4dd1d2e5..1e65718d 100644 --- a/src/emu/sound.h +++ b/src/emu/sound.h @@ -82,21 +82,7 @@ constexpr u32 SAMPLE_RATE_MINIMUM = 50; // DEBUGGING //************************************************************************** -// turn this on to enable aggressive assertions and other checks -#ifdef MAME_DEBUG -#define SOUND_DEBUG (1) -#else -#define SOUND_DEBUG (0) -#endif - -// if SOUND_DEBUG is on, make assertions fire regardless of MAME_DEBUG -#if (SOUND_DEBUG) -#define sound_assert(x) do { if (!(x)) { osd_printf_error("sound_assert: " #x "\n"); osd_break_into_debugger("sound_assert: " #x "\n"); } } while (0) -#else #define sound_assert assert -#endif - - //************************************************************************** // TYPE DEFINITIONS @@ -155,9 +141,6 @@ private: { sound_assert(u32(index) < size()); sample_t value = m_buffer[index]; -#if (SOUND_DEBUG) - sound_assert(!std::isnan(value)); -#endif return value; } @@ -205,18 +188,6 @@ private: u32 m_sample_rate; // sample rate of the data in the buffer attoseconds_t m_sample_attos; // pre-computed attoseconds per sample std::vector m_buffer; // vector of actual buffer data - -#if (SOUND_DEBUG) -public: - // for debugging, provide an interface to write a WAV stream - void open_wav(char const *filename); - void flush_wav(); - -private: - // internal debugging state - util::wav_file_ptr m_wav_file; // pointer to the current WAV file - u32 m_last_written = 0; // last written sample index -#endif }; @@ -472,10 +443,6 @@ private: class sound_stream_output { -#if (SOUND_DEBUG) - friend class sound_stream; -#endif - public: // construction/destruction sound_stream_output(); @@ -526,10 +493,6 @@ private: class sound_stream_input { -#if (SOUND_DEBUG) - friend class sound_stream; -#endif - public: // construction/destruction sound_stream_input(); @@ -651,11 +614,6 @@ public: // apply any pending sample rate changes; should only be called by the sound manager void apply_sample_rate_changes(u32 updatenum, u32 downstream_rate); -#if (SOUND_DEBUG) - // print one level of the sound graph and recursively tell our inputs to do the same - void print_graph_recursive(int indent, int index); -#endif - protected: // protected state std::string m_name; // name of this stream diff --git a/src/emu/tilemap.cpp b/src/emu/tilemap.cpp index 5757f353..a2f85555 100644 --- a/src/emu/tilemap.cpp +++ b/src/emu/tilemap.cpp @@ -772,8 +772,6 @@ void tilemap_t::pixmap_update() if (m_all_tiles_clean) return; -g_profiler.start(PROFILER_TILEMAP_DRAW); - // flush the dirty state to all tiles as appropriate realize_all_dirty_tiles(); @@ -786,8 +784,6 @@ g_profiler.start(PROFILER_TILEMAP_DRAW); // mark it all clean m_all_tiles_clean = true; - -g_profiler.stop(); } @@ -797,8 +793,6 @@ g_profiler.stop(); void tilemap_t::tile_update(logical_index logindex, u32 col, u32 row) { -g_profiler.start(PROFILER_TILEMAP_UPDATE); - // call the get info callback for the associated memory index tilemap_memory_index memindex = m_logical_to_memory[logindex]; m_tile_get_info(*this, m_tileinfo, memindex); @@ -822,8 +816,6 @@ g_profiler.start(PROFILER_TILEMAP_UPDATE); m_gfx_used |= 1 << m_tileinfo.gfxnum; m_gfx_dirtyseq[m_tileinfo.gfxnum] = m_tileinfo.decoder->gfx(m_tileinfo.gfxnum)->dirtyseq(); } - -g_profiler.stop(); } @@ -997,7 +989,6 @@ void tilemap_t::draw_common(screen_device &screen, _BitmapClass &dest, const rec if (!m_enable) return; -g_profiler.start(PROFILER_TILEMAP_DRAW); // configure the blit parameters based on the input parameters blit_parameters blit; configure_blit_parameters(blit, screen.priority(), cliprect, flags, priority, priority_mask); @@ -1095,7 +1086,6 @@ g_profiler.start(PROFILER_TILEMAP_DRAW); } } } -g_profiler.stop(); } void tilemap_t::draw(screen_device &screen, bitmap_ind16 &dest, const rectangle &cliprect, u32 flags, u8 priority, u8 priority_mask) @@ -1134,7 +1124,6 @@ void tilemap_t::draw_roz_common(screen_device &screen, _BitmapClass &dest, const return; } -g_profiler.start(PROFILER_TILEMAP_DRAW_ROZ); // configure the blit parameters blit_parameters blit; configure_blit_parameters(blit, screen.priority(), cliprect, flags, priority, priority_mask); @@ -1146,7 +1135,6 @@ g_profiler.start(PROFILER_TILEMAP_DRAW_ROZ); // then do the roz copy draw_roz_core(screen, dest, blit, startx, starty, incxx, incxy, incyx, incyy, wraparound); -g_profiler.stop(); } void tilemap_t::draw_roz(screen_device &screen, bitmap_ind16 &dest, const rectangle &cliprect, diff --git a/src/emu/uiinput.cpp b/src/emu/uiinput.cpp index d1398591..47d608c2 100644 --- a/src/emu/uiinput.cpp +++ b/src/emu/uiinput.cpp @@ -254,8 +254,6 @@ bool ui_input_manager::pressed_repeat(int code, int speed) { bool pressed; -g_profiler.start(PROFILER_INPUT); - /* get the status of this key (assumed to be only in the defaults) */ assert(code >= IPT_UI_CONFIGURE && code <= IPT_OSD_16); pressed = (m_seqpressed[code] == SEQ_PRESSED_TRUE); @@ -289,8 +287,6 @@ g_profiler.start(PROFILER_INPUT); else m_next_repeat[code] = 0; -g_profiler.stop(); - return pressed; } diff --git a/src/emu/video.cpp b/src/emu/video.cpp index 5797f72d..11fa0b9f 100644 --- a/src/emu/video.cpp +++ b/src/emu/video.cpp @@ -231,9 +231,7 @@ void video_manager::frame_update(bool from_debugger) update_throttle(current_time); // ask the OSD to update - g_profiler.start(PROFILER_BLIT); machine().osd().update(!from_debugger && skipped_it); - g_profiler.stop(); // we synchronize after rendering instead of before, if low latency mode is enabled if (!from_debugger && !skipped_it && phase > machine_phase::INIT && m_low_latency && effective_throttle()) @@ -701,11 +699,7 @@ void video_manager::update_throttle(attotime emutime) // wrong and requires a resync attoseconds_t emu_delta_attoseconds = (emutime - m_throttle_emutime).as_attoseconds(); if (emu_delta_attoseconds < 0 || emu_delta_attoseconds > ATTOSECONDS_PER_SECOND / 10) - { - if (LOG_THROTTLE) - machine().logerror("Resync due to weird emutime delta: %s\n", attotime(0, emu_delta_attoseconds).as_string(18)); break; - } // now determine the current real time in OSD-specified ticks; we have to be careful // here because counters can wrap, so we only use the difference between the last @@ -716,11 +710,7 @@ void video_manager::update_throttle(attotime emutime) // if it has been more than a full second of real time since the last call to this // function, we just need to resynchronize if (diff_ticks >= ticks_per_second) - { - if (LOG_THROTTLE) - machine().logerror("Resync due to real time advancing by more than 1 second\n"); break; - } // convert this value into attoseconds for easier comparison attoseconds_t real_delta_attoseconds = diff_ticks * attoseconds_per_tick; @@ -742,11 +732,7 @@ void video_manager::update_throttle(attotime emutime) // is taking longer than the real frame, we just need to resync if (real_is_ahead_attoseconds < -ATTOSECONDS_PER_SECOND / 10 || (real_is_ahead_attoseconds < 0 && population_count_32(m_throttle_history & 0xff) < 6)) - { - if (LOG_THROTTLE) - machine().logerror("Resync due to being behind: %s (history=%08X)\n", attotime(0, -real_is_ahead_attoseconds).as_string(18), m_throttle_history); break; - } // if we're behind, it's time to just get out if (real_is_ahead_attoseconds < 0) @@ -780,7 +766,6 @@ osd_ticks_t video_manager::throttle_until_ticks(osd_ticks_t target_ticks) bool const allowed_to_sleep = (machine().options().sleep() && (!effective_autoframeskip() || effective_frameskip() == 0)) || machine().paused(); // loop until we reach our target - g_profiler.start(PROFILER_IDLE); osd_ticks_t current_ticks = osd_ticks(); while (current_ticks < target_ticks) { @@ -809,14 +794,10 @@ osd_ticks_t video_manager::throttle_until_ticks(osd_ticks_t target_ticks) // take 99% of the previous average plus 1% of the new value osd_ticks_t const oversleep_milliticks = 1000 * (actual_ticks - delta); m_average_oversleep = (m_average_oversleep * 99 + oversleep_milliticks) / 100; - - if (LOG_THROTTLE) - machine().logerror("Slept for %d ticks, got %d ticks, avgover = %d\n", (int)delta, (int)actual_ticks, (int)m_average_oversleep); } } current_ticks = new_ticks; } - g_profiler.stop(); return current_ticks; } @@ -1185,8 +1166,6 @@ void video_manager::record_frame() if (!is_recording()) return; - // start the profiler and get the current time - g_profiler.start(PROFILER_MOVIE_REC); attotime curtime = machine().time(); bool error = false; @@ -1205,7 +1184,6 @@ void video_manager::record_frame() if (error) end_recording(); - g_profiler.stop(); } diff --git a/src/frontend/mame/luaengine.ipp b/src/frontend/mame/luaengine.ipp index 10d1f55f..e72948a9 100644 --- a/src/frontend/mame/luaengine.ipp +++ b/src/frontend/mame/luaengine.ipp @@ -527,9 +527,7 @@ auto lua_engine::make_simple_callback_setter(void (T::*setter)(delegate && template inline sol::protected_function_result lua_engine::invoke(TFunc &&func, TArgs &&... args) { - g_profiler.start(PROFILER_LUA); sol::protected_function_result result = func(std::forward(args)...); - g_profiler.stop(); return result; } diff --git a/src/frontend/mame/ui/submenu.cpp b/src/frontend/mame/ui/submenu.cpp index 9f832125..7b228073 100644 --- a/src/frontend/mame/ui/submenu.cpp +++ b/src/frontend/mame/ui/submenu.cpp @@ -15,11 +15,7 @@ #include "ui/ui.h" #include "ui/utils.h" -#if defined(UI_WINDOWS) && !defined(UI_SDL) -#include "../osd/windows/winmain.h" -#else #include "../osd/modules/lib/osdobj_common.h" -#endif #include "../osd/modules/input/input_module.h" #include diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp index 03a4ac5b..229bb0cc 100644 --- a/src/frontend/mame/ui/ui.cpp +++ b/src/frontend/mame/ui/ui.cpp @@ -974,7 +974,6 @@ bool mame_ui_manager::show_fps_counter() void mame_ui_manager::set_show_profiler(bool show) { m_show_profiler = show; - g_profiler.enable(show); } @@ -1134,22 +1133,6 @@ void mame_ui_manager::draw_fps_counter(render_container &container) } -//------------------------------------------------- -// draw_profiler -//------------------------------------------------- - -void mame_ui_manager::draw_profiler(render_container &container) -{ - std::string_view text = g_profiler.text(machine()); - draw_text_full( - container, - text, - 0.0f, 0.0f, 1.0f, - ui::text_layout::text_justify::LEFT, ui::text_layout::word_wrapping::WORD, - OPAQUE_, rgb_t::white(), rgb_t::black(), nullptr, nullptr); -} - - //------------------------------------------------- // start_save_state //------------------------------------------------- @@ -1218,10 +1201,6 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container) if (show_fps_counter()) draw_fps_counter(container); - // draw the profiler if visible - if (show_profiler()) - draw_profiler(container); - // if we're single-stepping, pause now if (single_step()) { diff --git a/src/frontend/mame/ui/ui.h b/src/frontend/mame/ui/ui.h index e155a261..87662bed 100644 --- a/src/frontend/mame/ui/ui.h +++ b/src/frontend/mame/ui/ui.h @@ -186,7 +186,6 @@ public: void decrease_frameskip(); void request_quit(); void draw_fps_counter(render_container &container); - void draw_profiler(render_container &container); void start_save_state(); void start_load_state(); diff --git a/src/osd/mac/appdelegate.h b/src/osd/mac/appdelegate.h deleted file mode 100644 index 31daea12..00000000 --- a/src/osd/mac/appdelegate.h +++ /dev/null @@ -1,15 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont -//============================================================ -// -// appdelegate.h - Cocoa app delegate -// -// Mac OSD by R. Belmont -// -//============================================================ - -#import - -@interface MAMEAppDelegate : NSObject - -@end diff --git a/src/osd/mac/appdelegate.mm b/src/osd/mac/appdelegate.mm deleted file mode 100644 index 8aa80e4f..00000000 --- a/src/osd/mac/appdelegate.mm +++ /dev/null @@ -1,38 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont -//============================================================ -// -// appdelegate.mm - Cocoa app delegate -// -// Mac OSD by R. Belmont -// -//============================================================ - -#import "appdelegate.h" - -@interface MAMEAppDelegate () -@end - -@implementation MAMEAppDelegate - -- (void)applicationDidFinishLaunching:(NSNotification *)notification -{ -} - -- (void)applicationWillTerminate:(NSNotification *)notification -{ -} - -- (void)applicationDidBecomeActive:(NSNotification *)notification -{ -} - -- (void)applicationDidResignActive:(NSNotification *)notification -{ -} - -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSNotification *)notification -{ - return NSTerminateNow; -} -@end diff --git a/src/osd/mac/macmain.cpp b/src/osd/mac/macmain.cpp deleted file mode 100644 index 6a99d0c5..00000000 --- a/src/osd/mac/macmain.cpp +++ /dev/null @@ -1,268 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont -//============================================================ -// -// macmain.cpp - C++ side main file for MAME on the Mac -// -// Mac OSD by R. Belmont -// -//============================================================ - -// oslog callback -#include - -#define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 -#include -#include -#include - -// MAME headers -#include "corestr.h" -#include "osdepend.h" -#include "emu.h" -#include "emuopts.h" -#include "strconv.h" - -// OSD headers -#include "video.h" -#include "osdmac.h" -#include "modules/lib/osdlib.h" -#include "modules/diagnostics/diagnostics_module.h" - -//============================================================ -// OPTIONS -//============================================================ - -#ifndef INI_PATH -#define INI_PATH "$HOME/Library/Application Support/APP_NAME;$HOME/.APP_NAME;.;ini" -#endif // INI_PATH - -//============================================================ -// Local variables -//============================================================ - -const options_entry mac_options::s_option_entries[] = -{ - { MACOPTION_INIPATH, INI_PATH, OPTION_STRING, "path to ini files" }, - - // End of list - { nullptr } -}; - -//============================================================ -// mac_options -//============================================================ - -mac_options::mac_options() -: osd_options() -{ - std::string ini_path(INI_PATH); - add_entries(mac_options::s_option_entries); - strreplace(ini_path,"APP_NAME", emulator_info::get_appname_lower()); - set_default_value(MACOPTION_INIPATH, std::move(ini_path)); -} - -//============================================================ -// mac_run_emulator - this is the MAME entry point from the -// Cocoa shell -//============================================================ - -int mac_run_emulator(int argc, char *argv[]) -{ - std::vector args = osd_get_command_line(argc, argv); - int res = 0; - - // disable I/O buffering - setvbuf(stdout, (char *) nullptr, _IONBF, 0); - setvbuf(stderr, (char *) nullptr, _IONBF, 0); - - // Initialize crash diagnostics - diagnostics_module::get_instance()->init_crash_diagnostics(); - - mac_options options; - mac_osd_interface osd(options); - osd.register_options(); - res = emulator_info::start_frontend(options, osd, args); - - return res; -} - -//============================================================ -// constructor -//============================================================ - -mac_osd_interface::mac_osd_interface(mac_options &options) -: osd_common_t(options), m_options(options) -{ -} - - -//============================================================ -// destructor -//============================================================ - -mac_osd_interface::~mac_osd_interface() -{ -} - - -//============================================================ -// osd_exit -//============================================================ - -void mac_osd_interface::osd_exit() -{ - osd_common_t::osd_exit(); -} - -//============================================================ -// defines_verbose -//============================================================ - -#define MAC_EXPAND_STR(_m) #_m -#define MACRO_VERBOSE(_mac) \ - do { \ - if (strcmp(MAC_EXPAND_STR(_mac), #_mac) != 0) \ - osd_printf_verbose("%s=%s ", #_mac, MAC_EXPAND_STR(_mac)); \ - } while (0) - -#define _mac_VER #mac_MAJOR_VERSION "." #mac_MINOR_VERSION "." #mac_PATCHLEVEL - -static void defines_verbose(void) -{ - osd_printf_verbose("Build version: %s\n", emulator_info::get_build_version()); - osd_printf_verbose("Build architecure: "); - MACRO_VERBOSE(SDLMAME_ARCH); - osd_printf_verbose("\n"); - osd_printf_verbose("Build defines 1: "); - MACRO_VERBOSE(SDLMAME_UNIX); - MACRO_VERBOSE(SDLMAME_X11); - MACRO_VERBOSE(SDLMAME_WIN32); - MACRO_VERBOSE(SDLMAME_MACOSX); - MACRO_VERBOSE(SDLMAME_DARWIN); - MACRO_VERBOSE(SDLMAME_LINUX); - MACRO_VERBOSE(SDLMAME_SOLARIS); - MACRO_VERBOSE(SDLMAME_IRIX); - MACRO_VERBOSE(SDLMAME_BSD); - osd_printf_verbose("\n"); - osd_printf_verbose("Build defines 1: "); - MACRO_VERBOSE(LSB_FIRST); - MACRO_VERBOSE(PTR64); - MACRO_VERBOSE(MAME_NOASM); - MACRO_VERBOSE(MAME_DEBUG); - MACRO_VERBOSE(BIGENDIAN); - MACRO_VERBOSE(CPP_COMPILE); - MACRO_VERBOSE(SYNC_IMPLEMENTATION); - osd_printf_verbose("\n"); - osd_printf_verbose("OpenGL defines: "); - MACRO_VERBOSE(USE_OPENGL); - MACRO_VERBOSE(USE_DISPATCH_GL); - osd_printf_verbose("\n"); - osd_printf_verbose("Compiler defines A: "); - MACRO_VERBOSE(__GNUC__); - MACRO_VERBOSE(__GNUC_MINOR__); - MACRO_VERBOSE(__GNUC_PATCHLEVEL__); - MACRO_VERBOSE(__VERSION__); - osd_printf_verbose("\n"); - osd_printf_verbose("Compiler defines B: "); - MACRO_VERBOSE(__amd64__); - MACRO_VERBOSE(__x86_64__); - MACRO_VERBOSE(__unix__); - MACRO_VERBOSE(__i386__); - MACRO_VERBOSE(__ppc__); - MACRO_VERBOSE(__ppc64__); - osd_printf_verbose("\n"); - osd_printf_verbose("Compiler defines C: "); - MACRO_VERBOSE(_FORTIFY_SOURCE); - MACRO_VERBOSE(__USE_FORTIFY_LEVEL); - osd_printf_verbose("\n"); -} - -//============================================================ -// osd_mac_info -//============================================================ - -static void osd_mac_info(void) -{ -} - - -//============================================================ -// video_register -//============================================================ - -void mac_osd_interface::video_register() -{ - video_options_add("opengl", nullptr); - video_options_add("bgfx", nullptr); -} - -//============================================================ -// output_oslog -//============================================================ - -void mac_osd_interface::output_oslog(const char *buffer) -{ - fputs(buffer, stderr); -} - - -//============================================================ -// osd_setup_osd_specific_emu_options -//============================================================ - -void osd_setup_osd_specific_emu_options(emu_options &opts) -{ - opts.add_entries(osd_options::s_option_entries); -} - - -//============================================================ -// init -//============================================================ - -void mac_osd_interface::init(running_machine &machine) -{ - // call our parent - osd_common_t::init(machine); - - const char *stemp; - - // determine if we are benchmarking, and adjust options appropriately - int bench = options().bench(); - if (bench > 0) - { - options().set_value(OPTION_SLEEP, false, OPTION_PRIORITY_MAXIMUM); - options().set_value(OPTION_THROTTLE, false, OPTION_PRIORITY_MAXIMUM); - options().set_value(OSDOPTION_SOUND, "none", OPTION_PRIORITY_MAXIMUM); - options().set_value(OSDOPTION_VIDEO, "none", OPTION_PRIORITY_MAXIMUM); - options().set_value(OPTION_SECONDS_TO_RUN, bench, OPTION_PRIORITY_MAXIMUM); - } - - /* get number of processors */ - stemp = options().numprocessors(); - - osd_num_processors = 0; - - if (strcmp(stemp, "auto") != 0) - { - osd_num_processors = atoi(stemp); - if (osd_num_processors < 1) - { - osd_printf_warning("numprocessors < 1 doesn't make much sense. Assuming auto ...\n"); - osd_num_processors = 0; - } - } - - osd_mac_info(); - - defines_verbose(); - - osd_common_t::init_subsystems(); - - if (options().oslog()) - { - using namespace std::placeholders; - machine.add_logerror_callback(std::bind(&mac_osd_interface::output_oslog, this, _1)); - } -} diff --git a/src/osd/mac/main.mm b/src/osd/mac/main.mm deleted file mode 100644 index d11eb0c7..00000000 --- a/src/osd/mac/main.mm +++ /dev/null @@ -1,42 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont -//============================================================ -// -// main.mm - main file for MAME on Mac -// -// Mac OSD by R. Belmont -// -//============================================================ - -#import "appdelegate.h" - -extern int mac_run_emulator(int argc, char *argv[]); - -int main(int argc, char * argv[]) -{ - [NSApplication sharedApplication]; - [NSApp setDelegate: [MAMEAppDelegate new]]; - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - [NSApp activateIgnoringOtherApps:YES]; - [NSApp finishLaunching]; - [[NSNotificationCenter defaultCenter] - postNotificationName:NSApplicationWillFinishLaunchingNotification - object:NSApp]; - [[NSNotificationCenter defaultCenter] - postNotificationName:NSApplicationDidFinishLaunchingNotification - object:NSApp]; - id quitMenuItem = [NSMenuItem new]; - [quitMenuItem - initWithTitle:@"Quit" - action:@selector(terminate:) - keyEquivalent:@"q"]; - id appMenu = [NSMenu new]; - [appMenu addItem:quitMenuItem]; - id appMenuItem = [NSMenuItem new]; - [appMenuItem setSubmenu:appMenu]; - id menubar = [[NSMenu new] autorelease]; - [menubar addItem:appMenuItem]; - [NSApp setMainMenu:menubar]; - - return mac_run_emulator(argc, argv); -} diff --git a/src/osd/mac/mamefswindow.h b/src/osd/mac/mamefswindow.h deleted file mode 100644 index d326b9df..00000000 --- a/src/osd/mac/mamefswindow.h +++ /dev/null @@ -1,15 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont -//============================================================ -// -// mamefswindow.h - our fullscreen window, subclassed from NSWindow -// -// Mac OSD by R. Belmont -// -//============================================================ - -#import - -@interface MAMEFSWindow : NSWindow - -@end diff --git a/src/osd/mac/mamefswindow.mm b/src/osd/mac/mamefswindow.mm deleted file mode 100644 index 1fcbdcd0..00000000 --- a/src/osd/mac/mamefswindow.mm +++ /dev/null @@ -1,41 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont -//============================================================ -// -// mamewfsindow.mm - our fullscreen window, subclassed from NSWindow -// -// Mac OSD by R. Belmont -// -//============================================================ - -#import "mamefswindow.h" - -@implementation MAMEFSWindow - --(instancetype)init -{ - NSRect screenRect = [[NSScreen mainScreen] frame]; - self = [super initWithContentRect:screenRect - styleMask:NSBorderlessWindowMask - backing:NSBackingStoreBuffered - defer:YES]; - - // Set the window level to be above the menu bar - [self setLevel:NSMainMenuWindowLevel+1]; - [self setOpaque:YES]; - [self setHidesOnDeactivate:YES]; - - return self; -} - --(BOOL)canBecomeKeyWindow -{ - return YES; -} - -- (void)keyDown:(NSEvent *)event -{ - [[self windowController] keyDown:event]; -} - -@end diff --git a/src/osd/mac/oglview.h b/src/osd/mac/oglview.h deleted file mode 100644 index 2f876952..00000000 --- a/src/osd/mac/oglview.h +++ /dev/null @@ -1,19 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont -//============================================================ -// -// oglview.h - our OpenGL view -// -// Mac OSD by R. Belmont -// -//============================================================ - -#define GL_SILENCE_DEPRECATION (1) - -#import - -@interface MAMEGLView : NSOpenGLView -{ -} - -@end diff --git a/src/osd/mac/oglview.mm b/src/osd/mac/oglview.mm deleted file mode 100644 index 8ef0a94f..00000000 --- a/src/osd/mac/oglview.mm +++ /dev/null @@ -1,106 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont -//============================================================ -// -// oglview.mm - our OpenGL view -// -// Mac OSD by R. Belmont -// -//============================================================ - -#import "oglview.h" - -#define SUPPORT_RETINA_RESOLUTION 1 - -@interface MAMEGLView () -{ -} -@end - -@implementation MAMEGLView - -- (void) awakeFromNib -{ - NSOpenGLPixelFormatAttribute attrs[] = - { - NSOpenGLPFADoubleBuffer, - NSOpenGLPFADepthSize, 24, - 0 - }; - - NSOpenGLPixelFormat *pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; - NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:pf shareContext:nil]; - - [self setPixelFormat:pf]; - [self setOpenGLContext:context]; - -#if SUPPORT_RETINA_RESOLUTION - // Opt-In to Retina resolution - [self setWantsBestResolutionOpenGLSurface:YES]; -#endif // SUPPORT_RETINA_RESOLUTION -} - -- (void) prepareOpenGL -{ - [super prepareOpenGL]; - - [self initGL]; -} - -- (void) windowWillClose:(NSNotification*)notification -{ -} - -- (void) initGL -{ - [[self openGLContext] makeCurrentContext]; - GLint swapInt = 1; - [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; -} - -- (void)reshape -{ - [super reshape]; - - CGLLockContext([[self openGLContext] CGLContextObj]); - -// NSRect viewRectPoints = [self bounds]; - -//#if SUPPORT_RETINA_RESOLUTION -// NSRect viewRectPixels = [self convertRectToBacking:viewRectPoints]; -//#else -// NSRect viewRectPixels = viewRectPoints; -//#endif - - CGLUnlockContext([[self openGLContext] CGLContextObj]); -} - - -- (void)renewGState -{ - [[self window] disableScreenUpdatesUntilFlush]; - [super renewGState]; -} - -- (void) drawRect: (NSRect) theRect -{ -} - -- (void) startDrawView -{ - [[self openGLContext] makeCurrentContext]; - - CGLLockContext([[self openGLContext] CGLContextObj]); -} - -- (void) completeDrawView -{ - CGLFlushDrawable([[self openGLContext] CGLContextObj]); - CGLUnlockContext([[self openGLContext] CGLContextObj]); -} - -- (void) dealloc -{ - [super dealloc]; -} -@end diff --git a/src/osd/mac/osdmac.h b/src/osd/mac/osdmac.h deleted file mode 100644 index 3e1dfe9b..00000000 --- a/src/osd/mac/osdmac.h +++ /dev/null @@ -1,87 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont -#ifndef _osdmac_h_ -#define _osdmac_h_ - -#include "modules/lib/osdobj_common.h" -#include "modules/osdmodule.h" -#include "modules/font/font_module.h" - -//============================================================ -// Defines -//============================================================ - -#define MACOPTION_INIPATH "inipath" - -#define MACOPTVAL_OPENGL "opengl" -#define MACOPTVAL_BGFX "bgfx" -#define MACOPTVAL_METAL "metal" - -#define MACOPTVAL_GLLIB "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib" - -//============================================================ -// TYPE DEFINITIONS -//============================================================ - -class mac_options : public osd_options -{ -public: - // construction/destruction - mac_options(); - -private: - static const options_entry s_option_entries[]; -}; - - -class mac_osd_interface : public osd_common_t -{ -public: - // construction/destruction - mac_osd_interface(mac_options &options); - virtual ~mac_osd_interface(); - - // general overridables - virtual void init(running_machine &machine) override; - virtual void update(bool skip_redraw) override; - virtual void input_update() override; - - // input overridables - virtual void customize_input_type_list(std::vector &typelist) override; - - virtual void video_register() override; - - virtual bool video_init() override; - virtual bool window_init() override; - - virtual void video_exit() override; - virtual void window_exit() override; - - // sdl specific - void poll_inputs(running_machine &machine); - void release_keys(); - bool should_hide_mouse(); - void process_events_buf(); - - virtual mac_options &options() override { return m_options; } - -protected: - virtual void build_slider_list() override; - virtual void update_slider_list() override; - -private: - virtual void osd_exit() override; - - void extract_video_config(); - void output_oslog(const char *buffer); - - mac_options &m_options; -}; - -//============================================================ -// macwork.cpp -//============================================================ - -extern int osd_num_processors; - -#endif diff --git a/src/osd/mac/video.cpp b/src/osd/mac/video.cpp deleted file mode 100644 index 6cfffb4b..00000000 --- a/src/osd/mac/video.cpp +++ /dev/null @@ -1,307 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Olivier Galibert, R. Belmont -//============================================================ -// -// video.cpp - Mac video handling -// -// Mac OSD by R. Belmont -// -//============================================================ - -// MAME headers -#include "emu.h" -#include "rendutil.h" -#include "ui/uimain.h" -#include "emuopts.h" -#include "uiinput.h" - - -// MAMEOS headers -#include "video.h" -#include "window.h" -#include "osdmac.h" -#include "modules/lib/osdlib.h" - -//============================================================ -// CONSTANTS -//============================================================ - - -//============================================================ -// GLOBAL VARIABLES -//============================================================ - -osd_video_config video_config; - -//============================================================ -// LOCAL VARIABLES -//============================================================ - - -//============================================================ -// PROTOTYPES -//============================================================ - -static void check_osd_inputs(running_machine &machine); - -static void get_resolution(const char *defdata, const char *data, osd_window_config *config, int report_error); - - -//============================================================ -// video_init -//============================================================ - -bool mac_osd_interface::video_init() -{ - int index; - - // extract data from the options - extract_video_config(); - - // we need the beam width in a float, contrary to what the core does. - video_config.beamwidth = options().beam_width_min(); - - // initialize the window system so we can make windows - if (!window_init()) - return false; - - // create the windows - for (index = 0; index < video_config.numscreens; index++) - { - osd_window_config conf; - memset(&conf, 0, sizeof(conf)); - get_resolution(options().resolution(), options().resolution(index), &conf, true); - - // create window ... - std::shared_ptr win = std::make_shared(machine(), index, m_monitor_module->pick_monitor(reinterpret_cast(options()), index), &conf); - - if (win->window_init()) - return false; - } - - return true; -} - -//============================================================ -// video_exit -//============================================================ - -void mac_osd_interface::video_exit() -{ - window_exit(); -} - -//============================================================ -// update -//============================================================ - -void mac_osd_interface::update(bool skip_redraw) -{ - osd_common_t::update(skip_redraw); - - // if we're not skipping this redraw, update all windows - if (!skip_redraw) - { -// profiler_mark(PROFILER_BLIT); - for (auto window : osd_common_t::s_window_list) - window->update(); -// profiler_mark(PROFILER_END); - } - - // if we're running, disable some parts of the debugger - if ((machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) != 0) - debugger_update(); -} - -//============================================================ -// input_update -//============================================================ - -void mac_osd_interface::input_update() -{ - // poll the joystick values here - process_events_buf(); - poll_inputs(machine()); - check_osd_inputs(machine()); -} - -//============================================================ -// check_osd_inputs -//============================================================ - -static void check_osd_inputs(running_machine &machine) -{ - // check for toggling fullscreen mode - if (machine.ui_input().pressed(IPT_OSD_1)) - { - for (auto curwin : osd_common_t::s_window_list) - std::static_pointer_cast(curwin)->toggle_full_screen(); - } - - auto window = osd_common_t::s_window_list.front(); - - //FIXME: on a per window basis - if (machine.ui_input().pressed(IPT_OSD_5)) - { - video_config.filter = !video_config.filter; - machine.ui().popup_time(1, "Filter %s", video_config.filter? "enabled":"disabled"); - } - - if (machine.ui_input().pressed(IPT_OSD_6)) - std::static_pointer_cast(window)->modify_prescale(-1); - - if (machine.ui_input().pressed(IPT_OSD_7)) - std::static_pointer_cast(window)->modify_prescale(1); - - if (machine.ui_input().pressed(IPT_OSD_8)) - window->renderer().record(); -} - -//============================================================ -// extract_video_config -//============================================================ - -void mac_osd_interface::extract_video_config() -{ - const char *stemp; - - // global options: extract the data - video_config.windowed = options().window(); - video_config.prescale = options().prescale(); - video_config.filter = options().filter(); - video_config.numscreens = options().numscreens(); - - // if we are in debug mode, never go full screen - if (machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) - video_config.windowed = true; - - // default to working video please - video_config.novideo = 0; - - // d3d options: extract the data - stemp = options().video(); - if (strcmp(stemp, "auto") == 0) - { - stemp = "opengl"; - } - - if (strcmp(stemp, OSDOPTVAL_NONE) == 0) - { - video_config.mode = VIDEO_MODE_SOFT; - video_config.novideo = 1; - - if (!emulator_info::standalone() && options().seconds_to_run() == 0) - osd_printf_warning("Warning: -video none doesn't make much sense without -seconds_to_run\n"); - } - - else if (strcmp(stemp, MACOPTVAL_OPENGL) == 0) - video_config.mode = VIDEO_MODE_OPENGL; - else if (strcmp(stemp, MACOPTVAL_BGFX) == 0) - { - video_config.mode = VIDEO_MODE_BGFX; - } - else - { - osd_printf_warning("Invalid video value %s; reverting to OpenGL\n", stemp); - video_config.mode = VIDEO_MODE_OPENGL; - } - - video_config.switchres = options().switch_res(); - video_config.waitvsync = options().wait_vsync(); - video_config.syncrefresh = options().sync_refresh(); - if (!video_config.waitvsync && video_config.syncrefresh) - { - osd_printf_warning("-syncrefresh specified without -waitvsync. Reverting to -nosyncrefresh\n"); - video_config.syncrefresh = 0; - } - - if (video_config.prescale < 1 || video_config.prescale > 8) - { - osd_printf_warning("Invalid prescale option, reverting to '1'\n"); - video_config.prescale = 1; - } - - // default to working video please - video_config.forcepow2texture = options().gl_force_pow2_texture(); - video_config.allowtexturerect = !(options().gl_no_texture_rect()); - video_config.vbo = options().gl_vbo(); - video_config.pbo = options().gl_pbo(); - video_config.glsl = options().gl_glsl(); - if ( video_config.glsl ) - { - int i; - video_config.glsl_filter = options().glsl_filter(); - video_config.glsl_shader_mamebm_num=0; - for(i=0; i0) - { - video_config.glsl_shader_mamebm[i] = (char *) malloc(strlen(stemp)+1); - strcpy(video_config.glsl_shader_mamebm[i], stemp); - video_config.glsl_shader_mamebm_num++; - } else { - video_config.glsl_shader_mamebm[i] = nullptr; - } - } - video_config.glsl_shader_scrn_num=0; - for(i=0; i0) - { - video_config.glsl_shader_scrn[i] = (char *) malloc(strlen(stemp)+1); - strcpy(video_config.glsl_shader_scrn[i], stemp); - video_config.glsl_shader_scrn_num++; - } else { - video_config.glsl_shader_scrn[i] = nullptr; - } - } - } else { - int i; - video_config.glsl_filter = 0; - video_config.glsl_shader_mamebm_num=0; - for(i=0; i MAX_VIDEO_WINDOWS) - { - osd_printf_warning("Invalid numscreens value %d; reverting to 1\n", video_config.numscreens); - video_config.numscreens = 1; - } -} - - -//============================================================ -// get_resolution -//============================================================ - -static void get_resolution(const char *defdata, const char *data, osd_window_config *config, int report_error) -{ - config->width = config->height = config->depth = config->refresh = 0; - if (strcmp(data, OSDOPTVAL_AUTO) == 0) - { - if (strcmp(defdata, OSDOPTVAL_AUTO) == 0) - return; - data = defdata; - } - - if (sscanf(data, "%dx%dx%d", &config->width, &config->height, &config->depth) < 2 && report_error) - osd_printf_error("Illegal resolution value = %s\n", data); - - const char * at_pos = strchr(data, '@'); - if (at_pos) - if (sscanf(at_pos + 1, "%d", &config->refresh) < 1 && report_error) - osd_printf_error("Illegal refresh rate in resolution value = %s\n", data); -} diff --git a/src/osd/mac/window.cpp b/src/osd/mac/window.cpp deleted file mode 100644 index 4056958b..00000000 --- a/src/osd/mac/window.cpp +++ /dev/null @@ -1,916 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Olivier Galibert, R. Belmont -//============================================================ -// -// window.cpp - Mac window handling -// -// Mac OSD by R. Belmont -// -//============================================================ - -// standard C headers -#include -#ifndef _MSC_VER -#include -#endif -#include -#include - -// MAME headers -#include "emu.h" -#include "emuopts.h" -#include "render.h" -#include "ui/uimain.h" - -// OSD headers - -#include "window.h" -#include "osdmac.h" -#include "modules/render/drawbgfx.h" -#include "modules/render/drawogl.h" -#include "modules/monitor/monitor_common.h" - -//============================================================ -// PARAMETERS -//============================================================ - -// these are arbitrary values since AFAIK there's no way to make X/SDL tell you -#define WINDOW_DECORATION_WIDTH (8) // should be more than plenty -#define WINDOW_DECORATION_HEIGHT (48) // title bar + bottom drag region - -// minimum window dimension -#define MIN_WINDOW_DIM 200 - -#define WMSZ_TOP (0) -#define WMSZ_BOTTOM (1) -#define WMSZ_BOTTOMLEFT (2) -#define WMSZ_BOTTOMRIGHT (3) -#define WMSZ_LEFT (4) -#define WMSZ_TOPLEFT (5) -#define WMSZ_TOPRIGHT (6) -#define WMSZ_RIGHT (7) - -// debugger -//static int in_background; - - -//============================================================ -// PROTOTYPES -//============================================================ - - -//============================================================ -// window_init -// (main thread) -//============================================================ - -bool mac_osd_interface::window_init() -{ - osd_printf_verbose("Enter macwindow_init\n"); - - // initialize the drawers - - switch (video_config.mode) - { - case VIDEO_MODE_BGFX: - renderer_bgfx::init(machine()); - break; - case VIDEO_MODE_OPENGL: - renderer_ogl::init(machine()); - break; - } - - // set up the window list - osd_printf_verbose("Leave macwindow_init\n"); - return true; -} - - -void mac_osd_interface::update_slider_list() -{ - for (auto window : osd_common_t::s_window_list) - { - // check if any window has dirty sliders - if (window->renderer().sliders_dirty()) - { - build_slider_list(); - return; - } - } -} - -void mac_osd_interface::build_slider_list() -{ - m_sliders.clear(); - - for (auto window : osd_common_t::s_window_list) - { - std::vector window_sliders = window->renderer().get_slider_list(); - m_sliders.insert(m_sliders.end(), window_sliders.begin(), window_sliders.end()); - } -} - -//============================================================ -// macwindow_exit -// (main thread) -//============================================================ - -void mac_osd_interface::window_exit() -{ - osd_printf_verbose("Enter macwindow_exit\n"); - - // free all the windows - while (!osd_common_t::s_window_list.empty()) - { - auto window = osd_common_t::s_window_list.front(); - - // Part of destroy removes the window from the list - window->destroy(); - } - - switch(video_config.mode) - { - case VIDEO_MODE_BGFX: - renderer_bgfx::exit(); - break; - case VIDEO_MODE_OPENGL: - renderer_ogl::exit(); - break; - default: - break; - } - osd_printf_verbose("Leave macwindow_exit\n"); -} - -void mac_window_info::capture_pointer() -{ - if (!m_mouse_captured) - { - m_mouse_captured = true; - } -} - -void mac_window_info::release_pointer() -{ - if (m_mouse_captured) - { - m_mouse_captured = false; - } -} - -void mac_window_info::hide_pointer() -{ - if (!m_mouse_hidden) - { - m_mouse_hidden = true; - } -} - -void mac_window_info::show_pointer() -{ - if (m_mouse_hidden) - { - m_mouse_hidden = false; - } -} - - -//============================================================ -// macwindow_resize -//============================================================ - -void mac_window_info::resize(int32_t width, int32_t height) -{ - osd_dim cd = get_size(); - - if (width != cd.width() || height != cd.height()) - { - // TODO: change window size here - renderer().notify_changed(); - } -} - - -//============================================================ -// notify_changed -//============================================================ - -void mac_window_info::notify_changed() -{ - renderer().notify_changed(); -} - - -//============================================================ -// toggle_full_screen -//============================================================ - -void mac_window_info::toggle_full_screen() -{ - // if we are in debug mode, never go full screen - if (machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) - return; - - // If we are going fullscreen (leaving windowed) remember our windowed size - if (!fullscreen()) - { - m_windowed_dim = get_size(); - } - - // reset UI to main menu - machine().ui().menu_reset(); - // kill off the drawers - renderer_reset(); - if (fullscreen() && video_config.switchres) - { - } - //SDL_DestroyWindow(platform_window()); - //set_platform_window(nullptr); - - downcast(machine().osd()).release_keys(); - - set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this())); - - // toggle the window mode - set_fullscreen(!fullscreen()); - - complete_create(); -} - -void mac_window_info::modify_prescale(int dir) -{ - int new_prescale = prescale(); - - if (dir > 0 && prescale() < 3) - new_prescale = prescale() + 1; - if (dir < 0 && prescale() > 1) - new_prescale = prescale() - 1; - - if (new_prescale != prescale()) - { - if (m_fullscreen && video_config.switchres) - { - complete_destroy(); - - m_prescale = new_prescale; - - complete_create(); - } - else - { - notify_changed(); - m_prescale = new_prescale; - } - machine().ui().popup_time(1, "Prescale %d", prescale()); - } -} - -//============================================================ -// update_cursor_state -// (main or window thread) -//============================================================ - -void mac_window_info::update_cursor_state() -{ - // do not do mouse capture if the debugger's enabled to avoid - // the possibility of losing control - if (!(machine().debug_flags & DEBUG_FLAG_OSD_ENABLED)) - { - bool should_hide_mouse = downcast(machine().osd()).should_hide_mouse(); - - if (!fullscreen() && !should_hide_mouse) - { - show_pointer(); - release_pointer(); - } - else - { - hide_pointer(); - capture_pointer(); - } - } -} - -int mac_window_info::xy_to_render_target(int x, int y, int *xt, int *yt) -{ - return renderer().xy_to_render_target(x, y, xt, yt); -} - -//============================================================ -// mac_window_info::window_init -// (main thread) -//============================================================ - -int mac_window_info::window_init() -{ - int result; - - // set the initial maximized state - // FIXME: Does not belong here - m_startmaximized = downcast(machine().options()).maximize(); - - create_target(); - - set_renderer(osd_renderer::make_for_type(video_config.mode, static_cast(this)->shared_from_this())); - - result = complete_create(); - - // handle error conditions - if (result == 1) - goto error; - - return 0; - -error: - destroy(); - return 1; -} - - -//============================================================ -// mac_window_info::complete_destroy -//============================================================ - -void mac_window_info::complete_destroy() -{ - // Release pointer grab and hide if needed - show_pointer(); - release_pointer(); - - if (fullscreen() && video_config.switchres) - { - } - - //SDL_DestroyWindow(platform_window()); - // release all keys ... - downcast(machine().osd()).release_keys(); -} - - -//============================================================ -// pick_best_mode -//============================================================ - -osd_dim mac_window_info::pick_best_mode() -{ -// int minimum_width, minimum_height, target_width, target_height; -// int i; -// int num; -// float size_score, best_score = 0.0f; - osd_dim ret(0,0); -#if 0 - // determine the minimum width/height for the selected target - target()->compute_minimum_size(minimum_width, minimum_height); - - // use those as the target for now - target_width = minimum_width * std::max(1, prescale()); - target_height = minimum_height * std::max(1, prescale()); - - // if we're not stretching, allow some slop on the minimum since we can handle it - { - minimum_width -= 4; - minimum_height -= 4; - } - - // FIXME: this should be provided by monitor ! - num = SDL_GetNumDisplayModes(monitor()->oshandle()); - - if (num == 0) - { - osd_printf_error("SDL: No modes available?!\n"); - exit(-1); - } - else - { - for (i = 0; i < num; ++i) - { - SDL_DisplayMode mode; - SDL_GetDisplayMode(monitor()->oshandle(), i, &mode); - - // compute initial score based on difference between target and current - size_score = 1.0f / (1.0f + abs((int32_t)mode.w - target_width) + abs((int32_t)mode.h - target_height)); - - // if the mode is too small, give a big penalty - if (mode.w < minimum_width || mode.h < minimum_height) - size_score *= 0.01f; - - // if mode is smaller than we'd like, it only scores up to 0.1 - if (mode.w < target_width || mode.h < target_height) - size_score *= 0.1f; - - // if we're looking for a particular mode, that's a winner - if (mode.w == m_win_config.width && mode.h == m_win_config.height) - size_score = 2.0f; - - // refresh adds some points - if (m_win_config.refresh) - size_score *= 1.0f / (1.0f + abs(m_win_config.refresh - mode.refresh_rate) / 10.0f); - - osd_printf_verbose("%4dx%4d@%2d -> %f\n", (int)mode.w, (int)mode.h, (int) mode.refresh_rate, (double) size_score); - - // best so far? - if (size_score > best_score) - { - best_score = size_score; - ret = osd_dim(mode.w, mode.h); - } - - } - } -#endif - return ret; -} - -//============================================================ -// sdlwindow_video_window_update -// (main thread) -//============================================================ - -void mac_window_info::update() -{ - osd_ticks_t event_wait_ticks; - - // adjust the cursor state - //sdlwindow_update_cursor_state(machine, window); - - update_cursor_state(); - - // if we're visible and running and not in the middle of a resize, draw - if (target() != nullptr) - { - int tempwidth, tempheight; - - // see if the games video mode has changed - target()->compute_minimum_size(tempwidth, tempheight); - if (osd_dim(tempwidth, tempheight) != m_minimum_dim) - { - m_minimum_dim = osd_dim(tempwidth, tempheight); - - if (!this->m_fullscreen) - { - //Don't resize window without user interaction; - //window_resize(blitwidth, blitheight); - } - else if (video_config.switchres) - { - osd_dim tmp = this->pick_best_mode(); - resize(tmp.width(), tmp.height()); - } - } - - if (video_config.waitvsync && video_config.syncrefresh) - event_wait_ticks = osd_ticks_per_second(); // block at most a second - else - event_wait_ticks = 0; - - if (m_rendered_event.wait(event_wait_ticks)) - { - const int update = 1; - - // ensure the target bounds are up-to-date, and then get the primitives - - render_primitive_list &primlist = *renderer().get_primitives(); - - // and redraw now - - // Check whether window has vector screens - - { - const screen_device *screen = screen_device_enumerator(machine().root_device()).byindex(index()); - if ((screen != nullptr) && (screen->screen_type() == SCREEN_TYPE_VECTOR)) - renderer().set_flags(osd_renderer::FLAG_HAS_VECTOR_SCREEN); - else - renderer().clear_flags(osd_renderer::FLAG_HAS_VECTOR_SCREEN); - } - - m_primlist = &primlist; - - // if no bitmap, just fill - if (m_primlist == nullptr) - { - } - // otherwise, render with our drawing system - else - { - if( video_config.perftest ) - measure_fps(update); - else - renderer().draw(update); - } - - /* all done, ready for next */ - m_rendered_event.set(); - } - } -} - - -//============================================================ -// complete_create -//============================================================ - -extern void *CreateMAMEWindow(const char *title, int x, int y, int w, int h, bool isFullscreen); -extern void *GetOSWindow(void *wincontroller); - -int mac_window_info::complete_create() -{ - osd_dim temp(0,0); - - // clear out original mode. Needed on OSX - if (fullscreen()) - { - // default to the current mode exactly - temp = monitor()->position_size().dim(); - - // if we're allowed to switch resolutions, override with something better - if (video_config.switchres) - temp = pick_best_mode(); - } - else if (m_windowed_dim.width() > 0) - { - // if we have a remembered size force the new window size to it - temp = m_windowed_dim; - } - else if (m_startmaximized) - { - temp = get_max_bounds(keepaspect()); - } - else - { - temp = get_min_bounds(keepaspect()); - } - - // create the window ..... - osd_printf_verbose("Enter mac_window_info::complete_create\n"); - - // get monitor work area for centering - osd_rect work = monitor()->usuable_position_size(); - - auto window = CreateMAMEWindow(title().c_str(), - work.left() + (work.width() - temp.width()) / 2, - work.top() + (work.height() - temp.height()) / 2, - temp.width(), temp.height(), fullscreen()); - - if (window == nullptr) - { - osd_printf_error("Window creation failed!\n"); - return 1; - } - - set_platform_window(window); - - // set main window - if (index() > 0) - { - for (auto w : osd_common_t::s_window_list) - { - if (w->index() == 0) - { - set_main_window(std::dynamic_pointer_cast(w)); - break; - } - } - } - else - { - // We must be the main window - set_main_window(shared_from_this()); - } - - // update monitor resolution after mode change to ensure proper pixel aspect - monitor()->refresh(); - if (fullscreen() && video_config.switchres) - monitor()->update_resolution(temp.width(), temp.height()); - - // initialize the drawing backend - if (renderer().create()) - { - osd_printf_verbose("Exiting mac_window_info::complete_create\n"); - return 1; - } - - return 0; -} - - -//============================================================ -// draw_video_contents -// (window thread) -//============================================================ - -void mac_window_info::measure_fps(int update) -{ - const unsigned long frames_skip4fps = 100; - static int64_t lastTime=0, sumdt=0, startTime=0; - static unsigned long frames = 0; - int64_t currentTime, t0; - double dt; - double tps; - osd_ticks_t tps_t; - - tps_t = osd_ticks_per_second(); - tps = (double) tps_t; - - t0 = osd_ticks(); - - renderer().draw(update); - - frames++; - currentTime = osd_ticks(); - if(startTime==0||frames==frames_skip4fps) - startTime=currentTime; - if( frames>=frames_skip4fps ) - sumdt+=currentTime-t0; - if( (currentTime-lastTime)>1L*osd_ticks_per_second() && frames>frames_skip4fps ) - { - dt = (double) (currentTime-startTime) / tps; // in decimale sec. - osd_printf_info("%6.2lfs, %4lu F, " - "avrg game: %5.2lf FPS %.2lf ms/f, " - "avrg video: %5.2lf FPS %.2lf ms/f, " - "last video: %5.2lf FPS %.2lf ms/f\n", - dt, frames-frames_skip4fps, - (double)(frames-frames_skip4fps)/dt, // avrg game fps - ( (currentTime-startTime) / ((frames-frames_skip4fps)) ) * 1000.0 / osd_ticks_per_second(), - (double)(frames-frames_skip4fps)/((double)(sumdt) / tps), // avrg vid fps - ( sumdt / ((frames-frames_skip4fps)) ) * 1000.0 / tps, - 1.0/((currentTime-t0) / osd_ticks_per_second()), // this vid fps - (currentTime-t0) * 1000.0 / tps - ); - lastTime = currentTime; - } -} - -int mac_window_info::wnd_extra_width() -{ - return m_fullscreen ? 0 : WINDOW_DECORATION_WIDTH; -} - -int mac_window_info::wnd_extra_height() -{ - return m_fullscreen ? 0 : WINDOW_DECORATION_HEIGHT; -} - - -//============================================================ -// constrain_to_aspect_ratio -// (window thread) -//============================================================ - -osd_rect mac_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int adjustment) -{ - int32_t extrawidth = wnd_extra_width(); - int32_t extraheight = wnd_extra_height(); - int32_t propwidth, propheight; - int32_t minwidth, minheight; - int32_t maxwidth, maxheight; - int32_t viswidth, visheight; - int32_t adjwidth, adjheight; - float pixel_aspect; - - // do not constrain aspect ratio for integer scaled views - if (target()->scale_mode() != SCALE_FRACTIONAL) - return rect; - - // get the pixel aspect ratio for the target monitor - pixel_aspect = monitor()->pixel_aspect(); - - // determine the proposed width/height - propwidth = rect.width() - extrawidth; - propheight = rect.height() - extraheight; - - // based on which edge we are adjusting, take either the width, height, or both as gospel - // and scale to fit using that as our parameter - switch (adjustment) - { - case WMSZ_BOTTOM: - case WMSZ_TOP: - target()->compute_visible_area(10000, propheight, pixel_aspect, target()->orientation(), propwidth, propheight); - break; - - case WMSZ_LEFT: - case WMSZ_RIGHT: - target()->compute_visible_area(propwidth, 10000, pixel_aspect, target()->orientation(), propwidth, propheight); - break; - - default: - target()->compute_visible_area(propwidth, propheight, pixel_aspect, target()->orientation(), propwidth, propheight); - break; - } - - // get the minimum width/height for the current layout - target()->compute_minimum_size(minwidth, minheight); - - // clamp against the absolute minimum - propwidth = std::max(propwidth, MIN_WINDOW_DIM); - propheight = std::max(propheight, MIN_WINDOW_DIM); - - // clamp against the minimum width and height - propwidth = std::max(propwidth, minwidth); - propheight = std::max(propheight, minheight); - - // clamp against the maximum (fit on one screen for full screen mode) - if (m_fullscreen) - { - maxwidth = monitor()->position_size().width() - extrawidth; - maxheight = monitor()->position_size().height() - extraheight; - } - else - { - maxwidth = monitor()->usuable_position_size().width() - extrawidth; - maxheight = monitor()->usuable_position_size().height() - extraheight; - - // further clamp to the maximum width/height in the window - if (m_win_config.width != 0) - maxwidth = std::min(maxwidth, m_win_config.width + extrawidth); - if (m_win_config.height != 0) - maxheight = std::min(maxheight, m_win_config.height + extraheight); - } - - // clamp to the maximum - propwidth = std::min(propwidth, maxwidth); - propheight = std::min(propheight, maxheight); - - // compute the visible area based on the proposed rectangle - target()->compute_visible_area(propwidth, propheight, pixel_aspect, target()->orientation(), viswidth, visheight); - - // compute the adjustments we need to make - adjwidth = (viswidth + extrawidth) - rect.width(); - adjheight = (visheight + extraheight) - rect.height(); - - // based on which corner we're adjusting, constrain in different ways - osd_rect ret(rect); - - switch (adjustment) - { - case WMSZ_BOTTOM: - case WMSZ_BOTTOMRIGHT: - case WMSZ_RIGHT: - ret = rect.resize(rect.width() + adjwidth, rect.height() + adjheight); - break; - - case WMSZ_BOTTOMLEFT: - ret = rect.move_by(-adjwidth, 0).resize(rect.width() + adjwidth, rect.height() + adjheight); - break; - - case WMSZ_LEFT: - case WMSZ_TOPLEFT: - case WMSZ_TOP: - ret = rect.move_by(-adjwidth, -adjheight).resize(rect.width() + adjwidth, rect.height() + adjheight); - break; - - case WMSZ_TOPRIGHT: - ret = rect.move_by(0, -adjheight).resize(rect.width() + adjwidth, rect.height() + adjheight); - break; -} - return ret; -} - - - -//============================================================ -// get_min_bounds -// (window thread) -//============================================================ - -osd_dim mac_window_info::get_min_bounds(int constrain) -{ - int32_t minwidth, minheight; - - //assert(GetCurrentThreadId() == window_threadid); - - // get the minimum target size - target()->compute_minimum_size(minwidth, minheight); - - // expand to our minimum dimensions - if (minwidth < MIN_WINDOW_DIM) - minwidth = MIN_WINDOW_DIM; - if (minheight < MIN_WINDOW_DIM) - minheight = MIN_WINDOW_DIM; - - // account for extra window stuff - minwidth += wnd_extra_width(); - minheight += wnd_extra_height(); - - // if we want it constrained, figure out which one is larger - if (constrain && target()->scale_mode() == SCALE_FRACTIONAL) - { - // first constrain with no height limit - osd_rect test1(0,0,minwidth,10000); - test1 = constrain_to_aspect_ratio(test1, WMSZ_BOTTOMRIGHT); - - // then constrain with no width limit - osd_rect test2(0,0,10000,minheight); - test2 = constrain_to_aspect_ratio(test2, WMSZ_BOTTOMRIGHT); - - // pick the larger - if (test1.width() > test2.width()) - { - minwidth = test1.width(); - minheight = test1.height(); - } - else - { - minwidth = test2.width(); - minheight = test2.height(); - } - } - - // remove extra window stuff - minwidth -= wnd_extra_width(); - minheight -= wnd_extra_height(); - - return osd_dim(minwidth, minheight); -} - -//============================================================ -// get_size -//============================================================ - -osd_dim mac_window_info::get_size() -{ - int w=0; int h=0; - // TODO: get window size from ObjC -// SDL_GetWindowSize(platform_window(), &w, &h); - return osd_dim(w,h); -} - - -//============================================================ -// get_max_bounds -// (window thread) -//============================================================ - -osd_dim mac_window_info::get_max_bounds(int constrain) -{ - //assert(GetCurrentThreadId() == window_threadid); - - // compute the maximum client area - // monitor()->refresh(); - osd_rect maximum = monitor()->usuable_position_size(); - - // clamp to the window's max - int tempw = maximum.width(); - int temph = maximum.height(); - if (m_win_config.width != 0) - { - int temp = m_win_config.width + wnd_extra_width(); - if (temp < maximum.width()) - tempw = temp; - } - if (m_win_config.height != 0) - { - int temp = m_win_config.height + wnd_extra_height(); - if (temp < maximum.height()) - temph = temp; - } - - maximum = maximum.resize(tempw, temph); - - // constrain to fit - if (constrain && target()->scale_mode() == SCALE_FRACTIONAL) - maximum = constrain_to_aspect_ratio(maximum, WMSZ_BOTTOMRIGHT); - - // remove extra window stuff - maximum = maximum.resize(maximum.width() - wnd_extra_width(), maximum.height() - wnd_extra_height()); - - return maximum.dim(); -} - -//============================================================ -// construction and destruction -//============================================================ - -mac_window_info::mac_window_info( - running_machine &a_machine, - int index, - std::shared_ptr a_monitor, - const osd_window_config *config) - : osd_window_t(a_machine, index, a_monitor, *config) - , m_startmaximized(0) - // Following three are used by input code to defer resizes - , m_minimum_dim(0, 0) - , m_windowed_dim(0, 0) - , m_rendered_event(0, 1) - , m_mouse_captured(false) - , m_mouse_hidden(false) -{ - //FIXME: these should be per_window in config-> or even better a bit set - m_fullscreen = !video_config.windowed; - m_prescale = video_config.prescale; - - m_windowed_dim = osd_dim(config->width, config->height); -} - -mac_window_info::~mac_window_info() -{ -} - - -//============================================================ -// osd_set_aggressive_input_focus -//============================================================ - -void osd_set_aggressive_input_focus(bool aggressive_focus) -{ - // dummy implementation for now -} diff --git a/src/osd/mac/window.h b/src/osd/mac/window.h deleted file mode 100644 index aed26c16..00000000 --- a/src/osd/mac/window.h +++ /dev/null @@ -1,114 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Olivier Galibert, R. Belmont -//============================================================ -// -// window.h - SDL window handling -// -// Mac OSD by R. Belmont -// -//============================================================ - -#ifndef __MACWINDOW__ -#define __MACWINDOW__ - -#include "osdmac.h" -#include "video.h" - -#include "modules/osdwindow.h" - -#include -#include -#include - -//============================================================ -// TYPE DEFINITIONS -//============================================================ - -class render_target; - -typedef uintptr_t HashT; - -#define OSDWORK_CALLBACK(name) void *name(void *param, int threadid) - -class mac_window_info : public osd_window_t -{ -public: - mac_window_info(running_machine &a_machine, int index, std::shared_ptr a_monitor, - const osd_window_config *config); - - ~mac_window_info(); - - int window_init(); - - void update() override; - void toggle_full_screen(); - void modify_prescale(int dir); - void resize(int32_t width, int32_t height); - void complete_destroy() override; - - void capture_pointer() override; - void release_pointer() override; - void show_pointer() override; - void hide_pointer() override; - - void notify_changed(); - - osd_dim get_size() override; - - int xy_to_render_target(int x, int y, int *xt, int *yt); - -private: - // window handle and info - int m_startmaximized; - - // dimensions - osd_dim m_minimum_dim; - osd_dim m_windowed_dim; - - // rendering info - osd_event m_rendered_event; - - //int m_extra_flags; - - // returns 0 on success, else 1 - int complete_create(); - -private: - int wnd_extra_width(); - int wnd_extra_height(); - osd_rect constrain_to_aspect_ratio(const osd_rect &rect, int adjustment); - osd_dim get_min_bounds(int constrain); - osd_dim get_max_bounds(int constrain); - void update_cursor_state(); - osd_dim pick_best_mode(); - void set_fullscreen(int afullscreen) { m_fullscreen = afullscreen; } - - // monitor info - bool m_mouse_captured; - bool m_mouse_hidden; - - void measure_fps(int update); -}; - -struct osd_draw_callbacks -{ - osd_renderer *(*create)(osd_window *window); -}; - -//============================================================ -// PROTOTYPES -//============================================================ - -//============================================================ -// PROTOTYPES - drawogl.c -//============================================================ - -int drawogl_init(running_machine &machine, osd_draw_callbacks *callbacks); - -//============================================================ -// PROTOTYPES - drawbgfx.c -//============================================================ - -int drawbgfx_init(running_machine &machine, osd_draw_callbacks *callbacks); - -#endif /* __MACWINDOW__ */ diff --git a/src/osd/mac/windowcontroller.h b/src/osd/mac/windowcontroller.h deleted file mode 100644 index 54f0b337..00000000 --- a/src/osd/mac/windowcontroller.h +++ /dev/null @@ -1,16 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont -//============================================================ -// -// windowcontroller.mm - our window/fullscreen manager -// -// Mac OSD by R. Belmont -// -//============================================================ - -#import -#import "oglview.h" - -@interface MAMEWindowController : NSWindowController - -@end diff --git a/src/osd/mac/windowcontroller.mm b/src/osd/mac/windowcontroller.mm deleted file mode 100644 index 3a4b046d..00000000 --- a/src/osd/mac/windowcontroller.mm +++ /dev/null @@ -1,137 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont -//============================================================ -// -// windowcontroller.mm - our window/fullscreen manager -// -// Mac OSD by R. Belmont -// -//============================================================ - -#import "windowcontroller.h" -#import "mamefswindow.h" - -@interface MAMEWindowController () -{ - MAMEFSWindow *_fullscreenWindow; - NSWindow* _standardWindow; -} -@end - -@implementation MAMEWindowController - -- (instancetype)initWithWindow:(NSWindow *)window -{ - self = [super initWithWindow:window]; - - if (self) - { - _fullscreenWindow = nil; - _standardWindow = window; - } - - return self; -} - -- (void) goFullscreen -{ - if(_fullscreenWindow) - { - return; - } - - _fullscreenWindow = [[MAMEFSWindow alloc] init]; - - NSRect viewRect = [_fullscreenWindow frame]; - [self.window.contentView setFrameSize: viewRect.size]; - [_fullscreenWindow setContentView:self.window.contentView]; - - _standardWindow = [self window]; - [_standardWindow orderOut:self]; - - [self setWindow:_fullscreenWindow]; - [_fullscreenWindow makeKeyAndOrderFront:self]; -} - -- (void) goWindow -{ - if(_fullscreenWindow == nil) - { - return; - } - - NSRect viewRect = [_standardWindow frame]; - [self.window.contentView setFrame:viewRect]; - - [self setWindow:_standardWindow]; - [[self window] setContentView:_fullscreenWindow.contentView]; - [[self window] makeKeyAndOrderFront:self]; - - _fullscreenWindow = nil; -} - - -- (void) keyDown:(NSEvent *)event -{ -// unichar c = [[event charactersIgnoringModifiers] characterAtIndex:0]; - [super keyDown:event]; -} - -- (NSWindow *) getWindow -{ - if(_fullscreenWindow == nil) - { - return _standardWindow; - } - - return _fullscreenWindow; -} -@end - -void MacPollInputs() -{ - NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny - untilDate:[NSDate distantPast] // do not wait for event - inMode:NSDefaultRunLoopMode - dequeue:YES]; - - if (event) - { - [NSApp sendEvent:event]; - [NSApp updateWindows]; - } -} - -void *GetOSWindow(void *wincontroller) -{ - MAMEWindowController *wc = (MAMEWindowController *)wincontroller; - - return [wc getWindow]; -} - -void *CreateMAMEWindow(const char *title, int x, int y, int w, int h, bool isFullscreen) -{ - NSRect bounds = NSMakeRect(x, y, w, h); - NSUInteger style = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask; - NSWindow *window = [NSWindow alloc]; - MAMEWindowController *controller = [MAMEWindowController alloc]; - - [window initWithContentRect:bounds - styleMask:style - backing:NSBackingStoreBuffered - defer:NO]; - [controller initWithWindow:window]; - NSString *nstitle = [[NSString alloc] initWithUTF8String:title]; - [window setTitle:nstitle]; - [nstitle release]; - if (isFullscreen) - { - [controller goFullscreen]; - } - else - { - [window makeKeyAndOrderFront:nil]; - } - - return (void *)controller; -} diff --git a/src/osd/modules/diagnostics/diagnostics_module.h b/src/osd/modules/diagnostics/diagnostics_module.h index 2f2c64b6..668d7f9d 100644 --- a/src/osd/modules/diagnostics/diagnostics_module.h +++ b/src/osd/modules/diagnostics/diagnostics_module.h @@ -26,15 +26,6 @@ public: // initializes crash diagnostics for MAME virtual int init_crash_diagnostics() = 0; - // starts the profiler - virtual void start_profiler(std::uint32_t max_seconds, std::uint8_t stack_depth) = 0; - - // stops the currently active profiler - virtual void stop_profiler() = 0; - - // prints the results of the profiling operation - virtual void print_profiler_results() = 0; - // Gets the instance of the diagnostic module static diagnostics_module* get_instance(); }; diff --git a/src/osd/modules/diagnostics/diagnostics_win32.cpp b/src/osd/modules/diagnostics/diagnostics_win32.cpp deleted file mode 100644 index b80bbdfc..00000000 --- a/src/osd/modules/diagnostics/diagnostics_win32.cpp +++ /dev/null @@ -1,1100 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles, Brad Hughes -//==================================================================== -// -// diagnostics_win32.cpp - Win32 implementation of diagnostic module -// -//==================================================================== - -#include "emu.h" -#include "diagnostics_module.h" - -#include "corestr.h" - -#if defined(OSD_WINDOWS) || defined(SDLMAME_WIN32) - -// standard windows headers -#include - -#include - -#include -#include - -#include -#include -#include - -#include "modules/lib/osdlib.h" - -#include - -// Typedefs for dynamically loaded functions -typedef BOOL (WINAPI *StackWalk64_fn)(DWORD, HANDLE, HANDLE, LPSTACKFRAME64, PVOID, PREAD_PROCESS_MEMORY_ROUTINE64, PFUNCTION_TABLE_ACCESS_ROUTINE64, PGET_MODULE_BASE_ROUTINE64, PTRANSLATE_ADDRESS_ROUTINE64); -typedef BOOL (WINAPI *SymInitialize_fn)(HANDLE, LPCTSTR, BOOL); -typedef PVOID (WINAPI *SymFunctionTableAccess64_fn)(HANDLE, DWORD64); -typedef DWORD64 (WINAPI *SymGetModuleBase64_fn)(HANDLE, DWORD64); -typedef BOOL (WINAPI *SymFromAddr_fn)(HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO); -typedef BOOL (WINAPI *SymGetLineFromAddr64_fn)(HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64); -typedef PIMAGE_SECTION_HEADER (WINAPI *ImageRvaToSection_fn)(PIMAGE_NT_HEADERS, PVOID, ULONG); -typedef PIMAGE_NT_HEADERS (WINAPI *ImageNtHeader_fn)(PVOID); -typedef VOID (WINAPI *RtlCaptureContext_fn)(PCONTEXT); - -class stack_walker -{ -public: - stack_walker(); - - uintptr_t ip() const { return m_stackframe.AddrPC.Offset; } - uintptr_t sp() const { return m_stackframe.AddrStack.Offset; } - uintptr_t frame() const { return m_stackframe.AddrFrame.Offset; } - - bool reset(); - void reset(CONTEXT &context, HANDLE thread); - bool unwind(); - -private: - HANDLE m_process; - HANDLE m_thread; - STACKFRAME64 m_stackframe; - CONTEXT m_context; - bool m_first; - - osd::dynamic_module::ptr m_dbghelp_dll; - osd::dynamic_module::ptr m_kernel32_dll; - - StackWalk64_fn m_stack_walk_64; - SymInitialize_fn m_sym_initialize; - SymFunctionTableAccess64_fn m_sym_function_table_access_64; - SymGetModuleBase64_fn m_sym_get_module_base_64; - RtlCaptureContext_fn m_rtl_capture_context; - - static bool s_initialized; -}; - - -class symbol_manager -{ -public: - // construction/destruction - symbol_manager(const char *argv0); - ~symbol_manager(); - - // getters - uintptr_t last_base() const { return m_last_base; } - - // core symbol lookup - const char *symbol_for_address(uintptr_t address); - const char *symbol_for_address(PVOID address) { return symbol_for_address(reinterpret_cast(address)); } - - // force symbols to be cached - void cache_symbols() { scan_file_for_address(0, true); } - - void reset_cache() { m_cache.clear(); } -private: - // internal helpers - bool query_system_for_address(uintptr_t address); - void scan_file_for_address(uintptr_t address, bool create_cache); - bool parse_sym_line(const char *line, uintptr_t &address, std::string &symbol); - bool parse_map_line(const char *line, uintptr_t &address, std::string &symbol); - void scan_cache_for_address(uintptr_t address); - void format_symbol(const char *name, uint32_t displacement, const char *filename = nullptr, int linenumber = 0); - - static uintptr_t get_text_section_base(ULONG &size); - - struct cache_entry - { - cache_entry(uintptr_t address, const char *symbol) : - m_address(address), m_name(symbol) { } - - uintptr_t m_address; - std::string m_name; - }; - std::vector> m_cache; - - std::string m_mapfile; - std::string m_symfile; - std::string m_buffer; - HANDLE m_process; - uintptr_t m_last_base; - uintptr_t m_text_base; - ULONG m_text_size; - - osd::dynamic_module::ptr m_dbghelp_dll; - - SymFromAddr_fn m_sym_from_addr; - SymGetLineFromAddr64_fn m_sym_get_line_from_addr_64; -}; - -class sampling_profiler -{ -public: - sampling_profiler(uint32_t max_seconds, uint8_t stack_depth); - ~sampling_profiler(); - - void start(); - void stop(); - - // void reset(); - void print_results(symbol_manager &symbols); - -private: - static DWORD WINAPI thread_entry(LPVOID lpParameter); - void thread_run(); - - static int CLIB_DECL compare_address(const void *item1, const void *item2); - static int CLIB_DECL compare_frequency(const void *item1, const void *item2); - - HANDLE m_target_thread; - - HANDLE m_thread; - DWORD m_thread_id; - volatile bool m_thread_exit; - - uint8_t m_stack_depth; - uint8_t m_entry_stride; - std::vector m_buffer; - uintptr_t * m_buffer_ptr; - uintptr_t * m_buffer_end; -}; - - -//************************************************************************** -// STACK WALKER -//************************************************************************** - -bool stack_walker::s_initialized = false; - -//------------------------------------------------- -// stack_walker - constructor -//------------------------------------------------- - -stack_walker::stack_walker() - : m_process(GetCurrentProcess()), - m_thread(GetCurrentThread()), - m_first(true) -{ - // zap the structs - memset(&m_stackframe, 0, sizeof(m_stackframe)); - memset(&m_context, 0, sizeof(m_context)); - - m_dbghelp_dll = osd::dynamic_module::open({ "dbghelp.dll" }); - m_kernel32_dll = osd::dynamic_module::open({ "kernel32.dll" }); - - m_stack_walk_64 = m_dbghelp_dll->bind("StackWalk64"); - m_sym_initialize = m_dbghelp_dll->bind("SymInitialize"); - m_sym_function_table_access_64 = m_dbghelp_dll->bind("SymFunctionTableAccess64"); - m_sym_get_module_base_64 = m_dbghelp_dll->bind("SymGetModuleBase64"); - m_rtl_capture_context = m_kernel32_dll->bind("RtlCaptureContext"); - - // initialize the symbols - if (!s_initialized && m_sym_initialize && m_stack_walk_64 && m_sym_function_table_access_64 && m_sym_get_module_base_64) - { - (*m_sym_initialize)(m_process, nullptr, TRUE); - s_initialized = true; - } -} - - -//------------------------------------------------- -// reset - set up a new context -//------------------------------------------------- - -bool stack_walker::reset() -{ - // set up the initial state - if (!m_rtl_capture_context) - return false; - (*m_rtl_capture_context)(&m_context); - m_thread = GetCurrentThread(); - m_first = true; - - // initialize the stackframe - memset(&m_stackframe, 0, sizeof(m_stackframe)); - m_stackframe.AddrPC.Mode = AddrModeFlat; - m_stackframe.AddrFrame.Mode = AddrModeFlat; - m_stackframe.AddrStack.Mode = AddrModeFlat; - - // pull architecture-specific fields from the context -#ifdef PTR64 - m_stackframe.AddrPC.Offset = m_context.Rip; - m_stackframe.AddrFrame.Offset = m_context.Rsp; - m_stackframe.AddrStack.Offset = m_context.Rsp; -#else - m_stackframe.AddrPC.Offset = m_context.Eip; - m_stackframe.AddrFrame.Offset = m_context.Ebp; - m_stackframe.AddrStack.Offset = m_context.Esp; -#endif - return true; -} - -void stack_walker::reset(CONTEXT &initial, HANDLE thread) -{ - // set up the initial state - m_context = initial; - m_thread = thread; - m_first = true; - - // initialize the stackframe - memset(&m_stackframe, 0, sizeof(m_stackframe)); - m_stackframe.AddrPC.Mode = AddrModeFlat; - m_stackframe.AddrFrame.Mode = AddrModeFlat; - m_stackframe.AddrStack.Mode = AddrModeFlat; - - // pull architecture-specific fields from the context -#ifdef PTR64 - m_stackframe.AddrPC.Offset = m_context.Rip; - m_stackframe.AddrFrame.Offset = m_context.Rsp; - m_stackframe.AddrStack.Offset = m_context.Rsp; -#else - m_stackframe.AddrPC.Offset = m_context.Eip; - m_stackframe.AddrFrame.Offset = m_context.Ebp; - m_stackframe.AddrStack.Offset = m_context.Esp; -#endif -} - - -//------------------------------------------------- -// unwind - unwind a single level -//------------------------------------------------- - -bool stack_walker::unwind() -{ - // if we were able to initialize, then we have everything we need - if (s_initialized) - { -#ifdef PTR64 - return (*m_stack_walk_64)(IMAGE_FILE_MACHINE_AMD64, m_process, m_thread, &m_stackframe, &m_context, nullptr, *m_sym_function_table_access_64, *m_sym_get_module_base_64, nullptr); -#else - return (*m_stack_walk_64)(IMAGE_FILE_MACHINE_I386, m_process, m_thread, &m_stackframe, &m_context, nullptr, *m_sym_function_table_access_64, *m_sym_get_module_base_64, nullptr); -#endif - } - - // otherwise, fake the first unwind, which will just return info from the context - else - { - bool result = m_first; - m_first = false; - return result; - } -} - - - -//************************************************************************** -// SYMBOL MANAGER -//************************************************************************** - -//------------------------------------------------- -// symbol_manager - constructor -//------------------------------------------------- - -symbol_manager::symbol_manager(const char *argv0) - : m_mapfile(argv0), - m_symfile(argv0), - m_process(GetCurrentProcess()), - m_last_base(0), - m_text_base(0) -{ -#ifdef __GNUC__ - // compute the name of the mapfile - int extoffs = m_mapfile.find_last_of('.'); - if (extoffs != -1) - m_mapfile.substr(0, extoffs); - m_mapfile.append(".map"); - - // and the name of the symfile - extoffs = m_symfile.find_last_of('.'); - if (extoffs != -1) - m_symfile = m_symfile.substr(0, extoffs); - m_symfile.append(".sym"); - - // figure out the base of the .text section - m_text_base = get_text_section_base(m_text_size); -#endif - - // expand the buffer to be decently large up front - m_buffer = string_format("%500s", ""); - - m_dbghelp_dll = osd::dynamic_module::open({ "dbghelp.dll" }); - - m_sym_from_addr = m_dbghelp_dll->bind("SymFromAddr"); - m_sym_get_line_from_addr_64 = m_dbghelp_dll->bind("SymGetLineFromAddr64"); -} - - -//------------------------------------------------- -// ~symbol_manager - destructor -//------------------------------------------------- - -symbol_manager::~symbol_manager() -{ -} - - -//------------------------------------------------- -// symbol_for_address - return a symbol by looking -// it up either in the cache or by scanning the -// file -//------------------------------------------------- - -const char *symbol_manager::symbol_for_address(uintptr_t address) -{ - // default the buffer - m_buffer.assign(" (not found)"); - m_last_base = 0; - - // first try to do it using system APIs - if (!query_system_for_address(address)) - { - // if that fails, scan the cache if we have one - if (!m_cache.empty()) - scan_cache_for_address(address); - - // or else try to open a sym/map file and find it there - else - scan_file_for_address(address, false); - } - return m_buffer.c_str(); -} - - -//------------------------------------------------- -// query_system_for_address - ask the system to -// look up our address -//------------------------------------------------- - -bool symbol_manager::query_system_for_address(uintptr_t address) -{ - // need at least the sym_from_addr API - if (!m_sym_from_addr) - return false; - - BYTE info_buffer[sizeof(SYMBOL_INFO) + 256] = { 0 }; - SYMBOL_INFO &info = *reinterpret_cast(&info_buffer[0]); - DWORD64 displacement; - - // even through the struct says TCHAR, we actually get back an ANSI string here - info.SizeOfStruct = sizeof(info); - info.MaxNameLen = sizeof(info_buffer) - sizeof(info); - if ((*m_sym_from_addr)(m_process, address, &displacement, &info)) - { - // if the address is within our image, but the symbol is at or below the text base, it's useless (lld produces these) - if (info.Address <= m_text_base && address > m_text_base && address < m_text_base + m_text_size) - return false; - - // try to get source info as well; again we are returned an ANSI string - IMAGEHLP_LINE64 lineinfo = { sizeof(lineinfo) }; - DWORD linedisp; - if (m_sym_get_line_from_addr_64 && (*m_sym_get_line_from_addr_64)(m_process, address, &linedisp, &lineinfo)) - format_symbol(info.Name, displacement, lineinfo.FileName, lineinfo.LineNumber); - else - format_symbol(info.Name, displacement); - - // set the last base - m_last_base = address - displacement; - return true; - } - return false; -} - - -//------------------------------------------------- -// scan_file_for_address - walk either the map -// or symbol files and find the best match for -// the given address, optionally creating a cache -// along the way -//------------------------------------------------- - -void symbol_manager::scan_file_for_address(uintptr_t address, bool create_cache) -{ - bool is_symfile = false; - FILE *srcfile = nullptr; - -#ifdef __GNUC__ - // see if we have a symbol file (gcc only) - srcfile = fopen(m_symfile.c_str(), "r"); - is_symfile = (srcfile != nullptr); -#endif - - // if not, see if we have a map file - if (srcfile == nullptr) - srcfile = fopen(m_mapfile.c_str(), "r"); - - // if not, fail - if (srcfile == nullptr) - return; - - // reset the best info - std::string best_symbol; - uintptr_t best_addr = 0; - - // parse the file, looking for valid entries - std::string symbol; - char line[1024]; - while (fgets(line, sizeof(line) - 1, srcfile)) - { - // parse the line looking for an interesting symbol - uintptr_t addr = 0; - bool valid = is_symfile ? parse_sym_line(line, addr, symbol) : parse_map_line(line, addr, symbol); - - // if we got one, see if this is the best - if (valid) - { - // if this is the best one so far, remember it - if (addr <= address && addr > best_addr) - { - best_addr = addr; - best_symbol = symbol; - } - - // also create a cache entry if we can - if (create_cache) - m_cache.push_back(std::make_unique(addr, symbol.c_str())); - } - } - - // close the file - fclose(srcfile); - - // format the symbol and remember the last base - format_symbol(best_symbol.c_str(), address - best_addr); - m_last_base = best_addr; -} - - -//------------------------------------------------- -// scan_cache_for_address - walk the cache to -// find the best match for the given address -//------------------------------------------------- - -void symbol_manager::scan_cache_for_address(uintptr_t address) -{ - // reset the best info - std::string best_symbol; - uintptr_t best_addr = 0; - - // walk the cache, looking for valid entries - for (auto &entry : m_cache) - - // if this is the best one so far, remember it - if (entry->m_address <= address && entry->m_address > best_addr) - { - best_addr = entry->m_address; - best_symbol = entry->m_name; - } - - // format the symbol and remember the last base - format_symbol(best_symbol.c_str(), address - best_addr); - m_last_base = best_addr; -} - - -//------------------------------------------------- -// parse_sym_line - parse a line from a sym file -// which is just the output of objdump -//------------------------------------------------- - -bool symbol_manager::parse_sym_line(const char *line, uintptr_t &address, std::string &symbol) -{ -#ifdef __GNUC__ - /* - 32-bit gcc symbol line: - [271778](sec 1)(fl 0x00)(ty 20)(scl 3) (nx 0) 0x007df675 line_to_symbol(char const*, unsigned int&, bool) - - 64-bit gcc symbol line: - [271775](sec 1)(fl 0x00)(ty 20)(scl 3) (nx 0) 0x00000000008dd1e9 line_to_symbol(char const*, unsigned long long&, bool) - */ - - // first look for a (ty) entry - const char *type = strstr(line, "(ty 20)"); - if (type == nullptr) - return false; - - // scan forward in the line to find the address - bool in_parens = false; - for (const char *chptr = type; *chptr != 0; chptr++) - { - // track open/close parentheses - if (*chptr == '(') - in_parens = true; - else if (*chptr == ')') - in_parens = false; - - // otherwise, look for an 0x address - else if (!in_parens && *chptr == '0' && chptr[1] == 'x') - { - // make sure we can get an address - void *temp; - if (sscanf(chptr, "0x%p", &temp) != 1) - return false; - address = m_text_base + reinterpret_cast(temp); - - // skip forward until we're past the space - while (*chptr != 0 && !isspace(*chptr)) - chptr++; - - // extract the symbol name - symbol.assign(strtrimspace(chptr)); - return (symbol.length() > 0); - } - } -#endif - return false; -} - - -//------------------------------------------------- -// parse_map_line - parse a line from a linker- -// generated map file -//------------------------------------------------- - -bool symbol_manager::parse_map_line(const char *line, uintptr_t &address, std::string &symbol) -{ -#ifdef __GNUC__ - /* - 32-bit gcc map line: - 0x0089cb00 nbmj9195_palette_r(_address_space const*, unsigned int) - - 64-bit gcc map line: - 0x0000000000961afc nbmj9195_palette_r(_address_space const*, unsigned int) - */ - - // find a matching start - if (strncmp(line, " 0x", 18) == 0) - { - // make sure we can get an address - void *temp; - if (sscanf(&line[16], "0x%p", &temp) != 1) - return false; - address = reinterpret_cast(temp); - - // skip forward until we're past the space - const char *chptr = &line[16]; - while (*chptr != 0 && !isspace(*chptr)) - chptr++; - - // extract the symbol name - symbol.assign(strtrimspace(chptr)); - return (symbol.length() > 0); - } -#endif - return false; -} - - -//------------------------------------------------- -// format_symbol - common symbol formatting -//------------------------------------------------- - -void symbol_manager::format_symbol(const char *name, uint32_t displacement, const char *filename, int linenumber) -{ - // start with the address and offset - m_buffer = string_format(" (%s", name); - if (displacement != 0) - m_buffer.append(string_format("+0x%04x", (uint32_t)displacement)); - - // append file/line if present - if (filename != nullptr) - m_buffer.append(string_format(", %s:%d", filename, linenumber)); - - // close up the string - m_buffer.append(")"); -} - - -//------------------------------------------------- -// get_text_section_base - figure out the base -// of the .text section -//------------------------------------------------- - -uintptr_t symbol_manager::get_text_section_base(ULONG &size) -{ - osd::dynamic_module::ptr m_dbghelp_dll = osd::dynamic_module::open({ "dbghelp.dll" }); - - ImageRvaToSection_fn image_rva_to_section = m_dbghelp_dll->bind("ImageRvaToSection"); - ImageNtHeader_fn image_nt_header = m_dbghelp_dll->bind("ImageNtHeader"); - - // start with the image base - auto base = reinterpret_cast(GetModuleHandleUni()); - assert(base != nullptr); - - // make sure we have the functions we need - if (image_nt_header && image_rva_to_section) - { - // get the NT header - PIMAGE_NT_HEADERS headers = (*image_nt_header)(base); - assert(headers != nullptr); - - // look ourself up (assuming we are in the .text section) - PIMAGE_SECTION_HEADER section = (*image_rva_to_section)(headers, base, reinterpret_cast(get_text_section_base) - reinterpret_cast(base)); - if (section != nullptr) - { - size = section->SizeOfRawData; - return reinterpret_cast(base) + section->VirtualAddress; - } - } - - // fallback to returning the image base (wrong) - size = 0; - return reinterpret_cast(base); -} - - - -//************************************************************************** -// SAMPLING PROFILER -//************************************************************************** - -//------------------------------------------------- -// sampling_profiler - constructor -//------------------------------------------------- - -sampling_profiler::sampling_profiler(uint32_t max_seconds, uint8_t stack_depth = 0) - : m_target_thread(nullptr), - m_thread(nullptr), - m_thread_id(0), - m_thread_exit(false), - m_stack_depth(stack_depth), - m_entry_stride(stack_depth + 2), - m_buffer(max_seconds * 1000 * m_entry_stride), - m_buffer_ptr(&m_buffer[0]), - m_buffer_end(&m_buffer[0] + max_seconds * 1000 * m_entry_stride) -{ -} - - -//------------------------------------------------- -// sampling_profiler - destructor -//------------------------------------------------- - -sampling_profiler::~sampling_profiler() -{ -} - - -////------------------------------------------------- -// start - begin gathering profiling information -//------------------------------------------------- - -void sampling_profiler::start() -{ - // do the dance to get a handle to ourself - BOOL const result = DuplicateHandle( - GetCurrentProcess(), GetCurrentThread(), - GetCurrentProcess(), &m_target_thread, - THREAD_GET_CONTEXT | THREAD_SUSPEND_RESUME | THREAD_QUERY_INFORMATION, FALSE, 0); - if (!result) - throw emu_fatalerror("sampling_profiler::start: Failed to get thread handle for main thread"); - - // reset the exit flag - m_thread_exit = false; - - // start the thread - m_thread = CreateThread(nullptr, 0, thread_entry, (LPVOID)this, 0, &m_thread_id); - if (!m_thread) - throw emu_fatalerror("sampling_profiler::start: Failed to create profiler thread"); - - // max out the priority - SetThreadPriority(m_thread, THREAD_PRIORITY_TIME_CRITICAL); -} - - -//------------------------------------------------- -// stop - stop gathering profiling information -//------------------------------------------------- - -void sampling_profiler::stop() -{ - // set the flag and wait a couple of seconds (max) - m_thread_exit = true; - WaitForSingleObject(m_thread, 2000); - - // regardless, close the handle - CloseHandle(m_thread); -} - - -//------------------------------------------------- -// compare_address - compare two entries by their -// bucket address -//------------------------------------------------- - -int CLIB_DECL sampling_profiler::compare_address(const void *item1, const void *item2) -{ - const auto *entry1 = reinterpret_cast(item1); - const auto *entry2 = reinterpret_cast(item2); - int mincount = std::min(entry1[0], entry2[0]); - - // sort in order of: bucket, caller, caller's caller, etc. - for (int index = 1; index <= mincount; index++) - if (entry1[index] != entry2[index]) - return entry1[index] - entry2[index]; - - // if we match to the end, sort by the depth of the stack - return entry1[0] - entry2[0]; -} - - -//------------------------------------------------- -// compare_frequency - compare two entries by -// their frequency of occurrence -//------------------------------------------------- - -int CLIB_DECL sampling_profiler::compare_frequency(const void *item1, const void *item2) -{ - const auto *entry1 = reinterpret_cast(item1); - const auto *entry2 = reinterpret_cast(item2); - - // sort by frequency, then by address - if (entry1[0] != entry2[0]) - return entry2[0] - entry1[0]; - return entry1[1] - entry2[1]; -} - - -//------------------------------------------------- -// print_results - output the results -//------------------------------------------------- - -void sampling_profiler::print_results(symbol_manager &symbols) -{ - // cache the symbols - symbols.cache_symbols(); - - // step 1: find the base of each entry - for (uintptr_t *current = &m_buffer[0]; current < m_buffer_ptr; current += m_entry_stride) - { - assert(current[0] >= 1 && current[0] < m_entry_stride); - - // convert the sampled PC to its function base as a bucket - symbols.symbol_for_address(current[1]); - current[1] = symbols.last_base(); - } - - // step 2: sort the results - qsort(&m_buffer[0], (m_buffer_ptr - &m_buffer[0]) / m_entry_stride, m_entry_stride * sizeof(uintptr_t), compare_address); - - // step 3: count and collapse unique entries - uint32_t total_count = 0; - for (uintptr_t *current = &m_buffer[0]; current < m_buffer_ptr; ) - { - int count = 1; - uintptr_t *scan; - for (scan = current + m_entry_stride; scan < m_buffer_ptr; scan += m_entry_stride) - { - if (compare_address(current, scan) != 0) - break; - scan[0] = 0; - count++; - } - current[0] = count; - total_count += count; - current = scan; - } - - // step 4: sort the results again, this time by frequency - qsort(&m_buffer[0], (m_buffer_ptr - &m_buffer[0]) / m_entry_stride, m_entry_stride * sizeof(uintptr_t), compare_frequency); - - // step 5: print the results - uint32_t num_printed = 0; - for (uintptr_t *current = &m_buffer[0]; current < m_buffer_ptr && num_printed < 30; current += m_entry_stride) - { - // once we hit 0 frequency, we're done - if (current[0] == 0) - break; - - // output the result - printf("%4.1f%% - %6d : %p%s\n", (double)current[0] * 100.0 / (double)total_count, (uint32_t)current[0], reinterpret_cast(current[1]), symbols.symbol_for_address(current[1])); - for (int index = 2; index < m_entry_stride; index++) - { - if (current[index] == 0) - break; - printf(" %p%s\n", reinterpret_cast(current[index]), symbols.symbol_for_address(current[index])); - } - printf("\n"); - num_printed++; - } - symbols.reset_cache(); -} - - -//------------------------------------------------- -// thread_entry - thread entry stub -//------------------------------------------------- - -DWORD WINAPI sampling_profiler::thread_entry(LPVOID lpParameter) -{ - reinterpret_cast(lpParameter)->thread_run(); - return 0; -} - - -//------------------------------------------------- -// thread_run - sampling thread -//------------------------------------------------- - -void sampling_profiler::thread_run() -{ - CONTEXT context; - memset(&context, 0, sizeof(context)); - - // loop until done - stack_walker walker; - while (!m_thread_exit && m_buffer_ptr < m_buffer_end) - { - // pause the main thread and get its context - SuspendThread(m_target_thread); - context.ContextFlags = CONTEXT_FULL; - GetThreadContext(m_target_thread, &context); - - // first entry is a count - uintptr_t *count = m_buffer_ptr++; - *count = 0; - - // iterate over the frames until we run out or hit an error - walker.reset(context, m_target_thread); - int frame; - for (frame = 0; frame <= m_stack_depth && walker.unwind(); frame++) - { - *m_buffer_ptr++ = walker.ip(); - *count += 1; - } - - // fill in any missing parts with nulls - for (; frame <= m_stack_depth; frame++) - *m_buffer_ptr++ = 0; - - // resume the thread - ResumeThread(m_target_thread); - - // sleep for 1ms - Sleep(1); - } -} - -/*----------------------------------------------------------------------------- - Diagnostics module for Win32 ------------------------------------------------------------------------------*/ - -class diagnostics_win32 : public diagnostics_module -{ - friend diagnostics_module* diagnostics_module::get_instance(); - -private: - std::unique_ptr m_symbols; - std::unique_ptr m_sampling_profiler; - LPTOP_LEVEL_EXCEPTION_FILTER m_pass_thru_filter; - - diagnostics_win32(): m_pass_thru_filter(nullptr) - { - } - -public: - int init_crash_diagnostics() override - { - ensure_symbols(); - - // set up exception handling - m_pass_thru_filter = SetUnhandledExceptionFilter(diagnostics_win32::exception_filter); - SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); - - return 0; - } - - void start_profiler(std::uint32_t max_seconds, std::uint8_t stack_depth) override - { - m_sampling_profiler = std::make_unique(max_seconds, stack_depth); - m_sampling_profiler->start(); - } - - void stop_profiler() override - { - if (m_sampling_profiler != nullptr) - { - m_sampling_profiler->stop(); - } - } - - void print_profiler_results() override - { - if (m_sampling_profiler != nullptr) - { - ensure_symbols(); - m_sampling_profiler->print_results(*m_symbols.get()); - } - } - -private: - //============================================================ - // exception_filter - //============================================================ - - static long __stdcall exception_filter(struct _EXCEPTION_POINTERS *info) - { - static const struct - { - DWORD code; - const char *string; - } exception_table[] = - { - { EXCEPTION_ACCESS_VIOLATION, "ACCESS VIOLATION" }, - { EXCEPTION_DATATYPE_MISALIGNMENT, "DATATYPE MISALIGNMENT" }, - { EXCEPTION_BREAKPOINT, "BREAKPOINT" }, - { EXCEPTION_SINGLE_STEP, "SINGLE STEP" }, - { EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "ARRAY BOUNDS EXCEEDED" }, - { EXCEPTION_FLT_DENORMAL_OPERAND, "FLOAT DENORMAL OPERAND" }, - { EXCEPTION_FLT_DIVIDE_BY_ZERO, "FLOAT DIVIDE BY ZERO" }, - { EXCEPTION_FLT_INEXACT_RESULT, "FLOAT INEXACT RESULT" }, - { EXCEPTION_FLT_INVALID_OPERATION, "FLOAT INVALID OPERATION" }, - { EXCEPTION_FLT_OVERFLOW, "FLOAT OVERFLOW" }, - { EXCEPTION_FLT_STACK_CHECK, "FLOAT STACK CHECK" }, - { EXCEPTION_FLT_UNDERFLOW, "FLOAT UNDERFLOW" }, - { EXCEPTION_INT_DIVIDE_BY_ZERO, "INTEGER DIVIDE BY ZERO" }, - { EXCEPTION_INT_OVERFLOW, "INTEGER OVERFLOW" }, - { EXCEPTION_PRIV_INSTRUCTION, "PRIVILEGED INSTRUCTION" }, - { EXCEPTION_IN_PAGE_ERROR, "IN PAGE ERROR" }, - { EXCEPTION_ILLEGAL_INSTRUCTION, "ILLEGAL INSTRUCTION" }, - { EXCEPTION_NONCONTINUABLE_EXCEPTION,"NONCONTINUABLE EXCEPTION" }, - { EXCEPTION_STACK_OVERFLOW, "STACK OVERFLOW" }, - { EXCEPTION_INVALID_DISPOSITION, "INVALID DISPOSITION" }, - { EXCEPTION_GUARD_PAGE, "GUARD PAGE VIOLATION" }, - { EXCEPTION_INVALID_HANDLE, "INVALID HANDLE" }, - { 0, "UNKNOWN EXCEPTION" } - }; - static int already_hit = 0; - int i; - - // if we're hitting this recursively, just exit - if (already_hit) - return EXCEPTION_CONTINUE_SEARCH; - already_hit = 1; - - // flush any debugging traces that were live - debugger_flush_all_traces_on_abnormal_exit(); - - // find our man - for (i = 0; exception_table[i].code != 0; i++) - if (info->ExceptionRecord->ExceptionCode == exception_table[i].code) - break; - - // print the exception type and address - fprintf(stderr, "\n-----------------------------------------------------\n"); - - auto diagnostics = downcast(get_instance()); - - fprintf(stderr, "Exception at EIP=%p%s: %s\n", info->ExceptionRecord->ExceptionAddress, - diagnostics->m_symbols->symbol_for_address((uintptr_t)info->ExceptionRecord->ExceptionAddress), exception_table[i].string); - - // for access violations, print more info - if (info->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) - fprintf(stderr, "While attempting to %s memory at %p\n", - info->ExceptionRecord->ExceptionInformation[0] ? "write" : "read", - (void *)info->ExceptionRecord->ExceptionInformation[1]); - - // print the state of the CPU - fprintf(stderr, "-----------------------------------------------------\n"); -#ifdef PTR64 - fprintf(stderr, "RAX=%p RBX=%p RCX=%p RDX=%p\n", - (void *)info->ContextRecord->Rax, - (void *)info->ContextRecord->Rbx, - (void *)info->ContextRecord->Rcx, - (void *)info->ContextRecord->Rdx); - fprintf(stderr, "RSI=%p RDI=%p RBP=%p RSP=%p\n", - (void *)info->ContextRecord->Rsi, - (void *)info->ContextRecord->Rdi, - (void *)info->ContextRecord->Rbp, - (void *)info->ContextRecord->Rsp); - fprintf(stderr, " R8=%p R9=%p R10=%p R11=%p\n", - (void *)info->ContextRecord->R8, - (void *)info->ContextRecord->R9, - (void *)info->ContextRecord->R10, - (void *)info->ContextRecord->R11); - fprintf(stderr, "R12=%p R13=%p R14=%p R15=%p\n", - (void *)info->ContextRecord->R12, - (void *)info->ContextRecord->R13, - (void *)info->ContextRecord->R14, - (void *)info->ContextRecord->R15); -#else - fprintf(stderr, "EAX=%p EBX=%p ECX=%p EDX=%p\n", - (void *)info->ContextRecord->Eax, - (void *)info->ContextRecord->Ebx, - (void *)info->ContextRecord->Ecx, - (void *)info->ContextRecord->Edx); - fprintf(stderr, "ESI=%p EDI=%p EBP=%p ESP=%p\n", - (void *)info->ContextRecord->Esi, - (void *)info->ContextRecord->Edi, - (void *)info->ContextRecord->Ebp, - (void *)info->ContextRecord->Esp); -#endif - - // reprint the actual exception address - fprintf(stderr, "-----------------------------------------------------\n"); - fprintf(stderr, "Stack crawl:\n"); - diagnostics->print_stacktrace(info->ContextRecord, GetCurrentThread()); - - // flush stderr, so the data is actually written when output is being redirected - fflush(stderr); - - // exit - return EXCEPTION_CONTINUE_SEARCH; - } - - void print_stacktrace(void* context, void* thread) - { - ensure_symbols(); - - // set up the stack walker - stack_walker walker; - - if (context != nullptr && thread != nullptr) - { - walker.reset(*static_cast(context), thread); - } - else - { - if (!walker.reset()) - return; - } - - // walk the stack - while (walker.unwind()) - fprintf( - stderr, - " %p: %p%s\n", - reinterpret_cast(walker.frame()), - reinterpret_cast(walker.ip()), - m_symbols == nullptr ? "" : m_symbols->symbol_for_address(walker.ip())); - } - - void ensure_symbols() - { - if (m_symbols == nullptr) - { - char exe_path[MAX_PATH]; - size_t len = GetModuleFileNameA(nullptr, exe_path, sizeof(exe_path)); - if (len == 0) - { - osd_printf_error("Failed to get the executable path.\n"); - fatalerror("Failed to get the executable path."); - } - - exe_path[len] = '\0'; - m_symbols = std::make_unique(exe_path); - } - - if (m_symbols == nullptr) - { - fatalerror("Could not initialize symbols."); - } - } -}; - -// Static accessor for the win32 diagnostic module -diagnostics_module * diagnostics_module::get_instance() -{ - static diagnostics_win32 s_instance; - return &s_instance; -} - -#endif diff --git a/src/osd/modules/diagnostics/none.cpp b/src/osd/modules/diagnostics/none.cpp index 4663e8aa..ad117e3a 100644 --- a/src/osd/modules/diagnostics/none.cpp +++ b/src/osd/modules/diagnostics/none.cpp @@ -19,18 +19,6 @@ public: { return 0; } - - void start_profiler(std::uint32_t max_seconds, std::uint8_t stack_depth) override - { - } - - void stop_profiler() override - { - } - - void print_profiler_results() override - { - } }; // Determine if diagnostics_none should be used based on OSD diff --git a/src/osd/windows/ledutil.cpp b/src/osd/windows/ledutil.cpp deleted file mode 100644 index f1976cd4..00000000 --- a/src/osd/windows/ledutil.cpp +++ /dev/null @@ -1,708 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles,Paul Priest -//============================================================ -// -// ledutil.cpp - Win32 example code that tracks changing -// outputs and updates the keyboard LEDs in response -// -//============================================================ -// -// This is sample code. To use it as a starting point, you -// should do the following: -// -// 1. Change the CLIENT_ID define to something unique. -// -// 2. Change the WINDOW_CLASS and WINDOW_NAME defines to -// something unique. -// -// 3. Delete all the code from the >8 snip 8< comment and -// downward. -// -// 4. Implement the following functions: -// -// output_startup - called at app init time -// output_shutdown - called before the app exits -// output_mame_start - called when MAME starts -// output_mame_stop - called when MAME exits -// output_set_state - called whenever state changes -// -//============================================================ - -// standard windows headers -#include -#include - -// standard C headers -#include -#include -#include -#include - -// MAME output header file -typedef int running_machine; -#include "osdcomm.h" -#include "modules/output/win32_output.h" - - -//============================================================ -// DEBUGGING -//============================================================ - -// note you need to compile as a console app to have any of -// these printfs show up -#define DEBUG_VERSION 0 - -#if DEBUG_VERSION -#define DEBUG_PRINTF(x) printf x -#else -#define DEBUG_PRINTF(x) -#endif - - -//============================================================ -// CONSTANTS -//============================================================ - -// unique client ID -#define CLIENT_ID (('M' << 24) | ('L' << 16) | ('E' << 8) | ('D' << 0)) - -// LED methods -#define LED_METHOD_PS2 0 -#define LED_METHOD_USB 1 - -// window parameters -#define WINDOW_CLASS TEXT("LEDSample") -#define WINDOW_NAME TEXT("LEDSample") - -// window styles -#define WINDOW_STYLE WS_OVERLAPPEDWINDOW -#define WINDOW_STYLE_EX 0 - -// Define the keyboard indicators. -// (Definitions borrowed from ntddkbd.h) - -#define IOCTL_KEYBOARD_SET_INDICATORS CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0002, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_KEYBOARD_QUERY_TYPEMATIC CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0008, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_KEYBOARD_QUERY_INDICATORS CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0010, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define KEYBOARD_SCROLL_LOCK_ON 1 -#define KEYBOARD_NUM_LOCK_ON 2 -#define KEYBOARD_CAPS_LOCK_ON 4 - - - -//============================================================ -// TYPE DEFINITIONS -//============================================================ - -struct KEYBOARD_INDICATOR_PARAMETERS -{ - USHORT UnitId; // Unit identifier. - USHORT LedFlags; // LED indicator state. -}; - - -struct id_map_entry -{ - id_map_entry * next; - const char * name; - WPARAM id; -}; - - - -//============================================================ -// GLOBAL VARIABLES -//============================================================ - -static int ledmethod; -static int original_state; -static int current_state; -static int pause_state; -static HANDLE hKbdDev; - -static HWND mame_target; -static HWND listener_hwnd; - -static id_map_entry * idmaplist; - -// 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 int create_window_class(void); -static LRESULT CALLBACK listener_window_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam); -static LRESULT handle_mame_start(WPARAM wparam, LPARAM lparam); -static LRESULT handle_mame_stop(WPARAM wparam, LPARAM lparam); -static LRESULT handle_copydata(WPARAM wparam, LPARAM lparam); -static void reset_id_to_outname_cache(void); -static const char *map_id_to_outname(WPARAM id); -static LRESULT handle_update_state(WPARAM wparam, LPARAM lparam); - -// these functions provide the meat -static void output_startup(const char *commandline); -static void output_mame_start(void); -static void output_set_state(const char *name, int32_t state); -static void output_mame_stop(void); -static void output_shutdown(void); - -static int led_get_state(void); -static void led_set_state(int state); - - -//============================================================ -// main -//============================================================ - -int main(int argc, char *argv[]) -{ - const char *arg = (argc > 1) ? argv[1] : ""; - int exitcode = 1; - HWND otherwnd; - MSG message; - int result; - - // see if there is another instance of us running - otherwnd = FindWindow(WINDOW_CLASS, WINDOW_NAME); - - // if the argument is "-kill", post a close message - if (strcmp(arg, "-kill") == 0) - { - if (otherwnd != nullptr) - PostMessage(otherwnd, WM_QUIT, 0, 0); - return (otherwnd != nullptr) ? 1 : 0; - } - - // if we had another instance, defer to it - if (otherwnd != nullptr) - return 0; - - // call the startup code - output_startup(arg); - - // create our window class - result = create_window_class(); - if (result != 0) - goto error; - - // create a window - listener_hwnd = CreateWindowEx( - WINDOW_STYLE_EX, - WINDOW_CLASS, - WINDOW_NAME, - WINDOW_STYLE, - 0, 0, - 1, 1, - nullptr, - nullptr, - GetModuleHandle(nullptr), - nullptr); - if (listener_hwnd == nullptr) - goto error; - - // allocate message ids - om_mame_start = RegisterWindowMessage(OM_MAME_START); - if (om_mame_start == 0) - goto error; - om_mame_stop = RegisterWindowMessage(OM_MAME_STOP); - if (om_mame_stop == 0) - goto error; - om_mame_update_state = RegisterWindowMessage(OM_MAME_UPDATE_STATE); - if (om_mame_update_state == 0) - goto error; - - om_mame_register_client = RegisterWindowMessage(OM_MAME_REGISTER_CLIENT); - if (om_mame_register_client == 0) - goto error; - om_mame_unregister_client = RegisterWindowMessage(OM_MAME_UNREGISTER_CLIENT); - if (om_mame_unregister_client == 0) - goto error; - om_mame_get_id_string = RegisterWindowMessage(OM_MAME_GET_ID_STRING); - if (om_mame_get_id_string == 0) - goto error; - - // see if MAME is already running - otherwnd = FindWindow(OUTPUT_WINDOW_CLASS, OUTPUT_WINDOW_NAME); - if (otherwnd != nullptr) - handle_mame_start((WPARAM)otherwnd, 0); - - // process messages - while (GetMessage(&message, nullptr, 0, 0)) - { - TranslateMessage(&message); - DispatchMessage(&message); - } - - // reset on the way out if still live - if (mame_target != nullptr) - handle_mame_stop((WPARAM)mame_target, 0); - exitcode = 0; - -error: - // call the shutdown code - output_shutdown(); - - return exitcode; -} - - -//============================================================ -// create_window_class -//============================================================ - -static int create_window_class(void) -{ - static int classes_created = FALSE; - - /* only do this once */ - if (!classes_created) - { - WNDCLASS wc = { 0 }; - - // initialize the description of the window class - wc.lpszClassName = WINDOW_CLASS; - wc.hInstance = GetModuleHandle(nullptr); - wc.lpfnWndProc = listener_window_proc; - - // register the class; fail if we can't - if (!RegisterClass(&wc)) - return 1; - classes_created = TRUE; - } - - return 0; -} - - -//============================================================ -// window_proc -//============================================================ - -static LRESULT CALLBACK listener_window_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam) -{ - // OM_MAME_START: register ourselves with the new MAME (first instance only) - if (message == om_mame_start) - return handle_mame_start(wparam, lparam); - - // OM_MAME_STOP: no need to unregister, just note that we've stopped caring and reset the LEDs - else if (message == om_mame_stop) - return handle_mame_stop(wparam, lparam); - - // OM_MAME_UPDATE_STATE: update the state of this item if we care - else if (message == om_mame_update_state) - return handle_update_state(wparam, lparam); - - // WM_COPYDATA: extract the string and create an ID map entry - else if (message == WM_COPYDATA) - return handle_copydata(wparam, lparam); - - // everything else is default - else - return DefWindowProc(wnd, message, wparam, lparam); -} - - -//============================================================ -// handle_mame_start -//============================================================ - -static LRESULT handle_mame_start(WPARAM wparam, LPARAM lparam) -{ - DEBUG_PRINTF(("mame_start (%08X)\n", (uint32_t)wparam)); - - // make this the targeted version of MAME - mame_target = (HWND)wparam; - - // initialize the LED states - output_mame_start(); - reset_id_to_outname_cache(); - - // register ourselves as a client - PostMessage(mame_target, om_mame_register_client, (WPARAM)listener_hwnd, CLIENT_ID); - - // get the game name - map_id_to_outname(0); - return 0; -} - - -//============================================================ -// handle_mame_stop -//============================================================ - -static LRESULT handle_mame_stop(WPARAM wparam, LPARAM lparam) -{ - DEBUG_PRINTF(("mame_stop (%08X)\n", (uint32_t)wparam)); - - // ignore if this is not the instance we care about - if (mame_target != (HWND)wparam) - return 1; - - // clear our target out - mame_target = nullptr; - reset_id_to_outname_cache(); - - // reset the LED states - output_mame_stop(); - return 0; -} - - -//============================================================ -// handle_copydata -//============================================================ - -static LRESULT handle_copydata(WPARAM wparam, LPARAM lparam) -{ - COPYDATASTRUCT *copydata = (COPYDATASTRUCT *)lparam; - copydata_id_string *data = (copydata_id_string *)copydata->lpData; - id_map_entry *entry; - char *string; - - DEBUG_PRINTF(("copydata (%08X)\n", (uint32_t)wparam)); - - // ignore requests we don't care about - if (mame_target != (HWND)wparam) - return 1; - - // allocate memory - entry = (id_map_entry *)malloc(sizeof(*entry)); - if (entry == nullptr) - return 0; - - string = (char *)malloc(strlen(data->string) + 1); - if (string == nullptr) - { - free(entry); - return 0; - } - - // if all allocations worked, make a new entry - entry->next = idmaplist; - entry->name = string; - entry->id = data->id; - - // copy the string and hook us into the list - strcpy(string, data->string); - idmaplist = entry; - - DEBUG_PRINTF((" id %d = '%s'\n", (int)entry->id, entry->name)); - - return 0; -} - - -//============================================================ -// reset_id_to_outname_cache -//============================================================ - -static void reset_id_to_outname_cache(void) -{ - // free our ID list - while (idmaplist != nullptr) - { - id_map_entry *temp = idmaplist; - idmaplist = temp->next; - free((void*)temp->name); - free(temp); - } -} - - -//============================================================ -// map_id_to_outname -//============================================================ - -static const char *map_id_to_outname(WPARAM id) -{ - id_map_entry *entry; - - // see if we have an entry in our map - for (entry = idmaplist; entry != nullptr; entry = entry->next) - if (entry->id == id) - return entry->name; - - // no entry yet; we have to ask - SendMessage(mame_target, om_mame_get_id_string, (WPARAM)listener_hwnd, id); - - // now see if we have the entry in our map - for (entry = idmaplist; entry != nullptr; entry = entry->next) - if (entry->id == id) - return entry->name; - - // if not, use an empty string - return ""; -} - - -//============================================================ -// handle_update_state -//============================================================ - -static LRESULT handle_update_state(WPARAM wparam, LPARAM lparam) -{ - DEBUG_PRINTF(("update_state: id=%d state=%d\n", (uint32_t)wparam, (uint32_t)lparam)); - output_set_state(map_id_to_outname(wparam), lparam); - return 0; -} - - -// -// END BOILERPLATE CODE -// -// ------------------------>8 snip 8<------------------------- -// -// BEGIN LED-SPECIFIC CODE -// - - -//============================================================ -// output_startup -//============================================================ - -static void output_startup(const char *commandline) -{ - // default to PS/2, override if USB is specified as a parameter - ledmethod = LED_METHOD_PS2; - if (commandline != nullptr && strcmp(commandline, "-usb") == 0) - ledmethod = LED_METHOD_USB; - - // output the method - switch (ledmethod) - { - case LED_METHOD_PS2: - DEBUG_PRINTF(("Using PS/2 method\n")); - break; - - case LED_METHOD_USB: - DEBUG_PRINTF(("Using USB method\n")); - break; - } -} - - -//============================================================ -// output_shutdown -//============================================================ - -static void output_shutdown(void) -{ - // nothing to do here -} - - -//============================================================ -// output_mame_start -//============================================================ - -static void output_mame_start(void) -{ - HRESULT error_number; - - // initialize the system based on the method - switch (ledmethod) - { - case LED_METHOD_PS2: - if (!DefineDosDevice(DDD_RAW_TARGET_PATH, TEXT("Kbd"), TEXT("\\Device\\KeyboardClass0"))) - { - error_number = GetLastError(); - fprintf(stderr, "Unable to open the keyboard device. (error %d)\n", (uint32_t)error_number); - return; - } - - hKbdDev = CreateFile(TEXT("\\\\.\\Kbd"), GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); - if (hKbdDev == INVALID_HANDLE_VALUE) - { - error_number = GetLastError(); - fprintf(stderr, "Unable to open the keyboard device. (error %d)\n", (uint32_t)error_number); - return; - } - break; - } - - // remember the initial LED states - original_state = current_state = led_get_state(); -} - - -//============================================================ -// output_mame_stop -//============================================================ - -static void output_mame_stop(void) -{ - int error_number = 0; - - // restore the initial LED states - led_set_state(original_state); - - switch (ledmethod) - { - case LED_METHOD_PS2: - if (!DefineDosDevice(DDD_REMOVE_DEFINITION, TEXT("Kbd"), nullptr)) - { - error_number = GetLastError(); - fprintf(stderr, "Unable to close the keyboard device. (error %d)\n", error_number); - return; - } - if (!CloseHandle(hKbdDev)) - { - error_number = GetLastError(); - fprintf(stderr, "Unable to close the keyboard device. (error %d)\n", error_number); - return; - } - break; - } -} - - -//============================================================ -// output_set_state -//============================================================ - -static void output_set_state(const char *outname, int32_t state) -{ - // look for pause state - if (strcmp(outname, "pause") == 0) - { - if (state) - { - pause_state = led_get_state(); - led_set_state(original_state); - } - else - { - original_state = led_get_state(); - led_set_state(pause_state); - } - } - // look for LED0/LED1/LED2 states and update accordingly - else if (strcmp(outname, "led0") == 0) - led_set_state((current_state & ~1) | (state & 1)); - else if (strcmp(outname, "led1") == 0) - led_set_state((current_state & ~2) | ((state & 1) << 1)); - else if (strcmp(outname, "led2") == 0) - led_set_state((current_state & ~4) | ((state & 1) << 2)); -} - - -//============================================================ -// led_get_state -//============================================================ - -static int led_get_state(void) -{ - int result = 0; - - switch (ledmethod) - { - case LED_METHOD_USB: - { - BYTE key_states[256]; - - // get the current state - GetKeyboardState(&key_states[0]); - - // set the numlock bit - result |= (key_states[VK_NUMLOCK] & 1); - result |= (key_states[VK_CAPITAL] & 1) << 1; - result |= (key_states[VK_SCROLL] & 1) << 2; - break; - } - - case LED_METHOD_PS2: - { - KEYBOARD_INDICATOR_PARAMETERS OutputBuffer; // Output buffer for DeviceIoControl - ULONG DataLength = sizeof(KEYBOARD_INDICATOR_PARAMETERS); - ULONG ReturnedLength; // Number of bytes returned in output buffer - - // Address first keyboard - OutputBuffer.UnitId = 0; - - DeviceIoControl(hKbdDev, IOCTL_KEYBOARD_QUERY_INDICATORS, - nullptr, 0, - &OutputBuffer, DataLength, - &ReturnedLength, nullptr); - - // Demangle lights to match 95/98 - if (OutputBuffer.LedFlags & KEYBOARD_NUM_LOCK_ON) result |= 0x1; - if (OutputBuffer.LedFlags & KEYBOARD_CAPS_LOCK_ON) result |= 0x2; - if (OutputBuffer.LedFlags & KEYBOARD_SCROLL_LOCK_ON) result |= 0x4; - break; - } - } - - return result; -} - - -//============================================================ -// led_set_state -//============================================================ - -static void led_set_state(int state) -{ - current_state = state; - - switch (ledmethod) - { - case LED_METHOD_USB: - { - static const BYTE vk[3] = { VK_NUMLOCK, VK_CAPITAL, VK_SCROLL }; - BYTE keyState[256]; - int k; - - GetKeyboardState((LPBYTE)&keyState); - for (k = 0; k < 3; k++) - { - if ((((state >> k) & 1) && !(keyState[vk[k]] & 1)) || - (!((state >> k) & 1) && (keyState[vk[k]] & 1))) - { - // Simulate a key press - keybd_event(vk[k], 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0); - - // Simulate a key release - keybd_event(vk[k], 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); - } - } - - keyState[VK_NUMLOCK] = (keyState[VK_NUMLOCK] & ~1) | ((state >> 0) & 1); - keyState[VK_CAPITAL] = (keyState[VK_CAPITAL] & ~1) | ((state >> 1) & 1); - keyState[VK_SCROLL] = (keyState[VK_SCROLL] & ~1) | ((state >> 2) & 1); - SetKeyboardState(&keyState[0]); - break; - } - - case LED_METHOD_PS2: - { - KEYBOARD_INDICATOR_PARAMETERS InputBuffer; // Input buffer for DeviceIoControl - ULONG DataLength = sizeof(KEYBOARD_INDICATOR_PARAMETERS); - ULONG ReturnedLength; // Number of bytes returned in output buffer - UINT LedFlags=0; - - // Demangle lights to match 95/98 - if (state & 0x1) LedFlags |= KEYBOARD_NUM_LOCK_ON; - if (state & 0x2) LedFlags |= KEYBOARD_CAPS_LOCK_ON; - if (state & 0x4) LedFlags |= KEYBOARD_SCROLL_LOCK_ON; - - // Address first keyboard - InputBuffer.UnitId = 0; - InputBuffer.LedFlags = LedFlags; - DeviceIoControl(hKbdDev, IOCTL_KEYBOARD_SET_INDICATORS, - &InputBuffer, DataLength, - nullptr, 0, - &ReturnedLength, nullptr); - break; - } - } -} diff --git a/src/osd/windows/video.cpp b/src/osd/windows/video.cpp deleted file mode 100644 index c277e4a0..00000000 --- a/src/osd/windows/video.cpp +++ /dev/null @@ -1,284 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -//============================================================ -// -// video.cpp - Win32 video handling -// -//============================================================ - -// standard windows headers -#include - -// MAME headers -#include "emu.h" -#include "emuopts.h" -#include "render.h" -#include "uiinput.h" - -// MAMEOS headers -#include "winmain.h" -#include "window.h" -#include "strconv.h" - -#include "modules/osdwindow.h" - -//============================================================ -// CONSTANTS -//============================================================ - - -//============================================================ -// GLOBAL VARIABLES -//============================================================ - -osd_video_config video_config; - - -//============================================================ -// PROTOTYPES -//============================================================ - -static void get_resolution(const char *defdata, const char *data, osd_window_config *config, int report_error); - - -//============================================================ -// video_init -//============================================================ - -// FIXME: Temporary workaround -static osd_window_config windows[MAX_VIDEO_WINDOWS]; // configuration data per-window - -bool windows_osd_interface::video_init() -{ - // extract data from the options - extract_video_config(); - - // initialize the window system so we can make windows - window_init(); - - // create the windows - auto &options = downcast(machine().options()); - for (int index = 0; index < video_config.numscreens; index++) - { - win_window_info::create(machine(), index, m_monitor_module->pick_monitor(options, index), &windows[index]); - } - - if (video_config.mode != VIDEO_MODE_NONE) - SetForegroundWindow(std::static_pointer_cast(osd_common_t::s_window_list.front())->platform_window()); - - return true; -} - -//============================================================ -// video_exit -//============================================================ - -void windows_osd_interface::video_exit() -{ - window_exit(); -} - -//============================================================ -// update -//============================================================ - -void windows_osd_interface::update(bool skip_redraw) -{ - osd_common_t::update(skip_redraw); - - // if we're not skipping this redraw, update all windows - if (!skip_redraw) - { -// profiler_mark(PROFILER_BLIT); - for (const auto &window : osd_common_t::s_window_list) - window->update(); -// profiler_mark(PROFILER_END); - } - - // if we're running, disable some parts of the debugger - if ((machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) != 0) - debugger_update(); -} - - -//============================================================ -// input_update -//============================================================ - -void windows_osd_interface::input_update() -{ - // poll the joystick values here - winwindow_process_events(machine(), true, false); - poll_input(machine()); - check_osd_inputs(); -} - -//============================================================ -// check_osd_inputs -//============================================================ - -void windows_osd_interface::check_osd_inputs() -{ - // check for toggling fullscreen mode - if (machine().ui_input().pressed(IPT_OSD_1)) - winwindow_toggle_full_screen(); - - // check for taking fullscreen snap - if (machine().ui_input().pressed(IPT_OSD_2)) - winwindow_take_snap(); - - // check for taking fullscreen video - if (machine().ui_input().pressed(IPT_OSD_3)) - winwindow_take_video(); - - // check for taking fullscreen video - if (machine().ui_input().pressed(IPT_OSD_4)) - winwindow_toggle_fsfx(); -} - - - -//============================================================ -// extract_video_config -//============================================================ - -void windows_osd_interface::extract_video_config() -{ - const char *stemp; - - // global options: extract the data - video_config.windowed = options().window(); - video_config.prescale = options().prescale(); - video_config.filter = options().filter(); - video_config.numscreens = options().numscreens(); - - // if we are in debug mode, never go full screen - if (machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) - video_config.windowed = TRUE; - - // per-window options: extract the data - const char *default_resolution = options().resolution(); - get_resolution(default_resolution, options().resolution(0), &windows[0], TRUE); - get_resolution(default_resolution, options().resolution(1), &windows[1], TRUE); - get_resolution(default_resolution, options().resolution(2), &windows[2], TRUE); - get_resolution(default_resolution, options().resolution(3), &windows[3], TRUE); - - // video options: extract the data - stemp = options().video(); - if (strcmp(stemp, "d3d") == 0) - video_config.mode = VIDEO_MODE_D3D; - else if (strcmp(stemp, "auto") == 0) - video_config.mode = VIDEO_MODE_D3D; - else if (strcmp(stemp, "gdi") == 0) - video_config.mode = VIDEO_MODE_GDI; - else if (strcmp(stemp, "bgfx") == 0) - video_config.mode = VIDEO_MODE_BGFX; - else if (strcmp(stemp, "none") == 0) - { - video_config.mode = VIDEO_MODE_NONE; - if (!emulator_info::standalone() && options().seconds_to_run() == 0) - osd_printf_warning("Warning: -video none doesn't make much sense without -seconds_to_run\n"); - } -#if (USE_OPENGL) - else if (strcmp(stemp, "opengl") == 0) - video_config.mode = VIDEO_MODE_OPENGL; -#endif - else - { - osd_printf_warning("Invalid video value %s; reverting to gdi\n", stemp); - video_config.mode = VIDEO_MODE_GDI; - } - video_config.waitvsync = options().wait_vsync(); - video_config.syncrefresh = options().sync_refresh(); - video_config.triplebuf = options().triple_buffer(); - video_config.switchres = options().switch_res(); - - if (video_config.prescale < 1 || video_config.prescale > 8) - { - osd_printf_warning("Invalid prescale option, reverting to '1'\n"); - video_config.prescale = 1; - } - #if (USE_OPENGL) - // default to working video please - video_config.forcepow2texture = options().gl_force_pow2_texture(); - video_config.allowtexturerect = !(options().gl_no_texture_rect()); - video_config.vbo = options().gl_vbo(); - video_config.pbo = options().gl_pbo(); - video_config.glsl = options().gl_glsl(); - if ( video_config.glsl ) - { - int i; - - video_config.glsl_filter = options().glsl_filter(); - - video_config.glsl_shader_mamebm_num=0; - - for(i=0; i0) - { - video_config.glsl_shader_mamebm[i] = (char *) malloc(strlen(stemp)+1); - strcpy(video_config.glsl_shader_mamebm[i], stemp); - video_config.glsl_shader_mamebm_num++; - } else { - video_config.glsl_shader_mamebm[i] = nullptr; - } - } - - video_config.glsl_shader_scrn_num=0; - - for(i=0; i0) - { - video_config.glsl_shader_scrn[i] = (char *) malloc(strlen(stemp)+1); - strcpy(video_config.glsl_shader_scrn[i], stemp); - video_config.glsl_shader_scrn_num++; - } else { - video_config.glsl_shader_scrn[i] = nullptr; - } - } - } else { - int i; - video_config.glsl_filter = 0; - video_config.glsl_shader_mamebm_num=0; - for(i=0; iwidth = config->height = config->depth = config->refresh = 0; - if (strcmp(data, OSDOPTVAL_AUTO) == 0) - { - if (strcmp(defdata, OSDOPTVAL_AUTO) == 0) - return; - data = defdata; - } - - if (sscanf(data, "%dx%dx%d", &config->width, &config->height, &config->depth) < 2 && report_error) - osd_printf_error("Illegal resolution value = %s\n", data); - - const char * at_pos = strchr(data, '@'); - if (at_pos) - if (sscanf(at_pos + 1, "%d", &config->refresh) < 1 && report_error) - osd_printf_error("Illegal refresh rate in resolution value = %s\n", data); -} diff --git a/src/osd/windows/video.h b/src/osd/windows/video.h deleted file mode 100644 index c012e42a..00000000 --- a/src/osd/windows/video.h +++ /dev/null @@ -1,29 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles, Vas Crabb -//============================================================ -// -// video.h - Win32 video helpers -// -//============================================================ -#ifndef MAME_OSD_WINDOWS_VIDEO_H -#define MAME_OSD_WINDOWS_VIDEO_H - -#pragma once - -#include "modules/osdhelper.h" - -#include - - -constexpr osd_rect RECT_to_osd_rect(RECT const &r) -{ - return osd_rect(r.left, r.top, r.right - r.left, r.bottom - r.top); -} - -inline RECT osd_rect_to_RECT(osd_rect const &r) -{ - RECT const result{ r.left(), r.top(), r.right(), r.bottom() }; - return result; -} - -#endif // MAME_OSD_WINDOWS_VIDEO_H diff --git a/src/osd/windows/window.cpp b/src/osd/windows/window.cpp deleted file mode 100644 index c5166d67..00000000 --- a/src/osd/windows/window.cpp +++ /dev/null @@ -1,1894 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -//============================================================ -// -// window.cpp - Win32 window handling -// -//============================================================ - -#define LOG_TEMP_PAUSE 0 - -// Needed for RAW Input -#define WM_INPUT 0x00FF - -// standard C headers -#include - -#include -#include -#include - -// MAME headers -#include "emu.h" -#include "uiinput.h" -#include "ui/uimain.h" - -// MAMEOS headers -#include "winmain.h" -#include "window.h" -#include "video.h" -#include "winutf8.h" - -#include "winutil.h" -#include "strconv.h" - -#include "modules/monitor/monitor_common.h" - -#include "modules/render/drawbgfx.h" -#include "modules/render/drawnone.h" -#include "modules/render/drawd3d.h" -#include "modules/render/drawgdi.h" -#if (USE_OPENGL) -#include "modules/render/drawogl.h" -#endif - -#define NOT_ALREADY_DOWN(x) (x & 0x40000000) == 0 -#define SCAN_CODE(x) ((x >> 16) & 0xff) -#define IS_EXTENDED(x) (0x01000000 & x) -#define MAKE_DI_SCAN(scan, isextended) (scan & 0x7f) | (isextended ? 0x80 : 0x00) -#define WINOSD(machine) downcast(&machine.osd()) - -//============================================================ -// PARAMETERS -//============================================================ - -// window styles -#define WINDOW_STYLE WS_OVERLAPPEDWINDOW -#define WINDOW_STYLE_EX 0 - -// debugger window styles -#define DEBUG_WINDOW_STYLE WS_OVERLAPPED -#define DEBUG_WINDOW_STYLE_EX 0 - -// full screen window styles -#define FULLSCREEN_STYLE WS_POPUP -#define FULLSCREEN_STYLE_EX WS_EX_TOPMOST - -// minimum window dimension -#define MIN_WINDOW_DIMX 200 -#define MIN_WINDOW_DIMY 50 - -// custom window messages -#define WM_USER_REDRAW (WM_USER + 2) -#define WM_USER_SET_FULLSCREEN (WM_USER + 3) -#define WM_USER_SET_MAXSIZE (WM_USER + 4) -#define WM_USER_SET_MINSIZE (WM_USER + 5) - - - -//============================================================ -// GLOBAL VARIABLES -//============================================================ - -static DWORD main_threadid; - - - -//============================================================ -// LOCAL VARIABLES -//============================================================ - -// event handling -static std::chrono::steady_clock::time_point last_event_check; - -static int ui_temp_pause; -static int ui_temp_was_paused; - -static HANDLE window_thread; -static DWORD window_threadid; - -static DWORD last_update_time; - -static HANDLE ui_pause_event; - -static bool s_aggressive_focus; - - - -//============================================================ -// PROTOTYPES -//============================================================ - - -static void create_window_class(); - -//============================================================ -// window_init -// (main thread) -//============================================================ - -bool windows_osd_interface::window_init() -{ - // get the main thread ID before anything else - main_threadid = GetCurrentThreadId(); - - // set up window class and register it - create_window_class(); - - // create an event to signal UI pausing - ui_pause_event = CreateEvent(nullptr, TRUE, FALSE, nullptr); - if (!ui_pause_event) - fatalerror("Failed to create pause event\n"); - - window_thread = GetCurrentThread(); - window_threadid = main_threadid; - - const int fallbacks[VIDEO_MODE_COUNT] = { - -1, // NONE -> no fallback - VIDEO_MODE_NONE, // GDI -> NONE - VIDEO_MODE_D3D, // BGFX -> D3D -#if (USE_OPENGL) - VIDEO_MODE_GDI, // OPENGL -> GDI -#endif - -1, // No SDL2ACCEL on Windows OSD -#if (USE_OPENGL) - VIDEO_MODE_OPENGL, // D3D -> OPENGL -#else - VIDEO_MODE_GDI, // D3D -> GDI -#endif - -1 // No SOFT on Windows OSD - }; - - int current_mode = video_config.mode; - while (current_mode != VIDEO_MODE_NONE) - { - bool error = false; - switch(current_mode) - { - case VIDEO_MODE_NONE: - error = renderer_none::init(machine()); - break; - case VIDEO_MODE_GDI: - error = renderer_gdi::init(machine()); - break; - case VIDEO_MODE_BGFX: - error = renderer_bgfx::init(machine()); - break; -#if (USE_OPENGL) - case VIDEO_MODE_OPENGL: - renderer_ogl::init(machine()); - break; -#endif - case VIDEO_MODE_SDL2ACCEL: - fatalerror("SDL2-Accel renderer unavailable on Windows OSD."); - break; - case VIDEO_MODE_D3D: - error = renderer_d3d9::init(machine()); - break; - case VIDEO_MODE_SOFT: - fatalerror("SDL1 renderer unavailable on Windows OSD."); - break; - default: - fatalerror("Unknown video mode."); - break; - } - if (error) - { - current_mode = fallbacks[current_mode]; - } - else - { - break; - } - } - video_config.mode = current_mode; - - return true; -} - -void windows_osd_interface::update_slider_list() -{ - for (const auto &window : osd_common_t::s_window_list) - { - // check if any window has dirty sliders - if (window->has_renderer() && window->renderer().sliders_dirty()) - { - build_slider_list(); - return; - } - } -} - -int windows_osd_interface::window_count() -{ - return osd_common_t::s_window_list.size(); -} - -void windows_osd_interface::build_slider_list() -{ - m_sliders.clear(); - - for (const auto &window : osd_common_t::s_window_list) - { - if (window->has_renderer()) - { - // take the sliders of the first window - std::vector window_sliders = window->renderer().get_slider_list(); - m_sliders.insert(m_sliders.end(), window_sliders.begin(), window_sliders.end()); - } - } -} - -void windows_osd_interface::add_audio_to_recording(const int16_t *buffer, int samples_this_frame) -{ - auto window = osd_common_t::s_window_list.front(); // We only record on the first window - if (window != nullptr) - { - window->renderer().add_audio_to_recording(buffer, samples_this_frame); - } -} - -//============================================================ -// winwindow_exit -// (main thread) -//============================================================ - -void windows_osd_interface::window_exit() -{ - assert(GetCurrentThreadId() == main_threadid); - - // if we hid the cursor during the emulation, show it - if (!osd_common_t::s_window_list.empty()) - osd_common_t::s_window_list.front()->show_pointer(); - - // free all the windows - while (!osd_common_t::s_window_list.empty()) - { - auto window = osd_common_t::s_window_list.front(); - - // Destroy removes it from the list also - window->destroy(); - } - - switch(video_config.mode) - { - case VIDEO_MODE_NONE: - renderer_none::exit(); - break; - case VIDEO_MODE_GDI: - renderer_gdi::exit(); - break; - case VIDEO_MODE_BGFX: - renderer_bgfx::exit(); - break; -#if (USE_OPENGL) - case VIDEO_MODE_OPENGL: - renderer_ogl::exit(); - break; -#endif - case VIDEO_MODE_D3D: - renderer_d3d9::exit(); - break; - default: - break; - } - - // kill the UI pause event - if (ui_pause_event) - CloseHandle(ui_pause_event); -} - - -win_window_info::win_window_info( - running_machine &machine, - int index, - std::shared_ptr monitor, - const osd_window_config *config) - : osd_window_t(machine, index, std::move(monitor), *config) - , m_init_state(0) - , m_startmaximized(0) - , m_isminimized(0) - , m_ismaximized(0) - , m_fullscreen_safe(0) - , m_aspect(0) - , m_targetview(0) - , m_targetorient(0) - , m_targetvismask(0) - , m_lastclicktime(std::chrono::steady_clock::time_point::min()) - , m_lastclickx(0) - , m_lastclicky(0) - , m_last_surrogate(0) - , m_attached_mode(false) -{ - m_non_fullscreen_bounds.left = 0; - m_non_fullscreen_bounds.top = 0; - m_non_fullscreen_bounds.right = 0; - m_non_fullscreen_bounds.bottom = 0; - - m_fullscreen = !video_config.windowed; - m_prescale = video_config.prescale; -} - -POINT win_window_info::s_saved_cursor_pos = { -1, -1 }; - -void win_window_info::capture_pointer() -{ - RECT bounds; - GetClientRect(platform_window(), &bounds); - ClientToScreen(platform_window(), &reinterpret_cast(&bounds)[0]); - ClientToScreen(platform_window(), &reinterpret_cast(&bounds)[1]); - ClipCursor(&bounds); -} - -void win_window_info::release_pointer() -{ - ClipCursor(nullptr); -} - -void win_window_info::hide_pointer() -{ - GetCursorPos(&s_saved_cursor_pos); - - while (ShowCursor(FALSE) >= -1) { } - ShowCursor(TRUE); -} - -void win_window_info::show_pointer() -{ - if (s_saved_cursor_pos.x != -1 || s_saved_cursor_pos.y != -1) - { - SetCursorPos(s_saved_cursor_pos.x, s_saved_cursor_pos.y); - s_saved_cursor_pos.x = s_saved_cursor_pos.y = -1; - } - - while (ShowCursor(TRUE) < 1) {}; - ShowCursor(FALSE); -} - -//============================================================ -// winwindow_process_events_periodic -// (main thread) -//============================================================ - -void winwindow_process_events_periodic(running_machine &machine) -{ - auto currticks = std::chrono::steady_clock::now(); - - assert(GetCurrentThreadId() == main_threadid); - - // update once every 1/8th of a second - if (currticks - last_event_check < std::chrono::milliseconds(1000 / 8)) - return; - winwindow_process_events(machine, true, false); -} - - - -//============================================================ -// is_mame_window -//============================================================ - -static bool is_mame_window(HWND hwnd) -{ - for (const auto &window : osd_common_t::s_window_list) - if (std::static_pointer_cast(window)->platform_window() == hwnd) - return true; - - return false; -} - -inline static BOOL handle_mouse_button(windows_osd_interface *osd, int button, int down, int x, int y) -{ - MouseButtonEventArgs args; - args.button = button; - args.keydown = down; - args.xpos = x; - args.ypos = y; - - bool handled = osd->handle_input_event(INPUT_EVENT_MOUSE_BUTTON, &args); - - // When in lightgun mode or mouse mode, the mouse click may be routed to the input system - // because the mouse interactions in the UI are routed from the video_window_proc below - // we need to make sure they aren't suppressed in these cases. - return handled && !osd->options().lightgun() && !osd->options().mouse(); -} - -inline static BOOL handle_keypress(windows_osd_interface *osd, int vkey, int down, int scancode, BOOL extended_key) -{ - KeyPressEventArgs args; - args.event_id = down ? INPUT_EVENT_KEYDOWN : INPUT_EVENT_KEYUP; - args.scancode = MAKE_DI_SCAN(scancode, extended_key); - args.vkey = vkey; - - return osd->handle_input_event(args.event_id, &args); -} - -//============================================================ -// winwindow_process_events -// (main thread) -//============================================================ - -void winwindow_process_events(running_machine &machine, bool ingame, bool nodispatch) -{ - MSG message; - - assert(GetCurrentThreadId() == main_threadid); - - // remember the last time we did this - last_event_check = std::chrono::steady_clock::now(); - - do - { - // if we are paused, lets wait for a message - if (ui_temp_pause > 0) - WaitMessage(); - - // loop over all messages in the queue - while (PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) - { - // prevent debugger windows from getting messages during reset - int dispatch = TRUE && !nodispatch; - - if (message.hwnd == nullptr || is_mame_window(message.hwnd)) - { - dispatch = TRUE; - switch (message.message) - { - // ignore keyboard messages - case WM_SYSKEYUP: - case WM_SYSKEYDOWN: - dispatch = FALSE; - break; - - // forward mouse button downs to the input system - case WM_LBUTTONDOWN: - dispatch = !handle_mouse_button(WINOSD(machine), 0, TRUE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); - break; - - case WM_RBUTTONDOWN: - dispatch = !handle_mouse_button(WINOSD(machine), 1, TRUE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); - break; - - case WM_MBUTTONDOWN: - dispatch = !handle_mouse_button(WINOSD(machine), 2, TRUE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); - break; - - case WM_XBUTTONDOWN: - dispatch = !handle_mouse_button(WINOSD(machine), 3, TRUE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); - break; - - // forward mouse button ups to the input system - case WM_LBUTTONUP: - dispatch = !handle_mouse_button(WINOSD(machine), 0, FALSE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); - break; - - case WM_RBUTTONUP: - dispatch = !handle_mouse_button(WINOSD(machine), 1, FALSE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); - break; - - case WM_MBUTTONUP: - dispatch = !handle_mouse_button(WINOSD(machine), 2, FALSE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); - break; - - case WM_XBUTTONUP: - dispatch = !handle_mouse_button(WINOSD(machine), 3, FALSE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); - break; - - case WM_KEYDOWN: - if (NOT_ALREADY_DOWN(message.lParam)) - dispatch = !handle_keypress(WINOSD(machine), message.wParam, TRUE, SCAN_CODE(message.lParam), IS_EXTENDED(message.lParam)); - break; - - case WM_KEYUP: - dispatch = !handle_keypress(WINOSD(machine), message.wParam, FALSE, SCAN_CODE(message.lParam), IS_EXTENDED(message.lParam)); - break; - } - } - - // dispatch if necessary - if (dispatch) - winwindow_dispatch_message(machine, &message); - } - } while (ui_temp_pause > 0); - - // update the cursor state after processing events - winwindow_update_cursor_state(machine); -} - - - -//============================================================ -// winwindow_dispatch_message -// (main thread) -//============================================================ - -void winwindow_dispatch_message(running_machine &machine, MSG *message) -{ - assert(GetCurrentThreadId() == main_threadid); - - // dispatch our special communication messages - switch (message->message) - { - // special case for quit - case WM_QUIT: - machine.schedule_exit(); - break; - - // everything else dispatches normally - default: - TranslateMessage(message); - DispatchMessage(message); - break; - } -} - - - -//============================================================ -// winwindow_take_snap -// (main thread) -//============================================================ - -void winwindow_take_snap() -{ - assert(GetCurrentThreadId() == main_threadid); - - // iterate over windows and request a snap - for (const auto &window : osd_common_t::s_window_list) - { - window->renderer().save(); - } -} - - - -//============================================================ -// winwindow_toggle_fsfx -// (main thread) -//============================================================ - -void winwindow_toggle_fsfx() -{ - assert(GetCurrentThreadId() == main_threadid); - - // iterate over windows and request a snap - for (const auto &window : osd_common_t::s_window_list) - { - window->renderer().toggle_fsfx(); - } -} - - - -//============================================================ -// winwindow_take_video -// (main thread) -//============================================================ - -void winwindow_take_video() -{ - assert(GetCurrentThreadId() == main_threadid); - - // iterate over windows and request a snap - for (const auto &window : osd_common_t::s_window_list) - { - window->renderer().record(); - } -} - - - -//============================================================ -// winwindow_toggle_full_screen -// (main thread) -//============================================================ - -void winwindow_toggle_full_screen() -{ - assert(GetCurrentThreadId() == main_threadid); - - // if we are in debug mode, never go full screen - for (const auto &window : osd_common_t::s_window_list) - if (window->machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) - return; - - // toggle the window mode - video_config.windowed = !video_config.windowed; - - // iterate over windows and toggle their fullscreen state - for (const auto &window : osd_common_t::s_window_list) - SendMessage(std::static_pointer_cast(window)->platform_window(), WM_USER_SET_FULLSCREEN, !video_config.windowed, 0); - - // Set the first window as foreground - SetForegroundWindow(std::static_pointer_cast(osd_common_t::s_window_list.front())->platform_window()); -} - - - -//============================================================ -// winwindow_has_focus -// (main or window thread) -//============================================================ - -bool winwindow_has_focus() -{ - // see if one of the video windows has focus - for (const auto &window : osd_common_t::s_window_list) - { - switch (std::static_pointer_cast(window)->focus()) - { - case win_window_focus::NONE: - break; - - case win_window_focus::THREAD: - if (s_aggressive_focus) - return true; - break; - - case win_window_focus::WINDOW: - return true; - - default: - throw false; - } - } - return false; -} - - -//============================================================ -// osd_set_aggressive_input_focus -//============================================================ - -void osd_set_aggressive_input_focus(bool aggressive_focus) -{ - s_aggressive_focus = aggressive_focus; -} - - -//============================================================ -// winwindow_update_cursor_state -// (main thread) -//============================================================ - -void winwindow_update_cursor_state(running_machine &machine) -{ - assert(GetCurrentThreadId() == main_threadid); - - // If no windows, just return - if (osd_common_t::s_window_list.empty()) - return; - - auto window = osd_common_t::s_window_list.front(); - - // if we should hide the mouse cursor, then do it - // rules are: - // 1. we must have focus before hiding the cursor - // 2. we also hide the cursor in full screen mode and when the window doesn't have a menu - // 3. we also hide the cursor in windowed mode if we're not paused and - // the input system requests it - if (winwindow_has_focus() && ( - (window->fullscreen() && !window->win_has_menu()) - || (!machine.paused() && WINOSD(machine)->should_hide_mouse()))) - { - // hide cursor - window->hide_pointer(); - - // clip pointer to game video window - window->capture_pointer(); - } - else - { - // show cursor - window->show_pointer(); - - // allow cursor to move freely - window->release_pointer(); - } -} - - - -//============================================================ -// winwindow_video_window_create -// (main thread) -//============================================================ - -void win_window_info::create(running_machine &machine, int index, std::shared_ptr monitor, const osd_window_config *config) -{ - assert(GetCurrentThreadId() == main_threadid); - - // allocate a new window object - auto window = std::make_shared(machine, index, monitor, config); - - // set main window - if (window->index() > 0) - { - for (const auto &w : osd_common_t::s_window_list) - { - if (w->index() == 0) - { - window->set_main_window(std::static_pointer_cast(w)); - break; - } - } - } - else - { - // We must be the main window - window->set_main_window(window); - } - - // see if we are safe for fullscreen - window->m_fullscreen_safe = TRUE; - for (const auto &win : osd_common_t::s_window_list) - if (win->monitor() == monitor.get()) - window->m_fullscreen_safe = FALSE; - - window->create_target(); - - // remember the current values in case they change - window->m_targetview = window->target()->view(); - window->m_targetorient = window->target()->orientation(); - window->m_targetlayerconfig = window->target()->layer_config(); - window->m_targetvismask = window->target()->visibility_mask(); - - // set the initial maximized state - window->m_startmaximized = downcast(machine.options()).maximize(); - - window->m_init_state = window->complete_create() ? -1 : 1; - - // handle error conditions - if (window->m_init_state == -1) - fatalerror("Unable to complete window creation\n"); -} - -//============================================================ -// winwindow_video_window_destroy -// (main thread) -//============================================================ - -void win_window_info::complete_destroy() -{ - assert(GetCurrentThreadId() == main_threadid); - - // destroy the window - if (platform_window() != nullptr) - DestroyWindow(platform_window()); -} - - - -//============================================================ -// winwindow_video_window_update -// (main thread) -//============================================================ - -void win_window_info::update() -{ - assert(GetCurrentThreadId() == main_threadid); - - // see if the target has changed significantly in window mode - unsigned const targetview = target()->view(); - int const targetorient = target()->orientation(); - render_layer_config const targetlayerconfig = target()->layer_config(); - u32 const targetvismask = target()->visibility_mask(); - if (targetview != m_targetview || targetorient != m_targetorient || targetlayerconfig != m_targetlayerconfig || targetvismask != m_targetvismask) - { - m_targetview = targetview; - m_targetorient = targetorient; - m_targetlayerconfig = targetlayerconfig; - m_targetvismask = targetvismask; - - // in window mode, reminimize/maximize - if (!fullscreen()) - { - if (m_isminimized) - SendMessage(platform_window(), WM_USER_SET_MINSIZE, 0, 0); - if (m_ismaximized) - SendMessage(platform_window(), WM_USER_SET_MAXSIZE, 0, 0); - } - } - - // if we're visible and running and not in the middle of a resize, draw - if (platform_window() != nullptr && target() != nullptr && has_renderer()) - { - bool got_lock = true; - - // only block if we're throttled - if (machine().video().throttled() || timeGetTime() - last_update_time > 250) - m_render_lock.lock(); - else - got_lock = m_render_lock.try_lock(); - - // only render if we were able to get the lock - if (got_lock) - { - render_primitive_list *primlist; - - // don't hold the lock; we just used it to see if rendering was still happening - m_render_lock.unlock(); - - // ensure the target bounds are up-to-date, and then get the primitives - primlist = renderer().get_primitives(); - - // post a redraw request with the primitive list as a parameter - last_update_time = timeGetTime(); - - if (attached_mode()) - { - HDC hdc = GetDC(platform_window()); - - m_primlist = primlist; - draw_video_contents(hdc, FALSE); - - ReleaseDC(platform_window(), hdc); - } - else - { - SendMessage(platform_window(), WM_USER_REDRAW, 0, (LPARAM)primlist); - } - } - } -} - -//============================================================ -// create_window_class -// (main thread) -//============================================================ - -static void create_window_class() -{ - static int classes_created = FALSE; - - assert(GetCurrentThreadId() == main_threadid); - - if (!classes_created) - { - WNDCLASS wc = { 0 }; - - // initialize the description of the window class - wc.lpszClassName = TEXT("MAME"); - wc.hInstance = GetModuleHandleUni(); - wc.lpfnWndProc = winwindow_video_window_proc_ui; - wc.hCursor = LoadCursor(nullptr, IDC_ARROW); - wc.hIcon = LoadIcon(wc.hInstance, MAKEINTRESOURCE(2)); - - UnregisterClass(wc.lpszClassName, wc.hInstance); - - // register the class; fail if we can't - if (!RegisterClass(&wc)) - fatalerror("Failed to create window class\n"); - classes_created = TRUE; - } -} - - - -//============================================================ -// winwindow_ui_pause -// (main thread) -//============================================================ - -void winwindow_ui_pause(running_machine &machine, int pause) -{ - int old_temp_pause = ui_temp_pause; - - assert(GetCurrentThreadId() == main_threadid); - - if (pause) - { - // if we're pausing, increment the pause counter - - // if we're the first to pause, we have to actually initiate it - if (ui_temp_pause++ == 0) - { - // only call mame_pause if we weren't already paused due to some external reason - ui_temp_was_paused = machine.paused(); - if (!ui_temp_was_paused) - machine.pause(); - - SetEvent(ui_pause_event); - } - } - else - { - // if we're resuming, decrement the pause counter - - // if we're the last to resume, unpause MAME - if (--ui_temp_pause == 0) - { - // but only do it if we were the ones who initiated it - if (!ui_temp_was_paused) - machine.resume(); - - ResetEvent(ui_pause_event); - } - } - - if (LOG_TEMP_PAUSE) - osd_printf_verbose("winwindow_ui_pause(): %d --> %d\n", old_temp_pause, ui_temp_pause); -} - - - -//============================================================ -// winwindow_ui_is_paused -//============================================================ - -int winwindow_ui_is_paused(running_machine &machine) -{ - return machine.paused() && ui_temp_was_paused; -} - - - -//============================================================ -// wnd_extra_width -// (window thread) -//============================================================ - -int win_window_info::wnd_extra_width() -{ - RECT temprect = { 100, 100, 200, 200 }; - if (fullscreen()) - return 0; - AdjustWindowRectEx(&temprect, WINDOW_STYLE, win_has_menu(), WINDOW_STYLE_EX); - return rect_width(&temprect) - 100; -} - - - -//============================================================ -// wnd_extra_height -// (window thread) -//============================================================ - -int win_window_info::wnd_extra_height() -{ - RECT temprect = { 100, 100, 200, 200 }; - if (fullscreen()) - return 0; - AdjustWindowRectEx(&temprect, WINDOW_STYLE, win_has_menu(), WINDOW_STYLE_EX); - return rect_height(&temprect) - 100; -} - - -//============================================================ -// complete_create -// (window thread) -//============================================================ - -int win_window_info::complete_create() -{ - RECT client; - int tempwidth, tempheight; - HMENU menu = nullptr; - HDC dc; - - assert(GetCurrentThreadId() == window_threadid); - - // get the monitor bounds - osd_rect monitorbounds = monitor()->position_size(); - - // create the window menu if needed - if (downcast(machine().options()).menu()) - { - if (win_create_menu(machine(), &menu)) - return 1; - } - - // are we in worker UI mode? - HWND hwnd; - const char *attach_window_name = downcast(machine().options()).attach_window(); - m_attached_mode = attach_window_name && *attach_window_name ? true : false; - if (m_attached_mode) - { - // we are in worker UI mode; either this value is an HWND or a window name - hwnd = (HWND)atoll(attach_window_name); - if (!hwnd) - hwnd = FindWindowEx(nullptr, nullptr, nullptr, osd::text::to_tstring(attach_window_name).c_str()); - } - else - { - // create the window, but don't show it yet - hwnd = win_create_window_ex_utf8( - fullscreen() ? FULLSCREEN_STYLE_EX : WINDOW_STYLE_EX, - "MAME", - title().c_str(), - fullscreen() ? FULLSCREEN_STYLE : WINDOW_STYLE, - monitorbounds.left() + 20, monitorbounds.top() + 20, - monitorbounds.left() + 100, monitorbounds.top() + 100, - nullptr,//(osd_common_t::s_window_list != nullptr) ? osd_common_t::s_window_list->m_hwnd : nullptr, - menu, - GetModuleHandleUni(), - nullptr); - } - - if (hwnd == nullptr) - return 1; - - set_platform_window(hwnd); - - // set a pointer back to us - if (!attached_mode()) - SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this); - - // skip the positioning stuff for '-video none' or '-attach_window' - if (video_config.mode == VIDEO_MODE_NONE || attached_mode()) - { - set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this())); - renderer().create(); - return 0; - } - - // adjust the window position to the initial width/height - tempwidth = (m_win_config.width != 0) ? m_win_config.width : 640; - tempheight = (m_win_config.height != 0) ? m_win_config.height : 480; - SetWindowPos(platform_window(), nullptr, monitorbounds.left() + 20, monitorbounds.top() + 20, - monitorbounds.left() + tempwidth + wnd_extra_width(), - monitorbounds.top() + tempheight + wnd_extra_height(), - SWP_NOZORDER); - - // maximum or minimize as appropriate - if (m_startmaximized) - maximize_window(); - else - minimize_window(); - adjust_window_position_after_major_change(); - - // show the window - if (!fullscreen() || m_fullscreen_safe) - { - set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this())); - if (renderer().create()) - return 1; - - ShowWindow(platform_window(), SW_SHOW); - } - - // clear the window - dc = GetDC(platform_window()); - GetClientRect(platform_window(), &client); - FillRect(dc, &client, (HBRUSH)GetStockObject(BLACK_BRUSH)); - ReleaseDC(platform_window(), dc); - return 0; -} - - - -//============================================================ -// winwindow_video_window_proc -// (window thread) -//============================================================ - -LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam) -{ - LONG_PTR ptr = GetWindowLongPtr(wnd, GWLP_USERDATA); - auto *window = (win_window_info *)ptr; - - // we may get called before SetWindowLongPtr is called - if (window) - { - assert(GetCurrentThreadId() == window_threadid); - window->update_minmax_state(); - } - - // handle a few messages - switch (message) - { - // paint: redraw the last bitmap - case WM_PAINT: - { - PAINTSTRUCT pstruct; - HDC hdc = BeginPaint(wnd, &pstruct); - window->draw_video_contents(hdc, true); - if (window->win_has_menu()) - DrawMenuBar(window->platform_window()); - EndPaint(wnd, &pstruct); - } - break; - - // non-client paint: punt if full screen - case WM_NCPAINT: - if (!window->fullscreen() || window->win_has_menu()) - return DefWindowProc(wnd, message, wparam, lparam); - break; - - // input: handle the raw input - case WM_INPUT: - downcast(window->machine().osd()).handle_input_event(INPUT_EVENT_RAWINPUT, &lparam); - break; - - // syskeys - ignore - case WM_SYSKEYUP: - case WM_SYSKEYDOWN: - break; - - // input events - case WM_MOUSEMOVE: - window->machine().ui_input().push_mouse_move_event(window->target(), GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)); - break; - - case WM_MOUSELEAVE: - window->machine().ui_input().push_mouse_leave_event(window->target()); - break; - - case WM_LBUTTONDOWN: - { - auto const ticks = std::chrono::steady_clock::now(); - window->machine().ui_input().push_mouse_down_event(window->target(), GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)); - - // check for a double-click - avoid overflow by adding times rather than subtracting - if (ticks < (window->m_lastclicktime + std::chrono::milliseconds(GetDoubleClickTime())) && - GET_X_LPARAM(lparam) >= window->m_lastclickx - 4 && GET_X_LPARAM(lparam) <= window->m_lastclickx + 4 && - GET_Y_LPARAM(lparam) >= window->m_lastclicky - 4 && GET_Y_LPARAM(lparam) <= window->m_lastclicky + 4) - { - window->m_lastclicktime = std::chrono::steady_clock::time_point::min(); - window->machine().ui_input().push_mouse_double_click_event(window->target(), GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)); - } - else - { - window->m_lastclicktime = ticks; - window->m_lastclickx = GET_X_LPARAM(lparam); - window->m_lastclicky = GET_Y_LPARAM(lparam); - } - } - break; - - case WM_LBUTTONUP: - window->machine().ui_input().push_mouse_up_event(window->target(), GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)); - break; - - case WM_RBUTTONDOWN: - window->machine().ui_input().push_mouse_rdown_event(window->target(), GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)); - break; - - case WM_RBUTTONUP: - window->machine().ui_input().push_mouse_rup_event(window->target(), GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)); - break; - - case WM_CHAR: - { - char16_t const ch = char16_t(wparam); - if ((0xd800 <= ch) && (0xdbff >= ch)) - { - window->m_last_surrogate = ch; - } - else if ((0xdc00 <= ch) && (0xdfff >= ch)) - { - if (window->m_last_surrogate) - { - char32_t const uch = 0x10000 + ((ch & 0x03ff) | ((window->m_last_surrogate & 0x03ff) << 10)); - window->machine().ui_input().push_char_event(window->target(), uch); - } - window->m_last_surrogate = 0; - } - else - { - window->machine().ui_input().push_char_event(window->target(), char32_t(ch)); - window->m_last_surrogate = 0; - } - } - break; - - case WM_UNICHAR: - if (UNICODE_NOCHAR == wparam) - return TRUE; - else - window->machine().ui_input().push_char_event(window->target(), char32_t(wparam)); - break; - - case WM_MOUSEWHEEL: - { - UINT ucNumLines = 3; // default - SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &ucNumLines, 0); - window->machine().ui_input().push_mouse_wheel_event(window->target(), GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam), GET_WHEEL_DELTA_WPARAM(wparam), ucNumLines); - } - break; - - // pause the system when we start a menu or resize - case WM_ENTERSIZEMOVE: - window->m_resize_state = RESIZE_STATE_RESIZING; - [[fallthrough]]; - case WM_ENTERMENULOOP: - winwindow_ui_pause(window->machine(), TRUE); - break; - - // unpause the system when we stop a menu or resize and force a redraw - case WM_EXITSIZEMOVE: - window->m_resize_state = RESIZE_STATE_PENDING; - [[fallthrough]]; - case WM_EXITMENULOOP: - winwindow_ui_pause(window->machine(), FALSE); - InvalidateRect(wnd, nullptr, FALSE); - break; - - // get min/max info: set the minimum window size - case WM_GETMINMAXINFO: - { - auto *minmax = (MINMAXINFO *)lparam; - minmax->ptMinTrackSize.x = MIN_WINDOW_DIMX; - minmax->ptMinTrackSize.y = MIN_WINDOW_DIMY; - break; - } - break; - - // sizing: constrain to the aspect ratio unless control key is held down - case WM_SIZING: - { - RECT *rect = (RECT *)lparam; - if (window->keepaspect() && (window->target()->scale_mode() == SCALE_FRACTIONAL) && !(GetAsyncKeyState(VK_CONTROL) & 0x8000)) - { - osd_rect r = window->constrain_to_aspect_ratio(RECT_to_osd_rect(*rect), wparam); - rect->top = r.top(); - rect->left = r.left(); - rect->bottom = r.bottom(); - rect->right = r.right(); - } - InvalidateRect(wnd, nullptr, FALSE); - } - break; - - // syscommands: catch win_start_maximized - case WM_SYSCOMMAND: - { - uint16_t cmd = wparam & 0xfff0; - - // prevent screensaver or monitor power events - if (cmd == SC_MONITORPOWER || cmd == SC_SCREENSAVE) - return 1; - - // most SYSCOMMANDs require us to invalidate the window - InvalidateRect(wnd, nullptr, FALSE); - - // handle maximize - if (cmd == SC_MAXIMIZE) - { - window->update_minmax_state(); - if (window->m_ismaximized) - window->minimize_window(); - else - window->maximize_window(); - break; - } - } - return DefWindowProc(wnd, message, wparam, lparam); - - case WM_ACTIVATE: - if (window->has_renderer()) - { - if (window->fullscreen()) - { - if ((wparam == WA_ACTIVE) || (wparam == WA_CLICKACTIVE)) - { - for (const auto &w : osd_common_t::s_window_list) - ShowWindow(std::static_pointer_cast(w)->platform_window(), SW_RESTORE); - } - else if ((wparam == WA_INACTIVE) && !is_mame_window(HWND(lparam))) - { - for (const auto &w : osd_common_t::s_window_list) - ShowWindow(std::static_pointer_cast(w)->platform_window(), SW_MINIMIZE); - } - } - - if ((wparam == WA_ACTIVE) || (wparam == WA_CLICKACTIVE)) - window->machine().ui_input().push_window_focus_event(window->target()); - else if (wparam == WA_INACTIVE) - window->machine().ui_input().push_window_defocus_event(window->target()); - } - return DefWindowProc(wnd, message, wparam, lparam); - - // close: cause MAME to exit - case WM_CLOSE: - window->machine().schedule_exit(); - break; - - // destroy: clean up all attached rendering bits and nullptr out our hwnd - case WM_DESTROY: - window->renderer_reset(); - window->set_platform_window(nullptr); - return DefWindowProc(wnd, message, wparam, lparam); - - // self redraw: draw ourself in a non-painty way - case WM_USER_REDRAW: - { - HDC hdc = GetDC(wnd); - - window->m_primlist = (render_primitive_list *)lparam; - window->draw_video_contents(hdc, false); - - ReleaseDC(wnd, hdc); - } - break; - - // fullscreen set - case WM_USER_SET_FULLSCREEN: - window->set_fullscreen(wparam); - break; - - // minimum size set - case WM_USER_SET_MINSIZE: - window->minimize_window(); - break; - - // maximum size set - case WM_USER_SET_MAXSIZE: - window->maximize_window(); - break; - - // maximum size set - case WM_DISPLAYCHANGE: - /* FIXME: The current codebase has an issue with setting aspect - * ratios correctly after display change. set_aspect should - * be set_forced_aspect and on a refresh this forced aspect should - * be preserved if set. If not, the standard aspect calculation - * should be used. - */ - window->monitor()->refresh(); - window->monitor()->update_resolution(LOWORD(lparam), HIWORD(lparam)); - break; - - // set focus: if we're not the primary window, switch back - // commented out ATM because this prevents us from resizing secondary windows -// case WM_SETFOCUS: -// if (window != osd_common_t::s_window_list && osd_common_t::s_window_list != nullptr) -// SetFocus(osd_common_t::s_window_list->m_hwnd); -// break; - - // everything else: defaults - default: - return DefWindowProc(wnd, message, wparam, lparam); - } - - return 0; -} - - - -//============================================================ -// draw_video_contents -// (window thread) -//============================================================ - -void win_window_info::draw_video_contents(HDC dc, bool update) -{ - assert(GetCurrentThreadId() == window_threadid); - - std::lock_guard lock(m_render_lock); - - // if we're iconic, don't bother - if (platform_window() != nullptr && !IsIconic(platform_window())) - { - // if no bitmap, just fill - if (m_primlist == nullptr) - { - RECT fill; - GetClientRect(platform_window(), &fill); - FillRect(dc, &fill, (HBRUSH)GetStockObject(BLACK_BRUSH)); - } - - // otherwise, render with our drawing system - else - { - // update DC - m_dc = dc; - renderer().draw(update); - } - } -} - - -//============================================================ -// constrain_to_aspect_ratio -// (window thread) -//============================================================ - -osd_rect win_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int adjustment) -{ - assert(GetCurrentThreadId() == window_threadid); - - int32_t extrawidth = wnd_extra_width(); - int32_t extraheight = wnd_extra_height(); - int32_t propwidth, propheight; - int32_t minwidth, minheight; - int32_t maxwidth, maxheight; - int32_t viswidth, visheight; - int32_t adjwidth, adjheight; - float pixel_aspect; - - auto monitor = monitor_from_rect(&rect); - - // Sometimes this gets called when monitors have already been torn down - // In that the case, just return the unmodified rect - if (monitor == nullptr) - return rect; - - // get the pixel aspect ratio for the target monitor - pixel_aspect = monitor->pixel_aspect(); - - // determine the proposed width/height - propwidth = rect.width() - extrawidth; - propheight = rect.height() - extraheight; - - // based on which edge we are adjusting, take either the width, height, or both as gospel - // and scale to fit using that as our parameter - switch (adjustment) - { - case WMSZ_BOTTOM: - case WMSZ_TOP: - target()->compute_visible_area(10000, propheight, pixel_aspect, target()->orientation(), propwidth, propheight); - break; - - case WMSZ_LEFT: - case WMSZ_RIGHT: - target()->compute_visible_area(propwidth, 10000, pixel_aspect, target()->orientation(), propwidth, propheight); - break; - - default: - target()->compute_visible_area(propwidth, propheight, pixel_aspect, target()->orientation(), propwidth, propheight); - break; - } - - // get the minimum width/height for the current layout - target()->compute_minimum_size(minwidth, minheight); - - // clamp against the maximum (fit on one screen for full screen mode) - if (fullscreen()) - { - maxwidth = monitor->position_size().width() - extrawidth; - maxheight = monitor->position_size().height() - extraheight; - } - else - { - maxwidth = monitor->usuable_position_size().width() - extrawidth; - maxheight = monitor->usuable_position_size().height() - extraheight; - - // clamp minimum against half of maximum to allow resizing very large targets (eg. SVG screen) - minwidth = std::min(minwidth, maxwidth / 2); - minheight = std::min(minheight, maxheight / 2); - - // clamp maximum to the maximum width/height in the window - if (m_win_config.width != 0) - maxwidth = std::min(maxwidth, m_win_config.width + extrawidth); - if (m_win_config.height != 0) - maxheight = std::min(maxheight, m_win_config.height + extraheight); - } - - // clamp against the absolute minimum - propwidth = std::max(propwidth, MIN_WINDOW_DIMX); - propheight = std::max(propheight, MIN_WINDOW_DIMY); - - // clamp against the minimum width and height - propwidth = std::max(propwidth, minwidth); - propheight = std::max(propheight, minheight); - - // clamp to the maximum - propwidth = std::min(propwidth, maxwidth); - propheight = std::min(propheight, maxheight); - - // compute the visible area based on the proposed rectangle - target()->compute_visible_area(propwidth, propheight, pixel_aspect, target()->orientation(), viswidth, visheight); - - // compute the adjustments we need to make - adjwidth = (viswidth + extrawidth) - rect.width(); - adjheight = (visheight + extraheight) - rect.height(); - - // based on which corner we're adjusting, constrain in different ways - osd_rect ret(rect); - - switch (adjustment) - { - case WMSZ_BOTTOM: - case WMSZ_BOTTOMRIGHT: - case WMSZ_RIGHT: - ret = rect.resize(rect.width() + adjwidth, rect.height() + adjheight); - break; - - case WMSZ_BOTTOMLEFT: - ret = rect.move_by(-adjwidth, 0).resize(rect.width() + adjwidth, rect.height() + adjheight); - break; - - case WMSZ_LEFT: - case WMSZ_TOPLEFT: - case WMSZ_TOP: - ret = rect.move_by(-adjwidth, -adjheight).resize(rect.width() + adjwidth, rect.height() + adjheight); - break; - - case WMSZ_TOPRIGHT: - ret = rect.move_by(0, -adjheight).resize(rect.width() + adjwidth, rect.height() + adjheight); - break; - } - return ret; -} - - - -//============================================================ -// get_min_bounds -// (window thread) -//============================================================ - -osd_dim win_window_info::get_min_bounds(int constrain) -{ - int32_t minwidth, minheight; - - //assert(GetCurrentThreadId() == window_threadid); - - // get the minimum target size - target()->compute_minimum_size(minwidth, minheight); - - // expand to our minimum dimensions - if (minwidth < MIN_WINDOW_DIMX) - minwidth = MIN_WINDOW_DIMX; - if (minheight < MIN_WINDOW_DIMY) - minheight = MIN_WINDOW_DIMY; - - // account for extra window stuff - minwidth += wnd_extra_width(); - minheight += wnd_extra_height(); - - // if we want it constrained, figure out which one is larger - if (constrain) - { - // first constrain with no height limit - osd_rect test1(0,0,minwidth,10000); - test1 = constrain_to_aspect_ratio(test1, WMSZ_BOTTOMRIGHT); - - // then constrain with no width limit - osd_rect test2(0,0,10000,minheight); - test2 = constrain_to_aspect_ratio(test2, WMSZ_BOTTOMRIGHT); - - // pick the larger - if (test1.width() > test2.width()) - { - minwidth = test1.width(); - minheight = test1.height(); - } - else - { - minwidth = test2.width(); - minheight = test2.height(); - } - } - - return osd_dim(minwidth, minheight); -} - - - -//============================================================ -// get_max_bounds -// (window thread) -//============================================================ - -osd_dim win_window_info::get_max_bounds(int constrain) -{ - //assert(GetCurrentThreadId() == window_threadid); - - // compute the maximum client area - //monitor()->refresh(); - osd_rect maximum = monitor()->usuable_position_size(); - - // clamp to the window's max - int tempw = maximum.width(); - int temph = maximum.height(); - if (m_win_config.width != 0) - { - int temp = m_win_config.width + wnd_extra_width(); - if (temp < maximum.width()) - tempw = temp; - } - if (m_win_config.height != 0) - { - int temp = m_win_config.height + wnd_extra_height(); - if (temp < maximum.height()) - temph = temp; - } - - maximum = maximum.resize(tempw, temph); - - // constrain to fit - if (constrain) - maximum = constrain_to_aspect_ratio(maximum, WMSZ_BOTTOMRIGHT); - - return maximum.dim(); -} - - - -//============================================================ -// update_minmax_state -// (window thread) -//============================================================ - -void win_window_info::update_minmax_state() -{ - assert(GetCurrentThreadId() == window_threadid); - - if (!fullscreen()) - { - RECT bounds; - - // compare the maximum bounds versus the current bounds - const bool keep_aspect = keepaspect(); - osd_dim minbounds = get_min_bounds(keep_aspect); - osd_dim maxbounds = get_max_bounds(keep_aspect); - GetWindowRect(platform_window(), &bounds); - - // if either the width or height matches, we were maximized - m_isminimized = (rect_width(&bounds) == minbounds.width()) || - (rect_height(&bounds) == minbounds.height()); - m_ismaximized = (rect_width(&bounds) == maxbounds.width()) || - (rect_height(&bounds) == maxbounds.height()); - } - else - { - m_isminimized = FALSE; - m_ismaximized = TRUE; - } -} - - - -//============================================================ -// minimize_window -// (window thread) -//============================================================ - -void win_window_info::minimize_window() -{ - assert(GetCurrentThreadId() == window_threadid); - - osd_dim newsize = get_min_bounds(keepaspect()); - - // get the window rect - RECT bounds; - GetWindowRect(platform_window(), &bounds); - - osd_rect newrect(bounds.left, bounds.top, newsize); - - - SetWindowPos(platform_window(), nullptr, newrect.left(), newrect.top(), newrect.width(), newrect.height(), SWP_NOZORDER); -} - - - -//============================================================ -// maximize_window -// (window thread) -//============================================================ - -void win_window_info::maximize_window() -{ - assert(GetCurrentThreadId() == window_threadid); - - osd_dim newsize = get_max_bounds(keepaspect()); - - // center within the work area - osd_rect work = monitor()->usuable_position_size(); - osd_rect newrect = osd_rect(work.left() + (work.width() - newsize.width()) / 2, - work.top() + (work.height() - newsize.height()) / 2, - newsize); - - SetWindowPos(platform_window(), nullptr, newrect.left(), newrect.top(), newrect.width(), newrect.height(), SWP_NOZORDER); -} - - - -//============================================================ -// adjust_window_position_after_major_change -// (window thread) -//============================================================ - -void win_window_info::adjust_window_position_after_major_change() -{ - RECT oldrect; - - assert(GetCurrentThreadId() == window_threadid); - - // get the current size - GetWindowRect(platform_window(), &oldrect); - osd_rect newrect = RECT_to_osd_rect(oldrect); - - // adjust the window size so the client area is what we want - if (!fullscreen()) - { - // constrain the existing size to the aspect ratio - if (keepaspect()) - newrect = constrain_to_aspect_ratio(newrect, WMSZ_BOTTOMRIGHT); - - // restrict the window to one monitor and avoid toolbars if possible - HMONITOR const nearest_monitor = MonitorFromWindow(platform_window(), MONITOR_DEFAULTTONEAREST); - if (NULL != nearest_monitor) - { - MONITORINFO info; - std::memset(&info, 0, sizeof(info)); - info.cbSize = sizeof(info); - if (GetMonitorInfo(nearest_monitor, &info)) - { - if (newrect.right() > info.rcWork.right) - newrect = newrect.move_by(info.rcWork.right - newrect.right(), 0); - if (newrect.bottom() > info.rcWork.bottom) - newrect = newrect.move_by(0, info.rcWork.bottom - newrect.bottom()); - if (newrect.left() < info.rcWork.left) - newrect = newrect.move_by(info.rcWork.left - newrect.left(), 0); - if (newrect.top() < info.rcWork.top) - newrect = newrect.move_by(0, info.rcWork.top - newrect.top()); - } - } - } - else - { - // in full screen, make sure it covers the primary display - std::shared_ptr monitor = monitor_from_rect(nullptr); - newrect = monitor->position_size(); - } - - // adjust the position if different - if (RECT_to_osd_rect(oldrect) != newrect) - SetWindowPos(platform_window(), fullscreen() ? HWND_TOPMOST : HWND_TOP, - newrect.left(), newrect.top(), - newrect.width(), newrect.height(), 0); - - // take note of physical window size (used for lightgun coordinate calculation) - if (index() == 0) - osd_printf_verbose("Physical width %d, height %d\n", newrect.width(), newrect.height()); -} - - -//============================================================ -// set_fullscreen -// (window thread) -//============================================================ - -void win_window_info::set_fullscreen(int fullscreen) -{ - assert(GetCurrentThreadId() == window_threadid); - - // if we're in the right state, punt - if (this->fullscreen() == fullscreen) - return; - m_fullscreen = fullscreen; - - // reset UI to main menu - // FIXME: this cause crash if called when running_machine.m_ui not yet initialised. e.g. when trying to show error/warning messagebox at startup (during auto-switch from full screen to windowed mode). - machine().ui().menu_reset(); - - // kill off the drawers - renderer_reset(); - - // hide ourself - ShowWindow(platform_window(), SW_HIDE); - - // configure the window if non-fullscreen - if (!fullscreen) - { - // adjust the style - SetWindowLong(platform_window(), GWL_STYLE, WINDOW_STYLE); - SetWindowLong(platform_window(), GWL_EXSTYLE, WINDOW_STYLE_EX); - SetWindowPos(platform_window(), nullptr, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); - - // force to the bottom, then back on top - SetWindowPos(platform_window(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - SetWindowPos(platform_window(), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - - // if we have previous non-fullscreen bounds, use those - if (m_non_fullscreen_bounds.right != m_non_fullscreen_bounds.left) - { - SetWindowPos(platform_window(), HWND_TOP, m_non_fullscreen_bounds.left, m_non_fullscreen_bounds.top, - rect_width(&m_non_fullscreen_bounds), rect_height(&m_non_fullscreen_bounds), - SWP_NOZORDER); - } - - // otherwise, set a small size and maximize from there - else - { - SetWindowPos(platform_window(), HWND_TOP, 0, 0, MIN_WINDOW_DIMX, MIN_WINDOW_DIMY, SWP_NOZORDER); - maximize_window(); - } - } - - // configure the window if fullscreen - else - { - // save the bounds - GetWindowRect(platform_window(), &m_non_fullscreen_bounds); - - // adjust the style - SetWindowLong(platform_window(), GWL_STYLE, FULLSCREEN_STYLE); - SetWindowLong(platform_window(), GWL_EXSTYLE, FULLSCREEN_STYLE_EX); - SetWindowPos(platform_window(), nullptr, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); - - // set topmost - SetWindowPos(platform_window(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - } - - // adjust the window to compensate for the change - adjust_window_position_after_major_change(); - - // show ourself - if (!this->fullscreen() || m_fullscreen_safe) - { - if (video_config.mode != VIDEO_MODE_NONE) - ShowWindow(platform_window(), SW_SHOW); - - set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this())); - if (renderer().create()) - exit(1); - } - - // ensure we're still adjusted correctly - adjust_window_position_after_major_change(); -} - - -//============================================================ -// focus -// (main or window thread) -//============================================================ - -win_window_focus win_window_info::focus() const -{ - HWND focuswnd = nullptr; - if (attached_mode()) - { - // if this window is in attached mode, we need to see if it has - // focus in its context; first find out what thread owns it - DWORD window_thread_id = GetWindowThreadProcessId(platform_window(), nullptr); - - // and then identify which window has focus in that thread's context - GUITHREADINFO gti; - gti.cbSize = sizeof(gti); - focuswnd = GetGUIThreadInfo(window_thread_id, >i) - ? gti.hwndFocus - : nullptr; - } - else - { - // life is simpler in non-attached mode - focuswnd = GetFocus(); - } - - if (focuswnd == platform_window()) - return win_window_focus::WINDOW; - else if (focuswnd) - return win_window_focus::THREAD; - else - return win_window_focus::NONE; -} - - -//============================================================ -// winwindow_qt_filter -//============================================================ - -#if (USE_QTDEBUG) -bool winwindow_qt_filter(void *message) -{ - MSG *msg = (MSG *)message; - - if(is_mame_window(msg->hwnd) || (!msg->hwnd && (msg->message >= WM_USER))) - { - LONG_PTR ptr; - if(msg->hwnd) // get the machine associated with this window - ptr = GetWindowLongPtr(msg->hwnd, GWLP_USERDATA); - else // any one will have to do - ptr = (LONG_PTR)osd_common_t::s_window_list.front().get(); - - winwindow_dispatch_message(((win_window_info *)ptr)->machine(), msg); - return true; - } - return false; -} -#endif diff --git a/src/osd/windows/window.h b/src/osd/windows/window.h deleted file mode 100644 index 6586420d..00000000 --- a/src/osd/windows/window.h +++ /dev/null @@ -1,184 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -//============================================================ -// -// window.h - Win32 window handling -// -//============================================================ -#ifndef MAME_OSD_WINDOWS_WINDOW_H -#define MAME_OSD_WINDOWS_WINDOW_H - -#pragma once - -#include "render.h" - -#include "modules/osdwindow.h" -#include "modules/lib/osdlib.h" - -#include -#include -#include -#include -#include -#include - -// standard windows headers -#include -#include -#include - - -//============================================================ -// CONSTANTS -//============================================================ - -#define RESIZE_STATE_NORMAL 0 -#define RESIZE_STATE_RESIZING 1 -#define RESIZE_STATE_PENDING 2 - - - -//============================================================ -// TYPE DEFINITIONS -//============================================================ - -enum class win_window_focus -{ - NONE, // neither this window nor this thread have focus - THREAD, // a window in this thread has focus - WINDOW // this window has focus directly -}; - - -class win_window_info : public osd_window_t -{ -public: - win_window_info(running_machine &machine, int index, std::shared_ptr monitor, const osd_window_config *config); - - bool attached_mode() const { return m_attached_mode; } - win_window_focus focus() const; - - void update() override; - - virtual bool win_has_menu() override - { - return GetMenu(platform_window()) ? true : false; - } - - virtual osd_dim get_size() override - { - RECT client; - GetClientRect(platform_window(), &client); - return osd_dim(client.right - client.left, client.bottom - client.top); - } - - void capture_pointer() override; - void release_pointer() override; - void show_pointer() override; - void hide_pointer() override; - - void complete_destroy() override; - - // static - - static void create(running_machine &machine, int index, std::shared_ptr monitor, const osd_window_config *config); - - // static callbacks - - static LRESULT CALLBACK video_window_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam); - - // member variables - - volatile int m_init_state; - - // window handle and info - RECT m_non_fullscreen_bounds; - int m_startmaximized; - int m_isminimized; - int m_ismaximized; - - // monitor info - int m_fullscreen_safe; - float m_aspect; - - // rendering info - std::mutex m_render_lock; - unsigned m_targetview; - int m_targetorient; - render_layer_config m_targetlayerconfig; - u32 m_targetvismask; - - // input info - std::chrono::steady_clock::time_point m_lastclicktime; - int m_lastclickx; - int m_lastclicky; - char16_t m_last_surrogate; - -private: - void draw_video_contents(HDC dc, bool update); - int complete_create(); - int wnd_extra_width(); - int wnd_extra_height(); - osd_rect constrain_to_aspect_ratio(const osd_rect &rect, int adjustment); - osd_dim get_min_bounds(int constrain); - osd_dim get_max_bounds(int constrain); - void update_minmax_state(); - void minimize_window(); - void maximize_window(); - void adjust_window_position_after_major_change(); - void set_fullscreen(int fullscreen); - - static POINT s_saved_cursor_pos; - - bool m_attached_mode; -}; - -struct osd_draw_callbacks -{ - osd_renderer *(*create)(osd_window *window); - void (*exit)(void); -}; - - -//============================================================ -// PROTOTYPES -//============================================================ - -bool winwindow_has_focus(void); -void winwindow_update_cursor_state(running_machine &machine); - -extern LRESULT CALLBACK winwindow_video_window_proc_ui(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam); - -void winwindow_toggle_full_screen(void); -void winwindow_take_snap(void); -void winwindow_take_video(void); -void winwindow_toggle_fsfx(void); - -void winwindow_process_events_periodic(running_machine &machine); -void winwindow_process_events(running_machine &machine, bool ingame, bool nodispatch); - -void winwindow_ui_pause(running_machine &machine, int pause); -int winwindow_ui_is_paused(running_machine &machine); - -void winwindow_dispatch_message(running_machine &machine, MSG *message); - -extern int win_create_menu(running_machine &machine, HMENU *menus); - - - -//============================================================ -// rect_width / rect_height -//============================================================ - -static inline int rect_width(const RECT *rect) -{ - return rect->right - rect->left; -} - - -static inline int rect_height(const RECT *rect) -{ - return rect->bottom - rect->top; -} - -#endif // MAME_OSD_WINDOWS_WINDOW_H diff --git a/src/osd/windows/winmain.cpp b/src/osd/windows/winmain.cpp deleted file mode 100644 index ba66380f..00000000 --- a/src/osd/windows/winmain.cpp +++ /dev/null @@ -1,566 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -//============================================================ -// -// winmain.cpp - Win32 main program -// -//============================================================ - -// MAME headers -#include "emu.h" -#include "emuopts.h" -#include "strconv.h" - -// MAMEOS headers -#include "winmain.h" -#include "window.h" -#include "winutf8.h" -#include "winutil.h" -#include "winfile.h" -#include "modules/diagnostics/diagnostics_module.h" -#include "modules/monitor/monitor_common.h" - -// standard C headers -#include -#include -#include -#include -#include -#include -#include -#include - -// standard windows headers -#include -#include -#include -#include -#include - -#define DEBUG_SLOW_LOCKS 0 - -//************************************************************************** -// MACROS -//************************************************************************** - -#ifdef UNICODE -#define UNICODE_POSTFIX "W" -#else -#define UNICODE_POSTFIX "A" -#endif - -//************************************************************************** -// TYPE DEFINITIONS -//************************************************************************** - -//============================================================ -// winui_output_error -//============================================================ - -class winui_output_error : public osd_output -{ -private: - struct ui_state - { - ~ui_state() - { - if (thread) - thread->join(); - } - - std::ostringstream buffer; - std::optional thread; - std::mutex mutex; - bool active; - }; - - static ui_state &get_state() - { - static ui_state state; - return state; - } - -public: - virtual void output_callback(osd_output_channel channel, const util::format_argument_pack &args) override - { - if (channel == OSD_OUTPUT_CHANNEL_ERROR) - { - // if we are in fullscreen mode, go to windowed mode - if ((video_config.windowed == 0) && !osd_common_t::s_window_list.empty()) - winwindow_toggle_full_screen(); - - auto &state(get_state()); - std::lock_guard guard(state.mutex); - util::stream_format(state.buffer, args); - if (!state.active) - { - if (state.thread) - { - state.thread->join(); - state.thread = std::nullopt; - } - state.thread.emplace( - [] () - { - auto &state(get_state()); - std::string message; - while (true) - { - { - std::lock_guard guard(state.mutex); - message = std::move(state.buffer).str(); - if (message.empty()) - { - state.active = false; - return; - } - state.buffer.str(std::string()); - } - // Don't hold any locks lock while calling MessageBox. - // Parent window isn't set because MAME could destroy - // the window out from under us on a fatal error. - win_message_box_utf8(nullptr, message.c_str(), emulator_info::get_appname(), MB_OK); - } - }); - state.active = true; - } - } - else - { - chain_output(channel, args); - } - } -}; - -//************************************************************************** -// GLOBAL VARIABLES -//************************************************************************** - -// this line prevents globbing on the command line -int _CRT_glob = 0; - -//************************************************************************** -// LOCAL VARIABLES -//************************************************************************** - -static int timeresult = !TIMERR_NOERROR; -static TIMECAPS timecaps; - -static running_machine *g_current_machine; - - -//************************************************************************** -// FUNCTION PROTOTYPES -//************************************************************************** - -static BOOL WINAPI control_handler(DWORD type); -static int is_double_click_start(int argc); - - -//************************************************************************** -// OPTIONS -//************************************************************************** - -// struct definitions -const options_entry windows_options::s_option_entries[] = -{ - // performance options - { nullptr, nullptr, OPTION_HEADER, "WINDOWS PERFORMANCE OPTIONS" }, - { WINOPTION_PRIORITY "(-15-1)", "0", OPTION_INTEGER, "thread priority for the main game thread; range from -15 to 1" }, - { WINOPTION_PROFILE, "0", OPTION_INTEGER, "enables profiling, specifying the stack depth to track" }, - - // video options - { nullptr, nullptr, OPTION_HEADER, "WINDOWS VIDEO OPTIONS" }, - { WINOPTION_MENU, "0", OPTION_BOOLEAN, "enables menu bar if available by UI implementation" }, - { WINOPTION_ATTACH_WINDOW, "", OPTION_STRING, "attach to arbitrary window" }, - - // post-processing options - { nullptr, nullptr, OPTION_HEADER, "DIRECT3D POST-PROCESSING OPTIONS" }, - { WINOPTION_HLSLPATH, "hlsl", OPTION_STRING, "path to HLSL support files" }, - { WINOPTION_HLSL_ENABLE";hlsl", "0", OPTION_BOOLEAN, "enable HLSL post-processing (PS3.0 required)" }, - { WINOPTION_HLSL_OVERSAMPLING, "0", OPTION_BOOLEAN, "enable HLSL oversampling" }, - { WINOPTION_HLSL_WRITE, OSDOPTVAL_AUTO, OPTION_STRING, "enable HLSL AVI writing (huge disk bandwidth suggested)" }, - { WINOPTION_HLSL_SNAP_WIDTH, "2048", OPTION_STRING, "HLSL upscaled-snapshot width" }, - { WINOPTION_HLSL_SNAP_HEIGHT, "1536", OPTION_STRING, "HLSL upscaled-snapshot height" }, - { WINOPTION_SHADOW_MASK_TILE_MODE, "0", OPTION_INTEGER, "shadow mask tile mode (0 for screen based, 1 for source based)" }, - { WINOPTION_SHADOW_MASK_ALPHA";fs_shadwa(0.0-1.0)", "0.0", OPTION_FLOAT, "shadow mask alpha-blend value (1.0 is fully blended, 0.0 is no mask)" }, - { WINOPTION_SHADOW_MASK_TEXTURE";fs_shadwt(0.0-1.0)", "shadow-mask.png", OPTION_STRING, "shadow mask texture name" }, - { WINOPTION_SHADOW_MASK_COUNT_X";fs_shadww", "6", OPTION_INTEGER, "shadow mask tile width, in screen dimensions" }, - { WINOPTION_SHADOW_MASK_COUNT_Y";fs_shadwh", "4", OPTION_INTEGER, "shadow mask tile height, in screen dimensions" }, - { WINOPTION_SHADOW_MASK_USIZE";fs_shadwu(0.0-1.0)", "0.1875", OPTION_FLOAT, "shadow mask texture width, in U/V dimensions" }, - { WINOPTION_SHADOW_MASK_VSIZE";fs_shadwv(0.0-1.0)", "0.25", OPTION_FLOAT, "shadow mask texture height, in U/V dimensions" }, - { WINOPTION_SHADOW_MASK_UOFFSET";fs_shadwou(-1.0-1.0)", "0.0", OPTION_FLOAT, "shadow mask texture offset, in U direction" }, - { WINOPTION_SHADOW_MASK_VOFFSET";fs_shadwov(-1.0-1.0)", "0.0", OPTION_FLOAT, "shadow mask texture offset, in V direction" }, - { WINOPTION_DISTORTION";fs_dist(-1.0-1.0)", "0.0", OPTION_FLOAT, "screen distortion amount" }, - { WINOPTION_CUBIC_DISTORTION";fs_cubedist(-1.0-1.0)", "0.0", OPTION_FLOAT, "screen cubic distortion amount" }, - { WINOPTION_DISTORT_CORNER";fs_distc(0.0-1.0)", "0.0", OPTION_FLOAT, "screen distort corner amount" }, - { WINOPTION_ROUND_CORNER";fs_rndc(0.0-1.0)", "0.0", OPTION_FLOAT, "screen round corner amount" }, - { WINOPTION_SMOOTH_BORDER";fs_smob(0.0-1.0)", "0.0", OPTION_FLOAT, "screen smooth border amount" }, - { WINOPTION_REFLECTION";fs_ref(0.0-1.0)", "0.0", OPTION_FLOAT, "screen reflection amount" }, - { WINOPTION_VIGNETTING";fs_vig(0.0-1.0)", "0.0", OPTION_FLOAT, "image vignetting amount" }, - /* Beam-related values below this line*/ - { WINOPTION_SCANLINE_AMOUNT";fs_scanam(0.0-4.0)", "0.0", OPTION_FLOAT, "overall alpha scaling value for scanlines" }, - { WINOPTION_SCANLINE_SCALE";fs_scansc(0.0-4.0)", "1.0", OPTION_FLOAT, "overall height scaling value for scanlines" }, - { WINOPTION_SCANLINE_HEIGHT";fs_scanh(0.0-4.0)", "1.0", OPTION_FLOAT, "individual height scaling value for scanlines" }, - { WINOPTION_SCANLINE_VARIATION";fs_scanv(0.0-4.0)", "1.0", OPTION_FLOAT, "individual height varying value for scanlines" }, - { WINOPTION_SCANLINE_BRIGHT_SCALE";fs_scanbs(0.0-2.0)", "1.0", OPTION_FLOAT, "overall brightness scaling value for scanlines (multiplicative)" }, - { WINOPTION_SCANLINE_BRIGHT_OFFSET";fs_scanbo(0.0-1.0)", "0.0", OPTION_FLOAT, "overall brightness offset value for scanlines (additive)" }, - { WINOPTION_SCANLINE_JITTER";fs_scanjt(0.0-4.0)", "0.0", OPTION_FLOAT, "overall interlace jitter scaling value for scanlines" }, - { WINOPTION_HUM_BAR_ALPHA";fs_humba(0.0-1.0)", "0.0", OPTION_FLOAT, "overall alpha scaling value for hum bar" }, - { WINOPTION_DEFOCUS";fs_focus", "0.0,0.0", OPTION_STRING, "overall defocus value in screen-relative coords" }, - { WINOPTION_CONVERGE_X";fs_convx", "0.0,0.0,0.0", OPTION_STRING, "convergence in screen-relative X direction" }, - { WINOPTION_CONVERGE_Y";fs_convy", "0.0,0.0,0.0", OPTION_STRING, "convergence in screen-relative Y direction" }, - { WINOPTION_RADIAL_CONVERGE_X";fs_rconvx", "0.0,0.0,0.0", OPTION_STRING, "radial convergence in screen-relative X direction" }, - { WINOPTION_RADIAL_CONVERGE_Y";fs_rconvy", "0.0,0.0,0.0", OPTION_STRING, "radial convergence in screen-relative Y direction" }, - /* RGB colorspace convolution below this line */ - { WINOPTION_RED_RATIO";fs_redratio", "1.0,0.0,0.0", OPTION_STRING, "red output signal generated by input signal" }, - { WINOPTION_GRN_RATIO";fs_grnratio", "0.0,1.0,0.0", OPTION_STRING, "green output signal generated by input signal" }, - { WINOPTION_BLU_RATIO";fs_bluratio", "0.0,0.0,1.0", OPTION_STRING, "blue output signal generated by input signal" }, - { WINOPTION_SATURATION";fs_sat(0.0-4.0)", "1.0", OPTION_FLOAT, "saturation scaling value" }, - { WINOPTION_OFFSET";fs_offset", "0.0,0.0,0.0", OPTION_STRING, "signal offset value (additive)" }, - { WINOPTION_SCALE";fs_scale", "1.0,1.0,1.0", OPTION_STRING, "signal scaling value (multiplicative)" }, - { WINOPTION_POWER";fs_power", "1.0,1.0,1.0", OPTION_STRING, "signal power value (exponential)" }, - { WINOPTION_FLOOR";fs_floor", "0.0,0.0,0.0", OPTION_STRING, "signal floor level" }, - { WINOPTION_PHOSPHOR";fs_phosphor", "0.0,0.0,0.0", OPTION_STRING, "phosphorescence decay rate (0.0 is instant, 1.0 is forever)" }, - { WINOPTION_CHROMA_MODE, "3", OPTION_INTEGER, "number of phosphors to use: 1 - monochrome, 2 - dichrome, 3 - trichrome (color)" }, - { WINOPTION_CHROMA_CONVERSION_GAIN, "0.299,0.587,0.114", OPTION_STRING, "gain to be applied when summing RGB signal for monochrome and dichrome modes" }, - { WINOPTION_CHROMA_A, "0.64,0.33", OPTION_STRING, "chromaticity coordinate for first phosphor" }, - { WINOPTION_CHROMA_B, "0.30,0.60", OPTION_STRING, "chromaticity coordinate for second phosphor" }, - { WINOPTION_CHROMA_C, "0.15,0.06", OPTION_STRING, "chromaticity coordinate for third phosphor" }, - { WINOPTION_CHROMA_Y_GAIN, "0.2126,0.7152,0.0722", OPTION_STRING, "gain to be applied for each phosphor" }, - /* NTSC simulation below this line */ - { nullptr, nullptr, OPTION_HEADER, "NTSC POST-PROCESSING OPTIONS" }, - { WINOPTION_YIQ_ENABLE";yiq", "0", OPTION_BOOLEAN, "enable YIQ-space HLSL post-processing" }, - { WINOPTION_YIQ_JITTER";yiqj", "0.0", OPTION_FLOAT, "jitter for the NTSC signal processing" }, - { WINOPTION_YIQ_CCVALUE";yiqcc", "3.57954545", OPTION_FLOAT, "color carrier frequency for NTSC signal processing" }, - { WINOPTION_YIQ_AVALUE";yiqa", "0.5", OPTION_FLOAT, "A value for NTSC signal processing" }, - { WINOPTION_YIQ_BVALUE";yiqb", "0.5", OPTION_FLOAT, "B value for NTSC signal processing" }, - { WINOPTION_YIQ_OVALUE";yiqo", "0.0", OPTION_FLOAT, "outgoing Color Carrier phase offset for NTSC signal processing" }, - { WINOPTION_YIQ_PVALUE";yiqp", "1.0", OPTION_FLOAT, "incoming Pixel Clock scaling value for NTSC signal processing" }, - { WINOPTION_YIQ_NVALUE";yiqn", "1.0", OPTION_FLOAT, "Y filter notch width for NTSC signal processing" }, - { WINOPTION_YIQ_YVALUE";yiqy", "6.0", OPTION_FLOAT, "Y filter cutoff frequency for NTSC signal processing" }, - { WINOPTION_YIQ_IVALUE";yiqi", "1.2", OPTION_FLOAT, "I filter cutoff frequency for NTSC signal processing" }, - { WINOPTION_YIQ_QVALUE";yiqq", "0.6", OPTION_FLOAT, "Q filter cutoff frequency for NTSC signal processing" }, - { WINOPTION_YIQ_SCAN_TIME";yiqsc", "52.6", OPTION_FLOAT, "horizontal scanline duration for NTSC signal processing (microseconds)" }, - { WINOPTION_YIQ_PHASE_COUNT";yiqpc", "2", OPTION_INTEGER, "phase count value for NTSC signal processing" }, - /* Vector simulation below this line */ - { nullptr, nullptr, OPTION_HEADER, "VECTOR POST-PROCESSING OPTIONS" }, - { WINOPTION_VECTOR_BEAM_SMOOTH";vecsmooth", "0.0", OPTION_FLOAT, "vector beam smoothness" }, - { WINOPTION_VECTOR_LENGTH_SCALE";vecscale", "0.5", OPTION_FLOAT, "maximum vector attenuation" }, - { WINOPTION_VECTOR_LENGTH_RATIO";vecratio", "0.5", OPTION_FLOAT, "minimum vector length affected by attenuation (vector length to screen size ratio)" }, - /* Bloom below this line */ - { nullptr, nullptr, OPTION_HEADER, "BLOOM POST-PROCESSING OPTIONS" }, - { WINOPTION_BLOOM_BLEND_MODE, "0", OPTION_INTEGER, "bloom blend mode (0 for brighten, 1 for darken)" }, - { WINOPTION_BLOOM_SCALE, "0.0", OPTION_FLOAT, "intensity factor for bloom" }, - { WINOPTION_BLOOM_OVERDRIVE, "1.0,1.0,1.0", OPTION_STRING, "overdrive factor for bloom" }, - { WINOPTION_BLOOM_LEVEL0_WEIGHT, "1.0", OPTION_FLOAT, "bloom level 0 weight (full-size target)" }, - { WINOPTION_BLOOM_LEVEL1_WEIGHT, "0.64", OPTION_FLOAT, "bloom level 1 weight (1/4 smaller that level 0 target)" }, - { WINOPTION_BLOOM_LEVEL2_WEIGHT, "0.32", OPTION_FLOAT, "bloom level 2 weight (1/4 smaller that level 1 target)" }, - { WINOPTION_BLOOM_LEVEL3_WEIGHT, "0.16", OPTION_FLOAT, "bloom level 3 weight (1/4 smaller that level 2 target)" }, - { WINOPTION_BLOOM_LEVEL4_WEIGHT, "0.08", OPTION_FLOAT, "bloom level 4 weight (1/4 smaller that level 3 target)" }, - { WINOPTION_BLOOM_LEVEL5_WEIGHT, "0.06", OPTION_FLOAT, "bloom level 5 weight (1/4 smaller that level 4 target)" }, - { WINOPTION_BLOOM_LEVEL6_WEIGHT, "0.04", OPTION_FLOAT, "bloom level 6 weight (1/4 smaller that level 5 target)" }, - { WINOPTION_BLOOM_LEVEL7_WEIGHT, "0.02", OPTION_FLOAT, "bloom level 7 weight (1/4 smaller that level 6 target)" }, - { WINOPTION_BLOOM_LEVEL8_WEIGHT, "0.01", OPTION_FLOAT, "bloom level 8 weight (1/4 smaller that level 7 target)" }, - { WINOPTION_LUT_TEXTURE, "", OPTION_STRING, "3D LUT texture filename for screen, PNG format" }, - { WINOPTION_LUT_ENABLE, "0", OPTION_BOOLEAN, "Enables 3D LUT to be applied to screen after post-processing" }, - { WINOPTION_UI_LUT_TEXTURE, "", OPTION_STRING, "3D LUT texture filename of UI, PNG format" }, - { WINOPTION_UI_LUT_ENABLE, "0", OPTION_BOOLEAN, "enable 3D LUT to be applied to UI and artwork after post-processing" }, - - // full screen options - { nullptr, nullptr, OPTION_HEADER, "FULL SCREEN OPTIONS" }, - { WINOPTION_TRIPLEBUFFER ";tb", "0", OPTION_BOOLEAN, "enable triple buffering" }, - { WINOPTION_FULLSCREENBRIGHTNESS ";fsb(0.1-2.0)", "1.0", OPTION_FLOAT, "brightness value in full screen mode" }, - { WINOPTION_FULLSCREENCONTRAST ";fsc(0.1-2.0)", "1.0", OPTION_FLOAT, "contrast value in full screen mode" }, - { WINOPTION_FULLSCREENGAMMA ";fsg(0.1-3.0)", "1.0", OPTION_FLOAT, "gamma value in full screen mode" }, - - // input options - { nullptr, nullptr, OPTION_HEADER, "INPUT DEVICE OPTIONS" }, - { WINOPTION_GLOBAL_INPUTS, "0", OPTION_BOOLEAN, "enable global inputs" }, - { WINOPTION_DUAL_LIGHTGUN ";dual", "0", OPTION_BOOLEAN, "enable dual lightgun input" }, - - { nullptr } -}; - -//************************************************************************** -// MAIN ENTRY POINT -//************************************************************************** - -//============================================================ -// main -//============================================================ - -int main(int argc, char *argv[]) -{ - std::setlocale(LC_ALL, ""); - std::vector args = osd_get_command_line(argc, argv); - - // use small output buffers on non-TTYs (i.e. pipes) - if (!isatty(fileno(stdout))) - setvbuf(stdout, (char *) nullptr, _IOFBF, 64); - if (!isatty(fileno(stderr))) - setvbuf(stderr, (char *) nullptr, _IOFBF, 64); - - // initialize common controls - InitCommonControls(); - - // set a handler to catch ctrl-c - SetConsoleCtrlHandler(control_handler, TRUE); - - // Initialize crash diagnostics - diagnostics_module::get_instance()->init_crash_diagnostics(); - - // parse config and cmdline options - DWORD result; - { - 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(args.size())) - { - // 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(); - result = emulator_info::start_frontend(options, osd, args); - osd_output::pop(&winerror); - } - - return result; -} - -//============================================================ -// control_handler -//============================================================ - -static BOOL WINAPI control_handler(DWORD type) -{ - // indicate to the user that we detected something - switch (type) - { - case CTRL_C_EVENT: fprintf(stderr, "Caught Ctrl+C"); break; - case CTRL_BREAK_EVENT: fprintf(stderr, "Caught Ctrl+break"); break; - case CTRL_CLOSE_EVENT: fprintf(stderr, "Caught console close"); break; - case CTRL_LOGOFF_EVENT: fprintf(stderr, "Caught logoff"); break; - case CTRL_SHUTDOWN_EVENT: fprintf(stderr, "Caught shutdown"); break; - default: fprintf(stderr, "Caught unexpected console event"); break; - } - - // if we don't have a machine yet, or if we are handling ctrl+c/ctrl+break, - // just terminate hard, without throwing or handling any atexit stuff - if (g_current_machine == nullptr || type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT) - { - fprintf(stderr, ", exiting\n"); - TerminateProcess(GetCurrentProcess(), EMU_ERR_FATALERROR); - } - - // all other situations attempt to do a clean exit - else - { - fprintf(stderr, ", exit requested\n"); - g_current_machine->schedule_exit(); - } - - // in all cases we handled it - return TRUE; -} - -//============================================================ -// windows_options -//============================================================ - -windows_options::windows_options() -: osd_options() -{ - add_entries(s_option_entries); -} - - -//============================================================ -// output_oslog -//============================================================ - -void windows_osd_interface::output_oslog(const char *buffer) -{ - if (IsDebuggerPresent()) - win_output_debug_string_utf8(buffer); - else - fputs(buffer, stderr); -} - - -//============================================================ -// constructor -//============================================================ - -windows_osd_interface::windows_osd_interface(windows_options &options) - : osd_common_t(options) - , m_options(options) -{ -} - - -//============================================================ -// destructor -//============================================================ - -windows_osd_interface::~windows_osd_interface() -{ -} - - -//============================================================ -// video_register -//============================================================ - -void windows_osd_interface::video_register() -{ - video_options_add("gdi", nullptr); - video_options_add("d3d", nullptr); -#if USE_OPENGL - video_options_add("opengl", nullptr); -#endif - video_options_add("bgfx", nullptr); - //video_options_add("auto", nullptr); // making d3d video default one -} - -//============================================================ -// init -//============================================================ - -void windows_osd_interface::init(running_machine &machine) -{ - // call our parent - osd_common_t::init(machine); - - const char *stemp; - auto &options = downcast(machine.options()); - - // determine if we are benchmarking, and adjust options appropriately - int bench = options.bench(); - if (bench > 0) - { - options.set_value(OPTION_SLEEP, false, OPTION_PRIORITY_MAXIMUM); - options.set_value(OPTION_THROTTLE, false, OPTION_PRIORITY_MAXIMUM); - options.set_value(OSDOPTION_SOUND, "none", OPTION_PRIORITY_MAXIMUM); - options.set_value(OSDOPTION_VIDEO, "none", OPTION_PRIORITY_MAXIMUM); - options.set_value(OPTION_SECONDS_TO_RUN, bench, OPTION_PRIORITY_MAXIMUM); - } - - // determine if we are profiling, and adjust options appropriately - int profile = options.profile(); - if (profile > 0) - { - options.set_value(OPTION_THROTTLE, false, OPTION_PRIORITY_MAXIMUM); - options.set_value(OSDOPTION_NUMPROCESSORS, 1, OPTION_PRIORITY_MAXIMUM); - } - - // thread priority - if (!(machine.debug_flags & DEBUG_FLAG_OSD_ENABLED)) - SetThreadPriority(GetCurrentThread(), options.priority()); - - // get number of processors - stemp = options.numprocessors(); - - osd_num_processors = 0; - - if (strcmp(stemp, "auto") != 0) - { - osd_num_processors = atoi(stemp); - if (osd_num_processors < 1) - { - osd_printf_warning("Warning: numprocessors < 1 doesn't make much sense. Assuming auto ...\n"); - osd_num_processors = 0; - } - } - - // initialize the subsystems - osd_common_t::init_subsystems(); - - // notify listeners of screen configuration - for (const auto &info : osd_common_t::s_window_list) - { - machine.output().set_value(string_format("Orientation(%s)", info->monitor()->devicename()), std::static_pointer_cast(info)->m_targetorient); - } - - // hook up the debugger log - if (options.oslog()) - machine.add_logerror_callback(&windows_osd_interface::output_oslog); - - // crank up the multimedia timer resolution to its max - // this gives the system much finer timeslices - timeresult = timeGetDevCaps(&timecaps, sizeof(timecaps)); - if (timeresult == TIMERR_NOERROR) - timeBeginPeriod(timecaps.wPeriodMin); - - // create and start the profiler - if (profile > 0) - { - diagnostics_module::get_instance()->start_profiler(1000, profile - 1); - } - - // initialize sockets - win_init_sockets(); - - // note the existence of a machine - g_current_machine = &machine; -} - - -//============================================================ -// osd_exit -//============================================================ - -void windows_osd_interface::osd_exit() -{ - // no longer have a machine - g_current_machine = nullptr; - - // cleanup sockets - win_cleanup_sockets(); - - osd_common_t::osd_exit(); - - // stop the profiler - diagnostics_module::get_instance()->stop_profiler(); - diagnostics_module::get_instance()->print_profiler_results(); - - // restore the timer resolution - if (timeresult == TIMERR_NOERROR) - timeEndPeriod(timecaps.wPeriodMin); - - // one last pass at events - winwindow_process_events(machine(), false, false); -} - - -//============================================================ -// osd_setup_osd_specific_emu_options -//============================================================ - -void osd_setup_osd_specific_emu_options(emu_options &opts) -{ - opts.add_entries(osd_options::s_option_entries); - opts.add_entries(windows_options::s_option_entries); -} - - -//============================================================ -// check_for_double_click_start -//============================================================ - -static int is_double_click_start(int argc) -{ - STARTUPINFO startup_info = { sizeof(STARTUPINFO) }; - - // determine our startup information - GetStartupInfo(&startup_info); - - // try to determine if MAME was simply double-clicked - return (argc <= 1 && startup_info.dwFlags && !(startup_info.dwFlags & STARTF_USESTDHANDLES)); -} diff --git a/src/osd/windows/winmain.h b/src/osd/windows/winmain.h deleted file mode 100644 index ef1cd1af..00000000 --- a/src/osd/windows/winmain.h +++ /dev/null @@ -1,332 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -//============================================================ -// -// winmain.h - Win32 main program and core headers -// -//============================================================ - -#ifndef __WINDOWS_WINMAIN_H__ -#define __WINDOWS_WINMAIN_H__ - -#include "osdepend.h" -#include "modules/lib/osdobj_common.h" - - -//============================================================ -// CONSTANTS -//============================================================ - -// performance options -#define WINOPTION_PRIORITY "priority" -#define WINOPTION_PROFILE "profile" - -// video options -#define WINOPTION_MENU "menu" -#define WINOPTION_ATTACH_WINDOW "attach_window" - -// core post-processing options -#define WINOPTION_HLSLPATH "hlslpath" -#define WINOPTION_HLSL_ENABLE "hlsl_enable" -#define WINOPTION_HLSL_OVERSAMPLING "hlsl_oversampling" -#define WINOPTION_HLSL_WRITE "hlsl_write" -#define WINOPTION_HLSL_SNAP_WIDTH "hlsl_snap_width" -#define WINOPTION_HLSL_SNAP_HEIGHT "hlsl_snap_height" -#define WINOPTION_SHADOW_MASK_TILE_MODE "shadow_mask_tile_mode" -#define WINOPTION_SHADOW_MASK_ALPHA "shadow_mask_alpha" -#define WINOPTION_SHADOW_MASK_TEXTURE "shadow_mask_texture" -#define WINOPTION_SHADOW_MASK_COUNT_X "shadow_mask_x_count" -#define WINOPTION_SHADOW_MASK_COUNT_Y "shadow_mask_y_count" -#define WINOPTION_SHADOW_MASK_USIZE "shadow_mask_usize" -#define WINOPTION_SHADOW_MASK_VSIZE "shadow_mask_vsize" -#define WINOPTION_SHADOW_MASK_UOFFSET "shadow_mask_uoffset" -#define WINOPTION_SHADOW_MASK_VOFFSET "shadow_mask_voffset" -#define WINOPTION_REFLECTION "reflection" -#define WINOPTION_DISTORTION "distortion" -#define WINOPTION_CUBIC_DISTORTION "cubic_distortion" -#define WINOPTION_DISTORT_CORNER "distort_corner" -#define WINOPTION_ROUND_CORNER "round_corner" -#define WINOPTION_SMOOTH_BORDER "smooth_border" -#define WINOPTION_VIGNETTING "vignetting" -#define WINOPTION_SCANLINE_AMOUNT "scanline_alpha" -#define WINOPTION_SCANLINE_SCALE "scanline_size" -#define WINOPTION_SCANLINE_HEIGHT "scanline_height" -#define WINOPTION_SCANLINE_VARIATION "scanline_variation" -#define WINOPTION_SCANLINE_BRIGHT_SCALE "scanline_bright_scale" -#define WINOPTION_SCANLINE_BRIGHT_OFFSET "scanline_bright_offset" -#define WINOPTION_SCANLINE_JITTER "scanline_jitter" -#define WINOPTION_HUM_BAR_ALPHA "hum_bar_alpha" -#define WINOPTION_DEFOCUS "defocus" -#define WINOPTION_CONVERGE_X "converge_x" -#define WINOPTION_CONVERGE_Y "converge_y" -#define WINOPTION_RADIAL_CONVERGE_X "radial_converge_x" -#define WINOPTION_RADIAL_CONVERGE_Y "radial_converge_y" -#define WINOPTION_RED_RATIO "red_ratio" -#define WINOPTION_GRN_RATIO "grn_ratio" -#define WINOPTION_BLU_RATIO "blu_ratio" -#define WINOPTION_OFFSET "offset" -#define WINOPTION_SCALE "scale" -#define WINOPTION_POWER "power" -#define WINOPTION_FLOOR "floor" -#define WINOPTION_PHOSPHOR "phosphor_life" -#define WINOPTION_SATURATION "saturation" -#define WINOPTION_CHROMA_MODE "chroma_mode" -#define WINOPTION_CHROMA_CONVERSION_GAIN "chroma_conversion_gain" -#define WINOPTION_CHROMA_A "chroma_a" -#define WINOPTION_CHROMA_B "chroma_b" -#define WINOPTION_CHROMA_C "chroma_c" -#define WINOPTION_CHROMA_Y_GAIN "chroma_y_gain" -#define WINOPTION_YIQ_ENABLE "yiq_enable" -#define WINOPTION_YIQ_JITTER "yiq_jitter" -#define WINOPTION_YIQ_CCVALUE "yiq_cc" -#define WINOPTION_YIQ_AVALUE "yiq_a" -#define WINOPTION_YIQ_BVALUE "yiq_b" -#define WINOPTION_YIQ_OVALUE "yiq_o" -#define WINOPTION_YIQ_PVALUE "yiq_p" -#define WINOPTION_YIQ_NVALUE "yiq_n" -#define WINOPTION_YIQ_YVALUE "yiq_y" -#define WINOPTION_YIQ_IVALUE "yiq_i" -#define WINOPTION_YIQ_QVALUE "yiq_q" -#define WINOPTION_YIQ_SCAN_TIME "yiq_scan_time" -#define WINOPTION_YIQ_PHASE_COUNT "yiq_phase_count" -#define WINOPTION_VECTOR_BEAM_SMOOTH "vector_beam_smooth" -#define WINOPTION_VECTOR_LENGTH_SCALE "vector_length_scale" -#define WINOPTION_VECTOR_LENGTH_RATIO "vector_length_ratio" -#define WINOPTION_BLOOM_BLEND_MODE "bloom_blend_mode" -#define WINOPTION_BLOOM_SCALE "bloom_scale" -#define WINOPTION_BLOOM_OVERDRIVE "bloom_overdrive" -#define WINOPTION_BLOOM_LEVEL0_WEIGHT "bloom_lvl0_weight" -#define WINOPTION_BLOOM_LEVEL1_WEIGHT "bloom_lvl1_weight" -#define WINOPTION_BLOOM_LEVEL2_WEIGHT "bloom_lvl2_weight" -#define WINOPTION_BLOOM_LEVEL3_WEIGHT "bloom_lvl3_weight" -#define WINOPTION_BLOOM_LEVEL4_WEIGHT "bloom_lvl4_weight" -#define WINOPTION_BLOOM_LEVEL5_WEIGHT "bloom_lvl5_weight" -#define WINOPTION_BLOOM_LEVEL6_WEIGHT "bloom_lvl6_weight" -#define WINOPTION_BLOOM_LEVEL7_WEIGHT "bloom_lvl7_weight" -#define WINOPTION_BLOOM_LEVEL8_WEIGHT "bloom_lvl8_weight" -#define WINOPTION_LUT_TEXTURE "lut_texture" -#define WINOPTION_LUT_ENABLE "lut_enable" -#define WINOPTION_UI_LUT_TEXTURE "ui_lut_texture" -#define WINOPTION_UI_LUT_ENABLE "ui_lut_enable" - -// full screen options -#define WINOPTION_TRIPLEBUFFER "triplebuffer" -#define WINOPTION_FULLSCREENBRIGHTNESS "full_screen_brightness" -#define WINOPTION_FULLSCREENCONTRAST "full_screen_contrast" -#define WINOPTION_FULLSCREENGAMMA "full_screen_gamma" - -// input options -#define WINOPTION_GLOBAL_INPUTS "global_inputs" -#define WINOPTION_DUAL_LIGHTGUN "dual_lightgun" - -//============================================================ -// TYPE DEFINITIONS -//============================================================ - -class windows_options : public osd_options -{ -public: - // construction/destruction - windows_options(); - - // performance options - int priority() const { return int_value(WINOPTION_PRIORITY); } - int profile() const { return int_value(WINOPTION_PROFILE); } - - // video options - bool menu() const { return bool_value(WINOPTION_MENU); } - const char *attach_window() const { return value(WINOPTION_ATTACH_WINDOW); } - - // core post-processing options - const char *screen_post_fx_dir() const { return value(WINOPTION_HLSLPATH); } - bool d3d_hlsl_enable() const { return bool_value(WINOPTION_HLSL_ENABLE); } - bool d3d_hlsl_oversampling() const { return bool_value(WINOPTION_HLSL_OVERSAMPLING); } - const char *d3d_hlsl_write() const { return value(WINOPTION_HLSL_WRITE); } - int d3d_snap_width() const { return int_value(WINOPTION_HLSL_SNAP_WIDTH); } - int d3d_snap_height() const { return int_value(WINOPTION_HLSL_SNAP_HEIGHT); } - int screen_shadow_mask_tile_mode() const { return int_value(WINOPTION_SHADOW_MASK_TILE_MODE); } - float screen_shadow_mask_alpha() const { return float_value(WINOPTION_SHADOW_MASK_ALPHA); } - const char *screen_shadow_mask_texture() const { return value(WINOPTION_SHADOW_MASK_TEXTURE); } - int screen_shadow_mask_count_x() const { return int_value(WINOPTION_SHADOW_MASK_COUNT_X); } - int screen_shadow_mask_count_y() const { return int_value(WINOPTION_SHADOW_MASK_COUNT_Y); } - float screen_shadow_mask_u_size() const { return float_value(WINOPTION_SHADOW_MASK_USIZE); } - float screen_shadow_mask_v_size() const { return float_value(WINOPTION_SHADOW_MASK_VSIZE); } - float screen_shadow_mask_u_offset() const { return float_value(WINOPTION_SHADOW_MASK_UOFFSET); } - float screen_shadow_mask_v_offset() const { return float_value(WINOPTION_SHADOW_MASK_VOFFSET); } - float screen_scanline_amount() const { return float_value(WINOPTION_SCANLINE_AMOUNT); } - float screen_scanline_scale() const { return float_value(WINOPTION_SCANLINE_SCALE); } - float screen_scanline_height() const { return float_value(WINOPTION_SCANLINE_HEIGHT); } - float screen_scanline_variation() const { return float_value(WINOPTION_SCANLINE_VARIATION); } - float screen_scanline_bright_scale() const { return float_value(WINOPTION_SCANLINE_BRIGHT_SCALE); } - float screen_scanline_bright_offset() const { return float_value(WINOPTION_SCANLINE_BRIGHT_OFFSET); } - float screen_scanline_jitter() const { return float_value(WINOPTION_SCANLINE_JITTER); } - float screen_hum_bar_alpha() const { return float_value(WINOPTION_HUM_BAR_ALPHA); } - float screen_reflection() const { return float_value(WINOPTION_REFLECTION); } - float screen_distortion() const { return float_value(WINOPTION_DISTORTION); } - float screen_cubic_distortion() const { return float_value(WINOPTION_CUBIC_DISTORTION); } - float screen_distort_corner() const { return float_value(WINOPTION_DISTORT_CORNER); } - float screen_round_corner() const { return float_value(WINOPTION_ROUND_CORNER); } - float screen_smooth_border() const { return float_value(WINOPTION_SMOOTH_BORDER); } - float screen_vignetting() const { return float_value(WINOPTION_VIGNETTING); } - const char *screen_defocus() const { return value(WINOPTION_DEFOCUS); } - const char *screen_converge_x() const { return value(WINOPTION_CONVERGE_X); } - const char *screen_converge_y() const { return value(WINOPTION_CONVERGE_Y); } - const char *screen_radial_converge_x() const { return value(WINOPTION_RADIAL_CONVERGE_X); } - const char *screen_radial_converge_y() const { return value(WINOPTION_RADIAL_CONVERGE_Y); } - const char *screen_red_ratio() const { return value(WINOPTION_RED_RATIO); } - const char *screen_grn_ratio() const { return value(WINOPTION_GRN_RATIO); } - const char *screen_blu_ratio() const { return value(WINOPTION_BLU_RATIO); } - bool screen_yiq_enable() const { return bool_value(WINOPTION_YIQ_ENABLE); } - float screen_yiq_jitter() const { return float_value(WINOPTION_YIQ_JITTER); } - float screen_yiq_cc() const { return float_value(WINOPTION_YIQ_CCVALUE); } - float screen_yiq_a() const { return float_value(WINOPTION_YIQ_AVALUE); } - float screen_yiq_b() const { return float_value(WINOPTION_YIQ_BVALUE); } - float screen_yiq_o() const { return float_value(WINOPTION_YIQ_OVALUE); } - float screen_yiq_p() const { return float_value(WINOPTION_YIQ_PVALUE); } - float screen_yiq_n() const { return float_value(WINOPTION_YIQ_NVALUE); } - float screen_yiq_y() const { return float_value(WINOPTION_YIQ_YVALUE); } - float screen_yiq_i() const { return float_value(WINOPTION_YIQ_IVALUE); } - float screen_yiq_q() const { return float_value(WINOPTION_YIQ_QVALUE); } - float screen_yiq_scan_time() const { return float_value(WINOPTION_YIQ_SCAN_TIME); } - int screen_yiq_phase_count() const { return int_value(WINOPTION_YIQ_PHASE_COUNT); } - float screen_vector_beam_smooth() const { return float_value(WINOPTION_VECTOR_BEAM_SMOOTH); } - float screen_vector_length_scale() const { return float_value(WINOPTION_VECTOR_LENGTH_SCALE); } - float screen_vector_length_ratio() const { return float_value(WINOPTION_VECTOR_LENGTH_RATIO); } - int screen_bloom_blend_mode() const { return int_value(WINOPTION_BLOOM_BLEND_MODE); } - float screen_bloom_scale() const { return float_value(WINOPTION_BLOOM_SCALE); } - const char *screen_bloom_overdrive() const { return value(WINOPTION_BLOOM_OVERDRIVE); } - float screen_bloom_lvl0_weight() const { return float_value(WINOPTION_BLOOM_LEVEL0_WEIGHT); } - float screen_bloom_lvl1_weight() const { return float_value(WINOPTION_BLOOM_LEVEL1_WEIGHT); } - float screen_bloom_lvl2_weight() const { return float_value(WINOPTION_BLOOM_LEVEL2_WEIGHT); } - float screen_bloom_lvl3_weight() const { return float_value(WINOPTION_BLOOM_LEVEL3_WEIGHT); } - float screen_bloom_lvl4_weight() const { return float_value(WINOPTION_BLOOM_LEVEL4_WEIGHT); } - float screen_bloom_lvl5_weight() const { return float_value(WINOPTION_BLOOM_LEVEL5_WEIGHT); } - float screen_bloom_lvl6_weight() const { return float_value(WINOPTION_BLOOM_LEVEL6_WEIGHT); } - float screen_bloom_lvl7_weight() const { return float_value(WINOPTION_BLOOM_LEVEL7_WEIGHT); } - float screen_bloom_lvl8_weight() const { return float_value(WINOPTION_BLOOM_LEVEL8_WEIGHT); } - const char *screen_offset() const { return value(WINOPTION_OFFSET); } - const char *screen_scale() const { return value(WINOPTION_SCALE); } - const char *screen_power() const { return value(WINOPTION_POWER); } - const char *screen_floor() const { return value(WINOPTION_FLOOR); } - const char *screen_phosphor() const { return value(WINOPTION_PHOSPHOR); } - float screen_saturation() const { return float_value(WINOPTION_SATURATION); } - int screen_chroma_mode() const { return int_value(WINOPTION_CHROMA_MODE); } - const char *screen_chroma_a() const { return value(WINOPTION_CHROMA_A); } - const char *screen_chroma_b() const { return value(WINOPTION_CHROMA_B); } - const char *screen_chroma_c() const { return value(WINOPTION_CHROMA_C); } - const char *screen_chroma_conversion_gain() const { return value(WINOPTION_CHROMA_CONVERSION_GAIN); } - const char *screen_chroma_y_gain() const { return value(WINOPTION_CHROMA_Y_GAIN); } - const char *screen_lut_texture() const { return value(WINOPTION_LUT_TEXTURE); } - bool screen_lut_enable() const { return bool_value(WINOPTION_LUT_ENABLE); } - const char *ui_lut_texture() const { return value(WINOPTION_UI_LUT_TEXTURE); } - bool ui_lut_enable() const { return bool_value(WINOPTION_UI_LUT_ENABLE); } - - // full screen options - bool triple_buffer() const { return bool_value(WINOPTION_TRIPLEBUFFER); } - float full_screen_brightness() const { return float_value(WINOPTION_FULLSCREENBRIGHTNESS); } - float full_screen_contrast() const { return float_value(WINOPTION_FULLSCREENCONTRAST); } - float full_screen_gamma() const { return float_value(WINOPTION_FULLSCREENGAMMA); } - - // input options - bool global_inputs() const { return bool_value(WINOPTION_GLOBAL_INPUTS); } - bool dual_lightgun() const { return bool_value(WINOPTION_DUAL_LIGHTGUN); } - - static const options_entry s_option_entries[]; -}; - -//============================================================ -// TYPE DEFINITIONS -//============================================================ - -enum input_event -{ - INPUT_EVENT_KEYDOWN, - INPUT_EVENT_KEYUP, - INPUT_EVENT_RAWINPUT, - INPUT_EVENT_MOUSE_BUTTON -}; - -struct KeyPressEventArgs -{ - input_event event_id; - uint8_t vkey; - uint8_t scancode; -}; - -struct MouseButtonEventArgs -{ - int button; - int keydown; - int xpos; - int ypos; -}; - -// Forward declarations -struct _EXCEPTION_POINTERS; - -class windows_osd_interface : public osd_common_t -{ - // Access to exception filter static method - friend int main(int argc, char *argv[]); - -public: - // construction/destruction - windows_osd_interface(windows_options &options); - virtual ~windows_osd_interface(); - - // general overridables - virtual void init(running_machine &machine) override; - virtual void update(bool skip_redraw) override; - virtual void input_update() override; - - // input overrideables - virtual void customize_input_type_list(std::vector &typelist) override; - - // video overridables - virtual void add_audio_to_recording(const int16_t *buffer, int samples_this_frame) override; - - virtual void video_register() override; - - virtual bool video_init() override; - virtual bool window_init() override; - - virtual void video_exit() override; - virtual void window_exit() override; - - void extract_video_config(); - - // windows osd specific - bool handle_input_event(input_event eventid, void *eventdata) const; - bool should_hide_mouse() const; - void poll_input(running_machine &machine) const; - - virtual windows_options &options() override { return m_options; } - - int window_count(); - -protected: - virtual void build_slider_list() override; - virtual void update_slider_list() override; - - void check_osd_inputs(); - -private: - virtual void osd_exit() override; - static void output_oslog(const char *buffer); - - windows_options & m_options; - - static const int DEFAULT_FONT_HEIGHT = 200; -}; - -//============================================================ -// GLOBAL VARIABLES -//============================================================ - -extern const options_entry mame_win_options[]; - -// defined in winwork.c -extern int osd_num_processors; - - -#endif diff --git a/src/osd/windows/winmenu.cpp b/src/osd/windows/winmenu.cpp deleted file mode 100644 index d55bd3e3..00000000 --- a/src/osd/windows/winmenu.cpp +++ /dev/null @@ -1,33 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -//============================================================ -// -// winmenu.cpp - Win32 OSD core dummy menu implementation -// -//============================================================ - -// standard windows headers -#include - -#include "emu.h" - -#include "window.h" - -//============================================================ -// winwindow_video_window_proc_ui -// (window thread) -//============================================================ - -LRESULT CALLBACK winwindow_video_window_proc_ui(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam) -{ - return win_window_info::video_window_proc(wnd, message, wparam, lparam); -} - -//============================================================ -// win_create_menu -//============================================================ - -int win_create_menu(running_machine &machine, HMENU *menus) -{ - return 0; -}