mirror of
https://github.com/libretro/same_cdi.git
synced 2026-11-07 12:37:58 -10:00
Get rid of profiler
This commit is contained in:
1 parent
2a358ce754
commit
198ada82ec
51 files changed
+3
-8218
No files matched your search
@@ -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",
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -421,7 +421,6 @@ while (0)
|
||||
template <typename BitmapType, typename FunctionClass>
|
||||
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 <typename BitmapType, typename PriorityType, typename FunctionClass>
|
||||
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 <typename BitmapType, typename FunctionClass>
|
||||
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 <typename BitmapType, typename PriorityType, typename FunctionClass>
|
||||
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 <typename BitmapType, typename FunctionClass>
|
||||
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 <typename BitmapType, typename PriorityType, typename FunctionClass>
|
||||
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 <typename BitmapType, typename FunctionClass>
|
||||
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 <typename BitmapType, typename PriorityType, typename FunctionClass>
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include "eminline.h"
|
||||
#include "xtal.h"
|
||||
#include "attotime.h"
|
||||
#include "profiler.h"
|
||||
|
||||
// http interface helpers
|
||||
#include "http.h"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -20,16 +20,6 @@
|
||||
|
||||
#include <set>
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// 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;
|
||||
|
||||
+3
-189
@@ -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<default_resampler_stream *>(&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();
|
||||
}
|
||||
@@ -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<sample_t> 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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -527,9 +527,7 @@ auto lua_engine::make_simple_callback_setter(void (T::*setter)(delegate<R ()> &&
|
||||
template <typename TFunc, typename... TArgs>
|
||||
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<TArgs>(args)...);
|
||||
g_profiler.stop();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 <limits>
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
//============================================================
|
||||
//
|
||||
// appdelegate.h - Cocoa app delegate
|
||||
//
|
||||
// Mac OSD by R. Belmont
|
||||
//
|
||||
//============================================================
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface MAMEAppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
@end
|
||||
@@ -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
|
||||
@@ -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 <functional>
|
||||
|
||||
#define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <crt_externs.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// 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<std::string> 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));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 <Cocoa/Cocoa.h>
|
||||
|
||||
@interface MAMEFSWindow : NSWindow
|
||||
|
||||
@end
|
||||
@@ -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
|
||||
@@ -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 <Cocoa/Cocoa.h>
|
||||
|
||||
@interface MAMEGLView : NSOpenGLView
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -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
|
||||
@@ -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<input_type_entry> &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
|
||||
@@ -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<mac_window_info> win = std::make_shared<mac_window_info>(machine(), index, m_monitor_module->pick_monitor(reinterpret_cast<osd_options &>(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<mac_window_info>(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<mac_window_info>(window)->modify_prescale(-1);
|
||||
|
||||
if (machine.ui_input().pressed(IPT_OSD_7))
|
||||
std::static_pointer_cast<mac_window_info>(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; i<GLSL_SHADER_MAX; i++)
|
||||
{
|
||||
stemp = options().shader_mame(i);
|
||||
if (stemp && strcmp(stemp, OSDOPTVAL_NONE) != 0 && strlen(stemp)>0)
|
||||
{
|
||||
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; i<GLSL_SHADER_MAX; i++)
|
||||
{
|
||||
stemp = options().shader_screen(i);
|
||||
if (stemp && strcmp(stemp, OSDOPTVAL_NONE) != 0 && strlen(stemp)>0)
|
||||
{
|
||||
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<GLSL_SHADER_MAX; i++)
|
||||
{
|
||||
video_config.glsl_shader_mamebm[i] = nullptr;
|
||||
}
|
||||
video_config.glsl_shader_scrn_num=0;
|
||||
for(i=0; i<GLSL_SHADER_MAX; i++)
|
||||
{
|
||||
video_config.glsl_shader_scrn[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// misc options: sanity check values
|
||||
|
||||
// global options: sanity check values
|
||||
if (video_config.numscreens < 1 || video_config.numscreens > 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);
|
||||
}
|
||||
@@ -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 <cmath>
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
// 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<ui::menu_item> 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<mac_osd_interface &>(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<mac_osd_interface&>(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<mac_options &>(machine().options()).maximize();
|
||||
|
||||
create_target();
|
||||
|
||||
set_renderer(osd_renderer::make_for_type(video_config.mode, static_cast<osd_window*>(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<mac_osd_interface &>(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<osd_window>(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<osd_monitor_info> 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
|
||||
}
|
||||
@@ -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 <cstdint>
|
||||
#include <memory>
|
||||
#include <list>
|
||||
|
||||
//============================================================
|
||||
// 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<void *>
|
||||
{
|
||||
public:
|
||||
mac_window_info(running_machine &a_machine, int index, std::shared_ptr<osd_monitor_info> 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__ */
|
||||
@@ -1,16 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
//============================================================
|
||||
//
|
||||
// windowcontroller.mm - our window/fullscreen manager
|
||||
//
|
||||
// Mac OSD by R. Belmont
|
||||
//
|
||||
//============================================================
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "oglview.h"
|
||||
|
||||
@interface MAMEWindowController : NSWindowController
|
||||
|
||||
@end
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -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
|
||||
|
||||
@@ -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 <windows.h>
|
||||
#include <winioctl.h>
|
||||
|
||||
// standard C headers
|
||||
#include <conio.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Aaron Giles
|
||||
//============================================================
|
||||
//
|
||||
// video.cpp - Win32 video handling
|
||||
//
|
||||
//============================================================
|
||||
|
||||
// standard windows headers
|
||||
#include <windows.h>
|
||||
|
||||
// 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<windows_options &>(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<win_window_info>(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; i<GLSL_SHADER_MAX; i++)
|
||||
{
|
||||
stemp = options().shader_mame(i);
|
||||
if (stemp && strcmp(stemp, OSDOPTVAL_NONE) != 0 && strlen(stemp)>0)
|
||||
{
|
||||
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; i<GLSL_SHADER_MAX; i++)
|
||||
{
|
||||
stemp = options().shader_screen(i);
|
||||
if (stemp && strcmp(stemp, OSDOPTVAL_NONE) != 0 && strlen(stemp)>0)
|
||||
{
|
||||
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<GLSL_SHADER_MAX; i++)
|
||||
{
|
||||
video_config.glsl_shader_mamebm[i] = nullptr;
|
||||
}
|
||||
video_config.glsl_shader_scrn_num=0;
|
||||
for(i=0; i<GLSL_SHADER_MAX; i++)
|
||||
{
|
||||
video_config.glsl_shader_scrn[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_OPENGL */
|
||||
|
||||
}
|
||||
|
||||
|
||||
//============================================================
|
||||
// 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);
|
||||
}
|
||||
@@ -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 <windows.h>
|
||||
|
||||
|
||||
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
|
||||
File diff suppressed because it is too large.
Load diff
@@ -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 <chrono>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
// standard windows headers
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
|
||||
//============================================================
|
||||
// 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<HWND>
|
||||
{
|
||||
public:
|
||||
win_window_info(running_machine &machine, int index, std::shared_ptr<osd_monitor_info> 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<osd_monitor_info> 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
|
||||
@@ -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 <cctype>
|
||||
#include <clocale>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
|
||||
// standard windows headers
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <mmsystem.h>
|
||||
#include <tchar.h>
|
||||
#include <io.h>
|
||||
|
||||
#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<std::thread> 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<std::ostream> &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<std::mutex> 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<std::mutex> 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<std::string> 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<windows_options &>(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<win_window_info>(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));
|
||||
}
|
||||
@@ -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<input_type_entry> &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
|
||||
@@ -1,33 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Aaron Giles
|
||||
//============================================================
|
||||
//
|
||||
// winmenu.cpp - Win32 OSD core dummy menu implementation
|
||||
//
|
||||
//============================================================
|
||||
|
||||
// standard windows headers
|
||||
#include <windows.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
Reference in new issue
Block a user