summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatarGravatar couriersud <couriersud@gmx.org>2019-11-17 03:07:04 +0100
committerGravatarGravatar couriersud <couriersud@gmx.org>2019-11-17 03:07:09 +0100
commit6b004964ef5f67a0416f6036d34c4f9a57059793 (patch) (github)
treeadf7db38af7f681d13677f1acb01b21f2dbecdc2
parent1ac2d06ea131d47298318dcf55c1438970293248 (diff)
downloadmame-6b004964ef5f67a0416f6036d34c4f9a57059793.tar.bz2
mame-6b004964ef5f67a0416f6036d34c4f9a57059793.zip
netlist video: Add VECTOR support. [Couriersud]
Fixfreq now supports VECTOR screens automatically. For now the default remains to be RASTER since bgfx does not support VECTOR screens. Nevertheless please expect changes in the video output. Video output is now collected timing-exact, i.e. with subpixel accuracy. Only during screen_update this is converted and scaled to the bitmap. There may be changes due to rounding in comparison to current rendering. Also added a link to a video showing a breakout cocktail table.
-rw-r--r--src/devices/video/fixfreq.cpp55
-rw-r--r--src/devices/video/fixfreq.h20
-rw-r--r--src/mame/drivers/pong.cpp10
3 files changed, 59 insertions, 26 deletions
diff --git a/src/devices/video/fixfreq.cpp b/src/devices/video/fixfreq.cpp
index c5dc2e5ffcb..4957a0343fa 100644
--- a/src/devices/video/fixfreq.cpp
+++ b/src/devices/video/fixfreq.cpp
@@ -14,6 +14,7 @@
***************************************************************************/
#include "emu.h"
+#include "rendutil.h"
#include "fixfreq.h"
//#define VERBOSE 1
@@ -83,7 +84,7 @@ void fixedfreq_monitor_state::update_sync_channel(const time_type &time, const d
void fixedfreq_monitor_state::update_bm(const time_type &time)
{
- const int pixels = round((time - m_line_time) * m_desc.m_hscale / m_clock_period);
+ const float pixels = (time - m_line_time) * static_cast<time_type>(m_desc.m_hscale) / m_clock_period;
const int has_fields = (m_desc.m_fieldcount > 1) ? 1: 0;
uint32_t col(0xffff0000); // Mark sync areas
@@ -91,7 +92,8 @@ void fixedfreq_monitor_state::update_bm(const time_type &time)
if (m_sync_signal >= m_desc.m_sync_threshold)
col = m_col;
- m_intf.plot_hline(m_last_x, m_last_y + m_sig_field * has_fields, pixels - m_last_x, col);
+ m_fragments.push_back({static_cast<float>(m_last_y + m_sig_field * has_fields), m_last_x, pixels, col});
+ //m_intf.plot_hline(m_last_x, m_last_y + m_sig_field * has_fields, pixels, col);
m_last_x = pixels;
}
@@ -157,7 +159,6 @@ 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)
: device_t(mconfig, type, tag, owner, clock),
device_video_interface(mconfig, *this, false),
- m_cur_bm(0),
m_htotal(0),
m_vtotal(0),
m_refresh_period(time_type(0)),
@@ -190,12 +191,8 @@ void fixedfreq_device::device_start()
m_refresh_period = time_type(0);
- m_cur_bm = 0;
-
m_htotal = m_monitor.m_hbackporch;
m_vtotal = m_monitor.m_vbackporch;
- m_bitmap[0] = std::make_unique<bitmap_rgb32>(m_htotal * m_monitor.m_hscale, m_vtotal);
- m_bitmap[1] = std::make_unique<bitmap_rgb32>(m_htotal * m_monitor.m_hscale, m_vtotal);
m_state.start();
@@ -209,9 +206,6 @@ void fixedfreq_device::device_start()
save_item(NAME(m_state.m_last_vsync_time));
save_item(NAME(m_refresh_period));
save_item(NAME(m_state.m_clock_period));
- //save_item(NAME(m_bitmap[0]));
- //save_item(NAME(m_bitmap[1]));
- save_item(NAME(m_cur_bm));
/* sync separator */
save_item(NAME(m_state.m_vsync_filter));
@@ -235,15 +229,45 @@ void fixedfreq_device::device_post_load()
uint32_t fixedfreq_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
- copybitmap(bitmap, *m_bitmap[!m_cur_bm], 0, 0, 0, 0, cliprect);
+ if (screen.screen_type() == SCREEN_TYPE_RASTER)
+ {
+ for (auto &f : m_state.m_fragments)
+ if (f.y < bitmap.height())
+ bitmap.plot_box(f.x, f.y, f.xr - f.x, 1, f.col);
+ }
+ else if (screen.screen_type() == SCREEN_TYPE_VECTOR)
+ {
+ constexpr const uint32_t flags(PRIMFLAG_ANTIALIAS(1) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_VECTOR(1));
+ const rectangle &visarea = screen.visible_area();
+ float xscale = 1.0f / visarea.width();
+ float yscale = 1.0f / visarea.height();
+ float xoffs = (float)visarea.min_x;
+ float yoffs = (float)visarea.min_y;
+ 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));
+
+ for (auto &f : m_state.m_fragments)
+ {
+ const float x0((f.x - xoffs) * xscale);
+ const float y0((f.y - yoffs) * yscale);
+ const float x1((f.xr - xoffs) * xscale);
+ const float y1((f.y + 1.0f - yoffs) * yscale);
+
+ screen.container().add_rect(
+ x0, y0, x1, y1,
+ (0xff << 24) | (f.col & 0xffffff),
+ flags);
+ }
+ }
+ m_state.m_fragments.clear();
return 0;
}
void fixedfreq_device::vsync_start_cb(double refresh_time)
{
// toggle bitmap
- m_cur_bm ^= 1;
+ //m_cur_bm ^= 1;
rectangle visarea(m_monitor.minh(), m_monitor.maxh(), m_monitor.minv(), m_monitor.maxv());
@@ -251,13 +275,6 @@ void fixedfreq_device::vsync_start_cb(double refresh_time)
screen().configure(m_htotal * m_monitor.m_hscale, m_vtotal, visarea, DOUBLE_TO_ATTOSECONDS(m_refresh_period));
}
-void fixedfreq_device::plot_hline(int x, int y, int w, uint32_t col)
-{
- bitmap_rgb32 *bm = m_bitmap[m_cur_bm].get();
- if (y < bm->height())
- bm->plot_box(x, y, w, 1, col);
-}
-
NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_composite_monochrome)
{
// double is good enough for this exercise;
diff --git a/src/devices/video/fixfreq.h b/src/devices/video/fixfreq.h
index 6e758ec4ffa..fdbf728f04a 100644
--- a/src/devices/video/fixfreq.h
+++ b/src/devices/video/fixfreq.h
@@ -60,7 +60,14 @@ struct fixedfreq_monitor_intf
{
virtual ~fixedfreq_monitor_intf() = default;
virtual void vsync_start_cb(double refresh_time) = 0;
- virtual void plot_hline(int x, int y, int w, uint32_t col) = 0;
+};
+
+struct fixedfreq_monitor_line
+{
+ float y;
+ float x;
+ float xr;
+ uint32_t col;
};
struct fixedfreq_monitor_state
@@ -127,8 +134,10 @@ struct fixedfreq_monitor_state
m_clock_period = 1.0 / m_desc.m_monitor_clock;
// 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_intf.vsync_start_cb(m_min_frame_period);
+ m_fragments.clear();
+
+ m_intf.vsync_start_cb(m_min_frame_period);
}
void reset()
@@ -148,6 +157,7 @@ struct fixedfreq_monitor_state
m_sig_vsync = 0;
m_sig_composite = 0;
m_sig_field = 0;
+ m_fragments.clear();
}
void update_sync_channel(const time_type &time, const double newval);
@@ -163,7 +173,7 @@ struct fixedfreq_monitor_state
double m_sync_signal;
uint32_t m_col;
- int m_last_x;
+ float m_last_x;
int m_last_y;
time_type m_last_sync_time;
time_type m_line_time;
@@ -180,6 +190,7 @@ struct fixedfreq_monitor_state
int m_sig_composite;
int m_sig_field;
time_type m_min_frame_period;
+ std::vector<fixedfreq_monitor_line> m_fragments;
};
// ======================> fixedfreq_device
@@ -254,12 +265,9 @@ protected:
//virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
void vsync_start_cb(double refresh_time) override;
- void plot_hline(int x, int y, int w, uint32_t col) override;
private:
- std::unique_ptr<bitmap_rgb32> m_bitmap[2];
- int m_cur_bm;
int m_htotal;
int m_vtotal;
diff --git a/src/mame/drivers/pong.cpp b/src/mame/drivers/pong.cpp
index a140ea5ea8a..ea4ad14e7ab 100644
--- a/src/mame/drivers/pong.cpp
+++ b/src/mame/drivers/pong.cpp
@@ -97,6 +97,12 @@ TODO: Volleyball...
* https://www.youtube.com/watch?v=pDrRnJOCKZc (no longer available)
*
* https://www.youtube.com/watch?v=fiShX2pTz9A
+ * https://www.youtube.com/watch?v=YmzH4E3x1_g
+ *
+ * Breakout videos:
+ *
+ * https://www.youtube.com/watch?v=NOGO49j5gCE
+ *
*/
static const int NS_PER_CLOCK_PONG = static_cast<int>((double) NETLIST_INTERNAL_RES / (double) 7159000 + 0.5);
@@ -483,6 +489,7 @@ void pong_state::pong(machine_config &config)
/* video hardware */
SCREEN(config, "screen", SCREEN_TYPE_RASTER);
+ //SCREEN(config, "screen", SCREEN_TYPE_VECTOR);
FIXFREQ(config, m_video).set_screen("screen");
m_video->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);
@@ -533,8 +540,9 @@ void breakout_state::breakout(machine_config &config)
NETLIST_ANALOG_OUTPUT(config, "maincpu:coin_counter", 0).set_params("CON_T", FUNC(breakout_state::coin_counter_cb));
/* video hardware */
- SCREEN(config, "screen", SCREEN_TYPE_RASTER);
FIXFREQ(config, m_video).set_screen("screen");
+ SCREEN(config, "screen", SCREEN_TYPE_RASTER);
+ //SCREEN(config, "screen", SCREEN_TYPE_VECTOR);
/* The Pixel width is a 2,1,2,1,2,1,1,1 repeating pattern
* Thus we must use double resolution horizontally
*/