mirror of
https://github.com/holub/mame
synced 2025-04-29 03:20:50 +03:00
netlist: move nl_examples to src/lib/netlist/examples. (nw)
One folder less in the top-level.
This commit is contained in:
parent
ceae2fdc3e
commit
c50bf9a698
@ -14,25 +14,53 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
|
#include "ui/uimain.h"
|
||||||
#include "rendutil.h"
|
#include "rendutil.h"
|
||||||
#include "fixfreq.h"
|
#include "fixfreq.h"
|
||||||
|
|
||||||
//#define VERBOSE 1
|
// for quick and dirty debugging
|
||||||
|
#define VERBOSE 0
|
||||||
|
#define LOG_OUTPUT_FUNC printf
|
||||||
#include "logmacro.h"
|
#include "logmacro.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
/***************************************************************************
|
// --------------------------------------------------------------------------
|
||||||
|
// Fixed frequency monitor
|
||||||
Fixed frequency monitor
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// device type definition
|
// device type definition
|
||||||
DEFINE_DEVICE_TYPE(FIXFREQ, fixedfreq_device, "fixfreq", "Fixed-Frequency Monochrome Monitor")
|
DEFINE_DEVICE_TYPE(FIXFREQ, fixedfreq_device, "fixfreq", "Fixed-Frequency Monochrome Monitor")
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// Port adjuster support
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define PORT_ADJUSTERX(_id, _name, _min, _max) \
|
||||||
|
PORT_START(# _id) \
|
||||||
|
configurer.field_alloc(IPT_ADJUSTER, (static_cast<fixedfreq_device &>(owner).monitor_val(_id)), 0xffff, ("Monitor - " _name)); \
|
||||||
|
PORT_MINMAX(_min, _max) PORT_CHANGED_MEMBER(DEVICE_SELF, fixedfreq_device, port_changed, _id) \
|
||||||
|
PORT_CONDITION("ENABLE", 0x01, EQUALS, 0x01)
|
||||||
|
|
||||||
|
#define IOPORT_ID(_id) ioport(# _id)
|
||||||
|
|
||||||
|
enum fixedfreq_tag_id_e
|
||||||
|
{
|
||||||
|
HVISIBLE,
|
||||||
|
HFRONTPORCH,
|
||||||
|
HSYNC,
|
||||||
|
HBACKPORCH,
|
||||||
|
VVISIBLE,
|
||||||
|
VFRONTPORCH,
|
||||||
|
VSYNC,
|
||||||
|
VBACKPORCH,
|
||||||
|
SYNCTHRESHOLD,
|
||||||
|
VSYNCTHRESHOLD,
|
||||||
|
GAIN,
|
||||||
|
SCANLINE_HEIGHT,
|
||||||
|
USE_VECTOR
|
||||||
|
};
|
||||||
|
|
||||||
void fixedfreq_monitor_state::update_sync_channel(const time_type &time, const double newval)
|
void fixedfreq_monitor_state::update_sync_channel(const time_type &time, const double newval)
|
||||||
{
|
{
|
||||||
const time_type delta_time = time - m_last_sync_time;
|
const time_type delta_time = time - m_last_sync_time;
|
||||||
@ -40,59 +68,73 @@ void fixedfreq_monitor_state::update_sync_channel(const time_type &time, const d
|
|||||||
const int last_vsync = m_sig_vsync;
|
const int last_vsync = m_sig_vsync;
|
||||||
const int last_comp = m_sig_composite;
|
const int last_comp = m_sig_composite;
|
||||||
|
|
||||||
m_vsync_filter += ((double) last_comp - m_vsync_filter) * (1.0 - exp(-delta_time * m_vsync_filter_timeconst));
|
m_vsync_filter += ((double) last_comp - m_vsync_filter) * (1.0 - exp(-delta_time * m_desc.vsync_filter_timeconst()));
|
||||||
m_sig_composite = (newval < m_desc.m_sync_threshold) ? 1 : 0 ;
|
m_sig_composite = (newval < m_desc.m_sync_threshold) ? 1 : 0 ;
|
||||||
|
|
||||||
m_sig_vsync = (m_vsync_filter > m_vsync_threshold) ? 1 : 0;
|
m_sig_vsync = (m_vsync_filter > m_desc.m_vsync_threshold) ? 1 : 0;
|
||||||
|
|
||||||
if (!last_vsync && m_sig_vsync)
|
if (!last_vsync && m_sig_vsync)
|
||||||
{
|
{
|
||||||
//LOG("VSYNC %d %d\n", m_last_x, m_last_y + m_sig_field);
|
LOG("VSYNC UP %f %d\n", m_last_x, m_last_y);
|
||||||
m_last_y = m_desc.m_vbackporch - m_desc.m_vsync;
|
m_intf.vsync_end_cb(time - m_last_vsync_time);
|
||||||
m_intf.vsync_start_cb(std::max(time - m_last_vsync_time, m_min_frame_period));
|
|
||||||
m_last_vsync_time = time;
|
m_last_vsync_time = time;
|
||||||
|
// FIXME: this is wrong: we need to count lines with half-scanline width
|
||||||
|
// to determine the field.
|
||||||
|
m_sig_field = last_comp; /* force false-progressive */
|
||||||
|
m_sig_field = (m_sig_field ^ 1) ^ last_comp; /* if there is no field switch, auto switch */
|
||||||
|
m_last_y = 0; //m_desc.vbackporch_width();
|
||||||
}
|
}
|
||||||
else if (last_vsync && !m_sig_vsync)
|
else if (last_vsync && !m_sig_vsync)
|
||||||
{
|
{
|
||||||
m_sig_field = last_comp; /* force false-progressive */
|
LOG("VSYNC DOWN %f %d\n", m_last_x, m_last_y);
|
||||||
m_sig_field = (m_sig_field ^ 1) ^ last_comp; /* if there is no field switch, auto switch */
|
|
||||||
//LOG("Field: %d\n", m_sig_field);
|
//LOG("Field: %d\n", m_sig_field);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!last_comp && m_sig_composite)
|
if (!last_comp && m_sig_composite)
|
||||||
{
|
{
|
||||||
|
if (m_sig_vsync)
|
||||||
|
LOG("Hsync in vsync\n");
|
||||||
/* TODO - time since last hsync and field detection */
|
/* TODO - time since last hsync and field detection */
|
||||||
//LOG("HSYNC up %d\n", m_last_x);
|
//LOG("HSYNC up %d\n", m_last_x);
|
||||||
// FIXME: pixels > 50 filters some spurious hysnc on line 27 in breakout
|
// FIXME: pixels > 50 filters some spurious hysnc on line 23/24 in breakout
|
||||||
|
// The hsync signal transition from high to low is 7 pixels too
|
||||||
|
// early, goes up again after 6.8 pix and down after 7.2 pix.
|
||||||
|
// Therefore we need to filter early low to high transitions
|
||||||
|
// and base hsync on the start of the hsync signal.
|
||||||
if (!m_sig_vsync && (m_last_x > m_desc.m_hscale * 100))
|
if (!m_sig_vsync && (m_last_x > m_desc.m_hscale * 100))
|
||||||
{
|
{
|
||||||
m_last_y += m_desc.m_fieldcount;
|
m_last_y += m_desc.m_fieldcount;
|
||||||
m_last_x = 0;
|
m_last_x = 0;
|
||||||
m_line_time = time;
|
m_line_time = time + 1.0 / m_desc.hsync_filter_timeconst();
|
||||||
}
|
}
|
||||||
//if (m_last_y == 27) printf("HSYNC up %d %d\n", m_last_y, pixels);
|
//if (!m_sig_vsync && (m_last_x < m_desc.m_hscale * 100))
|
||||||
|
// printf("HSYNC up %d %f\n", m_last_y, m_last_x);
|
||||||
}
|
}
|
||||||
else if (last_comp && !m_sig_composite)
|
else if (last_comp && !m_sig_composite)
|
||||||
{
|
{
|
||||||
/* falling composite */
|
/* falling composite */
|
||||||
//LOG("HSYNC down %f %d %f\n", time * 1e6, m_last_x, m_sync_signal);
|
//LOG("HSYNC down %f %d %f\n", time * 1e6, m_last_x, m_sync_signal);
|
||||||
}
|
}
|
||||||
|
m_last_sync = newval;
|
||||||
m_sync_signal = newval;
|
|
||||||
m_last_sync_time = time;
|
m_last_sync_time = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fixedfreq_monitor_state::update_bm(const time_type &time)
|
void fixedfreq_monitor_state::update_bm(const time_type &time)
|
||||||
{
|
{
|
||||||
const float pixels = (time - m_line_time) * static_cast<time_type>(m_desc.m_hscale) / m_clock_period;
|
const float pixels = (time - m_line_time) * (double) m_desc.monitor_clock();
|
||||||
const int has_fields = (m_desc.m_fieldcount > 1) ? 1: 0;
|
const int has_fields = (m_desc.m_fieldcount > 1) ? 1: 0;
|
||||||
|
float fhscale(static_cast<float>(m_desc.m_hscale));
|
||||||
|
|
||||||
uint32_t col(0xffff0000); // Mark sync areas
|
//uint32_t col(0xffff0000); // Mark sync areas
|
||||||
|
|
||||||
if (m_sync_signal >= m_desc.m_sync_threshold)
|
//if (m_last_sync >= m_desc.m_sync_threshold)
|
||||||
col = m_col;
|
// col = m_col;
|
||||||
|
|
||||||
m_fragments.push_back({static_cast<float>(m_last_y + m_sig_field * has_fields), m_last_x, pixels, col});
|
if (!m_sig_vsync && !m_sig_composite)
|
||||||
|
{
|
||||||
|
m_fragments.push_back({static_cast<float>(m_last_y + m_sig_field * has_fields),
|
||||||
|
m_last_x * fhscale, pixels * fhscale, m_col});
|
||||||
|
}
|
||||||
//m_intf.plot_hline(m_last_x, m_last_y + m_sig_field * has_fields, pixels, col);
|
//m_intf.plot_hline(m_last_x, m_last_y + m_sig_field * has_fields, pixels, col);
|
||||||
m_last_x = pixels;
|
m_last_x = pixels;
|
||||||
}
|
}
|
||||||
@ -102,11 +144,13 @@ void fixedfreq_monitor_state::update_composite_monochrome(const time_type &time,
|
|||||||
update_bm(time);
|
update_bm(time);
|
||||||
update_sync_channel(time, data);
|
update_sync_channel(time, data);
|
||||||
|
|
||||||
int colv = (int) ((data - m_desc.m_sync_threshold) * m_desc.m_gain * 255.0);
|
//int colv = (int) ((data - m_desc.m_sync_threshold) * m_desc.m_gain * 255.0);
|
||||||
|
int colv = (int) ((data - 1.5) * m_desc.m_gain * 255.0);
|
||||||
if (colv > 255)
|
if (colv > 255)
|
||||||
colv = 255;
|
colv = 255;
|
||||||
if (colv < 0)
|
if (colv < 0)
|
||||||
m_col = 0xffff0000;
|
//m_col = 0xffff0000;
|
||||||
|
m_col = 0x0000000;
|
||||||
else
|
else
|
||||||
m_col = 0xff000000 | (colv<<16) | (colv<<8) | colv;
|
m_col = 0xff000000 | (colv<<16) | (colv<<8) | colv;
|
||||||
}
|
}
|
||||||
@ -159,9 +203,9 @@ void fixedfreq_monitor_state::update_sync(const time_type &time, const double da
|
|||||||
fixedfreq_device::fixedfreq_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
fixedfreq_device::fixedfreq_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||||
: device_t(mconfig, type, tag, owner, clock),
|
: device_t(mconfig, type, tag, owner, clock),
|
||||||
device_video_interface(mconfig, *this, false),
|
device_video_interface(mconfig, *this, false),
|
||||||
m_htotal(0),
|
m_force_vector(false),
|
||||||
m_vtotal(0),
|
m_scanline_height(1.0),
|
||||||
m_refresh_period(time_type(0)),
|
m_texture(nullptr),
|
||||||
m_monitor(),
|
m_monitor(),
|
||||||
m_state(m_monitor, *this)
|
m_state(m_monitor, *this)
|
||||||
{
|
{
|
||||||
@ -176,103 +220,222 @@ void fixedfreq_device::device_config_complete()
|
|||||||
{
|
{
|
||||||
if (!has_screen())
|
if (!has_screen())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!screen().refresh_attoseconds())
|
if (!screen().refresh_attoseconds())
|
||||||
screen().set_raw(m_monitor.m_monitor_clock, m_monitor.m_hbackporch, 0,
|
screen().set_raw(m_monitor.m_monitor_clock, m_monitor.htotal(), 0,
|
||||||
m_monitor.m_hbackporch, m_monitor.m_vbackporch, 0,
|
m_monitor.htotal(), m_monitor.vtotal(), 0,
|
||||||
m_monitor.m_vbackporch);
|
m_monitor.vtotal());
|
||||||
|
|
||||||
if (!screen().has_screen_update())
|
if (!screen().has_screen_update())
|
||||||
screen().set_screen_update(*this, FUNC(fixedfreq_device::screen_update));
|
screen().set_screen_update(*this, FUNC(fixedfreq_device::screen_update));
|
||||||
|
LOG("config complete\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void fixedfreq_device::device_start()
|
void fixedfreq_device::device_start()
|
||||||
{
|
{
|
||||||
|
|
||||||
m_refresh_period = time_type(0);
|
|
||||||
|
|
||||||
m_htotal = m_monitor.m_hbackporch;
|
|
||||||
m_vtotal = m_monitor.m_vbackporch;
|
|
||||||
|
|
||||||
m_state.start();
|
m_state.start();
|
||||||
|
if (m_texture == nullptr)
|
||||||
|
create_texture();
|
||||||
|
|
||||||
// FIXME: will be done by netlist going forward
|
// FIXME: will be done by netlist going forward
|
||||||
save_item(NAME(m_state.m_sync_signal));
|
save_item(NAME(m_state.m_last_sync));
|
||||||
save_item(NAME(m_state.m_last_x));
|
save_item(NAME(m_state.m_last_x));
|
||||||
save_item(NAME(m_state.m_last_y));
|
save_item(NAME(m_state.m_last_y));
|
||||||
save_item(NAME(m_state.m_last_sync_time));
|
save_item(NAME(m_state.m_last_sync_time));
|
||||||
save_item(NAME(m_state.m_line_time));
|
save_item(NAME(m_state.m_line_time));
|
||||||
save_item(NAME(m_state.m_last_hsync_time));
|
save_item(NAME(m_state.m_last_hsync_time));
|
||||||
save_item(NAME(m_state.m_last_vsync_time));
|
save_item(NAME(m_state.m_last_vsync_time));
|
||||||
save_item(NAME(m_refresh_period));
|
|
||||||
save_item(NAME(m_state.m_clock_period));
|
|
||||||
|
|
||||||
/* sync separator */
|
/* sync separator */
|
||||||
save_item(NAME(m_state.m_vsync_filter));
|
save_item(NAME(m_state.m_vsync_filter));
|
||||||
save_item(NAME(m_state.m_vsync_threshold));
|
|
||||||
save_item(NAME(m_state.m_vsync_filter_timeconst));
|
|
||||||
|
|
||||||
save_item(NAME(m_state.m_sig_vsync));
|
save_item(NAME(m_state.m_sig_vsync));
|
||||||
save_item(NAME(m_state.m_sig_composite));
|
save_item(NAME(m_state.m_sig_composite));
|
||||||
save_item(NAME(m_state.m_sig_field));
|
save_item(NAME(m_state.m_sig_field));
|
||||||
|
LOG("start\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void fixedfreq_device::device_reset()
|
void fixedfreq_device::device_reset()
|
||||||
{
|
{
|
||||||
m_state.reset();
|
m_state.reset();
|
||||||
|
LOG("Reset\n");
|
||||||
|
//ioport("YYY")->field(0xffff)->live().value = 20;
|
||||||
|
#if 0
|
||||||
|
//IOPORT_ID(HVISIBLE)->field(~0)->set_value(m_monitor.m_hvisible);
|
||||||
|
//IOPORT_ID(HVISIBLE)->update_defvalue(false);
|
||||||
|
IOPORT_ID(HVISIBLE)->live().defvalue = m_monitor.m_hvisible;
|
||||||
|
IOPORT_ID(HFRONTPORCH)->write(m_monitor.m_hsync);
|
||||||
|
IOPORT_ID(HSYNC)->write(m_monitor.m_hfrontporch);
|
||||||
|
IOPORT_ID(HBACKPORCH)->write(m_monitor.m_hbackporch);
|
||||||
|
IOPORT_ID(VVISIBLE)->write(m_monitor.m_vvisible);
|
||||||
|
IOPORT_ID(VFRONTPORCH)->write(m_monitor.m_vfrontporch);
|
||||||
|
IOPORT_ID(VSYNC)->write(m_monitor.m_vsync);
|
||||||
|
IOPORT_ID(VBACKPORCH)->write(m_monitor.m_vbackporch);
|
||||||
|
IOPORT_ID(SYNCTHRESHOLD)->write(m_monitor.m_sync_threshold * 1000.0);
|
||||||
|
IOPORT_ID(GAIN)->write(m_monitor.m_gain * 1000.0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void fixedfreq_device::device_post_load()
|
void fixedfreq_device::device_post_load()
|
||||||
{
|
{
|
||||||
//recompute_parameters();
|
//recompute_parameters();
|
||||||
|
LOG("post load\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void fixedfreq_device::create_texture()
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
//if (m_texture == nullptr)
|
||||||
|
{
|
||||||
|
m_bitmap = std::make_unique<bitmap_argb32>();
|
||||||
|
m_texture = machine().render().texture_alloc(); // render_texture::hq_scale
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
emu_file crossfile(m_machine.options().crosshair_path(), OPEN_FLAG_READ);
|
||||||
|
if (!m_name.empty())
|
||||||
|
{
|
||||||
|
// look for user specified file
|
||||||
|
std::string filename = m_name + ".png";
|
||||||
|
render_load_png(*m_bitmap, crossfile, nullptr, filename.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// look for default cross?.png in crsshair/game dir
|
||||||
|
std::string filename = string_format("cross%d.png", m_player + 1);
|
||||||
|
render_load_png(*m_bitmap, crossfile, m_machine.system().name, filename.c_str());
|
||||||
|
|
||||||
|
// look for default cross?.png in crsshair dir
|
||||||
|
if (!m_bitmap->valid())
|
||||||
|
render_load_png(*m_bitmap, crossfile, nullptr, filename.c_str());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* if that didn't work, use the built-in one */
|
||||||
|
if (!m_bitmap->valid())
|
||||||
|
{
|
||||||
|
const int WX = 1;
|
||||||
|
const int WY = 16;
|
||||||
|
/* allocate a blank bitmap to start with */
|
||||||
|
m_bitmap->allocate(WX, WY);
|
||||||
|
m_bitmap->fill(rgb_t(0x00,0xff,0xff,0xff));
|
||||||
|
|
||||||
|
/* extract the raw source data to it */
|
||||||
|
for (y = 0; y < WY / 2; y++)
|
||||||
|
{
|
||||||
|
/* assume it is mirrored vertically */
|
||||||
|
u32 *dest0 = &m_bitmap->pix32(y);
|
||||||
|
u32 *dest1 = &m_bitmap->pix32(WY - 1 - y);
|
||||||
|
|
||||||
|
/* extract to two rows simultaneously */
|
||||||
|
for (x = 0; x < WX; x++)
|
||||||
|
{
|
||||||
|
uint8_t t = 255 / (WY/2 - y);
|
||||||
|
dest0[x] = dest1[x] = rgb_t(0xff,t,t,t);
|
||||||
|
//dest0[x] = dest1[x] = rgb_t(t, 0xff,0xff,0xff);
|
||||||
|
//dest0[x] = dest1[x] = rgb_t(t,t,t,t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reference the new bitmap */
|
||||||
|
m_texture->set_bitmap(*m_bitmap, m_bitmap->cliprect(), TEXFORMAT_ARGB32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t nom_col(uint32_t col)
|
||||||
|
{
|
||||||
|
float r = ((col >> 16) & 0xff);
|
||||||
|
float g = ((col >> 8) & 0xff);
|
||||||
|
float b = ((col >> 0) & 0xff);
|
||||||
|
|
||||||
|
float m = std::max(r, std::max(g,b));
|
||||||
|
if (m == 0.0f)
|
||||||
|
return 0;
|
||||||
|
return (((uint32_t) m ) << 24) | (((uint32_t) (r/m*255.0f) ) << 16)
|
||||||
|
| (((uint32_t) (g/m*255.0f) ) << 8) | (((uint32_t) (b/m*255.0f) ) << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t fixedfreq_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
uint32_t fixedfreq_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||||
{
|
{
|
||||||
|
//printf("%f %f\n", m_state.m_fragments[0].y, m_state.m_fragments[m_state.m_fragments.size()-1].y);
|
||||||
if (screen.screen_type() == SCREEN_TYPE_RASTER)
|
if (!m_force_vector && screen.screen_type() == SCREEN_TYPE_RASTER)
|
||||||
{
|
{
|
||||||
|
bitmap.fill(rgb_t(0xff, 0xff, 0x00, 0x00));
|
||||||
for (auto &f : m_state.m_fragments)
|
for (auto &f : m_state.m_fragments)
|
||||||
if (f.y < bitmap.height())
|
if (f.y < bitmap.height())
|
||||||
bitmap.plot_box(f.x, f.y, f.xr - f.x, 1, f.col);
|
bitmap.plot_box(f.x, f.y, f.xr - f.x, 1, f.col);
|
||||||
}
|
}
|
||||||
else if (screen.screen_type() == SCREEN_TYPE_VECTOR)
|
else if (m_force_vector || screen.screen_type() == SCREEN_TYPE_VECTOR)
|
||||||
{
|
{
|
||||||
constexpr const uint32_t flags(PRIMFLAG_ANTIALIAS(1) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_VECTOR(1));
|
if (m_texture == nullptr)
|
||||||
|
create_texture();
|
||||||
|
|
||||||
|
const uint32_t flags(PRIMFLAG_ANTIALIAS(1)
|
||||||
|
| PRIMFLAG_BLENDMODE(BLENDMODE_ADD)
|
||||||
|
| (screen.screen_type() == SCREEN_TYPE_VECTOR ? PRIMFLAG_VECTOR(1) : 0));
|
||||||
const rectangle &visarea = screen.visible_area();
|
const rectangle &visarea = screen.visible_area();
|
||||||
float xscale = 1.0f / visarea.width();
|
float xscale = 1.0f / (float)visarea.width();
|
||||||
float yscale = 1.0f / visarea.height();
|
float yscale = 1.0f / (float)visarea.height();
|
||||||
float xoffs = (float)visarea.min_x;
|
float xoffs = (float)visarea.min_x;
|
||||||
float yoffs = (float)visarea.min_y;
|
float yoffs = (float)visarea.min_y;
|
||||||
screen.container().empty();
|
screen.container().empty();
|
||||||
screen.container().add_rect(0.0f, 0.0f, 1.0f, 1.0f, rgb_t(0xff,0x00,0x00,0x00), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_VECTORBUF(1));
|
screen.container().add_rect(0.0f, 0.0f, 1.0f, 1.0f, rgb_t(0xff,0x00,0x00,0x00),
|
||||||
|
PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)
|
||||||
|
| (screen.screen_type() == SCREEN_TYPE_VECTOR ? PRIMFLAG_VECTORBUF(1) : 0));
|
||||||
|
|
||||||
|
float last_y = -1e6;
|
||||||
for (auto &f : m_state.m_fragments)
|
for (auto &f : m_state.m_fragments)
|
||||||
|
{
|
||||||
|
|
||||||
|
// FIXME: Debug check for proper vsync timing
|
||||||
|
if (f.y >= last_y)
|
||||||
{
|
{
|
||||||
const float x0((f.x - xoffs) * xscale);
|
const float x0((f.x - xoffs) * xscale);
|
||||||
const float y0((f.y - yoffs) * yscale);
|
const float y0((f.y - yoffs) * yscale);
|
||||||
const float x1((f.xr - xoffs) * xscale);
|
const float x1((f.xr - xoffs) * xscale);
|
||||||
const float y1((f.y + 1.0f - yoffs) * yscale);
|
#if 0
|
||||||
|
auto w = m_scanline_height * xscale * 0.5;
|
||||||
|
screen.container().add_line(
|
||||||
|
x0+w, y0, x1-w, y0, m_scanline_height*yscale,
|
||||||
|
nom_col(f.col),
|
||||||
|
// (0xff << 24) | (f.col & 0xffffff),
|
||||||
|
flags);
|
||||||
|
#elif 1
|
||||||
|
const float y1((f.y + m_scanline_height - yoffs) * yscale);
|
||||||
screen.container().add_rect(
|
screen.container().add_rect(
|
||||||
x0, y0, x1, y1,
|
x0, y0, x1, y1,
|
||||||
(0xff << 24) | (f.col & 0xffffff),
|
nom_col(f.col),
|
||||||
|
// (0xaf << 24) | (f.col & 0xffffff),
|
||||||
flags);
|
flags);
|
||||||
|
#else
|
||||||
|
const float y1((f.y + m_scanline_height - yoffs) * yscale);
|
||||||
|
// Crashes with bgfx
|
||||||
|
screen.container().add_quad(
|
||||||
|
x0, y0, x1, y1,
|
||||||
|
rgb_t(nom_col(f.col)),
|
||||||
|
// (0xaf << 24) | (f.col & 0xffffff),
|
||||||
|
m_texture,
|
||||||
|
flags);
|
||||||
|
#endif
|
||||||
|
last_y = f.y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_state.m_fragments.clear();
|
m_state.m_fragments.clear();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fixedfreq_device::vsync_start_cb(double refresh_time)
|
void fixedfreq_device::vsync_end_cb(double refresh_time)
|
||||||
{
|
{
|
||||||
// toggle bitmap
|
const auto expected_frame_period(m_monitor.clock_period() * m_monitor.vtotal() * m_monitor.htotal());
|
||||||
//m_cur_bm ^= 1;
|
|
||||||
|
const auto refresh_limited(std::min(4.0 * expected_frame_period,
|
||||||
|
std::max(refresh_time, 0.25 * expected_frame_period)));
|
||||||
|
|
||||||
rectangle visarea(m_monitor.minh(), m_monitor.maxh(), m_monitor.minv(), m_monitor.maxv());
|
rectangle visarea(m_monitor.minh(), m_monitor.maxh(), m_monitor.minv(), m_monitor.maxv());
|
||||||
|
|
||||||
m_refresh_period = refresh_time;
|
screen().configure(m_monitor.htotal_scaled(), m_monitor.vtotal(), visarea, DOUBLE_TO_ATTOSECONDS(refresh_limited));
|
||||||
screen().configure(m_htotal * m_monitor.m_hscale, m_vtotal, visarea, DOUBLE_TO_ATTOSECONDS(m_refresh_period));
|
screen().reset_origin(m_state.m_last_y-(m_monitor.vsync_width() + m_monitor.vbackporch_width()), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_composite_monochrome)
|
NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_composite_monochrome)
|
||||||
@ -316,3 +479,138 @@ NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_sync)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
static INPUT_PORTS_START(fixedfreq_base_ports)
|
||||||
|
PORT_START("ENABLE")
|
||||||
|
PORT_CONFNAME( 0x01, 0x00, "Display Monitor sliders" )
|
||||||
|
PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
|
||||||
|
PORT_CONFSETTING( 0x01, DEF_STR( On ) )
|
||||||
|
|
||||||
|
PORT_ADJUSTERX(HVISIBLE, "H Visible", 10, 1000)
|
||||||
|
PORT_ADJUSTERX(HFRONTPORCH, "H Front porch width", 1, 100)
|
||||||
|
PORT_ADJUSTERX(HSYNC, "H Sync width", 1, 100)
|
||||||
|
PORT_ADJUSTERX(HBACKPORCH, "H Back porch width", 1, 1000)
|
||||||
|
PORT_ADJUSTERX(VVISIBLE, "V Visible", 1, 1000)
|
||||||
|
PORT_ADJUSTERX(VFRONTPORCH, "V Front porch width", 0, 100)
|
||||||
|
PORT_ADJUSTERX(VSYNC, "V Sync width", 1, 100)
|
||||||
|
PORT_ADJUSTERX(VBACKPORCH, "V Back porch width", 1, 100)
|
||||||
|
PORT_ADJUSTERX(SYNCTHRESHOLD, "Sync threshold mV", 10, 2000)
|
||||||
|
PORT_ADJUSTERX(VSYNCTHRESHOLD, "V Sync threshold mV", 10, 1000)
|
||||||
|
PORT_ADJUSTERX(GAIN, "Signal Gain", 10, 1000)
|
||||||
|
PORT_ADJUSTERX(SCANLINE_HEIGHT, "Scanline Height", 10, 300)
|
||||||
|
INPUT_PORTS_END
|
||||||
|
|
||||||
|
|
||||||
|
static INPUT_PORTS_START(fixedfreq_raster_ports)
|
||||||
|
PORT_START("ZZZ")
|
||||||
|
PORT_CONFNAME( 0x01, 0x00, "Use vector rendering" ) PORT_CHANGED_MEMBER(DEVICE_SELF, fixedfreq_device, port_changed, USE_VECTOR)
|
||||||
|
PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
|
||||||
|
PORT_CONFSETTING( 0x01, DEF_STR( On ) )
|
||||||
|
|
||||||
|
PORT_INCLUDE(fixedfreq_base_ports)
|
||||||
|
|
||||||
|
PORT_START("YYY")
|
||||||
|
PORT_ADJUSTER(50, "TEST")
|
||||||
|
INPUT_PORTS_END
|
||||||
|
|
||||||
|
static INPUT_PORTS_START(fixedfreq_vector_ports)
|
||||||
|
PORT_INCLUDE(fixedfreq_base_ports)
|
||||||
|
INPUT_PORTS_END
|
||||||
|
|
||||||
|
ioport_constructor fixedfreq_device::device_input_ports() const
|
||||||
|
{
|
||||||
|
LOG("input ports\n");
|
||||||
|
if (screen().screen_type() == SCREEN_TYPE_RASTER)
|
||||||
|
return INPUT_PORTS_NAME(fixedfreq_raster_ports);
|
||||||
|
else
|
||||||
|
return INPUT_PORTS_NAME(fixedfreq_vector_ports);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned fixedfreq_device::monitor_val(unsigned param) const
|
||||||
|
{
|
||||||
|
switch (param)
|
||||||
|
{
|
||||||
|
case HVISIBLE:
|
||||||
|
return m_monitor.hvisible_width();
|
||||||
|
case HFRONTPORCH:
|
||||||
|
return m_monitor.hfrontporch_width();
|
||||||
|
case HSYNC:
|
||||||
|
return m_monitor.hsync_width();
|
||||||
|
case HBACKPORCH:
|
||||||
|
return m_monitor.hbackporch_width();
|
||||||
|
case VVISIBLE:
|
||||||
|
return m_monitor.vvisible_width();
|
||||||
|
case VFRONTPORCH:
|
||||||
|
return m_monitor.vfrontporch_width();
|
||||||
|
case VSYNC:
|
||||||
|
return m_monitor.vsync_width();
|
||||||
|
case VBACKPORCH:
|
||||||
|
return m_monitor.vbackporch_width();
|
||||||
|
case SYNCTHRESHOLD:
|
||||||
|
return m_monitor.m_sync_threshold * 1000.0;
|
||||||
|
case VSYNCTHRESHOLD:
|
||||||
|
return m_monitor.m_vsync_threshold * 1000.0;
|
||||||
|
case GAIN:
|
||||||
|
return m_monitor.m_gain * 100.0;
|
||||||
|
case SCANLINE_HEIGHT:
|
||||||
|
return m_scanline_height * 100.0;
|
||||||
|
case USE_VECTOR:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
INPUT_CHANGED_MEMBER(fixedfreq_device::port_changed)
|
||||||
|
{
|
||||||
|
auto &m(m_monitor);
|
||||||
|
|
||||||
|
LOG("%d %d\n", param, newval);
|
||||||
|
switch (param)
|
||||||
|
{
|
||||||
|
case HVISIBLE:
|
||||||
|
m.set_h_rel(newval, m.hfrontporch_width(), m.hsync_width(), m.hbackporch_width());
|
||||||
|
break;
|
||||||
|
case HFRONTPORCH:
|
||||||
|
m.set_h_rel(m.hvisible_width(), newval, m.hsync_width(), m.hbackporch_width());
|
||||||
|
break;
|
||||||
|
case HSYNC:
|
||||||
|
m.set_h_rel(m.hvisible_width(), m.hfrontporch_width(), newval, m.hbackporch_width());
|
||||||
|
break;
|
||||||
|
case HBACKPORCH:
|
||||||
|
m.set_h_rel(m.hvisible_width(), m.hfrontporch_width(), m.hsync_width(), newval);
|
||||||
|
break;
|
||||||
|
case VVISIBLE:
|
||||||
|
m.set_v_rel(newval, m.vfrontporch_width(), m.vsync_width(), m.vbackporch_width());
|
||||||
|
break;
|
||||||
|
case VFRONTPORCH:
|
||||||
|
m.set_v_rel(m.vvisible_width(), newval, m.vsync_width(), m.vbackporch_width());
|
||||||
|
break;
|
||||||
|
case VSYNC:
|
||||||
|
m.set_v_rel(m.vvisible_width(), m.vfrontporch_width(), newval, m.vbackporch_width());
|
||||||
|
break;
|
||||||
|
case VBACKPORCH:
|
||||||
|
m.set_v_rel(m.vvisible_width(), m.vfrontporch_width(), m.vsync_width(), newval);
|
||||||
|
break;
|
||||||
|
case SYNCTHRESHOLD:
|
||||||
|
m.m_sync_threshold = static_cast<double>(newval) / 1000.0;
|
||||||
|
break;
|
||||||
|
case VSYNCTHRESHOLD:
|
||||||
|
m.m_vsync_threshold = static_cast<double>(newval) / 1000.0;
|
||||||
|
break;
|
||||||
|
case GAIN:
|
||||||
|
m.m_gain = static_cast<double>(newval) / 100.0;
|
||||||
|
break;
|
||||||
|
case SCANLINE_HEIGHT:
|
||||||
|
m_scanline_height = static_cast<double>(newval) / 100.0;
|
||||||
|
break;
|
||||||
|
case USE_VECTOR:
|
||||||
|
if (screen().screen_type() == SCREEN_TYPE_RASTER)
|
||||||
|
{
|
||||||
|
m_force_vector = newval;
|
||||||
|
screen().set_video_attributes(newval ? VIDEO_SELF_RENDER : 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
machine().ui().popup_time(5, "Screen Dim %d x %d\n", m.htotal(), m.vtotal());
|
||||||
|
//ioport("YYY")->update_defvalue(true);
|
||||||
|
}
|
||||||
|
@ -22,6 +22,11 @@ struct fixedfreq_monitor_desc
|
|||||||
fixedfreq_monitor_desc()
|
fixedfreq_monitor_desc()
|
||||||
// default to NTSC "704x480@30i"
|
// default to NTSC "704x480@30i"
|
||||||
: m_monitor_clock(13500000),
|
: m_monitor_clock(13500000),
|
||||||
|
m_fieldcount(2),
|
||||||
|
m_sync_threshold(0.3),
|
||||||
|
m_gain(1.0 / 3.7),
|
||||||
|
m_hscale(1),
|
||||||
|
m_vsync_threshold(0.600), // trigger at 91.5% of vsync length 1-exp(-0.96)
|
||||||
m_hvisible(704),
|
m_hvisible(704),
|
||||||
m_hfrontporch(728),
|
m_hfrontporch(728),
|
||||||
m_hsync(791),
|
m_hsync(791),
|
||||||
@ -29,19 +34,64 @@ struct fixedfreq_monitor_desc
|
|||||||
m_vvisible(480),
|
m_vvisible(480),
|
||||||
m_vfrontporch(486),
|
m_vfrontporch(486),
|
||||||
m_vsync(492),
|
m_vsync(492),
|
||||||
m_vbackporch(525),
|
m_vbackporch(525)
|
||||||
m_fieldcount(2),
|
|
||||||
m_sync_threshold(0.3),
|
|
||||||
m_gain(1.0 / 3.7),
|
|
||||||
m_hscale(1)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
int minh() const { return (m_hbackporch - m_hfrontporch) * m_hscale; }
|
uint32_t monitor_clock() const noexcept { return m_monitor_clock; }
|
||||||
int maxh() const { return (m_hbackporch - m_hfrontporch + m_hvisible) * m_hscale - 1; }
|
double clock_period() const noexcept { return 1.0 / (double) m_monitor_clock; };
|
||||||
int minv() const { return m_vbackporch - m_vfrontporch; }
|
|
||||||
int maxv() const { return m_vbackporch - m_vfrontporch + m_vvisible - 1; }
|
int minh() const noexcept { return (m_hbackporch - m_hsync) * m_hscale; }
|
||||||
|
int maxh() const noexcept { return (m_hbackporch - m_hsync + m_hvisible) * m_hscale - 1; }
|
||||||
|
int minv() const noexcept { return m_vbackporch - m_vsync; }
|
||||||
|
int maxv() const noexcept { return m_vbackporch - m_vsync + m_vvisible - 1; }
|
||||||
|
|
||||||
|
int htotal_scaled() const noexcept { return m_hbackporch * m_hscale; }
|
||||||
|
|
||||||
|
int vbackporch_width() const noexcept { return m_vbackporch - m_vsync; }
|
||||||
|
int vsync_width() const noexcept { return m_vsync - m_vfrontporch; }
|
||||||
|
int vfrontporch_width() const noexcept { return m_vfrontporch - m_vvisible; }
|
||||||
|
int vvisible_width() const noexcept { return m_vvisible; }
|
||||||
|
int vtotal() const noexcept { return m_vbackporch; }
|
||||||
|
|
||||||
|
int hbackporch_width() const noexcept { return m_hbackporch - m_hsync; }
|
||||||
|
int hsync_width() const noexcept { return m_hsync - m_hfrontporch; }
|
||||||
|
int hfrontporch_width() const noexcept { return m_hfrontporch - m_hvisible; }
|
||||||
|
int hvisible_width() const noexcept { return m_hvisible; }
|
||||||
|
int htotal() const noexcept { return m_hbackporch; }
|
||||||
|
|
||||||
|
void set_h_rel(int vw, int fpw, int sw, int bpw)
|
||||||
|
{
|
||||||
|
m_hvisible = vw;
|
||||||
|
m_hfrontporch = m_hvisible + fpw;
|
||||||
|
m_hsync = m_hfrontporch + sw;
|
||||||
|
m_hbackporch = m_hsync + bpw;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_v_rel(int vw, int fpw, int sw, int bpw)
|
||||||
|
{
|
||||||
|
m_vvisible = vw;
|
||||||
|
m_vfrontporch = m_vvisible + fpw;
|
||||||
|
m_vsync = m_vfrontporch + sw;
|
||||||
|
m_vbackporch = m_vsync + bpw;
|
||||||
|
}
|
||||||
|
|
||||||
|
double vsync_filter_timeconst() const noexcept
|
||||||
|
{
|
||||||
|
return (double) (m_monitor_clock) / ((double) m_hbackporch * vsync_width());
|
||||||
|
}
|
||||||
|
|
||||||
|
double hsync_filter_timeconst() const noexcept
|
||||||
|
{
|
||||||
|
return (double) m_monitor_clock / (double) hsync_width();
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t m_monitor_clock;
|
uint32_t m_monitor_clock;
|
||||||
|
int m_fieldcount;
|
||||||
|
double m_sync_threshold;
|
||||||
|
double m_gain;
|
||||||
|
int m_hscale;
|
||||||
|
double m_vsync_threshold;
|
||||||
|
private:
|
||||||
int m_hvisible;
|
int m_hvisible;
|
||||||
int m_hfrontporch;
|
int m_hfrontporch;
|
||||||
int m_hsync;
|
int m_hsync;
|
||||||
@ -50,16 +100,12 @@ struct fixedfreq_monitor_desc
|
|||||||
int m_vfrontporch;
|
int m_vfrontporch;
|
||||||
int m_vsync;
|
int m_vsync;
|
||||||
int m_vbackporch;
|
int m_vbackporch;
|
||||||
int m_fieldcount;
|
|
||||||
double m_sync_threshold;
|
|
||||||
double m_gain;
|
|
||||||
int m_hscale;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fixedfreq_monitor_intf
|
struct fixedfreq_monitor_intf
|
||||||
{
|
{
|
||||||
virtual ~fixedfreq_monitor_intf() = default;
|
virtual ~fixedfreq_monitor_intf() = default;
|
||||||
virtual void vsync_start_cb(double refresh_time) = 0;
|
virtual void vsync_end_cb(double refresh_time) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fixedfreq_monitor_line
|
struct fixedfreq_monitor_line
|
||||||
@ -77,7 +123,7 @@ struct fixedfreq_monitor_state
|
|||||||
fixedfreq_monitor_state(fixedfreq_monitor_desc &desc, fixedfreq_monitor_intf &intf)
|
fixedfreq_monitor_state(fixedfreq_monitor_desc &desc, fixedfreq_monitor_intf &intf)
|
||||||
: m_desc(desc),
|
: m_desc(desc),
|
||||||
m_intf(intf),
|
m_intf(intf),
|
||||||
m_sync_signal(0),
|
m_last_sync(0),
|
||||||
m_col(0),
|
m_col(0),
|
||||||
m_last_x(0),
|
m_last_x(0),
|
||||||
m_last_y(0),
|
m_last_y(0),
|
||||||
@ -85,14 +131,10 @@ struct fixedfreq_monitor_state
|
|||||||
m_line_time(time_type(0)),
|
m_line_time(time_type(0)),
|
||||||
m_last_hsync_time(time_type(0)),
|
m_last_hsync_time(time_type(0)),
|
||||||
m_last_vsync_time(time_type(0)),
|
m_last_vsync_time(time_type(0)),
|
||||||
m_clock_period(time_type(0)),
|
|
||||||
m_vsync_filter(0),
|
m_vsync_filter(0),
|
||||||
m_vsync_threshold(0),
|
|
||||||
m_vsync_filter_timeconst(0),
|
|
||||||
m_sig_vsync(0),
|
m_sig_vsync(0),
|
||||||
m_sig_composite(0),
|
m_sig_composite(0),
|
||||||
m_sig_field(0),
|
m_sig_field(0)
|
||||||
m_min_frame_period(time_type(0))
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@ -103,7 +145,7 @@ struct fixedfreq_monitor_state
|
|||||||
// FIXME: once moved to netlist this may no longer be necessary.
|
// FIXME: once moved to netlist this may no longer be necessary.
|
||||||
// Only copies constructor init
|
// Only copies constructor init
|
||||||
|
|
||||||
m_sync_signal = 0.0;
|
m_last_sync = 0.0;
|
||||||
m_col = rgb_t(0,0,0);
|
m_col = rgb_t(0,0,0);
|
||||||
m_last_x = 0;
|
m_last_x = 0;
|
||||||
m_last_y = 0;
|
m_last_y = 0;
|
||||||
@ -111,12 +153,9 @@ struct fixedfreq_monitor_state
|
|||||||
m_line_time = time_type(0);
|
m_line_time = time_type(0);
|
||||||
m_last_hsync_time = time_type(0);
|
m_last_hsync_time = time_type(0);
|
||||||
m_last_vsync_time = time_type(0);
|
m_last_vsync_time = time_type(0);
|
||||||
m_clock_period = time_type(0);
|
|
||||||
|
|
||||||
/* sync separator */
|
/* sync separator */
|
||||||
m_vsync_filter = 0.0;
|
m_vsync_filter = 0.0;
|
||||||
m_vsync_threshold = 0.0;
|
|
||||||
m_vsync_filter_timeconst = 0.0;
|
|
||||||
|
|
||||||
m_sig_vsync = 0;
|
m_sig_vsync = 0;
|
||||||
m_sig_composite = 0;
|
m_sig_composite = 0;
|
||||||
@ -127,22 +166,18 @@ struct fixedfreq_monitor_state
|
|||||||
|
|
||||||
/* sync separator */
|
/* sync separator */
|
||||||
|
|
||||||
m_vsync_threshold = (exp(- 3.0/(3.0+3.0))) - exp(-1.0);
|
//m_vsync_threshold = (exp(- 3.0/(3.0+3.0))) - exp(-1.0);
|
||||||
m_vsync_filter_timeconst = (double) (m_desc.m_monitor_clock) / (double) m_desc.m_hbackporch * 1.0; // / (3.0 + 3.0);
|
//printf("trigger %f with len %f\n", m_vsync_threshold, 1e6 / m_vsync_filter_timeconst);
|
||||||
//LOG("trigger %f with len %f\n", m_vsync_threshold, 1e6 / m_vsync_filter_timeconst);
|
|
||||||
|
|
||||||
m_clock_period = 1.0 / m_desc.m_monitor_clock;
|
|
||||||
// Minimum frame period to be passed to video system ?
|
// Minimum frame period to be passed to video system ?
|
||||||
m_min_frame_period = 0.25 * m_clock_period * m_desc.m_vbackporch * m_desc.m_hbackporch;
|
|
||||||
|
|
||||||
m_fragments.clear();
|
m_fragments.clear();
|
||||||
|
|
||||||
m_intf.vsync_start_cb(m_min_frame_period);
|
m_intf.vsync_end_cb(m_desc.clock_period() * m_desc.vtotal() * m_desc.htotal());
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
m_sync_signal = 0;
|
m_last_sync = 0;
|
||||||
m_col = 0;
|
m_col = 0;
|
||||||
m_last_x = 0;
|
m_last_x = 0;
|
||||||
m_last_y = 0;
|
m_last_y = 0;
|
||||||
@ -171,7 +206,7 @@ struct fixedfreq_monitor_state
|
|||||||
const fixedfreq_monitor_desc &m_desc;
|
const fixedfreq_monitor_desc &m_desc;
|
||||||
fixedfreq_monitor_intf &m_intf;
|
fixedfreq_monitor_intf &m_intf;
|
||||||
|
|
||||||
double m_sync_signal;
|
double m_last_sync;
|
||||||
uint32_t m_col;
|
uint32_t m_col;
|
||||||
float m_last_x;
|
float m_last_x;
|
||||||
int m_last_y;
|
int m_last_y;
|
||||||
@ -179,17 +214,13 @@ struct fixedfreq_monitor_state
|
|||||||
time_type m_line_time;
|
time_type m_line_time;
|
||||||
time_type m_last_hsync_time;
|
time_type m_last_hsync_time;
|
||||||
time_type m_last_vsync_time;
|
time_type m_last_vsync_time;
|
||||||
time_type m_clock_period;
|
|
||||||
|
|
||||||
/* sync separator */
|
/* sync separator */
|
||||||
double m_vsync_filter;
|
double m_vsync_filter;
|
||||||
double m_vsync_threshold;
|
|
||||||
double m_vsync_filter_timeconst;
|
|
||||||
|
|
||||||
int m_sig_vsync;
|
int m_sig_vsync;
|
||||||
int m_sig_composite;
|
int m_sig_composite;
|
||||||
int m_sig_field;
|
int m_sig_field;
|
||||||
time_type m_min_frame_period;
|
|
||||||
std::vector<fixedfreq_monitor_line> m_fragments;
|
std::vector<fixedfreq_monitor_line> m_fragments;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -206,42 +237,48 @@ public:
|
|||||||
fixedfreq_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
|
fixedfreq_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
|
||||||
|
|
||||||
// inline configuration helpers
|
// inline configuration helpers
|
||||||
void set_monitor_clock(uint32_t clock) { m_monitor.m_monitor_clock = clock; }
|
fixedfreq_device &set_monitor_clock(uint32_t clock) { m_monitor.m_monitor_clock = clock; return *this;}
|
||||||
void set_fieldcount(int count) { m_monitor.m_fieldcount = count; }
|
fixedfreq_device &set_fieldcount(int count) { m_monitor.m_fieldcount = count; return *this; }
|
||||||
void set_threshold(double threshold) { m_monitor.m_sync_threshold = threshold; }
|
fixedfreq_device &set_threshold(double threshold) { m_monitor.m_sync_threshold = threshold; return *this; }
|
||||||
void set_gain(double gain) { m_monitor.m_gain = gain; }
|
fixedfreq_device &set_gain(double gain) { m_monitor.m_gain = gain; return *this; }
|
||||||
void set_horz_params(int visible, int frontporch, int sync, int backporch)
|
fixedfreq_device &set_horz_params(int visible, int frontporch, int sync, int backporch)
|
||||||
{
|
{
|
||||||
m_monitor.m_hvisible = visible;
|
m_monitor.set_h_rel(
|
||||||
m_monitor.m_hfrontporch = frontporch;
|
visible,
|
||||||
m_monitor.m_hsync = sync;
|
frontporch - visible,
|
||||||
m_monitor.m_hbackporch = backporch;
|
sync - frontporch,
|
||||||
|
backporch - sync);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
void set_vert_params(int visible, int frontporch, int sync, int backporch)
|
fixedfreq_device &set_vert_params(int visible, int frontporch, int sync, int backporch)
|
||||||
{
|
{
|
||||||
m_monitor.m_vvisible = visible;
|
m_monitor.set_v_rel(
|
||||||
m_monitor.m_vfrontporch = frontporch;
|
visible,
|
||||||
m_monitor.m_vsync = sync;
|
frontporch - visible,
|
||||||
m_monitor.m_vbackporch = backporch;
|
sync - frontporch,
|
||||||
|
backporch - sync);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
void set_horz_scale(int hscale) { m_monitor.m_hscale = hscale; }
|
fixedfreq_device &set_horz_scale(int hscale) { m_monitor.m_hscale = hscale; return *this;}
|
||||||
|
|
||||||
// pre-defined configurations
|
// pre-defined configurations
|
||||||
void set_mode_ntsc720() //ModeLine "720x480@30i" 13.5 720 736 799 858 480 486 492 525 interlace -hsync -vsync
|
fixedfreq_device &set_mode_ntsc720() //ModeLine "720x480@30i" 13.5 720 736 799 858 480 486 492 525 interlace -hsync -vsync
|
||||||
{
|
{
|
||||||
set_monitor_clock(13500000);
|
set_monitor_clock(13500000);
|
||||||
set_horz_params(720, 736, 799, 858);
|
set_horz_params(720, 736, 799, 858);
|
||||||
set_vert_params(480, 486, 492, 525);
|
set_vert_params(480, 486, 492, 525);
|
||||||
set_fieldcount(2);
|
set_fieldcount(2);
|
||||||
set_threshold(0.3);
|
set_threshold(0.3);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
void set_mode_ntsc704() //ModeLine "704x480@30i" 13.5 704 728 791 858 480 486 492 525
|
fixedfreq_device &set_mode_ntsc704() //ModeLine "704x480@30i" 13.5 704 728 791 858 480 486 492 525
|
||||||
{
|
{
|
||||||
set_monitor_clock(13500000);
|
set_monitor_clock(13500000);
|
||||||
set_horz_params(704, 728, 791, 858);
|
set_horz_params(704, 728, 791, 858);
|
||||||
set_vert_params(480, 486, 492, 525);
|
set_vert_params(480, 486, 492, 525);
|
||||||
set_fieldcount(2);
|
set_fieldcount(2);
|
||||||
set_threshold(0.3);
|
set_threshold(0.3);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
virtual uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||||
@ -252,6 +289,9 @@ public:
|
|||||||
NETDEV_ANALOG_CALLBACK_MEMBER(update_blue);
|
NETDEV_ANALOG_CALLBACK_MEMBER(update_blue);
|
||||||
NETDEV_ANALOG_CALLBACK_MEMBER(update_sync);
|
NETDEV_ANALOG_CALLBACK_MEMBER(update_sync);
|
||||||
|
|
||||||
|
INPUT_CHANGED_MEMBER(port_changed);
|
||||||
|
|
||||||
|
unsigned monitor_val(unsigned param) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -264,14 +304,17 @@ protected:
|
|||||||
virtual void device_post_load() override;
|
virtual void device_post_load() override;
|
||||||
//virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
|
//virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
|
||||||
|
|
||||||
void vsync_start_cb(double refresh_time) override;
|
virtual ioport_constructor device_input_ports() const override;
|
||||||
|
|
||||||
|
void vsync_end_cb(double refresh_time) override;
|
||||||
|
|
||||||
|
void create_texture();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool m_force_vector;
|
||||||
int m_htotal;
|
float m_scanline_height;
|
||||||
int m_vtotal;
|
std::unique_ptr<bitmap_argb32> m_bitmap; // bitmap for line
|
||||||
|
render_texture * m_texture; // texture for line
|
||||||
time_type m_refresh_period;
|
|
||||||
|
|
||||||
/* adjustable by drivers */
|
/* adjustable by drivers */
|
||||||
fixedfreq_monitor_desc m_monitor;
|
fixedfreq_monitor_desc m_monitor;
|
||||||
|
@ -490,14 +490,14 @@ void pong_state::pong(machine_config &config)
|
|||||||
/* video hardware */
|
/* video hardware */
|
||||||
SCREEN(config, "screen", SCREEN_TYPE_RASTER);
|
SCREEN(config, "screen", SCREEN_TYPE_RASTER);
|
||||||
//SCREEN(config, "screen", SCREEN_TYPE_VECTOR);
|
//SCREEN(config, "screen", SCREEN_TYPE_VECTOR);
|
||||||
FIXFREQ(config, m_video).set_screen("screen");
|
FIXFREQ(config, m_video)
|
||||||
m_video->set_monitor_clock(MASTER_CLOCK_PONG);
|
.set_monitor_clock(MASTER_CLOCK_PONG)
|
||||||
m_video->set_horz_params(H_TOTAL_PONG-67,H_TOTAL_PONG-40,H_TOTAL_PONG-8,H_TOTAL_PONG);
|
.set_horz_params(H_TOTAL_PONG-67,H_TOTAL_PONG-40,H_TOTAL_PONG-8,H_TOTAL_PONG)
|
||||||
m_video->set_vert_params(V_TOTAL_PONG-22,V_TOTAL_PONG-19,V_TOTAL_PONG-12,V_TOTAL_PONG);
|
.set_vert_params(V_TOTAL_PONG-22,V_TOTAL_PONG-19,V_TOTAL_PONG-12,V_TOTAL_PONG)
|
||||||
m_video->set_fieldcount(1);
|
.set_fieldcount(1)
|
||||||
m_video->set_threshold(0.11);
|
.set_threshold(0.11)
|
||||||
m_video->set_horz_scale(4);
|
.set_horz_scale(4)
|
||||||
|
.set_screen("screen");
|
||||||
/* sound hardware */
|
/* sound hardware */
|
||||||
SPEAKER(config, "speaker").front_center();
|
SPEAKER(config, "speaker").front_center();
|
||||||
DAC_16BIT_R2R_TWOS_COMPLEMENT(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.5); // unknown DAC
|
DAC_16BIT_R2R_TWOS_COMPLEMENT(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.5); // unknown DAC
|
||||||
@ -548,7 +548,7 @@ void breakout_state::breakout(machine_config &config)
|
|||||||
*/
|
*/
|
||||||
m_video->set_monitor_clock(MASTER_CLOCK_BREAKOUT);
|
m_video->set_monitor_clock(MASTER_CLOCK_BREAKOUT);
|
||||||
m_video->set_horz_params((H_TOTAL_BREAKOUT-208),(H_TOTAL_BREAKOUT-144),(H_TOTAL_BREAKOUT-16), (H_TOTAL_BREAKOUT));
|
m_video->set_horz_params((H_TOTAL_BREAKOUT-208),(H_TOTAL_BREAKOUT-144),(H_TOTAL_BREAKOUT-16), (H_TOTAL_BREAKOUT));
|
||||||
m_video->set_vert_params(V_TOTAL_BREAKOUT-22,V_TOTAL_BREAKOUT-23,V_TOTAL_BREAKOUT-4, V_TOTAL_BREAKOUT);
|
m_video->set_vert_params(V_TOTAL_BREAKOUT-22,V_TOTAL_BREAKOUT-21,V_TOTAL_BREAKOUT-4, V_TOTAL_BREAKOUT);
|
||||||
m_video->set_fieldcount(1);
|
m_video->set_fieldcount(1);
|
||||||
m_video->set_threshold(1.0);
|
m_video->set_threshold(1.0);
|
||||||
m_video->set_gain(1.5);
|
m_video->set_gain(1.5);
|
||||||
@ -721,7 +721,7 @@ ROM_END
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
GAME( 1972, pong, 0, pong, pong, pong_state, empty_init, ROT0, "Atari", "Pong (Rev E) external [TTL]", MACHINE_SUPPORTS_SAVE)
|
GAME( 1972, pong, 0, pong, pong, pong_state, empty_init, ROT0, "Atari", "Pong (Rev E) external [TTL]", MACHINE_SUPPORTS_SAVE)
|
||||||
GAME( 1972, pongf, 0, pongf, pong, pong_state, empty_init, ROT0, "Atari", "Pong (Rev E) [TTL]", MACHINE_SUPPORTS_SAVE)
|
GAME( 1972, pongf, pong, pongf, pong, pong_state, empty_init, ROT0, "Atari", "Pong (Rev E) [TTL]", MACHINE_SUPPORTS_SAVE)
|
||||||
GAME( 1973, pongd, 0, pongd, pongd, pong_state, empty_init, ROT0, "Atari", "Pong Doubles [TTL]", MACHINE_SUPPORTS_SAVE)
|
GAME( 1973, pongd, 0, pongd, pongd, pong_state, empty_init, ROT0, "Atari", "Pong Doubles [TTL]", MACHINE_SUPPORTS_SAVE)
|
||||||
GAMEL( 1974, rebound, 0, rebound, rebound, rebound_state, empty_init, ROT0, "Atari", "Rebound (Rev B) [TTL]", MACHINE_SUPPORTS_SAVE, layout_rebound)
|
GAMEL( 1974, rebound, 0, rebound, rebound, rebound_state, empty_init, ROT0, "Atari", "Rebound (Rev B) [TTL]", MACHINE_SUPPORTS_SAVE, layout_rebound)
|
||||||
GAMEL( 1976, breakout, 0, breakout, breakout, breakout_state, empty_init, ROT90, "Atari", "Breakout [TTL]", MACHINE_SUPPORTS_SAVE, layout_breakout)
|
GAMEL( 1976, breakout, 0, breakout, breakout, breakout_state, empty_init, ROT90, "Atari", "Breakout [TTL]", MACHINE_SUPPORTS_SAVE, layout_breakout)
|
||||||
|
@ -150,7 +150,8 @@ enum
|
|||||||
TEXTURE_TYPE_SURFACE
|
TEXTURE_TYPE_SURFACE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//#undef GL_TEXTURE_2D
|
||||||
|
//#define GL_TEXTURE_2D GL_TEXTURE_2D_MULTISAMPLE
|
||||||
//============================================================
|
//============================================================
|
||||||
// MACROS
|
// MACROS
|
||||||
//============================================================
|
//============================================================
|
||||||
@ -506,7 +507,7 @@ void renderer_ogl::initialize_gl()
|
|||||||
|
|
||||||
if (strstr(extstr, "GL_EXT_framebuffer_object"))
|
if (strstr(extstr, "GL_EXT_framebuffer_object"))
|
||||||
{
|
{
|
||||||
m_usefbo = 1;
|
//m_usefbo = 1;
|
||||||
if (!s_shown_video_info)
|
if (!s_shown_video_info)
|
||||||
{
|
{
|
||||||
if(m_usefbo)
|
if(m_usefbo)
|
||||||
@ -1123,11 +1124,21 @@ int renderer_ogl::draw(const int update)
|
|||||||
|
|
||||||
GLsizei iScale = 1;
|
GLsizei iScale = 1;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||||
|
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||||
|
glEnable(GL_LINE_SMOOTH);
|
||||||
|
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
|
||||||
|
glEnable(GL_POLYGON_SMOOTH);
|
||||||
|
glEnable(GL_MULTISAMPLE_ARB);
|
||||||
|
glEnable(GL_MULTISAMPLE);
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
Mac hack: macOS version 10.15 and later flipped from assuming you don't support Retina to
|
Mac hack: macOS version 10.15 and later flipped from assuming you don't support Retina to
|
||||||
assuming you do support Retina. SDL 2.0.11 is scheduled to fix this, but it's not out yet.
|
assuming you do support Retina. SDL 2.0.11 is scheduled to fix this, but it's not out yet.
|
||||||
So we double-scale everything if you're on 10.15 or later and SDL is not at least version 2.0.11.
|
So we double-scale everything if you're on 10.15 or later and SDL is not at least version 2.0.11.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(SDLMAME_MACOSX) || defined(OSD_MAC)
|
#if defined(SDLMAME_MACOSX) || defined(OSD_MAC)
|
||||||
SDL_version sdlVers;
|
SDL_version sdlVers;
|
||||||
SDL_GetVersion(&sdlVers);
|
SDL_GetVersion(&sdlVers);
|
||||||
|
@ -704,6 +704,9 @@ int sdl_window_info::complete_create()
|
|||||||
* SDL_GL_SetAttribute( SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1 );
|
* SDL_GL_SetAttribute( SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1 );
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1 );
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, 16);
|
||||||
m_extra_flags = SDL_WINDOW_OPENGL;
|
m_extra_flags = SDL_WINDOW_OPENGL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user