mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00

* Eliminates the need for the horizontal/vertical/LCD/SVG layout files * Screens can now have orientation and physical aspect ratio specified * RASTER/VECTOR defaults to 4:3, LCD/SVG defaults to square pixels at config time * System orientation is applied on top of screen orientation Automatically generated single-screen views and orientation flags in XML output now work correctly for systems with multiple screens in different geometries/orientations, e.g. housemnq, rocnms, stepstag, or netmerc. The "core rotation options" only interact with system orientation. Allowing multi-screen systems to work well with one monitor per emulated screen is a complex topic. System orientation also affects the GFX viewer while screen orientation doesn't. The orientation displayed in the system selection menu is from the system orientation. Let me know if I've broken any systems or use cases. Also, add save state support for std::array/C array nested to any depth.
168 lines
3.7 KiB
C++
168 lines
3.7 KiB
C++
// license:BSD-3-Clause
|
|
// copyright-holders:Olivier Galibert, R. Belmont
|
|
//============================================================
|
|
//
|
|
// osdsync.h - Core synchronization functions
|
|
//
|
|
//============================================================
|
|
#ifndef MAME_OSD_OSDSYNC_H
|
|
#define MAME_OSD_OSDSYNC_H
|
|
|
|
#pragma once
|
|
|
|
// C++ headers
|
|
#include <mutex>
|
|
#include <atomic>
|
|
#include <condition_variable>
|
|
|
|
#include "osdcomm.h"
|
|
|
|
/***************************************************************************
|
|
SYNCHRONIZATION INTERFACES - Events
|
|
***************************************************************************/
|
|
|
|
#define OSD_EVENT_WAIT_INFINITE (~(osd_ticks_t)0)
|
|
|
|
/* osd_event is an opaque type which represents a setable/resettable event */
|
|
|
|
class osd_event
|
|
{
|
|
public:
|
|
/*-----------------------------------------------------------------------------
|
|
constructor: allocate a new event
|
|
|
|
Parameters:
|
|
|
|
manualreset - boolean. If true, the event will be automatically set
|
|
to non-signalled after a thread successfully waited for
|
|
it.
|
|
initialstate - boolean. If true, the event is signalled initially.
|
|
|
|
Return value:
|
|
|
|
A pointer to the allocated event.
|
|
-----------------------------------------------------------------------------*/
|
|
osd_event(int manualreset, int initialstate)
|
|
{
|
|
m_signalled = initialstate;
|
|
m_autoreset = !manualreset;
|
|
}
|
|
|
|
~osd_event()
|
|
{
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
wait: wait for an event to be signalled
|
|
If the event is in signalled state, the
|
|
function returns immediately. If not it will wait for the event
|
|
to become signalled.
|
|
|
|
Parameters:
|
|
|
|
timeout - timeout in osd_ticks
|
|
|
|
Return value:
|
|
|
|
true: The event was signalled
|
|
false: A timeout occurred
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
bool wait(osd_ticks_t timeout)
|
|
{
|
|
if (timeout == OSD_EVENT_WAIT_INFINITE)
|
|
timeout = osd_ticks_per_second() * (osd_ticks_t)10000;
|
|
|
|
std::unique_lock<std::mutex> lock(m_mutex);
|
|
if (!timeout)
|
|
{
|
|
if (!m_signalled)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!m_signalled)
|
|
{
|
|
uint64_t msec = timeout * 1000 / osd_ticks_per_second();
|
|
|
|
do {
|
|
if (m_cond.wait_for(lock, std::chrono::milliseconds(msec)) == std::cv_status::timeout)
|
|
{
|
|
if (!m_signalled)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
break;
|
|
} else
|
|
break;
|
|
|
|
} while (true);
|
|
}
|
|
}
|
|
|
|
if (m_autoreset)
|
|
m_signalled = 0;
|
|
|
|
return true;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
osd_event_reset: reset an event to non-signalled state
|
|
|
|
Parameters:
|
|
|
|
None
|
|
|
|
Return value:
|
|
|
|
None
|
|
-----------------------------------------------------------------------------*/
|
|
void reset()
|
|
{
|
|
m_mutex.lock();
|
|
m_signalled = false;
|
|
m_mutex.unlock();
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
osd_event_set: set an event to signalled state
|
|
|
|
Parameters:
|
|
|
|
None
|
|
|
|
Return value:
|
|
|
|
None
|
|
|
|
Notes:
|
|
|
|
All threads waiting for the event will be signalled.
|
|
-----------------------------------------------------------------------------*/
|
|
void set()
|
|
{
|
|
m_mutex.lock();
|
|
if (m_signalled == false)
|
|
{
|
|
m_signalled = true;
|
|
if (m_autoreset)
|
|
m_cond.notify_one();
|
|
else
|
|
m_cond.notify_all();
|
|
}
|
|
m_mutex.unlock();
|
|
}
|
|
|
|
private:
|
|
std::mutex m_mutex;
|
|
std::condition_variable m_cond;
|
|
std::atomic<int32_t> m_autoreset;
|
|
std::atomic<int32_t> m_signalled;
|
|
|
|
};
|
|
|
|
#endif // MAME_OSD_OSDSYNC_H
|